连续复制
一键复制
一键打包

api

activity.js


import request from "@utils/request";

/**
 * 拼团列表
 */
export function getCombinationList(data) {
  return request.get("/combination/list", data, { login: false });
}

/**
 * 拼团产品详情
 * @param {*} id
 */
export function getCombinationDetail(id) {
  return request.get("/combination/detail/" + id, {}, { login: false });
}

/**
 * 拼团 开团
 * @param {*} id
 */
export function getCombinationPink(id) {
  return request.get("/combination/pink/" + id);
}

/**
 * 拼团 取消开团
 */
export function getCombinationRemove(data) {
  return request.post("/combination/remove", data);
}

/**
 * 拼团海报
 * @param {*} id
 */
export function getCombinationPoster(data) {
  return request.post("/combination/poster", data);
}

/**
 * 秒杀列表配置
 */
export function getSeckillConfig() {
  return request.get("/seckill/index", {}, { login: false });
}

/**
 * 秒杀列表
 */
export function getSeckillList(time, data) {
  return request.get("/seckill/list/" + time, data, { login: false });
}

/**
 * 秒杀产品详情
 */
export function getSeckillDetail(id) {
  return request.get("/seckill/detail/" + id, {}, { login: false });
}

/**
 * 砍价列表
 * @param {*} data
 */
export function getBargainList(data) {
  return request.get("/bargain/list", data, { login: false });
}

/**
 * 砍价产品详情
 */
export function getBargainDetail(id) {
  return request.get("/bargain/detail/" + id);
}

/**
 * 砍价 观看/分享/参与次数
 */
export function getBargainShare(data) {
  return request.post("/bargain/share", data);
}

/**
 * 砍价开启
 * @param {*} data
 */
export function getBargainStart(data) {
  return request.post("/bargain/start", data);
}

/**
 * 砍价 帮助好友砍价
 * @param {*} data
 */
export function getBargainHelp(data) {
  return request.post("/bargain/help", data);
}

/**
 * 砍价 砍掉金额
 * @param {*} data
 */
export function getBargainHelpPrice(data) {
  return request.post("/bargain/help/price", data);
}

/**
 * 砍价 砍价帮总人数、剩余金额、进度条、已经砍掉的价格
 * @param {*} data
 */
export function getBargainHelpCount(data) {
  return request.post("/bargain/help/count", data);
}

/**
 * 砍价 开启砍价用户信息
 * @param {*} data
 */
export function getBargainStartUser(data) {
  return request.post("/bargain/start/user", data);
}

/**
 * 砍价 砍价帮
 * @param {*} data
 */
export function getBargainHelpList(data) {
  return request.post("/bargain/help/list", data);
}

/**
 * 砍价海报
 * @param {*} data
 */
export function getBargainPoster(data) {
  return request.post("/bargain/poster", data);
}

/**
 * 砍价列表(已参与)
 * @param {*} data
 */
export function getBargainUserList(data) {
  return request.get("/bargain/user/list", data);
}

/**
 * 砍价取消
 */
export function getBargainUserCancel(data) {
  return request.post("/bargain/user/cancel", data);
}

order.js


/*
 * 订单确认
 * */
import request from "@utils/request";

/**
 * 通过购物车 id 获取订单信息
 * @param cartId
 * @returns {*}
 */
export function postOrderConfirm(cartId) {
  return request.post("/order/confirm", { cartId });
}

/**
 * 计算订单金额
 * @param key
 * @param data
 * @returns {*}
 */
export function postOrderComputed(key, data) {
  return request.post("/order/computed/" + key, data);
}

/**
 * 获取指定金额可用优惠券
 * @param price
 * @returns {*}
 */
export function getOrderCoupon(price) {
  return request.get("/coupons/order/" + (parseFloat(price) || 0));
}

/**
 * 生成订单
 * @param key
 * @param data
 * @returns {*}
 */
export function createOrder(key, data) {
  return request.post("/order/create/" + key, data || {});
}

/**
 * 订单统计数据
 * @returns {*}
 */
export function getOrderData() {
  return request.get("/order/data");
}

/**
 * 订单列表
 * @returns {*}
 */
export function getOrderList(data) {
  return request.get("/order/list", data);
}

/**
 * 取消订单
 * @returns {*}
 */
export function cancelOrder(id) {
  return request.post("/order/cancel", { id });
}

/**
 * 订单详情
 * @returns {*}
 */
export function orderDetail(id) {
  return request.get("/order/detail/" + id);
}

/**
 * 退款理由
 * @returns {*}
 */
export function getRefundReason() {
  return request.get("/order/refund/reason");
}

/**
 * 提交退款
 * @returns {*}
 */
export function postOrderRefund(data) {
  return request.post("/order/refund/verify", data);
}

/**
 * 确认收货
 * @returns {*}
 */
export function takeOrder(uni) {
  return request.post("/order/take", { uni });
}

/**
 * 删除订单
 * @returns {*}
 */
export function delOrder(uni) {
  return request.post("/order/del", { uni });
}

/**
 * 订单查询物流信息
 * @returns {*}
 */
export function express(uni) {
  return request.get("order/express/" + uni);
}

/**
 * 订单查询物流信息
 * @returns {*}
 */
export function payOrder(uni, paytype, from) {
  return request.post("order/pay", { uni, paytype, from });
}
/**
 * 订单核销
 * @returns {*}
 */
export function orderVerific(verify_code, is_confirm) {
  return request.post("order/order_verific", { verify_code, is_confirm });
}

public.js


import request from "@utils/request";

/**
 * 首页
 * @returns {*}
 */
export function getHomeData() {
  return request.get("index", {}, { login: false });
}

/**
 * 文章 轮播列表
 * @returns {*}
 */
export function getArticleBanner() {
  return request.get("/article/banner/list", {}, { login: false });
}

/**
 * 文章分类列表
 * @returns {*}
 */
export function getArticleCategory() {
  return request.get("/article/category/list", {}, { login: false });
}

/**
 * 文章 热门列表
 * @returns {*}
 */
export function getArticleHotList() {
  return request.get("/article/hot/list", {}, { login: false });
}

/**
 * 文章列表
 * @returns {*}
 */
export function getArticleList(q, cid) {
  return request.get("/article/list/" + cid, q, { login: false });
}

/**
 * 分享
 * @returns {*}
 */
export function getShare() {
  return request.get("/share", {}, { login: false });
}

/**
 * 文章详情
 * @returns {*}
 */
export function getArticleDetails(id) {
  return request.get("/article/details/" + id, {}, { login: false });
}

/**
 * 获取微信sdk配置
 * @returns {*}
 */
export function getWechatConfig() {
  return request.get(
    "/wechat/config",
    { url: document.location.href },
    { login: false }
  );
}

/**
 * 获取微信sdk配置
 * @returns {*}
 */
export function wechatAuth(code, spread, login_type) {
  return request.get(
    "/wechat/auth",
    { code, spread, login_type },
    { login: false }
  );
}
/**
 * 获取快递公司
 * @returns {*}
 */
export function getLogistics() {
  return request.get("/logistics", {}, { login: false });
}

/**
 * 获取登陆logo
 * @returns {*}
 */
export function getLogo(type) {
  return request.get("/wechat/get_logo", { type: type }, { login: false });
}

/**
 * 获取图片base64
 * @retins {*}
 * */
export function imageBase64(image, code) {
  return request.post(
    "/image_base64",
    { image: image, code: code },
    { login: false }
  );
}

store.js


import request from "@utils/request";

/*
 * 商品分类
 * */
export function getCategory() {
  return request.get("/category", {}, { login: false });
}

/*
 * 商品详情
 * */
export function getProductDetail(id) {
  return request.get("/product/detail/" + id, {}, { login: false });
}

/*
 * 商品分销二维码
 * */
export function getProductCode(id) {
  return request.get("/product/code/" + id, {}, { login: true });
}

/*
 * 商品列表
 * */
export function getProducts(q) {
  return request.get("/products", q, { login: false });
}

/*
 * 购物车数量
 * */
export function getCartNum() {
  return request.get("/cart/count");
}

/*
 * 添加收藏
 * */
export function toCollect(id, category) {
  return request.get("/collect/add/" + id + "/" + category);
}

/*
 * 为你推荐
 * */
export function getHostProducts(page, limit) {
  return request.get(
    "/product/hot",
    { page: page, limit: limit },
    { login: false }
  );
}

/*
 * 精品、热门、首发列表
 * */
export function getGroomList(type) {
  return request.get("/groom/list/" + type, {}, { login: false });
}

/*
 * 购物车 添加
 * */
export function postCartAdd(data) {
  return request.post("/cart/add", data);
}

/*
 * 购物车列表
 * */
export function getCartList() {
  return request.get("/cart/list");
}

/*
 * 购物车 删除
 * */
export function postCartDel(ids) {
  return request.post("/cart/del", { ids });
}

/*
 * 购物车 获取数量
 * */
export function getCartCount(data) {
  return request.get("/cart/count", data);
}

/*
 * 购物车 修改商品数量
 * */
export function changeCartNum(id, number) {
  return request.post("/cart/num", { id, number });
}

/**
 * 搜索推荐关键字
 */
export function getSearchKeyword() {
  return request.get("/search/keyword", {}, { login: false });
}

/**
 * 产品评论列表
 */
export function getReplyList(id, q) {
  return request.get("/reply/list/" + id, q, { login: false });
}

/**
 * 产品评价数量和好评度
 */
export function getReplyConfig(id) {
  return request.get("/reply/config/" + id, {}, { login: false });
}

/**
 * 评价页面获取单个产品详情
 */
export function postOrderProduct(unique) {
  return request.post("/order/product", { unique }, { login: false });
}

/**
 * 提交评价页面;
 */
export function postOrderComment(data) {
  return request.post("/order/comment", data, { login: false });
}

user.js


import request from "@utils/request";

/**
 * 用户登录
 * @param data object 用户账号密码
 */
export function login(data) {
  return request.post("/login", data, { login: false });
}

/**
 * 用户手机号登录
 * @param data object 用户手机号 也只能
 */
export function loginMobile(data) {
  return request.post("/login/mobile", data, { login: false });
}

/**
 * 用户发送验证码
 * @param data object 用户手机号
 */
export function registerVerify(data) {
  return request.post("/register/verify", data, { login: false });
}

/**
 * 用户手机号注册
 * @param data object 用户手机号 验证码 密码
 */
export function register(data) {
  return request.post("/register", data, { login: false });
}

/**
 * 用户手机号修改密码
 * @param data object 用户手机号 验证码 密码
 */
export function registerReset(data) {
  return request.post("/register/reset", data, { login: false });
}

/*
 * 领取优惠券列表
 * */
export function getCoupon(q) {
  return request.get("/coupons", q, { login: false });
}

/*
 * 点击领取优惠券
 * */
export function getCouponReceive(id) {
  return request.post("/coupon/receive", { couponId: id }, { login: true });
}

/*
 * 批量领取优惠券
 * */
export function couponReceiveBatch(couponId) {
  return request.post("/coupon/receive/batch", { couponId });
}

/*
 * 我的优惠券
 * */
export function getCouponsUser(type) {
  return request.get("/coupons/user/" + type);
}

/*
 * 个人中心
 * */
export function getUser() {
  return request.get("/user");
}

/*
 * 用户信息
 * */
export function getUserInfo() {
  return request.get("/userinfo");
}

/*
 * 个人中心(功能列表)
 * */
export function getMenuUser() {
  return request.get("/menu/user");
}

/*
 * 地址列表
 * */
export function getAddressList(data) {
  return request.get("/address/list", data || {});
}

/*
 * 删除地址
 * */
export function getAddressRemove(id) {
  return request.post("/address/del", { id: id });
}

/*
 * 设置默认地址
 * */
export function getAddressDefaultSet(id) {
  return request.post("/address/default/set", { id: id });
}

/*
 * 获取默认地址
 * */
export function getAddressDefault() {
  return request.get("/address/default");
}

/*
 * 获取单个地址
 * */
export function getAddress(id) {
  return request.get("/address/detail/" + id);
}

/*
 * 修改 添加地址
 * */
export function postAddress(data) {
  return request.post("/address/edit", data);
}

/*
 * 获取收藏产品
 * */
export function getCollectUser(page, limit) {
  return request.get("/collect/user", { page: page, limit: limit });
}

/*
 * 删除收藏产品
 * */
export function getCollectDel(id, category) {
  return request.post("/collect/del", { id: id, category: category });
}

/*
 * 批量收藏产品
 * */
export function postCollectAll(data) {
  return request.post("/collect/all", data);
}

/*
 * 添加收藏产品
 * */
export function getCollectAdd(id, category) {
  return request.post("collect/add", { id: id, category: category });
}

/*
 * 签到配置
 * */
export function getSignConfig() {
  return request.get("/sign/config");
}

/*
 * 签到里的签到列表
 * */
export function getSignList(page, limit) {
  return request.get("/sign/list", { page: page, limit: limit });
}

/*
 * 签到列表
 * */
export function getSignMonth(page, limit) {
  return request.get("/sign/month", { page: page, limit: limit });
}

/*
 * 签到用户信息
 * */
export function postSignUser(sign) {
  return request.post("/sign/user", sign);
}

/*
 * 签到
 * */
export function postSignIntegral(sign) {
  return request.post("/sign/integral", sign);
}

/*
 * 推广数据
 * */
export function getSpreadInfo() {
  return request.get("/commission");
}

/*
 * 推广人列表
 * */
export function getSpreadUser(screen) {
  return request.post("/spread/people", screen);
}

/*
 * 推广人订单
 * */
export function getSpreadOrder(where) {
  return request.post("/spread/order", where);
}

/*
 * 资金明细(types|0=全部,1=消费,2=充值,3=返佣,4=提现)
 * */
export function getCommissionInfo(q, types) {
  return request.get("/spread/commission/" + types, q);
}

/*
 * 积分记录
 * */
export function getIntegralList(q) {
  return request.get("/integral/list", q);
}

/*
 * 提现银行
 * */
export function getBank() {
  return request.get("/extract/bank");
}

/*
 * 提现申请
 * */
export function postCashInfo(cash) {
  return request.post("/extract/cash", cash);
}

/*
 * 会员中心
 * */
export function getVipInfo() {
  return request.get("/user/level/grade");
}

/*
 * 会员等级任务
 * */
export function getVipTask(id) {
  return request.get("/user/level/task/" + id);
}

/*
 * 资金统计
 * */
export function getBalance() {
  return request.get("/user/balance");
}

/*
 * 活动状态
 * */
export function getActivityStatus() {
  return request.get("/user/activity", {}, { login: false });
}

/*
 * 活动状态
 * */
export function getSpreadImg() {
  return request.get("/spread/banner");
}

/*
 * 用户修改信息
 * */
export function postUserEdit(data) {
  return request.post("/user/edit", data);
}

/*
 * 用户修改信息
 * */
export function getChatRecord(to_uid, data) {
  return request.get("user/service/record/" + to_uid, data);
}

/*
 * 用户修改信息
 * */
export function serviceList() {
  return request.get("user/service/list");
}

/*
 * 公众号充值
 * */
export function rechargeWechat(data) {
  return request.post("/recharge/wechat", data);
}

/*
 * 退出登录
 * */
export function getLogout() {
  return request.get("/logout");
}

/*
 * 绑定手机号
 * */
export function bindingPhone(data) {
  return request.post("binding", data);
}

/*
 * h5切换公众号登陆
 * */
export function switchH5Login() {
  return request.post("switch_h5", { from: "wechat" });
}
/*
 * 获取推广人排行
 * */
export function getRankList(q) {
  return request.get("rank", q);
}
/*
 * 获取佣金排名
 * */
export function getBrokerageRank(q) {
  return request.get("brokerage_rank", q);
}
/**
 * 检测会员等级
 */
export function setDetection() {
  return request.get("user/level/detection");
}

App.vue


<template>
  <div>
    <div class="app" v-cloak>
      <!--      <transition :name="transitionName">-->
      <keep-alive :include="include" :max="10">
        <router-view class="router" ref="router"></router-view>
      </keep-alive>
      <!--      </transition>-->
    </div>
    <Footer v-if="footer === true"></Footer>
    <Home v-if="home === true"></Home>
  </div>
</template>
<script>
function isKeepAlive($route) {
  return $route.meta.keepAlive === undefined || $route.meta.keepAlive;
}

import Footer from "@components/Footer";
import Home from "@components/Home";
import { mapGetters } from "vuex";
import { openShareAll } from "@libs/wechat";
import { getShare } from "@api/public";
import { isWeixin } from "@utils/index";

export default {
  data() {
    return {
      transitionName: "fold-right",
      include: isKeepAlive(this.$route) ? [this.$route.name] : [],
      history: []
    };
  },
  provide() {
    return {
      app: this
    };
  },
  computed: mapGetters(["footer", "home", "isLogin"]),
  components: {
    Footer,
    Home
  },
  watch: {
    $route(to, from) {
      const lastPath = this.history[this.history.length - 1] || {},
        { isReplace, isBack } = this.$router;

      if (lastPath.path === to.path) {
        this.transitionName = "fold-right";
        this.history.pop();
      } else {
        this.transitionName = "fold-left";
        if (!isReplace) this.history.push({ path: from.path, name: from.name });
      }

      if (isKeepAlive(to) && to.name !== "Login") {
        !this.include.includes(to.name) && this.include.push(to.name);
      }

      if (isKeepAlive(from) && isBack) {
        var index = this.include.indexOf(from.name);
        index !== -1 && this.include.splice(index, 1);
      }

      this.$router.isBack = false;
      this.$router.isReplace = false;

      console.log(this.transitionName, "change");
    }
  },
  mounted: function() {
    this.setOpenShare();
  },
  methods: {
    setOpenShare: function() {
      if (isWeixin()) {
        getShare().then(res => {
          var data = res.data.data;
          var configAppMessage = {
            desc: data.synopsis,
            title: data.title,
            link: location.href,
            imgUrl: data.img
          };
          openShareAll(configAppMessage);
        });
      }
    }
  }
};
</script>
<style lang="scss">
[v-cloak] {
  display: none !important;
}

.router {
  position: absolute;
  width: 100%;
}

.fold-left-enter-active {
  animation-name: fold-left-in;
  animation-duration: 0.5s;
}

.fold-left-leave-active {
  animation-name: fold-left-out;
  animation-duration: 0.5s;
}

@keyframes fold-left-in {
  0% {
    -webkit-transform: translate3d(100%, 0, 0);
    transform: translate3d(100%, 0, 0);
  }
  10% {
    -webkit-transform: translate3d(100%, 0, 0);
    transform: translate3d(100%, 0, 0);
  }
  100% {
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }
}

@keyframes fold-left-out {
  0% {
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }
  10% {
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }
  100% {
    -webkit-transform: translate3d(-100%, 0, 0);
    transform: translate3d(-100%, 0, 0);
  }
}

.fold-right-enter-active {
  animation-name: fold-right-in;
  animation-duration: 0.5s;
}

.fold-right-leave-active {
  animation-name: fold-right-out;
  animation-duration: 0.5s;
}

@keyframes fold-right-in {
  0% {
    width: 100%;
    -webkit-transform: translate3d(-100%, 0, 0);
    transform: translate3d(-100%, 0, 0);
  }
  10% {
    width: 100%;
    -webkit-transform: translate3d(-100%, 0, 0);
    transform: translate3d(-100%, 0, 0);
  }
  100% {
    width: 100%;
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }
}

@keyframes fold-right-out {
  0% {
    width: 100%;
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }
  10% {
    width: 100%;
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }
  100% {
    width: 100%;
    -webkit-transform: translate3d(100%, 0, 0);
    transform: translate3d(100%, 0, 0);
  }
}
</style>

assets

css

base.css

@charset "UTF-8";
/**
    *相关初始化
*/
.font-color-red {
  color: #fc4141 !important;
}
.bg-color-red {
  background-color: #e93323 !important;
}
.icon-color {
  color: #ff3c2b;
}
.cart-color {
  color: #ff3700 !important;
  border: 1px solid #ff3700 !important;
}
/* padding20 */
.padding20 {
  padding: 0.2rem;
}
/* pad20 */
.pad20 {
  padding: 0 0.2rem;
}
/* padding30 */
.padding30 {
  padding: 0.3rem;
}
/*pad30 */
.pad30 {
  padding: 0 0.3rem;
}
/* layout */
.acea-row {
  display: -webkit-box;
  display: -moz-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-lines: multiple;
  -moz-box-lines: multiple;
  -o-box-lines: multiple;
  -webkit-flex-wrap: wrap;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap;
  /* 辅助类 */
}
.acea-row.row-middle {
  -webkit-box-align: center;
  -moz-box-align: center;
  -o-box-align: center;
  -ms-flex-align: center;
  -webkit-align-items: center;
  align-items: center;
}
.acea-row.row-top {
  -webkit-box-align: start;
  -moz-box-align: start;
  -o-box-align: start;
  -ms-flex-align: start;
  -webkit-align-items: flex-start;
  align-items: flex-start;
}
.acea-row.row-bottom {
  -webkit-box-align: end;
  -moz-box-align: end;
  -o-box-align: end;
  -ms-flex-align: end;
  -webkit-align-items: flex-end;
  align-items: flex-end;
}
.acea-row.row-center {
  -webkit-box-pack: center;
  -moz-box-pack: center;
  -o-box-pack: center;
  -ms-flex-pack: center;
  -webkit-justify-content: center;
  justify-content: center;
}
.acea-row.row-right {
  -webkit-box-pack: end;
  -moz-box-pack: end;
  -o-box-pack: end;
  -ms-flex-pack: end;
  -webkit-justify-content: flex-end;
  justify-content: flex-end;
}
.acea-row.row-left {
  -webkit-box-pack: start;
  -moz-box-pack: start;
  -o-box-pack: start;
  -ms-flex-pack: start;
  -webkit-justify-content: flex-start;
  justify-content: flex-start;
}
.acea-row.row-between {
  -webkit-box-pack: justify;
  -moz-box-pack: justify;
  -o-box-pack: justify;
  -ms-flex-pack: justify;
  -webkit-justify-content: space-between;
  justify-content: space-between;
}
.acea-row.row-around {
  justify-content: space-around;
  -webkit-justify-content: space-around;
}
.acea-row.row-column-around {
  -webkit-flex-direction: column;
  -ms-flex-direction: column;
  flex-direction: column;
  justify-content: space-around;
  -webkit-justify-content: space-around;
}
.acea-row.row-column {
  -webkit-box-orient: vertical;
  -moz-box-orient: vertical;
  -o-box-orient: vertical;
  -webkit-flex-direction: column;
  -ms-flex-direction: column;
  flex-direction: column;
}
.acea-row.row-column-between {
  -webkit-box-orient: vertical;
  -moz-box-orient: vertical;
  -o-box-orient: vertical;
  -webkit-flex-direction: column;
  -ms-flex-direction: column;
  flex-direction: column;
  -webkit-box-pack: justify;
  -moz-box-pack: justify;
  -o-box-pack: justify;
  -ms-flex-pack: justify;
  -webkit-justify-content: space-between;
  justify-content: space-between;
}
/* 上下左右垂直居中 */
.acea-row.row-center-wrapper {
  -webkit-box-align: center;
  -moz-box-align: center;
  -o-box-align: center;
  -ms-flex-align: center;
  -webkit-align-items: center;
  align-items: center;
  -webkit-box-pack: center;
  -moz-box-pack: center;
  -o-box-pack: center;
  -ms-flex-pack: center;
  -webkit-justify-content: center;
  justify-content: center;
}
/* 上下两边居中对齐 */
.acea-row.row-between-wrapper {
  -webkit-box-align: center;
  -moz-box-align: center;
  -o-box-align: center;
  -ms-flex-align: center;
  -webkit-align-items: center;
  align-items: center;
  -webkit-box-pack: justify;
  -moz-box-pack: justify;
  -o-box-pack: justify;
  -ms-flex-pack: justify;
  -webkit-justify-content: space-between;
  justify-content: space-between;
}
/* 轮播图 */
.slider-banner {
  position: relative;
  width: 100%;
  overflow: hidden;
}
.slider-banner .swiper-container {
  height: 100%;
}
.slider-banner img {
  display: block;
  width: 100%;
  height: auto;
}
.start {
  width: 1.22rem;
  height: 0.3rem;
  background-image: url("../images/start.png");
  background-repeat: no-repeat;
  background-size: 1.22rem auto;
}
.start.star5 {
  background-position: 0 0.03rem;
}
.start.star4 {
  background-position: 0 -0.3rem;
}
.start.star3 {
  background-position: 0 -0.7rem;
}
.start.star2 {
  background-position: 0 -1.05rem;
}
.start.star1 {
  background-position: 0 -1.4rem;
}
.start.star0 {
  background-position: 0 -1.75rem;
}
/* 单选框和多选框 */
.checkbox-wrapper {
  position: relative;
}
.checkbox-wrapper input {
  display: none;
}
.checkbox-wrapper .icon {
  position: absolute;
  left: 0;
  top: 50%;
  display: inline-block;
  width: 18px;
  height: 18px;
  border: 1px solid #cccccc;
  border-radius: 50%;
  -webkit-transform: translate(0, -50%);
  -moz-transform: translate(0, -50%);
  -o-transform: translate(0, -50%);
  -ms-transform: translate(0, -50%);
  transform: translate(0, -50%);
}
.checkbox-wrapper input:checked + .icon {
  background-color: #e93323;
  border-color: #e93323;
  background-image: url("../images/enter.png");
  -webkit-background-size: 0.21rem 0.15rem;
  -moz-background-size: 0.21rem 0.15rem;
  background-size: 0.21rem 0.15rem;
  background-repeat: no-repeat;
  background-position: center center;
}
.Loads {
  height: 0.8rem;
  font-size: 0.25rem;
  color: #000;
}
.Loads .iconfont {
  font-size: 0.3rem;
  margin-right: 0.1rem;
  height: 0.32rem;
  line-height: 0.32rem;
}
/*加载动画*/
@keyframes load {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
.loadingpic {
  animation: load 3s linear 1s infinite;
}
.loading {
  animation: load linear 1s infinite;
}

reset.css

body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li, pre, form, fieldset, legend, button, input, textarea, th, td,select { margin:0; padding:0; } 
body, button, input, select, textarea {font-size:.3rem;}
h1, h2, h3, h4, h5, h6{ font-size:100%; } 
address, cite, dfn, em, var { font-style:normal; } 
code, kbd, pre, samp { font-family:couriernew, courier, monospace; } 
small{ font-size:12px; } 
ul, ol { list-style:none; } 
sup { vertical-align:text-top; } 
sub{ vertical-align:text-bottom; } 
legend { color:#000; } 
fieldset, img { border:0; } 
button, input, select, textarea { font-size:100%; } 
table { border-collapse:collapse; border-spacing:0;width:100%;}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, menu, nav, section { display: block; }
input,input[type="search"],button,select,option,textarea,a{ outline:none; border:0; -webkit-appearance:none;border-radius: 0; background:none;-webkit-box-sizing:border-box;box-sizing:border-box;}
/* custom */
a { text-decoration: none; -webkit-backface-visibility: hidden; color:#333; }
body,input,textarea{ -webkit-text-size-adjust: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); font-family: 'PingFang SC', 'STHeitiSC-Light', 'Helvetica-Light', arial, sans-serif, 'Droid Sans Fallback'; color:#333;}
div,section,header,footer{-webkit-box-sizing:border-box; box-sizing:border-box;}
input{line-height: normal; box-sizing:border-box;}
.fl{ float:left; }
.fr{ float:right; }
.clear{ clear:both; height: 0; line-height: 0; font-size: 0; }
.clearfix:after{ content:"."; display:block; height:0; visibility:hidden; clear:both; overflow: hidden; }
::-webkit-scrollbar {
  width:0px;
}
::-webkit-scrollbar-track {
  background-color:unset;
}

::-webkit-scrollbar-thumb {
  background-color:unset;
}

::-webkit-scrollbar-thumb:hover {
  background-color:unset;
}

::-webkit-scrollbar-thumb:active {
  background-color:unset;
}
.flex {
  display: -webkit-box;
  display: -moz-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
}
.con-cell{ display: table-cell; height: 100%; vertical-align: middle; }
.old-price{text-decoration: line-through;}

.icon {
  width: 1em; height: 1em;
  vertical-align: -0.15em;
  fill: currentColor;
  overflow: hidden;
}
@font-face {
  font-family: 'GuildfordProBook 5';
  src:url('GuildfordProBook 5.otf')
}
[v-cloak] {
  display: none;
}
.iconfont{
  font-size: .36rem;
}
/* 一像素边框 */
@media (-webkit-min-device-pixel-ratio: 1.5), (min-device-pixel-ratio: 1.5) {
  .border-1px::after {
    -webkit-transform: scaleY(0.7);
    -moz-transform: scaleY(0.7);
    -o-transform: scaleY(0.7);
    -ms-transform: scaleY(0.7);
    transform: scaleY(0.7);
  }
  .border-1px::before {
    -webkit-transform: scaleY(0.7);
    -moz-transform: scaleY(0.7);
    -o-transform: scaleY(0.7);
    -ms-transform: scaleY(0.7);
    transform: scaleY(0.7);
  }
}
@media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2) {
  .border-1px::after {
    -webkit-transform: scaleY(0.5);
    -moz-transform: scaleY(0.5);
    -o-transform: scaleY(0.5);
    -ms-transform: scaleY(0.5);
    transform: scaleY(0.5);
  }
  .border-1px::before {
    -webkit-transform: scaleY(0.5);
    -moz-transform: scaleY(0.5);
    -o-transform: scaleY(0.5);
    -ms-transform: scaleY(0.5);
    transform: scaleY(0.5);
  }
}
@media (-webkit-min-device-pixel-ratio: 3), (min-device-pixel-ratio: 3) {
  .border-1px::after {
    -webkit-transform: scaleY(0.33);
    -moz-transform: scaleY(0.33);
    -o-transform: scaleY(0.33);
    -ms-transform: scaleY(0.33);
    transform: scaleY(0.33);
  }
  .border-1px::before {
    -webkit-transform: scaleY(0.33);
    -moz-transform: scaleY(0.33);
    -o-transform: scaleY(0.33);
    -ms-transform: scaleY(0.33);
    transform: scaleY(0.33);
  }
}
.line1{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width: 100%;}
.line2{word-break:break-all;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
.mask{position:fixed;top:0;left:0;right:0;bottom:0;z-index:55;background-color:rgba(0,0,0,0.5);}





style.css

body{font-size:0.28rem;background-color:#f5f5f5;transition: background-color .3s ease;-webkit-transition: background-color .3s ease;}
/*vant-tab标签页样式修改*/
.time-tabs .van-tab{padding: 0;flex-basis: 27%!important;-webkit-flex-basis:27%!important;height:0.96rem;line-height:unset;}
.time-tabs .van-tab~.van-tab{border-left: 1px solid #e3b06e;}
.time-tabs .van-tab.van-tab--active .timeItem{background-color:#e93323;color:#fff;}
.time-tabs .van-tab.van-tab--active .timeItem:before{content: "";width: 0;height: 0;border-left: 0.08rem solid transparent;
    border-right: 0.08rem solid transparent;border-top: 0.1rem solid #e93323;position: absolute;
    bottom: -0.09rem;z-index: 99;left: 50%;transform: translateX(-50%);-webkit-transform: translateX(-50%);-ms-transform: translateX(-50%);-moz-transform: translateX(-50%);-o-transform: translateX(-50%);}
.time-tabs.van-tabs--line .van-tabs__wrap{height:1.1rem;}
.newsList .newsSwitch .van-hairline--top-bottom::after{border:0;}
.newsList .newsSwitch .van-tab{font-size:0.32rem;padding:0;flex-basis:unset!important;-webkit-flex-basis:unset!important;margin-right:0.46rem;}
.newsList .newsSwitch .van-tabs__wrap{padding: 0 0.3rem;}
#footer{position:fixed;width:100%;height:1rem;bottom:0;left:0;background-color:#fff;border-top:1px solid #eee;z-index:22;}
#footer .item{flex:1;-webkit-flex:1;-o-flex:1;-ms-flex:1;text-align:center;font-size:0.2rem;color:#282828;}
#footer .item.on{color:#fc4141;}
#footer .item .iconfont{font-size:0.45rem;height: 0.55rem;line-height: 0.55rem;}
.goodList .item{position:relative;padding-left:0.3rem;background-color:#fff;}
.goodList .item .pictrue{width:1.8rem;height:1.8rem;position:relative;}
.goodList .item .pictrue .image{width:100%;height:100%;border-radius:0.06rem;}
.goodList .item .pictrue .numPic{position:absolute;left:0.07rem;top:0.07rem;width:0.5rem;height:0.5rem;border-radius:50%;}
.goodList .item .underline{padding:0.3rem 0.3rem 0.3rem 0;border-bottom:1px solid #f5f5f5;}
.goodList .item:nth-last-child(1) .underline{border-bottom:0;}
.goodList .item .text{font-size:0.3rem;color:#222;width:4.89rem;text-align: left;}
.goodList .item .text .money{font-size:0.26rem;font-weight:bold;margin-top:0.5rem;}
.goodList .item .text .money .num{font-size:0.34rem;}
.goodList .item .text .vip-money{font-size:0.24rem;color:#282828;font-weight:bold;margin-top:0.1rem;}
.goodList .item .text .vip-money .vip{margin-right:0.22rem;}
.goodList .item .text .vip-money .image{width:0.46rem;height:0.21rem;margin-left:0.05rem;}
.goodList .item .text .vip-money .num{font-size:0.22rem;color:#aaa;font-weight:normal;margin:-0.02rem 0 0 0;}
.goodList .item .iconfont{position:absolute;right:0.3rem;width:0.5rem;height:0.5rem;border-radius:50%;font-size:0.3rem;bottom:0.38rem;}
.promotionGood{padding:0 0.3rem;background-color: #fff;}
.promotionGood .item{border-bottom:1px solid #eee;height:2.5rem;}
.promotionGood .item .pictrue{width:1.88rem;height:1.88rem;}
.promotionGood .item .pictrue .image{width:100%;height:100%;border-radius:0.08rem;}
.promotionGood .item .text{font-size:0.24rem;color:#999;width:4.72rem;text-align:left;}
.promotionGood .item .text .name{font-size:0.3rem;color:#333;}
.promotionGood .item .text .sp-money{margin:0.34rem 0 0.2rem 0;}
.promotionGood .item .text .sp-money .moneyCon{padding:0 0.18rem;background-color:red;height:0.46rem;line-height:0.46rem;
    background-image:linear-gradient(to right,#ff6248 0%,#ff3e1e 100%);font-size:0.2rem;color:#fff;
   background-image: -webkit-linear-gradient(to right,#ff6248 0%,#ff3e1e 100%);
   background-image: -moz-linear-gradient(to right,#ff6248 0%,#ff3e1e 100%);
    border-radius:0.24rem 0.03rem 0.24rem 0.03rem;}
.promotionGood .item .text .sp-money .moneyCon .num{font-size:0.24rem;}
.promotionGood .item .text .money{text-decoration:line-through;}
.recommend{background-color:#fff;}
.recommend .title{height:1.35rem;font-size:0.28rem;color:#282828;}
.recommend .title .name{margin:0 0.28rem;}
.recommend .title .iconfont{font-size:1.7rem;color:#454545;height:0.5rem;line-height:0.5rem;}
.recommend .title .iconfont.lefticon{transform:rotate(180deg);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);-moz-transform:rotate(180deg);-o-transform:rotate(180deg);}
.recommend .recommendList{padding:0 0.3rem;}
.recommend .recommendList .item{width:3.35rem;margin-bottom:0.3rem;}
.recommend .recommendList .item .pictrue{width:100%;height:3.35rem;}
.recommend .recommendList .item .pictrue .image{width:100%;height:100%;border-radius:0.06rem;}
.recommend .recommendList .item .name{font-size:0.28rem;color:#282828;margin-top:0.2rem;}
.recommend .recommendList .item .money{font-size:0.2rem;margin-top:0.03rem;}
.recommend .recommendList .item .money .num{font-size:0.28rem;}
.noCommodity{padding-top: 0.75rem;}
.noCommodity .noPictrue{width:4.14rem;height:3.36rem;margin:0 auto 0.3rem auto;}
.noCommodity .noPictrue .image{width:100%;height:100%;}
/*产品详情轮播*/
.product-bg{height:7.5rem;}
.product-bg .slide-image{width:100%;height:100%;}
.product-bg .pages{position:absolute;background-color:#fff;height:0.34rem;padding:0 0.1rem;border-radius:0.03rem;
    right:0.3rem;bottom:0.3rem;line-height:0.34rem;font-size:0.24rem;color:#050505;z-index:9;}
/*评价列表公共*/
.evaluateWtapper .evaluateItem{background-color:#fff;padding-bottom:0.25rem;}
.evaluateWtapper .evaluateItem~.evaluateItem{border-top:1px solid #f5f5f5;}
.evaluateWtapper .evaluateItem .pic-text{font-size:0.26rem;color:#282828;height:0.95rem;padding:0 0.3rem;}
.evaluateWtapper .evaluateItem .pic-text .pictrue{width:0.56rem;height:0.56rem;margin-right:0.2rem;}
.evaluateWtapper .evaluateItem .pic-text .pictrue .image{width:100%;height:100%;border-radius:50%;}
.evaluateWtapper .evaluateItem .pic-text .name{max-width:4.5rem;margin-right:0.15rem;}
.evaluateWtapper .evaluateItem .time{font-size:0.24rem;color:#82848f;padding:0 0.3rem;}
.evaluateWtapper .evaluateItem .evaluate-infor{font-size:0.28rem;color:#282828;margin-top:0.19rem;padding:0 0.3rem;}
.evaluateWtapper .evaluateItem .imgList{padding:0 0.3rem 0 0.15rem;margin-top:0.25rem;}
.evaluateWtapper .evaluateItem .imgList .pictrue{width:1.56rem;height:1.56rem;margin:0 0 0.15rem 0.15rem;}
.evaluateWtapper .evaluateItem .imgList .pictrue .image{width:100%;height:100%;}
.evaluateWtapper .evaluateItem .reply{font-size:0.26rem;color:#454545;background-color:#f7f7f7;border-radius:0.05rem;
    margin:0.2rem 0.3rem 0 0.3rem;padding:0.3rem;position:relative;}
.evaluateWtapper .evaluateItem .reply::before{content:"";width: 0;height: 0;border-left:0.1rem solid transparent;
    border-right:0.1rem solid transparent;border-bottom:0.2rem solid #f7f7f7;position:absolute;top:-0.2rem;left:1rem;}
/*优惠券列表公共*/
.coupon-list{padding:0 0.3rem;margin-top:0.25rem;}
.coupon-list .item{width:100%;height:1.7rem;margin-bottom:0.16rem;}
.coupon-list .item .money{background-image:url('../images/coupon1.png');background-repeat:no-repeat;background-size:100% 100%;
    width:2.4rem;height:100%;color:#fff;font-size:0.36rem;font-weight:bold;text-align:center;line-height:1.7rem;}
.coupon-list .item .money.moneyGray{background-image:url('../images/coupon2.png');}
.coupon-list .item .money .num{font-size:0.6rem;}
.coupon-list .item .text{width:4.5rem;padding:0 0.17rem 0 0.24rem;background-color:#fff;}
.coupon-list .item .text .condition{font-size:0.3rem;color:#282828;height:0.93rem;line-height:0.93rem;
    border-bottom:1px solid #f0f0f0;}
.coupon-list .item .text .data{font-size:0.2rem;color:#999;height:0.76rem;}
.coupon-list .item .text .data .bnt{width:1.36rem;height:0.44rem;border-radius:0.22rem;font-size:0.22rem;color:#fff;text-align:center;line-height:0.44rem;}
.coupon-list .item .text .data .bnt.gray{background-color:#ccc;}
/*优惠券列表弹窗*/
.coupon-list-window{position:fixed;bottom:0;left:0;width:100%;background-color:#f5f5f5;border-radius:0.16rem 0.16rem 0 0;z-index:111;transition:all .3s cubic-bezier(.25,.5,.5,.9);-webkit-transition:all .3s cubic-bezier(.25,.5,.5,.9);-moz-transition:all .3s cubic-bezier(.25,.5,.5,.9);-o-transition:all .3s cubic-bezier(.25,.5,.5,.9);transform:translate3d(0,100%,0);
-webkit-transform:translate3d(0,100%,0);-ms-transform:translate3d(0,100%,0);-moz-transform:translate3d(0,100%,0);
-o-transform:translate3d(0,100%,0);}
.coupon-list-window.on{transform:translate3d(0,0,0);-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);}
.coupon-list-window .title{height:1.24rem;width:100%;text-align:center;line-height:1.24rem;font-size:0.32rem;
    font-weight:bold;position:relative;color: #333;}
.coupon-list-window .title .iconfont{position:absolute;right:0.3rem;top:50%;transform:translateY(-50%);font-size:0.35rem;
    color:#8a8a8a;font-weight:normal;}
.coupon-list-window .coupon-list{margin:0 0 0.5rem 0;height:5.5rem;overflow:auto;}
.coupon-list-window .pictrue{width:4.14rem;height:3.36rem;margin:0 auto 0.5rem auto;}
.coupon-list-window .pictrue .image{width:100%;height:100%;}
/*详情首页弹窗*/
.product-window{position:fixed;bottom:0;width:100%;left:0;background-color:#fff;z-index:88;border-radius:0.16rem 0.16rem 0 0;
    padding-bottom:1.4rem;transform:translate3d(0,100%,0);-webkit-transform:translate3d(0,100%,0);-ms-transform:translate3d(0,100%,0);-moz-transform:translate3d(0,100%,0);
    -o-transform:translate3d(0,100%,0);transition:all .3s cubic-bezier(.25,.5,.5,.9);-webkit-transition:all .3s cubic-bezier(.25,.5,.5,.9);-moz-transition:all .3s cubic-bezier(.25,.5,.5,.9);-o-transition:all .3s cubic-bezier(.25,.5,.5,.9);}
.product-window.on{transform:translate3d(0,0,0);-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);}
.product-window .textpic{padding:0 1.3rem 0 0.3rem;margin-top:0.29rem;position:relative;}
.product-window .textpic .pictrue{width:1.5rem;height:1.5rem;}
.product-window .textpic .pictrue .image{width:100%;height:100%;border-radius:0.1rem;}
.product-window .textpic .text{width:4.1rem;font-size:0.32rem;color:#202020;}
.product-window .textpic .text .money{font-size:0.24rem;margin-top:0.4rem;}
.product-window .textpic .text .money .num{font-size:0.36rem;}
.product-window .textpic .text .money .stock{color:#999;margin-left:0.18rem;}
.product-window .textpic .iconfont{position:absolute;right:0.3rem;top:-0.05rem;font-size:0.35rem;color:#8a8a8a;}
.product-window .productWinList{max-height:3.95rem;overflow:auto;margin-top:0.36rem;}
.product-window .productWinList .item~.item{margin-top:0.36rem;}
.product-window .productWinList .item .title{font-size:0.3rem;color:#999;padding:0 0.3rem;}
.product-window .productWinList .item .listn{padding:0 0.3rem 0 0.16rem;}
.product-window .productWinList .item .listn .itemn{border:1px solid #bbb;font-size:0.26rem;color:#282828;
    padding:0.07rem 0.33rem;border-radius:0.06rem;margin:0.14rem 0 0 0.14rem;}
.product-window .productWinList .item .listn .itemn.on{color:#fff;background-color:#ff3700;border-color:#ff3700;}
.product-window .cart{margin-top:0.36rem;padding:0 0.3rem;}
.product-window .cart .title{font-size:0.3rem;color:#999;}
.product-window .cart .carnum{height:0.54rem;margin-top:0.24rem;}
.product-window .cart .carnum .item{border:1px solid #a4a4a4;width:0.84rem;text-align:center;height:100%;line-height:0.54rem;
    color:#a4a4a4;font-size:0.45rem;}
.product-window .cart .carnum .reduce{border-right:0;border-radius:0.06rem 0 0 0.06rem;line-height:0.48rem;}
.product-window .cart .carnum .reduce.on{border-color:#e3e3e3;color:#dedede;}
.product-window .cart .carnum .plus{border-left:0;border-radius:0 0.06rem 0.06rem 0;line-height:0.46rem;}
.product-window .cart .carnum .plus.on{border-color:#e3e3e3;color:#dedede;}
.product-window .cart .carnum .num{color:#282828;font-size:0.28rem;}
/*产品详情的分享红包*/
.sharing-packets{position:fixed;left:0.3rem;bottom:1.5rem;z-index:5;transition:all 0.3s ease-in-out 0s;-webkit-transition:all 0.3s ease-in-out 0s;-moz-transition:all 0.3s ease-in-out 0s;-o-transition:all 0.3s ease-in-out 0s;opacity:1;
    transform: scale(1);-webkit-transform: scale(1);-moz-transform: scale(1);-o-transform: scale(1);-ms-transform: scale(1);}
.sharing-packets.on{transform: scale(0);-webkit-transform: scale(0);-moz-transform: scale(0);-o-transform: scale(0);-ms-transform: scale(0);opacity:0;}
.sharing-packets .iconfont{width:0.44rem;height:0.44rem;border-radius:50%;background-color:#999;font-size:0.2rem;color:#fff;margin:0 auto;padding-left:0.01rem;}
.sharing-packets .line{width:0.02rem;height:0.4rem;background-color:#999;margin:0 auto;}
.sharing-packets .sharing-con{width:1.87rem;height:2.1rem;position:relative;}
.sharing-packets .sharing-con .image{width:100%;height:100%;}
.sharing-packets .sharing-con .text{position:absolute;top:0.2rem;font-size:0.2rem;width:100%;text-align:center;}
.sharing-packets .sharing-con .text .money{font-size:0.32rem;font-weight:bold;}
.sharing-packets .sharing-con .text .money .label{font-size:0.2rem;}
.sharing-packets .sharing-con .text .tip{font-size:0.18rem;color:#999;}
.sharing-packets .sharing-con .text .shareBut{font-size:0.22rem;color:#fff;margin-top:0.27rem;height:0.5rem;
    line-height:0.5rem;}
/*订单产品*/
.orderGoods{background-color:#fff;margin-top:0.12rem;}
.orderGoods .total{width:100%;height:0.86rem;padding:0 0.3rem;border-bottom:0.01rem solid #eee;font-size:0.3rem;color:#282828;line-height:0.86rem;}
.goodWrapper .item{margin-left:0.3rem;padding-right:0.3rem;border-bottom:0.02rem solid #f0f0f0;height:1.8rem;}
.goodWrapper .item .pictrue{width:1.3rem;height:1.3rem;}
.goodWrapper .item .pictrue .image{width:100%;height:100%;border-radius:0.06rem;}
.goodWrapper .item .text{width:5.37rem;position:relative;}
.goodWrapper .item .text .name{font-size:0.28rem;color:#282828;width:4.53rem;}
.goodWrapper .item .text .num{font-size:0.26rem;color:#868686;}
.goodWrapper .item .text .attr{font-size:0.2rem;color:#868686;margin-top:0.07rem;}
.goodWrapper .item .text .money{font-size:0.26rem;margin-top:0.17rem;}
.goodWrapper .item .text .evaluate{position:absolute;width:1.14rem;height:0.46rem;border:1px solid #e93323; color: #e93323;
    border-radius:0.04rem;text-align:center;line-height:0.46rem;right:0;bottom:-.1rem;}
.goodWrapper .item .text .evaluate.userEvaluated{font-size:0.26rem;color:#aaa;background-color:#f7f7f7;border-color:#f7f7f7;}
/*地址弹窗*/
.address-window{background-color:#fff;position:fixed;bottom:0;left:0;width:100%;z-index:99;transform:translate3d(0,100%,0);-webkit-transform:translate3d(0,100%,0);-ms-transform:translate3d(0,100%,0);-moz-transform:translate3d(0,100%,0);
    -o-transform:translate3d(0,100%,0);transition:all .3s cubic-bezier(.25,.5,.5,.9);
    -webkit-transition:all .3s cubic-bezier(.25,.5,.5,.9);-moz-transition:all .3s cubic-bezier(.25,.5,.5,.9);
    -o-transition:all .3s cubic-bezier(.25,.5,.5,.9);}
.address-window.on{transform:translate3d(0,0,0);-webkit-transform:translate3d(0,0,0);
    -ms-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);}
.address-window .title{font-size:0.32rem;font-weight:bold;text-align:center;height:1.23rem;line-height:1.23rem;
    position:relative;color: #333;}
.address-window .title .iconfont{position:absolute;right:0.3rem;color:#8a8a8a;font-size:0.35rem;}
.address-window .list{max-height:6rem;overflow-y:auto;overflow-x:hidden;}
.address-window .list .item{margin-left:0.3rem;padding-right:0.3rem;border-bottom:1px solid #eee;height:1.29rem;
    font-size:0.25rem;color:#333;}
.address-window .list .item .iconfont{font-size:0.37rem;color:#2c2c2c;}
.address-window .list .item .iconfont.icon-complete{font-size:0.3rem;color:#fff;}
.address-window .list .item .addressTxt{width:5.6rem;}
.address-window .list .item .addressTxt .name{font-size:0.28rem;font-weight:bold;color:#282828;margin-bottom:0.04rem;}
.address-window .list .item .addressTxt .name .phone{margin-left:0.18rem;}
.address-window .addressBnt{font-size:0.3rem;font-weight:bold;color:#fff;width:6.9rem;height:0.86rem;border-radius:0.43rem;
    text-align:center;line-height:0.86rem;margin:0.85rem auto;}
.address-window .pictrue{width:4.14rem;height:3.36rem;margin:0.8rem auto;}
.address-window .pictrue .image{width:100%;height:100%;}
/*轮播图*/
.swiper{height:2.82rem;}
.swiper .slide-image{width:100%;height:100%;}
.swiper .swiper-pagination{text-align:right;padding-right:0.4rem;bottom:0.1rem;width:100%;}
.swiper .swiper-pagination-bullet{width:0.12rem;height:0.12rem;border:0.02rem solid #fff;border-radius:50%;background-color:rgba(0,0,0,0);opacity:1;}
.swiper .swiper-pagination-bullet~.swiper-pagination-bullet{margin-left:0.12rem;}
.swiper .swiper-pagination-bullet-active{border-color:#e93323;background-color:#e93323;}
/**/
.goodsStyle{background-color:#fff;padding:0.22rem 0.3rem;}
.goodsStyle .pictrue{width:1.2rem;height:1.2rem;}
.goodsStyle .pictrue .image{width:100%;height:100%;border-radius:0.06rem;}
.goodsStyle .text{width:5.45rem;font-size:0.28rem;color:#999;}
.goodsStyle .text .name{width:3.6rem;color:#282828;}
.goodsStyle .text .money{text-align:right;}
.goodsStyle .text .money .num{margin-top:0.07rem;}
/*所有推广头部样式*/
.promoterHeader{width:100%;height:2.2rem;}
.promoterHeader .headerCon{width:100%;height:100%;padding:0 0.88rem 0 0.55rem;font-size:0.28rem;color:#fff;background-image:url('../images/transparent.png');background-repeat:no-repeat;background-size:100% 100%;}
.promoterHeader .headerCon .name{margin-bottom:0.02rem;}
.promoterHeader .headerCon .num{font-size:0.5rem;}
.promoterHeader .headerCon .iconfont{font-size:1.25rem;}
/*首页优惠券弹窗*/
.coupon-window{background-image:url('../images/coupon-window.png');background-repeat:no-repeat;background-size:100% 100%;width:6.3rem;height:6.49rem;position:fixed;top:20%;z-index:99;left:50%;margin-left:-3.05rem;transform:translate3d(0,-200%,0);-webkit-transform:translate3d(0,-200%,0);-ms-transform:translate3d(0,-200%,0);-moz-transform:translate3d(0,-200%,0);-o-transform:translate3d(0,-200%,0);transition:all .3s cubic-bezier(.25,.5,.5,.9);-webkit-transition:all .3s cubic-bezier(.25,.5,.5,.9);-moz-transition:all .3s cubic-bezier(.25,.5,.5,.9);-o-transition:all .3s cubic-bezier(.25,.5,.5,.9);}
.coupon-window.on{transform:translate3d(0,0,0);-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);}
.coupon-window .couponWinList{width:4.8rem;margin:1.57rem 0 0 0.6rem;height:4.15rem;overflow:auto;}
.coupon-window .couponWinList .item{width:100%;height:1.2rem;background-color:#fff;position:relative;margin-bottom:0.17rem;}
.coupon-window .couponWinList .item::after{content:'';position: absolute;width:0.18rem;height: 0.18rem;border-radius: 50%;background-color: #f2443a;left:25.5%;bottom:0;margin-bottom:-0.09rem;}
.coupon-window .couponWinList .item::before{content:'';position: absolute;width:0.18rem;height: 0.18rem;border-radius: 50%;background-color: #f2443a;left:25.5%;top:0;margin-top:-0.09rem;}
.coupon-window .couponWinList .item .money{width:1.3rem;border-right:1px dashed #ddd;height:100%;text-align:center;line-height:1.2rem;font-size:0.26rem;font-weight:bold;}
.coupon-window .couponWinList .item .money .num{font-size:0.4rem;}
.coupon-window .couponWinList .item .text{width:3.49rem;font-size:0.22rem;color:#999;padding:0 0.29rem;}
.coupon-window .couponWinList .item .text .name{font-size:0.26rem;color:#282828;font-weight:bold;margin-bottom:0.09rem;}
.coupon-window .lid{background-image:url('../images/coupon-window2.png');background-repeat:no-repeat;background-size:100% 100%;width:5.73rem;height:2.24rem;position:fixed;left:50%;top:20%;margin:4.24rem 0 0 -2.96rem;}
.coupon-window .lid .bnt{font-size:0.29rem;width:4.4rem;height:0.8rem;border-radius:0.4rem;background-color:#f9f1d3;text-align:center;line-height:0.8rem;font-weight:bold;margin:0.98rem auto 0 auto;}
.coupon-window .lid .iconfont{color:#fff;font-size:0.6rem;text-align:center;margin-top:0.87rem;}
/*首页*/
.index .header{height:0.98rem;width:100%;}
.index .header .logo{width:1.27rem;height:0.45rem;margin-right:0.25rem;}
.index .header .logo img{width:100%;height:100%;display:block;}
.index .header .search{width:5rem;height:0.64rem;background-color:#f7f7f7;border-radius:0.5rem;padding:0 0.28rem;
    font-size:0.28rem;color:#bbb;}
.index .header  .search .iconfont{font-size:0.34rem;margin-right:0.16rem;}
.index .banner{height:3.75rem;}
.index .banner img{width:100%;height:100%;}
.index .banner .swiper-pagination{bottom:0.07rem;}
.index .banner .swiper-pagination-bullet{width:0.2rem;height:0.04rem;border-radius:0.03rem;
    background-color:#fff;opacity:0.6;}
.index .banner .swiper-pagination-bullet-active{opacity:1;}
.index .nav{padding-top:0.26rem;}
.index .nav .item{width:25%;text-align:center;font-size:0.26rem;margin-bottom:0.35rem;}
.index .nav .item .pictrue{width:0.9rem;height:0.9rem;margin:0 auto 0.15rem auto;}
.index .nav .item .pictrue img{width:100%;height:100%;border-radius:50%;}
.index .news{height:0.77rem;border-top:1px solid #f4f4f4;padding:0 0.3rem;box-shadow:0 0.1rem 0.3rem #f5f5f5;
-webkit-box-shadow:0 0.1rem 0.3rem #f5f5f5;-moz-box-shadow:0 0.1rem 0.3rem #f5f5f5;-o-box-shadow:0 0.1rem 0.3rem #f5f5f5;}
.index .news .pictrue{width:1.24rem;height:0.28rem;border-right:1px solid #ddd;padding-right:0.23rem;box-sizing:content-box;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;}
.index .news .pictrue img{width:100%;height:100%;display:block;}
.index .news .new-banner{width:5.23rem;overflow:hidden;height:0.77rem;}
.index .news .new-banner .swiper-slide{height:100%;}
.index .news .new-banner .text{width:4.8rem;height:0.77rem;}
.index .news .new-banner .text .label{font-size:0.2rem;color:#ff4c48;width:0.68rem;height:0.34rem;border-radius:0.2rem;
    text-align:center;line-height:0.34rem;border:0.02rem solid #ff4947;}
.index .news .new-banner .text .newsTitle{width:3.97rem;font-size:0.24rem;color:#666;}
.index .news .new-banner .iconfont{font-size:0.28rem;color:#888;}
.index .specialArea{padding:0.3rem;}
.index .specialArea .assemble{width:2.6rem;height:2.6rem;position:relative;}
.index .specialArea .assemble img{width:100%;height:100%;border-radius:0.05rem;}
.index .specialArea .assemble .text{position:absolute;top:0.37rem;left:0.22rem;}
.index .specialArea .name{font-size:0.3rem;color:#fff;}
.index .specialArea .infor{font-size:0.22rem;color:rgba(255, 255, 255, 0.8);margin-top:0.05rem;}
.index .specialArea .list{height:2.6rem;width:4.16rem;}
.index .specialArea .item{width:100%;height:1.24rem;position:relative;}
.index .specialArea .item img{width:100%;height:100%;}
.index .specialArea .item .text{position:absolute;top:0.23rem;left:0.28rem;}
.index .wrapper .title{border-top:1px solid #eee;padding-top:0.34rem;margin:0 0.3rem;}
.index .wrapper .title .text{font-size:0.24rem;color:#999;width:5.3rem;text-align: left;}
.index .wrapper .title .text .name{color:#282828;font-size:0.3rem;font-weight:bold;margin-bottom:0.05rem;position:relative;}
.index .wrapper .title .text .name .new{position:absolute;top:0.02rem;left:1.3rem;font-size:0.16rem;font-weight:bold;}
.index .wrapper .title .more{font-size:0.26rem;color:#333;}
.index .wrapper .title .more .iconfont{margin-left:0.02rem;font-size:0.26rem;}
.index .wrapper .scroll-product{white-space:nowrap;margin-top:0.38rem;padding:0 0.3rem 0.37rem 0.3rem;overflow:hidden;}
.index .wrapper .scroll-product .swiper-slide{width:1.8rem;display:inline-block;margin-right:0.19rem;
    border-bottom:0.04rem solid #47b479;box-shadow:0 0.15rem 0.15rem -0.1rem #eee;
    -webkit-box-shadow:0 0.15rem 0.15rem -0.1rem #eee;-moz-box-shadow:0 0.15rem 0.15rem -0.1rem #eee;-o-box-shadow:0 0.15rem 0.15rem -0.1rem #eee;}
.index .wrapper .scroll-product .swiper-slide:nth-of-type(3n){border-bottom:0.04rem solid #ff6960;}
.index .wrapper .scroll-product .swiper-slide:nth-of-type(3n-1){border-bottom:0.04rem solid #579afe;}
.index .wrapper .scroll-product .swiper-slide:nth-last-child(1){margin-right:0;}
.index .wrapper .scroll-product .swiper-slide .img-box{width:100%;height:1.8rem;}
.index .wrapper .scroll-product .swiper-slide .img-box img{width:100%;height:100%;border-radius:0.06rem 0.06rem 0 0;}
.index .wrapper .scroll-product .swiper-slide .pro-info{font-size:0.24rem;color:#282828;text-align:center;height:0.6rem;
    line-height:0.6rem;border:1px solid #f5f5f5;border-bottom:0;border-top:0;padding:0 0.1rem;}.index .wrapper .boutique{width:6.9rem;height:2.9rem;margin:0.28rem auto 0 auto;}
.index .wrapper .boutique{width:6.9rem;height:2.9rem;margin:0.28rem auto 0 auto;}
.index .wrapper .boutique img{width:100%;height:2.6rem;}
.index .wrapper .boutique .swiper-pagination{bottom:-0.08rem;width:100%;}
.index .wrapper .boutique .swiper-pagination-bullet{width:0.07rem;height:0.07rem;border-radius:50%;
    background-color:#fc4141;opacity:0.3;}
.index .wrapper .boutique .swiper-pagination-bullet~ .swiper-pagination-bullet{margin-left:0.1rem;}
.index .wrapper .boutique .swiper-pagination-bullet-active{width:0.2rem;height:0.07rem;border-radius:0.035rem;opacity:1}
.index .hotList .hot-bg{width:100%;height:2.15rem;background-image:url('../images/index-bg.png');background-repeat:no-repeat;
    background-size:100% 100%;padding:0 0.3rem;font-size:0.24rem;color:#fff;margin-top:0.15rem;}
.index .hotList .hot-bg .title{height:0.87rem;}
.index .hotList .hot-bg .title .text{width:5.75rem;}
.index .hotList .hot-bg .title .text .label{font-size:0.3rem;font-weight:bold;margin-right:0.2rem;}
.index .hotList .hot-bg .title .more{font-size:0.26rem;color:#fff;}
.index .hotList .hot-bg .title .more .iconfont{font-size:0.25rem;vertical-align:0.02rem;margin-left:0.1rem;}
.index .hotList .list{width:6.9rem;height:3.3rem;border-radius:0.2rem;background-color:#fff;margin:-1.28rem auto 0 auto;
    padding:0 0.22rem;box-shadow: 0 0 0.2rem -0.1rem #aaa;-moz-box-shadow:0 0 0.2rem -0.1rem #aaa;
    -webkit-box-shadow:0 0 0.2rem -0.1rem #aaa;-o-box-shadow:0 0 0.2rem -0.1rem #aaa;}
.index .hotList .list .item{width:2rem;text-align: left;}
.index .hotList .list .item~.item{margin-left:0.23rem;}
.index .hotList .list .item .pictrue{width:100%;height:2rem;position:relative;}
.index .hotList .list .item .pictrue img{width:100%;height:100%;border-radius:0.1rem;}
.index .hotList .list .item .pictrue .numPic{width:0.5rem;height:0.5rem;border-radius:50%;position:absolute;top:0.07rem;
    left:0.07rem;}
.index .hotList .list .item .name{font-size:0.26rem;color:#282828;margin-top:0.12rem;}
.index .hotList .list .item .money{font-size:0.2rem;font-weight:bold;margin-top: 0.02rem;}
.index .hotList .list .item .money .num{font-size:0.28rem;}
.index .adver{width:100%;height:1.8rem;margin-top:0.37rem;}
.index .adver img{width:100%;height:100%;display:block;}
.index .wrapper .newProducts{white-space:nowrap;padding:0 0.3rem;margin:0.35rem 0 0.42rem 0;overflow:hidden;}
.index .wrapper .newProducts .swiper-slide{display:inline-block;width:2.43rem;margin-right:0.2rem;border:1px solid #eee;
    border-radius:0.12rem;}
.index .wrapper .newProducts .swiper-slide:nth-last-child(1){margin-right:0;}
.index .wrapper .newProducts .swiper-slide .img-box{width:100%;height:2.4rem;}
.index .wrapper .newProducts .swiper-slide .img-box img{width:100%;height:100%;border-radius:0.12rem 0.12rem 0 0;}
.index .wrapper .newProducts .swiper-slide .pro-info{font-size:0.28rem;color:#333;text-align:center;padding:0.15rem 0.1rem 0 0.1rem;}
.index .wrapper .newProducts .swiper-slide .money{padding:0 0.1rem 0.18rem 0.1rem;text-align:center;font-size:0.26rem;font-weight:bold;}
/*商品列表*/
.productList .search{width:100%;height:0.86rem;padding-left:0.23rem;position:fixed;left:0;top:0;z-index:5;}
.productList .search .input{width:6.4rem;height:0.6rem;background-color:#fff;border-radius:0.5rem;padding:0 0.2rem;}
.productList .search .input input{width:5.48rem;height:100%;font-size:0.26rem;}
.productList .search .input input::placeholder{color:#999;}
.productList .search .input .iconfont{font-size:0.35rem;color:#555;}
.productList .search .icon-pailie,.productList .search .icon-tupianpailie{margin: 0 auto;color:#fff;width:0.4rem;font-size:0.4rem;
    height:0.86rem;line-height:0.86rem;}
.productList .nav{height:0.86rem;color:#454545;position:fixed;left:0;width:100%;font-size:0.28rem;background-color:#fff;
    top: 0.86rem;z-index:5;}
.productList .nav .item{width:25%;text-align:center;}
.productList .nav .item.font-color{font-weight:bold;}
.productList .nav .item img{width:0.15rem;height:0.19rem;margin-left:0.1rem;}
.productList .list{padding:0 0.2rem;margin-top:1.72rem;}
.productList .list.on{background-color:#fff;border-top:1px solid #f6f6f6;}
.productList .list .item{width:3.45rem;margin-top:0.2rem;background-color:#fff;border-radius:0.1rem;}
.productList .list .item.on{width:100%;display:flex;display:-webkit-flex;display:-webkit-box;border-bottom:1px solid #f6f6f6;padding:0.3rem 0;
    margin:0;}
.productList .list .item .pictrue{width:100%;height:3.45rem;}
.productList .list .item .pictrue.on{width:1.8rem;height:1.8rem;}
.productList .list .item .pictrue img{width:100%;height:100%;border-radius:0.1rem 0.1rem 0 0;}
.productList .list .item .pictrue img.on{border-radius:0.06rem;}
.productList .list .item .text{padding:0.2rem 0.17rem 0.26rem 0.17rem;font-size:0.3rem;color:#222;text-align: left;}
.productList .list .item .text.on{width:5.08rem;padding:0 0 0 0.22rem;}
.productList .list .item .text .money{font-size:0.26rem;font-weight:bold;margin-top:0.08rem;}
.productList .list .item .text .money.on{margin-top:0.4rem;}
.productList .list .item .text .money .num{font-size:0.34rem;}
.productList .list .item .text .vip{font-size:0.22rem;color:#aaa;margin-top:0.07rem;}
.productList .list .item .text .vip.on{margin-top:0.11rem;}
.productList .list .item .text .vip .vip-money{font-size:0.24rem;color:#282828;font-weight:bold;}
.productList .list .item .text .vip .vip-money img{width:0.46rem;height:0.21rem;margin-left:0.04rem;}
/*购物车*/
.shoppingCart .labelNav{height:0.76rem;padding:0 0.3rem;font-size:0.22rem;color:#8c8c8c;position:fixed;left:0;width:100%;
background-color:#f5f5f5;z-index:5;top: 0;}
.shoppingCart .labelNav .item .iconfont{font-size:0.25rem;margin-right:0.1rem;}
.shoppingCart .nav{width:100%;height:0.8rem;background-color:#fff;padding:0 0.3rem;font-size:0.28rem;color:#282828;
    position:fixed;left:0;z-index:5;top:0.76rem;border-bottom: 1px solid #f5f5f5;}
.shoppingCart .nav .administrate{font-size:0.26rem;color:#282828;width:1.1rem;height:0.46rem;border-radius:0.06rem;
    border:1px solid #868686;}
.shoppingCart .noCart{margin-top:1.71rem;background-color:#fff;padding: 0.78rem 0 0.56rem 0;}
.shoppingCart .noCart .pictrue{width:4.14rem;height:3.36rem;margin:0 auto;}
.shoppingCart .noCart .pictrue img{width:100%;height:100%;}
.shoppingCart .list{margin-top:1.71rem;}
.shoppingCart .list .item{padding:0.25rem 0.3rem;background-color:#fff;margin-bottom:0.15rem;}
.shoppingCart .list .item .picTxt{width:6.27rem;position:relative;}
.shoppingCart .list .item .picTxt .pictrue{width:1.6rem;height:1.6rem;}
.shoppingCart .list .item .picTxt .pictrue img{width:100%;height:100%;border-radius:0.06rem;}
.shoppingCart .list .item .picTxt .text{width:4.44rem;font-size:0.28rem;color:#282828;text-align:left;}
.shoppingCart .list .item .picTxt .text .infor{font-size:0.24rem;color:#868686;margin-top:0.16rem;}
.shoppingCart .list .item .picTxt .text .money{font-size:0.32rem;color:#282828;margin-top:0.26rem;}
.shoppingCart .list .item .picTxt .carnum{height:0.44rem;position:absolute;bottom:0.07rem;right:0;}
.shoppingCart .list .item .picTxt .carnum div{border:1px solid #a4a4a4;width:0.66rem;text-align:center;height:100%;
    line-height:0.44rem;font-size:0.28rem;color:#a4a4a4;}
.shoppingCart .list .item .picTxt .carnum .reduce{border-right:0;border-radius:0.03rem 0 0 0.03rem;line-height:0.39rem;}
.shoppingCart .list .item .picTxt .carnum .reduce.on{border-color:#e3e3e3;color:#dedede;}
.shoppingCart .list .item .picTxt .carnum .plus{border-left:0;border-radius:0 0.03rem 0.03rem 0;line-height:0.38rem;}
.shoppingCart .list .item .picTxt .carnum .num{color:#282828;}
.shoppingCart .invalidGoods{background-color:#fff;}
.shoppingCart .invalidGoods .goodsNav{width:100%;height:0.66rem;padding:0 0.3rem;font-size:0.28rem;color:#282828;}
.shoppingCart .invalidGoods .goodsNav .iconfont{color:#424242;font-size:0.28rem;margin-right:0.17rem;}
.shoppingCart .invalidGoods .goodsNav .del{font-size:0.26rem;color:#999;}
.shoppingCart .invalidGoods .goodsNav .del .icon-shanchu1{color:#999;font-size:0.33rem;vertical-align:-0.02rem;
    margin-right:0.08rem;}
.shoppingCart .invalidGoods .goodsList .item{padding:0.2rem 0.3rem;border-top:1px solid #f5f5f5;}
.shoppingCart .invalidGoods .goodsList .item .invalid{font-size:0.22rem;color:#fff;width:0.7rem;height:0.36rem;background-color:#aaa;border-radius:0.03rem;}
.shoppingCart .invalidGoods .goodsList .item .pictrue{width:1.4rem;height:1.4rem;}
.shoppingCart .invalidGoods .goodsList .item .pictrue img{width:100%;height:100%;border-radius:0.06rem;}
.shoppingCart .invalidGoods .goodsList .item .text{width:4.33rem;font-size:0.28rem;color:#999;height:1.4rem;text-align:left;}
.shoppingCart .invalidGoods .goodsList .item .text .infor{font-size:0.24rem;}
.shoppingCart .invalidGoods .goodsList .item .text .end{font-size:0.26rem;color:#bbb;}
.shoppingCart .footer{width:100%;height:0.96rem;background-color:#fafafa;position:fixed;bottom:1rem;padding:0 0.3rem;border-top:1px solid #eee;}
.shoppingCart .footer .checkAll{font-size:0.28rem;color:#282828;margin-left:0.6rem;}
.shoppingCart .footer .money{font-size:0.3rem;}
.shoppingCart .footer .placeOrder{color:#fff;font-size:0.3rem;width:2.26rem;height:0.7rem;border-radius:0.5rem;
    text-align:center;line-height:0.7rem;margin-left:0.22rem;}
.shoppingCart .footer .button .bnt{font-size:0.28rem;color:#999;border-radius:0.5rem;border:1px solid #999;width:1.6rem;
    height:0.6rem;text-align:center;line-height:0.6rem;}
.shoppingCart .footer .button .bnt~.bnt{margin-left:0.17rem;}
/*个人中心*/
.user .header{padding:0 0.3rem;height:1.9rem;position:relative;}
.user .header:after {position: absolute;left: 0;right: 0;bottom: -0.98rem;z-index: -1;content:'';height:1rem;width: 100%;
    border-radius: 0 0 50% 50%;background-color: #e93323;}
.user .header .picTxt .pictrue{width:1.2rem;height:1.2rem;}
.user .header .picTxt .pictrue img{width:100%;height:100%;border-radius:50%;border:0.03rem solid #f5f5f5;}
.user .header .picTxt .text{width:4.34rem;color:rgba(255,255,255,1);margin-left:0.35rem;text-align:left;}
.user .header .picTxt .text .name{font-size:0.32rem;max-width:2.6rem;width:unset;}
.user .header .picTxt .text .member{padding:0 0.1rem;height:0.36rem;background-color:rgba(0, 0, 0, 0.2);font-size:0.2rem;
    border-radius:0.3rem;margin-left:0.17rem;}
.user .header .picTxt .text .member img{width:0.28rem;height:0.28rem;font-size:0.2rem;margin-right:0.08rem;}
.user .header .picTxt .text .id{color:rgba(255,255,255,0.6);font-size:0.26rem;margin-top:0.15rem;}
.user .header .picTxt .text .id .iconfont{font-size:0.3rem;margin-left:0.12rem;}
.user .header .icon-shezhi{font-size:0.36rem;color:#fff;margin-top:-0.52rem;}
.user .wrapper{padding:0 0.2rem;}
.user .wrapper .nav{background-color:#fff;border-radius:0.06rem;height:1.4rem;}
.user .wrapper .nav .item{flex:1;-webkit-flex:1;-o-flex:1;-ms-flex:1;text-align:center;font-size:0.26rem;color:#aaa;position:relative;}
.user .wrapper .nav .item~.item:after{position:absolute;content:'';left:0;width:1px;height:0.7rem;background-color:#eee;
top:50%;margin-top:-0.35rem;}
.user .wrapper .nav .item .num{margin-top:0.1rem;font-size:0.36rem;color:#282828;}
.user .wrapper .myOrder{background-color:#fff;border-radius:0.1rem;margin-top:0.15rem;}
.user .wrapper .myOrder .title,.user .wrapper .myService .title{height:0.88rem;padding:0 0.3rem;border-bottom:1px dashed #eee;
    font-size:0.3rem;color:#282828;}
.user .wrapper .myOrder .title .allOrder{font-size:0.26rem;color:#666;}
.user .wrapper .myOrder .title .allOrder .iconfont{font-size:0.25rem;margin-left:0.07rem;}
.user .wrapper .myOrder .orderState{height:1.6rem;}
.user .wrapper .myOrder .orderState .item{font-size:0.26rem;color:#454545;flex:1;-webkit-flex:1;-o-flex:1;-ms-flex:1;text-align:center;}
.user .wrapper .myOrder .orderState .item .pictrue{width:0.49rem;height:0.42rem;margin:0 auto 0.18rem auto;}
.user .wrapper .myOrder .orderState .item .pictrue img{width:100%;height:100%;}
.user .wrapper .myService{background-color:#fff;margin-top:0.15rem;border-radius:0.1rem;}
.user .wrapper .myService .serviceList{padding:0.08rem 0 0.27rem 0;}
.user .wrapper .myService .serviceList .item{width:25%;text-align:center;font-size:0.26rem;color:#333;margin-top:0.3rem;}
.user .wrapper .myService .serviceList .item .pictrue{width:0.52rem;height:0.52rem;margin:0 auto 0.16rem auto;}
.user .wrapper .myService .serviceList .item .pictrue img{width:100%;height:100%;}
.user .support{width:2.19rem;height:0.74rem;margin:0.54rem auto;display:block;}
/*所有产品的详情公用部分*/
.product-con .wrapper{background-color:#fff;}
.product-con .wrapper .share{margin:0 0.3rem;padding-top:0.25rem;}
.product-con .wrapper .share .money{font-size:0.28rem;font-weight:bold;}
.product-con .wrapper .share .money .num{font-size:0.48rem;}
.product-con .wrapper .share .money .vip-money{color:#282828;margin-left:0.13rem;}
.product-con .wrapper .share .money .image{width:0.46rem;height:0.21rem;margin-left:0.07rem;}
.product-con .wrapper .share .money .vip-money{color:#282828;margin-left:0.13rem;}
.product-con .wrapper .share .iconfont{color:#515151;font-size:0.4rem;margin-bottom:0.1rem;}
.product-con .wrapper .introduce{font-size:0.32rem;font-weight:bold;margin:0.1rem 0.3rem 0 0.3rem;}
.product-con .wrapper .label{margin:0.22rem 0.3rem 0 0.3rem;font-size:0.24rem;color:#82848f;padding-bottom: 0.25rem;}
.product-con .wrapper .coupon{padding:0 0.3rem;border-top:1px solid #f5f5f5;height:0.8rem;
    font-size:0.26rem;color:#82848f;}
.product-con .wrapper .coupon .hide{width:5.4rem;height:0.8rem;line-height:0.8rem;}
.product-con .wrapper .coupon .activity{height:0.4rem;padding:0 0.2rem;border:1px solid #f2857b;color:#e93323;
    font-size:0.24rem;line-height:0.4rem;position:relative;margin:0.19rem 0 0.19rem 0.15rem;}
.product-con .wrapper .coupon .activity:before {content: ' ';position: absolute;width:0.07rem;height:0.1rem;
    border-radius:0 0.07rem 0.07rem 0;border:1px solid #f2857b;background-color:#fff;bottom:50%;left:-0.02rem;
    margin-bottom: -0.07rem;border-left-color:#fff;}
.product-con .wrapper .coupon .activity:after {content: ' ';position: absolute;width:0.07rem;height:0.1rem;
    border-radius:0.07rem 0 0 0.07rem;border:1px solid #f2857b;background-color:#fff;right:-0.02rem;bottom:50%;
    margin-bottom:-0.05rem;border-right-color:#fff;}
.product-con .wrapper .coupon .iconfont{color:#7a7a7a;font-size:0.28rem;}
.product-con .attribute{background-color:#fff;padding:0 0.3rem;font-size:0.26rem;color:#82848f;margin-top:0.2rem;
    height:0.8rem;}
.product-con .attribute .atterTxt{font-size:0.28rem;color:#282828;}
.product-con .attribute .iconfont{font-size:0.28rem;color:#7a7a7a;}
.product-con .userEvaluation{margin-top:0.2rem;background-color:#fff;}
.product-con .userEvaluation .title{height:0.86rem;border-bottom:1px solid #eee;font-size:0.28rem;color:#282828;
    margin-left:0.3rem;padding-right:0.3rem;}
.product-con .userEvaluation .title .praise{font-size:0.28rem;color:#808080;}
.product-con .userEvaluation .title .praise .iconfont{color:#7a7a7a;font-size:0.28rem;vertical-align:0.01rem;
    margin-left:0.08rem;}
.product-con .product-intro{margin-top:0.2rem;}
.product-con .product-intro .title{font-size:0.3rem;color:#282828;height:0.86rem;width:100%;background-color:#fff;
    text-align:center;line-height:0.86rem;}
.product-con .product-intro .conter{width:100%;}
.product-con .product-intro .conter img{width:100%!important;display:block!important;}
/*产品详情*/
.product-con .footer{padding:0 0.2rem 0 0.3rem;position:fixed;bottom:0;width:100%;height:1rem;background-color:#fff;
    z-index:99;border-top:1px solid #f0f0f0;}
.product-con .footer .item{font-size:0.18rem;color:#666;margin-top: 0.07rem;}
.product-con .footer .item .iconfont{text-align:center;font-size:0.4rem;height: 0.4rem;line-height: 0.4rem;}
.product-con .footer .item .iconfont.icon-gouwuche1{position:relative;}
.product-con .footer .item .iconfont.icon-gouwuche1 .num{color:#fff;position:absolute;font-size:0.18rem;
border-radius:2rem;top:-0.1rem;right:0;height:0.3rem;line-height:0.3rem;padding:0 0.08rem;min-width:0.3rem;}
.product-con .footer .bnt{width:4.44rem;height:0.76rem;color:#fff;font-size:0.28rem;}
.product-con .footer .bnt>div{width:2.22rem;text-align:center;line-height:0.76rem;}
.product-con .footer .bnt .joinCart{border-radius:0.5rem 0 0 0.5rem;
    background-image:linear-gradient(to right,#fea10f 0%,#fa8013 100%);
    background-image:-webkit-linear-gradient(to right,#fea10f 0%,#fa8013 100%);
    background-image:-moz-linear-gradient(to right,#fea10f 0%,#fa8013 100%);}
.product-con .footer .bnt .buy{border-radius:0 0.5rem 0.5rem 0;
    background-image: linear-gradient(to right,#fa6514 0%,#e93323 100%);
    background-image: -webkit-linear-gradient(to right,#fa6514 0%,#e93323 100%);
    background-image: -moz-linear-gradient(to right,#fa6514 0%,#e93323 100%);}
/*订单提交*/
.order-submission .line{width:100%;height:0.03rem;}
.order-submission .line img{width:100%;height:100%;display:block;}
.order-submission .address{padding:0.28rem 0.3rem;background-color:#fff;}
.order-submission .address .addressCon{width:6.1rem;font-size:0.26rem;color:#666;}
.order-submission .address .addressCon .name{font-size:0.3rem;color:#282828;font-weight:bold;margin-bottom:0.1rem;}
.order-submission .address .addressCon .name .phone{margin-left:0.5rem;}
.order-submission .address .addressCon .default{margin-right:0.12rem;}
.order-submission .address .addressCon .setaddress{color:#333;font-size:0.28rem;}
.order-submission .address .iconfont{font-size:0.35rem;color:#707070;}
.order-submission .wrapper{background-color:#fff;margin-top:0.13rem;}
.order-submission .wrapper .item{padding:0.27rem 0.3rem;font-size:0.3rem;color:#282828;border-bottom:1px solid #f0f0f0;}
.order-submission .wrapper .item .discount{font-size:0.3rem;color:#999;width: 5rem;text-align: right;}
.order-submission .wrapper .item .discount .integral{margin-right: 0.4rem;}
.order-submission .wrapper .item .discount .checkbox-wrapper .icon{right: 0;left: unset;}
.order-submission .wrapper .item .discount .iconfont{color:#515151;font-size:0.3rem;margin-left:0.15rem;}
.order-submission .wrapper .item .discount .num{font-size:0.32rem;margin-right:0.2rem;}
.order-submission .wrapper .item textarea{background-color:#f9f9f9;width:6.9rem;height:1.4rem;border-radius:0.03rem;
    margin-top:0.3rem;padding:0.25rem 0.28rem;}
.order-submission .wrapper .item textarea::placeholder{color:#ccc;}
.order-submission .wrapper .item .list{margin-top:0.35rem;}
.order-submission .wrapper .item .list .payItem{border:1px solid #eee;border-radius:0.06rem;height:0.86rem;width:100%;
    margin-top:0.2rem;font-size:0.28rem;color:#282828;}
.order-submission .wrapper .item .list .payItem.on{border-color:#fc5445;color:#e93323;}
.order-submission .wrapper .item .list .payItem .name{width:50%;text-align:center;border-right:1px solid #eee;}
.order-submission .wrapper .item .list .payItem .name .iconfont{width:0.44rem;height:0.44rem;border-radius:50%;
    text-align:center;line-height:0.44rem;background-color:#fe960f;color:#fff;font-size:0.3rem;margin-right:0.15rem;}
.order-submission .wrapper .item .list .payItem .name .iconfont.icon-weixin2{background-color:#41b035;}
.order-submission .wrapper .item .list .payItem .name .iconfont.icon-yinhangqia{background-color:#eb6623;}
.order-submission .wrapper .item .list .payItem .tip{width:49%;text-align:center;font-size:0.26rem;color:#aaa;}
.order-submission .moneyList{margin-top:0.12rem;background-color:#fff;padding:0.3rem;}
.order-submission .moneyList .item{font-size:0.28rem;color:#282828;}
.order-submission .moneyList .item~.item{margin-top:0.2rem;}
.order-submission .moneyList .item .money{color:#868686;}
.order-submission .footer{width:100%;height:1rem;background-color:#fff;padding:0 0.3rem;font-size:0.28rem;color:#333;
    position:fixed;bottom:0;left:0;}
.order-submission .footer .settlement{font-size:0.3rem;color:#fff;width:2.4rem;height:0.7rem;background-color:#e93323;
    border-radius:0.5rem;text-align:center;line-height:0.7rem;}
/*地址管理*/
.address-management .line{width:100%;height:0.03rem;}
.address-management .line img{width:100%;height:100%;display:block;}
.address-management .item{background-color:#fff;padding:0 0.3rem;margin-bottom:0.12rem;}
.address-management .item .address{padding:0.3rem 0;border-bottom:1px solid #eee;font-size:0.28rem;color:#282828;}
.address-management .item .address .consignee{font-size:0.28rem;font-weight:bold;margin-bottom:0.08rem;}
.address-management .item .address .consignee .phone{margin-left:0.25rem;}
.address-management .item .operation{height:0.83rem;font-size:0.28rem;color:#282828;}
.address-management .item .operation .default{margin-left:0.6rem;}
.address-management .item .operation .iconfont{color:#2c2c2c;font-size:0.3rem;vertical-align:-0.02rem;margin-right:0.1rem;}
.address-management .item .operation .iconfont.icon-shanchu{margin-left:0.4rem;font-size:0.33rem;}
.address-management .footer{position:fixed;width:100%;background-color:#fff;bottom:0;height:1.06rem;padding:0 0.3rem;}
.address-management .footer .addressBnt{width:3.3rem;height:0.76rem;border-radius:0.5rem;text-align:center;
    line-height:0.76rem;font-size:0.3rem;color:#fff;}
.address-management .footer .addressBnt.on{width:6.9rem;margin:0 auto;}
.address-management .footer .addressBnt .iconfont{font-size:0.35rem;margin-right:0.08rem;vertical-align:-0.01rem;}
.address-management .footer .addressBnt.wxbnt{background-color:#fe960f;}
/*添加地址*/
.addAddress .list{background-color:#fff;}
.addAddress .list .item{padding:0 0.3rem;min-height:0.9rem;border-top:0.01rem solid #eee;font-size:0.3rem;}
.addAddress .list .item .name{width:1.95rem;color:#333;}
.addAddress .list .item input{width:4.75rem;font-size:0.3rem;}
.addAddress .list .item input::placeholder{color:#ccc;}
.addAddress .list .item .picker{width:4.75rem;}
.addAddress .list .item .address{width:4.1rem;}
.addAddress .list .item .picker .iconfont{font-size:0.43rem;}
.addAddress .default{padding:0 0.3rem;height:0.9rem;background-color:#fff;margin-top:0.23rem;}
.addAddress .default .def{margin-left:0.6rem;}
.addAddress .keepBnt{width:6.9rem;height:0.86rem;border-radius:0.5rem;text-align:center;line-height:0.86rem;
    margin: 0.5rem auto 0.3rem auto;font-size:0.32rem;color:#fff;}
.addAddress .wechatAddress{width:6.9rem;height:0.86rem;border-radius:0.5rem;text-align:center;line-height:0.86rem;
    margin:0 auto;font-size:0.32rem;color:#fe960f;border:1px solid #fe960f;}
/*我的订单*/
.my-order .header{height:2.6rem;padding:0 0.3rem;}
.my-order .header .picTxt{height:1.9rem;}
.my-order .header .picTxt .text{color:rgba(255, 255, 255, 0.8);font-size:0.26rem;font-family: 'GuildfordProBook 5';}
.my-order .header .picTxt .text .name{font-size:0.34rem;font-weight:bold;color:#fff;margin-bottom:0.2rem;}
.my-order .header .picTxt .pictrue{width:1.22rem;height:1.09rem;}
.my-order .header .picTxt .pictrue img{width:100%;height:100%;}
.my-order .nav{background-color:#fff;width:6.9rem;height:1.4rem;border-radius:0.06rem;margin:-0.73rem auto 0 auto;}
.my-order .nav .item{text-align:center;font-size:0.26rem;color:#282828;padding: 0.29rem 0 0.2rem 0;}
.my-order .nav .item.on{font-weight:bold;border-bottom:0.05rem solid #e93323;}
.my-order .nav .item .num{margin-top:0.1rem;}
.my-order .list{width:6.9rem;margin:0.14rem auto 0 auto;}
.my-order .list .item{background-color:#fff;border-radius:0.06rem;margin-bottom:0.14rem;}
.my-order .list .item .title{height:0.84rem;padding:0 0.3rem;border-bottom:0.01rem solid #eee;font-size:0.28rem;color:#282828;}
.my-order .list .item .title .sign{font-size:0.24rem;padding:0 0.07rem;height: 0.36rem;margin-right: 0.15rem;}
.my-order .list .item .item-info{padding:0 0.3rem;margin-top:0.22rem;}
.my-order .list .item .item-info .pictrue{width:1.2rem;height:1.2rem;}
.my-order .list .item .item-info .pictrue img{width:100%;height:100%;border-radius:0.06rem;}
.my-order .list .item .item-info .text{width:4.86rem;font-size:0.28rem;color:#999;margin-top:0.06rem;}
.my-order .list .item .item-info .text .name{width:3.06rem;color:#282828;}
.my-order .list .item .item-info .text .money{text-align:right;}
.my-order .list .item .totalPrice{font-size:0.26rem;color:#282828;text-align:right;margin:0.27rem 0 0 0.3rem;
    padding:0 0.3rem 0.3rem 0;border-bottom:0.01rem solid #eee;}
.my-order .list .item .totalPrice .money{font-size:0.28rem;font-weight:bold;}
.my-order .list .item .bottom{height:1.07rem;padding:0 0.3rem;}
.my-order .list .item .bottom .bnt{width:1.76rem;height:0.6rem;text-align:center;line-height:0.6rem;color:#fff;
    border-radius:0.5rem;font-size:0.27rem;}
.my-order .list .item .bottom .bnt.cancelBnt{border:1px solid #ddd;color:#aaa;}
.my-order .list .item .bottom .bnt.default{color: #444;border: 1px solid #444;}
.my-order .list .item .bottom .bnt~.bnt{margin-left:0.17rem;}
/*订单详情*/
.order-details .header{padding:0 0.3rem;height:1.5rem;}
.order-details .header.on{background-color:#666!important;}
.order-details .header .pictrue{width:1.1rem;height:1.1rem;}
.order-details .header .pictrue img{width:100%;height:100%;}
.order-details .header .data{color:rgba(255,255,255,0.8);font-size:0.24rem;margin-left:0.27rem;}
.order-details .header.on .data{margin-left:0;}
.order-details .header .data .state{font-size:0.3rem;font-weight:bold;color:#fff;margin-bottom:0.07rem;}
.order-details .header .data .time{margin-left:0.2rem;}
.order-details .nav{background-color:#fff;font-size:0.26rem;color:#282828;padding:0.25rem 0;}
.order-details .nav .navCon{padding:0 0.4rem;}
.order-details .nav .navCon .on{font-weight:bold;color:#e93323;}
.order-details .nav .progress{padding:0 0.65rem;margin-top:0.1rem;}
.order-details .nav .progress .line{width:1rem;height:0.02rem;background-color:#939390;}
.order-details .nav .progress .iconfont{font-size:0.25rem;color:#939390;margin-top:-0.02rem;width: 0.3rem;height: 0.3rem;
    line-height: 0.33rem;text-align:center;}
.order-details .address{font-size:0.26rem;color:#868686;background-color:#fff;padding: 0.25rem 0.3rem 0.3rem 0.3rem;}
.order-details .address .name{font-size:0.3rem;color:#282828;margin-bottom:0.1rem;}
.order-details .address .name .phone{margin-left:0.4rem;}
.order-details .line{width:100%;height:0.03rem;}
.order-details .line img{width:100%;height:100%;display:block;}
.order-details .wrapper{background-color:#fff;margin-top:0.12rem;padding:0.3rem;}
.order-details .wrapper .item{font-size:0.28rem;color:#282828;}
.order-details .wrapper .item~.item{margin-top:0.2rem;}
.order-details .wrapper .item .conter{color:#868686;width:5rem;text-align:right;}
.order-details .wrapper .item .conter .copy{font-size:0.2rem;color:#333;border-radius:0.03rem;border:1px solid #666;
    padding:0.03rem 0.15rem;margin-left:0.24rem;}
.order-details .wrapper .actualPay{border-top:0.01rem solid #eee;margin-top:0.3rem;padding-top:0.3rem;}
.order-details .wrapper .actualPay .money{font-weight:bold;font-size:0.3rem;}
.order-details .footer{width:100%;height:1rem;position:fixed;bottom:0;left:0;background-color:#fff;padding:0 0.3rem;border-top:1px solid #eee;}
.order-details .footer .bnt{width:1.76rem;height:0.6rem;text-align:center;line-height:0.6rem;border-radius:0.5rem;
    color:#fff;font-size:0.27rem;}
.order-details .footer .bnt.cancel{color:#aaa;border:1px solid #ddd;}
.order-details .footer .bnt.default{color: #444;border: 1px solid #444;}
.order-details .footer .bnt~.bnt{margin-left:0.18rem;}
/*物流信息*/
.logistics .header{padding:0.23rem 0.3rem;background-color:#fff;height:1.66rem;}
.logistics .header .pictrue{width:1.2rem;height:1.2rem;}
.logistics .header .pictrue img{width:100%;height:100%;border-radius:0.06rem;}
.logistics .header .text{width:5.4rem;font-size:0.28rem;color:#999;margin-top:0.06rem;}
.logistics .header .text .name{width:3.65rem;color:#282828;}
.logistics .header .text .money{text-align:right;}
.logistics .logisticsCon{background-color:#fff;margin:0.12rem 0;}
.logistics .logisticsCon .company{height:1.2rem;margin:0 0 0.45rem 0.3rem;padding-right:0.3rem;
    border-bottom:1px solid #f5f5f5;}
.logistics .logisticsCon .company .picTxt{width:5.2rem;}
.logistics .logisticsCon .company .picTxt .iconfont{width:0.5rem;height:0.5rem;background-color:#666;text-align:center;
    line-height:0.5rem;color:#fff;font-size:0.35rem;}
.logistics .logisticsCon .company .picTxt .text{width:4.5rem;font-size:0.26rem;color:#282828;}
.logistics .logisticsCon .company .picTxt .text .name{color:#999;}
.logistics .logisticsCon .company .picTxt .text .express{margin-top:0.05rem;}
.logistics .logisticsCon .company .copy{font-size:0.2rem;width:1.06rem;height:0.4rem;border-radius:0.03rem;border:1px solid #999;}
.logistics .logisticsCon .item{padding:0 0.4rem;position:relative;}
.logistics .logisticsCon .item .circular{width:0.2rem;height:0.2rem;border-radius:50%;position:absolute;top:-0.01rem;
    left:0.315rem;background-color:#ddd;}
.logistics .logisticsCon .item .circular.on{background-color:#e93323;}
.logistics .logisticsCon .item .text{font-size:0.26rem;color:#666;width:6.15rem;border-left:1px solid #e6e6e6;
    padding:0 0 0.6rem 0.38rem;}
.logistics .logisticsCon .item .text.on{border-left-color:#f8c1bd;}
.logistics .logisticsCon .item .text .data{font-size:0.24rem;color:#999;margin-top:0.1rem;}
.logistics .logisticsCon .item .text .data .time{margin-left:0.15rem;}
/*支付状态*/
.payment-status{background-color:#fff;margin:1.95rem auto 0 auto;border-radius:0.1rem;padding:0.01rem 0 0.28rem 0;width: 6.9rem;left:50%;margin-left:-3.45rem;}
.payment-status .iconfont{font-size:0.7rem;width:1.4rem;height:1.4rem;border-radius:50%;color:#fff;text-align:center;
    line-height:1.3rem;text-shadow:0 4px 0 #df1e14;border:0.06rem solid #f5f5f5;margin:-0.76rem auto 0 auto;
    background-color:#999;}
.payment-status .iconfont.fail{text-shadow:0 4px 0 #7a7a7a;}
.payment-status .status{font-size:0.32rem;font-weight:bold;text-align:center;margin:0.25rem 0 0.37rem 0;}
.payment-status .wrapper{border:1px solid #eee;margin:0 0.3rem 0.47rem 0.3rem;padding:0.35rem 0;border-left:0;
    border-right:0;}
.payment-status .wrapper .item{font-size:0.28rem;color:#282828;}
.payment-status .wrapper .item~.item{margin-top:0.2rem;}
.payment-status .wrapper .item .itemCom{color:#666;}
.payment-status .returnBnt{width:6.3rem;height:0.86rem;border-radius:0.5rem;color:#fff;font-size:0.3rem;text-align:center;
    line-height:0.86rem;margin:0 auto 0.2rem auto;}
/*个人资料*/
.personal-data .wrapper{margin:0.1rem 0;background-color:#fff;padding:0.36rem 0.3rem 0.13rem 0.3rem;}
.personal-data .wrapper .title{margin-bottom:0.3rem;font-size:0.32rem;color:#282828;}
.personal-data .wrapper .wrapList .item{width:6.9rem;height:1.6rem;background-color:#f8f8f8;border-radius:0.2rem;margin-bottom:0.22rem;padding:0 0.3rem;position:relative;border:0.02rem solid #f8f8f8;}
.personal-data .wrapper .wrapList .item.on{border-color:#e93323;border-radius:0.2rem;background:url("../images/figure.png") no-repeat;background-size:100% 100%;background-color:#fff9f9;}
.personal-data .wrapper .wrapList .item .picTxt{width:4.45rem;}
.personal-data .wrapper .wrapList .item .picTxt .pictrue{width:0.96rem;height:0.96rem;position:relative;}
.personal-data .wrapper .wrapList .item .picTxt .pictrue img{width:100%;height:100%;border-radius:50%;}
.personal-data .wrapper .wrapList .item .picTxt .pictrue .alter{width:0.3rem;height:0.3rem;border-radius:50%;position:absolute;bottom:0;right:0;}
.personal-data .wrapper .wrapList .item .picTxt .text{width:3.25rem;}
.personal-data .wrapper .wrapList .item .picTxt .text .name{width:100%;font-size:0.3rem;color:#282828;}
.personal-data .wrapper .wrapList .item .picTxt .text .phone{font-size:0.24rem;color:#999;margin-top:0.1rem;}
.personal-data .wrapper .wrapList .item .bnt{font-size:0.24rem;background-color:#fff;border-radius:0.27rem;width:1.4rem;height:0.54rem;border:0.02rem solid #e93323;}
.personal-data .wrapper .wrapList .item .currentBnt{position:absolute;right:0;top:0;font-size:0.26rem;background-color:rgba(233,51,35,0.1);width:1.4rem;height:0.48rem;border-radius:0 0.2rem 0 0.2rem;}
.personal-data .list{background-color:#fff;}
.personal-data .list .item{padding:0.3rem 0.3rem 0.3rem 0;border-bottom:1px solid #f2f2f2;margin-left:0.3rem;
    font-size:0.32rem;color:#282828;}
.personal-data .list .item .pictrue{width:0.88rem;height:0.88rem;}
.personal-data .list .item .pictrue img{width:100%;height:100%;border-radius:50%;}
.personal-data .list .item .input{width:4.15rem;text-align:right;color:#868686;}
.personal-data .list .item .input input{color:#868686;text-align:right;width: 100%;}
.personal-data .list .item .input .id{width:3.65rem;}
.personal-data .list .item .input .iconfont{font-size:0.35rem;}
.personal-data .list .item .input .iconfont.icon-xiangyou{font-size:0.3rem;margin-left:0.27rem;}
.personal-data .modifyBnt{font-size:0.32rem;color:#fff;width:6.9rem;height:0.9rem;border-radius:0.5rem;text-align:center;line-height:0.9rem;margin:0.76rem auto 0 auto;}
.personal-data .logOut{font-size:0.32rem;text-align:center;width:6.9rem;height:0.9rem;border-radius:0.45rem;margin:0.3rem auto 0.7rem auto;}
/*拼团海报*/
.poster-poster .tip{height:0.8rem;font-size:0.26rem;color:#e8c787;text-align:center;line-height:0.8rem;}
.poster-poster .tip .iconfont{font-size:0.36rem;vertical-align:-0.04rem;margin-right:0.18rem;}
.poster-poster .poster{width:6.9rem;height:100%;margin:0 auto;}
.poster-poster .poster img{width:100%;height:100%;display:block;}
/*分销海报*/
.distribution-posters .slider-banner{width:100%;height:10rem;position:relative;margin-top:1rem;}
.distribution-posters .slider-banner .swiper-slide{width:6rem!important;height:100%;}
.distribution-posters .slide-image{width:100%;height:100%;border-radius:0.15rem;}
.distribution-posters .keep{font-size:0.3rem;color:#fff;width:6rem;height:0.8rem;border-radius:0.5rem;text-align:center;
    line-height:0.8rem;margin:0.38rem auto;}
/*会员中心*/
.member-center .header{background-color:#232323;width:100%;padding:0.5rem 0;}
.member-center .header .slider-banner{height:3.28rem;}
.member-center .header .slider-banner .swiper-slide{width:6.36rem!important;height:3.28rem;border-radius:0.16rem;
    color:#fff;position:relative;background-repeat:no-repeat;background-size:100% 100%;}
.member-center .header .slider-banner .swiper-slide.diamonds{background-image:url("../images/diamonds.jpg");}
.member-center .header .slider-banner .swiper-slide.gold{background-image:url("../images/gold.jpg");}
.member-center .header .slider-banner .swiper-slide.silver{background-image:url("../images/silver.jpg");}
.member-center .header .slider-banner .swiper-slide.brass{background-image:url("../images/brass.jpg");}
.member-center .header .slider-banner .swiper-slide.bronze{background-image:url("../images/bronze.jpg");}
.member-center .header .slider-banner .swiper-slide.ordinary{background-image:url("../images/ordinary.jpg");}
.member-center .header .slider-banner .swiper-slide img{width:0.89rem;height:1.08rem;display:block;position:absolute;right:0.6rem;}
.member-center .header .slider-banner .swiper-slide .name{font-size:0.46rem;font-weight:bold;padding:0.33rem 0 0 0.35rem;}
.member-center .header .slider-banner .swiper-slide .discount{font-size:0.28rem;font-weight:bold;margin:0.02rem 0 0 0.35rem;}
.member-center .header .slider-banner .swiper-slide .discount .iconfont{margin-left:0.1rem;font-size:0.3rem;}
.member-center .header .slider-banner .swiper-slide .nav{margin-top:0.48rem;}
.member-center .header .slider-banner .swiper-slide .nav .item{flex:1;-webkit-flex:1;-o-flex:1;-ms-flex:1;text-align:center;
    color:rgba(255, 255, 255, 0.6);position:relative;}
.member-center .header .slider-banner .swiper-slide .nav .item .num{font-size:0.4rem;color:#fff;font-family: 'GuildfordProBook 5';}
.member-center .header .slider-banner .swiper-slide .nav .item~.item::before{position:absolute;width:0.02rem;height:0.32rem;
    background-color:rgba(255, 255, 255, 0.6);content:'';left:0;top:50%;transform:translateY(-50%);-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);-moz-transform:translateY(-50%);-o-transform:translateY(-50%);}
.member-center .header .slider-banner .swiper-slide .lock{font-size:0.26rem;margin:0.73rem 0 0 0.35rem;}
.member-center .header .slider-banner .swiper-slide .lock .iconfont{font-size:0.33rem;margin-right:0.15rem;
    vertical-align:-0.04rem;}
.member-center .wrapper{background-color:#fff;padding-bottom:0.16rem;margin-bottom:0.2rem;}
.member-center .wrapper .title{height:0.98rem;padding:0 0.3rem;font-size:0.3rem;font-weight:bold;color:#282828;}
.member-center .wrapper .title .iconfont{color:#ffae06;font-weight:normal;font-size:0.4rem;margin-right:0.12rem;
    vertical-align:-0.02rem;}
.member-center .wrapper .title .num{font-size:0.28rem;color:#999;}
.member-center .wrapper .title .num .current{color:#ffae06;}
.member-center .wrapper .list .item{width:6.9rem;height:1.84rem;background-color:#f9f9f9;margin:0 auto 0.2rem auto;
    padding:0.27rem 0 0.22rem 0;border-radius:0.12rem;}
.member-center .wrapper .list .item .top{padding-right:0.27rem;font-size:0.26rem;color:#999;}
.member-center .wrapper .list .item .top .name{border-left:0.06rem solid #ffae06;padding-left:0.2rem;font-size:0.28rem;
    color:#282828;font-weight:bold;}
.member-center .wrapper .list .item .top .name .iconfont{color:#999;font-size:0.3rem;vertical-align:-0.02rem;
    margin-left:0.1rem;}
.member-center .wrapper .list .item .cu-progress{overflow: hidden;height:0.12rem;background-color: #eee;width:6.36rem;
    border-radius:0.2rem;margin:0.35rem auto 0 auto;}
.member-center .wrapper .list .item .cu-progress .bg-red{width:0;height:100%;transition:width 0.6s ease;-webkit-transition:width 0.6s ease;-moz-transition:width 0.6s ease;-o-transition:width 0.6s ease;
    background-color: #ffaa29;border-radius:0.2rem;}
.member-center .wrapper .list .item .experience{margin-top:0.17rem;padding:0 0.27rem;font-size:0.24rem;color:#999;}
.member-center .wrapper .list .item .experience .num{color:#ffad07;}
.member-center .growthValue{background-color:#fff;border-radius:0.16rem;position:fixed;top:2.66rem;left:50%;width:5.6rem;
    height:7.4rem;margin-left:-2.8rem;z-index:99;transform:translate3d(0,-200%,0);-webkit-transform:translate3d(0,-200%,0);-ms-transform:translate3d(0,-200%,0);-moz-transform:translate3d(0,-200%,0);
    -o-transform:translate3d(0,-200%,0);
    transition:all .3s cubic-bezier(.25,.5,.5,.9);-webkit-transition:all .3s cubic-bezier(.25,.5,.5,.9);-moz-transition:all .3s cubic-bezier(.25,.5,.5,.9);-o-transition:all .3s cubic-bezier(.25,.5,.5,.9);}
.member-center .growthValue.on{transform:translate3d(0,0,0);-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);}
.member-center .growthValue .pictrue{width:100%;height:2.57rem;position:relative;}
.member-center .growthValue .pictrue img{width:100%;height:100%;border-radius:0.16rem 0.16rem 0 0;}
.member-center .growthValue .conter{padding:0 0.35rem;font-size:0.3rem;color:#333;margin-top:0.58rem;line-height:1.5;
    height:3.5rem;overflow:auto;}
.member-center .growthValue .pictrue .iconfont{position:absolute;font-size:0.65rem;color:#fff;top:7.75rem;left:50%;
    transform:translateX(-50%);-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);-moz-transform:translateX(-50%);-o-transform:translateX(-50%);}
/*积分详情*/
.integral-details .header{background-image:url('../images/integralbg.jpg');background-repeat:no-repeat;
    background-size:100% 100%;width:100%;height:4.6rem;font-size:0.72rem;color:#fff;padding:0.31rem 0 0.45rem 0;
    text-align:center;font-family: 'GuildfordProBook 5';}
.integral-details .header .currentScore{font-size:0.26rem;color:rgba(255, 255, 255, 0.8);text-align:center;margin-bottom: 0.05rem;}
.integral-details .header .line{width:0.6rem;height:0.03rem;background-color:#fff;margin:0.2rem auto 0 auto;}
.integral-details .header .nav{font-size:0.22rem;color:rgba(255, 255, 255, 0.8);flex:1;-webkit-flex:1;-o-flex:1;-ms-flex:1;margin-top:0.35rem;}
.integral-details .header .nav .item{width:33.33%;text-align:center;}
.integral-details .header .nav .item .num{color:#fff;font-size:0.4rem;}
.integral-details .wrapper .nav{flex:1;-webkit-flex:1;-o-flex:1;-ms-flex:1;width:6.9rem;border-radius:0.2rem 0.2rem 0 0;
    margin:-0.96rem auto 0 auto;background-color:#f7f7f7;height:0.96rem;font-size:0.3rem;color:#bbb;}
.integral-details .wrapper .nav .item{text-align:center;width:50%;}
.integral-details .wrapper .nav .item.on{background-color:#fff;color:#e93323;font-weight:bold;border-radius:0.2rem 0 0 0;}
.integral-details .wrapper .nav .item .iconfont{font-size:0.38rem;margin-right:0.1rem;}
.integral-details .wrapper .list{background-color:#fff;padding:0.24rem 0.3rem;}
.integral-details .wrapper .list .tip{font-size:0.25rem;width:6.9rem;height:0.6rem;border-radius:0.5rem;
    background-color:#fff5e2;border:1px solid #ffeac1;color:#c8a86b;padding:0 0.2rem;margin-bottom:0.24rem;}
.integral-details .wrapper .list .tip .iconfont{font-size:0.35rem;margin-right:0.15rem;}
.integral-details .wrapper .list .item{height:1.24rem;border-bottom:1px solid #eee;font-size:0.24rem;color:#999;}
.integral-details .wrapper .list .item .state{font-size:0.28rem;color:#282828;margin-bottom:0.08rem;}
.integral-details .wrapper .list .item .num{font-size:0.36rem;font-family: 'GuildfordProBook 5';color: #16ac57;}
.integral-details .wrapper .list2{background-color:#fff;padding:0.24rem 0;}
.integral-details .wrapper .list2 .item{background-image:linear-gradient(to right,#fff7e7 0%,#fffdf9 100%);
    background-image:-webkit-linear-gradient(to right,#fff7e7 0%,#fffdf9 100%);
    background-image:-moz-linear-gradient(to right,#fff7e7 0%,#fffdf9 100%);
    width:6.9rem;height:1.8rem;position:relative;border-radius:0.1rem;margin:0 auto 0.2rem auto;padding:0 0.25rem 0 1.8rem;}
.integral-details .wrapper .list2 .item .pictrue{width:0.9rem;height:1.5rem;position:absolute;bottom:0;left:0.45rem;}
.integral-details .wrapper .list2 .item .pictrue img{width:100%;height:100%;}
.integral-details .wrapper .list2 .item .name{width:2.85rem;font-size:0.3rem;font-weight:bold;color:#c8a86b;}
.integral-details .wrapper .list2 .item .earn{font-size:0.26rem;color:#c8a86b;border:0.02rem solid #c8a86b;
    text-align:center;line-height:0.52rem;height:0.52rem;width:1.6rem;border-radius:0.5rem;}
/*金品推荐*/
.quality-recommend .title{height:1.2rem;font-size:0.32rem;color:#282828;background-color:#f5f5f5;}
.quality-recommend .title .line{width:2.3rem;height:0.02rem;background-color:#e9e9e9;}
.quality-recommend .title .name{margin:0 0.2rem;}
.quality-recommend .title .name .iconfont{margin-right:0.13rem;font-size:0.38rem;vertical-align:-0.04rem;}
/*砍价列表*/
.bargain-list .icon-xiangzuo{font-size:0.4rem;color:#fff;position:fixed;top:0.51rem;left:0.3rem;z-index:99;}
.bargain-list .header{background-image:url('../images/cut-bg.png');background-repeat:no-repeat;background-size:100% 100%;width:7.5rem;
    height:7.13rem;}
.bargain-list .list{background-color:#fff;border:0.06rem solid #fc8b42;border-radius:0.3rem;
    margin:-0.45rem 0.3rem 0.66rem 0.3rem;padding:0 0.24rem;}
.bargain-list .list .item{border-bottom:1px solid #eee;position:relative;height:2.23rem;}
.bargain-list .list .item .pictrue{width:1.6rem;height:1.6rem;}
.bargain-list .list .item .pictrue img{width:100%;height:100%;border-radius:0.06rem;}
.bargain-list .list .item .text{width:4.5rem;font-size:0.3rem;color:#282828;height:1.6rem;}
.bargain-list .list .item .text .num{font-size:0.26rem;color:#999;}
.bargain-list .list .item .text .num .iconfont{font-size:0.35rem;margin-right:0.07rem;}
.bargain-list .list .item .text .money{font-size:0.24rem;font-weight:bold;}
.bargain-list .list .item .text .money .price{font-size:0.32rem;}
.bargain-list .list .item .cutBnt{position:absolute;width:1.8rem;height:0.5rem;border-radius:0.5rem;font-size:0.24rem;
    color:#fff;text-align:center;line-height:0.46rem;right:0.24rem;bottom:0.28rem;box-shadow:0 0.07rem 0 #f8c1bd;
    -webkit-box-shadow: 0 0.07rem 0 #f8c1bd;-moz-box-shadow: 0 0.07rem 0 #f8c1bd;-o-box-shadow:0 0.07rem 0 #f8c1bd;}
.bargain-list .list .item .cutBnt .iconfont{margin-right:0.08rem;font-size:0.3rem;}
.bargain-list .list .load{font-size:0.24rem;height:0.85rem;text-align:center;line-height:0.85rem;}
/*砍价*/
.bargain .icon-xiangzuo{font-size:0.4rem;color:#fff;position:fixed;top:0.51rem;left:0.3rem;z-index:99;}
.bargain .header{background-image:url('../images/cut1.png');background-repeat:no-repeat;background-size:100% 100%;width:6.98rem;
    height:5.72rem;margin:0 auto;padding-top:0.001rem;margin-top:0.4rem}
.bargain .header.on{background-image:url('../images/cut2.png');}
.bargain .header .pictxt{margin:2.6rem auto 0 auto;font-size:0.26rem;color:#fff;}
.bargain .header .pictxt .pictrue{width:0.56rem;height:0.56rem;margin-right:0.3rem;}
.bargain .header .pictxt .pictrue img{width:100%;height:100%;border-radius:50%;border:0.02rem solid #fff;}
.bargain .header .pictxt .text span{margin-left:0.2rem;}
.bargain .header .time{background-image:url('../images/time.png');background-repeat:no-repeat;background-size:100% 100%;
    width:4.4rem;height:1.66rem;margin:2.8rem auto 0 auto;font-size:0.22rem;text-align:center;padding-top:0.09rem;
    color: #fc4141;}
.bargain .header .people{text-align:center;color:#fff;font-size:0.2rem;margin-top:0.2rem;}
.bargain .header .time .styleAll{color:#333;}
.bargain .wrapper,.bargain .bargainGang,.bargain .goodsDetails{width:6.6rem;border:0.06rem solid #fc8b42;
    background-color:#fff;border-radius:0.2rem;margin:-1.62rem auto 0 auto;padding:0 0.24rem 0.47rem 0.24rem;position:relative;}
.bargain .wrapper .pictxt{margin:0.26rem 0 0.37rem 0;}
.bargain .wrapper .pictxt .pictrue{width:1.8rem;height:1.8rem;}
.bargain .wrapper .pictxt .pictrue img{width:100%;height:100%;border-radius:0.06rem;}
.bargain .wrapper .pictxt .text{width:3.95rem;font-size:0.28rem;color:#282828;height:1.8rem;}
.bargain .wrapper .pictxt .text .money{font-weight:bold;font-size:0.24rem;}
.bargain .wrapper .pictxt .text .money .num{font-size:0.36rem;}
.bargain .wrapper .pictxt .text .successNum{font-size:0.22rem;color:#999;margin-right: 0.15rem;}
.bargain .wrapper .cu-progress {overflow: hidden;height:0.12rem;background-color: #eee;width:100%;border-radius:0.2rem;}
.bargain .wrapper .cu-progress .bg-red{width: 0;height: 100%;transition: width 0.6s ease;-webkit-transition: width 0.6s ease;-moz-transition: width 0.6s ease;-o-transition: width 0.6s ease;border-radius:0.2rem;
    background-image: linear-gradient(to right,#ffa363 0%,#e93323 100%);
    background-image: -webkit-linear-gradient(to right,#ffa363 0%,#e93323 100%);
    background-image: -moz-linear-gradient(to right,#ffa363 0%,#e93323 100%);}
.bargain .wrapper .balance{font-size:0.22rem;color:#999;margin-top:0.15rem;}
.bargain .wrapper .bargainSuccess{font-size:0.26rem;color:#282828;text-align:center;}
.bargain .wrapper .bargainSuccess .iconfont{font-size:0.45rem;color:#54c762;padding-right:0.18rem;vertical-align:-0.05rem;}
.bargain .wrapper .bargainBnt{font-size:0.3rem;font-weight:bold;color:#fff;width:6rem;height:0.8rem;border-radius:0.4rem;
    background-image: linear-gradient(to right,#f67a38 0%,#f11b09 100%);text-align:center;line-height:0.8rem;
    margin-top:0.32rem;}
.bargain .wrapper .bargainBnt.on{border:0.02rem solid #e93323;color:#e93323;
    background-image: linear-gradient(to right,#fff 0%,#fff 100%);
    background-image: -webkit-linear-gradient(to right,#fff 0%,#fff 100%);
    background-image: -moz-linear-gradient(to right,#fff 0%,#fff 100%);
    width:5.96rem;height:0.76rem;}
.bargain .wrapper .tip{font-size:0.22rem;color:#999;text-align:center;margin-top:0.2rem;}
.bargain .wrapper .lock,.bargain .bargainGang .lock,.bargain .goodsDetails .lock{background-image:url('../images/lock.png');
    background-repeat:no-repeat;background-size:100% 100%;width:5.48rem;height:0.66rem;position:absolute;left:50%;
    transform:translateX(-50%);-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);-moz-transform:translateX(-50%);-o-transform:translateX(-50%);bottom:-0.43rem;z-index:5;}
.bargain .bargainGang{margin:0.13rem auto 0 auto;}
.bargain .bargainGang .title,.bargain .goodsDetails .title{font-size:0.32rem;font-weight:bold;height:0.8rem;
    margin-top:0.3rem;}
.bargain .bargainGang .title .pictrue,.bargain .goodsDetails .title .pictrue{width:0.46rem;height:0.24rem;}
.bargain .bargainGang .title .pictrue.on,.bargain .goodsDetails .title .pictrue.on{transform:rotate(180deg);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);-moz-transform:rotate(180deg);-o-transform:rotate(180deg);}
.bargain .bargainGang .title .pictrue img,.bargain .goodsDetails .title .pictrue img{width:100%;height:100%;display:block;}
.bargain .bargainGang .title .titleCon,.bargain .goodsDetails .title .titleCon{margin:0 0.2rem;}
.bargain .bargainGang .list .item{border-bottom:1px dashed #ddd;height:1.12rem;}
.bargain .bargainGang .list .item .pictxt{width:3.1rem;}
.bargain .bargainGang .list .item .pictxt .pictrue{width:0.7rem;height:0.7rem;}
.bargain .bargainGang .list .item .pictxt .pictrue img{width:100%;height:100%;border-radius:50%;border:0.02px solid #e93323;}
.bargain .bargainGang .list .item .pictxt .text{width:2.25rem;font-size:0.2rem;color:#999;}
.bargain .bargainGang .list .item .pictxt .text .name{font-size:0.25rem;color:#282828;margin-bottom:0.07rem;}
.bargain .bargainGang .list .item .money{font-size:0.25rem;}
.bargain .bargainGang .list .item .money .iconfont{font-size:0.35rem;vertical-align:middle;margin-right:0.1rem;}
.bargain .bargainGang .load{font-size:0.24rem;text-align:center;line-height:0.8rem;height:0.8rem;}
.bargain .goodsDetails{margin:0.13rem auto 0 auto;}
.bargain .goodsDetails~.goodsDetails{margin-bottom:0.5rem;}
.bargain .goodsDetails .conter{margin-top:0.2rem;}
.bargain .goodsDetails .conter img{width:100%!important;display:block;}
.bargain .bargainTip{position:fixed;top:50%;left:50%;width:5.6rem;margin-left:-2.8rem;z-index:99;border-radius:0.2rem;
    background-color:#fff;transition:all 0.3s ease-in-out 0s;-webkit-transition:all 0.3s ease-in-out 0s;-moz-transition:all 0.3s ease-in-out 0s;-o-transition:all 0.3s ease-in-out 0s;opacity:0;transform: scale(0);-webkit-transform: scale(0);-ms-transform: scale(0);-moz-transform: scale(0);-o-transform: scale(0);padding-bottom:0.6rem;
    margin-top:-3.3rem;}
.bargain .bargainTip.on{opacity:1;transform: scale(1);-webkit-transform: scale(1);-ms-transform: scale(1);-moz-transform: scale(1);-o-transform: scale(1);}
.bargain .bargainTip .pictrue{width:100%;height:3.21rem;position:relative;}
.bargain .bargainTip .pictrue .iconfont{position: absolute;right: 0.18rem;top: 0.18rem;color: #fff;font-size: 0.36rem;
    width: 0.5rem;height: 0.5rem;text-align: center;line-height: 0.5rem;}
.bargain .bargainTip .pictrue img{width:100%;height:100%;border-radius:0.2rem 0.2rem 0 0;}
.bargain .bargainTip .cutOff{font-size:0.3rem;color:#666;padding:0 0.29rem;text-align:center;margin-top:0.5rem;}
.bargain .bargainTip .cutOff.on{margin-top:0.26rem;}
.bargain .bargainTip .help{font-size:0.32rem;font-weight:bold;text-align:center;margin-top:0.4rem;}
.bargain .bargainTip .tipBnt{font-size:0.32rem;color:#fff;width:3.6rem;height:0.82rem;border-radius:0.41rem;
    background-image:linear-gradient(to right,#f67a38 0%,#f11b09 100%);
    background-image:-webkit-linear-gradient(to right,#f67a38 0%,#f11b09 100%);
    background-image:-moz-linear-gradient(to right,#f67a38 0%,#f11b09 100%);
    text-align:center;line-height:0.82rem;margin:0.5rem auto 0 auto;}
/*砍价记录*/
.bargain-record .item{background-color:#fff;margin-bottom:0.12rem;}
.bargain-record .item .picTxt{height:2.1rem;border-bottom:1px solid #f0f0f0;padding:0 0.3rem;}
.bargain-record .item .picTxt .pictrue{width:1.5rem;height:1.5rem;}
.bargain-record .item .picTxt .pictrue img{width:100%;height:100%;border-radius:0.06rem;}
.bargain-record .item .picTxt .text{width:5.15rem;font-size:0.3rem;color:#282828;height:1.5rem;}
.bargain-record .item .picTxt .text .time{font-size:0.24rem;color:#868686;}
.bargain-record .item .picTxt .text .time .styleAll{color:#fc4141;}
.bargain-record .item .picTxt .text .money{font-size:0.24rem;}
.bargain-record .item .picTxt .text .money .num{font-size:0.32rem;font-weight:bold;}
.bargain-record .item .picTxt .text .money .symbol{font-weight:bold;}
.bargain-record .item .bottom{height:1rem;padding:0 0.3rem;font-size:0.27rem;}
.bargain-record .item .bottom .purple{color:#f78513;}
.bargain-record .item .bottom .end{color:#999;}
.bargain-record .item .bottom .success{color:#e93323;}
.bargain-record .item .bottom .bnt{font-size:0.27rem;color:#fff;width:1.76rem;height:0.6rem;border-radius:0.06rem;
    text-align:center;line-height:0.6rem;}
.bargain-record .item .bottom .bnt.cancel{color:#aaa;border:1px solid #ddd;}
.bargain-record .item .bottom .bnt~.bnt{margin-left:0.18rem;}
/*拼团列表*/
.group-list .header{background-image:url('../images/group.png');background-repeat:no-repeat;background-size:100% 100%;
    width:100%;height:4.5rem;}
.group-list .list{margin-top:-1.08rem;}
.group-list .list .item{width:6.9rem;height:2.08rem;background-color:#fff;border-radius:0.06rem;padding:0 0.24rem;
    margin:0 auto 0.2rem auto;}
.group-list .list .item .pictrue{width:1.6rem;height:1.6rem;}
.group-list .list .item .pictrue img{width:100%;height:100%;border-radius:0.06rem;}
.group-list .list .item .text{width:4.58rem;font-size:0.3rem;color:#282828;}
.group-list .list .item .text .team{height:0.4rem;border-radius:0.04rem;font-size:0.22rem;margin-top:0.2rem;}
.group-list .list .item .text .team .iconfont{width:0.54rem;background-color:#ffdcd9;text-align:center;color:#dd3823;
    height:100%;line-height:0.38rem;}
.group-list .list .item .text .team .num{text-align:center;padding:0 0.1rem;}
.group-list .list .item .text .bottom{margin-top:0.07rem;}
.group-list .list .item .text .bottom .money{font-size:0.24rem;font-weight:bold;color:#282828;}
.group-list .list .item .text .bottom .money .num{font-size:0.32rem;}
.group-list .list .item .text .bottom .money .y-money{font-size:0.24rem;color:#999;font-weight:normal;
    text-decoration:line-through;margin-left:0.1rem;}
.group-list .list .item .text .bottom .groupBnt{font-size:0.26rem;color:#fff;width:1.46rem;height:0.54rem;text-align:center;
    line-height:0.54rem;border-radius:0.04rem;}
.group-list .list .item .text .bottom .groupBnt .iconfont{font-size:0.25rem;margin-left:0.1rem;}
/*拼团商品详情*/
.product-con .wrapper .share .money .y-money {color:#82848f;margin-left:0.13rem;text-decoration:line-through;
    font-weight:normal;}
.product-con .notice{width:100%;height:0.62rem;background-color:#ffedeb;margin-top:0.2rem;padding:0 0.3rem;}
.product-con .notice .num{font-size:0.24rem;}
.product-con .notice .num .iconfont{font-size:0.3rem;vertical-align:-0.03rem;margin-right:0.2rem;}
.product-con .notice .num .line{color:#282828;margin-left:0.15rem;}
.product-con .notice .swiper{height:100%;width:4.7rem;line-height:0.62rem;overflow:hidden;margin-left:0.14rem;}
.product-con .notice .swiper .swiper-slide{height:100%;width:100%;overflow:hidden;font-size:0.24rem;color:#282828;}
.product-con .assemble{background-color:#fff;}
.product-con .assemble .item{padding-right:0.3rem;margin-left:0.3rem;border-bottom:1px solid #f0f0f0;height:1.32rem;}
.product-con .assemble .item .pictxt{width:2.95rem;}
.product-con .assemble .item .pictxt .text{width:1.94rem;}
.product-con .assemble .item .pictxt .pictrue{width:0.8rem;height:0.8rem;}
.product-con .assemble .item .pictxt .pictrue img{width:100%;height:100%;border-radius:50%;}
.product-con .assemble .item .right .lack{font-size:0.24rem;color:#333333;text-align: right;}
.product-con .assemble .item .right .time{font-size:0.22rem;color:#82848f;margin-top:0.05rem;}
.product-con .assemble .item .right .spellBnt{font-size:0.24rem;color:#fff;width:1.4rem;height:0.5rem;border-radius:0.5rem;
    background-image: linear-gradient(to right,#ff2358 0%,#ff0000 100%);
    background-image: -webkit-linear-gradient(to right,#ff2358 0%,#ff0000 100%);
    background-image: -moz-linear-gradient(to right,#ff2358 0%,#ff0000 100%);
    text-align:center;line-height:0.5rem;margin-left:0.3rem;}
.product-con .assemble .item .right .spellBnt .iconfont{font-size:0.2rem;margin-left:0.05rem;}
.product-con .assemble .more{font-size:0.24rem;color:#282828;text-align:center;height:0.9rem;line-height:0.9rem;}
.product-con .assemble .more .iconfont{margin-left:0.13rem;font-size:0.25rem;}
.product-con .playWay{background-color:#fff;padding:0 0.3rem;margin-top:0.2rem;font-size:0.28rem;color:#282828;}
.product-con .playWay .title{height:0.86rem;border-bottom:1px solid #eee;}
.product-con .playWay .title .iconfont{margin-left:0.13rem;font-size:0.28rem;color:#717171;}
.product-con .playWay .way{min-height:1.1rem;font-size:0.26rem;color:#282828;}
.product-con .playWay .way .iconfont{color:#cdcdcd;font-size:0.4rem;margin:0 0.35rem;}
.product-con .playWay .way .item .num{font-size:0.3rem;margin-right:0.06rem;}
.product-con .playWay .way .item .tip{font-size:0.22rem;color:#a5a5a5;}
.product-con .footer-group{position:fixed;bottom:0;width:100%;height:1rem;background-color:#fff;font-size:0.18rem;color:#666;
    z-index:99;}
.product-con .footer-group .customerSer{width:14%;font-size:0.2rem;color:#666;}
.product-con .footer-group .customerSer .iconfont{font-size:0.35rem;}
.product-con .footer-group .bnt{width:86%;text-align:center;line-height:1rem;height:100%;color:#fff;font-size:0.3rem;}
.product-con .superior .slider-banner .swiper-pagination-bullet {background-color: #999;}
.product-con .superior .slider-banner .swiper-pagination-bullet-active {background-color: #e93323;}
.product-con .superior .slider-banner .swiper-container-horizontal>.swiper-pagination-bullets{bottom:0;}
/*开团*/
.group-con .header{width:100%;height:1.86rem;background-color:#fff;border-top:1px solid #f5f5f5;padding:0 0.3rem;
position:relative;}
.group-con .header .iconfont{font-size:1rem;position:absolute;color:#ccc;right:0.33rem;bottom:0.2rem;}
.group-con .header .pictrue{width:1.4rem;height:1.4rem;}
.group-con .header .pictrue img{width:100%;height:100%;border-radius:0.06rem;}
.group-con .header .text{width:5.25rem;font-size:0.3rem;color:#222;}
.group-con .header .text .money{font-size:0.24rem;font-weight:bold;margin-top:0.15rem;}
.group-con .header .text .money .num{font-size:0.32rem;}
.group-con .header .text .money .team{padding:0.01rem 0.1rem;font-weight:normal;border-radius:0.5rem;font-size:0.2rem;vertical-align:0.04rem;margin-left:0.15rem;}
.group-con .wrapper{background-color:#fff;margin-top:0.2rem;padding:0.02rem 0 0.35rem 0;}
.group-con .wrapper .title{margin-top:0.3rem;}
.group-con .wrapper .title .line{width:1.36rem;height:1px;background-color:#ddd;}
.group-con .wrapper .title .name{margin:0 0.45rem;font-size:0.28rem;color:#282828;}
.group-con .wrapper .title .name .time{margin:0 0.14rem;}
.group-con .wrapper .title .name .timeTxt{color:#fc4141;}
.group-con .wrapper .title .name .time .styleAll{background-color:#ffcfcb;text-align:center;border-radius:0.03rem;font-size:0.28rem;font-weight:bold;display: inline-block;vertical-align: middle;color:#fc4141;padding: 0.02rem 0.05rem;}
.group-con .wrapper .tips{font-size:0.3rem;font-weight:bold;text-align:center;margin-top:0.3rem;color:#999;}
.group-con .wrapper .list{padding:0 0.3rem;margin-top:0.45rem;}
.group-con .wrapper .list.result{max-height:2.4rem;overflow:hidden;}
.group-con .wrapper .list.result.on{max-height:20rem;}
.group-con .wrapper .list .pictrue{width:0.94rem;height:0.94rem;margin:0 0 0.29rem 0.35rem;}
.group-con .wrapper .list .pictrue img{width:100%;height:100%;border-radius:50%;border:0.02rem solid #e93323;}
.group-con .wrapper .list .pictrue img.img-none{border:none;}
.group-con .wrapper .lookAll{font-size:0.24rem;color:#282828;padding-top:0.1rem;}
.group-con .wrapper .lookAll .iconfont{font-size:0.25rem;margin:0.02rem 0 0 0.1rem;}
.group-con .wrapper .teamBnt{font-size:0.3rem;width:6.2rem;height:0.86rem;border-radius:0.5rem;text-align:center;
    line-height:0.86rem;color:#fff;margin:0.21rem auto 0 auto;}
.group-con .wrapper .cancel,.group-con .wrapper .lookOrder{text-align:center;font-size:0.24rem;color:#282828;
    padding-top:0.3rem;}
.group-con .wrapper .cancel .iconfont{font-size:0.35rem;color:#2c2c2c;vertical-align:-0.04rem;margin-right:0.09rem;}
.group-con .wrapper .lookOrder .iconfont{font-size:0.25rem;color:#2c2c2c;margin-left:0.1rem;}
.group-con .group-recommend{background-color:#fff;margin-top:0.25rem;}
.group-con .group-recommend .title{padding-right:0.3rem;margin-left:0.3rem;height:0.85rem;border-bottom:1px solid #eee;
    font-size:0.28rem;color:#282828;}
.group-con .group-recommend .title .more{color:#808080;}
.group-con .group-recommend .title .more .iconfont{margin-left:0.13rem;font-size:0.28rem;}
.group-con .group-recommend .list{margin-top:0.3rem;}
.group-con .group-recommend .list .item{width:2.1rem;margin:0 0 0.25rem 0.3rem;}
.group-con .group-recommend .list .item .pictrue{width:100%;height:2.1rem;position:relative;}
.group-con .group-recommend .list .item .pictrue img{width:100%;height:100%;border-radius:0.1rem;}
.group-con .group-recommend .list .item .pictrue .team{position:absolute;top:0.28rem;left:-0.05rem;min-width:1rem;
    height:0.36rem;line-height:0.36rem;text-align:center;border-radius:0 0.18rem 0.18rem 0;font-size:0.2rem;color:#fff;
    background-image:linear-gradient(to right,#fb5445 0%,#e93323 100%);
    background-image:-webkit-linear-gradient(to right,#fb5445 0%,#e93323 100%);
    background-image:-moz-linear-gradient(to right,#fb5445 0%,#e93323 100%);}
.group-con .group-recommend .list .item .name{font-size:0.28rem;color:#333;margin-top:0.18rem;}
.group-con .group-recommend .list .item .money{font-weight:bold;font-size:0.26rem;}
/*商品评分*/
.evaluate-list .generalComment{height:0.94rem;padding:0 0.3rem;background-color:#fff;font-size:0.28rem;
    color:#808080;}
.evaluate-list .generalComment .evaluate{margin-right:0.07rem;}
.evaluate-list .nav{font-size:0.24rem;color:#282828;padding:0 0.3rem 0.15rem 0.3rem;background-color:#fff;border-bottom:1px solid #f5f5f5;}
.evaluate-list .nav .item{font-size:0.24rem;color:#282828;border-radius:0.06rem;height:0.54rem;padding:0 0.2rem;
    background-color:#f4f4f4;line-height:0.54rem;margin:0 0.17rem 0.17rem 0;}
.evaluate-list .nav .item.bg-color-red{color:#fff;}
/*商品评价*/
.evaluate-con .score{background-color:#fff;border-top:1px solid #f5f5f5;font-size:0.28rem;color:#282828;
    padding:0.48rem 0.3rem 0.65rem 0.3rem;}
.evaluate-con .score .item~.item{margin-top:0.25rem;}
.evaluate-con .score .item .starsList{padding:0 0.35rem 0 0.4rem;}
.evaluate-con .score .item .starsList .iconfont{font-size:0.4rem;color:#aaa;}
.evaluate-con .score .item .starsList .iconfont~.iconfont{margin-left:0.2rem;}
.evaluate-con .score .item .evaluate{color:#aaa;font-size:0.24rem;}
.evaluate-con .score .textarea{width:6.9rem;background-color:#fafafa;border-radius:0.1rem;margin-top:0.48rem;}
.evaluate-con .score .textarea textarea{font-size:0.28rem;padding:0.38rem 0.3rem 0 0.3rem;width:100%;
    height:1.6rem;}
.evaluate-con .score .textarea textarea::placeholder{color:#bbb;}
.evaluate-con .score .textarea .list{margin-top:0.25rem;padding-left:0.05rem;}
.evaluate-con .score .textarea .list .pictrue{width:1.4rem;height:1.4rem;margin:0 0 0.35rem 0.25rem;position:relative;
    font-size:0.22rem;color:#bbb;}
.evaluate-con .score .textarea .list .pictrue img{width:100%;height:100%;border-radius:0.03rem;}
.evaluate-con .score .textarea .list .pictrue .icon-guanbi1{font-size:0.45rem;position:absolute;top:-0.2rem;right:-0.2rem;}
.evaluate-con .score .textarea .list .pictrue .icon-icon25201{color:#bfbfbf;font-size:0.5rem;}
.evaluate-con .score .evaluateBnt{font-size:0.3rem;color:#fff;width:6.9rem;height:0.86rem;border-radius:0.43rem;
    text-align:center;line-height:0.86rem;margin-top:0.45rem;}
/*签到*/
.sign .header{width:100%;height:3.1rem;}
.sign .header .headerCon{padding:0 0 0 0.3rem;height:2.34rem;}
.sign .header .headerCon .left{width:5.3rem;font-size:0.32rem;color:#fff;font-weight:bold;}
.sign .header .headerCon .left .integral span{font-size:0.24rem;margin-top:0.19rem;background-color:#ff9000;
    text-align:center;border-radius:0.06rem;font-weight:normal;padding:0.06rem 0.15rem;}
.sign .header .headerCon .text{width:4.1rem;}
.sign .header .headerCon .left .pictrue{width:0.86rem;height:0.86rem;border-radius:50%;border:0.04rem solid #ecddbc;}
.sign .header .headerCon .left .pictrue img{width:100%;height:100%;border-radius:50%;}
.sign .header .headerCon .right{width:1.42rem;height:0.66rem;background-color:#fff;border-radius:0.5rem 0 0 0.5rem;
    font-size:0.24rem;color:#ff9000;}
.sign .header .headerCon .right .iconfont{font-size:0.33rem;padding:0 0.1rem 0 0.3rem;height: 0.35rem;line-height: 0.35rem;}
.sign .wrapper{background-color:#fff;margin:-0.8rem 0.2rem 0 0.2rem;border-radius:0.15rem;padding-bottom:0.8rem;
    position:relative;}
.sign .wrapper .list{padding:0 0.3rem;height:2.4rem;}
.sign .wrapper .list .item{font-size:0.22rem;color:#8a8886;text-align:center;}
.sign .wrapper .list .item .rewardTxt{width:0.74rem;height:0.32rem;background-color:#f4b409;border-radius:0.16rem;
    font-size:0.2rem;color:#a57d3f;line-height:0.32rem;}
.sign .wrapper .list .item .num{font-size:0.3rem;color:#999;}
.sign .wrapper .list .item .num.on{color:#ff9000;}
.sign .wrapper .list .item .venus{background-image:url('../images/stars2.png');background-repeat:no-repeat;
    background-size:100% 100%;width:0.56rem;height:0.56rem;margin:0.1rem 0;}
.sign .wrapper .list .item .venus.venusSelect{background-image:url('../images/stars1.png');}
.sign .wrapper .list .item .venus.reward{background-image:url('../images/stars3.png');width:0.75rem;height:0.56rem;}
.sign .wrapper .but{width:4rem;height:0.76rem;font-size:0.3rem;line-height:0.76rem;color:#fff;border-radius:0.5rem;text-align:center;margin:0 auto;}
.sign .wrapper .but.on{background-color:#999!important;}
.sign .wrapper .lock{background-image:url('../images/lock2.png');background-repeat:no-repeat;background-size:100% 100%;width:5.58rem;height:0.68rem;position:absolute;left:50%;transform: translateX(-50%);-webkit-transform: translateX(-50%);-ms-transform: translateX(-50%);-moz-transform: translateX(-50%);-o-transform: translateX(-50%);bottom:-0.41rem;z-index:9;}
.sign .wrapper2{margin-top:0.15rem;padding:0.73rem 0 0 0;}
.sign .wrapper2 .tip{font-size:0.3rem;color:#666;text-align:center;}
.sign .wrapper2 .list2{margin:0.45rem 0 0.49rem 0;}
.sign .wrapper2 .list2 .item{width:0.8rem;height:1.16rem;background-repeat:no-repeat;background-size:100% 100%;color:#fff;
    font-size:0.72rem;text-align:center;line-height:1.16rem;margin-right:0.19rem;background-image:url('../images/redBg.png');}
.sign .wrapper2 .list2 .data{font-size:0.30rem;color:#232323;}
.sign .wrapper2 .tip2{font-size:0.3rem;color:#999999;padding:0 0.55rem;text-align:center;line-height:1.5;}
.sign .list3{margin:0.45rem 0.37rem 0 0.37rem;border-top:1px dashed #eee;}
.sign .list3 .item{border-bottom:1px solid #eee;height:1.3rem;}
.sign .list3 .item .name{color:#232323;font-size:0.3rem;width:4rem;}
.sign .list3 .item .data{font-size:0.24rem;color:#bbbbbb;margin-top:0.09rem;}
.sign .list3 .item .num{font-size:0.36rem;font-family: 'GuildfordProBook 5';}
.sign .signTip{width:6.44rem;height:6.45rem;position:fixed;top:50%;left:50%;margin-left:-3.22rem;margin-top:-3.225rem;z-index:99;text-align:center;transition:all 0.3s ease-in-out 0s;-webkit-transition:all 0.3s ease-in-out 0s;-moz-transition:all 0.3s ease-in-out 0s;-o-transition:all 0.3s ease-in-out 0s;opacity:0;transform: scale(0);-webkit-transform: scale(0);-ms-transform: scale(0);-moz-transform: scale(0);-o-transform: scale(0);}
.sign .signTip .signTipLight{background-image:url('../images/light.png');background-repeat:no-repeat;background-size:100% 100%;width:100%;height:100%;}
.sign .signTip.on{opacity:1;transform: scale(1);-webkit-transform: scale(1);-ms-transform: scale(1);-moz-transform: scale(1);-o-transform: scale(1);}
.sign .signTip .signTipCon{background-image:url('../images/register.png');background-repeat:no-repeat;background-size:100% 100%;width:4.2rem;height:4.2rem;margin-top:-7rem;position:relative;}
.sign .signTip .signTipCon .state{font-size:0.34rem;color:#fff;margin-top:1.5rem;}
.sign .signTip .signTipCon .integral{font-size:0.3rem;color:rgba(255,255,255,0.6);margin-top:0.09rem;}
.sign .signTip .signTipCon .signTipBnt{font-size:0.3rem;color:#eb4331;width:2.6rem;height:0.76rem;background-color:#f8d168;border-radius:0.38rem;line-height:0.76rem;margin:0.48rem auto 0 auto;}
/*签到记录、账单明细列表*/
.sign-record .list .item .data{height:0.8rem;line-height:0.8rem;padding:0 0.3rem;font-size:0.24rem;color:#666;}
.sign-record .list .item .listn{background-color:#fff;font-size:0.24rem;color:#999;}
.sign-record .list .item .listn .itemn{height:1.2rem;border-bottom:1px solid #eee;padding-right:0.3rem;margin-left:0.3rem;}
.sign-record .list .item .listn .itemn .name{width:3.9rem;font-size:0.28rem;color:#282828;margin-bottom:0.06rem;}
.sign-record .list .item .listn .itemn .num{font-size:0.36rem;font-family: 'GuildfordProBook 5';color:#16ac57;}
/*申请退货*/
.apply-return .list{background-color:#fff;margin-top:0.18rem;}
.apply-return .list .item{margin-left:0.3rem;padding-right:0.3rem;min-height:0.9rem;border-bottom:1px solid #eee;font-size:0.3rem;color:#333;}
.apply-return .list .item .num{color:#282828;width:4.27rem;text-align:right;position:relative;}
.apply-return .list .item .num select{width:100%;white-space:pre-wrap;direction: rtl;padding-right:0.42rem;z-index:5;}
.apply-return .list .item .num .iconfont{color:#666;font-size:0.3rem;position:absolute;right:0;top:50%;transform:translateY(-50%);-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);-moz-transform:translateY(-50%);-o-transform:translateY(-50%);}
.apply-return .list .item.textarea{padding:0.3rem 0.3rem 0.3rem 0;}
.apply-return .list .item textarea{height:1rem;font-size:0.3rem;}
.apply-return .list .item textarea::placeholder{color:#bbb;}
.apply-return .list .item .title{height:0.95rem;width:100%;}
.apply-return .list .item .title .tip{font-size:0.3rem;color:#bbb;}
.apply-return .list .item .upload{padding-bottom:0.36rem;}
.apply-return .list .item .upload .pictrue{margin:0.22rem 0.23rem 0 0;width:1.56rem;height:1.56rem;position:relative;font-size:0.24rem;color:#bbb;border: 1px solid #bbb;}
.apply-return .list .item .upload .pictrue:nth-of-type(4n){margin-right:0;}
.apply-return .list .item .upload .pictrue img{width:100%;height:100%;border-radius:0.03rem;}
.apply-return .list .item .upload .pictrue .icon-guanbi1{position:absolute;font-size:0.45rem;top:-0.1rem;right:-0.1rem;
    width: 0.45rem;height: 0.45rem;line-height: 0.45rem;}
.apply-return .list .item .upload .pictrue .icon-icon25201{color:#bfbfbf;font-size:0.5rem;width: 0.5rem;height: 0.6rem;
    line-height: 0.6rem;}
.apply-return .list .item .upload .pictrue:nth-last-child(1){border:1px solid #ddd;}
.apply-return .returnBnt{font-size:0.32rem;color:#fff;width:6.9rem;height:0.86rem;border-radius:0.5rem;text-align:center;line-height:0.86rem;margin:0.43rem auto;}
/*退货列表*/
.return-list .goodWrapper{background-color:#fff;margin-bottom:0.13rem;position:relative;}
.return-list .goodWrapper .orderNum{padding:0 0.3rem;border-bottom:1px solid #eee;height:0.87rem;line-height:0.87rem;font-size:0.3rem;color:#282828;}
.return-list .goodWrapper .item{border-bottom:0;}
.return-list .goodWrapper .totalSum{padding:0 0.3rem 0.32rem 0.3rem;text-align:right;font-size:0.26rem;color:#282828;}
.return-list .goodWrapper .totalSum .price{font-size:0.28rem;font-weight:bold;}
.return-list .goodWrapper .iconfont{position:absolute;font-size:1.09rem;top:0.07rem;right:0.3rem;color:#ccc;width: 1.09rem;
    height: 1.09rem;line-height: 1.09rem;}
.return-list .goodWrapper .iconfont.powder{color:#f8c1bd;}
/*收藏商品*/
.collectionGoods{background-color:#fff;border-top:1px solid #eee;}
.collectionGoods .item{margin-left:0.3rem;padding-right:0.3rem;border-bottom:1px solid #eee;height:1.8rem;}
.collectionGoods .item .pictrue{width:1.3rem;height:1.3rem;}
.collectionGoods .item .pictrue img{width:100%;height:100%;border-radius:0.06rem;}
.collectionGoods .item .text{width:5.35rem;height:1.3rem;font-size:0.28rem;color:#282828;}
.collectionGoods .item .text .infor{width:100%;}
.collectionGoods .item .text .money{font-size:0.26rem;}
.collectionGoods .item .text .delete{font-size:0.26rem;color:#282828;width:1.14rem;height:0.46rem;border:1px solid #bbb;border-radius:0.04rem;text-align:center;line-height:0.46rem;}
/*搜索商品*/
.searchGood .search{padding-left:0.3rem;}
.searchGood .search{margin-top:0.2rem;}
.searchGood .search .input{width:5.98rem;background-color:#f7f7f7;border-radius:0.33rem;padding:0 0.35rem;height:0.66rem;}
.searchGood .search .input input{width:4.72rem;font-size:0.28rem;}
.searchGood .search .input input::placeholder{color:#bbb;}
.searchGood .search .input .iconfont{color:#000;font-size:0.35rem;}
.searchGood .search .bnt{width:1.2rem;text-align:center;height:0.66rem;line-height:0.66rem;font-size:0.3rem;color:#282828;}
.searchGood .title{font-size:0.28rem;color:#999;margin:0.5rem 0.3rem 0.25rem 0.3rem;}
.searchGood .list{padding-left:0.1rem;}
.searchGood .list .item{font-size:0.26rem;color:#454545;padding:0 0.21rem;height:0.6rem;border-radius:0.03rem;line-height:0.6rem;border:1px solid #aaa;margin:0 0 0.2rem 0.2rem;}
.searchGood .line{border-bottom:1px solid #eee;margin:0.2rem 0.3rem 0 0.3rem;}
/*银行卡提现*/
.cash-withdrawal .nav{height:1.3rem;box-shadow:0 0.1rem 0.1rem #f8f8f8;-webkit-box-shadow:0 0.1rem 0.1rem #f8f8f8;
    -moz-box-shadow: 0 0.1rem 0.1rem #f8f8f8;-o-box-shadow:0 0.1rem 0.1rem #f8f8f8;}
.cash-withdrawal .nav .item{font-size:0.26rem;flex:1;-webkit-flex:1;-o-flex:1;-ms-flex:1;text-align:center;}
.cash-withdrawal .nav .item~.item{border-left:1px solid #f0f0f0;}
.cash-withdrawal .nav .item .iconfont{width:0.4rem;height:0.4rem;border-radius:50%;border:0.02rem solid #e93323;text-align:center;line-height:0.37rem;margin:0 auto 0.06rem auto;font-size:0.22rem;}
.cash-withdrawal .nav .item .iconfont.on{background-color:#e93323;color:#fff;border-color:#e93323;}
.cash-withdrawal .nav .item .line{width:0.02rem;height:0.2rem;margin:0 auto;transition:height 0.3s;-webkit-transition:height 0.3s;-moz-transition:height 0.3s;-o-transition:height 0.3s;}
.cash-withdrawal .nav .item .line.on{height:0.39rem;}
.cash-withdrawal .wrapper .list{padding:0 0.3rem;}
.cash-withdrawal .wrapper .list .item{border-bottom:1px solid #eee;height:1.07rem;font-size:0.3rem;color:#333;}
.cash-withdrawal .wrapper .list .item .name{width:1.3rem;}
.cash-withdrawal .wrapper .list .item .input{width:5.05rem;}
.cash-withdrawal .wrapper .list .item .input input::placeholder{color:#bbb;}
.cash-withdrawal .wrapper .list .tip{font-size:0.26rem;color:#999;margin-top:0.25rem;}
.cash-withdrawal .wrapper .list .bnt{font-size:0.32rem;color:#fff;width:6.9rem;height:0.9rem;text-align:center;border-radius:0.5rem;line-height:0.9rem;margin:0.64rem auto;}
.cash-withdrawal .wrapper .list .tip2{font-size:0.26rem;color:#999;text-align:center;margin:0.44rem 0 0.2rem 0;}
.cash-withdrawal .wrapper .list .value{height:1.35rem;line-height:1.35rem;border-bottom:1px solid #eee;width:6.9rem;margin:0 auto;}
.cash-withdrawal .wrapper .list .value input{font-size:0.8rem;color:#282828;height:1.35rem;text-align:center;width: 100%;}
.cash-withdrawal .wrapper .list .value input::placeholder{color:#bbb;}
/*提现审核*/
.cash-audit{width:7.1rem;background-color:#fff;border-radius:0.06rem;margin:0.25rem auto 0 auto;padding:0.53rem 0 0.58rem 0;left: 50%;margin-left: -3.55rem;}
.cash-audit .pictrue{width:2.14rem;height:1.79rem;margin:0 auto;}
.cash-audit .pictrue img{width:100%;height:100%;}
.cash-audit .tip{font-size:0.32rem;color:#282828;margin-top:0.4rem;text-align:center;padding:0 0.4rem;}
.cash-audit .time{font-size:0.26rem;color:#999;text-align:center;margin-top:0.15rem;}
.cash-audit .bnt{font-size:0.32rem;color:#fff;width:5rem;height:0.86rem;border-radius:0.43rem;text-align:center;line-height:0.86rem;margin:0.5rem auto 0 auto;}
/*推广人订单*/
.promoter-order .list .item .title{height:1.33rem;padding:0 0.3rem;font-size:0.26rem;color:#999;}
.promoter-order .list .item .title .data{font-size:0.28rem;color:#282828;margin-bottom:0.05rem;}
.promoter-order .list .item .listn .itenm{background-color:#fff;}
.promoter-order .list .item .listn .itenm~.itenm{margin-top:0.12rem;}
.promoter-order .list .item .listn .itenm .top{margin-left:0.3rem;padding-right:0.3rem;border-bottom:1px solid #eee;height:1rem;}
.promoter-order .list .item .listn .itenm .top .pictxt{width:3.2rem;}
.promoter-order .list .item .listn .itenm .top .pictxt .text{width:2.3rem;font-size:0.3rem;color:#282828;}
.promoter-order .list .item .listn .itenm .top .pictxt .pictrue{width:0.66rem;height:0.66rem;}
.promoter-order .list .item .listn .itenm .top .pictxt .pictrue img{width:100%;height:100%;border-radius:50%;border:0.03rem solid #fff;box-shadow:0 0 0.1rem #aaa;-webkit-box-shadow:0 0 0.1rem #aaa;-moz-box-shadow:0 0 0.1rem #aaa;-o-box-shadow:0 0 0.1rem #aaa;-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;}
.promoter-order .list .item .listn .itenm .top .money{font-size:0.28rem;}
.promoter-order .list .item .listn .itenm .bottom{padding:0.2rem 0.3rem;font-size:0.28rem;color:#666;line-height:1.6;}
.promoter-order .list .item .listn .itenm .bottom .name{color:#999;}
/*推广人列表*/
.promoter-list .header{padding-bottom: 0.12rem;}
.promoter-list .nav{background-color:#fff;height:0.86rem;line-height:0.86rem;font-size:0.28rem;color:#282828;border-bottom:1px solid #eee;}
.promoter-list .nav .item{height:100%;}
.promoter-list .nav .item.on{color:#e93323;border-bottom:0.05rem solid #e93323;}
.promoter-list .search{width:100%;background-color:#fff;height:0.86rem;padding:0 0.3rem;}
.promoter-list .search .input{width:6.3rem;height:0.6rem;border-radius:0.5rem;background-color:#f5f5f5;text-align:center;position:relative;}
.promoter-list .search .input input{height:100%;font-size:0.26rem;width:6.2rem;text-align:center;}
.promoter-list .search .input input::placeholder{color:#bbb;}
.promoter-list .search .input .iconfont{position:absolute;right:0.28rem;color:#999;font-size:0.28rem;top:50%;transform:translateY(-50%);-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);-moz-transform:translateY(-50%);-o-transform:translateY(-50%);}
.promoter-list .search .iconfont{font-size:0.4rem;color:#515151;}
.promoter-list .list .sortNav{background-color:#fff;height:0.76rem;border-bottom:1px solid #eee;color:#333;font-size:0.28rem;}
.promoter-list .list .sortNav.on{position: fixed;top: 0;left: 0;width: 100%;z-index: 5;}
.promoter-list .list .sortNav .sortItem{text-align:center;flex:1;-webkit-flex:1;-o-flex:1;-ms-flex:1;}
.promoter-list .list .sortNav .sortItem img{width:0.24rem;height:0.24rem;margin-left:0.06rem;vertical-align:-0.03rem;}
.promoter-list .list .sortList{margin-top:0.76rem;}
.promoter-list .list .item{background-color:#fff;border-bottom:1px solid #eee;height:1.52rem;padding:0 0.3rem 0 0.2rem;font-size:0.24rem;color:#666;}
.promoter-list .list .item .picTxt{width:4.4rem;}
.promoter-list .list .item .picTxt .pictrue{width:1.06rem;height:1.06rem;border-radius:50%;}
.promoter-list .list .item .picTxt .pictrue img{width:100%;height:100%;border-radius:50%;border:0.03rem solid #fff;box-shadow:0 0 0.07rem #aaa;-webkit-box-shadow:0 0 0.07rem #aaa;-moz-box-shadow:0 0 0.07rem #aaa;-o-box-shadow:0 0 0.07rem #aaa;
    -webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;}
.promoter-list .list .item .picTxt .text{width:3.04rem;font-size:0.24rem;color:#666;}
.promoter-list .list .item .picTxt .text .name{font-size:0.28rem;color:#333;margin-bottom:0.13rem;}
.promoter-list .list .item .right{width:2.4rem;text-align:right;font-size:0.22rem;color:#333;}
/*我的推广*/
.my-promotion .header{background-image:url("../images/promotionBg.png");background-repeat:no-repeat;background-size:100% 100%;width:100%;height:3.75rem;}
.my-promotion .header .name{font-size:0.3rem;color:#fff;padding-top:0.57rem;position:relative;}
.my-promotion .header .name .record{font-size:0.26rem;color:rgba(255, 255, 255, 0.8);position:absolute;right:0.2rem;}
.my-promotion .header .name .record .iconfont{font-size:0.25rem;margin-left:0.1rem;}
.my-promotion .header .num{text-align:center;color:#fff;margin-top:0.25rem;font-size:0.9rem;font-family: 'GuildfordProBook 5';}
.my-promotion .header .profit{padding:0 0.2rem;margin-top:0.33rem;font-size:0.24rem;color:rgba(255, 255, 255, 0.8);}
.my-promotion .header .profit .item{min-width:2rem;text-align:center;}
.my-promotion .header .profit .item .money{font-size:0.34rem;color:#fff;}
.my-promotion .bnt{font-size:0.28rem;color:#fff;width:2.58rem;height:0.68rem;border-radius:0.5rem;text-align:center;line-height:0.68rem;margin:-0.32rem auto 0 auto;}
.my-promotion .list{padding:0 0.2rem;margin-top:0.1rem;}
.my-promotion .list .item{width:3.45rem;height:2.4rem;border-radius:0.2rem;background-color:#fff;margin-top:0.2rem;font-size:0.3rem;color:#666;}
.my-promotion .list .item .iconfont{font-size:0.7rem;background-image:linear-gradient(to right,#fc4d3d 0%,#e93323 100%);
    background-image:-webkit-linear-gradient(to right,#fc4d3d 0%,#e93323 100%);
    background-image:-moz-linear-gradient(to right,#fc4d3d 0%,#e93323 100%);
    -webkit-background-clip:text;-webkit-text-fill-color:transparent;margin-bottom:0.2rem;}
/*我的账户*/
.my-account .wrapper{background-color:#fff;padding:0.32rem 0 0.34rem 0;margin-bottom:0.14rem;}
.my-account .wrapper .header{width:6.9rem;height:3.3rem;
    background-image:linear-gradient(to right,#f33b2b 0%,#f36053 100%);
    background-image:-webkit-linear-gradient(to right,#f33b2b 0%,#f36053 100%);
    background-image:-moz-linear-gradient(to right,#f33b2b 0%,#f36053 100%);
    border-radius:0.16rem;margin:0 auto;color:rgba(255,255,255,0.6);font-size:0.24rem;}
.my-account .wrapper .header .headerCon{background-image:url('../images/accountBg.png');background-repeat:no-repeat;background-size:100%;height:100%;width:100%;padding:0.36rem 0 0.29rem 0;}
.my-account .wrapper .header .headerCon .account{padding:0 0.35rem;}
.my-account .wrapper .header .headerCon .account .assets .money{font-size:0.72rem;color:#fff;font-family: 'GuildfordProBook 5';margin-top: 0.1rem;height: 0.75rem;line-height: 0.75rem;}
.my-account .wrapper .header .headerCon .account .recharge{font-size:0.28rem;width:1.5rem;height:0.54rem;border-radius:0.27rem;background-color:#fff9f8;text-align:center;line-height:0.54rem;}
.my-account .wrapper .header .headerCon .cumulative{margin-top:0.46rem;}
.my-account .wrapper .header .headerCon .cumulative .item{flex:1;-webkit-flex:1;-o-flex:1;-ms-flex:1;padding-left:0.35rem;}
.my-account .wrapper .header .headerCon .cumulative .item .money{font-size:0.48rem;font-family: 'GuildfordProBook 5';color:#fff;margin-top:0.06rem;}
.my-account .wrapper .nav{height:1.55rem;border-bottom:1px solid #f5f5f5;}
.my-account .wrapper .nav .item{flex:1;-webkit-flex:1;-o-flex:1;-ms-flex:1;text-align:center;font-size:0.26rem;color:#999;}
.my-account .wrapper .nav .item .pictrue{width:0.44rem;height:0.44rem;margin:0 auto;margin-bottom:0.2rem;}
.my-account .wrapper .nav .item .pictrue img{width:100%;height:100%;}
.my-account .wrapper .advert{padding:0 0.3rem;margin-top:0.3rem;}
.my-account .wrapper .advert .item{background-color:#fff6d1;width:3.32rem;height:1.18rem;border-radius:0.1rem;padding:0 0.27rem 0 0.25rem;font-size:0.24rem;color:#e44609;}
.my-account .wrapper .advert .item.on{background-color:#fff3f3;color:#e96868;}
.my-account .wrapper .advert .item .pictrue{width:0.78rem;height:0.78rem;}
.my-account .wrapper .advert .item .pictrue img{width:100%;height:100%;}
.my-account .wrapper .advert .item .text .name{font-size:0.3rem;font-weight:bold;color:#f33c2b;margin-bottom:0.07rem;}
.my-account .wrapper .advert .item.on .text .name{color:#f64051;}
.my-account .wrapper .list{padding:0 0.3rem;}
.my-account .wrapper .list .item{margin-top:0.44rem;}
.my-account .wrapper .list .item .picTxt .iconfont{width:0.82rem;height:0.82rem;border-radius:50%;background-image:linear-gradient(to right,#ff9389 0%,#f9776b 100%);
    background-image:-webkit-linear-gradient(to right,#ff9389 0%,#f9776b 100%);
    background-image:-moz-linear-gradient(to right,#ff9389 0%,#f9776b 100%);
    text-align:center;line-height:0.82rem;color:#fff;font-size:0.4rem;}
.my-account .wrapper .list .item .picTxt .iconfont.yellow{
    background-image:linear-gradient(to right,#ffccaa 0%,#fea060 100%);
    background-image:-webkit-linear-gradient(to right,#ffccaa 0%,#fea060 100%);
    background-image:-moz-linear-gradient(to right,#ffccaa 0%,#fea060 100%);}
.my-account .wrapper .list .item .picTxt .iconfont.green{
    background-image:linear-gradient(to right,#a1d67c 0%,#9dd074 100%);
    background-image:-webkit-linear-gradient(to right,#a1d67c 0%,#9dd074 100%);
    background-image:-moz-linear-gradient(to right,#a1d67c 0%,#9dd074 100%);}
.my-account .wrapper .list .item .picTxt{width:4.28rem;font-size:0.3rem;color:#282828;}
.my-account .wrapper .list .item .picTxt .text{width:3.17rem;}
.my-account .wrapper .list .item .picTxt .text .infor{font-size:0.24rem;color:#999;margin-top:0.05rem;}
.my-account .wrapper .list .item .bnt{font-size:0.26rem;color:#282828;width:1.56rem;height:0.52rem;border:1px solid #ddd;border-radius:0.26rem;text-align:center;line-height:0.5rem;}
.my-account .wrapper .list .item .bnt.end{font-size:0.26rem;color:#aaa;background-color:#f2f2f2;
    border-color:#f2f2f2;}
/*账单明细*/
.bill-details .nav{background-color:#fff;height:0.9rem;width:100%;line-height:0.9rem;}
.bill-details .nav .item{flex:1;-webkit-flex:1;-o-flex:1;-ms-flex:1;text-align:center;font-size:0.3rem;color:#282828;height:100%;}
.bill-details .nav .item.on{color:#e93323;border-bottom:0.03rem solid #e93323;}
/*限时抢购*/
.flash-sale .header{width:100%;height:2.4rem;}
.flash-sale .header img{width:100%;height:100%;}
.flash-sale .whiteFixed{position: fixed;top: 0;background-color: #fff;left: 0;width: 100%;z-index:5;}
.flash-sale .timeLsit{width:100%;white-space:nowrap;overflow: hidden;height: 1.1rem;}
.flash-sale .timeLsit .rush-time{overflow-y: hidden;overflow-x: auto;width: 100%;-webkit-overflow-scrolling: touch;height: 1.5rem;}
.flash-sale .timeLsit .item{display:inline-block;font-size:0.22rem;color:#282828;width:2rem;text-align:center;padding:0.11rem 0;height:0.96rem;background-color:#efc58f;}
.flash-sale .timeLsit .item~.item{border-left:1px solid #e3b06e;}
.flash-sale .timeLsit .item .time{font-size:0.32rem;font-weight:bold;height:0.37rem;line-height:0.37rem;}
.flash-sale .timeLsit .item.on{background-color:#e93323;color:#fff;position:relative;}
.flash-sale .timeLsit .item.on::before{content:"";width: 0;height: 0;border-left: 0.08rem solid transparent;border-right: 0.08rem solid transparent;border-top:0.1rem solid #e93323;position:absolute;bottom:-0.09rem;z-index:99;left:50%;transform:translateX(-50%);-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);-moz-transform:translateX(-50%);-o-transform:translateX(-50%);}
.flash-sale .countDown{height:0.92rem;border-bottom:1px solid #f0f0f0;font-size:0.28rem;color:#282828;}
.flash-sale .countDown .timeTxt{color:#fc4141;}
.flash-sale .countDown .time{font-size:0.28rem;color:#282828}
.flash-sale .countDown .styleAll{font-size:0.28rem;font-weight:bold;background-color:#ffcfcb;padding:0.04rem 0.07rem;border-radius:0.03rem;color:#fc4141;}
.flash-sale .countDown .text{}
.flash-sale .list.on{margin-top:2.02rem;}
.flash-sale .list .item{padding:0 0.3rem;border-bottom:1px solid #f0f0f0;height:2.27rem;position:relative;}
.flash-sale .list .item .pictrue{width:1.66rem;height:1.66rem;}
.flash-sale .list .item .pictrue img{width:100%;height:100%;border-radius:0.06rem;}
.flash-sale .list .item .text{width:5rem;font-size:0.3rem;color:#333;height:1.66rem;}
.flash-sale .list .item .text .money{font-size:0.24rem;color:#282828;margin-top:-0.13rem;}
.flash-sale .list .item .text .money .num{font-size:0.34rem;font-weight:bold;}
.flash-sale .list .item .text .progress {overflow: hidden;background-color:#fff;width:2.6rem;border-radius:0.2rem;height:0.34rem;position:relative;}
.flash-sale .list .item .text .progress .bg-red{width: 0;height: 100%;transition: width 0.6s ease;-webkit-transition: width 0.6s ease;-moz-transition: width 0.6s ease;-o-transition: width 0.6s ease;background-color: #ffe3e1;}
.flash-sale .list .item .text .progress .piece{position:absolute;left:50%;transform:translate(-50%,-50%);-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);-moz-transform:translate(-50%,-50%);-o-transform:translate(-50%,-50%);top:49%;font-size:0.22rem;}
.flash-sale .list .item .grab{font-size:0.28rem;color:#fff;width:1.4rem;height:0.54rem;border-radius:0.04rem;text-align:center;line-height:0.54rem;position:absolute;right:0.3rem;bottom:0.3rem;}
/*抢购详情页*/
.product-con .nav{background-image:url('../images/rushBuy.jpg');background-repeat:no-repeat;background-size:100% 100%;width:100%;height:1rem;padding:0 0.3rem;}
.product-con .nav .money{font-size:0.28rem;color:#fff;}
.product-con .nav .money .num{font-size:0.48rem;}
.product-con .nav .money .y-money{font-size:0.26rem;margin-left:0.1rem;text-decoration:line-through;}
.product-con .nav .times{font-size:0.2rem;color:#fff;text-align:center;margin-bottom: 0.04rem;}
.product-con .nav .times .time{margin-top:0.07rem;}
.product-con .nav .times .time .styleAll{padding:0 0.07rem;font-size:0.22rem;color:#ff3d3d;background-color:#fff;border-radius:0.02rem;}
.product-con .nav .iconfont{color:#fff;font-size:0.3rem;margin-left:0.2rem;}
.product-con .wrapperRush{padding:0.32rem 0.3rem;background-color:#fff;}
.product-con .wrapperRush .introduce .infor{width:5.7rem;font-size: 0.32rem;font-weight: bold;}
.product-con .wrapperRush .introduce .iconfont{font-size:0.37rem;color:#515151;}
.product-con .wrapperRush .label{margin:0.18rem 0 0 0;font-size:0.24rem;color:#82848f;}
.product-con .wrapperRush .label .stock{width:2.55rem;margin-right:0.28rem;}
.product-con .footerRush{position:fixed;bottom:0;width:100%;height:1rem;background-color:#fff;font-size:0.18rem;color:#666;z-index:99;}
.product-con .footerRush .customerSer{width:14%;font-size:0.2rem;color:#666;}
.product-con .footerRush .bnt{width:86%;text-align:center;line-height:1rem;height:100%;color:#fff;font-size:0.3rem;}
/*新闻*/
.newsList .swiperNews{width:6.9rem;height:3.67rem;margin:0.3rem auto 0 auto;}
.newsList .swiperNews .swiper-slide{width:100%;height:3.3rem;}
.newsList .swiperNews .slide-image{width:100%;height:100%;border-radius:0.06rem;}
.newsList .swiperNews .swiper-pagination-bullet{width:0.12rem;height:0.12rem;border-radius:0;transform: rotate(-45deg);-webkit-transform: rotate(-45deg);-ms-transform: rotate(-45deg);-moz-transform: rotate(-45deg);-o-transform: rotate(-45deg);transform-origin: 0 100%;-webkit-transform-origin:0 100%;-ms-transform-origin:0 100%;-moz-transform-origin:0 100%;-o-transform-origin:0 100%;background-color:#d1d1d1;opacity:1;margin:0 0.1rem;}
.newsList .swiperNews .swiper-pagination-bullet-active{background-color:#666666;border:0;}
.newsList .swiperNews .swiper-pagination{bottom:-0.07rem;width:100%;}
.newsList .nav{padding:0 0.3rem;width:100%;height:1.05rem;overflow:hidden;background-color:#fff;}
.newsList .nav.on{position:fixed;top:0;left:0;width:100%;z-index:5;}
.newsList .nav .scrollNav{white-space:nowrap;overflow-y:hidden;overflow-x:auto;-webkit-overflow-scrolling:touch;width:100%;}
.newsList .nav .item{display:inline-block;font-size:0.32rem;color:#999;margin-top:0.4rem;}
.newsList .nav .item.on{color:#282828;}
.newsList .nav .item~.item{margin-left:0.46rem;}
.newsList .nav .item .line{width:0.24rem;height:0.04rem;border-radius:0.02rem;margin:0.1rem auto 0 auto;}
.newsList .list.on{margin-top:1.05rem;}
.newsList .list .item{margin:0 0.3rem;border-bottom:1px solid #f0f0f0;padding:0.35rem 0;}
.newsList .list .item .pictrue{width:2.5rem;height:1.56rem;}
.newsList .list .item .pictrue img{width:100%;height:100%;border-radius:0.06rem;}
.newsList .list .item .text{width:4.2rem;height:1.56rem;font-size:0.24rem;color:#999;}
.newsList .list .item .text .name{font-size:0.3rem;color:#282828;}
.newsList .list .item .picList .pictrue{width:3.35rem;height:2.1rem;margin-top:0.3rem;}
.newsList .list .item .picList.on .pictrue{width:2.17rem;height:1.36rem;}
.newsList .list .item .picList .pictrue img{width:100%;height:100%;border-radius:0.06rem;}
.newsList .list .item .time{text-align:right;font-size:0.24rem;color:#999;margin-top:0.22rem;}
.newsList .van-tabs__wrap{top:0!important;}
/*新闻详情*/
.newsDetail .title{padding:0 0.3rem;font-size:0.34rem;color:#282828;font-weight:bold;margin:0.45rem 0 0.23rem 0;
    line-height:1.5;}
.newsDetail .list{margin:0 0.3rem;border-bottom:1px solid #eee;padding-bottom:0.25rem;}
.newsDetail .list .label{font-size:0.24rem;height:0.38rem;border-radius:0.03rem;text-align:center;
    line-height:0.36rem;padding:0 0.1rem;max-width:1.9rem;width: unset;}
.newsDetail .list .item{margin-left:0.27rem;font-size:0.24rem;color:#999;}
.newsDetail .list .item .iconfont{font-size:0.28rem;margin-right:0.1rem;}
.newsDetail .list .item .iconfont.icon-shenhezhong{font-size:0.26rem;}
.newsDetail .conter{padding:0 0.3rem;font-size:0.3rem;color:#333;line-height:1.8;padding-top:0.35rem;}
.newsDetail .conter img{width:100%;display:block;}
/*佣金明细*/
.commission-details .promoterHeader .headerCon .money{font-size:0.36rem;}
.commission-details .promoterHeader .headerCon .money .num{font-family: 'GuildfordProBook 5';}
/*立即注册*/
.register{background-image: linear-gradient(to bottom,#eb5447 0%,#ff8e3b 100%);
    background-image: -webkit-linear-gradient(to bottom, #eb5447 0%,#ff8e3b 100%);
    background-image: -moz-linear-gradient(to bottom,#eb5447 0%,#ff8e3b 100%);width:100%;height:100vh;}
.register .shading{background-image:url("../images/registerw.png");background-repeat:no-repeat;background-size:100% 100%;width:100%;height:2.86rem;padding-top:0.7rem;}
.register .shading .pictrue{width:1.72rem;height:1.72rem;border-radius:50%;background-color:rgba(255,255,255,0.8);margin:0 auto;}
.register .shading .pictrue img{width:1.64rem;height:1.64rem;border-radius:50%;display:block;}
.register .whiteBg{width:6.2rem;border-radius:0.16rem;background-color:#fff;margin:0.3rem auto 0 auto;padding:0.45rem 0.3rem 0 0.3rem;}
.register .whiteBg .title{font-size:0.36rem;color:#282828;text-align:center;font-weight: bold;}
.register .whiteBg .title .item~.item{margin-left:0.85rem;}
.register .whiteBg .title .item{color:#999999;border-bottom:0.05rem solid #fff;padding-bottom:0.1rem;}
.register .whiteBg .title .item.on{color:#282828;border-bottom-color:#f35749;}
.register .whiteBg .list .item{border-bottom:1px solid #ededed;padding:0.47rem 0 0.13rem 0;position:relative;}
.register .whiteBg .list .item .name{font-size:0.26rem;color:#2d3342;margin-bottom:0.27rem;text-align: left;}
.register .whiteBg .list .item .icon{font-size:0.35rem;margin-right:0.32rem;}
.register .whiteBg .list .item input{font-size:0.33rem;width:4.9rem;}
.register .whiteBg .list .item input::placeholder{color:#cccccc;}
.register .whiteBg .list .item .codeIput{width:2.5rem;}
.register .whiteBg .list .item .code{position:absolute;width:1.5rem;height:0.5rem;background-color:#f35446;
border-radius:0.3rem;color:#fff;line-height:0.5rem;text-align:center;bottom:0.17rem;right:0;font-size:0.25rem;}
.register .whiteBg .list .item .code.on{background-color:#bbbbbb;}
.register .whiteBg .list .forgetPwd{text-align:right;font-size:0.28rem;color:#cccccc;margin-top:0.2rem;}
.register .whiteBg .list .forgetPwd .iconfont{font-size:0.3rem;margin-right:0.1rem;vertical-align:middle;}
.register .whiteBg .logon{font-size:0.34rem;color:#fff;font-weight:bold;height:0.86rem;border-radius:0.43rem;background: linear-gradient(to right,#f35447 0%,#ff8e3c 100%);
    background: -webkit-linear-gradient(to right, #f35447 0%,#ff8e3c 100%);
    background: -moz-linear-gradient(to right,#f35447 0%,#ff8e3c 100%);text-align:center;line-height:0.86rem;margin-top:0.47rem;}
.register .whiteBg .tip{height:1.1rem;text-align:center;line-height:1.05rem;font-size:0.3rem;color:#cccccc;}
.register .bottom{background-image:url("../images/registerB.png");background-repeat:no-repeat;background-size:100% 100%;width:6.2rem;height:0.36rem;margin:0 auto;}
/*产品分类*/
.productSort .header{width:100%;height:0.96rem;background-color:#fff;position:fixed;left:0;right:0;top:0;z-index:9;border-bottom:1px solid #f5f5f5;}
.productSort .header .input{width:7rem;height:0.6rem;background-color:#f5f5f5;border-radius:0.5rem;padding:0 0.25rem;}
.productSort .header .input .iconfont{font-size:0.35rem;color:#555;}
.productSort .header .input input{font-size:0.26rem;height:100%;width:5.97rem;}
.productSort .header .input input::placeholder{color:#999;}
.productSort .aside{position:fixed;width:1.8rem;left:0;top:0.96rem;bottom:1rem;background-color:#f7f7f7;overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling: touch;overflow-scrolling: touch;}
.productSort .aside .item{height:0.8rem;width:100%;font-size:0.26rem;color:#424242;}
.productSort .aside .item.on{background-color:#fff;border-left:0.04rem solid #fc4141;width:100%;text-align:center;color:#fc4141;font-weight:bold;}
.productSort .conter{margin-left:1.8rem;padding: 0 0.14rem;margin-top:0.96rem;}
.productSort .conter .listw{padding-top:0.2rem;}
.productSort .conter .listw .title{height:0.9rem;}
.productSort .conter .listw .title .line{width:1rem;height:0.02rem;background-color:#999;}
.productSort .conter .listw .title .name{font-size:0.28rem;color:#333;margin:0 0.3rem;font-weight:bold;}
.productSort .conter .list{flex-wrap:wrap;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;}
.productSort .conter .list .item{width:1.77rem;margin-top:0.26rem;}
.productSort .conter .list .item .picture{width:1.2rem;height:1.2rem;border-radius:50%;}
.productSort .conter .list .item .picture img{width:100%;height:100%;border-radius:50%;}
.productSort .conter .list .item .name{font-size:0.24rem;color:#333;height:0.56rem;line-height:0.56rem;width:1.2rem;text-align:center;}
/*返回主页按钮*/
.home{position: fixed ;top:7.8rem;color: white;text-align: center;z-index:33;right:0.1rem;}
.home .homeCon{overflow: hidden;width:0.86rem;border-radius:0.5rem;transition:all 0.3s ease-in-out 0s;-webkit-transition:all 0.3s ease-in-out 0s;-moz-transition:all 0.3s ease-in-out 0s;-o-transition:all 0.3s ease-in-out 0s;opacity:0;transform: scale(0);-webkit-transform: scale(0);-ms-transform: scale(0);-moz-transform: scale(0);-o-transform: scale(0);height:0;color:#e93323;}
.home .homeCon.on{opacity:1;transform: scale(1);-webkit-transform: scale(1);-ms-transform: scale(1);-moz-transform: scale(1);-o-transform: scale(1);height:3rem;padding: 0.34rem 0;margin-bottom: 0.2rem;}
.home .homeCon .iconfont{font-size:0.48rem;color:#fff;display: inline-block;height: 0.9rem;margin: 0 auto;}
.home .pictrue{width:0.86rem;height:0.86rem;border-radius:50%;}
.home .pictrue .image{width:100%;height:100%;border-radius:50%;}
/*商户管理公共样式*/
.pos-order-goods{padding:0 0.3rem;background-color: #fff;}
.pos-order-goods .goods{height:1.85rem;}
.pos-order-goods .goods~.goods{border-top:1px dashed #e5e5e5;}
.pos-order-goods .goods .picTxt{width:5.15rem;}
.pos-order-goods .goods .picTxt .pictrue{width:1.3rem;height:1.3rem;}
.pos-order-goods .goods .picTxt .pictrue img{width:100%;height:100%;border-radius:0.06rem;}
.pos-order-goods .goods .picTxt .text{width:3.65rem;height:1.3rem;}
.pos-order-goods .goods .picTxt .text .info{font-size:0.28rem;color:#282828;}
.pos-order-goods .goods .picTxt .text .attr{font-size:0.2rem;color:#999;}
.pos-order-goods .goods .money{width:1.64rem;text-align:right;font-size:0.28rem;}
.pos-order-goods .goods .money .x-money{color:#282828;}
.pos-order-goods .goods .money .num{color:#ff9600;margin:0.05rem 0;}
.pos-order-goods .goods .money .y-money{color:#999;text-decoration:line-through;}
.public-total{font-size:0.28rem;color:#282828;border-top:1px solid #eee;height:0.92rem;line-height:0.92rem;text-align:right;padding:0 0.3rem;background-color: #fff;}
.public-total .money{color:#ff4c3c;}
.priceChange{position:fixed;width:5.8rem;height:6.7rem;background-color:#fff;border-radius:0.1rem;top:50%;left:50%;margin-left:-2.9rem;margin-top:-3.35rem;z-index:99;transition:all 0.3s ease-in-out 0s;-webkit-transition:all 0.3s ease-in-out 0s;-o-transition:all 0.3s ease-in-out 0s;-moz-transition:all 0.3s ease-in-out 0s;-webkit-transform:scale(0);-o-transform:scale(0);-moz-transform:scale(0);-ms-transform:scale(0);
    transform: scale(0);opacity:0;}
.priceChange.on{opacity:1;transform: scale(1);-webkit-transform:scale(1);-o-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);}
.priceChange .priceTitle{background:url("../images/pricetitle.jpg") no-repeat;background-size:100% 100%;width:100%;height:1.6rem;border-radius:0.1rem 0.1rem 0 0;text-align:center;font-size:0.4rem;color:#fff;line-height:1.6rem;position:relative;}
.priceChange .priceTitle .iconfont{position:absolute;font-size:0.4rem;right:0.26rem;top:0.23rem;width:0.4rem;height:0.4rem;line-height:0.4rem;}
.priceChange .listChange{padding:0 0.4rem;}
.priceChange .listChange .item{height:1.03rem;border-bottom:1px solid #e3e3e3;font-size:0.32rem;color:#333;}
.priceChange .listChange .item .money{color:#666;width:3rem;text-align:right;}
.priceChange .listChange .item .money .iconfont{font-size:0.32rem;margin-left:0.2rem;}
.priceChange .listChange .item .money input{width:100%;height:100%;text-align:right;color:#ccc;}
.priceChange .listChange .item .money input.on{color:#666;}
.priceChange .modify{font-size:0.32rem;color:#fff;width:4.9rem;height:0.9rem;text-align:center;line-height:0.9rem;border-radius:0.45rem;background-color:#2291f8;margin:0.53rem auto 0 auto;}
.priceChange .modify1{font-size:0.32rem;color:#312b2b;width:4.9rem;height:0.9rem;text-align:center;line-height:0.9rem;border-radius:0.45rem;background-color:#eee;margin:0.3rem auto 0 auto;}
.public-wrapper .title{font-size:0.3rem;color:#282828;padding:0 0.3rem;margin-bottom:0.2rem;}
.public-wrapper .title .iconfont{color:#2291f8;font-size:0.4rem;margin-right:0.13rem;vertical-align:middle;}
.public-wrapper{margin:0.18rem auto 0 auto;width:6.9rem;background-color:#fff;border-radius:0.1rem;padding-top:0.25rem;}
.public-wrapper .nav{padding:0 0.3rem;height:0.7rem;line-height:0.7rem;font-size:0.24rem;color:#999;}
.public-wrapper .data{width:2.1rem;text-align:left;}
.public-wrapper .browse{width:1.92rem;text-align:right;}
.public-wrapper .turnover{width:2.27rem;text-align:right;}
.public-wrapper .conter{padding:0 0.3rem;}
.public-wrapper .conter .item{border-bottom:1px solid #f7f7f7;height:0.7rem;font-size:0.24rem;}
.public-wrapper .conter .item .turnover{color:#d84242;}
/*商户管理订单列表*/
.pos-order-list .nav{width:100%;height:0.96rem;background-color:#fff;font-size:0.3rem;color:#282828;position:fixed;top:0;left:0;}
.pos-order-list .nav .item.on{color:#2291f8;}
.pos-order-list .list{margin-top:1.2rem;}
.pos-order-list .list .item{background-color:#fff;width:100%;}
.pos-order-list .list .item~.item{margin-top:0.24rem;}
.pos-order-list .list .item .order-num{height:1.24rem;border-bottom:1px solid #eee;font-size:0.3rem;font-weight:bold;color:#282828;padding:0 0.3rem;}
.pos-order-list .list .item .order-num .time{font-size:0.26rem;font-weight:normal;color:#999;margin-top: -0.4rem;}
.pos-order-list .list .item .operation{padding:0.2rem 0.3rem;margin-top: 0.03rem;}
.pos-order-list .list .item .operation .more{position:relative;}
.pos-order-list .list .item .operation .icon-gengduo{font-size:0.5rem;color:#aaa;}

.pos-order-list .list .item .operation .order .arrow{width: 0;height: 0;border-left: 0.11rem solid transparent;border-right: 0.11rem solid transparent;border-top: 0.2rem solid #e5e5e5;position:absolute;left: 0.15rem;bottom:-0.18rem;}
.pos-order-list .list .item .operation .order .arrow:before{content:'';width: 0;height: 0;border-left: 0.07rem solid transparent;border-right: 0.07rem solid transparent;border-top: 0.2rem solid #fff;position:absolute;left:-0.07rem;bottom:0;}
.pos-order-list .list .item .operation .order{width:2rem;background-color:#fff;border:1px solid #eee;border-radius:0.1rem;position:absolute;top:-1rem;z-index:9;}
.pos-order-list .list .item .operation .order .items{height:0.77rem;line-height:0.77rem;text-align:center;}
.pos-order-list .list .item .operation .order .items~.items{border-top:1px solid #f5f5f5;}

.pos-order-list .list .item .operation .bnt{font-size:0.28rem;color:#5c5c5c;width:1.7rem;height:0.6rem;border-radius:0.3rem;border:1px solid #bbb;text-align:center;line-height:0.6rem;}
.pos-order-list .list .item .operation .bnt~.bnt{margin-left:0.14rem;}
/*商户管理订单详情*/
.pos-order-details .header{background: linear-gradient(to right,#2291f8 0%,#1cd1dc 100%);background: -webkit-linear-gradient(to right, #2291f8 0%,#1cd1dc 100%);background: -moz-linear-gradient(to right,#2291f8 0%,#1cd1dc 100%);}
.pos-order-details .header .state{font-size:0.36rem;color:#fff;}
.pos-order-details .header .data{margin-left:0.35rem;font-size:0.28rem;}
.pos-order-details .header .data .order-num{font-size:0.3rem;margin-bottom:0.08rem;}
.pos-order-details .remarks{width:100%;height:0.86rem;background-color:#fff;padding:0 0.3rem;}
.pos-order-details .remarks .iconfont{font-size:0.4rem;color:#2a7efb;}
.pos-order-details .remarks input{width:6.3rem;height:100%;font-size:0.3rem;}
.pos-order-details .remarks input::placeholder{color:#666;}
.pos-order-details .orderingUser{font-size:0.26rem;color:#282828;padding:0 0.3rem;height:0.67rem;background-color:#fff;margin-top:0.16rem;border-bottom:1px solid #f5f5f5;}
.pos-order-details .orderingUser .iconfont{font-size:0.4rem;color:#2a7efb;margin-right:0.15rem;}
.pos-order-details .address{margin-top:0;}
.pos-order-details .pos-order-goods{margin-top:0.17rem;}
.pos-order-details .footer .more{font-size:0.27rem;color:#aaa;width:1rem;height:0.64rem;text-align:center;line-height:0.64rem;margin-right: 0.25rem;position:relative;}
.pos-order-details .footer .delivery{background: linear-gradient(to right,#2291f8 0%,#1cd1dc 100%);background: -webkit-linear-gradient(to right, #2291f8 0%,#1cd1dc 100%);background: -moz-linear-gradient(to right,#2291f8 0%,#1cd1dc 100%);}
.pos-order-details .footer .more .order .arrow{width: 0;height: 0;border-left: 0.11rem solid transparent;border-right: 0.11rem solid transparent;border-top: 0.2rem solid #e5e5e5;position:absolute;left: 0.15rem;bottom:-0.18rem;}
.pos-order-details .footer .more .order .arrow:before{content:'';width: 0;height: 0;border-left: 0.09rem solid transparent;border-right: 0.09rem solid transparent;border-top: 0.19rem solid #fff;position:absolute;left:-0.1rem;bottom:0;}
.pos-order-details .footer .more .order{width:2rem;background-color:#fff;border:1px solid #eee;border-radius:0.1rem;position:absolute;top:-2rem;z-index:9;}
.pos-order-details .footer .more .order .item{height:0.77rem;line-height:0.77rem;}
.pos-order-details .footer .more .order .item~.item{border-top:1px solid #f5f5f5;}
.pos-order-details .footer .more .moreName{width:100%;height:100%;}
/*发货*/
.deliver-goods header{width:100%;background-color:#fff;margin-top:0.1rem;}
.deliver-goods header .order-num{padding:0 0.3rem;border-bottom:1px solid #f5f5f5;height:0.67rem;}
.deliver-goods header .order-num .num{width:4.3rem;font-size:0.26rem;color:#282828;position:relative;}
.deliver-goods header .order-num .num:after{position:absolute;content:'';width:1px;height:0.3rem;background-color:#ddd;top:50%;margin-top:-0.15rem;right:0;}
.deliver-goods header .order-num .name{width:2.6rem;font-size:0.26rem;color:#282828;text-align: center;}
.deliver-goods header .order-num .name .iconfont{font-size:0.35rem;color:#477ef3;vertical-align:middle;margin-right:0.1rem;}
.deliver-goods header .address{font-size:0.26rem;color:#868686;background-color:#fff;padding:0.3rem;}
.deliver-goods header .address .name{font-size:0.3rem;color:#282828;margin-bottom:0.1rem;}
.deliver-goods header .address .name .phone{margin-left:0.4rem;}
.deliver-goods header .line{width:100%;height:0.03rem;}
.deliver-goods header .line img{width:100%;height:100%;display:block;}
.deliver-goods .wrapper{width:100%;background-color:#fff;}
.deliver-goods .wrapper .item{border-bottom:1px solid #f0f0f0;padding:0 0.3rem;height:0.96rem;font-size:0.32rem;color:#282828;position:relative;}
.deliver-goods .wrapper .item .mode{width:4.6rem;height:100%;text-align:right;}
.deliver-goods .wrapper .item .mode .iconfont{font-size:0.3rem;margin-left:0.13rem;}
.deliver-goods .wrapper .item .mode .goods~.goods{margin-left:0.3rem;}
.deliver-goods .wrapper .item .mode .goods{color:#bbb;}
.deliver-goods .wrapper .item .mode .goods.on{color:#477ef3;}
.deliver-goods .wrapper .item .icon-up{position:absolute;font-size:0.35rem;color:#2c2c2c;right:0.3rem;}
.deliver-goods .wrapper .item select{direction: rtl;padding-right:0.6rem;position: relative;z-index: 2;}
.deliver-goods .wrapper .item input::placeholder{color:#bbb;}
.deliver-goods .confirm{font-size:0.32rem;color:#fff;width:100%;height:1rem;background-color:#477ef3;text-align:center;line-height:1rem;position:fixed;bottom:0;}
/*订单首页*/
.order-index .header{background:url("../images/orderIndex.png") no-repeat;background-size:100% 100%;width:100%;height:3.02rem;padding:0.45rem 0.3rem 0 0.3rem;}
.order-index .header .item{flex:1;-webkit-flex:1;-o-flex:1;-ms-flex:1;text-align:center;font-size:0.24rem;color:#fff;}
.order-index .header .item .num{font-size:0.4rem;margin-bottom:0.07rem;}
.order-index .wrapper{width:6.9rem;background-color:#fff;border-radius:0.1rem;margin:-1.15rem auto 0 auto;padding-top:0.25rem;}
.order-index .wrapper .title{font-size:0.3rem;color:#282828;padding:0 0.3rem;margin-bottom:0.4rem;}
.order-index .wrapper .title .iconfont{color:#2291f8;font-size:0.4rem;margin-right:0.13rem;vertical-align:middle;}
.order-index .wrapper .list .item{width:33.33%;text-align:center;font-size:0.24rem;color:#999;margin-bottom:0.45rem;}
.order-index .wrapper .list .item .num{font-size:0.4rem;color:#333;}
/*交易额统计*/
.statistical-page .navs{width:100%;height:0.96rem;background-color:#fff;overflow:hidden;line-height:0.96rem;position:fixed;top:0;left:0;z-index:9;}
.statistical-page .navs .list{overflow-y:hidden;overflow-x:auto;white-space: nowrap;-webkit-overflow-scrolling: touch;
    width: 100%;}
.statistical-page .navs .item{font-size:0.32rem;color:#282828;margin-left:0.6rem;display: inline-block;}
.statistical-page .navs .item.on{color:#2291f8;}
.statistical-page .navs .item .iconfont{font-size:0.25rem;margin-left:0.13rem;}
.statistical-page .wrapper{width:7.4rem;background-color:#fff;border-radius:0.1rem;margin:1.19rem auto 0 auto;padding:0.5rem 0.6rem;}
.statistical-page .wrapper .title{font-size:0.3rem;color:#999;text-align:center;}
.statistical-page .wrapper .money{font-size:0.72rem;color:#fba02a;text-align:center;margin-top:0.1rem;}
.statistical-page .wrapper .increase{font-size:0.28rem;color:#999;margin-top:0.2rem;}
.statistical-page .wrapper .increase .red{color:#ff6969;}
.statistical-page .wrapper .increase .green{color:#1abb1d;}
.statistical-page .wrapper .increase .iconfont{font-size:0.23rem;margin-left:0.15rem;}
.statistical-page .chart{width:6.9rem;height:4.8rem;background-color:#fff;border-radius:0.1rem;margin:0.23rem auto 0 auto;padding: 0.25rem 0.22rem 0 0.22rem;}
.statistical-page .chart .company{font-size:0.26rem;color:#999;}
.statistical-page .mc-body{padding-bottom:0;}
.statistical-page .mc-body tr{background-color: #edf8fe;border-top: 1px solid #fff;width:100%;}
.statistical-page .mpvue-calendar{min-width:100%;}
.statistical-page .mpvue-calendar table{margin:0;}
.statistical-page .mpvue-calendar td{border-right:1px solid #fff;padding:0;width:14%!important;}
.statistical-page .calendar-tools{box-shadow:unset;-webkit-box-shadow:unset;-o-box-shadow:unset;-moz-box-shadow:unset;}
.statistical-page .mc-head-box div{font-size: 14px;}
.statistical-page .mpvue-calendar td:not(.disabled) span.mc-date-red{color:unset;}
.statistical-page .mpvue-calendar .mc-range-mode .mc-range-end span.calendar-date, .statistical-page .mpvue-calendar .mc-range-mode .mc-range-begin span.calendar-date{
    border-radius:0;background-color:#2291f8!important;
}
.statistical-page .mpvue-calendar td.selected span.mc-date-red{color:#fff;}
.statistical-page .mc-range-mode .selected .mc-range-bg{background-color:#a0dcf9;}
.statistical-page .mpvue-calendar .mc-range-mode .mc-range-row-last .calendar-date,.statistical-page .mpvue-calendar .mc-range-mode .mc-range-row-first .calendar-date{
    background-color:#a0dcf9;
}
.statistical-page .mpvue-calendar .mc-range-mode .selected.mc-range-second-to-last span{background-color:#a0dcf9;}
.statistical-page .mpvue-calendar .mc-range-mode .mc-range-month-first.selected .calendar-date, .statistical-page .mpvue-calendar .mc-range-mode .mc-range-month-last.selected .calendar-date{
    background-color:#a0dcf9;
}
.statistical-page .mc-today-element .calendar-date{border-radius:0;background-color:unset;}
.yd-confirm {background-color: #fff;font-size:unset;width: 5.4rem;height: 2.5rem;border-radius: 0.4rem;}
.yd-confirm-hd {text-align: center;}
.yd-confirm-title {color: #030303;font-weight: bold;font-size: 0.36rem;}
.yd-confirm-bd {text-align: center;font-size: 0.28rem;color: #333333;}
.yd-confirm-ft {line-height: 0.9rem;margin-top: 14px;border-top: 0.01rem solid #eee;}
.yd-confirm-ft>a{color:#e93323;}
.yd-confirm-ft>a.primary{border-left:0.01rem solid #eee;color:#e93323;}
/*修改密码*/
.ChangePassword .phone{font-size:0.32rem;font-weight:bold;text-align:center;margin-top:0.55rem;}
.ChangePassword .list{width:5.8rem;margin:0.53rem auto 0 auto;}
.ChangePassword .list .item{width:100%;height:1.1rem;border-bottom:0.02rem solid #f0f0f0;}
.ChangePassword .list .item input{width:100%;height:100%;font-size:0.32rem;}
.ChangePassword .list .item input::placeholder{color:#b9b9bc;}
.ChangePassword .list .item input.codeIput{width:3.4rem;}
.ChangePassword .list .item .code{font-size:0.32rem;}
.ChangePassword .list .item .code.on{color:#b9b9bc!important;}
.ChangePassword .confirmBnt{font-size:0.32rem;width:5.8rem;height:0.9rem;border-radius:0.45rem;color:#fff;margin:0.92rem auto 0 auto;text-align:center;line-height:0.9rem;}
.van-tabs__wrap{z-index:22!important;}
















































images

js

area.js

export default {
    province_list: {
        110000: '北京市',
        120000: '天津市',
        130000: '河北省',
        140000: '山西省',
        150000: '内蒙古自治区',
        210000: '辽宁省',
        220000: '吉林省',
        230000: '黑龙江省',
        310000: '上海市',
        320000: '江苏省',
        330000: '浙江省',
        340000: '安徽省',
        350000: '福建省',
        360000: '江西省',
        370000: '山东省',
        410000: '河南省',
        420000: '湖北省',
        430000: '湖南省',
        440000: '广东省',
        450000: '广西壮族自治区',
        460000: '海南省',
        500000: '重庆市',
        510000: '四川省',
        520000: '贵州省',
        530000: '云南省',
        540000: '西藏自治区',
        610000: '陕西省',
        620000: '甘肃省',
        630000: '青海省',
        640000: '宁夏回族自治区',
        650000: '新疆维吾尔自治区',
        710000: '台湾省',
        810000: '香港特别行政区',
        820000: '澳门特别行政区',
        900000: '海外'
    },
    city_list: {
        110100: '北京市',
        120100: '天津市',
        130100: '石家庄市',
        130200: '唐山市',
        130300: '秦皇岛市',
        130400: '邯郸市',
        130500: '邢台市',
        130600: '保定市',
        130700: '张家口市',
        130800: '承德市',
        130900: '沧州市',
        131000: '廊坊市',
        131100: '衡水市',
        140100: '太原市',
        140200: '大同市',
        140300: '阳泉市',
        140400: '长治市',
        140500: '晋城市',
        140600: '朔州市',
        140700: '晋中市',
        140800: '运城市',
        140900: '忻州市',
        141000: '临汾市',
        141100: '吕梁市',
        150100: '呼和浩特市',
        150200: '包头市',
        150300: '乌海市',
        150400: '赤峰市',
        150500: '通辽市',
        150600: '鄂尔多斯市',
        150700: '呼伦贝尔市',
        150800: '巴彦淖尔市',
        150900: '乌兰察布市',
        152200: '兴安盟',
        152500: '锡林郭勒盟',
        152900: '阿拉善盟',
        210100: '沈阳市',
        210200: '大连市',
        210300: '鞍山市',
        210400: '抚顺市',
        210500: '本溪市',
        210600: '丹东市',
        210700: '锦州市',
        210800: '营口市',
        210900: '阜新市',
        211000: '辽阳市',
        211100: '盘锦市',
        211200: '铁岭市',
        211300: '朝阳市',
        211400: '葫芦岛市',
        220100: '长春市',
        220200: '吉林市',
        220300: '四平市',
        220400: '辽源市',
        220500: '通化市',
        220600: '白山市',
        220700: '松原市',
        220800: '白城市',
        222400: '延边朝鲜族自治州',
        230100: '哈尔滨市',
        230200: '齐齐哈尔市',
        230300: '鸡西市',
        230400: '鹤岗市',
        230500: '双鸭山市',
        230600: '大庆市',
        230700: '伊春市',
        230800: '佳木斯市',
        230900: '七台河市',
        231000: '牡丹江市',
        231100: '黑河市',
        231200: '绥化市',
        232700: '大兴安岭地区',
        310100: '上海市',
        320100: '南京市',
        320200: '无锡市',
        320300: '徐州市',
        320400: '常州市',
        320500: '苏州市',
        320600: '南通市',
        320700: '连云港市',
        320800: '淮安市',
        320900: '盐城市',
        321000: '扬州市',
        321100: '镇江市',
        321200: '泰州市',
        321300: '宿迁市',
        330100: '杭州市',
        330200: '宁波市',
        330300: '温州市',
        330400: '嘉兴市',
        330500: '湖州市',
        330600: '绍兴市',
        330700: '金华市',
        330800: '衢州市',
        330900: '舟山市',
        331000: '台州市',
        331100: '丽水市',
        340100: '合肥市',
        340200: '芜湖市',
        340300: '蚌埠市',
        340400: '淮南市',
        340500: '马鞍山市',
        340600: '淮北市',
        340700: '铜陵市',
        340800: '安庆市',
        341000: '黄山市',
        341100: '滁州市',
        341200: '阜阳市',
        341300: '宿州市',
        341500: '六安市',
        341600: '亳州市',
        341700: '池州市',
        341800: '宣城市',
        350100: '福州市',
        350200: '厦门市',
        350300: '莆田市',
        350400: '三明市',
        350500: '泉州市',
        350600: '漳州市',
        350700: '南平市',
        350800: '龙岩市',
        350900: '宁德市',
        360100: '南昌市',
        360200: '景德镇市',
        360300: '萍乡市',
        360400: '九江市',
        360500: '新余市',
        360600: '鹰潭市',
        360700: '赣州市',
        360800: '吉安市',
        360900: '宜春市',
        361000: '抚州市',
        361100: '上饶市',
        370100: '济南市',
        370200: '青岛市',
        370300: '淄博市',
        370400: '枣庄市',
        370500: '东营市',
        370600: '烟台市',
        370700: '潍坊市',
        370800: '济宁市',
        370900: '泰安市',
        371000: '威海市',
        371100: '日照市',
        371200: '莱芜市',
        371300: '临沂市',
        371400: '德州市',
        371500: '聊城市',
        371600: '滨州市',
        371700: '菏泽市',
        410100: '郑州市',
        410200: '开封市',
        410300: '洛阳市',
        410400: '平顶山市',
        410500: '安阳市',
        410600: '鹤壁市',
        410700: '新乡市',
        410800: '焦作市',
        410900: '濮阳市',
        411000: '许昌市',
        411100: '漯河市',
        411200: '三门峡市',
        411300: '南阳市',
        411400: '商丘市',
        411500: '信阳市',
        411600: '周口市',
        411700: '驻马店市',
        419000: '省直辖县',
        420100: '武汉市',
        420200: '黄石市',
        420300: '十堰市',
        420500: '宜昌市',
        420600: '襄阳市',
        420700: '鄂州市',
        420800: '荆门市',
        420900: '孝感市',
        421000: '荆州市',
        421100: '黄冈市',
        421200: '咸宁市',
        421300: '随州市',
        422800: '恩施土家族苗族自治州',
        429000: '省直辖县',
        430100: '长沙市',
        430200: '株洲市',
        430300: '湘潭市',
        430400: '衡阳市',
        430500: '邵阳市',
        430600: '岳阳市',
        430700: '常德市',
        430800: '张家界市',
        430900: '益阳市',
        431000: '郴州市',
        431100: '永州市',
        431200: '怀化市',
        431300: '娄底市',
        433100: '湘西土家族苗族自治州',
        440100: '广州市',
        440200: '韶关市',
        440300: '深圳市',
        440400: '珠海市',
        440500: '汕头市',
        440600: '佛山市',
        440700: '江门市',
        440800: '湛江市',
        440900: '茂名市',
        441200: '肇庆市',
        441300: '惠州市',
        441400: '梅州市',
        441500: '汕尾市',
        441600: '河源市',
        441700: '阳江市',
        441800: '清远市',
        441900: '东莞市',
        442000: '中山市',
        445100: '潮州市',
        445200: '揭阳市',
        445300: '云浮市',
        450100: '南宁市',
        450200: '柳州市',
        450300: '桂林市',
        450400: '梧州市',
        450500: '北海市',
        450600: '防城港市',
        450700: '钦州市',
        450800: '贵港市',
        450900: '玉林市',
        451000: '百色市',
        451100: '贺州市',
        451200: '河池市',
        451300: '来宾市',
        451400: '崇左市',
        460100: '海口市',
        460200: '三亚市',
        460300: '三沙市',
        460400: '儋州市',
        469000: '省直辖县',
        500100: '重庆市',
        500200: '县',
        510100: '成都市',
        510300: '自贡市',
        510400: '攀枝花市',
        510500: '泸州市',
        510600: '德阳市',
        510700: '绵阳市',
        510800: '广元市',
        510900: '遂宁市',
        511000: '内江市',
        511100: '乐山市',
        511300: '南充市',
        511400: '眉山市',
        511500: '宜宾市',
        511600: '广安市',
        511700: '达州市',
        511800: '雅安市',
        511900: '巴中市',
        512000: '资阳市',
        513200: '阿坝藏族羌族自治州',
        513300: '甘孜藏族自治州',
        513400: '凉山彝族自治州',
        520100: '贵阳市',
        520200: '六盘水市',
        520300: '遵义市',
        520400: '安顺市',
        520500: '毕节市',
        520600: '铜仁市',
        522300: '黔西南布依族苗族自治州',
        522600: '黔东南苗族侗族自治州',
        522700: '黔南布依族苗族自治州',
        530100: '昆明市',
        530300: '曲靖市',
        530400: '玉溪市',
        530500: '保山市',
        530600: '昭通市',
        530700: '丽江市',
        530800: '普洱市',
        530900: '临沧市',
        532300: '楚雄彝族自治州',
        532500: '红河哈尼族彝族自治州',
        532600: '文山壮族苗族自治州',
        532800: '西双版纳傣族自治州',
        532900: '大理白族自治州',
        533100: '德宏傣族景颇族自治州',
        533300: '怒江傈僳族自治州',
        533400: '迪庆藏族自治州',
        540100: '拉萨市',
        540200: '日喀则市',
        540300: '昌都市',
        540400: '林芝市',
        540500: '山南市',
        540600: '那曲市',
        542500: '阿里地区',
        610100: '西安市',
        610200: '铜川市',
        610300: '宝鸡市',
        610400: '咸阳市',
        610500: '渭南市',
        610600: '延安市',
        610700: '汉中市',
        610800: '榆林市',
        610900: '安康市',
        611000: '商洛市',
        620100: '兰州市',
        620200: '嘉峪关市',
        620300: '金昌市',
        620400: '白银市',
        620500: '天水市',
        620600: '武威市',
        620700: '张掖市',
        620800: '平凉市',
        620900: '酒泉市',
        621000: '庆阳市',
        621100: '定西市',
        621200: '陇南市',
        622900: '临夏回族自治州',
        623000: '甘南藏族自治州',
        630100: '西宁市',
        630200: '海东市',
        632200: '海北藏族自治州',
        632300: '黄南藏族自治州',
        632500: '海南藏族自治州',
        632600: '果洛藏族自治州',
        632700: '玉树藏族自治州',
        632800: '海西蒙古族藏族自治州',
        640100: '银川市',
        640200: '石嘴山市',
        640300: '吴忠市',
        640400: '固原市',
        640500: '中卫市',
        650100: '乌鲁木齐市',
        650200: '克拉玛依市',
        650400: '吐鲁番市',
        650500: '哈密市',
        652300: '昌吉回族自治州',
        652700: '博尔塔拉蒙古自治州',
        652800: '巴音郭楞蒙古自治州',
        652900: '阿克苏地区',
        653000: '克孜勒苏柯尔克孜自治州',
        653100: '喀什地区',
        653200: '和田地区',
        654000: '伊犁哈萨克自治州',
        654200: '塔城地区',
        654300: '阿勒泰地区',
        659000: '自治区直辖县级行政区划',
        710100: '台北市',
        710200: '高雄市',
        710300: '台南市',
        710400: '台中市',
        710500: '金门县',
        710600: '南投县',
        710700: '基隆市',
        710800: '新竹市',
        710900: '嘉义市',
        711100: '新北市',
        711200: '宜兰县',
        711300: '新竹县',
        711400: '桃园县',
        711500: '苗栗县',
        711700: '彰化县',
        711900: '嘉义县',
        712100: '云林县',
        712400: '屏东县',
        712500: '台东县',
        712600: '花莲县',
        712700: '澎湖县',
        712800: '连江县',
        810100: '香港岛',
        810200: '九龙',
        810300: '新界',
        820100: '澳门半岛',
        820200: '离岛',
        900400: '阿富汗',
        900800: '阿尔巴尼亚',
        901000: '南极洲',
        901200: '阿尔及利亚',
        901600: '美属萨摩亚',
        902000: '安道尔',
        902400: '安哥拉',
        902800: '安提瓜和巴布达',
        903100: '阿塞拜疆',
        903200: '阿根廷',
        903600: '澳大利亚',
        904000: '奥地利',
        904400: '巴哈马',
        904800: '巴林',
        905000: '孟加拉',
        905100: '亚美尼亚',
        905200: '巴巴多斯',
        905600: '比利时',
        906000: '百慕大',
        906400: '不丹',
        906800: '玻利维亚',
        907000: '波黑',
        907200: '博茨瓦纳',
        907400: '布韦岛',
        907600: '巴西',
        908400: '伯利兹',
        908600: '英属印度洋领地',
        909000: '所罗门群岛',
        909200: '英属维尔京群岛',
        909600: '文莱',
        910000: '保加利亚',
        910400: '缅甸',
        910800: '布隆迪',
        911200: '白俄罗斯',
        911600: '柬埔寨',
        912000: '喀麦隆',
        912400: '加拿大',
        913200: '佛得角',
        913600: '开曼群岛',
        914000: '中非',
        914400: '斯里兰卡',
        914800: '乍得',
        915200: '智利',
        916200: '圣诞岛',
        916600: '科科斯群岛',
        917000: '哥伦比亚',
        917400: '科摩罗',
        917500: '马约特',
        917800: '刚果(布)',
        918000: '刚果(金)',
        918400: '库克群岛',
        918800: '哥斯达黎加',
        919100: '克罗地亚',
        919200: '古巴',
        919600: '塞浦路斯',
        920300: '捷克',
        920400: '贝宁',
        920800: '丹麦',
        921200: '多米尼克',
        921400: '多米尼加',
        921800: '厄瓜多尔',
        922200: '萨尔瓦多',
        922600: '赤道几内亚',
        923100: '埃塞俄比亚',
        923200: '厄立特里亚',
        923300: '爱沙尼亚',
        923400: '法罗群岛',
        923800: '马尔维纳斯群岛( 福克兰)',
        923900: '南乔治亚岛和南桑威奇群岛',
        924200: '斐济群岛',
        924600: '芬兰',
        924800: '奥兰群岛',
        925000: '法国',
        925400: '法属圭亚那',
        925800: '法属波利尼西亚',
        926000: '法属南部领地',
        926200: '吉布提',
        926600: '加蓬',
        926800: '格鲁吉亚',
        927000: '冈比亚',
        927500: '巴勒斯坦',
        927600: '德国',
        928800: '加纳',
        929200: '直布罗陀',
        929600: '基里巴斯',
        930000: '希腊',
        930400: '格陵兰',
        930800: '格林纳达',
        931200: '瓜德罗普',
        931600: '关岛',
        932000: '危地马拉',
        932400: '几内亚',
        932800: '圭亚那',
        933200: '海地',
        933400: '赫德岛和麦克唐纳群岛',
        933600: '梵蒂冈',
        934000: '洪都拉斯',
        934800: '匈牙利',
        935200: '冰岛',
        935600: '印度',
        936000: '印尼',
        936400: '伊朗',
        936800: '伊拉克',
        937200: '爱尔兰',
        937600: '以色列',
        938000: '意大利',
        938400: '科特迪瓦',
        938800: '牙买加',
        939200: '日本',
        939800: '哈萨克斯坦',
        940000: '约旦',
        940400: '肯尼亚',
        940800: '朝鲜 北朝鲜',
        941000: '韩国',
        941400: '科威特',
        941700: '吉尔吉斯斯坦',
        941800: '老挝',
        942200: '黎巴嫩',
        942600: '莱索托',
        942800: '拉脱维亚',
        943000: '利比里亚',
        943400: '利比亚',
        943800: '列支敦士登',
        944000: '立陶宛',
        944200: '卢森堡',
        945000: '马达加斯加',
        945400: '马拉维',
        945800: '马来西亚',
        946200: '马尔代夫',
        946600: '马里',
        947000: '马耳他',
        947400: '马提尼克',
        947800: '毛里塔尼亚',
        948000: '毛里求斯',
        948400: '墨西哥',
        949200: '摩纳哥',
        949600: '蒙古国',
        949800: '摩尔多瓦',
        949900: '黑山',
        950000: '蒙塞拉特岛',
        950400: '摩洛哥',
        950800: '莫桑比克',
        951200: '阿曼',
        951600: '纳米比亚',
        952000: '瑙鲁',
        952400: '尼泊尔',
        952800: '荷兰',
        953300: '阿鲁巴',
        953500: '荷兰加勒比区',
        954000: '新喀里多尼亚',
        954800: '瓦努阿图',
        955400: '新西兰',
        955800: '尼加拉瓜',
        956200: '尼日尔',
        956600: '尼日利亚',
        957000: '纽埃',
        957400: '诺福克岛',
        957800: '挪威',
        958000: '北马里亚纳群岛',
        958100: '美国本土外小岛屿',
        958300: '密克罗尼西亚联邦',
        958400: '马绍尔群岛',
        958500: '帕劳',
        958600: '巴基斯坦',
        959100: '巴拿马',
        959800: '巴布亚新几内亚',
        960000: '巴拉圭',
        960400: '秘鲁',
        960800: '菲律宾',
        961200: '皮特凯恩群岛',
        961600: '波兰',
        962000: '葡萄牙',
        962400: '几内亚比绍',
        962600: '东帝汶',
        963000: '波多黎各',
        963400: '卡塔尔',
        963800: '留尼汪',
        964200: '罗马尼亚',
        964300: '俄罗斯',
        964600: '卢旺达',
        965200: '圣巴泰勒米岛',
        965400: '圣赫勒拿',
        965900: '圣基茨和尼维斯',
        966000: '安圭拉',
        966200: '圣卢西亚',
        966300: '法属圣马丁',
        966600: '圣皮埃尔和密克隆',
        967000: '圣文森特和格林纳丁斯',
        967400: '圣马力诺',
        967800: '圣多美和普林西比',
        968200: '沙特阿拉伯',
        968600: '塞内加尔',
        968800: '塞尔维亚',
        969000: '塞舌尔',
        969400: '塞拉利昂',
        970200: '新加坡',
        970300: '斯洛伐克',
        970400: '越南',
        970500: '斯洛文尼亚',
        970600: '索马里',
        971000: '南非',
        971600: '津巴布韦',
        972400: '西班牙',
        972800: '南苏丹',
        972900: '苏丹',
        973200: '西撒哈拉',
        974000: '苏里南',
        974400: '斯瓦尔巴群岛和 扬马延岛',
        974800: '斯威士兰',
        975200: '瑞典',
        975600: '瑞士',
        976000: '叙利亚',
        976200: '塔吉克斯坦',
        976400: '泰国',
        976800: '多哥',
        977200: '托克劳',
        977600: '汤加',
        978000: '特立尼达和多巴哥',
        978400: '阿联酋',
        978800: '突尼斯',
        979200: '土耳其',
        979500: '土库曼斯坦',
        979600: '特克斯和凯科斯群岛',
        979800: '图瓦卢',
        980000: '乌干达',
        980400: '乌克兰',
        980700: '马其顿',
        981800: '埃及',
        982600: '英国',
        983100: '根西岛',
        983200: '泽西岛',
        983300: '马恩岛',
        983400: '坦桑尼亚',
        984000: '美国',
        985000: '美属维尔京群岛',
        985400: '布基纳法索',
        985800: '乌拉圭',
        986000: '乌兹别克斯坦',
        986200: '委内瑞拉',
        987600: '瓦利斯和富图纳',
        988200: '萨摩亚',
        988700: '也门',
        989400: '赞比亚'
    },
    county_list: {
        110101: '东城区',
        110102: '西城区',
        110105: '朝阳区',
        110106: '丰台区',
        110107: '石景山区',
        110108: '海淀区',
        110109: '门头沟区',
        110111: '房山区',
        110112: '通州区',
        110113: '顺义区',
        110114: '昌平区',
        110115: '大兴区',
        110116: '怀柔区',
        110117: '平谷区',
        110118: '密云区',
        110119: '延庆区',
        120101: '和平区',
        120102: '河东区',
        120103: '河西区',
        120104: '南开区',
        120105: '河北区',
        120106: '红桥区',
        120110: '东丽区',
        120111: '西青区',
        120112: '津南区',
        120113: '北辰区',
        120114: '武清区',
        120115: '宝坻区',
        120116: '滨海新区',
        120117: '宁河区',
        120118: '静海区',
        120119: '蓟州区',
        130102: '长安区',
        130104: '桥西区',
        130105: '新华区',
        130107: '井陉矿区',
        130108: '裕华区',
        130109: '藁城区',
        130110: '鹿泉区',
        130111: '栾城区',
        130121: '井陉县',
        130123: '正定县',
        130125: '行唐县',
        130126: '灵寿县',
        130127: '高邑县',
        130128: '深泽县',
        130129: '赞皇县',
        130130: '无极县',
        130131: '平山县',
        130132: '元氏县',
        130133: '赵县',
        130181: '辛集市',
        130183: '晋州市',
        130184: '新乐市',
        130202: '路南区',
        130203: '路北区',
        130204: '古冶区',
        130205: '开平区',
        130207: '丰南区',
        130208: '丰润区',
        130209: '曹妃甸区',
        130224: '滦南县',
        130225: '乐亭县',
        130227: '迁西县',
        130229: '玉田县',
        130281: '遵化市',
        130283: '迁安市',
        130284: '滦州市',
        130302: '海港区',
        130303: '山海关区',
        130304: '北戴河区',
        130306: '抚宁区',
        130321: '青龙满族自治县',
        130322: '昌黎县',
        130324: '卢龙县',
        130390: '经济技术开发区',
        130402: '邯山区',
        130403: '丛台区',
        130404: '复兴区',
        130406: '峰峰矿区',
        130407: '肥乡区',
        130408: '永年区',
        130423: '临漳县',
        130424: '成安县',
        130425: '大名县',
        130426: '涉县',
        130427: '磁县',
        130430: '邱县',
        130431: '鸡泽县',
        130432: '广平县',
        130433: '馆陶县',
        130434: '魏县',
        130435: '曲周县',
        130481: '武安市',
        130502: '桥东区',
        130503: '桥西区',
        130521: '邢台县',
        130522: '临城县',
        130523: '内丘县',
        130524: '柏乡县',
        130525: '隆尧县',
        130526: '任县',
        130527: '南和县',
        130528: '宁晋县',
        130529: '巨鹿县',
        130530: '新河县',
        130531: '广宗县',
        130532: '平乡县',
        130533: '威县',
        130534: '清河县',
        130535: '临西县',
        130581: '南宫市',
        130582: '沙河市',
        130602: '竞秀区',
        130606: '莲池区',
        130607: '满城区',
        130608: '清苑区',
        130609: '徐水区',
        130623: '涞水县',
        130624: '阜平县',
        130626: '定兴县',
        130627: '唐县',
        130628: '高阳县',
        130629: '容城县',
        130630: '涞源县',
        130631: '望都县',
        130632: '安新县',
        130633: '易县',
        130634: '曲阳县',
        130635: '蠡县',
        130636: '顺平县',
        130637: '博野县',
        130638: '雄县',
        130681: '涿州市',
        130682: '定州市',
        130683: '安国市',
        130684: '高碑店市',
        130702: '桥东区',
        130703: '桥西区',
        130705: '宣化区',
        130706: '下花园区',
        130708: '万全区',
        130709: '崇礼区',
        130722: '张北县',
        130723: '康保县',
        130724: '沽源县',
        130725: '尚义县',
        130726: '蔚县',
        130727: '阳原县',
        130728: '怀安县',
        130730: '怀来县',
        130731: '涿鹿县',
        130732: '赤城县',
        130802: '双桥区',
        130803: '双滦区',
        130804: '鹰手营子矿区',
        130821: '承德县',
        130822: '兴隆县',
        130824: '滦平县',
        130825: '隆化县',
        130826: '丰宁满族自治县',
        130827: '宽城满族自治县',
        130828: '围场满族蒙古族自治县',
        130881: '平泉市',
        130902: '新华区',
        130903: '运河区',
        130921: '沧县',
        130922: '青县',
        130923: '东光县',
        130924: '海兴县',
        130925: '盐山县',
        130926: '肃宁县',
        130927: '南皮县',
        130928: '吴桥县',
        130929: '献县',
        130930: '孟村回族自治县',
        130981: '泊头市',
        130982: '任丘市',
        130983: '黄骅市',
        130984: '河间市',
        131002: '安次区',
        131003: '广阳区',
        131022: '固安县',
        131023: '永清县',
        131024: '香河县',
        131025: '大城县',
        131026: '文安县',
        131028: '大厂回族自治县',
        131081: '霸州市',
        131082: '三河市',
        131090: '开发区',
        131102: '桃城区',
        131103: '冀州区',
        131121: '枣强县',
        131122: '武邑县',
        131123: '武强县',
        131124: '饶阳县',
        131125: '安平县',
        131126: '故城县',
        131127: '景县',
        131128: '阜城县',
        131182: '深州市',
        140105: '小店区',
        140106: '迎泽区',
        140107: '杏花岭区',
        140108: '尖草坪区',
        140109: '万柏林区',
        140110: '晋源区',
        140121: '清徐县',
        140122: '阳曲县',
        140123: '娄烦县',
        140181: '古交市',
        140212: '新荣区',
        140213: '平城区',
        140214: '云冈区',
        140215: '云州区',
        140221: '阳高县',
        140222: '天镇县',
        140223: '广灵县',
        140224: '灵丘县',
        140225: '浑源县',
        140226: '左云县',
        140302: '城区',
        140303: '矿区',
        140311: '郊区',
        140321: '平定县',
        140322: '盂县',
        140403: '潞州区',
        140404: '上党区',
        140405: '屯留区',
        140406: '潞城区',
        140423: '襄垣县',
        140425: '平顺县',
        140426: '黎城县',
        140427: '壶关县',
        140428: '长子县',
        140429: '武乡县',
        140430: '沁县',
        140431: '沁源县',
        140502: '城区',
        140521: '沁水县',
        140522: '阳城县',
        140524: '陵川县',
        140525: '泽州县',
        140581: '高平市',
        140602: '朔城区',
        140603: '平鲁区',
        140621: '山阴县',
        140622: '应县',
        140623: '右玉县',
        140681: '怀仁市',
        140702: '榆次区',
        140721: '榆社县',
        140722: '左权县',
        140723: '和顺县',
        140724: '昔阳县',
        140725: '寿阳县',
        140726: '太谷县',
        140727: '祁县',
        140728: '平遥县',
        140729: '灵石县',
        140781: '介休市',
        140802: '盐湖区',
        140821: '临猗县',
        140822: '万荣县',
        140823: '闻喜县',
        140824: '稷山县',
        140825: '新绛县',
        140826: '绛县',
        140827: '垣曲县',
        140828: '夏县',
        140829: '平陆县',
        140830: '芮城县',
        140881: '永济市',
        140882: '河津市',
        140902: '忻府区',
        140921: '定襄县',
        140922: '五台县',
        140923: '代县',
        140924: '繁峙县',
        140925: '宁武县',
        140926: '静乐县',
        140927: '神池县',
        140928: '五寨县',
        140929: '岢岚县',
        140930: '河曲县',
        140931: '保德县',
        140932: '偏关县',
        140981: '原平市',
        141002: '尧都区',
        141021: '曲沃县',
        141022: '翼城县',
        141023: '襄汾县',
        141024: '洪洞县',
        141025: '古县',
        141026: '安泽县',
        141027: '浮山县',
        141028: '吉县',
        141029: '乡宁县',
        141030: '大宁县',
        141031: '隰县',
        141032: '永和县',
        141033: '蒲县',
        141034: '汾西县',
        141081: '侯马市',
        141082: '霍州市',
        141102: '离石区',
        141121: '文水县',
        141122: '交城县',
        141123: '兴县',
        141124: '临县',
        141125: '柳林县',
        141126: '石楼县',
        141127: '岚县',
        141128: '方山县',
        141129: '中阳县',
        141130: '交口县',
        141181: '孝义市',
        141182: '汾阳市',
        150102: '新城区',
        150103: '回民区',
        150104: '玉泉区',
        150105: '赛罕区',
        150121: '土默特左旗',
        150122: '托克托县',
        150123: '和林格尔县',
        150124: '清水河县',
        150125: '武川县',
        150202: '东河区',
        150203: '昆都仑区',
        150204: '青山区',
        150205: '石拐区',
        150206: '白云鄂博矿区',
        150207: '九原区',
        150221: '土默特右旗',
        150222: '固阳县',
        150223: '达尔罕茂明安联合旗',
        150302: '海勃湾区',
        150303: '海南区',
        150304: '乌达区',
        150402: '红山区',
        150403: '元宝山区',
        150404: '松山区',
        150421: '阿鲁科尔沁旗',
        150422: '巴林左旗',
        150423: '巴林右旗',
        150424: '林西县',
        150425: '克什克腾旗',
        150426: '翁牛特旗',
        150428: '喀喇沁旗',
        150429: '宁城县',
        150430: '敖汉旗',
        150502: '科尔沁区',
        150521: '科尔沁左翼中旗',
        150522: '科尔沁左翼后旗',
        150523: '开鲁县',
        150524: '库伦旗',
        150525: '奈曼旗',
        150526: '扎鲁特旗',
        150581: '霍林郭勒市',
        150602: '东胜区',
        150603: '康巴什区',
        150621: '达拉特旗',
        150622: '准格尔旗',
        150623: '鄂托克前旗',
        150624: '鄂托克旗',
        150625: '杭锦旗',
        150626: '乌审旗',
        150627: '伊金霍洛旗',
        150702: '海拉尔区',
        150703: '扎赉诺尔区',
        150721: '阿荣旗',
        150722: '莫力达瓦达斡尔族自治旗',
        150723: '鄂伦春自治旗',
        150724: '鄂温克族自治旗',
        150725: '陈巴尔虎旗',
        150726: '新巴尔虎左旗',
        150727: '新巴尔虎右旗',
        150781: '满洲里市',
        150782: '牙克石市',
        150783: '扎兰屯市',
        150784: '额尔古纳市',
        150785: '根河市',
        150802: '临河区',
        150821: '五原县',
        150822: '磴口县',
        150823: '乌拉特前旗',
        150824: '乌拉特中旗',
        150825: '乌拉特后旗',
        150826: '杭锦后旗',
        150902: '集宁区',
        150921: '卓资县',
        150922: '化德县',
        150923: '商都县',
        150924: '兴和县',
        150925: '凉城县',
        150926: '察哈尔右翼前旗',
        150927: '察哈尔右翼中旗',
        150928: '察哈尔右翼后旗',
        150929: '四子王旗',
        150981: '丰镇市',
        152201: '乌兰浩特市',
        152202: '阿尔山市',
        152221: '科尔沁右翼前旗',
        152222: '科尔沁右翼中旗',
        152223: '扎赉特旗',
        152224: '突泉县',
        152501: '二连浩特市',
        152502: '锡林浩特市',
        152522: '阿巴嘎旗',
        152523: '苏尼特左旗',
        152524: '苏尼特右旗',
        152525: '东乌珠穆沁旗',
        152526: '西乌珠穆沁旗',
        152527: '太仆寺旗',
        152528: '镶黄旗',
        152529: '正镶白旗',
        152530: '正蓝旗',
        152531: '多伦县',
        152921: '阿拉善左旗',
        152922: '阿拉善右旗',
        152923: '额济纳旗',
        210102: '和平区',
        210103: '沈河区',
        210104: '大东区',
        210105: '皇姑区',
        210106: '铁西区',
        210111: '苏家屯区',
        210112: '浑南区',
        210113: '沈北新区',
        210114: '于洪区',
        210115: '辽中区',
        210123: '康平县',
        210124: '法库县',
        210181: '新民市',
        210190: '经济技术开发区',
        210202: '中山区',
        210203: '西岗区',
        210204: '沙河口区',
        210211: '甘井子区',
        210212: '旅顺口区',
        210213: '金州区',
        210214: '普兰店区',
        210224: '长海县',
        210281: '瓦房店市',
        210283: '庄河市',
        210302: '铁东区',
        210303: '铁西区',
        210304: '立山区',
        210311: '千山区',
        210321: '台安县',
        210323: '岫岩满族自治县',
        210381: '海城市',
        210390: '高新区',
        210402: '新抚区',
        210403: '东洲区',
        210404: '望花区',
        210411: '顺城区',
        210421: '抚顺县',
        210422: '新宾满族自治县',
        210423: '清原满族自治县',
        210502: '平山区',
        210503: '溪湖区',
        210504: '明山区',
        210505: '南芬区',
        210521: '本溪满族自治县',
        210522: '桓仁满族自治县',
        210602: '元宝区',
        210603: '振兴区',
        210604: '振安区',
        210624: '宽甸满族自治县',
        210681: '东港市',
        210682: '凤城市',
        210702: '古塔区',
        210703: '凌河区',
        210711: '太和区',
        210726: '黑山县',
        210727: '义县',
        210781: '凌海市',
        210782: '北镇市',
        210793: '经济技术开发区',
        210802: '站前区',
        210803: '西市区',
        210804: '鲅鱼圈区',
        210811: '老边区',
        210881: '盖州市',
        210882: '大石桥市',
        210902: '海州区',
        210903: '新邱区',
        210904: '太平区',
        210905: '清河门区',
        210911: '细河区',
        210921: '阜新蒙古族自治县',
        210922: '彰武县',
        211002: '白塔区',
        211003: '文圣区',
        211004: '宏伟区',
        211005: '弓长岭区',
        211011: '太子河区',
        211021: '辽阳县',
        211081: '灯塔市',
        211102: '双台子区',
        211103: '兴隆台区',
        211104: '大洼区',
        211122: '盘山县',
        211202: '银州区',
        211204: '清河区',
        211221: '铁岭县',
        211223: '西丰县',
        211224: '昌图县',
        211281: '调兵山市',
        211282: '开原市',
        211302: '双塔区',
        211303: '龙城区',
        211321: '朝阳县',
        211322: '建平县',
        211324: '喀喇沁左翼蒙古族自治县',
        211381: '北票市',
        211382: '凌源市',
        211402: '连山区',
        211403: '龙港区',
        211404: '南票区',
        211421: '绥中县',
        211422: '建昌县',
        211481: '兴城市',
        220102: '南关区',
        220103: '宽城区',
        220104: '朝阳区',
        220105: '二道区',
        220106: '绿园区',
        220112: '双阳区',
        220113: '九台区',
        220122: '农安县',
        220182: '榆树市',
        220183: '德惠市',
        220192: '经济技术开发区',
        220202: '昌邑区',
        220203: '龙潭区',
        220204: '船营区',
        220211: '丰满区',
        220221: '永吉县',
        220281: '蛟河市',
        220282: '桦甸市',
        220283: '舒兰市',
        220284: '磐石市',
        220302: '铁西区',
        220303: '铁东区',
        220322: '梨树县',
        220323: '伊通满族自治县',
        220381: '公主岭市',
        220382: '双辽市',
        220402: '龙山区',
        220403: '西安区',
        220421: '东丰县',
        220422: '东辽县',
        220502: '东昌区',
        220503: '二道江区',
        220521: '通化县',
        220523: '辉南县',
        220524: '柳河县',
        220581: '梅河口市',
        220582: '集安市',
        220602: '浑江区',
        220605: '江源区',
        220621: '抚松县',
        220622: '靖宇县',
        220623: '长白朝鲜族自治县',
        220681: '临江市',
        220702: '宁江区',
        220721: '前郭尔罗斯蒙古族自治县',
        220722: '长岭县',
        220723: '乾安县',
        220781: '扶余市',
        220802: '洮北区',
        220821: '镇赉县',
        220822: '通榆县',
        220881: '洮南市',
        220882: '大安市',
        222401: '延吉市',
        222402: '图们市',
        222403: '敦化市',
        222404: '珲春市',
        222405: '龙井市',
        222406: '和龙市',
        222424: '汪清县',
        222426: '安图县',
        230102: '道里区',
        230103: '南岗区',
        230104: '道外区',
        230108: '平房区',
        230109: '松北区',
        230110: '香坊区',
        230111: '呼兰区',
        230112: '阿城区',
        230113: '双城区',
        230123: '依兰县',
        230124: '方正县',
        230125: '宾县',
        230126: '巴彦县',
        230127: '木兰县',
        230128: '通河县',
        230129: '延寿县',
        230183: '尚志市',
        230184: '五常市',
        230202: '龙沙区',
        230203: '建华区',
        230204: '铁锋区',
        230205: '昂昂溪区',
        230206: '富拉尔基区',
        230207: '碾子山区',
        230208: '梅里斯达斡尔族区',
        230221: '龙江县',
        230223: '依安县',
        230224: '泰来县',
        230225: '甘南县',
        230227: '富裕县',
        230229: '克山县',
        230230: '克东县',
        230231: '拜泉县',
        230281: '讷河市',
        230302: '鸡冠区',
        230303: '恒山区',
        230304: '滴道区',
        230305: '梨树区',
        230306: '城子河区',
        230307: '麻山区',
        230321: '鸡东县',
        230381: '虎林市',
        230382: '密山市',
        230402: '向阳区',
        230403: '工农区',
        230404: '南山区',
        230405: '兴安区',
        230406: '东山区',
        230407: '兴山区',
        230421: '萝北县',
        230422: '绥滨县',
        230502: '尖山区',
        230503: '岭东区',
        230505: '四方台区',
        230506: '宝山区',
        230521: '集贤县',
        230522: '友谊县',
        230523: '宝清县',
        230524: '饶河县',
        230602: '萨尔图区',
        230603: '龙凤区',
        230604: '让胡路区',
        230605: '红岗区',
        230606: '大同区',
        230621: '肇州县',
        230622: '肇源县',
        230623: '林甸县',
        230624: '杜尔伯特蒙古族自治县',
        230702: '伊春区',
        230703: '南岔区',
        230704: '友好区',
        230705: '西林区',
        230706: '翠峦区',
        230707: '新青区',
        230708: '美溪区',
        230709: '金山屯区',
        230710: '五营区',
        230711: '乌马河区',
        230712: '汤旺河区',
        230713: '带岭区',
        230714: '乌伊岭区',
        230715: '红星区',
        230716: '上甘岭区',
        230722: '嘉荫县',
        230781: '铁力市',
        230803: '向阳区',
        230804: '前进区',
        230805: '东风区',
        230811: '郊区',
        230822: '桦南县',
        230826: '桦川县',
        230828: '汤原县',
        230881: '同江市',
        230882: '富锦市',
        230883: '抚远市',
        230902: '新兴区',
        230903: '桃山区',
        230904: '茄子河区',
        230921: '勃利县',
        231002: '东安区',
        231003: '阳明区',
        231004: '爱民区',
        231005: '西安区',
        231025: '林口县',
        231081: '绥芬河市',
        231083: '海林市',
        231084: '宁安市',
        231085: '穆棱市',
        231086: '东宁市',
        231102: '爱辉区',
        231121: '嫩江县',
        231123: '逊克县',
        231124: '孙吴县',
        231181: '北安市',
        231182: '五大连池市',
        231202: '北林区',
        231221: '望奎县',
        231222: '兰西县',
        231223: '青冈县',
        231224: '庆安县',
        231225: '明水县',
        231226: '绥棱县',
        231281: '安达市',
        231282: '肇东市',
        231283: '海伦市',
        232701: '漠河市',
        232721: '呼玛县',
        232722: '塔河县',
        232790: '松岭区',
        232791: '呼中区',
        232792: '加格达奇区',
        232793: '新林区',
        310101: '黄浦区',
        310104: '徐汇区',
        310105: '长宁区',
        310106: '静安区',
        310107: '普陀区',
        310109: '虹口区',
        310110: '杨浦区',
        310112: '闵行区',
        310113: '宝山区',
        310114: '嘉定区',
        310115: '浦东新区',
        310116: '金山区',
        310117: '松江区',
        310118: '青浦区',
        310120: '奉贤区',
        310151: '崇明区',
        320102: '玄武区',
        320104: '秦淮区',
        320105: '建邺区',
        320106: '鼓楼区',
        320111: '浦口区',
        320113: '栖霞区',
        320114: '雨花台区',
        320115: '江宁区',
        320116: '六合区',
        320117: '溧水区',
        320118: '高淳区',
        320205: '锡山区',
        320206: '惠山区',
        320211: '滨湖区',
        320213: '梁溪区',
        320214: '新吴区',
        320281: '江阴市',
        320282: '宜兴市',
        320302: '鼓楼区',
        320303: '云龙区',
        320305: '贾汪区',
        320311: '泉山区',
        320312: '铜山区',
        320321: '丰县',
        320322: '沛县',
        320324: '睢宁县',
        320381: '新沂市',
        320382: '邳州市',
        320391: '工业园区',
        320402: '天宁区',
        320404: '钟楼区',
        320411: '新北区',
        320412: '武进区',
        320413: '金坛区',
        320481: '溧阳市',
        320505: '虎丘区',
        320506: '吴中区',
        320507: '相城区',
        320508: '姑苏区',
        320509: '吴江区',
        320581: '常熟市',
        320582: '张家港市',
        320583: '昆山市',
        320585: '太仓市',
        320590: '工业园区',
        320591: '高新区',
        320602: '崇川区',
        320611: '港闸区',
        320612: '通州区',
        320623: '如东县',
        320681: '启东市',
        320682: '如皋市',
        320684: '海门市',
        320685: '海安市',
        320691: '高新区',
        320703: '连云区',
        320706: '海州区',
        320707: '赣榆区',
        320722: '东海县',
        320723: '灌云县',
        320724: '灌南县',
        320803: '淮安区',
        320804: '淮阴区',
        320812: '清江浦区',
        320813: '洪泽区',
        320826: '涟水县',
        320830: '盱眙县',
        320831: '金湖县',
        320890: '经济开发区',
        320902: '亭湖区',
        320903: '盐都区',
        320904: '大丰区',
        320921: '响水县',
        320922: '滨海县',
        320923: '阜宁县',
        320924: '射阳县',
        320925: '建湖县',
        320981: '东台市',
        321002: '广陵区',
        321003: '邗江区',
        321012: '江都区',
        321023: '宝应县',
        321081: '仪征市',
        321084: '高邮市',
        321090: '经济开发区',
        321102: '京口区',
        321111: '润州区',
        321112: '丹徒区',
        321181: '丹阳市',
        321182: '扬中市',
        321183: '句容市',
        321202: '海陵区',
        321203: '高港区',
        321204: '姜堰区',
        321281: '兴化市',
        321282: '靖江市',
        321283: '泰兴市',
        321302: '宿城区',
        321311: '宿豫区',
        321322: '沭阳县',
        321323: '泗阳县',
        321324: '泗洪县',
        330102: '上城区',
        330103: '下城区',
        330104: '江干区',
        330105: '拱墅区',
        330106: '西湖区',
        330108: '滨江区',
        330109: '萧山区',
        330110: '余杭区',
        330111: '富阳区',
        330112: '临安区',
        330122: '桐庐县',
        330127: '淳安县',
        330182: '建德市',
        330203: '海曙区',
        330205: '江北区',
        330206: '北仑区',
        330211: '镇海区',
        330212: '鄞州区',
        330213: '奉化区',
        330225: '象山县',
        330226: '宁海县',
        330281: '余姚市',
        330282: '慈溪市',
        330302: '鹿城区',
        330303: '龙湾区',
        330304: '瓯海区',
        330305: '洞头区',
        330324: '永嘉县',
        330326: '平阳县',
        330327: '苍南县',
        330328: '文成县',
        330329: '泰顺县',
        330381: '瑞安市',
        330382: '乐清市',
        330402: '南湖区',
        330411: '秀洲区',
        330421: '嘉善县',
        330424: '海盐县',
        330481: '海宁市',
        330482: '平湖市',
        330483: '桐乡市',
        330502: '吴兴区',
        330503: '南浔区',
        330521: '德清县',
        330522: '长兴县',
        330523: '安吉县',
        330602: '越城区',
        330603: '柯桥区',
        330604: '上虞区',
        330624: '新昌县',
        330681: '诸暨市',
        330683: '嵊州市',
        330702: '婺城区',
        330703: '金东区',
        330723: '武义县',
        330726: '浦江县',
        330727: '磐安县',
        330781: '兰溪市',
        330782: '义乌市',
        330783: '东阳市',
        330784: '永康市',
        330802: '柯城区',
        330803: '衢江区',
        330822: '常山县',
        330824: '开化县',
        330825: '龙游县',
        330881: '江山市',
        330902: '定海区',
        330903: '普陀区',
        330921: '岱山县',
        330922: '嵊泗县',
        331002: '椒江区',
        331003: '黄岩区',
        331004: '路桥区',
        331022: '三门县',
        331023: '天台县',
        331024: '仙居县',
        331081: '温岭市',
        331082: '临海市',
        331083: '玉环市',
        331102: '莲都区',
        331121: '青田县',
        331122: '缙云县',
        331123: '遂昌县',
        331124: '松阳县',
        331125: '云和县',
        331126: '庆元县',
        331127: '景宁畲族自治县',
        331181: '龙泉市',
        340102: '瑶海区',
        340103: '庐阳区',
        340104: '蜀山区',
        340111: '包河区',
        340121: '长丰县',
        340122: '肥东县',
        340123: '肥西县',
        340124: '庐江县',
        340181: '巢湖市',
        340190: '高新技术开发区',
        340191: '经济技术开发区',
        340202: '镜湖区',
        340203: '弋江区',
        340207: '鸠江区',
        340208: '三山区',
        340221: '芜湖县',
        340222: '繁昌县',
        340223: '南陵县',
        340225: '无为县',
        340302: '龙子湖区',
        340303: '蚌山区',
        340304: '禹会区',
        340311: '淮上区',
        340321: '怀远县',
        340322: '五河县',
        340323: '固镇县',
        340402: '大通区',
        340403: '田家庵区',
        340404: '谢家集区',
        340405: '八公山区',
        340406: '潘集区',
        340421: '凤台县',
        340422: '寿县',
        340503: '花山区',
        340504: '雨山区',
        340506: '博望区',
        340521: '当涂县',
        340522: '含山县',
        340523: '和县',
        340602: '杜集区',
        340603: '相山区',
        340604: '烈山区',
        340621: '濉溪县',
        340705: '铜官区',
        340706: '义安区',
        340711: '郊区',
        340722: '枞阳县',
        340802: '迎江区',
        340803: '大观区',
        340811: '宜秀区',
        340822: '怀宁县',
        340824: '潜山县',
        340825: '太湖县',
        340826: '宿松县',
        340827: '望江县',
        340828: '岳西县',
        340881: '桐城市',
        341002: '屯溪区',
        341003: '黄山区',
        341004: '徽州区',
        341021: '歙县',
        341022: '休宁县',
        341023: '黟县',
        341024: '祁门县',
        341102: '琅琊区',
        341103: '南谯区',
        341122: '来安县',
        341124: '全椒县',
        341125: '定远县',
        341126: '凤阳县',
        341181: '天长市',
        341182: '明光市',
        341202: '颍州区',
        341203: '颍东区',
        341204: '颍泉区',
        341221: '临泉县',
        341222: '太和县',
        341225: '阜南县',
        341226: '颍上县',
        341282: '界首市',
        341302: '埇桥区',
        341321: '砀山县',
        341322: '萧县',
        341323: '灵璧县',
        341324: '泗县',
        341390: '经济开发区',
        341502: '金安区',
        341503: '裕安区',
        341504: '叶集区',
        341522: '霍邱县',
        341523: '舒城县',
        341524: '金寨县',
        341525: '霍山县',
        341602: '谯城区',
        341621: '涡阳县',
        341622: '蒙城县',
        341623: '利辛县',
        341702: '贵池区',
        341721: '东至县',
        341722: '石台县',
        341723: '青阳县',
        341802: '宣州区',
        341821: '郎溪县',
        341822: '广德县',
        341823: '泾县',
        341824: '绩溪县',
        341825: '旌德县',
        341881: '宁国市',
        350102: '鼓楼区',
        350103: '台江区',
        350104: '仓山区',
        350105: '马尾区',
        350111: '晋安区',
        350112: '长乐区',
        350121: '闽侯县',
        350122: '连江县',
        350123: '罗源县',
        350124: '闽清县',
        350125: '永泰县',
        350128: '平潭县',
        350181: '福清市',
        350203: '思明区',
        350205: '海沧区',
        350206: '湖里区',
        350211: '集美区',
        350212: '同安区',
        350213: '翔安区',
        350302: '城厢区',
        350303: '涵江区',
        350304: '荔城区',
        350305: '秀屿区',
        350322: '仙游县',
        350402: '梅列区',
        350403: '三元区',
        350421: '明溪县',
        350423: '清流县',
        350424: '宁化县',
        350425: '大田县',
        350426: '尤溪县',
        350427: '沙县',
        350428: '将乐县',
        350429: '泰宁县',
        350430: '建宁县',
        350481: '永安市',
        350502: '鲤城区',
        350503: '丰泽区',
        350504: '洛江区',
        350505: '泉港区',
        350521: '惠安县',
        350524: '安溪县',
        350525: '永春县',
        350526: '德化县',
        350527: '金门县',
        350581: '石狮市',
        350582: '晋江市',
        350583: '南安市',
        350602: '芗城区',
        350603: '龙文区',
        350622: '云霄县',
        350623: '漳浦县',
        350624: '诏安县',
        350625: '长泰县',
        350626: '东山县',
        350627: '南靖县',
        350628: '平和县',
        350629: '华安县',
        350681: '龙海市',
        350702: '延平区',
        350703: '建阳区',
        350721: '顺昌县',
        350722: '浦城县',
        350723: '光泽县',
        350724: '松溪县',
        350725: '政和县',
        350781: '邵武市',
        350782: '武夷山市',
        350783: '建瓯市',
        350802: '新罗区',
        350803: '永定区',
        350821: '长汀县',
        350823: '上杭县',
        350824: '武平县',
        350825: '连城县',
        350881: '漳平市',
        350902: '蕉城区',
        350921: '霞浦县',
        350922: '古田县',
        350923: '屏南县',
        350924: '寿宁县',
        350925: '周宁县',
        350926: '柘荣县',
        350981: '福安市',
        350982: '福鼎市',
        360102: '东湖区',
        360103: '西湖区',
        360104: '青云谱区',
        360105: '湾里区',
        360111: '青山湖区',
        360112: '新建区',
        360121: '南昌县',
        360123: '安义县',
        360124: '进贤县',
        360190: '经济技术开发区',
        360192: '高新区',
        360202: '昌江区',
        360203: '珠山区',
        360222: '浮梁县',
        360281: '乐平市',
        360302: '安源区',
        360313: '湘东区',
        360321: '莲花县',
        360322: '上栗县',
        360323: '芦溪县',
        360402: '濂溪区',
        360403: '浔阳区',
        360404: '柴桑区',
        360423: '武宁县',
        360424: '修水县',
        360425: '永修县',
        360426: '德安县',
        360428: '都昌县',
        360429: '湖口县',
        360430: '彭泽县',
        360481: '瑞昌市',
        360482: '共青城市',
        360483: '庐山市',
        360490: '经济技术开发区',
        360502: '渝水区',
        360521: '分宜县',
        360602: '月湖区',
        360603: '余江区',
        360681: '贵溪市',
        360702: '章贡区',
        360703: '南康区',
        360704: '赣县区',
        360722: '信丰县',
        360723: '大余县',
        360724: '上犹县',
        360725: '崇义县',
        360726: '安远县',
        360727: '龙南县',
        360728: '定南县',
        360729: '全南县',
        360730: '宁都县',
        360731: '于都县',
        360732: '兴国县',
        360733: '会昌县',
        360734: '寻乌县',
        360735: '石城县',
        360781: '瑞金市',
        360802: '吉州区',
        360803: '青原区',
        360821: '吉安县',
        360822: '吉水县',
        360823: '峡江县',
        360824: '新干县',
        360825: '永丰县',
        360826: '泰和县',
        360827: '遂川县',
        360828: '万安县',
        360829: '安福县',
        360830: '永新县',
        360881: '井冈山市',
        360902: '袁州区',
        360921: '奉新县',
        360922: '万载县',
        360923: '上高县',
        360924: '宜丰县',
        360925: '靖安县',
        360926: '铜鼓县',
        360981: '丰城市',
        360982: '樟树市',
        360983: '高安市',
        361002: '临川区',
        361003: '东乡区',
        361021: '南城县',
        361022: '黎川县',
        361023: '南丰县',
        361024: '崇仁县',
        361025: '乐安县',
        361026: '宜黄县',
        361027: '金溪县',
        361028: '资溪县',
        361030: '广昌县',
        361102: '信州区',
        361103: '广丰区',
        361121: '上饶县',
        361123: '玉山县',
        361124: '铅山县',
        361125: '横峰县',
        361126: '弋阳县',
        361127: '余干县',
        361128: '鄱阳县',
        361129: '万年县',
        361130: '婺源县',
        361181: '德兴市',
        370102: '历下区',
        370103: '市中区',
        370104: '槐荫区',
        370105: '天桥区',
        370112: '历城区',
        370113: '长清区',
        370114: '章丘区',
        370115: '济阳区',
        370124: '平阴县',
        370126: '商河县',
        370190: '高新区',
        370202: '市南区',
        370203: '市北区',
        370211: '黄岛区',
        370212: '崂山区',
        370213: '李沧区',
        370214: '城阳区',
        370215: '即墨区',
        370281: '胶州市',
        370283: '平度市',
        370285: '莱西市',
        370290: '开发区',
        370302: '淄川区',
        370303: '张店区',
        370304: '博山区',
        370305: '临淄区',
        370306: '周村区',
        370321: '桓台县',
        370322: '高青县',
        370323: '沂源县',
        370402: '市中区',
        370403: '薛城区',
        370404: '峄城区',
        370405: '台儿庄区',
        370406: '山亭区',
        370481: '滕州市',
        370502: '东营区',
        370503: '河口区',
        370505: '垦利区',
        370522: '利津县',
        370523: '广饶县',
        370602: '芝罘区',
        370611: '福山区',
        370612: '牟平区',
        370613: '莱山区',
        370634: '长岛县',
        370681: '龙口市',
        370682: '莱阳市',
        370683: '莱州市',
        370684: '蓬莱市',
        370685: '招远市',
        370686: '栖霞市',
        370687: '海阳市',
        370690: '开发区',
        370702: '潍城区',
        370703: '寒亭区',
        370704: '坊子区',
        370705: '奎文区',
        370724: '临朐县',
        370725: '昌乐县',
        370781: '青州市',
        370782: '诸城市',
        370783: '寿光市',
        370784: '安丘市',
        370785: '高密市',
        370786: '昌邑市',
        370790: '开发区',
        370791: '高新区',
        370811: '任城区',
        370812: '兖州区',
        370826: '微山县',
        370827: '鱼台县',
        370828: '金乡县',
        370829: '嘉祥县',
        370830: '汶上县',
        370831: '泗水县',
        370832: '梁山县',
        370881: '曲阜市',
        370883: '邹城市',
        370890: '高新区',
        370902: '泰山区',
        370911: '岱岳区',
        370921: '宁阳县',
        370923: '东平县',
        370982: '新泰市',
        370983: '肥城市',
        371002: '环翠区',
        371003: '文登区',
        371082: '荣成市',
        371083: '乳山市',
        371091: '经济技术开发区',
        371102: '东港区',
        371103: '岚山区',
        371121: '五莲县',
        371122: '莒县',
        371202: '莱城区',
        371203: '钢城区',
        371302: '兰山区',
        371311: '罗庄区',
        371312: '河东区',
        371321: '沂南县',
        371322: '郯城县',
        371323: '沂水县',
        371324: '兰陵县',
        371325: '费县',
        371326: '平邑县',
        371327: '莒南县',
        371328: '蒙阴县',
        371329: '临沭县',
        371402: '德城区',
        371403: '陵城区',
        371422: '宁津县',
        371423: '庆云县',
        371424: '临邑县',
        371425: '齐河县',
        371426: '平原县',
        371427: '夏津县',
        371428: '武城县',
        371481: '乐陵市',
        371482: '禹城市',
        371502: '东昌府区',
        371521: '阳谷县',
        371522: '莘县',
        371523: '茌平县',
        371524: '东阿县',
        371525: '冠县',
        371526: '高唐县',
        371581: '临清市',
        371602: '滨城区',
        371603: '沾化区',
        371621: '惠民县',
        371622: '阳信县',
        371623: '无棣县',
        371625: '博兴县',
        371681: '邹平市',
        371702: '牡丹区',
        371703: '定陶区',
        371721: '曹县',
        371722: '单县',
        371723: '成武县',
        371724: '巨野县',
        371725: '郓城县',
        371726: '鄄城县',
        371728: '东明县',
        410102: '中原区',
        410103: '二七区',
        410104: '管城回族区',
        410105: '金水区',
        410106: '上街区',
        410108: '惠济区',
        410122: '中牟县',
        410181: '巩义市',
        410182: '荥阳市',
        410183: '新密市',
        410184: '新郑市',
        410185: '登封市',
        410190: '高新技术开发区',
        410191: '经济技术开发区',
        410202: '龙亭区',
        410203: '顺河回族区',
        410204: '鼓楼区',
        410205: '禹王台区',
        410212: '祥符区',
        410221: '杞县',
        410222: '通许县',
        410223: '尉氏县',
        410225: '兰考县',
        410302: '老城区',
        410303: '西工区',
        410304: '瀍河回族区',
        410305: '涧西区',
        410306: '吉利区',
        410311: '洛龙区',
        410322: '孟津县',
        410323: '新安县',
        410324: '栾川县',
        410325: '嵩县',
        410326: '汝阳县',
        410327: '宜阳县',
        410328: '洛宁县',
        410329: '伊川县',
        410381: '偃师市',
        410402: '新华区',
        410403: '卫东区',
        410404: '石龙区',
        410411: '湛河区',
        410421: '宝丰县',
        410422: '叶县',
        410423: '鲁山县',
        410425: '郏县',
        410481: '舞钢市',
        410482: '汝州市',
        410502: '文峰区',
        410503: '北关区',
        410505: '殷都区',
        410506: '龙安区',
        410522: '安阳县',
        410523: '汤阴县',
        410526: '滑县',
        410527: '内黄县',
        410581: '林州市',
        410590: '开发区',
        410602: '鹤山区',
        410603: '山城区',
        410611: '淇滨区',
        410621: '浚县',
        410622: '淇县',
        410702: '红旗区',
        410703: '卫滨区',
        410704: '凤泉区',
        410711: '牧野区',
        410721: '新乡县',
        410724: '获嘉县',
        410725: '原阳县',
        410726: '延津县',
        410727: '封丘县',
        410728: '长垣县',
        410781: '卫辉市',
        410782: '辉县市',
        410802: '解放区',
        410803: '中站区',
        410804: '马村区',
        410811: '山阳区',
        410821: '修武县',
        410822: '博爱县',
        410823: '武陟县',
        410825: '温县',
        410882: '沁阳市',
        410883: '孟州市',
        410902: '华龙区',
        410922: '清丰县',
        410923: '南乐县',
        410926: '范县',
        410927: '台前县',
        410928: '濮阳县',
        411002: '魏都区',
        411003: '建安区',
        411024: '鄢陵县',
        411025: '襄城县',
        411081: '禹州市',
        411082: '长葛市',
        411102: '源汇区',
        411103: '郾城区',
        411104: '召陵区',
        411121: '舞阳县',
        411122: '临颍县',
        411202: '湖滨区',
        411203: '陕州区',
        411221: '渑池县',
        411224: '卢氏县',
        411281: '义马市',
        411282: '灵宝市',
        411302: '宛城区',
        411303: '卧龙区',
        411321: '南召县',
        411322: '方城县',
        411323: '西峡县',
        411324: '镇平县',
        411325: '内乡县',
        411326: '淅川县',
        411327: '社旗县',
        411328: '唐河县',
        411329: '新野县',
        411330: '桐柏县',
        411381: '邓州市',
        411402: '梁园区',
        411403: '睢阳区',
        411421: '民权县',
        411422: '睢县',
        411423: '宁陵县',
        411424: '柘城县',
        411425: '虞城县',
        411426: '夏邑县',
        411481: '永城市',
        411502: '浉河区',
        411503: '平桥区',
        411521: '罗山县',
        411522: '光山县',
        411523: '新县',
        411524: '商城县',
        411525: '固始县',
        411526: '潢川县',
        411527: '淮滨县',
        411528: '息县',
        411602: '川汇区',
        411621: '扶沟县',
        411622: '西华县',
        411623: '商水县',
        411624: '沈丘县',
        411625: '郸城县',
        411626: '淮阳县',
        411627: '太康县',
        411628: '鹿邑县',
        411681: '项城市',
        411690: '经济开发区',
        411702: '驿城区',
        411721: '西平县',
        411722: '上蔡县',
        411723: '平舆县',
        411724: '正阳县',
        411725: '确山县',
        411726: '泌阳县',
        411727: '汝南县',
        411728: '遂平县',
        411729: '新蔡县',
        419001: '济源市',
        420102: '江岸区',
        420103: '江汉区',
        420104: '硚口区',
        420105: '汉阳区',
        420106: '武昌区',
        420107: '青山区',
        420111: '洪山区',
        420112: '东西湖区',
        420113: '汉南区',
        420114: '蔡甸区',
        420115: '江夏区',
        420116: '黄陂区',
        420117: '新洲区',
        420202: '黄石港区',
        420203: '西塞山区',
        420204: '下陆区',
        420205: '铁山区',
        420222: '阳新县',
        420281: '大冶市',
        420302: '茅箭区',
        420303: '张湾区',
        420304: '郧阳区',
        420322: '郧西县',
        420323: '竹山县',
        420324: '竹溪县',
        420325: '房县',
        420381: '丹江口市',
        420502: '西陵区',
        420503: '伍家岗区',
        420504: '点军区',
        420505: '猇亭区',
        420506: '夷陵区',
        420525: '远安县',
        420526: '兴山县',
        420527: '秭归县',
        420528: '长阳土家族自治县',
        420529: '五峰土家族自治县',
        420581: '宜都市',
        420582: '当阳市',
        420583: '枝江市',
        420590: '经济开发区',
        420602: '襄城区',
        420606: '樊城区',
        420607: '襄州区',
        420624: '南漳县',
        420625: '谷城县',
        420626: '保康县',
        420682: '老河口市',
        420683: '枣阳市',
        420684: '宜城市',
        420702: '梁子湖区',
        420703: '华容区',
        420704: '鄂城区',
        420802: '东宝区',
        420804: '掇刀区',
        420822: '沙洋县',
        420881: '钟祥市',
        420882: '京山市',
        420902: '孝南区',
        420921: '孝昌县',
        420922: '大悟县',
        420923: '云梦县',
        420981: '应城市',
        420982: '安陆市',
        420984: '汉川市',
        421002: '沙市区',
        421003: '荆州区',
        421022: '公安县',
        421023: '监利县',
        421024: '江陵县',
        421081: '石首市',
        421083: '洪湖市',
        421087: '松滋市',
        421102: '黄州区',
        421121: '团风县',
        421122: '红安县',
        421123: '罗田县',
        421124: '英山县',
        421125: '浠水县',
        421126: '蕲春县',
        421127: '黄梅县',
        421181: '麻城市',
        421182: '武穴市',
        421202: '咸安区',
        421221: '嘉鱼县',
        421222: '通城县',
        421223: '崇阳县',
        421224: '通山县',
        421281: '赤壁市',
        421303: '曾都区',
        421321: '随县',
        421381: '广水市',
        422801: '恩施市',
        422802: '利川市',
        422822: '建始县',
        422823: '巴东县',
        422825: '宣恩县',
        422826: '咸丰县',
        422827: '来凤县',
        422828: '鹤峰县',
        429004: '仙桃市',
        429005: '潜江市',
        429006: '天门市',
        429021: '神农架林区',
        430102: '芙蓉区',
        430103: '天心区',
        430104: '岳麓区',
        430105: '开福区',
        430111: '雨花区',
        430112: '望城区',
        430121: '长沙县',
        430181: '浏阳市',
        430182: '宁乡市',
        430202: '荷塘区',
        430203: '芦淞区',
        430204: '石峰区',
        430211: '天元区',
        430212: '渌口区',
        430223: '攸县',
        430224: '茶陵县',
        430225: '炎陵县',
        430281: '醴陵市',
        430302: '雨湖区',
        430304: '岳塘区',
        430321: '湘潭县',
        430381: '湘乡市',
        430382: '韶山市',
        430405: '珠晖区',
        430406: '雁峰区',
        430407: '石鼓区',
        430408: '蒸湘区',
        430412: '南岳区',
        430421: '衡阳县',
        430422: '衡南县',
        430423: '衡山县',
        430424: '衡东县',
        430426: '祁东县',
        430481: '耒阳市',
        430482: '常宁市',
        430502: '双清区',
        430503: '大祥区',
        430511: '北塔区',
        430521: '邵东县',
        430522: '新邵县',
        430523: '邵阳县',
        430524: '隆回县',
        430525: '洞口县',
        430527: '绥宁县',
        430528: '新宁县',
        430529: '城步苗族自治县',
        430581: '武冈市',
        430602: '岳阳楼区',
        430603: '云溪区',
        430611: '君山区',
        430621: '岳阳县',
        430623: '华容县',
        430624: '湘阴县',
        430626: '平江县',
        430681: '汨罗市',
        430682: '临湘市',
        430702: '武陵区',
        430703: '鼎城区',
        430721: '安乡县',
        430722: '汉寿县',
        430723: '澧县',
        430724: '临澧县',
        430725: '桃源县',
        430726: '石门县',
        430781: '津市市',
        430802: '永定区',
        430811: '武陵源区',
        430821: '慈利县',
        430822: '桑植县',
        430902: '资阳区',
        430903: '赫山区',
        430921: '南县',
        430922: '桃江县',
        430923: '安化县',
        430981: '沅江市',
        431002: '北湖区',
        431003: '苏仙区',
        431021: '桂阳县',
        431022: '宜章县',
        431023: '永兴县',
        431024: '嘉禾县',
        431025: '临武县',
        431026: '汝城县',
        431027: '桂东县',
        431028: '安仁县',
        431081: '资兴市',
        431102: '零陵区',
        431103: '冷水滩区',
        431121: '祁阳县',
        431122: '东安县',
        431123: '双牌县',
        431124: '道县',
        431125: '江永县',
        431126: '宁远县',
        431127: '蓝山县',
        431128: '新田县',
        431129: '江华瑶族自治县',
        431202: '鹤城区',
        431221: '中方县',
        431222: '沅陵县',
        431223: '辰溪县',
        431224: '溆浦县',
        431225: '会同县',
        431226: '麻阳苗族自治县',
        431227: '新晃侗族自治县',
        431228: '芷江侗族自治县',
        431229: '靖州苗族侗族自治县',
        431230: '通道侗族自治县',
        431281: '洪江市',
        431302: '娄星区',
        431321: '双峰县',
        431322: '新化县',
        431381: '冷水江市',
        431382: '涟源市',
        433101: '吉首市',
        433122: '泸溪县',
        433123: '凤凰县',
        433124: '花垣县',
        433125: '保靖县',
        433126: '古丈县',
        433127: '永顺县',
        433130: '龙山县',
        440103: '荔湾区',
        440104: '越秀区',
        440105: '海珠区',
        440106: '天河区',
        440111: '白云区',
        440112: '黄埔区',
        440113: '番禺区',
        440114: '花都区',
        440115: '南沙区',
        440117: '从化区',
        440118: '增城区',
        440203: '武江区',
        440204: '浈江区',
        440205: '曲江区',
        440222: '始兴县',
        440224: '仁化县',
        440229: '翁源县',
        440232: '乳源瑶族自治县',
        440233: '新丰县',
        440281: '乐昌市',
        440282: '南雄市',
        440303: '罗湖区',
        440304: '福田区',
        440305: '南山区',
        440306: '宝安区',
        440307: '龙岗区',
        440308: '盐田区',
        440309: '龙华区',
        440310: '坪山区',
        440311: '光明区',
        440402: '香洲区',
        440403: '斗门区',
        440404: '金湾区',
        440507: '龙湖区',
        440511: '金平区',
        440512: '濠江区',
        440513: '潮阳区',
        440514: '潮南区',
        440515: '澄海区',
        440523: '南澳县',
        440604: '禅城区',
        440605: '南海区',
        440606: '顺德区',
        440607: '三水区',
        440608: '高明区',
        440703: '蓬江区',
        440704: '江海区',
        440705: '新会区',
        440781: '台山市',
        440783: '开平市',
        440784: '鹤山市',
        440785: '恩平市',
        440802: '赤坎区',
        440803: '霞山区',
        440804: '坡头区',
        440811: '麻章区',
        440823: '遂溪县',
        440825: '徐闻县',
        440881: '廉江市',
        440882: '雷州市',
        440883: '吴川市',
        440890: '经济技术开发区',
        440902: '茂南区',
        440904: '电白区',
        440981: '高州市',
        440982: '化州市',
        440983: '信宜市',
        441202: '端州区',
        441203: '鼎湖区',
        441204: '高要区',
        441223: '广宁县',
        441224: '怀集县',
        441225: '封开县',
        441226: '德庆县',
        441284: '四会市',
        441302: '惠城区',
        441303: '惠阳区',
        441322: '博罗县',
        441323: '惠东县',
        441324: '龙门县',
        441402: '梅江区',
        441403: '梅县区',
        441422: '大埔县',
        441423: '丰顺县',
        441424: '五华县',
        441426: '平远县',
        441427: '蕉岭县',
        441481: '兴宁市',
        441502: '城区',
        441521: '海丰县',
        441523: '陆河县',
        441581: '陆丰市',
        441602: '源城区',
        441621: '紫金县',
        441622: '龙川县',
        441623: '连平县',
        441624: '和平县',
        441625: '东源县',
        441702: '江城区',
        441704: '阳东区',
        441721: '阳西县',
        441781: '阳春市',
        441802: '清城区',
        441803: '清新区',
        441821: '佛冈县',
        441823: '阳山县',
        441825: '连山壮族瑶族自治县',
        441826: '连南瑶族自治县',
        441881: '英德市',
        441882: '连州市',
        441901: '中堂镇',
        441903: '南城街道办事处',
        441904: '长安镇',
        441905: '东坑镇',
        441906: '樟木头镇',
        441907: '莞城街道办事处',
        441908: '石龙镇',
        441909: '桥头镇',
        441910: '万江街道办事处',
        441911: '麻涌镇',
        441912: '虎门镇',
        441913: '谢岗镇',
        441914: '石碣镇',
        441915: '茶山镇',
        441916: '东城街道办事处',
        441917: '洪梅镇',
        441918: '道滘镇',
        441919: '高埗镇',
        441920: '企石镇',
        441921: '凤岗镇',
        441922: '大岭山镇',
        441923: '松山湖管委会',
        441924: '清溪镇',
        441925: '望牛墩镇',
        441926: '厚街镇',
        441927: '常平镇',
        441928: '寮步镇',
        441929: '石排镇',
        441930: '横沥镇',
        441931: '塘厦镇',
        441932: '黄江镇',
        441933: '大朗镇',
        441934: '东莞港',
        441935: '东莞生态园',
        441990: '沙田镇',
        442001: '南头镇',
        442002: '神湾镇',
        442003: '东凤镇',
        442004: '五桂山街道办事处',
        442005: '黄圃镇',
        442006: '小榄镇',
        442007: '石岐区街道办事处',
        442008: '横栏镇',
        442009: '三角镇',
        442010: '三乡镇',
        442011: '港口镇',
        442012: '沙溪镇',
        442013: '板芙镇',
        442015: '东升镇',
        442016: '阜沙镇',
        442017: '民众镇',
        442018: '东区街道办事处',
        442019: '火炬开发区街道办事处',
        442020: '西区街道办事处',
        442021: '南区街道办事处',
        442022: '古镇镇',
        442023: '坦洲镇',
        442024: '大涌镇',
        442025: '南朗镇',
        445102: '湘桥区',
        445103: '潮安区',
        445122: '饶平县',
        445202: '榕城区',
        445203: '揭东区',
        445222: '揭西县',
        445224: '惠来县',
        445281: '普宁市',
        445302: '云城区',
        445303: '云安区',
        445321: '新兴县',
        445322: '郁南县',
        445381: '罗定市',
        450102: '兴宁区',
        450103: '青秀区',
        450105: '江南区',
        450107: '西乡塘区',
        450108: '良庆区',
        450109: '邕宁区',
        450110: '武鸣区',
        450123: '隆安县',
        450124: '马山县',
        450125: '上林县',
        450126: '宾阳县',
        450127: '横县',
        450202: '城中区',
        450203: '鱼峰区',
        450204: '柳南区',
        450205: '柳北区',
        450206: '柳江区',
        450222: '柳城县',
        450223: '鹿寨县',
        450224: '融安县',
        450225: '融水苗族自治县',
        450226: '三江侗族自治县',
        450302: '秀峰区',
        450303: '叠彩区',
        450304: '象山区',
        450305: '七星区',
        450311: '雁山区',
        450312: '临桂区',
        450321: '阳朔县',
        450323: '灵川县',
        450324: '全州县',
        450325: '兴安县',
        450326: '永福县',
        450327: '灌阳县',
        450328: '龙胜各族自治县',
        450329: '资源县',
        450330: '平乐县',
        450332: '恭城瑶族自治县',
        450381: '荔浦市',
        450403: '万秀区',
        450405: '长洲区',
        450406: '龙圩区',
        450421: '苍梧县',
        450422: '藤县',
        450423: '蒙山县',
        450481: '岑溪市',
        450502: '海城区',
        450503: '银海区',
        450512: '铁山港区',
        450521: '合浦县',
        450602: '港口区',
        450603: '防城区',
        450621: '上思县',
        450681: '东兴市',
        450702: '钦南区',
        450703: '钦北区',
        450721: '灵山县',
        450722: '浦北县',
        450802: '港北区',
        450803: '港南区',
        450804: '覃塘区',
        450821: '平南县',
        450881: '桂平市',
        450902: '玉州区',
        450903: '福绵区',
        450921: '容县',
        450922: '陆川县',
        450923: '博白县',
        450924: '兴业县',
        450981: '北流市',
        451002: '右江区',
        451021: '田阳县',
        451022: '田东县',
        451023: '平果县',
        451024: '德保县',
        451026: '那坡县',
        451027: '凌云县',
        451028: '乐业县',
        451029: '田林县',
        451030: '西林县',
        451031: '隆林各族自治县',
        451081: '靖西市',
        451102: '八步区',
        451103: '平桂区',
        451121: '昭平县',
        451122: '钟山县',
        451123: '富川瑶族自治县',
        451202: '金城江区',
        451203: '宜州区',
        451221: '南丹县',
        451222: '天峨县',
        451223: '凤山县',
        451224: '东兰县',
        451225: '罗城仫佬族自治县',
        451226: '环江毛南族自治县',
        451227: '巴马瑶族自治县',
        451228: '都安瑶族自治县',
        451229: '大化瑶族自治县',
        451302: '兴宾区',
        451321: '忻城县',
        451322: '象州县',
        451323: '武宣县',
        451324: '金秀瑶族自治县',
        451381: '合山市',
        451402: '江州区',
        451421: '扶绥县',
        451422: '宁明县',
        451423: '龙州县',
        451424: '大新县',
        451425: '天等县',
        451481: '凭祥市',
        460105: '秀英区',
        460106: '龙华区',
        460107: '琼山区',
        460108: '美兰区',
        460202: '海棠区',
        460203: '吉阳区',
        460204: '天涯区',
        460205: '崖州区',
        460321: '西沙群岛',
        460322: '南沙群岛',
        460323: '中沙群岛的岛礁及其海域',
        460401: '那大镇',
        460402: '和庆镇',
        460403: '南丰镇',
        460404: '大成镇',
        460405: '雅星镇',
        460406: '兰洋镇',
        460407: '光村镇',
        460408: '木棠镇',
        460409: '海头镇',
        460410: '峨蔓镇',
        460411: '王五镇',
        460412: '白马井镇',
        460413: '中和镇',
        460414: '排浦镇',
        460415: '东成镇',
        460416: '新州镇',
        460417: '洋浦经济开发区',
        460418: '华南热作学院',
        469001: '五指山市',
        469002: '琼海市',
        469005: '文昌市',
        469006: '万宁市',
        469007: '东方市',
        469021: '定安县',
        469022: '屯昌县',
        469023: '澄迈县',
        469024: '临高县',
        469025: '白沙黎族自治县',
        469026: '昌江黎族自治县',
        469027: '乐东黎族自治县',
        469028: '陵水黎族自治县',
        469029: '保亭黎族苗族自治县',
        469030: '琼中黎族苗族自治县',
        500101: '万州区',
        500102: '涪陵区',
        500103: '渝中区',
        500104: '大渡口区',
        500105: '江北区',
        500106: '沙坪坝区',
        500107: '九龙坡区',
        500108: '南岸区',
        500109: '北碚区',
        500110: '綦江区',
        500111: '大足区',
        500112: '渝北区',
        500113: '巴南区',
        500114: '黔江区',
        500115: '长寿区',
        500116: '江津区',
        500117: '合川区',
        500118: '永川区',
        500119: '南川区',
        500120: '璧山区',
        500151: '铜梁区',
        500152: '潼南区',
        500153: '荣昌区',
        500154: '开州区',
        500155: '梁平区',
        500156: '武隆区',
        500229: '城口县',
        500230: '丰都县',
        500231: '垫江县',
        500233: '忠县',
        500235: '云阳县',
        500236: '奉节县',
        500237: '巫山县',
        500238: '巫溪县',
        500240: '石柱土家族自治县',
        500241: '秀山土家族苗族自治县',
        500242: '酉阳土家族苗族自治县',
        500243: '彭水苗族土家族自治县',
        510104: '锦江区',
        510105: '青羊区',
        510106: '金牛区',
        510107: '武侯区',
        510108: '成华区',
        510112: '龙泉驿区',
        510113: '青白江区',
        510114: '新都区',
        510115: '温江区',
        510116: '双流区',
        510117: '郫都区',
        510121: '金堂县',
        510129: '大邑县',
        510131: '蒲江县',
        510132: '新津县',
        510181: '都江堰市',
        510182: '彭州市',
        510183: '邛崃市',
        510184: '崇州市',
        510185: '简阳市',
        510191: '高新区',
        510302: '自流井区',
        510303: '贡井区',
        510304: '大安区',
        510311: '沿滩区',
        510321: '荣县',
        510322: '富顺县',
        510402: '东区',
        510403: '西区',
        510411: '仁和区',
        510421: '米易县',
        510422: '盐边县',
        510502: '江阳区',
        510503: '纳溪区',
        510504: '龙马潭区',
        510521: '泸县',
        510522: '合江县',
        510524: '叙永县',
        510525: '古蔺县',
        510603: '旌阳区',
        510604: '罗江区',
        510623: '中江县',
        510681: '广汉市',
        510682: '什邡市',
        510683: '绵竹市',
        510703: '涪城区',
        510704: '游仙区',
        510705: '安州区',
        510722: '三台县',
        510723: '盐亭县',
        510725: '梓潼县',
        510726: '北川羌族自治县',
        510727: '平武县',
        510781: '江油市',
        510791: '高新区',
        510802: '利州区',
        510811: '昭化区',
        510812: '朝天区',
        510821: '旺苍县',
        510822: '青川县',
        510823: '剑阁县',
        510824: '苍溪县',
        510903: '船山区',
        510904: '安居区',
        510921: '蓬溪县',
        510922: '射洪县',
        510923: '大英县',
        511002: '市中区',
        511011: '东兴区',
        511024: '威远县',
        511025: '资中县',
        511083: '隆昌市',
        511102: '市中区',
        511111: '沙湾区',
        511112: '五通桥区',
        511113: '金口河区',
        511123: '犍为县',
        511124: '井研县',
        511126: '夹江县',
        511129: '沐川县',
        511132: '峨边彝族自治县',
        511133: '马边彝族自治县',
        511181: '峨眉山市',
        511302: '顺庆区',
        511303: '高坪区',
        511304: '嘉陵区',
        511321: '南部县',
        511322: '营山县',
        511323: '蓬安县',
        511324: '仪陇县',
        511325: '西充县',
        511381: '阆中市',
        511402: '东坡区',
        511403: '彭山区',
        511421: '仁寿县',
        511423: '洪雅县',
        511424: '丹棱县',
        511425: '青神县',
        511502: '翠屏区',
        511503: '南溪区',
        511504: '叙州区',
        511523: '江安县',
        511524: '长宁县',
        511525: '高县',
        511526: '珙县',
        511527: '筠连县',
        511528: '兴文县',
        511529: '屏山县',
        511602: '广安区',
        511603: '前锋区',
        511621: '岳池县',
        511622: '武胜县',
        511623: '邻水县',
        511681: '华蓥市',
        511702: '通川区',
        511703: '达川区',
        511722: '宣汉县',
        511723: '开江县',
        511724: '大竹县',
        511725: '渠县',
        511781: '万源市',
        511802: '雨城区',
        511803: '名山区',
        511822: '荥经县',
        511823: '汉源县',
        511824: '石棉县',
        511825: '天全县',
        511826: '芦山县',
        511827: '宝兴县',
        511902: '巴州区',
        511903: '恩阳区',
        511921: '通江县',
        511922: '南江县',
        511923: '平昌县',
        512002: '雁江区',
        512021: '安岳县',
        512022: '乐至县',
        513201: '马尔康市',
        513221: '汶川县',
        513222: '理县',
        513223: '茂县',
        513224: '松潘县',
        513225: '九寨沟县',
        513226: '金川县',
        513227: '小金县',
        513228: '黑水县',
        513230: '壤塘县',
        513231: '阿坝县',
        513232: '若尔盖县',
        513233: '红原县',
        513301: '康定市',
        513322: '泸定县',
        513323: '丹巴县',
        513324: '九龙县',
        513325: '雅江县',
        513326: '道孚县',
        513327: '炉霍县',
        513328: '甘孜县',
        513329: '新龙县',
        513330: '德格县',
        513331: '白玉县',
        513332: '石渠县',
        513333: '色达县',
        513334: '理塘县',
        513335: '巴塘县',
        513336: '乡城县',
        513337: '稻城县',
        513338: '得荣县',
        513401: '西昌市',
        513422: '木里藏族自治县',
        513423: '盐源县',
        513424: '德昌县',
        513425: '会理县',
        513426: '会东县',
        513427: '宁南县',
        513428: '普格县',
        513429: '布拖县',
        513430: '金阳县',
        513431: '昭觉县',
        513432: '喜德县',
        513433: '冕宁县',
        513434: '越西县',
        513435: '甘洛县',
        513436: '美姑县',
        513437: '雷波县',
        520102: '南明区',
        520103: '云岩区',
        520111: '花溪区',
        520112: '乌当区',
        520113: '白云区',
        520115: '观山湖区',
        520121: '开阳县',
        520122: '息烽县',
        520123: '修文县',
        520181: '清镇市',
        520201: '钟山区',
        520203: '六枝特区',
        520221: '水城县',
        520281: '盘州市',
        520302: '红花岗区',
        520303: '汇川区',
        520304: '播州区',
        520322: '桐梓县',
        520323: '绥阳县',
        520324: '正安县',
        520325: '道真仡佬族苗族自治县',
        520326: '务川仡佬族苗族自治县',
        520327: '凤冈县',
        520328: '湄潭县',
        520329: '余庆县',
        520330: '习水县',
        520381: '赤水市',
        520382: '仁怀市',
        520402: '西秀区',
        520403: '平坝区',
        520422: '普定县',
        520423: '镇宁布依族苗族自治县',
        520424: '关岭布依族苗族自治县',
        520425: '紫云苗族布依族自治县',
        520502: '七星关区',
        520521: '大方县',
        520522: '黔西县',
        520523: '金沙县',
        520524: '织金县',
        520525: '纳雍县',
        520526: '威宁彝族回族苗族自治县',
        520527: '赫章县',
        520602: '碧江区',
        520603: '万山区',
        520621: '江口县',
        520622: '玉屏侗族自治县',
        520623: '石阡县',
        520624: '思南县',
        520625: '印江土家族苗族自治县',
        520626: '德江县',
        520627: '沿河土家族自治县',
        520628: '松桃苗族自治县',
        522301: '兴义市',
        522302: '兴仁市',
        522323: '普安县',
        522324: '晴隆县',
        522325: '贞丰县',
        522326: '望谟县',
        522327: '册亨县',
        522328: '安龙县',
        522601: '凯里市',
        522622: '黄平县',
        522623: '施秉县',
        522624: '三穗县',
        522625: '镇远县',
        522626: '岑巩县',
        522627: '天柱县',
        522628: '锦屏县',
        522629: '剑河县',
        522630: '台江县',
        522631: '黎平县',
        522632: '榕江县',
        522633: '从江县',
        522634: '雷山县',
        522635: '麻江县',
        522636: '丹寨县',
        522701: '都匀市',
        522702: '福泉市',
        522722: '荔波县',
        522723: '贵定县',
        522725: '瓮安县',
        522726: '独山县',
        522727: '平塘县',
        522728: '罗甸县',
        522729: '长顺县',
        522730: '龙里县',
        522731: '惠水县',
        522732: '三都水族自治县',
        530102: '五华区',
        530103: '盘龙区',
        530111: '官渡区',
        530112: '西山区',
        530113: '东川区',
        530114: '呈贡区',
        530115: '晋宁区',
        530124: '富民县',
        530125: '宜良县',
        530126: '石林彝族自治县',
        530127: '嵩明县',
        530128: '禄劝彝族苗族自治县',
        530129: '寻甸回族彝族自治县',
        530181: '安宁市',
        530302: '麒麟区',
        530303: '沾益区',
        530304: '马龙区',
        530322: '陆良县',
        530323: '师宗县',
        530324: '罗平县',
        530325: '富源县',
        530326: '会泽县',
        530381: '宣威市',
        530402: '红塔区',
        530403: '江川区',
        530422: '澄江县',
        530423: '通海县',
        530424: '华宁县',
        530425: '易门县',
        530426: '峨山彝族自治县',
        530427: '新平彝族傣族自治县',
        530428: '元江哈尼族彝族傣族自治县',
        530502: '隆阳区',
        530521: '施甸县',
        530523: '龙陵县',
        530524: '昌宁县',
        530581: '腾冲市',
        530602: '昭阳区',
        530621: '鲁甸县',
        530622: '巧家县',
        530623: '盐津县',
        530624: '大关县',
        530625: '永善县',
        530626: '绥江县',
        530627: '镇雄县',
        530628: '彝良县',
        530629: '威信县',
        530681: '水富市',
        530702: '古城区',
        530721: '玉龙纳西族自治县',
        530722: '永胜县',
        530723: '华坪县',
        530724: '宁蒗彝族自治县',
        530802: '思茅区',
        530821: '宁洱哈尼族彝族自治县',
        530822: '墨江哈尼族自治县',
        530823: '景东彝族自治县',
        530824: '景谷傣族彝族自治县',
        530825: '镇沅彝族哈尼族拉祜族自治县',
        530826: '江城哈尼族彝族自治县',
        530827: '孟连傣族拉祜族佤族自治县',
        530828: '澜沧拉祜族自治县',
        530829: '西盟佤族自治县',
        530902: '临翔区',
        530921: '凤庆县',
        530922: '云县',
        530923: '永德县',
        530924: '镇康县',
        530925: '双江拉祜族佤族布朗族傣族自治县',
        530926: '耿马傣族佤族自治县',
        530927: '沧源佤族自治县',
        532301: '楚雄市',
        532322: '双柏县',
        532323: '牟定县',
        532324: '南华县',
        532325: '姚安县',
        532326: '大姚县',
        532327: '永仁县',
        532328: '元谋县',
        532329: '武定县',
        532331: '禄丰县',
        532501: '个旧市',
        532502: '开远市',
        532503: '蒙自市',
        532504: '弥勒市',
        532523: '屏边苗族自治县',
        532524: '建水县',
        532525: '石屏县',
        532527: '泸西县',
        532528: '元阳县',
        532529: '红河县',
        532530: '金平苗族瑶族傣族自治县',
        532531: '绿春县',
        532532: '河口瑶族自治县',
        532601: '文山市',
        532622: '砚山县',
        532623: '西畴县',
        532624: '麻栗坡县',
        532625: '马关县',
        532626: '丘北县',
        532627: '广南县',
        532628: '富宁县',
        532801: '景洪市',
        532822: '勐海县',
        532823: '勐腊县',
        532901: '大理市',
        532922: '漾濞彝族自治县',
        532923: '祥云县',
        532924: '宾川县',
        532925: '弥渡县',
        532926: '南涧彝族自治县',
        532927: '巍山彝族回族自治县',
        532928: '永平县',
        532929: '云龙县',
        532930: '洱源县',
        532931: '剑川县',
        532932: '鹤庆县',
        533102: '瑞丽市',
        533103: '芒市',
        533122: '梁河县',
        533123: '盈江县',
        533124: '陇川县',
        533301: '泸水市',
        533323: '福贡县',
        533324: '贡山独龙族怒族自治县',
        533325: '兰坪白族普米族自治县',
        533401: '香格里拉市',
        533422: '德钦县',
        533423: '维西傈僳族自治县',
        540102: '城关区',
        540103: '堆龙德庆区',
        540104: '达孜区',
        540121: '林周县',
        540122: '当雄县',
        540123: '尼木县',
        540124: '曲水县',
        540127: '墨竹工卡县',
        540202: '桑珠孜区',
        540221: '南木林县',
        540222: '江孜县',
        540223: '定日县',
        540224: '萨迦县',
        540225: '拉孜县',
        540226: '昂仁县',
        540227: '谢通门县',
        540228: '白朗县',
        540229: '仁布县',
        540230: '康马县',
        540231: '定结县',
        540232: '仲巴县',
        540233: '亚东县',
        540234: '吉隆县',
        540235: '聂拉木县',
        540236: '萨嘎县',
        540237: '岗巴县',
        540302: '卡若区',
        540321: '江达县',
        540322: '贡觉县',
        540323: '类乌齐县',
        540324: '丁青县',
        540325: '察雅县',
        540326: '八宿县',
        540327: '左贡县',
        540328: '芒康县',
        540329: '洛隆县',
        540330: '边坝县',
        540402: '巴宜区',
        540421: '工布江达县',
        540422: '米林县',
        540423: '墨脱县',
        540424: '波密县',
        540425: '察隅县',
        540426: '朗县',
        540502: '乃东区',
        540521: '扎囊县',
        540522: '贡嘎县',
        540523: '桑日县',
        540524: '琼结县',
        540525: '曲松县',
        540526: '措美县',
        540527: '洛扎县',
        540528: '加查县',
        540529: '隆子县',
        540530: '错那县',
        540531: '浪卡子县',
        540602: '色尼区',
        540621: '嘉黎县',
        540622: '比如县',
        540623: '聂荣县',
        540624: '安多县',
        540625: '申扎县',
        540626: '索县',
        540627: '班戈县',
        540628: '巴青县',
        540629: '尼玛县',
        540630: '双湖县',
        542521: '普兰县',
        542522: '札达县',
        542523: '噶尔县',
        542524: '日土县',
        542525: '革吉县',
        542526: '改则县',
        542527: '措勤县',
        610102: '新城区',
        610103: '碑林区',
        610104: '莲湖区',
        610111: '灞桥区',
        610112: '未央区',
        610113: '雁塔区',
        610114: '阎良区',
        610115: '临潼区',
        610116: '长安区',
        610117: '高陵区',
        610118: '鄠邑区',
        610122: '蓝田县',
        610124: '周至县',
        610202: '王益区',
        610203: '印台区',
        610204: '耀州区',
        610222: '宜君县',
        610302: '渭滨区',
        610303: '金台区',
        610304: '陈仓区',
        610322: '凤翔县',
        610323: '岐山县',
        610324: '扶风县',
        610326: '眉县',
        610327: '陇县',
        610328: '千阳县',
        610329: '麟游县',
        610330: '凤县',
        610331: '太白县',
        610402: '秦都区',
        610403: '杨陵区',
        610404: '渭城区',
        610422: '三原县',
        610423: '泾阳县',
        610424: '乾县',
        610425: '礼泉县',
        610426: '永寿县',
        610428: '长武县',
        610429: '旬邑县',
        610430: '淳化县',
        610431: '武功县',
        610481: '兴平市',
        610482: '彬州市',
        610502: '临渭区',
        610503: '华州区',
        610522: '潼关县',
        610523: '大荔县',
        610524: '合阳县',
        610525: '澄城县',
        610526: '蒲城县',
        610527: '白水县',
        610528: '富平县',
        610581: '韩城市',
        610582: '华阴市',
        610602: '宝塔区',
        610603: '安塞区',
        610621: '延长县',
        610622: '延川县',
        610623: '子长县',
        610625: '志丹县',
        610626: '吴起县',
        610627: '甘泉县',
        610628: '富县',
        610629: '洛川县',
        610630: '宜川县',
        610631: '黄龙县',
        610632: '黄陵县',
        610702: '汉台区',
        610703: '南郑区',
        610722: '城固县',
        610723: '洋县',
        610724: '西乡县',
        610725: '勉县',
        610726: '宁强县',
        610727: '略阳县',
        610728: '镇巴县',
        610729: '留坝县',
        610730: '佛坪县',
        610802: '榆阳区',
        610803: '横山区',
        610822: '府谷县',
        610824: '靖边县',
        610825: '定边县',
        610826: '绥德县',
        610827: '米脂县',
        610828: '佳县',
        610829: '吴堡县',
        610830: '清涧县',
        610831: '子洲县',
        610881: '神木市',
        610902: '汉滨区',
        610921: '汉阴县',
        610922: '石泉县',
        610923: '宁陕县',
        610924: '紫阳县',
        610925: '岚皋县',
        610926: '平利县',
        610927: '镇坪县',
        610928: '旬阳县',
        610929: '白河县',
        611002: '商州区',
        611021: '洛南县',
        611022: '丹凤县',
        611023: '商南县',
        611024: '山阳县',
        611025: '镇安县',
        611026: '柞水县',
        620102: '城关区',
        620103: '七里河区',
        620104: '西固区',
        620105: '安宁区',
        620111: '红古区',
        620121: '永登县',
        620122: '皋兰县',
        620123: '榆中县',
        620201: '市辖区',
        620290: '雄关区',
        620291: '长城区',
        620292: '镜铁区',
        620293: '新城镇',
        620294: '峪泉镇',
        620295: '文殊镇',
        620302: '金川区',
        620321: '永昌县',
        620402: '白银区',
        620403: '平川区',
        620421: '靖远县',
        620422: '会宁县',
        620423: '景泰县',
        620502: '秦州区',
        620503: '麦积区',
        620521: '清水县',
        620522: '秦安县',
        620523: '甘谷县',
        620524: '武山县',
        620525: '张家川回族自治县',
        620602: '凉州区',
        620621: '民勤县',
        620622: '古浪县',
        620623: '天祝藏族自治县',
        620702: '甘州区',
        620721: '肃南裕固族自治县',
        620722: '民乐县',
        620723: '临泽县',
        620724: '高台县',
        620725: '山丹县',
        620802: '崆峒区',
        620821: '泾川县',
        620822: '灵台县',
        620823: '崇信县',
        620825: '庄浪县',
        620826: '静宁县',
        620881: '华亭市',
        620902: '肃州区',
        620921: '金塔县',
        620922: '瓜州县',
        620923: '肃北蒙古族自治县',
        620924: '阿克塞哈萨克族自治县',
        620981: '玉门市',
        620982: '敦煌市',
        621002: '西峰区',
        621021: '庆城县',
        621022: '环县',
        621023: '华池县',
        621024: '合水县',
        621025: '正宁县',
        621026: '宁县',
        621027: '镇原县',
        621102: '安定区',
        621121: '通渭县',
        621122: '陇西县',
        621123: '渭源县',
        621124: '临洮县',
        621125: '漳县',
        621126: '岷县',
        621202: '武都区',
        621221: '成县',
        621222: '文县',
        621223: '宕昌县',
        621224: '康县',
        621225: '西和县',
        621226: '礼县',
        621227: '徽县',
        621228: '两当县',
        622901: '临夏市',
        622921: '临夏县',
        622922: '康乐县',
        622923: '永靖县',
        622924: '广河县',
        622925: '和政县',
        622926: '东乡族自治县',
        622927: '积石山保安族东乡族撒拉族自治县',
        623001: '合作市',
        623021: '临潭县',
        623022: '卓尼县',
        623023: '舟曲县',
        623024: '迭部县',
        623025: '玛曲县',
        623026: '碌曲县',
        623027: '夏河县',
        630102: '城东区',
        630103: '城中区',
        630104: '城西区',
        630105: '城北区',
        630121: '大通回族土族自治县',
        630122: '湟中县',
        630123: '湟源县',
        630202: '乐都区',
        630203: '平安区',
        630222: '民和回族土族自治县',
        630223: '互助土族自治县',
        630224: '化隆回族自治县',
        630225: '循化撒拉族自治县',
        632221: '门源回族自治县',
        632222: '祁连县',
        632223: '海晏县',
        632224: '刚察县',
        632321: '同仁县',
        632322: '尖扎县',
        632323: '泽库县',
        632324: '河南蒙古族自治县',
        632521: '共和县',
        632522: '同德县',
        632523: '贵德县',
        632524: '兴海县',
        632525: '贵南县',
        632621: '玛沁县',
        632622: '班玛县',
        632623: '甘德县',
        632624: '达日县',
        632625: '久治县',
        632626: '玛多县',
        632701: '玉树市',
        632722: '杂多县',
        632723: '称多县',
        632724: '治多县',
        632725: '囊谦县',
        632726: '曲麻莱县',
        632801: '格尔木市',
        632802: '德令哈市',
        632803: '茫崖市',
        632821: '乌兰县',
        632822: '都兰县',
        632823: '天峻县',
        640104: '兴庆区',
        640105: '西夏区',
        640106: '金凤区',
        640121: '永宁县',
        640122: '贺兰县',
        640181: '灵武市',
        640202: '大武口区',
        640205: '惠农区',
        640221: '平罗县',
        640302: '利通区',
        640303: '红寺堡区',
        640323: '盐池县',
        640324: '同心县',
        640381: '青铜峡市',
        640402: '原州区',
        640422: '西吉县',
        640423: '隆德县',
        640424: '泾源县',
        640425: '彭阳县',
        640502: '沙坡头区',
        640521: '中宁县',
        640522: '海原县',
        650102: '天山区',
        650103: '沙依巴克区',
        650104: '新市区',
        650105: '水磨沟区',
        650106: '头屯河区',
        650107: '达坂城区',
        650109: '米东区',
        650121: '乌鲁木齐县',
        650202: '独山子区',
        650203: '克拉玛依区',
        650204: '白碱滩区',
        650205: '乌尔禾区',
        650402: '高昌区',
        650421: '鄯善县',
        650422: '托克逊县',
        650502: '伊州区',
        650521: '巴里坤哈萨克自治县',
        650522: '伊吾县',
        652301: '昌吉市',
        652302: '阜康市',
        652323: '呼图壁县',
        652324: '玛纳斯县',
        652325: '奇台县',
        652327: '吉木萨尔县',
        652328: '木垒哈萨克自治县',
        652701: '博乐市',
        652702: '阿拉山口市',
        652722: '精河县',
        652723: '温泉县',
        652801: '库尔勒市',
        652822: '轮台县',
        652823: '尉犁县',
        652824: '若羌县',
        652825: '且末县',
        652826: '焉耆回族自治县',
        652827: '和静县',
        652828: '和硕县',
        652829: '博湖县',
        652901: '阿克苏市',
        652922: '温宿县',
        652923: '库车县',
        652924: '沙雅县',
        652925: '新和县',
        652926: '拜城县',
        652927: '乌什县',
        652928: '阿瓦提县',
        652929: '柯坪县',
        653001: '阿图什市',
        653022: '阿克陶县',
        653023: '阿合奇县',
        653024: '乌恰县',
        653101: '喀什市',
        653121: '疏附县',
        653122: '疏勒县',
        653123: '英吉沙县',
        653124: '泽普县',
        653125: '莎车县',
        653126: '叶城县',
        653127: '麦盖提县',
        653128: '岳普湖县',
        653129: '伽师县',
        653130: '巴楚县',
        653131: '塔什库尔干塔吉克自治县',
        653201: '和田市',
        653221: '和田县',
        653222: '墨玉县',
        653223: '皮山县',
        653224: '洛浦县',
        653225: '策勒县',
        653226: '于田县',
        653227: '民丰县',
        654002: '伊宁市',
        654003: '奎屯市',
        654004: '霍尔果斯市',
        654021: '伊宁县',
        654022: '察布查尔锡伯自治县',
        654023: '霍城县',
        654024: '巩留县',
        654025: '新源县',
        654026: '昭苏县',
        654027: '特克斯县',
        654028: '尼勒克县',
        654201: '塔城市',
        654202: '乌苏市',
        654221: '额敏县',
        654223: '沙湾县',
        654224: '托里县',
        654225: '裕民县',
        654226: '和布克赛尔蒙古自治县',
        654301: '阿勒泰市',
        654321: '布尔津县',
        654322: '富蕴县',
        654323: '福海县',
        654324: '哈巴河县',
        654325: '青河县',
        654326: '吉木乃县',
        659001: '石河子市',
        659002: '阿拉尔市',
        659003: '图木舒克市',
        659004: '五家渠市',
        659005: '北屯市',
        659006: '铁门关市',
        659007: '双河市',
        659008: '可克达拉市',
        659009: '昆玉市',
        710101: '中正区',
        710102: '大同区',
        710103: '中山区',
        710104: '松山区',
        710105: '大安区',
        710106: '万华区',
        710107: '信义区',
        710108: '士林区',
        710109: '北投区',
        710110: '内湖区',
        710111: '南港区',
        710112: '文山区',
        710199: '其它区',
        710201: '新兴区',
        710202: '前金区',
        710203: '芩雅区',
        710204: '盐埕区',
        710205: '鼓山区',
        710206: '旗津区',
        710207: '前镇区',
        710208: '三民区',
        710209: '左营区',
        710210: '楠梓区',
        710211: '小港区',
        710241: '苓雅区',
        710242: '仁武区',
        710243: '大社区',
        710244: '冈山区',
        710245: '路竹区',
        710246: '阿莲区',
        710247: '田寮区',
        710248: '燕巢区',
        710249: '桥头区',
        710250: '梓官区',
        710251: '弥陀区',
        710252: '永安区',
        710253: '湖内区',
        710254: '凤山区',
        710255: '大寮区',
        710256: '林园区',
        710257: '鸟松区',
        710258: '大树区',
        710259: '旗山区',
        710260: '美浓区',
        710261: '六龟区',
        710262: '内门区',
        710263: '杉林区',
        710264: '甲仙区',
        710265: '桃源区',
        710266: '那玛夏区',
        710267: '茂林区',
        710268: '茄萣区',
        710299: '其它区',
        710301: '中西区',
        710302: '东区',
        710303: '南区',
        710304: '北区',
        710305: '安平区',
        710306: '安南区',
        710339: '永康区',
        710340: '归仁区',
        710341: '新化区',
        710342: '左镇区',
        710343: '玉井区',
        710344: '楠西区',
        710345: '南化区',
        710346: '仁德区',
        710347: '关庙区',
        710348: '龙崎区',
        710349: '官田区',
        710350: '麻豆区',
        710351: '佳里区',
        710352: '西港区',
        710353: '七股区',
        710354: '将军区',
        710355: '学甲区',
        710356: '北门区',
        710357: '新营区',
        710358: '后壁区',
        710359: '白河区',
        710360: '东山区',
        710361: '六甲区',
        710362: '下营区',
        710363: '柳营区',
        710364: '盐水区',
        710365: '善化区',
        710366: '大内区',
        710367: '山上区',
        710368: '新市区',
        710369: '安定区',
        710399: '其它区',
        710401: '中区',
        710402: '东区',
        710403: '南区',
        710404: '西区',
        710405: '北区',
        710406: '北屯区',
        710407: '西屯区',
        710408: '南屯区',
        710431: '太平区',
        710432: '大里区',
        710433: '雾峰区',
        710434: '乌日区',
        710435: '丰原区',
        710436: '后里区',
        710437: '石冈区',
        710438: '东势区',
        710439: '和平区',
        710440: '新社区',
        710441: '潭子区',
        710442: '大雅区',
        710443: '神冈区',
        710444: '大肚区',
        710445: '沙鹿区',
        710446: '龙井区',
        710447: '梧栖区',
        710448: '清水区',
        710449: '大甲区',
        710450: '外埔区',
        710451: '大安区',
        710499: '其它区',
        710507: '金沙镇',
        710508: '金湖镇',
        710509: '金宁乡',
        710510: '金城镇',
        710511: '烈屿乡',
        710512: '乌坵乡',
        710614: '南投市',
        710615: '中寮乡',
        710616: '草屯镇',
        710617: '国姓乡',
        710618: '埔里镇',
        710619: '仁爱乡',
        710620: '名间乡',
        710621: '集集镇',
        710622: '水里乡',
        710623: '鱼池乡',
        710624: '信义乡',
        710625: '竹山镇',
        710626: '鹿谷乡',
        710701: '仁爱区',
        710702: '信义区',
        710703: '中正区',
        710704: '中山区',
        710705: '安乐区',
        710706: '暖暖区',
        710707: '七堵区',
        710799: '其它区',
        710801: '东区',
        710802: '北区',
        710803: '香山区',
        710899: '其它区',
        710901: '东区',
        710902: '西区',
        710999: '其它区',
        711130: '万里区',
        711132: '板桥区',
        711133: '汐止区',
        711134: '深坑区',
        711135: '石碇区',
        711136: '瑞芳区',
        711137: '平溪区',
        711138: '双溪区',
        711139: '贡寮区',
        711140: '新店区',
        711141: '坪林区',
        711142: '乌来区',
        711143: '永和区',
        711144: '中和区',
        711145: '土城区',
        711146: '三峡区',
        711147: '树林区',
        711148: '莺歌区',
        711149: '三重区',
        711150: '新庄区',
        711151: '泰山区',
        711152: '林口区',
        711153: '芦洲区',
        711154: '五股区',
        711155: '八里区',
        711156: '淡水区',
        711157: '三芝区',
        711158: '石门区',
        711287: '宜兰市',
        711288: '头城镇',
        711289: '礁溪乡',
        711290: '壮围乡',
        711291: '员山乡',
        711292: '罗东镇',
        711293: '三星乡',
        711294: '大同乡',
        711295: '五结乡',
        711296: '冬山乡',
        711297: '苏澳镇',
        711298: '南澳乡',
        711299: '钓鱼台',
        711387: '竹北市',
        711388: '湖口乡',
        711389: '新丰乡',
        711390: '新埔镇',
        711391: '关西镇',
        711392: '芎林乡',
        711393: '宝山乡',
        711394: '竹东镇',
        711395: '五峰乡',
        711396: '横山乡',
        711397: '尖石乡',
        711398: '北埔乡',
        711399: '峨眉乡',
        711414: '中坜区',
        711415: '平镇区',
        711417: '杨梅区',
        711418: '新屋区',
        711419: '观音区',
        711420: '桃园区',
        711421: '龟山区',
        711422: '八德区',
        711423: '大溪区',
        711425: '大园区',
        711426: '芦竹区',
        711487: '中坜市',
        711488: '平镇市',
        711489: '龙潭乡',
        711490: '杨梅市',
        711491: '新屋乡',
        711492: '观音乡',
        711493: '桃园市',
        711494: '龟山乡',
        711495: '八德市',
        711496: '大溪镇',
        711497: '复兴乡',
        711498: '大园乡',
        711499: '芦竹乡',
        711520: '头份市',
        711582: '竹南镇',
        711583: '头份镇',
        711584: '三湾乡',
        711585: '南庄乡',
        711586: '狮潭乡',
        711587: '后龙镇',
        711588: '通霄镇',
        711589: '苑里镇',
        711590: '苗栗市',
        711591: '造桥乡',
        711592: '头屋乡',
        711593: '公馆乡',
        711594: '大湖乡',
        711595: '泰安乡',
        711596: '铜锣乡',
        711597: '三义乡',
        711598: '西湖乡',
        711599: '卓兰镇',
        711736: '员林市',
        711774: '彰化市',
        711775: '芬园乡',
        711776: '花坛乡',
        711777: '秀水乡',
        711778: '鹿港镇',
        711779: '福兴乡',
        711780: '线西乡',
        711781: '和美镇',
        711782: '伸港乡',
        711783: '员林镇',
        711784: '社头乡',
        711785: '永靖乡',
        711786: '埔心乡',
        711787: '溪湖镇',
        711788: '大村乡',
        711789: '埔盐乡',
        711790: '田中镇',
        711791: '北斗镇',
        711792: '田尾乡',
        711793: '埤头乡',
        711794: '溪州乡',
        711795: '竹塘乡',
        711796: '二林镇',
        711797: '大城乡',
        711798: '芳苑乡',
        711799: '二水乡',
        711982: '番路乡',
        711983: '梅山乡',
        711984: '竹崎乡',
        711985: '阿里山乡',
        711986: '中埔乡',
        711987: '大埔乡',
        711988: '水上乡',
        711989: '鹿草乡',
        711990: '太保市',
        711991: '朴子市',
        711992: '东石乡',
        711993: '六脚乡',
        711994: '新港乡',
        711995: '民雄乡',
        711996: '大林镇',
        711997: '溪口乡',
        711998: '义竹乡',
        711999: '布袋镇',
        712180: '斗南镇',
        712181: '大埤乡',
        712182: '虎尾镇',
        712183: '土库镇',
        712184: '褒忠乡',
        712185: '东势乡',
        712186: '台西乡',
        712187: '仑背乡',
        712188: '麦寮乡',
        712189: '斗六市',
        712190: '林内乡',
        712191: '古坑乡',
        712192: '莿桐乡',
        712193: '西螺镇',
        712194: '二仑乡',
        712195: '北港镇',
        712196: '水林乡',
        712197: '口湖乡',
        712198: '四湖乡',
        712199: '元长乡',
        712451: '崁顶乡',
        712467: '屏东市',
        712468: '三地门乡',
        712469: '雾台乡',
        712470: '玛家乡',
        712471: '九如乡',
        712472: '里港乡',
        712473: '高树乡',
        712474: '盐埔乡',
        712475: '长治乡',
        712476: '麟洛乡',
        712477: '竹田乡',
        712478: '内埔乡',
        712479: '万丹乡',
        712480: '潮州镇',
        712481: '泰武乡',
        712482: '来义乡',
        712483: '万峦乡',
        712484: '莰顶乡',
        712485: '新埤乡',
        712486: '南州乡',
        712487: '林边乡',
        712488: '东港镇',
        712489: '琉球乡',
        712490: '佳冬乡',
        712491: '新园乡',
        712492: '枋寮乡',
        712493: '枋山乡',
        712494: '春日乡',
        712495: '狮子乡',
        712496: '车城乡',
        712497: '牡丹乡',
        712498: '恒春镇',
        712499: '满州乡',
        712584: '台东市',
        712585: '绿岛乡',
        712586: '兰屿乡',
        712587: '延平乡',
        712588: '卑南乡',
        712589: '鹿野乡',
        712590: '关山镇',
        712591: '海端乡',
        712592: '池上乡',
        712593: '东河乡',
        712594: '成功镇',
        712595: '长滨乡',
        712596: '金峰乡',
        712597: '大武乡',
        712598: '达仁乡',
        712599: '太麻里乡',
        712686: '花莲市',
        712687: '新城乡',
        712688: '太鲁阁',
        712689: '秀林乡',
        712690: '吉安乡',
        712691: '寿丰乡',
        712692: '凤林镇',
        712693: '光复乡',
        712694: '丰滨乡',
        712695: '瑞穗乡',
        712696: '万荣乡',
        712697: '玉里镇',
        712698: '卓溪乡',
        712699: '富里乡',
        712794: '马公市',
        712795: '西屿乡',
        712796: '望安乡',
        712797: '七美乡',
        712798: '白沙乡',
        712799: '湖西乡',
        712896: '南竿乡',
        712897: '北竿乡',
        712898: '东引乡',
        712899: '莒光乡',
        810101: '中西区',
        810102: '湾仔区',
        810103: '东区',
        810104: '南区',
        810201: '九龙城区',
        810202: '油尖旺区',
        810203: '深水埗区',
        810204: '黄大仙区',
        810205: '观塘区',
        810301: '北区',
        810302: '大埔区',
        810303: '沙田区',
        810304: '西贡区',
        810305: '元朗区',
        810306: '屯门区',
        810307: '荃湾区',
        810308: '葵青区',
        810309: '离岛区',
        820101: '澳门半岛',
        820201: '离岛'
    }
};
media_750.js

(function flexible(window, document) {
  var docEl = document.documentElement;
  var dpr = window.devicePixelRatio || 1;

  // adjust body font size
  function setBodyFontSize() {
    if (document.body) {
    } else {
      document.addEventListener("DOMContentLoaded", setBodyFontSize);
    }
  }
  setBodyFontSize();

  // set 1rem = viewWidth / 10
  function setRemUnit() {
    var rem = docEl.clientWidth / 7.5;
    docEl.style.fontSize = rem + "px";
  }

  setRemUnit();

  // reset rem unit on page resize
  window.addEventListener("resize", setRemUnit);
  window.addEventListener("pageshow", function(e) {
    if (e.persisted) {
      setRemUnit();
    }
  });

  // detect 0.5px supports
  if (dpr >= 2) {
    var fakeBody = document.createElement("body");
    var testElement = document.createElement("div");
    testElement.style.border = ".5px solid transparent";
    fakeBody.appendChild(testElement);
    docEl.appendChild(fakeBody);
    if (testElement.offsetHeight === 1) {
      docEl.classList.add("hairlines");
    }
    docEl.removeChild(fakeBody);
  }
})(window, document);

components

AddressWindow.vue


<template>
  <div>
    <div class="address-window" :class="value === true ? 'on' : ''">
      <div class="title">
        选择地址<span class="iconfont icon-guanbi" @click="closeAddress"></span>
      </div>
      <div class="list" v-if="addressList.length">
        <div
          class="item acea-row row-between-wrapper"
          :class="item.id === checked ? 'font-color-red' : ''"
          v-for="(item, index) in addressList"
          @click="tapAddress(index)"
          :key="index"
        >
          <span
            class="iconfont icon-ditu"
            :class="item.id === checked ? 'font-color-red' : ''"
          ></span>
          <div class="addressTxt">
            <div
              class="name"
              :class="item.id === checked ? 'font-color-red' : ''"
            >
              {{ item.real_name }}<span class="phone">{{ item.phone }}</span>
            </div>
            <div class="line1">
              {{ item.province }}{{ item.city }}{{ item.district
              }}{{ item.detail }}
            </div>
          </div>
          <span
            class="iconfont icon-complete"
            :class="item.id === checked ? 'font-color-red' : ''"
          ></span>
        </div>
      </div>
      <div class="pictrue" v-if="addressList.length < 1">
        <img src="@assets/images/noAddress.png" class="image" />
      </div>
      <div class="addressBnt bg-color-red" @click="goAddressPages">
        新加地址
      </div>
    </div>
    <div
      class="mask"
      @touchmove.prevent
      :hidden="value === false"
      @click="closeAddress"
    ></div>
  </div>
</template>
<script>
import { getAddressList } from "../api/user";
export default {
  name: "AddressWindow",
  props: {
    value: Boolean,
    checked: Number
  },
  data: function() {
    return {
      addressList: [],
      current: 0,
      cartId: 0,
      pinkId: 0,
      couponId: 0
    };
  },
  mounted: function() {},
  methods: {
    getAddressList: function() {
      let that = this;
      getAddressList().then(res => {
        that.addressList = res.data;
      });
    },
    closeAddress() {
      this.$emit("input", false);
    },
    goAddressPages: function() {
      this.$router.push({ path: "/user/add_address" });
      this.$emit("redirect");
    },
    tapAddress: function(index) {
      this.$emit("checked", this.addressList[index]);
      this.$emit("input", false);
    }
  }
};
</script>

CountDown.vue


<template>
  <div class="time">
    {{ tipText }}<span class="styleAll" v-if="isDay === true">{{ day }}</span
    ><span class="timeTxt">{{ dayText }}</span
    ><span class="styleAll">{{ hour }}</span
    ><span class="timeTxt">{{ hourText }}</span
    ><span class="styleAll">{{ minute }}</span
    ><span class="timeTxt">{{ minuteText }}</span
    ><span class="styleAll">{{ second }}</span
    ><span class="timeTxt">{{ secondText }}</span>
  </div>
</template>
<script>
export default {
  name: "CountDown",
  props: {
    //距离开始提示文字
    tipText: {
      type: String,
      default: "倒计时"
    },
    dayText: {
      type: String,
      default: "天"
    },
    hourText: {
      type: String,
      default: "时"
    },
    minuteText: {
      type: String,
      default: "分"
    },
    secondText: {
      type: String,
      default: "秒"
    },
    datatime: {
      type: Number,
      default: 0
    },
    isDay: {
      type: Boolean,
      default: true
    }
  },
  data: function() {
    return {
      day: "00",
      hour: "00",
      minute: "00",
      second: "00"
    };
  },
  created: function() {
    this.show_time();
  },
  mounted: function() {},
  methods: {
    show_time: function() {
      let that = this;
      function runTime() {
        //时间函数
        let intDiff = that.datatime - Date.parse(new Date()) / 1000; //获取数据中的时间戳的时间差;
        let day = 0,
          hour = 0,
          minute = 0,
          second = 0;
        if (intDiff > 0) {
          //转换时间
          if (that.isDay === true) {
            day = Math.floor(intDiff / (60 * 60 * 24));
          } else {
            day = 0;
          }
          hour = Math.floor(intDiff / (60 * 60)) - day * 24;
          minute = Math.floor(intDiff / 60) - day * 24 * 60 - hour * 60;
          second =
            Math.floor(intDiff) -
            day * 24 * 60 * 60 -
            hour * 60 * 60 -
            minute * 60;
          if (hour <= 9) hour = "0" + hour;
          if (minute <= 9) minute = "0" + minute;
          if (second <= 9) second = "0" + second;
          that.day = day;
          that.hour = hour;
          that.minute = minute;
          that.second = second;
        } else {
          that.day = "00";
          that.hour = "00";
          that.minute = "00";
          that.second = "00";
        }
      }
      runTime();
      setInterval(runTime, 1000);
    }
  }
};
</script>

CouponListWindow.vue


<template>
  <div>
    <div class="coupon-list-window" :class="value === true ? 'on' : ''">
      <div class="title">
        优惠券
        <span class="iconfont icon-guanbi" @click="close"></span>
      </div>
      <div v-if="couponList.length > 0">
        <div class="coupon-list">
          <div
            class="item acea-row row-center-wrapper"
            v-for="coupon in couponList"
            :key="coupon.id"
            @click="click(coupon)"
          >
            <div class="money">
              ¥
              <span class="num">{{ coupon.coupon_price }}</span>
            </div>
            <div class="text">
              <div class="condition line1">{{ coupon.coupon_title }}</div>
              <div class="data acea-row row-between-wrapper">
                <div>
                  {{ coupon.start_time ? coupon.start_time + "-" : ""
                  }}{{ coupon.end_time }}
                </div>
                <div
                  class="iconfont icon-xuanzhong1 font-color-red"
                  v-if="checked === coupon.id"
                ></div>
                <div class="iconfont icon-weixuanzhong" v-else></div>
              </div>
            </div>
          </div>
        </div>
        <div class="couponNo bg-color-red" @click="couponNo">不使用优惠券</div>
      </div>
      <div v-if="!couponList.length && loaded">
        <div class="pictrue">
          <img src="@assets/images/noCoupon.png" class="image" />
        </div>
      </div>
    </div>
    <div
      class="mask"
      @touchmove.prevent
      :hidden="value === false"
      @click="close"
    ></div>
  </div>
</template>
<style scoped>
.coupon-list-window .iconfont {
  font-size: 0.4rem;
}
.couponNo {
  font-size: 0.3rem;
  font-weight: bold;
  color: #fff;
  width: 6.9rem;
  height: 0.86rem;
  border-radius: 0.43rem;
  text-align: center;
  line-height: 0.86rem;
  margin: 0.6rem auto;
}
</style>
<script>
import { getOrderCoupon } from "@api/order";

export default {
  name: "CouponListWindow",
  props: {
    value: Boolean,
    checked: Number,
    price: {
      type: [Number, String],
      default: undefined
    }
  },
  data: function() {
    return {
      couponList: [],
      loaded: false
    };
  },
  watch: {
    price(n) {
      if (n === undefined || n == null) return;
      this.getCoupon();
    }
  },
  mounted: function() {},
  methods: {
    close: function() {
      this.$emit("input", false);
      this.$emit("close");
    },
    getCoupon() {
      getOrderCoupon(this.price).then(res => {
        this.couponList = res.data;
        this.loaded = true;
      });
    },
    click(coupon) {
      this.$emit("checked", coupon);
      this.$emit("input", false);
    },
    couponNo: function() {
      this.$emit("checked", null);
      this.$emit("input", false);
    }
  }
};
</script>

CouponPop.vue


<template>
  <div>
    <div class="coupon-list-window" :class="coupon.coupon === true ? 'on' : ''">
      <div class="title">
        优惠券<span class="iconfont icon-guanbi" @click="close"></span>
      </div>
      <div class="coupon-list" v-if="coupon.list.length > 0">
        <div
          class="item acea-row row-center-wrapper"
          v-for="(item, index) in coupon.list"
          :key="index"
          @click="getCouponUser(index, item.id)"
        >
          <div class="money">
            ¥<span class="num">{{ item.coupon_price }}</span>
          </div>
          <div class="text">
            <div class="condition line1">
              购物满{{ item.use_min_price }}元可用
            </div>
            <div class="data acea-row row-between-wrapper">
              <div>
                {{ item.start_time ? item.start_time + "-" : ""
                }}{{ item.end_time }}
              </div>
              <div
                class="bnt acea-row row-center-wrapper"
                :class="!item.is_use ? 'bg-color-red' : 'gray'"
              >
                {{ !item.is_use ? "立即领取" : "已领取" }}
              </div>
            </div>
          </div>
        </div>
      </div>
      <!--无优惠券-->
      <div class="pictrue" v-else>
        <img src="@assets/images/noCoupon.png" class="image" />
      </div>
    </div>
    <div
      class="mask"
      @touchmove.prevent
      :hidden="coupon.coupon === false"
      @click="close"
    ></div>
  </div>
</template>
<script>
import { getCouponReceive } from "@api/user";
export default {
  name: "CouponPop",
  props: {
    coupon: {
      type: Object,
      default: () => {}
    }
  },
  data: function() {
    return {};
  },
  mounted: function() {},
  methods: {
    close: function() {
      this.$emit("changeFun", { action: "changecoupon", value: false }); //$emit():注册事件;
    },
    getCouponUser: function(index, id) {
      let that = this,
        list = that.coupon.list;
      if (list[index].is_use === true) return;
      getCouponReceive(id).then(function() {
        that.$dialog.toast({ mes: "已领取" });
        that.$set(list[index], "is_use", true);
        that.$emit("changefun", { action: "currentcoupon", value: index });
        that.$emit("changeFun", { action: "changecoupon", value: false });
      });
    }
  }
};
</script>

CouponWindow.vue


<template>
  <div v-if="couponList.length > 0">
    <div class="coupon-window" :class="value ? 'on' : ''">
      <div class="couponWinList">
        <div
          class="item acea-row row-between-wrapper"
          v-for="(item, index) in couponList"
          :key="index"
        >
          <div class="money font-color-red">
            ¥<span class="num">{{ item.coupon_price }}</span>
          </div>
          <div class="text">
            <div class="name">
              购物买{{ item.use_min_price }}减{{ item.coupon_price }}
            </div>
            <div v-if="item.end_time">
              {{ item.start_time ? item.start_time + "-" : ""
              }}{{ item.end_time }}
            </div>
          </div>
        </div>
        <div style="height:1.2rem"></div>
      </div>
      <div class="lid">
        <div class="bnt font-color-red" @click="checked">立即领取</div>
        <div class="iconfont icon-guanbi3" @click="close"></div>
      </div>
    </div>
    <div class="mask" @touchmove.prevent :hidden="!value"></div>
  </div>
</template>
<script>
import { mapGetters } from "vuex";
import toLogin from "@libs/login";
import { couponReceiveBatch } from "@api/user";

export default {
  name: "CouponWindow",
  props: {
    couponList: {
      type: Array,
      default: () => []
    }
  },
  computed: mapGetters(["isLogin"]),
  data: function() {
    return {
      value: true
    };
  },
  mounted: function() {},
  methods: {
    checked() {
      const isLogin = this.isLogin;
      if (!isLogin) return toLogin();

      const ids = this.couponList.reduce((initial, coupon) => {
        initial.push(coupon.id);
        return initial;
      }, []);
      couponReceiveBatch(ids)
        .then(() => {
          this.$emit("success");
          this.$dialog.toast({ mes: "领取成功" });
        })
        .catch(() => {
          this.$dialog.toast({ mes: "已领取" });
        });
      if (isLogin) {
        this.value = false;
        this.$emit("checked");
      }
    },
    close: function() {
      this.value = false;
      this.$emit("close");
    }
  }
};
</script>

Footer.vue


<template>
  <div id="footer" class="acea-row row-middle">
    <router-link
      :to="item.url"
      class="item"
      :class="{ on: item.url === $route.path }"
      v-for="(item, index) in footerList"
      :key="index"
    >
      <div
        class="iconfont"
        :class="item.icon1 + ' ' + (item.url === $route.path ? item.icon2 : '')"
      ></div>
      <div>{{ item.name }}</div>
    </router-link>
  </div>
</template>
<script>
export default {
  name: "Footer",
  props: {},
  data: function() {
    return {
      footerList: [
        {
          name: "首页",
          icon1: "icon-shouye-xianxing",
          icon2: "icon-shouye",
          url: "/"
        },
        {
          name: "分类",
          icon1: "icon-yingyongchengxu-xianxing",
          icon2: "icon-yingyongchengxu",
          url: "/category"
        },
        {
          name: "购物车",
          icon1: "icon-caigou-xianxing",
          icon2: "icon-caigou",
          url: "/cart"
        },
        {
          name: "我的",
          icon1: "icon-yonghu-xianxing",
          icon2: "icon-yonghu",
          url: "/user"
        }
      ]
    };
  },
  methods: {}
};
</script>

GoodList.vue


<template>
  <div class="goodList">
    <router-link
      :to="{ path: '/detail/' + item.id }"
      class="item acea-row row-between-wrapper"
      v-for="(item, index) in goodList"
      :key="index"
    >
      <div class="pictrue">
        <img :src="item.image" class="image" />
        <img
          src="@assets/images/one.png"
          class="numPic"
          v-if="isSort === true && index === 0"
        />
        <img
          src="@assets/images/two.png"
          class="numPic"
          v-if="isSort === true && index === 1"
        />
        <img
          src="@assets/images/three.png"
          class="numPic"
          v-if="isSort === true && index === 2"
        />
      </div>
      <div class="underline">
        <div class="text">
          <div class="line1">{{ item.store_name }}</div>
          <div class="money font-color-red">
            ¥<span class="num">{{ item.price }}</span>
          </div>
          <div class="vip-money acea-row row-middle">
            <div class="vip" v-if="item.vip_price && item.vip_price > 0">
              ¥{{ item.vip_price || 0
              }}<img src="@assets/images/vip.png" class="image" />
            </div>
            <span class="num">已售{{ item.sales }}{{ item.unit_name }}</span>
          </div>
        </div>
      </div>
      <div
        class="iconfont icon-gouwuche cart-color acea-row row-center-wrapper"
      ></div>
    </router-link>
  </div>
</template>
<script>
export default {
  name: "GoodList",
  props: {
    goodList: {
      type: Array,
      default: () => []
    },
    isSort: {
      type: Boolean,
      default: true
    }
  },
  data: function() {
    return {};
  }
};
</script>

HelloWorld.vue


<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <p>
      For a guide and recipes on how to configure / customize this project,<br />
      check out the
      <a href="https://cli.vuejs.org" target="_blank" rel="noopener"
        >vue-cli documentation</a
      >.
    </p>
    <h3>Installed CLI Plugins</h3>
    <ul>
      <li>
        <a
          href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel"
          target="_blank"
          rel="noopener"
          >babel</a
        >
      </li>
      <li>
        <a
          href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint"
          target="_blank"
          rel="noopener"
          >eslint</a
        >
      </li>
    </ul>
    <h3>Essential Links</h3>
    <ul>
      <li>
        <a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a>
      </li>
      <li>
        <a href="https://forum.vuejs.org" target="_blank" rel="noopener"
          >Forum</a
        >
      </li>
      <li>
        <a href="https://chat.vuejs.org" target="_blank" rel="noopener"
          >Community Chat</a
        >
      </li>
      <li>
        <a href="https://twitter.com/vuejs" target="_blank" rel="noopener"
          >Twitter</a
        >
      </li>
      <li>
        <a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a>
      </li>
    </ul>
    <h3>Ecosystem</h3>
    <ul>
      <li>
        <a href="https://router.vuejs.org" target="_blank" rel="noopener"
          >vue-router</a
        >
      </li>
      <li>
        <a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a>
      </li>
      <li>
        <a
          href="https://github.com/vuejs/vue-devtools#vue-devtools"
          target="_blank"
          rel="noopener"
          >vue-devtools</a
        >
      </li>
      <li>
        <a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener"
          >vue-loader</a
        >
      </li>
      <li>
        <a
          href="https://github.com/vuejs/awesome-vue"
          target="_blank"
          rel="noopener"
          >awesome-vue</a
        >
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: {
    msg: String
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

Home.vue


<template>
  <div
    class="home"
    :style="{ top: top + 'px' }"
    style="position:fixed;"
    id="right-nav"
    @touchmove="touchmove($event)"
  >
    <div class="homeCon bg-color-red" :class="homeActive === true ? 'on' : ''">
      <router-link
        :to="'/'"
        class="iconfont icon-shouye-xianxing"
      ></router-link>
      <router-link
        :to="'/cart'"
        class="iconfont icon-caigou-xianxing"
      ></router-link>
      <router-link :to="'/user'" class="iconfont icon-yonghu1"></router-link>
    </div>
    <div class="pictrue" @click="open">
      <img
        :src="
          homeActive === true
            ? require('../assets/images/close.gif')
            : require('../assets/images/open.gif')
        "
        class="image"
      />
    </div>
  </div>
</template>
<script>
import { mapGetters } from "vuex";
export default {
  name: "Home",
  props: {},
  data: function() {
    return {
      top: ""
    };
  },
  computed: mapGetters(["homeActive"]),
  methods: {
    touchmove(event) {
      event.preventDefault();
      let top =
        event.touches[0].pageY -
        (document.documentElement.scrollTop || document.body.scrollTop) -
        this.$el.clientHeight;

      if (top > 390) top = 390;
      else if (top < 55) top = 55;
      this.top = top;
    },
    open: function() {
      this.homeActive
        ? this.$store.commit("CLOSE_HOME")
        : this.$store.commit("OPEN_HOME");
    }
  }
};
</script>
<style scoped></style>

Loading.vue


<template>
  <div
    class="Loads acea-row row-center-wrapper"
    v-if="loading || !loaded"
    style="margin-top: .2rem;"
  >
    <template v-if="loading">
      <div
        class="iconfont icon-jiazai loading acea-row row-center-wrapper"
      ></div>
      正在加载中
    </template>
    <template v-else>
      上拉加载更多
    </template>
  </div>
</template>

<script>
export default {
  name: "Loading",
  props: {
    loaded: Boolean,
    loading: Boolean
  }
};
</script>

OrderGoods.vue


<template>
  <div class="orderGoods">
    <div class="total">共{{ cartInfo.length }}件商品</div>
    <div class="goodWrapper">
      <div
        class="item acea-row row-between-wrapper"
        v-for="cart in cartInfo"
        :key="cart.id"
      >
        <div class="pictrue">
          <img :src="cart.productInfo.image" class="image" />
        </div>
        <div class="text">
          <div class="acea-row row-between-wrapper">
            <div class="name line1">{{ cart.productInfo.store_name }}</div>
            <div class="num">x {{ cart.cart_num }}</div>
          </div>
          <div class="attr line1" v-if="cart.productInfo.attrInfo">
            {{ cart.productInfo.attrInfo.suk }}
          </div>
          <div class="money font-color-red">¥{{ cart.truePrice }}</div>
          <div
            class="evaluate"
            v-if="evaluate === 3"
            @click="$router.push({ path: '/goods_evaluate/' + cart.unique })"
          >
            评价
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  name: "OrderGoods",
  props: {
    evaluate: Number,
    cartInfo: {
      type: Array,
      default: () => []
    }
  },
  data: function() {
    return {};
  },
  mounted: function() {},
  methods: {}
};
</script>

Payment.vue


<template>
  <div>
    <div class="payment" :class="value === true ? 'on' : ''">
      <div class="title acea-row row-center-wrapper">
        选择付款方式<span class="iconfont icon-guanbi" @click="close"></span>
      </div>
      <div
        class="item acea-row row-between-wrapper"
        v-if="types.indexOf('weixin') !== -1"
        @click="checked('weixin')"
      >
        <div class="left acea-row row-between-wrapper">
          <div class="iconfont icon-weixinzhifu"></div>
          <div class="text">
            <div class="name">微信支付</div>
            <div class="info">使用微信快捷支付</div>
          </div>
        </div>
        <div class="iconfont icon-xiangyou"></div>
      </div>
      <div
        class="item acea-row row-between-wrapper"
        v-if="types.indexOf('alipay') !== -1"
        @click="checked('alipay')"
      >
        <div class="left acea-row row-between-wrapper">
          <div class="iconfont icon-zhifubao"></div>
          <div class="text">
            <div class="name">支付宝支付</div>
            <div class="info">使用线上支付宝支付</div>
          </div>
        </div>
        <div class="iconfont icon-xiangyou"></div>
      </div>
      <div
        class="item acea-row row-between-wrapper"
        v-if="types.indexOf('yue') !== -1"
        @click="checked('yue')"
      >
        <div class="left acea-row row-between-wrapper">
          <div class="iconfont icon-yuezhifu"></div>
          <div class="text">
            <div class="name">余额支付</div>
            <div class="info">
              当前可用余额:<span class="money">{{ balance }}</span>
            </div>
          </div>
        </div>
        <div class="iconfont icon-xiangyou"></div>
      </div>
      <div
        class="item acea-row row-between-wrapper"
        v-if="types.indexOf('offline') !== -1"
        @click="checked('offline')"
      >
        <div class="left acea-row row-between-wrapper">
          <div class="iconfont icon-yuezhifu1"></div>
          <div class="text">
            <div class="name">线下支付</div>
            <div class="info">选择线下付款方式</div>
          </div>
        </div>
        <div class="iconfont icon-xiangyou"></div>
      </div>
    </div>
    <div class="mask" v-show="value" @click="close"></div>
  </div>
</template>
<script>
export default {
  name: "Payment",
  props: {
    value: {
      type: Boolean,
      default: false
    },
    balance: {
      type: [Number, String],
      default: 0
    },
    types: {
      type: Array,
      default: () => ["weixin", "alipay", "yue", "offline"]
    }
  },
  data: function() {
    return {};
  },
  mounted: function() {},
  methods: {
    checked: function(type) {
      this.$emit("checked", type);
      this.close();
    },
    close: function() {
      this.$emit("input", false);
    }
  }
};
</script>
<style scoped>
.payment {
  position: fixed;
  bottom: 0;
  left: 0;
  width: 100%;
  border-radius: 0.16rem 0.16rem 0 0;
  background-color: #fff;
  padding-bottom: 0.6rem;
  z-index: 99;
  transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9);
  -webkit-transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9);
  -moz-transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9);
  -o-transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9);
  transform: translate3d(0, 100%, 0);
  -webkit-transform: translate3d(0, 100%, 0);
  -ms-transform: translate3d(0, 100%, 0);
  -moz-transform: translate3d(0, 100%, 0);
  -o-transform: translate3d(0, 100%, 0);
}

.payment.on {
  transform: translate3d(0, 0, 0);
  -webkit-transform: translate3d(0, 0, 0);
  -ms-transform: translate3d(0, 0, 0);
  -moz-transform: translate3d(0, 0, 0);
  -o-transform: translate3d(0, 0, 0);
}

.payment .title {
  text-align: center;
  height: 1.23rem;
  font-size: 0.32rem;
  color: #282828;
  font-weight: bold;
  padding-right: 0.3rem;
  margin-left: 0.3rem;
  position: relative;
  border-bottom: 0.01rem solid #eee;
}

.payment .title .iconfont {
  position: absolute;
  right: 0.3rem;
  top: 50%;
  transform: translateY(-50%);
  font-size: 0.43rem;
  color: #8a8a8a;
  font-weight: normal;
}

.payment .item {
  border-bottom: 0.01rem solid #eee;
  height: 1.3rem;
  margin-left: 0.3rem;
  padding-right: 0.3rem;
}

.payment .item .left {
  width: 6.1rem;
}

.payment .item .left .text {
  width: 5.4rem;
}

.payment .item .left .text .name {
  font-size: 0.32rem;
  color: #282828;
}

.payment .item .left .text .info {
  font-size: 0.24rem;
  color: #999;
}

.payment .item .left .text .info .money {
  color: #ff9900;
}

.payment .item .left .iconfont {
  font-size: 0.45rem;
  color: #09bb07;
}

.payment .item .left .iconfont.icon-zhifubao {
  color: #00aaea;
}

.payment .item .left .iconfont.icon-yuezhifu {
  color: #ff9900;
}

.payment .item .left .iconfont.icon-yuezhifu1 {
  color: #eb6623;
}

.payment .item .iconfont {
  font-size: 0.3rem;
  color: #999;
}
</style>

PriceChange.vue


<template>
  <div>
    <div class="priceChange" :class="change === true ? 'on' : ''">
      <div class="priceTitle">
        {{
          status == 0
            ? orderInfo.refund_status === 1
              ? "立即退款"
              : "一键改价"
            : "订单备注"
        }}
        <span class="iconfont icon-guanbi" @click="close"></span>
      </div>
      <div class="listChange" v-if="status == 0">
        <div
          class="item acea-row row-between-wrapper"
          v-if="orderInfo.refund_status === 0"
        >
          <div>商品总价(¥)</div>
          <div class="money">
            {{ orderInfo.total_price }}<span class="iconfont icon-suozi"></span>
          </div>
        </div>
        <div
          class="item acea-row row-between-wrapper"
          v-if="orderInfo.refund_status === 0"
        >
          <div>原始邮费(¥)</div>
          <div class="money">
            {{ orderInfo.pay_postage }}<span class="iconfont icon-suozi"></span>
          </div>
        </div>
        <div
          class="item acea-row row-between-wrapper"
          v-if="orderInfo.refund_status === 0"
        >
          <div>实际支付(¥)</div>
          <div class="money">
            <input
              type="text"
              v-model="price"
              :class="focus === true ? 'on' : ''"
              @focus="priceChange"
            />
          </div>
        </div>
        <div
          class="item acea-row row-between-wrapper"
          v-if="orderInfo.refund_status === 1"
        >
          <div>实际支付(¥)</div>
          <div class="money">
            {{ orderInfo.pay_price }}<span class="iconfont icon-suozi"></span>
          </div>
        </div>
        <div
          class="item acea-row row-between-wrapper"
          v-if="orderInfo.refund_status === 1"
        >
          <div>退款金额(¥)</div>
          <div class="money">
            <input
              type="text"
              v-model="refund_price"
              :class="focus === true ? 'on' : ''"
              @focus="priceChange"
            />
          </div>
        </div>
      </div>
      <div class="listChange" v-else>
        <textarea
          :placeholder="
            orderInfo.remark ? orderInfo.remark : '请填写备注信息...'
          "
          v-model="remark"
        ></textarea>
      </div>
      <div class="modify" @click="save">
        {{ orderInfo.refund_status === 0 ? "立即修改" : "确认退款" }}
      </div>
      <div class="modify1" @click="refuse" v-if="orderInfo.refund_status === 1">
        拒绝退款
      </div>
    </div>
    <div class="mask" @touchmove.prevent v-show="change === true"></div>
  </div>
</template>
<style scoped>
.priceChange .listChange textarea {
  border: 1px solid #eee;
  width: 100%;
  height: 2rem;
  margin-top: 0.5rem;
  border-radius: 0.1rem;
  color: #333;
  padding: 0.2rem;
}
</style>
<script>
export default {
  name: "PriceChange",
  components: {},
  props: {
    change: Boolean,
    orderInfo: Object,
    status: String
  },
  data: function() {
    return {
      focus: false,
      price: 0,
      refund_price: 0,
      remark: ""
    };
  },
  watch: {
    orderInfo: function() {
      this.price = this.orderInfo.pay_price;
      this.refund_price = this.orderInfo.pay_price;
      this.remark = "";
    }
  },
  mounted: function() {},
  methods: {
    priceChange: function() {
      this.focus = true;
    },
    close: function() {
      this.price = this.orderInfo.pay_price;
      this.$emit("closechange", false);
    },
    save: function() {
      let that = this;
      that.$emit("savePrice", {
        price: that.price,
        refund_price: that.refund_price,
        type: 1,
        remark: that.remark
      });
    },
    refuse: function() {
      let that = this;
      that.$emit("savePrice", {
        price: that.price,
        refund_price: that.refund_price,
        type: 2,
        remark: that.remark
      });
    }
  }
};
</script>

ProductConSwiper.vue


<template>
  <div class="slider-banner product-bg">
    <swiper
      class="swiper-wrapper"
      :options="ProductConSwiper"
      v-if="imgUrls.length > 0"
    >
      <swiperSlide
        class="swiper-slide"
        v-for="item in imgUrls"
        :key="item"
        ref="goodSwiper"
      >
        <img :src="item" class="slide-image" />
      </swiperSlide>
    </swiper>
    <div class="pages">{{ currents || 1 }}/{{ imgUrls.length || 1 }}</div>
  </div>
</template>
<script>
import { swiper, swiperSlide } from "vue-awesome-swiper";
import "@assets/css/swiper.min.css";
export default {
  name: "ProductConSwiper",
  components: {
    swiper,
    swiperSlide
  },
  props: {
    imgUrls: {
      type: Array,
      default: () => []
    }
  },
  data: function() {
    let that = this;
    return {
      currents: 1,
      ProductConSwiper: {
        autoplay: {
          disableOnInteraction: false,
          delay: 2000
        },
        loop: true,
        speed: 1000,
        observer: true,
        observeParents: true,
        on: {
          slideChangeTransitionStart: function() {
            that.currents = this.realIndex + 1;
          }
        }
      }
    };
  },
  mounted: function() {},
  methods: {}
};
</script>

ProductWindow.vue


<template>
  <div>
    <div class="product-window" :class="attr.cartAttr === true ? 'on' : ''">
      <div class="textpic acea-row row-between-wrapper">
        <div class="pictrue">
          <img :src="attr.productSelect.image" class="image" />
        </div>
        <div class="text">
          <div class="line1">
            {{ attr.productSelect.store_name }}
          </div>
          <div class="money font-color-red">
            ¥<span class="num">{{ attr.productSelect.price }}</span
            ><span class="stock">库存: {{ attr.productSelect.stock }}</span>
          </div>
        </div>
        <div class="iconfont icon-guanbi" @click="closeAttr"></div>
      </div>
      <div class="productWinList">
        <div
          class="item"
          v-for="(item, indexw) in attr.productAttr"
          :key="indexw"
        >
          <div class="title">{{ item.attr_name }}</div>
          <div class="listn acea-row row-middle">
            <div
              class="itemn"
              :class="item.index === indexn ? 'on' : ''"
              v-for="(itemn, indexn) in item.attr_value"
              @click="tapAttr(indexw, indexn)"
              :key="indexn"
            >
              {{ itemn.attr }}
            </div>
          </div>
        </div>
      </div>
      <div class="cart">
        <div class="title">数量</div>
        <div class="carnum acea-row row-left">
          <div
            class="item reduce"
            :class="attr.productSelect.cart_num <= 1 ? 'on' : ''"
            @click="CartNumDes"
          >
            -
          </div>
          <div class="item num">{{ attr.productSelect.cart_num }}</div>
          <div
            class="item plus"
            :class="
              attr.productSelect.cart_num >= attr.productSelect.stock
                ? 'on'
                : ''
            "
            @click="CartNumAdd"
          >
            +
          </div>
        </div>
      </div>
    </div>
    <div
      class="mask"
      @touchmove.prevent
      :hidden="attr.cartAttr === false"
      @click="closeAttr"
    ></div>
  </div>
</template>
<script>
export default {
  name: "ProductWindow",
  props: {
    attr: {
      type: Object,
      default: () => {}
    }
  },
  data: function() {
    return {};
  },
  mounted: function() {},
  methods: {
    closeAttr: function() {
      this.$emit("changeFun", { action: "changeattr", value: false });
    },
    CartNumDes: function() {
      this.$emit("changeFun", { action: "ChangeCartNum", value: false });
    },
    CartNumAdd: function() {
      this.$emit("changeFun", { action: "ChangeCartNum", value: 1 });
    },
    tapAttr: function(indexw, indexn) {
      let that = this;
      that.attr.productAttr[indexw].index = indexn;
      let value = that
        .getCheckedValue()
        .sort()
        .join(",");
      that.$emit("changeFun", { action: "ChangeAttr", value: value });
    },
    //获取被选中属性;
    getCheckedValue: function() {
      let productAttr = this.attr.productAttr;
      let value = [];
      for (let i = 0; i < productAttr.length; i++) {
        for (let j = 0; j < productAttr[i].attr_values.length; j++) {
          if (productAttr[i].index === j) {
            value.push(productAttr[i].attr_values[j]);
          }
        }
      }
      return value;
    }
  }
};
</script>

PromotionGood.vue


<template>
  <div class="promotionGood" v-if="benefit.length > 0">
    <router-link
      :to="{ path: '/detail/' + item.id }"
      class="item acea-row row-between-wrapper"
      v-for="(item, index) in benefit"
      :key="index"
    >
      <div class="pictrue">
        <img :src="item.image" class="image" />
      </div>
      <div class="text">
        <div class="name line1">{{ item.store_name }}</div>
        <div class="sp-money acea-row">
          <div class="moneyCon">
            促销价: ¥<span class="num">{{ item.price }}</span>
          </div>
        </div>
        <div class="acea-row row-between-wrapper">
          <div class="money">日常价:¥{{ item.ot_price }}</div>
          <div>仅剩:{{ item.stock }}{{ item.unit_name }}</div>
        </div>
      </div>
    </router-link>
  </div>
</template>
<script>
export default {
  name: "PromotionGood",
  props: {
    benefit: {
      type: Array,
      default: () => []
    }
  },
  data: function() {
    return {};
  }
};
</script>

Recommend.vue


<template>
  <div class="recommend" ref="container">
    <div class="title acea-row row-center-wrapper">
      <span class="iconfont icon-zhuangshixian"></span>
      <span class="name">为你推荐</span>
      <span class="iconfont icon-zhuangshixian lefticon"></span>
    </div>
    <div class="recommendList acea-row row-between-wrapper">
      <router-link
        :to="{ path: '/detail/' + item.id }"
        class="item"
        v-for="(item, index) in hostProduct"
        :key="index"
      >
        <div class="pictrue">
          <img :src="item.image" class="image" />
        </div>
        <div class="name line1">{{ item.store_name }}</div>
        <div class="money font-color-red">
          ¥<span class="num">{{ item.price }}</span>
        </div>
      </router-link>
    </div>
    <Loading :loaded="loadend" :loading="loading"></Loading>
  </div>
</template>
<script>
import { getHostProducts } from "@api/store";
import Loading from "@components/Loading";
export default {
  name: "Recommend",
  props: {},
  components: {
    Loading
  },
  data: function() {
    return {
      hostProduct: [],
      page: 1,
      limit: 20,
      loadTitle: "",
      loading: false,
      loadend: false
    };
  },
  mounted: function() {
    this.hostProducts();
    this.$scroll(this.$refs.container.parentElement, () => {
      !this.loading && this.hostProducts();
    });
  },
  methods: {
    hostProducts: function() {
      let that = this;
      if (that.loading) return; //阻止下次请求(false可以进行请求);
      if (that.loadend) return; //阻止结束当前请求(false可以进行请求);
      that.loading = true;
      getHostProducts(that.page, that.limit).then(res => {
        that.loading = false;
        //apply();js将一个数组插入另一个数组;
        that.hostProduct.push.apply(that.hostProduct, res.data);
        that.loadend = res.data.length < that.limit; //判断所有数据是否加载完成;
        that.page = that.page + 1;
      });
    }
  }
};
</script>

ShareInfo.vue


<template>
  <div v-if="shareInfoStatus" class="poster-first">
    <div class="mask-share">
      <img src="@assets/images/share-info.png" @click="shareInfoClose" />
    </div>
  </div>
</template>
<style scoped>
.poster-first {
  overscroll-behavior: contain;
}
.mask-share {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 999;
}
.mask-share img {
  width: 100%;
}
</style>
<script>
export default {
  name: "ShareInfo",
  props: {
    shareInfoStatus: Boolean
  },
  data: function() {
    return {};
  },
  mounted: function() {},
  methods: {
    shareInfoClose: function() {
      this.$emit("setShareInfoStatus");
    }
  }
};
</script>

ShareRedPackets.vue


<template>
  <div class="sharing-packets" :class="state === true ? 'on' : ''">
    <div
      class="iconfont icon-guanbi acea-row row-center-wrapper"
      @click="closeShare"
    ></div>
    <div class="line"></div>
    <div class="sharing-con" @click="goShare">
      <img src="@assets/images/red-packets.png" class="image" />
      <div class="text font-color-red">
        <div>会员分享返</div>
        <div class="money"><span class="label">¥</span>{{ priceName }}</div>
        <div class="tip">下单即返佣金</div>
        <div class="shareBut">立即分享</div>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  name: "ShareRedPackets",
  props: {
    priceName: {
      type: [String, Number],
      default: ""
    }
  },
  data: function() {
    return {
      state: false
    };
  },
  mounted: function() {},
  methods: {
    goShare: function() {
      this.$emit("changeFun", { action: "shareCode", value: false });
    },
    closeShare: function() {
      this.state = true;
    }
  }
};
</script>

StorePoster.vue


<template>
  <div v-if="posterImageStatus" class="poster-first">
    <div class="poster-pop" v-show="!canvasStatus">
      <img
        src="@assets/images/poster-close.png"
        class="close"
        @click="posterImageClose"
      />
      <div class="canvas" ref="poster">
        <img class="image" :src="posterData.image" alt="商品图片" />
        <div class="text black"><span v-text="posterData.title"></span></div>
        <div class="text rad">
          <span v-text="'¥' + posterData.price"></span>
        </div>
        <div class="code">
          <div class="code-img">
            <img :src="posterData.code" alt="二维码" />
          </div>
          <div class="code-text"><span>长按识别二维码 立即购买</span></div>
        </div>
      </div>
      <!--<div class="save-poster" @click="savePosterPath">生成图片</div>-->
    </div>
    <div class="poster-pop" v-show="canvasStatus">
      <img
        src="@assets/images/poster-close.png"
        class="close"
        @click="posterImageClose"
      />
      <img :src="posterImage" alt="tp" class="poster-image" />
      <div class="keep">长按图片可以保存到手机</div>
    </div>
    <div class="mask"></div>
  </div>
</template>
<style scoped>
.poster-first {
  overscroll-behavior: contain;
}
.poster-pop {
  width: 4.5rem;
  height: 8rem;
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  z-index: 99;
  top: 50%;
  margin-top: -4.6rem;
}
.poster-pop .canvas {
  background-color: #ffffff;
  height: 8rem;
}
.poster-pop .poster-image {
  width: 100%;
}
.poster-pop .canvas .image {
  width: 4.5rem;
  height: 4.5rem;
  display: block;
}
.poster-pop .canvas .text {
  text-align: center;
  color: #000000;
  margin-top: 0.32rem;
}
.poster-pop .canvas .text.black {
  height: 0.68rem;
}
.poster-pop .canvas .text.rad {
  color: #ff0000;
}
.poster-pop .canvas .code {
  height: 1.4rem;
  display: inline-flex;
}
.poster-pop .canvas .code .code-img {
  width: 40%;
  padding: 0.06rem;
}
.poster-pop .canvas .code .code-img img {
  width: 100%;
}
.poster-pop .canvas .code .code-text {
  width: 70%;
  font-size: 0.12rem;
  line-height: 1.8rem;
}
.poster-pop .close {
  width: 0.46rem;
  height: 0.75rem;
  position: fixed;
  right: 0;
  top: -0.73rem;
  display: block;
}
.poster-pop .save-poster {
  background-color: #df2d0a;
  font-size: 0.22rem;
  color: #fff;
  text-align: center;
  height: 0.76rem;
  line-height: 0.76rem;
  width: 100%;
  margin-top: -0.04rem;
}
.poster-pop .keep {
  color: #fff;
  text-align: center;
  font-size: 0.25rem;
  margin-top: 0.1rem;
}
.mask {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.6);
  z-index: 9;
}
</style>
<script>
import html2canvas from "html2canvas";
export default {
  name: "StorePoster",
  props: {
    posterImageStatus: Boolean,
    posterData: Object
  },
  data: function() {
    return {
      canvasStatus: false
    };
  },
  watch: {
    posterImageStatus: function() {
      var that = this;
      if (that.posterImageStatus === true) {
        that.$nextTick(function() {
          that.savePosterPath();
        });
      }
    }
  },
  mounted: function() {},
  methods: {
    posterImageClose: function() {
      this.posterImageStatus = false;
      this.canvasStatus = false;
      this.$emit("setPosterImageStatus");
    },
    savePosterPath: function() {
      this.$dialog.loading.open();
      this.setHtml2Canvas();
    },
    setHtml2Canvas: function() {
      var that = this;
      const canvas = document.createElement("canvas");
      let canvasBox = that.$refs.poster;
      const width = parseInt(window.getComputedStyle(canvasBox).width);
      const height = parseInt(window.getComputedStyle(canvasBox).height);
      canvas.width = width * 2;
      canvas.height = height * 2;
      canvas.style.width = width + "px";
      canvas.style.height = height + "px";
      const context = canvas.getContext("2d");
      context.scale(2, 2);
      const options = {
        backgroundColor: null,
        canvas,
        useCORS: true
      };
      html2canvas(canvasBox, options).then(function(canvas) {
        that.posterImage = canvas.toDataURL();
        that.canvasStatus = true;
        that.$dialog.loading.close();
      });
    }
  }
};
</script>

SwitchWindow.vue


<template>
  <div>
    <div class="switchWindow" :class="switchActive === true ? 'on' : ''">
      <!-- @assets/images/public.png -->
      <div class="pictrue">
        <img v-if="login_type === 'h5'" src="@assets/images/h5.png" />
        <img src="@assets/images/h5.png" alt="" v-else />
      </div>
      <!-- 是否选择切换到小程序账户? -->
      <div class="info">
        是否选择切换到<span class="font-color" v-if="login_type === 'h5'"
          >微信账号</span
        >
        <span class="font-color" v-else>手机用户</span>?
      </div>
      <div class="switchBnt" @click="switchH5">切换</div>
      <div class="switchBnt cancelBnt" @click="switchClose">取消</div>
    </div>
    <div
      class="mask"
      @touchmove.prevent
      v-show="switchActive === true"
      @click="switchClose"
    ></div>
  </div>
</template>
<style>
.switchWindow {
  width: 5.6rem;
  border-radius: 0.2rem;
  -webkit-border-radius: 0.2rem;
  background-color: #fff;
  position: fixed;
  top: 50%;
  left: 50%;
  margin-left: -2.8rem;
  margin-top: -3rem;
  z-index: 99;
  padding: 0.5rem 0.3rem 0.4rem 0.3rem;
  text-align: center;
  box-sizing: border-box;
  -webkit-box-sizing: border-box;
  transition: all 0.3s ease-in-out 0s;
  -webkit-transition: all 0.3s ease-in-out 0s;
  -moz-transition: all 0.3s ease-in-out 0s;
  -o-transition: all 0.3s ease-in-out 0s;
  opacity: 0;
  transform: scale(0);
}
.switchWindow.on {
  opacity: 1;
  transform: scale(1);
  -webkit-transform: scale(1);
  -ms-transform: scale(1);
  -moz-transform: scale(1);
  -o-transform: scale(1);
}
.switchWindow .pictrue {
  width: 2.36rem;
  height: 2.36rem;
  margin: 0 auto;
}
.switchWindow .pictrue img {
  width: 100%;
  height: 100%;
  display: block;
}
.switchWindow .info {
  font-size: 0.32rem;
  color: #282828;
  margin-top: 0.44rem;
  font-weight: bold;
}
.switchWindow .switchBnt {
  font-size: 0.32rem;
  color: #fff;
  width: 3.6rem;
  height: 0.82rem;
  border-radius: 0.41rem;
  -webkit-border-radius: 0.41rem;
  margin: 0.57rem auto 0 auto;
  line-height: 0.82rem;
  background-image: linear-gradient(to right, #f67a38 0%, #f11b09 100%);
  background-image: -webkit-linear-gradient(to right, #f67a38 0%, #f11b09 100%);
  background-image: -moz-linear-gradient(to right, #f67a38 0%, #f11b09 100%);
}
.switchWindow .switchBnt.cancelBnt {
  background-color: #fff;
  color: #999;
  background-image: none;
  margin-top: 0.1rem;
}
</style>
<script>
import { clearAuthStatus } from "@libs/wechat";
import { switchH5Login } from "@api/user";
import cookie from "@utils/store/cookie";
import store from "@/store";
import dayjs from "dayjs";

export default {
  name: "SwitchWindow",
  props: {
    switchActive: {
      type: Boolean,
      default: false
    },
    login_type: {
      type: String,
      default: ""
    }
  },
  data: function() {
    return {};
  },
  mounted: function() {},
  methods: {
    switchClose: function() {
      this.$emit("changeswitch", false); //$emit():注册事件;
    },
    switchH5() {
      let that = this;
      this.$dialog.loading.open("正在切换中");
      if (that.login_type === "h5") {
        cookie.set("loginType", "wechat", 60);
        this.$dialog.loading.close();
        this.$store.commit("LOGOUT");
        clearAuthStatus();
        this.$emit("changeswitch", false);
        location.reload();
      } else {
        switchH5Login()
          .then(({ data }) => {
            this.$dialog.loading.close();
            const expires_time = dayjs(data.expires_time);
            store.commit("LOGIN", data.token, expires_time);
            this.$emit("changeswitch", false);
            location.reload();
          })
          .catch(err => {
            this.$dialog.loading.close();
            return that.$dialog.toast({ mes: err });
          });
      }
    }
  }
};
</script>

UserEvaluation.vue


<template>
  <div class="evaluateWtapper">
    <div class="evaluateItem" v-for="(item, index) in reply" :key="index">
      <div class="pic-text acea-row row-middle">
        <div class="pictrue">
          <img :src="item.avatar" class="image" />
        </div>
        <div class="acea-row row-middle">
          <div class="name line1">{{ item.nickname }}</div>
          <div class="start" :class="'star' + item.star"></div>
        </div>
      </div>
      <div class="time">{{ item.add_time }} {{ item.suk }}</div>
      <div class="evaluate-infor">{{ item.comment }}</div>
      <div class="imgList acea-row">
        <div class="pictrue" v-for="(itemn, index) in item.pics" :key="index">
          <img :src="itemn" class="image" />
        </div>
      </div>
      <div class="reply" v-if="item.merchant_reply_content">
        <span class="font-color-red">店小二</span>:{{
          item.merchant_reply_content
        }}
      </div>
    </div>
  </div>
</template>
<script>
export default {
  name: "UserEvaluation",
  props: {
    reply: {
      type: Array,
      default: () => []
    }
  },
  data: function() {
    return {};
  },
  mounted: function() {},
  methods: {}
};
</script>

WriteOff.vue


<template>
  <div v-show="iShidden === false">
    <div class="WriteOff">
      <div class="pictrue"><img :src="orderInfo.image" /></div>
      <div class="num acea-row row-center-wrapper">
        {{ orderInfo.order_id }}
      </div>
      <div class="tip">确定要核销此订单吗?</div>
      <div class="sure" @click="confirm">确定核销</div>
      <div class="sure cancel" @click="cancel">取消</div>
    </div>
    <div class="mask" @touchmove.prevent></div>
  </div>
</template>
<style scoped>
.WriteOff {
  width: 5.6rem;
  height: 8rem;
  background-color: #fff;
  border-radius: 0.2rem;
  position: fixed;
  top: 50%;
  left: 50%;
  margin-top: -4rem;
  margin-left: -2.8rem;
  z-index: 99;
  padding-top: 0.55rem;
}
.WriteOff .pictrue {
  width: 3.4rem;
  height: 3.4rem;
  margin: 0 auto;
}
.WriteOff .pictrue img {
  width: 100%;
  height: 100%;
  display: block;
  border-radius: 0.1rem;
}
.WriteOff .num {
  font-size: 0.3rem;
  color: #666;
  margin: 0.28rem 0 0.3rem 0;
}
.WriteOff .num .see {
  font-size: 0.16rem;
  color: #fff;
  border-radius: 0.04rem;
  background-color: #c68937;
  padding-left: 0.05rem;
  margin-left: 0.12rem;
}
.WriteOff .num .see .iconfont {
  font-size: 0.15rem;
}
.WriteOff .tip {
  font-size: 0.36rem;
  color: #282828;
  text-align: center;
  border-top: 1px dashed #ccc;
  padding-top: 0.4rem;
  position: relative;
}
.WriteOff .tip:after {
  content: "";
  position: absolute;
  width: 0.25rem;
  height: 0.25rem;
  border-radius: 50%;
  background-color: #7f7f7f;
  right: -0.125rem;
  top: -0.125rem;
}
.WriteOff .tip:before {
  content: "";
  position: absolute;
  width: 0.25rem;
  height: 0.25rem;
  border-radius: 50%;
  background-color: #7f7f7f;
  left: -0.125rem;
  top: -0.125rem;
}
.WriteOff .sure {
  font-size: 0.32rem;
  color: #fff;
  text-align: center;
  line-height: 0.82rem;
  height: 0.82rem;
  width: 4.6rem;
  border-radius: 0.41rem;
  margin: 0.4rem auto 0 auto;
  background-image: linear-gradient(to right, #f67a38 0%, #f11b09 100%);
  background-image: -webkit-linear-gradient(to right, #f67a38 0%, #f11b09 100%);
  background-image: -moz-linear-gradient(to right, #f67a38 0%, #f11b09 100%);
}
.WriteOff .sure.cancel {
  background-image: none;
  color: #999;
  margin-top: 0.1rem;
}
</style>
<script>
export default {
  name: "WriteOff",
  props: {
    iShidden: {
      type: Boolean,
      default: true
    },
    orderInfo: {
      type: Object
    }
  },
  data: function() {
    return {};
  },
  mounted: function() {},
  methods: {
    cancel: function() {
      this.$emit("cancel", true);
    },
    confirm: function() {
      this.$emit("confirm", true);
    }
  }
};
</script>

libs

chat.js


import $store from "@/store";
import { VUE_APP_WS_URL } from "@utils";

const Socket = function() {
  this.ws = new WebSocket(VUE_APP_WS_URL);
  this.ws.onopen = this.onOpen.bind(this);
  this.ws.onerror = this.onError.bind(this);
  this.ws.onmessage = this.onMessage.bind(this);
  this.ws.onclose = this.onClose.bind(this);
};

Socket.prototype = {
  vm(vm) {
    this.vm = vm;
  },
  close() {
    clearInterval(this.timer);
    this.ws.close();
  },
  onOpen: function() {
    console.log("ws open");
    this.init();
    this.send({
      type: "login",
      data: $store.state.app.token
    });
    this.vm.$emit("socket_open");
  },
  init: function() {
    var that = this;
    this.timer = setInterval(function() {
      that.send({ type: "ping" });
    }, 10000);
  },
  send: function(data) {
    return this.ws.send(JSON.stringify(data));
  },
  onMessage: function(res) {
    const { type, data = {} } = JSON.parse(res.data);
    this.vm.$emit(type, data);
  },
  onClose: function() {
    clearInterval(this.timer);
  },
  onError: function(e) {
    console.log(e);
    this.vm.$emit("socket_error", e);
  }
};

Socket.prototype.constructor = Socket;

export default Socket;

login.js


import router from "../router";
import store from "../store";
import cookie from "@utils/store/cookie";
import { isWeixin } from "@utils";
import { oAuth } from "@libs/wechat";

export default function toLogin(push, backUrl) {
  store.commit("LOGOUT");
  const { fullPath, name } = router.currentRoute;
  cookie.set("login_back_url", backUrl || fullPath);
  if (isWeixin()) {
    oAuth();
  } else {
    if (name !== "Login") {
      push
        ? router.push({ path: "/login" })
        : router.replace({ path: "/login" });
    }
  }
}

order.js


import { cancelOrder, takeOrder, delOrder, payOrder } from "@api/order";
import dialog from "@utils/dialog";
import { pay } from "@libs/wechat";

export function cancelOrderHandle(orderId) {
  return new Promise((resolve, reject) => {
    dialog.confirm({
      mes: "确认取消该订单?",
      opts() {
        cancelOrder(orderId)
          .then(res => {
            dialog.success("取消成功");
            resolve(res);
          })
          .catch(err => {
            dialog.error("取消失败");
            reject(err);
          });
      }
    });
  });
}

export function takeOrderHandle(orderId) {
  return new Promise((resolve, reject) => {
    takeOrder(orderId)
      .then(res => {
        dialog.success("收货成功");
        resolve(res);
      })
      .catch(err => {
        dialog.error("收货失败");
        reject(err);
      });
  });
}

export function delOrderHandle(orderId) {
  return new Promise((resolve, reject) => {
    dialog.confirm({
      mes: "确认删除该订单?",
      opts() {
        delOrder(orderId)
          .then(res => {
            dialog.success("删除成功");
            resolve(res);
          })
          .catch(err => {
            dialog.error("删除失败");
            reject(err);
          });
      }
    });
  });
}

export function payOrderHandle(orderId, type, from) {
  return new Promise((resolve, reject) => {
    dialog.loading.open("");
    payOrder(orderId, type, from)
      .then(res => {
        const data = res.data;
        dialog.loading.close();
        switch (data.status) {
          case "WECHAT_H5_PAY":
            reject(data);
            setTimeout(() => {
              location.replace(data.result.jsConfig.mweb_url);
            }, 100);
            break;
          case "ORDER_EXIST":
          case "EXTEND_ORDER":
          case "PAY_ERROR":
          case "PAY_DEFICIENCY":
            dialog.toast({ mes: res.msg });
            reject(data);
            break;
          case "SUCCESS":
            dialog.success(res.msg);
            resolve(data);
            break;
          case "WECHAT_PAY":
            pay(data.result.jsConfig).then(() => {
              resolve(data);
            });
        }
      })
      .catch(err => {
        dialog.loading.close();
        dialog.toast({ mes: err.msg || "订单支付失败" });
      });
  });
}

wechat.js


import WechatJSSDK from "wechat-jssdk/dist/client.umd";
import { getWechatConfig, wechatAuth } from "@api/public";
import { parseQuery } from "@utils";
import cookie from "@utils/store/cookie";
import store from "@/store";
import dayjs from "dayjs";

const STATE_KEY = "wx_authorize_state";
const WX_AUTH = "wx_auth";
const BACK_URL = "login_back_url";
const LOGINTYPE = "loginType";
let instance;
let wechatObj;

export default function wechat() {
  return new Promise((resolve, reject) => {
    if (instance) return resolve(instance);
    getWechatConfig()
      .then(res => {
        const _wx = WechatJSSDK(res.data);
        wechatObj = _wx;
        _wx
          .initialize()
          .then(() => {
            instance = _wx.wx;
            instance.initConfig = res.data;
            resolve(instance);
          })
          .catch(reject);
      })
      .catch(err => {
        console.log(err);
        reject(err);
      });
  });
}

export function clearAuthStatus() {
  cookie.remove(WX_AUTH);
  cookie.remove(STATE_KEY);
}

export function oAuth() {
  if (cookie.has(WX_AUTH) && store.state.app.token) return;
  const { code } = parseQuery();
  if (!code) return toAuth();
}

export function auth(code) {
  return new Promise((resolve, reject) => {
    let loginType = cookie.get(LOGINTYPE);
    //if (state !== cookie.get(STATE_KEY)) return reject();
    wechatAuth(code, parseInt(cookie.get("spread")), loginType)
      .then(({ data }) => {
        const expires_time = dayjs(data.expires_time);
        const newTime = Math.round(new Date() / 1000);
        store.commit("LOGIN", data.token, expires_time - newTime);
        cookie.set(WX_AUTH, code, expires_time);
        cookie.remove(STATE_KEY);
        loginType && cookie.remove("loginType");
        resolve();
      })
      .catch(reject);
  });
}

export function toAuth() {
  wechat().then(wx => {
    location.href = getAuthUrl(wx.initConfig.appId);
  });
}

function getAuthUrl(appId) {
  const redirect_uri = encodeURIComponent(
    `${location.origin}/auth/` +
      encodeURIComponent(
        encodeURIComponent(
          cookie.has(BACK_URL)
            ? cookie.get(BACK_URL)
            : location.pathname + location.search
        )
      )
  );
  cookie.remove(BACK_URL);
  const state = encodeURIComponent(
    ("" + Math.random()).split(".")[1] + "authorizestate"
  );
  cookie.set(STATE_KEY, state);
  return `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${redirect_uri}&response_type=code&scope=snsapi_userinfo&state=${state}#wechat_redirect`;
}

function toPromise(fn, config = {}) {
  return new Promise((resolve, reject) => {
    fn({
      ...config,
      success(res) {
        resolve(res);
      },
      fail(err) {
        reject(err);
      },
      complete(err) {
        reject(err);
      },
      cancel(err) {
        reject(err);
      }
    });
  });
}

export function pay(config) {
  return toPromise(instance.chooseWXPay, config);
}

export function openAddress() {
  return new Promise((resolve, reject) => {
    wechatEvevt("openAddress", {})
      .then(res => {
        console.log(res);
        resolve(res);
      })
      .catch(res => {
        console.log(res);
        if (res.is_ready) {
          res.wx.openAddress({
            fail(res) {
              reject(res);
            },
            success(res) {
              resolve(res);
            }
          });
        } else {
          reject(res);
        }
      });
  });
}

export function openShareAll(config) {
  config || {};
  config.type = config.type == undefined ? "link" : config.type;
  return new Promise(resolve => {
    getWechatConfig().then(res => {
      wechatObj.signSignature({
        nonceStr: res.data.nonceStr,
        signature: res.data.signature,
        timestamp: res.data.timestamp
      });
      instance = wechatObj.getOriginalWx();
      instance.ready(() => {
        instance.updateAppMessageShareData(config);
        instance.updateTimelineShareData(config);
        resolve();
      });
    });
  });
}

export function openShareAppMessage(config) {
  instance.updateAppMessageShareData(config);
  instance.onMenuShareAppMessage && instance.onMenuShareAppMessage(config);
}

export function openShareTimeline(config) {
  instance.updateTimelineShareData(config);
  instance.onMenuShareTimeline && instance.onMenuShareTimeline(config);
}

/**
 * 公众号事件
 * @param name 事件名
 * @param config 配置
 * @returns {Promise<unknown>}
 */
export function wechatEvevt(name, config) {
  return new Promise((resolve, reject) => {
    let wx;
    let configDefault = {
      fail(res) {
        console.log(res);
        if (wx) return reject({ is_ready: true, wx: wx });
        getWechatConfig().then(res => {
          wechatObj.signSignature({
            nonceStr: res.data.nonceStr,
            signature: res.data.signature,
            timestamp: res.data.timestamp
          });
          wx = wechatObj.getOriginalWx();
          reject({ is_ready: true, wx: wx });
        });
      },
      success(res) {
        resolve(res);
      }
    };
    Object.assign(configDefault, config);
    if (typeof instance !== "undefined") {
      instance.ready(() => {
        if (typeof name === "object") {
          name.forEach(item => {
            instance[item] && instance[item](configDefault);
          });
        } else instance[name] && instance[name](configDefault);
      });
    } else {
      getWechatConfig().then(res => {
        const _wx = WechatJSSDK(res.data);
        _wx.initialize().then(() => {
          instance = _wx.getOriginalWx();
          instance.ready(() => {
            if (typeof name === "object") {
              name.forEach(item => {
                instance[item] && instance[item](configDefault);
              });
            } else instance[name] && instance[name](configDefault);
          });
        });
      });
    }
  });
}

export function ready() {
  return new Promise(resolve => {
    if (typeof instance !== "undefined") {
      instance.ready(() => {
        resolve(instance);
      });
    } else {
      getWechatConfig().then(res => {
        const _wx = WechatJSSDK(res.data);
        _wx.initialize().then(() => {
          instance = _wx.wx;
          instance.ready(() => {
            resolve(instance);
          });
        });
      });
    }
  });
}

main.js


import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import animate from "animate.css";
import schema from "async-validator";
import dialog from "./utils/dialog";
import $scroll from "@utils/loading";
import cookie from "@utils/store/cookie";

import "@assets/iconfont/iconfont";
import "@assets/iconfont/iconfont.css";
import "@assets/js/media_750";
import "vue-ydui/dist/ydui.base.css";
import "@assets/css/base.css";
import "@assets/css/reset.css";
import "@assets/css/style.css";
import { isWeixin, parseQuery } from "@utils";

Vue.use(animate);
Vue.config.productionTip = false;
Vue.config.devtools = process.env.NODE_ENV !== "production";
Vue.prototype.$validator = function(rule) {
  return new schema(rule);
};
Vue.prototype.$scroll = $scroll;
Vue.prototype.$dialog = dialog;

const CACHE_KEY = "clear_0.0.1";

if (!cookie.has(CACHE_KEY)) {
  cookie.clearAll();
  cookie.set(CACHE_KEY, 1);
}

let cookieName = "VCONSOLE";
let query = parseQuery();
let urlSpread = query["spread"];
let vconsole = query[cookieName.toLowerCase()];
let md5Crmeb = "b14d1e9baeced9bb7525ab19ee35f2d2"; //CRMEB MD5 加密开启vconsole模式
let md5UnCrmeb = "3dca2162c4e101b7656793a1af20295c"; //UN_CREMB MD5 加密关闭vconsole模式

if (urlSpread !== undefined) {
  var spread = cookie.get("spread");
  urlSpread = parseInt(urlSpread);
  if (!Number.isNaN(urlSpread) && spread !== urlSpread) {
    cookie.set("spread", urlSpread || 0);
  } else if (spread === 0 || typeof spread !== "number") {
    cookie.set("spread", urlSpread || 0);
  }
}

const _isWechat = isWeixin();

if (vconsole !== undefined) {
  if (vconsole === md5UnCrmeb && cookie.has(cookieName))
    cookie.remove(cookieName);
} else vconsole = cookie.get(cookieName);

if (vconsole !== undefined && vconsole === md5Crmeb) {
  cookie.set(cookieName, md5Crmeb, 3600);
  const module = () => import("vconsole");
  module().then(Module => {
    new Module.default();
  });
}

if (_isWechat) {
  const module = () => import("@libs/wechat");
  module().then(Module => {
    Module.default().then(() => Module.oAuth());
  });
}

const $vm = new Vue({
  router,
  store,
  render: h => h(App)
});

setTimeout(() => {
  $vm.$mount("#app");
}, 300);

mixins

SendVerifyCode.js


export default {
  data() {
    return {
      disabled: false,
      text: "获取验证码"
    };
  },
  methods: {
    sendCode() {
      if (this.disabled) return;
      this.disabled = true;
      let n = 60;
      this.text = "剩余 " + n + "s";
      const run = setInterval(() => {
        n = n - 1;
        if (n < 0) {
          clearInterval(run);
        }
        this.text = "剩余 " + n + "s";
        if (this.text < "剩余 " + 0 + "s") {
          this.disabled = false;
          this.text = "重新获取";
        }
      }, 1000);
    }
  }
};

router

index.js


import Vue from "vue";
import Router from "vue-router";
import module from "./module";
import Index from "@views/home/Index";
import Search from "@views/shop/GoodSearch";
import Category from "@views/shop/GoodsClass";
import ShoppingCart from "@views/shop/ShoppingCart";
import GoodsList from "@views/shop/GoodsList";
import NotDefined from "@views/NotDefined";
import $store from "../store";
import toLogin from "@libs/login";
import Loading from "@views/Loading";

Vue.use(Router);

const router = new Router({
  mode: "history",
  routes: [
    {
      path: "/",
      name: "Index",
      meta: {
        title: "首页",
        keepAlive: true,
        footer: true,
        backgroundColor: "#fff"
      },
      component: Index
    },
    {
      path: "/customer/chat/:id",
      name: "CustomerService",
      meta: {
        title: "客服聊天",
        keepAlive: false,
        auth: true
      },
      component: () => import("@views/user/CustomerService.vue")
    },
    {
      path: "/category/:pid?",
      name: "GoodsClass",
      meta: {
        title: "产品分类",
        keepAlive: true,
        footer: true,
        backgroundColor: "#fff"
      },
      component: Category
    },
    {
      path: "/collection",
      name: "GoodsCollection",
      meta: {
        title: "收藏商品",
        keepAlive: false,
        auth: true
      },
      component: () => import("@views/shop/GoodsCollection.vue")
    },
    {
      path: "/search",
      name: "GoodSearch",
      meta: {
        title: "搜索商品",
        keepAlive: true,
        backgroundColor: "#fff"
      },
      component: Search
    },
    {
      path: "/news_detail/:id",
      name: "NewsDetail",
      meta: {
        title: "新闻详情",
        keepAlive: true,
        backgroundColor: "#fff"
      },
      component: () => import("@views/shop/news/NewsDetail.vue")
    },
    {
      path: "/news_list",
      name: "NewsList",
      meta: {
        title: "新闻",
        keepAlive: true,
        backgroundColor: "#fff"
      },
      component: () => import("@views/shop/news/NewsList.vue")
    },
    {
      path: "/evaluate_list/:id",
      name: "EvaluateList",
      meta: {
        title: "商品评分",
        keepAlive: true,
        auth: true
      },
      component: () => import("@views/shop/EvaluateList.vue")
    },
    {
      path: "/goods_evaluate/:id",
      name: "GoodsEvaluate",
      meta: {
        title: "商品评价",
        keepAlive: true,
        auth: true
      },
      component: () => import("@views/shop/GoodsEvaluate.vue")
    },
    {
      path: "/promotion",
      name: "GoodsPromotion",
      meta: {
        title: "促销单品",
        keepAlive: false
      },
      component: () => import("@views/shop/GoodsPromotion.vue")
    },
    {
      path: "/hot_new_goods/:type",
      name: "HotNewGoods",
      meta: {
        title: "热门榜单",
        keepAlive: false
      },
      component: () => import("@views/shop/HotNewGoods.vue")
    },
    {
      path: "/detail/:id",
      name: "GoodsCon",
      meta: {
        title: "商品详情",
        keepAlive: false
      },
      component: () => import("@views/shop/GoodsCon.vue")
    },
    {
      path: "/cart",
      name: "ShoppingCart",
      meta: {
        title: "购物车",
        keepAlive: true,
        footer: true,
        auth: true
      },
      component: ShoppingCart
    },
    {
      path: "/goods_list",
      name: "GoodsList",
      meta: {
        title: "商品列表",
        keepAlive: true
      },
      component: GoodsList
    },
    {
      path: "/register",
      name: "Register",
      meta: {
        title: "注册",
        keepAlive: true
      },
      component: () =>
        import(/* webpackChunkName: "login" */ "@views/user/Register.vue")
    },
    {
      path: "/change_password",
      name: "ChangePassword",
      meta: {
        title: "修改密码",
        keepAlive: true,
        backgroundColor: "#fff",
        auth: true
      },
      component: () =>
        import(/* webpackChunkName: "login" */ "@views/user/ChangePassword.vue")
    },
    {
      path: "/retrieve_password",
      name: "RetrievePassword",
      meta: {
        title: "找回密码",
        keepAlive: true
      },
      component: () =>
        import(/* webpackChunkName: "login" */ "@views/user/RetrievePassword.vue")
    },
    {
      path: "/login",
      name: "Login",
      meta: {
        title: "登录",
        keepAlive: true
      },
      component: () =>
        import(/* webpackChunkName: "login" */ "@views/user/Login.vue")
    },
    ...module,
    {
      path: "/auth/:url",
      name: "Loading",
      meta: {
        title: " 加载中",
        keepAlive: true
      },
      component: Loading
    },
    {
      path: "*",
      name: "NotDefined",
      meta: {
        title: "页面找不到",
        keepAlive: true,
        home: false,
        backgroundColor: "#F4F6FB"
      },
      component: NotDefined
    }
  ],
  scrollBehavior(to, from) {
    from.meta.scrollTop = window.scrollY;
    return { x: 0, y: to.meta.scrollTop || 0 };
  }
});

const { back, replace } = router;

router.back = function() {
  this.isBack = true;
  back.call(router);
};
router.replace = function(...args) {
  this.isReplace = true;
  replace.call(router, ...args);
};

router.beforeEach((to, form, next) => {
  const { title, backgroundColor, footer, home, auth } = to.meta;
  console.log(to.name, form.name);
  if (auth === true && !$store.state.app.token) {
    if (form.name === "Login") return;
    return toLogin(true, to.fullPath);
  }
  document.title = title || process.env.VUE_APP_NAME || "crmeb商城";
  //判断是否显示底部导航
  footer === true ? $store.commit("SHOW_FOOTER") : $store.commit("HIDE_FOOTER");

  //控制悬浮按钮是否显示
  home === false ? $store.commit("HIDE_HOME") : $store.commit("SHOW_HOME");

  $store.commit("BACKGROUND_COLOR", backgroundColor || "#F5F5F5");

  if (auth) {
    $store.dispatch("USERINFO").then(() => {
      next();
    });
  } else next();
});

export default router;

module

activity.js

export default [
  {
    path: "/activity"
  },
  {
    path: "/activity/goods_seckill",
    name: "GoodsSeckill",
    meta: {
      title: "限时抢购",
      keepAlive: true,
      backgroundColor: "#ffffff"
    },
    component: () => import("@views/activity/GoodsSeckill.vue")
  },
  {
    path: "/activity/seckill_detail/:id?/:time",
    name: "SeckillDetails",
    meta: {
      title: "抢购详情页",
      keepAlive: true
    },
    component: () => import("@views/activity/SeckillDetails.vue")
  }
];

index.js

import user from "./user";
import order from "./order";
import activity from "./activity";

export default [...user, ...order, ...activity];

order.js

export default [
  {
    path: "/order/list/:type?",
    name: "MyOrder",
    meta: {
      title: "我的订单",
      keepAlive: false,
      auth: true
    },
    component: () => import("@views/order/MyOrder")
  },
  {
    path: "/order/logistics/:id",
    name: "Logistics",
    meta: {
      title: "物流信息",
      keepAlive: true,
      auth: true
    },
    component: () => import("@views/order/Logistics")
  },
  {
    path: "/order/detail/:id",
    name: "OrderDetails",
    meta: {
      title: "订单详情",
      keepAlive: false,
      auth: true
    },
    component: () => import("@views/order/OrderDetails")
  },
  {
    path: "/order/submit/:id",
    name: "OrderSubmission",
    meta: {
      title: "提交订单",
      keepAlive: true,
      auth: true
    },
    component: () => import("@views/order/OrderSubmission")
  },
  {
    path: "/order/status/:id/:status",
    name: "PaymentStatus",
    meta: {
      title: "支付状态",
      keepAlive: true,
      auth: true
    },
    component: () => import("@views/order/PaymentStatus")
  },
  {
    path: "/order/refund/:id",
    name: "GoodsReturn",
    meta: {
      title: "申请退货",
      keepAlive: true,
      auth: true
    },
    component: () => import("@views/order/GoodsReturn.vue")
  },
  {
    path: "/order/refund_list",
    name: "ReturnList",
    meta: {
      title: "退货列表",
      keepAlive: true,
      auth: true
    },
    component: () => import("@views/order/ReturnList.vue")
  }
];

user.js

import User from "@views/user/User";

export default [
  {
    path: "/user",
    name: "User",
    meta: {
      title: "个人中心",
      keepAlive: true,
      footer: true,
      auth: true
    },
    component: User
  },
  {
    path: "/user/binding",
    name: "BindingPhone",
    meta: {
      title: "绑定手机",
      keepAlive: true,
      backgroundColor: "#fff",
      auth: true
    },
    component: () => import("@views/user/BindingPhone.vue")
  },
  {
    path: "/user/add_address/:id?",
    name: "AddAddress",
    meta: {
      title: "添加收货地址",
      keepAlive: true,
      auth: true
    },
    component: () => import("@views/user/address/AddAddress.vue")
  },
  {
    path: "/user/account",
    name: "UserAccount",
    meta: {
      title: "我的账户",
      keepAlive: true,
      auth: true
    },
    component: () => import("@views/user/UserAccount.vue")
  },
  {
    path: "/user/add_manage",
    name: "AddressManagement",
    meta: {
      title: "地址管理",
      keepAlive: true,
      auth: true
    },
    component: () => import("@views/user/address/AddressManagement.vue")
  },
  {
    path: "/user/poster",
    name: "Poster",
    meta: {
      title: "分销海报",
      keepAlive: false,
      backgroundColor: "#a3a3a3",
      auth: true
    },
    component: () => import("@views/user/promotion/Poster.vue")
  },
  {
    path: "/user/sign",
    name: "Sign",
    meta: {
      title: "签到",
      keepAlive: true,
      auth: true
    },
    component: () => import("@views/user/signIn/Sign.vue")
  },
  {
    path: "/user/sign_record",
    name: "SignRecord",
    meta: {
      title: "签到记录",
      keepAlive: true
    },
    component: () => import("@views/user/signIn/SignRecord.vue")
  },
  {
    path: "/user/cash",
    name: "UserCash",
    meta: {
      title: "提现",
      keepAlive: true,
      auth: true
    },
    component: () => import("@views/user/promotion/UserCash.vue")
  },
  {
    path: "/user/audit",
    name: "CashAudit",
    meta: {
      title: "提现审核",
      keepAlive: true,
      auth: true
    },
    component: () => import("@views/user/promotion/CashAudit.vue")
  },
  {
    path: "/user/promoter_order",
    name: "PromoterOrder",
    meta: {
      title: "推广人订单",
      keepAlive: true,
      auth: true
    },
    component: () => import("@views/user/promotion/PromoterOrder.vue")
  },
  {
    path: "/user/promoter_list",
    name: "PromoterList",
    meta: {
      title: "推广人列表",
      keepAlive: true,
      auth: true
    },
    component: () => import("@views/user/promotion/PromoterList.vue")
  },
  {
    path: "/user/user_promotion",
    name: "UserPromotion",
    meta: {
      title: "我的推广",
      keepAlive: true,
      auth: true
    },
    component: () => import("@views/user/promotion/UserPromotion.vue")
  },
  {
    path: "/user/bill/:types?",
    name: "UserBill",
    meta: {
      title: "账单明细",
      keepAlive: true,
      auth: true
    },
    component: () => import("@views/user/UserBill.vue")
  },
  {
    path: "/user/cashrecord",
    name: "CashRecord",
    meta: {
      title: "提现记录",
      keepAlive: true,
      auth: true
    },
    component: () => import("@views/user/promotion/CashRecord.vue")
  },
  {
    path: "/user/commission",
    name: "CommissionDetails",
    meta: {
      title: "佣金明细",
      keepAlive: true,
      auth: true
    },
    component: () => import("@views/user/promotion/CommissionDetails.vue")
  },
  {
    path: "/user/integral",
    name: "Integral",
    meta: {
      title: "积分详情",
      keepAlive: true,
      auth: true
    },
    component: () => import("@views/user/signIn/Integral.vue")
  },
  {
    path: "/user/vip",
    name: "UserVip",
    meta: {
      title: "会员中心",
      keepAlive: true,
      auth: true
    },
    component: () => import("@views/user/UserVip.vue")
  },
  {
    path: "/user/data",
    name: "PersonalData",
    meta: {
      title: "个人资料",
      keepAlive: true,
      auth: true
    },
    component: () => import("@views/user/PersonalData.vue")
  },
  {
    path: "/user/user_coupon",
    name: "UserCoupon",
    meta: {
      title: "我的优惠券",
      keepAlive: true,
      auth: true
    },
    component: () => import("@views/user/coupon/UserCoupon.vue")
  },
  {
    path: "/user/get_coupon",
    name: "GetCoupon",
    meta: {
      title: "领取优惠券",
      keepAlive: true
    },
    component: () => import("@views/user/coupon/GetCoupon.vue")
  },
  {
    path: "/user/user_cash",
    name: "UserCash",
    meta: {
      title: "申请提现",
      keepAlive: true,
      auth: true
    },
    component: () => import("@views/user/promotion/UserCash.vue")
  },
  {
    path: "/customer/list",
    name: "CustomerList",
    meta: {
      title: "客服列表",
      keepAlive: true,
      auth: true
    },
    component: () => import("@views/user/CustomerList.vue")
  },
  {
    path: "/user/Recharge",
    name: "Recharge",
    meta: {
      title: "余额充值",
      keepAlive: true,
      auth: true
    },
    component: () => import("@views/user/Recharge.vue")
  },
  {
    path: "/user/promoter_rank",
    name: "PromoterRank",
    meta: {
      title: "推广人排行",
      keepAlive: true,
      auth: true
    },
    component: () => import("@views/user/promotion/PromoterRank.vue")
  },
  {
    path: "/user/commission/rank",
    name: "CommissionRank",
    meta: {
      title: "佣金排行",
      keepAlive: true,
      auth: true
    },
    component: () => import("@views/user/promotion/CommissionRank.vue")
  }
];

store

getters.js


export default {
  footer: state => state.app.footer,
  homeActive: state => state.app.homeActive,
  home: state => state.app.home,
  token: state => state.app.token,
  isLogin: state => !!state.app.token,
  backgroundColor: state => state.app.backgroundColor,
  userInfo: state => state.app.userInfo || {}
};

index.js


import Vue from "vue";
import Vuex from "vuex";
import modules from "./modules";
import getters from "./getters";

Vue.use(Vuex);
const debug = process.env.NODE_ENV !== "production";

export default new Vuex.Store({
  modules,
  getters,
  strict: debug
});

modules

app.js

import store from "@utils/store/cookie";
import { getUserInfo } from "@api/user";
import dialog from "@utils/dialog";

const LOGIN_KEY = "login_status";

const state = {
  footer: true,
  home: true,
  homeActive: false,
  token: store.get(LOGIN_KEY) || null,
  backgroundColor: "#fff",
  userInfo: null
};

const mutations = {
  SHOW_FOOTER(state) {
    state.footer = true;
  },
  HIDE_FOOTER(state) {
    state.footer = false;
  },
  SHOW_HOME(state) {
    state.home = true;
  },
  HIDE_HOME(state) {
    state.home = false;
  },
  OPEN_HOME(state) {
    state.homeActive = true;
  },
  CLOSE_HOME(state) {
    state.homeActive = false;
  },
  LOGIN(state, token, expires_time) {
    state.token = token;
    store.set(LOGIN_KEY, token, expires_time);
  },
  LOGOUT(state) {
    state.token = undefined;
    store.remove(LOGIN_KEY);
  },
  BACKGROUND_COLOR(state, color) {
    state.color = color;
    document.body.style.backgroundColor = color;
  },
  UPDATE_USERINFO(state, userInfo) {
    state.userInfo = userInfo;
  }
};

const actions = {
  USERINFO({ state, commit }, force) {
    if (state.userInfo !== null && !force)
      return Promise.resolve(state.userInfo);
    else
      return new Promise(reslove => {
        getUserInfo().then(res => {
          commit("UPDATE_USERINFO", res.data);
          reslove(res.data);
        });
      }).catch(() => {
        dialog.error("获取信息失败!");
      });
  }
};

export default {
  state,
  mutations,
  actions
};

index.js

import app from "./app";

export default {
  app
};

utils

bc.js


//除法函数,用来得到精确的除法结果
//说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。
//调用:div(arg1,arg2)
//返回值:arg1除以arg2的精确结果
export function div(arg1, arg2) {
  var t1 = 0,
    t2 = 0,
    r1,
    r2;
  try {
    t1 = arg1.toString().split(".")[1].length;
  } catch (e) {
    t1 = 0;
  }
  try {
    t2 = arg2.toString().split(".")[1].length;
  } catch (e) {
    t2 = 0;
  }
  r1 = Number(arg1.toString().replace(".", ""));
  r2 = Number(arg2.toString().replace(".", ""));
  return mul(r1 / r2, Math.pow(10, t2 - t1));
}
//乘法函数,用来得到精确的乘法结果
//说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。
//调用:mul(arg1,arg2)
//返回值:arg1乘以arg2的精确结果
export function mul(arg1, arg2) {
  var m = 0,
    s1 = arg1.toString(),
    s2 = arg2.toString();
  try {
    m += s1.split(".")[1].length;
  } catch (e) {
    m = 0;
  }
  try {
    m += s2.split(".")[1].length;
  } catch (e) {
    m = m || 0;
  }
  return (
    (Number(s1.replace(".", "")) * Number(s2.replace(".", ""))) /
    Math.pow(10, m)
  );
}

//加法函数,用来得到精确的加法结果
//说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
//调用:add(arg1,arg2)
//返回值:arg1加上arg2的精确结果
export function add(arg1, arg2) {
  var r1, r2, m, n;
  try {
    r1 = arg1.toString().split(".")[1].length;
  } catch (e) {
    r1 = 0;
  }
  try {
    r2 = arg2.toString().split(".")[1].length;
  } catch (e) {
    r2 = 0;
  }
  m = Math.pow(10, Math.max(r1, r2));
  n = r1 >= r2 ? r1 : r2;
  return ((arg1 * m + arg2 * m) / m).toFixed(n);
}

//减法函数,用来得到精确的减法结果
//说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的减法结果。
//调用:sub(arg1,arg2)
//返回值:arg1减去arg2的精确结果
export function sub(arg1, arg2) {
  var r1, r2, m, n;
  try {
    r1 = arg1.toString().split(".")[1].length;
  } catch (e) {
    r1 = 0;
  }
  try {
    r2 = arg2.toString().split(".")[1].length;
  } catch (e) {
    r2 = 0;
  }
  m = Math.pow(10, Math.max(r1, r2));
  //动态控制精度长度
  n = r1 >= r2 ? r1 : r2;
  return ((arg1 * m - arg2 * m) / m).toFixed(n);
}

function Compute(value) {
  this.value = value;
}
Object.assign(Compute.prototype, {
  add(v) {
    this.value = add(this.value, v);
    return this;
  },
  sub(v) {
    this.value = sub(this.value, v);
    return this;
  },
  div(v) {
    this.value = div(this.value, v);
    return this;
  },
  mul(v) {
    this.value = mul(this.value, v);
    return this;
  }
});

export default function(value) {
  return new Compute(value);
}

dialog.js


import {
  Confirm as confirm,
  Alert as alert,
  Toast as toast,
  Notify as notify,
  Loading as loading
} from "vue-ydui/dist/lib.rem/dialog";

const dialog = {
  confirm,
  alert,
  toast,
  notify,
  loading
};

const icons = { error: "操作失败", success: "操作成功" };
Object.keys(icons).reduce((dialog, key) => {
  dialog[key] = (mes, obj = {}) => {
    return new Promise(function(resolve) {
      toast({
        mes: mes || icons[key],
        timeout: 1000,
        icon: key,
        callback: () => {
          resolve();
        },
        ...obj
      });
    });
  };
  return dialog;
}, dialog);

dialog.message = (mes = "操作失败", obj = {}) => {
  return new Promise(function(resolve) {
    toast({
      mes,
      timeout: 1000,
      callback: () => {
        resolve();
      },
      ...obj
    });
  });
};

dialog.validateError = (...args) => {
  validatorDefaultCatch(...args);
};

export function validatorDefaultCatch(err, type = "message") {
  return dialog[type](err.errors[0].message);
}

export default dialog;

emoji.js


export default [
  "em-smile",
  "em-laughing",
  "em-blush",
  "em-smiley",
  "em-relaxed",
  "em-smirk",
  "em-heart_eyes",
  "em-kissing_heart",
  "em-kissing_closed_eyes",
  "em-flushed",
  "em-relieved",
  "em-satisfied",
  "em-grin",
  "em-wink",
  "em-stuck_out_tongue_winking_eye",
  "em-stuck_out_tongue_closed_eyes",
  "em-grinning",
  "em-kissing",
  "em-kissing_smiling_eyes",
  "em-stuck_out_tongue",
  "em-sleeping",
  "em-worried",
  "em-frowning",
  "em-anguished",
  "em-open_mouth",
  "em-grimacing",
  "em-confused",
  "em-hushed",
  "em-expressionless",
  "em-unamused",
  "em-sweat_smile",
  "em-sweat",
  "em-disappointed_relieved",
  "em-weary",
  "em-pensive",
  "em-disappointed",
  "em-confounded",
  "em-fearful",
  "em-cold_sweat",
  "em-persevere",
  "em-cry",
  "em-sob",
  "em-joy",
  "em-astonished",
  "em-scream",
  "em-tired_face",
  "em-angry",
  "em-rage",
  "em-triumph",
  "em-sleepy",
  "em-yum",
  "em-mask",
  "em-sunglasses",
  "em-dizzy_face",
  "em-imp",
  "em-smiling_imp",
  "em-neutral_face",
  "em-no_mouth",
  "em-innocent",
  "em-alien"
];

index.js


export function trim(str) {
  return String.prototype.trim.call(str);
}

export function isType(arg, type) {
  return Object.prototype.toString.call(arg) === "[object " + type + "]";
}

export function isWeixin() {
  return navigator.userAgent.toLowerCase().indexOf("micromessenger") !== -1;
}

export function parseQuery() {
  const res = {};

  const query = (location.href.split("?")[1] || "")
    .trim()
    .replace(/^(\?|#|&)/, "");

  if (!query) {
    return res;
  }

  query.split("&").forEach(param => {
    const parts = param.replace(/\+/g, " ").split("=");
    const key = decodeURIComponent(parts.shift());
    const val = parts.length > 0 ? decodeURIComponent(parts.join("=")) : null;

    if (res[key] === undefined) {
      res[key] = val;
    } else if (Array.isArray(res[key])) {
      res[key].push(val);
    } else {
      res[key] = [res[key], val];
    }
  });

  return res;
}

const VUE_APP_API_URL = process.env.VUE_APP_API_URL || `${location.origin}/api`;
const VUE_APP_WS_URL =
  process.env.VUE_APP_WS_URL || `ws:${location.hostname}:20003`;

export { VUE_APP_API_URL, VUE_APP_WS_URL };

loading.js


const events = [];

const $scroll = function(dom, fn) {
  events.push({ dom, fn });
  fn._index = events.length - 1;
};

$scroll.remove = function(fn) {
  fn._index && events.splice(fn._index, 1);
};

//上拉加载;
const Scroll = {
  addHandler: function(element, type, handler) {
    if (element.addEventListener)
      element.addEventListener(type, handler, false);
    else if (element.attachEvent) element.attachEvent("on" + type, handler);
    else element["on" + type] = handler;
  },
  listenTouchDirection: function() {
    this.addHandler(window, "scroll", function() {
      const wh = window.innerHeight,
        st = window.scrollY;
      events
        .filter(e => e.dom.scrollHeight && e.dom.scrollHeight > 0)
        .forEach(e => {
          var dh = e.dom.scrollHeight;
          var s = Math.ceil((st / (dh - wh)) * 100);
          if (s > 85) e.fn();
        });
    });
  }
};

Scroll.listenTouchDirection();

export default $scroll;
export { Scroll };

request.js


import axios from "axios";
import $store from "../store";
import toLogin from "@libs/login";
import { VUE_APP_API_URL } from "@utils/index";

const instance = axios.create({
  baseURL: VUE_APP_API_URL,
  timeout: 5000
});

const defaultOpt = { login: true };

function baseRequest(options) {
  const token = $store.state.app.token;
  const headers = options.headers || {};
  headers["Authori-zation"] = "Bearer " + token;
  options.headers = headers;
  if (options.login && !token) {
    toLogin();
    return Promise.reject({ msg: "未登录", toLogin: true });
  }
  console.log(options);
  return instance(options).then(res => {
    const data = res.data || {};

    if (res.status !== 200)
      return Promise.reject({ msg: "请求失败", res, data });

    if ([410000, 410001, 410002].indexOf(data.status) !== -1) {
      toLogin();
      return Promise.reject({ msg: res.data.msg, res, data, toLogin: true });
    } else if (data.status === 200) {
      return Promise.resolve(data, res);
    } else {
      return Promise.reject({ msg: res.data.msg, res, data });
    }
  });
}

/**
 * http 请求基础类
 * 参考文档 https://www.kancloud.cn/yunye/axios/234845
 *
 */
const request = ["post", "put", "patch"].reduce((request, method) => {
  /**
   *
   * @param url string 接口地址
   * @param data object get参数
   * @param options object axios 配置项
   * @returns {AxiosPromise}
   */
  request[method] = (url, data = {}, options = {}) => {
    return baseRequest(
      Object.assign({ url, data, method }, defaultOpt, options)
    );
  };
  return request;
}, {});

["get", "delete", "head"].forEach(method => {
  /**
   *
   * @param url string 接口地址
   * @param params object get参数
   * @param options object axios 配置项
   * @returns {AxiosPromise}
   */
  request[method] = (url, params = {}, options = {}) => {
    return baseRequest(
      Object.assign({ url, params, method }, defaultOpt, options)
    );
  };
});

export default request;

store

cookie.js

import { trim, isType } from "@utils";

const doc = window.document;

function get(key) {
  if (!key || !_has(key)) {
    return null;
  }
  let regexpStr =
    "(?:^|.*;\\s*)" +
    escape(key).replace(/[-.+*]/g, "\\$&") +
    "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*";
  return JSON.parse(unescape(doc.cookie.replace(new RegExp(regexpStr), "$1")));
}

function all() {
  let cookies = doc.cookie.split(/; ?/g),
    data = {};
  for (let i = cookies.length - 1; i >= 0; i--) {
    if (!trim(cookies[i])) {
      continue;
    }
    let kvp = cookies[i].split("=");
    let key = unescape(kvp[0]);
    data[key] = unescape(kvp[1]);
  }
  return data;
}

function set(key, data, time) {
  if (!key) {
    return;
  }
  let expires = "Tue, 19 Jan 2038 03:14:07 GMT";
  if (time) {
    let date;
    if (isType(time, "Date")) {
      date = time;
    } else {
      date = new Date();
      date.setTime(date.getTime() + time * 60000);
    }
    expires = date.toGMTString();
  }

  data = JSON.stringify(data);
  doc.cookie =
    escape(key) + "=" + escape(data) + "; expires=" + expires + "; path=/";
}

function remove(key) {
  if (!key || !_has(key)) {
    return;
  }
  doc.cookie = escape(key) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
}

function clearAll() {
  Object.keys(all()).forEach(function(key) {
    remove(key);
  });
}

function _has(key) {
  return new RegExp(
    "(?:^|;\\s*)" + escape(key).replace(/[-.+*]/g, "\\$&") + "\\s*\\="
  ).test(doc.cookie);
}

export default {
  get,
  all,
  set,
  remove,
  clearAll,
  has: _has
};

index.js

import cookie from "./cookie";
import localStorage from "./localStorage";

export default {
  cookie,
  localStorage
};

localStorage.js

function localStorage() {
  return window.localStorage;
}

function get(key) {
  return JSON.parse(localStorage().getItem(key));
}

function set(key, data) {
  return localStorage().setItem(key, JSON.stringify(data));
}

function all() {
  const data = {};
  for (var i = localStorage().length - 1; i >= 0; i--) {
    var key = localStorage().key(i);
    data[key] = get(key);
  }

  return data;
}

function remove(key) {
  return localStorage().removeItem(key);
}

function clearAll() {
  return localStorage().clear();
}

function has(key) {
  return localStorage().getItem(key) !== null;
}

export default {
  get,
  set,
  all,
  remove,
  clearAll,
  has
};

validate.js


const bindMessage = (fn, message) => {
  fn.message = field => message.replace("%s", field || "");
};

export function required(message, opt = {}) {
  return {
    required: true,
    message,
    type: "string",
    ...opt
  };
}

bindMessage(required, "请输入%s");

export function url(message, opt = {}) {
  return {
    type: "url",
    message,
    ...opt
  };
}

bindMessage(url, "请输入正确的链接");

export function email(message, opt = {}) {
  return {
    type: "email",
    message,
    ...opt
  };
}

bindMessage(email, "请输入正确的邮箱地址");

/**
 * 验证字段必须完全由字母构成。
 *
 * @param message
 * @returns {*}
 */
export function alpha(message) {
  return attrs.pattern(/^[\w]+$/, message);
}

bindMessage(alpha, "%s必须是字母");

/**
 * 只能包含由字母、数字,以及 - 和 _
 *
 * @param message
 * @returns {*}
 */
export function alpha_dash(message) {
  return attrs.pattern(/^[\w\d_-]+$/, message);
}

bindMessage(alpha_dash, "%s只能包含由字母、数字,以及 - 和 _");

/**
 * 必须是完全是字母、数字
 *
 * @param message
 * @returns {*}
 */
export function alpha_num(message) {
  return attrs.pattern(/^[\w\d]+$/, message);
}

bindMessage(alpha_num, "%s只能包含字母、数字");
/**
 * 正确的金额
 *
 * @param message
 * @returns {*}
 */
export function num(message) {
  return attrs.pattern(
    /(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/,
    message
  );
}

bindMessage(num, "%s格式不正确");

/**
 * 只能是汉字
 * @param message
 * @returns {*}
 */
export function chs(message) {
  return attrs.pattern(/^[\u4e00-\u9fa5]+$/, message);
}

bindMessage(chs, "%s只能是汉字");

/**
 * 只能包含汉字、字母
 * @param message
 * @returns {*}
 */
export function chs_alpha(message) {
  return attrs.pattern(/^[\u4e00-\u9fa5\w]+$/, message);
}

bindMessage(chs_alpha, "%s只能包含汉字、字母");

/**
 * 只能包含汉字、字母和数字
 * @param message
 * @returns {*}
 */
export function chs_alpha_num(message) {
  return attrs.pattern(/^[\u4e00-\u9fa5\w\d]+$/, message);
}

bindMessage(chs_alpha_num, "%s只能包含汉字、字母和数字");

/**
 * 只能包含由汉字、字母、数字,以及 - 和 _
 * @param message
 * @returns {*}
 */
export function chs_dash(message) {
  return attrs.pattern(/^[\u4e00-\u9fa5\w\d-_]+$/, message);
}

bindMessage(chs_dash, "%s只能包含由汉字、字母、数字,以及 - 和 _");

/**
 * 手机号验证
 * @param message
 * @returns {*}
 */
export function chs_phone(message) {
  return attrs.pattern(/^1(3|4|5|7|8|9|6)\d{9}$/i, message);
}
bindMessage(chs_phone, "请输入正确的手机号码");

const baseAttr = {
  min: "%s最小长度为:min",
  max: "%s最大长度为:max",
  length: "%s长度必须为:length",
  range: "%s长度为:range",
  pattern: "$s格式错误"
};

const attrs = Object.keys(baseAttr).reduce((attrs, key) => {
  attrs[key] = (attr, message = "", opt = {}) => {
    const _attr =
      key === "range" ? { min: attr[0], max: attr[1] } : { [key]: attr };

    return {
      message: message.replace(
        `:${key}`,
        key === "range" ? `${attr[0]}-${attr[1]}` : attr
      ),
      type: "string",
      ..._attr,
      ...opt
    };
  };
  bindMessage(attrs[key], baseAttr[key]);
  return attrs;
}, {});

export default attrs;

views

activity

GoodsSeckill.vue

<template>
  <div class="flash-sale" ref="container">
    <div class="header" v-if="headerImg"><img :src="headerImg" /></div>
    <Tabs
      class="time-tabs"
      line-height="0"
      v-model="active"
      animated
      title-inactive-color="2"
      sticky
      ref="timeList"
    >
      <Tab v-for="(item, index) in timeList" :key="index">
        <div slot="title" class="timeItem" @click="setTime(index)">
          <div class="time">{{ item.time }}</div>
          <div class="state">{{ item.state }}</div>
        </div>
        <div class="countDown font-color-red acea-row row-center-wrapper">
          <div v-if="item.status === 0" class="activity">活动已结束</div>
          <CountDown
            :is-day="false"
            :tip-text="'距结束仅剩 '"
            :day-text="''"
            :hour-text="' : '"
            :minute-text="' : '"
            :second-text="''"
            :datatime="datatime"
            v-if="item.status === 1"
          ></CountDown>
          <div v-if="item.status === 2" class="activity">活动即将开始</div>
        </div>
        <div class="list">
          <div
            class="item acea-row row-between-wrapper"
            v-for="(itemSeckill, indexSeckill) in seckillList"
            :key="indexSeckill"
          >
            <div class="pictrue">
              <img :src="itemSeckill.image" />
            </div>
            <div class="text acea-row row-column-around">
              <div class="line1" v-text="itemSeckill.title"></div>
              <div class="money">
                限时价<span
                  class="num font-color-red"
                  v-text="'¥' + itemSeckill.price"
                ></span>
              </div>
              <div class="progress cart-color">
                <div
                  class="bg-red"
                  :style="{ width: loading ? itemSeckill.percent + '%' : '' }"
                ></div>
                <div
                  class="piece font-color-red"
                  v-text="'仅剩' + itemSeckill.stock + '件'"
                ></div>
              </div>
            </div>
            <div
              class="grab bg-color-red"
              v-if="item.status === 1 && itemSeckill.stock > 0"
              @click="goDetail(itemSeckill.id)"
            >
              马上抢
            </div>
            <div
              class="grab"
              v-if="item.status === 1 && itemSeckill.stock <= 0"
            >
              已售磬
            </div>
            <div class="grab bg-color-red" v-if="item.status === 2">
              即将开始
            </div>
            <div class="grab bg-color-red" v-if="item.status === 0">已结束</div>
          </div>
        </div>
        <div
          class="noCommodity"
          v-cloak
          style="background-color: #fff;"
          v-if="seckillList.length === 0 && page > 1"
        >
          <div class="noPictrue">
            <img src="@assets/images/noGood.png" class="image" />
          </div>
        </div>
        <Loading
          :loaded="status"
          :loading="loadingList"
          v-if="seckillList.length > 0"
        ></Loading>
      </Tab>
    </Tabs>
  </div>
</template>
<script>
import { getSeckillConfig, getSeckillList } from "@api/activity";
import CountDown from "@components/CountDown";
import { Tab, Tabs } from "vant";
import Loading from "@components/Loading";

export default {
  name: "GoodsSeckill",
  components: {
    CountDown,
    Tab,
    Tabs,
    Loading
  },
  props: {},
  data: function() {
    return {
      headerImg: "",
      timeList: [],
      sticky: false,
      loading: false,
      datatime: 0,
      active: 0,
      seckillList: [],
      status: false, //砍价列表是否获取完成 false 未完成 true 完成
      loadingList: false, //当前接口是否请求完成 false 完成 true 未完成
      page: 1, //页码
      limit: 5 //数量
    };
  },
  mounted: function() {
    this.mountedStart();
  },
  methods: {
    mountedStart: function() {
      var that = this;
      getSeckillConfig().then(res => {
        that.$set(that, "headerImg", res.data.lovely);
        that.$set(that, "timeList", res.data.seckillTime);
        that.$set(that, "active", res.data.seckillTimeIndex);
        that.datatime = that.timeList[that.active].stop;
        that.getSeckillList();
        that.$nextTick(function() {
          that.sticky = true;
          that.$refs.timeList.scrollIntoView();
        });
      });
      this.$scroll(this.$refs.container, () => {
        !this.loadingList && this.getSeckillList();
      });
      setTimeout(function() {
        that.loading = true;
      }, 500);
    },
    setTime: function(index) {
      var that = this;
      that.active = index;
      that.datatime = that.timeList[that.active].stop;
      that.getSeckillList();
    },
    getSeckillList: function() {
      var that = this;
      if (that.loadingList) return;
      if (that.status) return;
      var time = that.timeList[that.active].id;
      getSeckillList(time, { page: that.page, limit: that.limit }).then(res => {
        that.status = res.data.length < that.limit;
        that.seckillList.push.apply(that.seckillList, res.data);
        that.page++;
        that.loadingList = false;
      });
    },
    goDetail: function(id) {
      var that = this;
      var time = that.timeList[that.active].stop;
      this.$router.push({
        path: "/activity/seckill_detail/" + id + "/" + time
      });
    }
  }
};
</script>
<style scoped>
.timeItem {
  font-size: 0.22rem;
  color: #282828;
  width: 100%;
  text-align: center;
  padding: 0.11rem 0;
  height: 0.96rem;
  background-color: #efc58f;
}
.time-tabs.van-tabs--line {
  padding: 0;
}
.timeItem .time {
  font-size: 0.32rem;
  font-weight: bold;
  height: 0.37rem;
  line-height: 0.37rem;
}
.timeItem .state {
  height: 0.37rem;
  line-height: 0.37rem;
}
.activity {
  color: #333;
}
.flash-sale .list .item .grab {
  background-color: #999;
}
</style>

SeckillDetails.vue

<template>
  <div
    :class="[posterImageStatus ? 'noscroll product-con' : 'product-con']"
    v-show="domStatus"
  >
    <ProductConSwiper :imgUrls="imgUrls"></ProductConSwiper>
    <div class="nav acea-row row-between-wrapper">
      <div class="money">
        ¥<span class="num" v-text="storeInfo.price"></span
        ><span class="y-money" v-text="'¥' + storeInfo.ot_price"></span>
      </div>
      <div class="acea-row row-middle">
        <div class="times">
          <div>距秒杀结束仅剩</div>
          <CountDown
            :is-day="false"
            :tip-text="''"
            :day-text="''"
            :hour-text="' : '"
            :minute-text="' : '"
            :second-text="''"
            :datatime="datatime"
          ></CountDown>
        </div>
        <div class="iconfont icon-jiantou"></div>
      </div>
    </div>
    <div class="wrapperRush">
      <div class="introduce acea-row row-between">
        <div class="infor" v-text="storeInfo.title"></div>
        <div class="iconfont icon-fenxiang" @click="setPosterImageStatus"></div>
      </div>
      <div class="label acea-row row-middle">
        <div class="stock" v-text="'库存:' + storeInfo.stock + '件'"></div>
        <div v-text="'销量:' + storeInfo.sales + '件'"></div>
      </div>
    </div>
    <div class="product-intro">
      <div class="title">产品介绍</div>
      <div class="conter" v-html="storeInfo.description"></div>
    </div>
    <div style="height:1.2rem;"></div>
    <div class="footerRush acea-row row-between-wrapper">
      <div
        class="customerSer acea-row row-center-wrapper row-column"
        @click="$router.push({ path: '/customer/list' })"
      >
        <div class="iconfont icon-kefu"></div>
        <div>客服</div>
      </div>
      <div class="bnt bg-color-red" @click="tapBuy">立即购买</div>
    </div>
    <ProductWindow v-on:changeFun="changeFun" :attr="attr"></ProductWindow>
    <StorePoster
      v-on:setPosterImageStatus="setPosterImageStatus"
      :posterImageStatus="posterImageStatus"
      :posterData="posterData"
    ></StorePoster>
  </div>
</template>
<style scoped>
.noscroll {
  height: 100%;
  overflow: hidden;
}
</style>
<script>
import ProductConSwiper from "@components/ProductConSwiper";
import CountDown from "@components/CountDown";
import ProductWindow from "@components/ProductWindow";
import StorePoster from "@components/StorePoster";
import { getSeckillDetail } from "@api/activity";
import { postCartAdd } from "@api/store";
import { imageBase64 } from "@api/public";
import { isWeixin } from "@utils/index";
import { openShareAll } from "@libs/wechat";

const NAME = "SeckillDetails";

export default {
  name: "SeckillDetails",
  components: {
    ProductConSwiper,
    CountDown,
    ProductWindow,
    StorePoster
  },
  props: {},
  data: function() {
    return {
      domStatus: false,
      posterData: {
        image: "",
        title: "",
        price: "",
        code: ""
      },
      posterImageStatus: false,
      action: "",
      imgUrls: [],
      storeInfo: [],
      replyCount: 0,
      reply: [],
      cartNum: 1,
      attr: {
        cartAttr: false,
        productSelect: {
          image: "",
          store_name: "",
          price: "",
          stock: "",
          unique: "",
          cart_num: 1
        }
      },
      datatime: 0
    };
  },
  watch: {
    $route: function(n) {
      var that = this;
      console.log(n);
      if (n.name === NAME) {
        that.mountedStart();
      }
    }
  },
  mounted: function() {
    this.mountedStart();
  },
  methods: {
    mountedStart: function() {
      var that = this;
      let id = that.$route.params.id;
      that.datatime = parseInt(that.$route.params.time);
      getSeckillDetail(id).then(res => {
        that.$set(that, "storeInfo", res.data.storeInfo);
        that.$set(that, "imgUrls", res.data.storeInfo.images);
        that.$set(that, "replyCount", res.data.replyCount);
        that.$set(that, "reply", res.data.reply);
        that.posterData.image = that.storeInfo.image_base;
        that.updateTitle();
        if (that.storeInfo.title.length > 30) {
          that.posterData.title = that.storeInfo.title.substring(0, 30) + "...";
        } else {
          that.posterData.title = that.storeInfo.title;
        }
        that.posterData.price = that.storeInfo.price;
        that.posterData.code = that.storeInfo.code_base;
        that.setProductSelect();
        that.domStatus = true;
        that.getImageBase64();
        that.setShare();
      });
    },
    setShare: function() {
      isWeixin() &&
        openShareAll({
          desc: this.storeInfo.info,
          title: this.storeInfo.title,
          link: location.href,
          imgUrl: this.storeInfo.image
        });
    },
    getImageBase64: function() {
      let that = this;
      imageBase64(this.posterData.image, that.posterData.code).then(res => {
        that.posterData.image = res.data.image;
        that.posterData.code = res.data.code;
      });
    },
    updateTitle() {
      document.title = this.storeInfo.title || this.$route.meta.title;
    },
    setPosterImageStatus: function() {
      var sTop = document.body || document.documentElement;
      sTop.scrollTop = 0;
      this.posterImageStatus = !this.posterImageStatus;
    },
    //将父级向子集多次传送的函数合二为一;
    changeFun: function(opt) {
      if (typeof opt !== "object") opt = {};
      let action = opt.action || "";
      let value = opt.value === undefined ? "" : opt.value;
      this[action] && this[action](value);
    },
    changeattr: function(res) {
      var that = this;
      that.attr.cartAttr = res;
    },
    ChangeCartNum: function(res) {
      var that = this;
      if (res) {
        if (that.attr.productSelect.cart_num < that.storeInfo.stock) {
          that.attr.productSelect.cart_num++;
        }
      } else {
        if (that.attr.productSelect.cart_num > 1) {
          that.attr.productSelect.cart_num--;
        }
      }
    },
    setProductSelect: function() {
      var that = this;
      var attr = that.attr;
      attr.productSelect.image = that.storeInfo.image;
      attr.productSelect.store_name = that.storeInfo.title;
      attr.productSelect.price = that.storeInfo.price;
      attr.productSelect.stock = that.storeInfo.stock;
      attr.cartAttr = false;
      that.$set(that, "attr", attr);
    },
    selecAttrTap: function() {
      this.cartAttr = true;
    },
    tapBuy: function() {
      var that = this;
      if (that.attr.cartAttr == false) {
        that.attr.cartAttr = !this.attr.attrcartAttr;
      } else {
        var data = {};
        data.productId = that.storeInfo.product_id;
        data.cartNum = that.attr.productSelect.cart_num;
        data.uniqueId = that.attr.productSelect.unique;
        data.secKillId = that.storeInfo.id;
        data.new = 1;
        postCartAdd(data)
          .then(res => {
            that.$router.push({
              path: "/order/submit/" + res.data.cartId
            });
          })
          .catch(res => {
            this.$dialog.error(res.msg);
          });
      }
    }
  }
};
</script>
<style scoped>
.product-con .nav {
  padding: 0 0.2rem;
}
</style>

home

Index.vue

<template>
  <div class="index" v-cloak>
    <div class="header acea-row row-center-wrapper">
      <div class="logo"><img :src="logoUrl" /></div>
      <router-link :to="'/search'" class="search acea-row row-middle">
        <span class="iconfont icon-xiazai5"></span>搜索商品
      </router-link>
    </div>
    <div class="slider-banner banner">
      <swiper :options="swiperOption" v-if="banner.length > 0">
        <swiper-slide v-for="(item, index) in banner" :key="index">
          <router-link
            :to="item.wap_url ? item.wap_url : ''"
            class="search acea-row row-middle"
          >
            <img :src="item.pic" />
          </router-link>
        </swiper-slide>
        <div class="swiper-pagination paginationBanner" slot="pagination"></div>
      </swiper>
    </div>
    <div class="nav acea-row">
      <router-link
        :to="item.wap_url ? item.wap_url : ''"
        class="item"
        v-for="(item, index) in menus"
        :key="index"
      >
        <div class="pictrue"><img :src="item.pic" /></div>
        <div>{{ item.name }}</div>
      </router-link>
    </div>
    <div class="news acea-row row-between-wrapper">
      <div class="pictrue"><img src="@assets/images/news.png" /></div>
      <div class="swiper-no-swiping new-banner">
        <swiper
          class="swiper-wrapper"
          :options="swiperRoll"
          v-if="roll.length > 0"
        >
          <swiper-slide
            class="swiper-slide"
            v-for="(item, index) in roll"
            :key="index"
          >
            <router-link
              :to="item.wap_url ? item.wap_url : ''"
              class="acea-row row-between-wrapper"
            >
              <div class="text acea-row row-between-wrapper">
                <div class="label" v-if="item.show === '是'">最新</div>
                <div class="newsTitle line1">{{ item.info }}</div>
              </div>
              <div class="iconfont icon-xiangyou"></div>
            </router-link>
          </swiper-slide>
        </swiper>
      </div>
    </div>
    <div
      class="specialArea acea-row row-between-wrapper"
      v-if="activityOne.wap_link !== undefined || activity.length"
    >
      <router-link
        :to="activityOne.wap_link ? activityOne.wap_link : ''"
        v-if="activityOne.wap_link !== undefined"
        class="assemble"
      >
        <img :src="activityOne.pic" />
        <div class="text">
          <div class="name">{{ activityOne.title }}</div>
          <div class="infor">{{ activityOne.info }}</div>
        </div>
      </router-link>
      <div class="list acea-row row-column-between">
        <router-link
          :to="item.wap_link ? item.wap_link : ''"
          class="item"
          v-for="(item, index) in activity"
          :key="index"
        >
          <img :src="item.pic" />
          <div class="text">
            <div class="name">{{ item.title }}</div>
            <div class="infor">{{ item.info }}</div>
          </div>
        </router-link>
      </div>
    </div>
    <div class="wrapper" v-if="info.fastList.length > 0">
      <div class="title acea-row row-between-wrapper">
        <div class="text">
          <div class="name line1">快速选择</div>
          <div class="line1">{{ info.fastInfo }}</div>
        </div>
        <router-link :to="'/category'" class="more"
          >更多<span class="iconfont icon-jiantou"></span
        ></router-link>
      </div>
      <div class="scroll-product">
        <swiper class="swiper-wrapper" :options="swiperScroll">
          <swiper-slide
            v-for="(item, index) in info.fastList"
            :key="index"
            class="swiper-slide"
          >
            <router-link
              :to="{
                path: '/goods_list',
                query: { id: item.id, title: item.cate_name }
              }"
            >
              <div class="img-box">
                <img :src="item.pic" />
              </div>
              <div class="pro-info line1">{{ item.cate_name }}</div>
            </router-link>
          </swiper-slide>
        </swiper>
      </div>
    </div>
    <div
      class="wrapper"
      v-if="info.bastList.length > 0 || info.bastBanner.length > 0"
    >
      <div class="title acea-row row-between-wrapper">
        <div class="text">
          <div class="name line1">精品推荐</div>
          <div class="line1">{{ info.bastInfo }}</div>
        </div>
        <router-link :to="{ path: '/hot_new_goods/' + 1 }" class="more"
          >更多<span class="iconfont icon-jiantou"></span
        ></router-link>
      </div>
      <div class="slider-banner boutique">
        <swiper class="swiper-wrapper" :options="swiperBoutique">
          <swiper-slide
            class="swiper-slide"
            v-for="(item, index) in info.bastBanner"
            :key="index"
          >
            <router-link :to="item.wap_link ? item.wap_link : ''"
              ><img :src="item.img"
            /></router-link>
          </swiper-slide>
        </swiper>
        <div class="swiper-pagination paginationBoutique"></div>
      </div>
      <Good-list :good-list="info.bastList" :is-sort="false"></Good-list>
    </div>
    <div class="hotList" v-if="likeInfo.length > 0">
      <div class="hot-bg">
        <div class="title acea-row row-between-wrapper">
          <div class="text line1">
            <span class="label">热门榜单</span>根据销量、搜索、好评等综合得出
          </div>
          <router-link :to="{ path: '/hot_new_goods/' + 2 }" class="more">
            更多<span class="iconfont icon-jiantou"></span>
          </router-link>
        </div>
      </div>
      <div class="list acea-row row-middle">
        <router-link
          :to="{ path: '/detail/' + item.id }"
          class="item"
          v-for="(item, index) in likeInfo"
          :key="index"
        >
          <div class="pictrue">
            <img :src="item.image" />
            <img
              src="@assets/images/one.png"
              class="numPic"
              v-if="index === 0"
            />
            <img
              src="@assets/images/two.png"
              class="numPic"
              v-else-if="index === 1"
            />
            <img
              src="@assets/images/three.png"
              class="numPic"
              v-else-if="index === 2"
            />
          </div>
          <div class="name line1">{{ item.store_name }}</div>
          <div class="money font-color-red">
            ¥<span class="num">{{ item.price }}</span>
          </div>
        </router-link>
      </div>
    </div>
    <div v-if="lovely.img">
      <div class="adver">
        <img :src="lovely.img" />
      </div>
    </div>
    <div class="wrapper" v-if="info.firstList.length > 0">
      <div class="title acea-row row-between-wrapper">
        <div class="text">
          <div class="name line1">
            首发新品<span class="new font-color-red">NEW~</span>
          </div>
          <div class="line1">{{ info.firstInfo }}</div>
        </div>
        <router-link :to="{ path: '/hot_new_goods/' + 3 }" class="more"
          >更多<span class="iconfont icon-jiantou"></span
        ></router-link>
      </div>
      <div class="newProducts">
        <swiper class="swiper-wrapper" :options="swiperProducts">
          <swiper-slide
            class="swiper-slide"
            v-for="(item, index) in info.firstList"
            :key="index"
          >
            <router-link :to="{ path: '/detail/' + item.id }">
              <div class="img-box">
                <img :src="item.image" />
              </div>
              <div class="pro-info line1">{{ item.store_name }}</div>
              <div class="money font-color-red">¥{{ item.price }}</div>
            </router-link>
          </swiper-slide>
        </swiper>
      </div>
    </div>
    <div class="wrapper" v-if="benefit.length > 0">
      <div class="title acea-row row-between-wrapper">
        <div class="text">
          <div class="name line1">促销单品</div>
          <div class="line1">{{ info.salesInfo }}</div>
        </div>
        <router-link :to="'/promotion'" class="more"
          >更多<span class="iconfont icon-jiantou"></span
        ></router-link>
      </div>
    </div>
    <Promotion-good :benefit="benefit"></Promotion-good>
    <Coupon-window
      :coupon-list="couponList"
      v-if="showCoupon"
      @checked="couponClose"
      @close="couponClose"
    ></Coupon-window>
    <div style="height:1.2rem;"></div>
  </div>
</template>
<script>
import { swiper, swiperSlide } from "vue-awesome-swiper";
import "@assets/css/swiper.min.css";
import GoodList from "@components/GoodList";
import PromotionGood from "@components/PromotionGood";
import CouponWindow from "@components/CouponWindow";
import { getHomeData, getShare } from "@api/public";
import cookie from "@utils/store/cookie";
import { openShareAll } from "@libs/wechat";
import { isWeixin } from "@utils/index";

const HAS_COUPON_WINDOW = "has_coupon_window";

export default {
  name: "Index",
  components: {
    swiper,
    swiperSlide,
    GoodList,
    PromotionGood,
    CouponWindow
  },
  props: {},
  data: function() {
    return {
      showCoupon: false,
      logoUrl: "",
      banner: [],
      menus: [],
      roll: [],
      activity: [],
      activityOne: {},
      info: {
        fastList: [],
        bastBanner: [],
        firstList: [],
        bastList: []
      },
      likeInfo: [],
      lovely: [],
      benefit: [],
      couponList: [],
      swiperOption: {
        pagination: {
          el: ".paginationBanner",
          clickable: true
        },
        autoplay: {
          disableOnInteraction: false,
          delay: 2000
        },
        loop: true,
        speed: 1000,
        observer: true,
        observeParents: true
      },
      swiperRoll: {
        direction: "vertical",
        autoplay: {
          disableOnInteraction: false,
          delay: 2000
        },
        loop: true,
        speed: 1000,
        observer: true,
        observeParents: true
      },
      swiperScroll: {
        freeMode: true,
        freeModeMomentum: false,
        slidesPerView: "auto",
        observer: true,
        observeParents: true
      },
      swiperBoutique: {
        pagination: {
          el: ".paginationBoutique",
          clickable: true
        },
        autoplay: {
          disableOnInteraction: false,
          delay: 2000
        },
        loop: true,
        speed: 1000,
        observer: true,
        observeParents: true
      },
      swiperProducts: {
        freeMode: true,
        freeModeMomentum: false,
        slidesPerView: "auto",
        observer: true,
        observeParents: true
      }
    };
  },
  mounted: function() {
    let that = this;
    getHomeData().then(res => {
      that.logoUrl = res.data.logoUrl;
      that.$set(that, "banner", res.data.banner);
      that.$set(that, "menus", res.data.menus);
      that.$set(that, "roll", res.data.roll);
      that.$set(that, "activity", res.data.activity);
      if (res.data.activity.length) {
        var activityOne = res.data.activity.shift();
        that.$set(that, "activityOne", activityOne);
      }
      that.$set(that, "info", res.data.info);
      that.$set(that, "likeInfo", res.data.likeInfo);
      that.$set(
        that,
        "lovely",
        res.data.lovely.length ? res.data.lovely[0] : {}
      );
      that.$set(that, "benefit", res.data.benefit);
      that.$set(that, "couponList", res.data.couponList);
      that.setOpenShare();
      this.showCoupon =
        !cookie.has(HAS_COUPON_WINDOW) &&
        res.data.couponList.some(coupon => coupon.is_use);
    });
  },
  methods: {
    couponClose() {
      cookie.set(HAS_COUPON_WINDOW, 1);
    },
    setOpenShare: function() {
      if (isWeixin()) {
        getShare().then(res => {
          var data = res.data.data;
          var configAppMessage = {
            desc: data.synopsis,
            title: data.title,
            link: location.href,
            imgUrl: data.img
          };
          openShareAll(configAppMessage);
        });
      }
    }
  }
};
</script>
<style scoped>
.index {
  background-color: #fff;
}
</style>

Loading.vue


<template>
  <div class="lottie-bg">
    <div id="lottie">
      <img
        src="@assets/images/live-logo.gif"
        rel="preload"
        style="width: 100%;"
      />
    </div>
  </div>
</template>

<script>
import { auth } from "@libs/wechat";

export default {
  name: "Loading",
  mounted() {
    const { code, state } = this.$route.query;
    auth(code, state)
      .then(() => {
        // location.replace(
        //   decodeURIComponent(decodeURIComponent(this.$route.params.url))
        // );
        location.href = decodeURIComponent(
          decodeURIComponent(this.$route.params.url)
        );
      })
      .catch(() => {
        location.replace("/");
      });
  }
};
</script>

<style scoped>
.lottie-bg {
  position: fixed;
  left: 0;
  top: 0;
  background-color: #fff;
  width: 100%;
  height: 100%;
  z-index: 999;
  display: -webkit-flex;
  display: flex;
  -webkit-align-items: center;
  align-items: center;
  -webkit-justify-content: center;
  justify-content: center;
}

#lottie {
  width: 35%;
  display: block;
  overflow: hidden;
  transform: translate3d(0, 0, 0);
  margin: auto;
}
</style>

NotDefined.vue


<template>
  <div class="not-defined">
    <img src="@assets/images/404.png" />

    <div class="content">
      <h3 class="title">页面未找到</h3>
      <span
        >抱歉!您访问的页面不存在,请返回上一级或点击下方按钮返回首页...</span
      >
    </div>

    <div class="btn" @click="$router.replace({ path: '/' })">
      返回首页
    </div>
  </div>
</template>

<script>
export default {
  name: "NotDefined"
};
</script>

<style scoped>
.not-defined img {
  width: 100%;
  margin-top: 18%;
}

.content {
  padding: 0 1rem;
  text-align: center;
  color: #44405e;
  font-size: 15px;
}

.title {
  margin-bottom: 0.6rem;
  color: #302c48;
  font-size: 20px;
}

.btn {
  color: #fff;
  background-color: #ef4c4c;
  font-size: 16px;
  padding: 0.16rem;
  border-radius: 25px;
  text-align: center;
  width: 2.4rem;
  margin: 0 auto;
  margin-top: 1rem;
}
</style>

order

GoodsReturn.vue

<template>
  <div class="apply-return">
    <div
      class="goodsStyle acea-row row-between"
      v-for="cart in orderInfo.cartInfo"
      :key="cart.id"
    >
      <div class="pictrue">
        <img :src="cart.productInfo.image" class="image" />
      </div>
      <div class="text acea-row row-between">
        <div class="name line2">{{ cart.productInfo.store_name }}</div>
        <div class="money">
          <div>
            ¥{{
              cart.productInfo.attrInfo
                ? cart.productInfo.attrInfo.price
                : cart.productInfo.price
            }}
          </div>
          <div class="num">x{{ cart.cart_num }}</div>
        </div>
      </div>
    </div>
    <div class="list">
      <div class="item acea-row row-between-wrapper">
        <div>退货件数</div>
        <div class="num">{{ orderInfo.total_num }}</div>
      </div>
      <div class="item acea-row row-between-wrapper">
        <div>退款金额</div>
        <div class="num">¥{{ orderInfo.pay_price }}</div>
      </div>
      <div class="item acea-row row-between-wrapper">
        <div>退款原因</div>
        <div class="num acea-row row-left">
          <select v-model="reason">
            <option value="">选择退款原因</option>
            <option
              v-for="(text, index) in reasonList"
              :value="text"
              :key="index"
            >
              {{ text }}
            </option>
          </select>
          <span class="iconfont icon-jiantou"></span>
        </div>
      </div>
      <div class="item textarea acea-row row-between">
        <div>备注说明</div>
        <textarea
          placeholder="填写备注信息,100字以内"
          class="num"
          v-model="refund_reason_wap_explain"
        ></textarea>
      </div>
      <div class="item acea-row row-between">
        <div class="title acea-row row-between-wrapper">
          <div>上传凭证</div>
          <div class="tip">( 最多可上传3张 )</div>
        </div>
        <div class="upload acea-row row-middle">
          <div
            class="pictrue"
            v-for="(img, index) in refund_reason_wap_img"
            :key="img"
          >
            <img :src="img" />
            <div
              class="iconfont icon-guanbi1 font-color-red"
              @click="refund_reason_wap_img.splice(index, 1)"
            ></div>
          </div>
          <VueCoreImageUpload
            class="btn btn-primary"
            :crop="false"
            compress="80"
            @imageuploaded="imageuploaded"
            :headers="headers"
            :max-file-size="5242880"
            :credentials="false"
            inputAccept="image/*"
            inputOfFile="file"
            :url="url"
            v-if="refund_reason_wap_img.length < 3"
          >
            <div class="pictrue acea-row row-center-wrapper row-column">
              <span class="iconfont icon-icon25201"></span>
              <div>上传凭证</div>
            </div>
          </VueCoreImageUpload>
        </div>
      </div>
    </div>
    <div class="returnBnt bg-color-red" @click="submit">申请退款</div>
  </div>
</template>

<script>
import { orderDetail, getRefundReason, postOrderRefund } from "@api/order";
import { trim, VUE_APP_API_URL } from "@utils";
import VueCoreImageUpload from "vue-core-image-upload";

export default {
  name: "goodsReturn",
  components: {
    VueCoreImageUpload
  },
  data() {
    return {
      url: `${VUE_APP_API_URL}/upload/image`,
      headers: {
        "Authori-zation": "Bearer " + this.$store.state.app.token
      },
      id: this.$route.params.id || 0,
      orderInfo: {},
      reasonList: [],
      reason: "",
      refund_reason_wap_explain: "",
      refund_reason_wap_img: []
    };
  },
  methods: {
    imageuploaded(res) {
      if (res.status !== 200)
        return this.$dialog.error(res.msg || "上传图片失败");
      this.refund_reason_wap_img.push(res.data.url);
    },
    getOrderDetail() {
      orderDetail(this.id)
        .then(res => {
          this.orderInfo = res.data;
        })
        .catch(err => {
          this.$dialog.error(err.msg || "获取订单失败");
        });
    },
    getRefundReason() {
      getRefundReason().then(res => {
        this.reasonList = res.data;
      });
    },
    submit() {
      const refund_reason_wap_explain = trim(this.refund_reason_wap_explain),
        text = this.reason;
      if (!text) return this.$dialog.toast({ mes: "请选择退款原因" });
      postOrderRefund({
        text,
        uni: this.orderInfo.order_id,
        refund_reason_wap_img: this.refund_reason_wap_img.join(","),
        refund_reason_wap_explain
      })
        .then(res => {
          this.$dialog.success(res.msg);
          this.$router.go(-1);
        })
        .catch(res => {
          this.$dialog.error(res.msg);
        });
    }
  },
  mounted() {
    this.getOrderDetail();
    this.getRefundReason();
  }
};
</script>

Logistics.vue

<template>
  <div class="logistics">
    <div
      class="header acea-row row-between row-top"
      v-for="cart in cartInfo"
      :key="cart.id"
    >
      <div class="pictrue"><img :src="cart.productInfo.image" /></div>
      <div class="text acea-row row-between">
        <div class="name line2">
          {{ cart.productInfo.store_name }}
        </div>
        <div class="money">
          <div>¥{{ cart.truePrice }}</div>
          <div>x{{ cart.cart_num }}</div>
        </div>
      </div>
    </div>
    <div class="logisticsCon">
      <div class="company acea-row row-between-wrapper">
        <div class="picTxt acea-row row-between-wrapper">
          <div class="iconfont icon-wuliu"></div>
          <div class="text">
            <div>
              <span class="name line1">物流公司:</span>
              {{ orderInfo.delivery_name }}
            </div>
            <div class="express line1">
              <span class="name">快递单号:</span> {{ orderInfo.delivery_id }}
            </div>
          </div>
        </div>
        <div
          class="copy acea-row row-center-wrapper copy-data"
          :data-clipboard-text="orderInfo.delivery_id"
        >
          复制单号
        </div>
      </div>
      <div class="item" v-for="(express, index) in expressList" :key="index">
        <div class="circular" :class="index === 0 ? 'on' : ''"></div>
        <div class="text">
          <div :class="index === 0 ? 'font-color-red' : ''">
            {{ express.status }}
          </div>
          <div class="data">{{ express.time }}</div>
        </div>
      </div>
    </div>
    <div class="no-express" v-if="loaded && !expressList.length">
      <img src="@assets/images/noExpress.png" />
    </div>
    <Recommend></Recommend>
  </div>
</template>
<script>
import Recommend from "@components/Recommend";
import ClipboardJS from "clipboard";
import { express } from "@api/order";

const NAME = "Logistics";

export default {
  name: NAME,
  components: {
    Recommend
  },
  data: function() {
    return {
      id: this.$route.params.id,
      cartInfo: [],
      orderInfo: {},
      expressList: [],
      loaded: false
    };
  },
  watch: {
    $route(n) {
      if (n.name === NAME && this.$route.params.id !== this.id) {
        this.id = this.$route.params.id;
        this.getExpress();
      }
    }
  },
  mounted: function() {
    this.getExpress();
  },
  methods: {
    getExpress() {
      if (!this.id) return this.$dialog.error("订单不存在");
      this.loaded = false;
      express(this.id)
        .then(res => {
          const result = res.data.express.result || {};
          this.cartInfo = res.data.order.cartInfo;
          this.orderInfo = res.data.order;
          this.expressList = result.list || [];
          this.loaded = true;
          this.$nextTick(function() {
            var copybtn = document.getElementsByClassName("copy-data");
            const clipboard = new ClipboardJS(copybtn);
            clipboard.on("success", () => {
              this.$dialog.success("复制成功");
            });
          });
        })
        .catch(e => {
          this.$dialog.error(e.msg || "加载失败");
        });
    }
  }
};
</script>

<style scoped>
.no-express {
  margin: 1.5rem 0;
}

.no-express img {
  width: 6rem;
  margin: 0 auto;
  display: block;
}
</style>

MyOrder.vue

<template>
  <div class="my-order" ref="container">
    <div class="header bg-color-red">
      <div class="picTxt acea-row row-between-wrapper">
        <div class="text">
          <div class="name">订单信息</div>
          <div>
            累计订单:{{ orderData.order_count || 0 }} 总消费:¥{{
              orderData.sum_price || 0
            }}
          </div>
        </div>
        <div class="pictrue"><img src="@assets/images/orderTime.png" /></div>
      </div>
    </div>
    <div class="nav acea-row row-around">
      <div
        class="item"
        :class="{ on: type === 0 }"
        @click="$router.replace({ path: '/order/list/0' })"
      >
        <div>待付款</div>
        <div class="num">{{ orderData.unpaid_count || 0 }}</div>
      </div>
      <div
        class="item"
        :class="{ on: type === 1 }"
        @click="$router.replace({ path: '/order/list/1' })"
      >
        <div>待发货</div>
        <div class="num">{{ orderData.unshipped_count || 0 }}</div>
      </div>
      <div
        class="item"
        :class="{ on: type === 2 }"
        @click="$router.replace({ path: '/order/list/2' })"
      >
        <div>待收货</div>
        <div class="num">{{ orderData.received_count || 0 }}</div>
      </div>
      <div
        class="item"
        :class="{ on: type === 3 }"
        @click="$router.replace({ path: '/order/list/3' })"
      >
        <div>待评价</div>
        <div class="num">{{ orderData.evaluated_count || 0 }}</div>
      </div>
      <div
        class="item"
        :class="{ on: type === 4 }"
        @click="$router.replace({ path: '/order/list/4' })"
      >
        <div>已完成</div>
        <div class="num">{{ orderData.complete_count || 0 }}</div>
      </div>
    </div>
    <div class="list">
      <div class="item" v-for="order in orderList" :key="order.id">
        <div class="title acea-row row-between-wrapper">
          <div class="acea-row row-middle">
            <span
              class="sign cart-color acea-row row-center-wrapper"
              v-if="order.combination_id > 0"
              >拼团</span
            ><span
              class="sign cart-color acea-row row-center-wrapper"
              v-if="order.seckill_id > 0"
              >秒杀</span
            ><span
              class="sign cart-color acea-row row-center-wrapper"
              v-if="order.bargain_id > 0"
              >砍价</span
            >
            {{ order._add_time }}
          </div>
          <div class="font-color-red">{{ getStatus(order) }}</div>
        </div>
        <div @click="$router.push({ path: '/order/detail/' + order.order_id })">
          <div
            class="item-info acea-row row-between row-top"
            v-for="cart in order.cartInfo"
            :key="cart.id"
          >
            <div class="pictrue">
              <img
                :src="cart.productInfo.image"
                @click.stop="
                  $router.push({ path: '/detail/' + cart.productInfo.id })
                "
                v-if="
                  cart.combination_id === 0 &&
                    cart.bargain_id === 0 &&
                    cart.seckill_id === 0
                "
              />
              <img
                :src="cart.productInfo.image"
                @click.stop="
                  $router.push({
                    path: '/activity/group_detail/' + cart.combination_id
                  })
                "
                v-else-if="cart.combination_id > 0"
              />
              <img
                :src="cart.productInfo.image"
                @click.stop="
                  $router.push({
                    path: '/activity/dargain_detail/' + cart.bargain_id
                  })
                "
                v-else-if="cart.bargain_id > 0"
              />
              <img
                :src="cart.productInfo.image"
                @click.stop="
                  $router.push({
                    path: '/activity/seckill_detail/' + cart.seckill_id
                  })
                "
                v-else-if="cart.seckill_id > 0"
              />
            </div>
            <div class="text acea-row row-between">
              <div class="name line2">
                {{ cart.productInfo.store_name }}
              </div>
              <div class="money">
                <div>
                  ¥{{
                    cart.productInfo.attrInfo
                      ? cart.productInfo.attrInfo.price
                      : cart.productInfo.price
                  }}
                </div>
                <div>x{{ cart.cart_num }}</div>
              </div>
            </div>
          </div>
        </div>
        <div class="totalPrice">
          共{{ order.cartInfo.length || 0 }}件商品,总金额
          <span class="money font-color-red">¥{{ order.pay_price }}</span>
        </div>
        <div class="bottom acea-row row-right row-middle">
          <template v-if="order._status._type === 0">
            <div class="bnt cancelBnt" @click="cancelOrder(order)">
              取消订单
            </div>
            <div class="bnt bg-color-red" @click="paymentTap(order)">
              立即付款
            </div>
          </template>
          <template
            v-if="order._status._type === 1 || order._status._type === 9"
          >
            <div
              class="bnt bg-color-red"
              @click="$router.push({ path: '/order/detail/' + order.order_id })"
            >
              查看详情
            </div>
          </template>
          <template v-if="order._status._type === 2">
            <div
              class="bnt default"
              @click="
                $router.push({ path: '/order/logistics/' + order.order_id })
              "
            >
              查看物流
            </div>
            <div class="bnt bg-color-red" @click="takeOrder(order)">
              确认收货
            </div>
          </template>
          <template v-if="order._status._type === 3">
            <div
              class="bnt default"
              @click="
                $router.push({ path: '/order/logistics/' + order.order_id })
              "
              v-if="order.delivery_type === 'express'"
            >
              查看物流
            </div>
            <div
              class="bnt bg-color-red"
              @click="$router.push({ path: '/order/detail/' + order.order_id })"
            >
              去评价
            </div>
          </template>
          <template v-if="order._status._type === 4">
            <div
              class="bnt bg-color-red"
              @click="$router.push({ path: '/order/detail/' + order.order_id })"
            >
              查看订单
            </div>
          </template>
        </div>
      </div>
    </div>
    <div class="noCart" v-if="orderList.length === 0 && page > 1">
      <div class="pictrue"><img src="@assets/images/noOrder.png" /></div>
    </div>
    <Loading :loaded="loaded" :loading="loading"></Loading>
    <Payment
      v-model="pay"
      :types="payType"
      @checked="toPay"
      :balance="userInfo.now_money"
    ></Payment>
  </div>
</template>
<script>
import { getOrderData, getOrderList } from "@api/order";
import {
  cancelOrderHandle,
  payOrderHandle,
  takeOrderHandle
} from "@libs/order";
import Loading from "@components/Loading";
import Payment from "@components/Payment";
import { mapGetters } from "vuex";
import { isWeixin } from "@utils";

const STATUS = [
  "待付款",
  "待发货",
  "待收货",
  "待评价",
  "已完成",
  "",
  "",
  "",
  "",
  "待付款"
];

const NAME = "MyOrder";

export default {
  name: NAME,
  data() {
    return {
      offlinePayStatus: 2,
      orderData: {},
      type: parseInt(this.$route.params.type) || 0,
      page: 1,
      limit: 20,
      loaded: false,
      loading: false,
      orderList: [],
      pay: false,
      payType: ["yue", "weixin"],
      from: isWeixin() ? "weixin" : "weixinh5"
    };
  },
  components: {
    Loading,
    Payment
  },
  computed: mapGetters(["userInfo"]),
  watch: {
    $route(n) {
      if (n.name === NAME) {
        const type = parseInt(this.$route.params.type) || 0;
        if (this.type !== type) {
          this.changeType(type);
        }
        this.getOrderData();
      }
    }
  },
  methods: {
    setOfflinePayStatus: function(status) {
      var that = this;
      that.offlinePayStatus = status;
      if (status === 1) {
        if (that.payType.indexOf("offline") < 0) {
          that.payType.push("offline");
        }
      }
    },
    getOrderData() {
      getOrderData().then(res => {
        this.orderData = res.data;
      });
    },
    takeOrder(order) {
      takeOrderHandle(order.order_id).finally(() => {
        this.reload();
        this.getOrderData();
      });
    },
    reload() {
      this.changeType(this.type);
    },
    changeType(type) {
      this.type = type;
      this.orderList = [];
      this.page = 1;
      this.loaded = false;
      this.loading = false;
      this.getOrderList();
    },
    getOrderList() {
      if (this.loading || this.loaded) return;
      this.loading = true;
      const { page, limit, type } = this;
      getOrderList({
        page,
        limit,
        type
      }).then(res => {
        this.orderList = this.orderList.concat(res.data);
        this.page++;
        this.loaded = res.data.length < this.limit;
        this.loading = false;
      });
    },
    getStatus(order) {
      return STATUS[order._status._type];
    },
    cancelOrder(order) {
      cancelOrderHandle(order.order_id)
        .then(() => {
          this.orderList.splice(this.orderList.indexOf(order), 1);
        })
        .catch(() => {
          this.reload();
        });
    },
    paymentTap: function(order) {
      var that = this;
      if (
        !(
          order.combination_id > 0 ||
          order.bargain_id > 0 ||
          order.seckill_id > 0
        )
      ) {
        that.setOfflinePayStatus(order.offlinePayStatus);
      }
      this.pay = true;
      this.toPay = type => {
        payOrderHandle(order.order_id, type, that.from)
          .then(() => {
            const type = parseInt(this.$route.params.type) || 0;
            that.changeType(type);
            that.getOrderData();
          })
          .catch(res => {
            if (res.status === "WECHAT_H5_PAY")
              return that.$router.push({
                path: "/order/status/" + order.order_id + "/5"
              });
            const type = parseInt(that.$route.params.type) || 0;
            that.changeType(type);
            that.getOrderData();
          });
      };
    },
    toPay() {}
  },
  mounted() {
    this.getOrderData();
    this.getOrderList();
    this.$scroll(this.$refs.container, () => {
      !this.loading && this.getOrderList();
    });
  }
};
</script>

<style scoped>
.noCart {
  margin-top: 0.17rem;
  padding-top: 0.1rem;
}

.noCart .pictrue {
  width: 4rem;
  height: 3rem;
  margin: 0.7rem auto 0.5rem auto;
}

.noCart .pictrue img {
  width: 100%;
  height: 100%;
}
</style>

OrderDetails.vue

<template>
  <div class="order-details">
    <!-- 给header上与data上加on为退款订单-->
    <div
      class="header bg-color-red acea-row row-middle"
      :class="refundOrder ? 'on' : ''"
    >
      <div class="pictrue" v-if="!refundOrder">
        <img :src="orderInfo.status_pic" />
      </div>
      <div class="data" :class="refundOrder ? 'on' : ''">
        <div class="state">{{ orderInfo._status._msg }}</div>
        <div>
          {{ orderInfo.add_time_y
          }}<span class="time">{{ orderInfo.add_time_h }}</span>
        </div>
      </div>
    </div>
    <template v-if="!refundOrder">
      <div class="nav">
        <div class="navCon acea-row row-between-wrapper">
          <div :class="{ on: status.type === 0 || status.type === 9 }">
            待付款
          </div>
          <div
            :class="{ on: status.type === 1 }"
            v-if="orderInfo.shipping_type === 2"
          >
            待核销
          </div>
          <div :class="{ on: status.type === 1 }" v-else>待发货</div>
          <div
            :class="{ on: status.type === 2 }"
            v-if="orderInfo.shipping_type === 1"
          >
            待收货
          </div>
          <div :class="{ on: status.type === 3 }">待评价</div>
          <div :class="{ on: status.type === 4 }">已完成</div>
        </div>
        <div class="progress acea-row row-between-wrapper">
          <div
            class="iconfont"
            :class="[
              status.type === 0 || status.type === 9
                ? 'icon-webicon318'
                : 'icon-yuandianxiao',
              status.type >= 0 ? 'font-color-red' : ''
            ]"
          ></div>
          <div
            class="line"
            :class="{ 'bg-color-red': status.type > 0 && status.type != 9 }"
          ></div>
          <div
            class="iconfont"
            :class="[
              status.type === 1 ? 'icon-webicon318' : 'icon-yuandianxiao',
              status.type >= 1 && status.type != 6 && status.type != 9
                ? 'font-color-red'
                : ''
            ]"
          ></div>
          <div
            class="line"
            :class="{
              'bg-color-red':
                status.type > 1 && status.type != 6 && status.type != 9
            }"
            v-if="orderInfo.shipping_type === 1"
          ></div>
          <div
            class="iconfont"
            :class="[
              status.type === 2 ? 'icon-webicon318' : 'icon-yuandianxiao',
              status.type >= 2 && status.type != 6 && status.type != 9
                ? 'font-color-red'
                : ''
            ]"
            v-if="orderInfo.shipping_type === 1"
          ></div>
          <div
            class="line"
            :class="{
              'bg-color-red':
                status.type > 2 && status.type != 6 && status.type != 9
            }"
          ></div>
          <div
            class="iconfont"
            :class="[
              status.type === 3 ? 'icon-webicon318' : 'icon-yuandianxiao',
              status.type >= 3 && status.type != 6 && status.type != 9
                ? 'font-color-red'
                : ''
            ]"
          ></div>
          <div
            class="line"
            :class="{
              'bg-color-red':
                status.type > 3 && status.type != 6 && status.type != 9
            }"
          ></div>
          <div
            class="iconfont"
            :class="[
              status.type == 4 ? 'icon-webicon318' : 'icon-yuandianxiao',
              status.type >= 4 && status.type != 6 && status.type != 9
                ? 'font-color-red'
                : ''
            ]"
          ></div>
        </div>
      </div>
      <div
        class="writeOff"
        v-if="orderInfo.shipping_type === 2 && orderInfo.paid === 1"
      >
        <div class="title">核销信息</div>
        <div class="grayBg">
          <div class="pictrue"><img :src="orderInfo.code" /></div>
        </div>
        <div class="gear"><img src="@assets/images/writeOff.jpg" /></div>
        <div class="num">{{ orderInfo._verify_code }}</div>
        <div class="rules">
          <div class="item">
            <div class="rulesTitle acea-row row-middle">
              <span class="iconfont icon-shijian"></span>核销时间
            </div>
            <div class="info">
              每日:<span class="time">{{ system_store.day_time }}</span>
            </div>
          </div>
          <div class="item">
            <div class="rulesTitle acea-row row-middle">
              <span class="iconfont icon-shuoming1"></span>使用说明
            </div>
            <div class="info">可将二维码出示给店员扫描或提供数字核销码</div>
          </div>
        </div>
      </div>
      <div
        class="map acea-row row-between-wrapper"
        v-if="orderInfo.shipping_type === 2 && orderInfo.paid === 1"
      >
        <div>自提地址信息</div>
        <div
          class="place cart-color acea-row row-center-wrapper"
          @click="showChang"
        >
          <span class="iconfont icon-weizhi"></span>查看位置
        </div>
      </div>
      <div class="address" v-if="orderInfo.shipping_type === 1">
        <div class="name">
          {{ orderInfo.real_name
          }}<span class="phone">{{ orderInfo.user_phone }}</span>
        </div>
        <div>{{ orderInfo.user_address }}</div>
      </div>
      <div class="address" v-else>
        <div class="name">
          {{ system_store.name
          }}<span class="phone">{{ system_store.phone }}</span>
          <a
            class="iconfont icon-tonghua font-color-red"
            :href="'tel:' + system_store.phone"
          ></a>
        </div>
        <div>{{ system_store._detailed_address }}</div>
      </div>
      <div class="line" v-if="orderInfo.shipping_type === 1">
        <img src="@assets/images/line.jpg" />
      </div>
    </template>
    <OrderGoods
      :evaluate="status.type || 0"
      :cartInfo="orderInfo.cartInfo || []"
    ></OrderGoods>
    <div class="wrapper">
      <div class="item acea-row row-between">
        <div>订单编号:</div>
        <div class="conter acea-row row-middle row-right">
          {{ orderInfo.order_id
          }}<span
            class="copy copy-data"
            :data-clipboard-text="orderInfo.order_id"
            >复制</span
          >
        </div>
      </div>
      <div class="item acea-row row-between">
        <div>下单时间:</div>
        <div class="conter">
          {{ orderInfo.add_time_y + " " + orderInfo.add_time_h }}
        </div>
      </div>
      <div class="item acea-row row-between">
        <div>订单类型:</div>
        <div class="conter">
          {{ orderTypeName }}
        </div>
      </div>
      <div class="item acea-row row-between">
        <div>支付状态:</div>
        <div class="conter">{{ orderInfo.paid ? "已支付" : "未支付" }}</div>
      </div>
      <div class="item acea-row row-between">
        <div>支付方式:</div>
        <div class="conter">{{ orderInfo._status._payType }}</div>
      </div>
      <div class="item acea-row row-between" v-if="orderInfo.mark">
        <div>买家留言:</div>
        <div class="conter">{{ orderInfo.mark }}</div>
      </div>
    </div>

    <div v-if="orderInfo.status != 0">
      <div class="wrapper" v-if="orderInfo.delivery_type === 'express'">
        <div class="item acea-row row-between">
          <div>配送方式:</div>
          <div class="conter">
            发货
          </div>
        </div>
        <div class="item acea-row row-between">
          <div>快递公司:</div>
          <div class="conter">{{ orderInfo.delivery_name || "" }}</div>
        </div>
        <div class="item acea-row row-between">
          <div>快递号:</div>
          <div class="conter">{{ orderInfo.delivery_id || "" }}</div>
        </div>
      </div>

      <div class="wrapper" v-else>
        <div class="item acea-row row-between">
          <div>配送方式:</div>
          <div class="conter">
            送货
          </div>
        </div>
        <div class="item acea-row row-between">
          <div>配送人:</div>
          <div class="conter">{{ orderInfo.delivery_name || "" }}</div>
        </div>
        <div class="item acea-row row-between">
          <div>配送电话:</div>
          <div class="conter acea-row row-middle row-right">
            {{ orderInfo.delivery_id || "" }}<span class="copy">拨打</span>
          </div>
        </div>
      </div>
    </div>
    <!--     退款订单详情 -->
    <div class="wrapper" v-if="refundOrder">
      <div class="item acea-row row-between">
        <div>收货人:</div>
        <div class="conter">{{ orderInfo.real_name }}</div>
      </div>
      <div class="item acea-row row-between">
        <div>联系电话:</div>
        <div class="conter">{{ orderInfo.user_phone }}</div>
      </div>
      <div class="item acea-row row-between">
        <div>收货地址:</div>
        <div class="conter">{{ orderInfo.user_address }}</div>
      </div>
    </div>
    <div class="wrapper">
      <div class="item acea-row row-between">
        <div>支付金额:</div>
        <div class="conter">¥{{ orderInfo.total_price }}</div>
      </div>
      <div class="item acea-row row-between" v-if="orderInfo.coupon_price > 0">
        <div>优惠券抵扣:</div>
        <div class="conter">-¥{{ orderInfo.coupon_price }}</div>
      </div>
      <div class="item acea-row row-between" v-if="orderInfo.use_integral > 0">
        <div>积分抵扣:</div>
        <div class="conter">-¥{{ orderInfo.deduction_price }}</div>
      </div>
      <div class="item acea-row row-between" v-if="orderInfo.pay_postage > 0">
        <div>运费:</div>
        <div class="conter">¥{{ orderInfo.pay_postage }}</div>
      </div>
      <div class="actualPay acea-row row-right">
        实付款:<span class="money font-color-red"
          >¥{{ orderInfo.pay_price }}</span
        >
      </div>
    </div>
    <div style="height:1.2rem;" v-if="!refundOrder && offlineStatus"></div>
    <div
      class="footer acea-row row-right row-middle"
      v-if="!refundOrder && offlineStatus"
    >
      <template v-if="status.type === 0">
        <div class="bnt cancel" @click="cancelOrder">取消订单</div>
        <div class="bnt bg-color-red" @click="pay = true">立即付款</div>
      </template>
      <template v-if="status.type === 1">
        <div
          class="bnt cancel"
          @click="$router.push({ path: '/order/refund/' + orderInfo.order_id })"
        >
          申请退款
        </div>
      </template>
      <template v-if="status.type === 2">
        <div
          class="bnt default"
          @click="
            $router.push({ path: '/order/logistics/' + orderInfo.order_id })
          "
        >
          查看物流
        </div>
        <div class="bnt bg-color-red" @click="takeOrder">
          确认收货
        </div>
      </template>
      <template
        v-if="status.type === 3 && orderInfo.delivery_type === 'express'"
      >
        <div
          class="bnt default"
          @click="
            $router.push({ path: '/order/logistics/' + orderInfo.order_id })
          "
        >
          查看物流
        </div>
      </template>
      <template v-if="status.type === 4">
        <div class="bnt cancel" @click="delOrder">
          删除订单
        </div>
        <div
          class="bnt default"
          @click="
            $router.push({ path: '/order/logistics/' + orderInfo.order_id })
          "
        >
          查看物流
        </div>
      </template>
      <template v-if="status.type === 6">
        <div
          class="bnt bg-color-red"
          @click="
            $router.push({ path: '/activity/group_rule/' + orderInfo.pink_id })
          "
        >
          查看拼团
        </div>
      </template>
    </div>
    <Payment
      v-model="pay"
      :types="payType"
      @checked="toPay"
      :balance="userInfo.now_money"
    ></Payment>
    <div class="geoPage" v-if="mapShow">
      <iframe
        width="100%"
        height="100%"
        frameborder="0"
        scrolling="no"
        :src="
          'https://apis.map.qq.com/uri/v1/geocoder?coord=' +
            system_store.latitude +
            ',' +
            system_store.longitude +
            '&referer=' +
            mapKey
        "
      >
      </iframe>
    </div>
  </div>
</template>
<style scoped>
.geoPage {
  position: fixed;
  width: 100%;
  height: 100%;
  top: 0;
  z-index: 10000;
}
.order-details .writeOff {
  background-color: #fff;
  margin-top: 0.13rem;
  padding-bottom: 0.3rem;
}
.order-details .writeOff .title {
  font-size: 0.3rem;
  color: #282828;
  height: 0.87rem;
  border-bottom: 1px solid #f0f0f0;
  padding: 0 0.3rem;
  line-height: 0.87rem;
}
.order-details .writeOff .grayBg {
  background-color: #f2f5f7;
  width: 5.9rem;
  height: 3.84rem;
  border-radius: 0.2rem 0.2rem 0 0;
  margin: 0.5rem auto 0 auto;
  padding-top: 0.55rem;
}
.order-details .writeOff .grayBg .pictrue {
  width: 2.9rem;
  height: 2.9rem;
  margin: 0 auto;
}
.order-details .writeOff .grayBg .pictrue img {
  width: 100%;
  height: 100%;
  display: block;
}
.order-details .writeOff .gear {
  width: 5.9rem;
  height: 0.3rem;
  margin: 0 auto;
}
.order-details .writeOff .gear img {
  width: 100%;
  height: 100%;
  display: block;
}
.order-details .writeOff .num {
  background-color: #f0c34c;
  width: 5.9rem;
  height: 0.84rem;
  color: #282828;
  font-size: 0.48rem;
  margin: 0 auto;
  border-radius: 0 0 0.2rem 0.2rem;
  text-align: center;
  padding-top: 0.04rem;
}
.order-details .writeOff .rules {
  margin: 0.46rem 0.3rem 0 0.3rem;
  border-top: 0.01rem solid #f0f0f0;
  padding-top: 0.1rem;
}
.order-details .writeOff .rules .item {
  margin-top: 0.15rem;
}
.order-details .writeOff .rules .item .rulesTitle {
  font-size: 0.28rem;
  color: #282828;
}
.order-details .writeOff .rules .item .rulesTitle .iconfont {
  font-size: 0.3rem;
  color: #333;
  margin-right: 0.08rem;
  margin-top: 0.05rem;
}
.order-details .writeOff .rules .item .info {
  font-size: 0.28rem;
  color: #999;
  margin-top: 0.05rem;
}
.order-details .writeOff .rules .item .info .time {
  margin-left: 0.2rem;
}
.order-details .map {
  height: 0.86rem;
  font-size: 0.3rem;
  color: #282828;
  line-height: 0.86rem;
  border-bottom: 0.01rem solid #f0f0f0;
  margin-top: 0.13rem;
  background-color: #fff;
  padding: 0 0.3rem;
}
.order-details .map .place {
  font-size: 0.26rem;
  width: 1.76rem;
  height: 0.5rem;
  border-radius: 0.25rem;
  line-height: 0.5rem;
  text-align: center;
}
.order-details .map .place .iconfont {
  font-size: 0.27rem;
  height: 0.27rem;
  line-height: 0.27rem;
  margin: 0.02rem 0.03rem 0 0;
}
.order-details .address .name .iconfont {
  font-size: 0.34rem;
  margin-left: 0.1rem;
}
</style>
<script>
import OrderGoods from "@components/OrderGoods";
import { orderDetail } from "@api/order";
import ClipboardJS from "clipboard";
import Payment from "@components/Payment";
import { isWeixin } from "@utils";
import { mapGetters } from "vuex";
import {
  cancelOrderHandle,
  takeOrderHandle,
  delOrderHandle,
  payOrderHandle
} from "@libs/order";
import { wechatEvevt } from "@libs/wechat";

const NAME = "OrderDetails";

export default {
  name: NAME,
  components: {
    OrderGoods,
    Payment
  },
  props: {},
  data: function() {
    return {
      offlinePayStatus: 2,
      orderTypeName: "普通订单",
      orderTypeNameStatus: true,
      offlineStatus: true,
      id: this.$route.params.id,
      orderInfo: {
        _status: {}
      },
      status: {},
      pay: false,
      payType: ["yue", "weixin"],
      from: isWeixin() ? "weixin" : "weixinh5",
      system_store: {},
      mapKay: "",
      mapShow: false
    };
  },
  computed: {
    refundOrder() {
      return this.orderInfo.refund_status > 0;
    },
    ...mapGetters(["userInfo"])
  },
  watch: {
    $route(n) {
      if (n.name === NAME && this.id !== n.params.id) {
        this.id = n.params.id;
        this.getDetail();
      }
    }
  },
  inject: ["app"],
  mounted: function() {
    this.getDetail();
    this.$nextTick(function() {
      let copybtn = document.getElementsByClassName("copy-data");
      const clipboard = new ClipboardJS(copybtn);
      clipboard.on("success", () => {
        this.$dialog.success("复制成功");
      });
    });
  },
  methods: {
    showChang: function() {
      if (isWeixin()) {
        let config = {
          latitude: parseFloat(this.system_store.latitude),
          longitude: parseFloat(this.system_store.longitude),
          name: this.system_store.name,
          address: this.system_store._detailed_address
        };
        wechatEvevt("openLocation", config)
          .then(res => {
            console.log(res);
          })
          .catch(res => {
            if (res.is_ready) {
              res.wx.openLocation(config);
            }
          });
      } else {
        if (!this.mapKey)
          return this.$dialog.error(
            "暂无法使用查看地图,请配置您的腾讯地图key"
          );
        this.mapShow = true;
      }
    },
    goBack() {
      const history = this.app.history,
        last = history[history.length - 1] || {};
      if (last.name === "MyOrder") return this.$router.go(-1);
      else return this.$router.replace({ path: "/order/list/" });
    },
    cancelOrder() {
      cancelOrderHandle(this.orderInfo.order_id)
        .then(() => {
          setTimeout(() => this.goBack(), 300);
        })
        .catch(() => {
          this.getDetail();
        });
    },
    takeOrder() {
      takeOrderHandle(this.orderInfo.order_id).finally(() => {
        this.getDetail();
      });
    },
    delOrder() {
      delOrderHandle(this.orderInfo.order_id).then(() => {
        setTimeout(() => this.goBack(), 300);
      });
    },
    setOfflinePayStatus: function(status) {
      var that = this;
      that.offlinePayStatus = status;
      if (status === 1 && that.orderTypeNameStatus === true) {
        that.payType.push("offline");
      }
    },
    getOrderStatus: function() {
      let orderInfo = this.orderInfo || {},
        _status = orderInfo._status || { _type: 0 },
        status = {};
      let type = parseInt(_status._type),
        delivery_type = orderInfo.delivery_type,
        seckill_id = orderInfo.seckill_id ? parseInt(orderInfo.seckill_id) : 0,
        bargain_id = orderInfo.bargain_id ? parseInt(orderInfo.bargain_id) : 0,
        combination_id = orderInfo.combination_id
          ? parseInt(orderInfo.combination_id)
          : 0;
      status = {
        type: type,
        class_status: 0
      };
      if (type === 1 && combination_id > 0) {
        status.type = 6;
        status.class_status = 1;
      } //查看拼团
      if (type === 2 && delivery_type === "express") status.class_status = 2; //查看物流
      if (type === 2) status.class_status = 3; //确认收货
      if (type === 4 || type === 0) status.class_status = 4; //删除订单
      if (
        !seckill_id &&
        !bargain_id &&
        !combination_id &&
        (type === 3 || type === 4)
      )
        status.class_status = 5; //再次购买
      if (type == 9) {
        //线下付款
        status.class_status = 0;
        this.offlineStatus = false;
      }
      this.status = status;
    },
    getDetail() {
      const id = this.id;
      if (!id) return this.$dialog.error("订单不存在");
      orderDetail(id)
        .then(res => {
          this.orderInfo = res.data;
          this.getOrderStatus();
          if (this.orderInfo.combination_id > 0) {
            this.orderTypeName = "拼团订单";
            this.orderTypeNameStatus = false;
          } else if (this.orderInfo.bargain_id > 0) {
            this.orderTypeName = "砍价订单";
            this.orderTypeNameStatus = false;
          } else if (this.orderInfo.seckill_id > 0) {
            this.orderTypeName = "秒杀订单";
            this.orderTypeNameStatus = false;
          }
          this.system_store = res.data.system_store || {};
          this.mapKey = res.data.mapKey;
          this.setOfflinePayStatus(this.orderInfo.offlinePayStatus);
        })
        .catch(err => {
          this.$dialog.error(err.msg);
        });
    },
    async toPay(type) {
      var that = this;
      await payOrderHandle(this.orderInfo.order_id, type, that.from)
        .then(() => {})
        .catch(res => {
          if (res.status === "WECHAT_H5_PAY")
            that.$router.push({
              path: "/order/status/" + that.orderInfo.order_id + "/0"
            });
        });
      that.getDetail();
    }
  }
};
</script>

OrderSubmission.vue

<template>
  <div class="order-submission">
    <div
      class="allAddress"
      :style="store_self_mention ? '' : 'padding-top: 0.2rem'"
    >
      <div class="nav acea-row">
        <div
          class="item font-color-red"
          :class="shipping_type === 0 ? 'on' : 'on2'"
          @click="addressType(0)"
          v-if="store_self_mention"
        ></div>
        <div
          class="item font-color-red"
          :class="shipping_type === 1 ? 'on' : 'on2'"
          @click="addressType(1)"
          v-if="store_self_mention"
        ></div>
      </div>
      <div
        class="address acea-row row-between-wrapper"
        v-if="shipping_type === 0"
        @click="addressTap"
      >
        <div class="addressCon" v-if="addressInfo.real_name">
          <div class="name">
            {{ addressInfo.real_name }}
            <span class="phone">{{ addressInfo.phone }}</span>
          </div>
          <div>
            <span class="default font-color-red" v-if="addressInfo.is_default"
              >[默认]</span
            >
            {{ addressInfo.province }}{{ addressInfo.city
            }}{{ addressInfo.district }}{{ addressInfo.detail }}
          </div>
        </div>
        <div class="addressCon" v-else>
          <div class="setaddress">设置收货地址</div>
        </div>
        <div class="iconfont icon-jiantou"></div>
      </div>
      <div class="address acea-row row-between-wrapper" v-else>
        <div class="addressCon">
          <div class="name">
            {{ system_store.name }}
            <span class="phone">{{ system_store.phone }}</span>
          </div>
          <div>
            {{ system_store._detailed_address }}
          </div>
        </div>
      </div>
      <div class="line">
        <img src="@assets/images/line.jpg" />
      </div>
    </div>
    <OrderGoods :evaluate="0" :cartInfo="orderGroupInfo.cartInfo"></OrderGoods>
    <div class="wrapper">
      <div
        class="item acea-row row-between-wrapper"
        @click="couponTap"
        v-if="deduction === false"
      >
        <div>优惠券</div>
        <div class="discount">
          {{ usableCoupon.coupon_title || "请选择" }}
          <span class="iconfont icon-jiantou"></span>
        </div>
      </div>
      <div class="item acea-row row-between-wrapper" v-if="deduction === false">
        <div>积分抵扣</div>
        <div class="discount">
          <div class="select-btn">
            <div class="checkbox-wrapper">
              <label class="well-check">
                <input type="checkbox" v-model="useIntegral" />
                <i class="icon"></i>
                <span class="integral">
                  当前积分
                  <span class="num font-color-red">
                    {{ userInfo.integral || 0 }}
                  </span>
                </span>
              </label>
            </div>
          </div>
        </div>
      </div>
      <div
        class="item acea-row row-between-wrapper"
        v-if="
          orderGroupInfo.priceGroup.vipPrice > 0 &&
            userInfo.vip &&
            pinkId == 0 &&
            orderGroupInfo.bargain_id == 0 &&
            orderGroupInfo.combination_id == 0 &&
            orderGroupInfo.seckill_id == 0
        "
      >
        会员优惠
        <div class="discount">¥{{ orderGroupInfo.priceGroup.vipPrice }}</div>
      </div>
      <div class="item acea-row row-between-wrapper" v-if="shipping_type === 0">
        <div>快递费用</div>
        <div class="discount">
          {{
            orderGroupInfo.priceGroup.storePostage > 0
              ? orderGroupInfo.priceGroup.storePostage
              : "免运费"
          }}
        </div>
      </div>
      <div v-else>
        <div class="item acea-row row-between-wrapper">
          <div>联系人</div>
          <div class="discount">
            <input
              type="text"
              placeholder="请填写您的联系姓名"
              v-model="contacts"
            />
          </div>
        </div>
        <div class="item acea-row row-between-wrapper">
          <div>联系电话</div>
          <div class="discount">
            <input
              type="text"
              placeholder="请填写您的联系电话"
              v-model="contactsTel"
            />
          </div>
        </div>
      </div>
      <div class="item">
        <div>备注信息</div>
        <textarea
          placeholder="请添加备注(150字以内)"
          v-model="mark"
        ></textarea>
      </div>
    </div>
    <div class="wrapper">
      <div class="item">
        <div>支付方式</div>
        <div class="list">
          <div
            class="payItem acea-row row-middle"
            :class="active === 'weixin' ? 'on' : ''"
            @click="payItem('weixin')"
            v-show="isWeixin"
          >
            <div class="name acea-row row-center-wrapper">
              <div
                class="iconfont icon-weixin2"
                :class="active === 'weixin' ? 'bounceIn' : ''"
              ></div>
              微信支付
            </div>
            <div class="tip">微信快捷支付</div>
          </div>
          <div
            class="payItem acea-row row-middle"
            :class="active === 'weixin' ? 'on' : ''"
            @click="payItem('weixin')"
            v-show="!isWeixin"
          >
            <div class="name acea-row row-center-wrapper">
              <div
                class="iconfont icon-weixin2"
                :class="active === 'weixin' ? 'bounceIn' : ''"
              ></div>
              微信支付
            </div>
            <div class="tip">微信快捷支付</div>
          </div>
          <div
            class="payItem acea-row row-middle"
            :class="active === 'yue' ? 'on' : ''"
            @click="payItem('yue')"
          >
            <div class="name acea-row row-center-wrapper">
              <div
                class="iconfont icon-icon-test"
                :class="active === 'yue' ? 'bounceIn' : ''"
              ></div>
              余额支付
            </div>
            <div class="tip">可用余额:{{ userInfo.now_money || 0 }}</div>
          </div>
          <div
            class="payItem acea-row row-middle"
            :class="active === 'offline' ? 'on' : ''"
            @click="payItem('offline')"
            v-if="offlinePayStatus === 1 && deduction === false"
          >
            <div class="name acea-row row-center-wrapper">
              <div
                class="iconfont icon-yinhangqia"
                :class="active === 'offline' ? 'bounceIn' : ''"
              ></div>
              线下支付
            </div>
            <div class="tip">线下方便支付</div>
          </div>
        </div>
      </div>
    </div>
    <div class="moneyList">
      <div
        class="item acea-row row-between-wrapper"
        v-if="orderPrice.total_price !== undefined"
      >
        <div>商品总价:</div>
        <div class="money">¥{{ orderPrice.total_price }}</div>
      </div>
      <div
        class="item acea-row row-between-wrapper"
        v-if="orderPrice.pay_postage > 0"
      >
        <div>运费:</div>
        <div class="money">¥{{ orderPrice.pay_postage }}</div>
      </div>
      <div
        class="item acea-row row-between-wrapper"
        v-if="orderPrice.coupon_price > 0"
      >
        <div>优惠券抵扣:</div>
        <div class="money">-¥{{ orderPrice.coupon_price }}</div>
      </div>
      <div
        class="item acea-row row-between-wrapper"
        v-if="orderPrice.deduction_price > 0"
      >
        <div>积分抵扣:</div>
        <div class="money">-¥{{ orderPrice.deduction_price }}</div>
      </div>
    </div>
    <div style="height:1.2rem"></div>
    <div class="footer acea-row row-between-wrapper">
      <div>
        合计:
        <span class="font-color-red">¥{{ orderPrice.pay_price }}</span>
      </div>
      <div class="settlement" @click="createOrder">立即结算</div>
    </div>
    <CouponListWindow
      v-on:couponchange="changecoupon($event)"
      v-model="showCoupon"
      :price="orderPrice.total_price"
      :checked="usableCoupon.id"
      @checked="changeCoupon"
    ></CouponListWindow>
    <AddressWindow
      @checked="changeAddress"
      @redirect="addressRedirect"
      v-model="showAddress"
      :checked="addressInfo.id"
      ref="mychild"
    ></AddressWindow>
  </div>
</template>
<style scoped>
.order-submission .wrapper .shipping select {
  color: #999;
  padding-right: 0.15rem;
}
.order-submission .wrapper .shipping .iconfont {
  font-size: 0.3rem;
  color: #515151;
}
.order-submission .allAddress {
  width: 100%;
  background-image: linear-gradient(to bottom, #e93323 0%, #f5f5f5 100%);
  background-image: -webkit-linear-gradient(
    to bottom,
    #e93323 0%,
    #f5f5f5 100%
  );
  background-image: -moz-linear-gradient(to bottom, #e93323 0%, #f5f5f5 100%);
  padding-top: 1rem;
}
.order-submission .allAddress .nav {
  width: 7.1rem;
  margin: 0 auto;
}
.order-submission .allAddress .nav .item {
  width: 3.55rem;
}
.order-submission .allAddress .nav .item.on {
  position: relative;
  width: 2.5rem;
}
.order-submission .allAddress .nav .item.on:before {
  position: absolute;
  bottom: 0;
  content: "快递配送";
  font-size: 0.28rem;
  display: block;
  height: 0;
  width: 3.55rem;
  border-width: 0 0.2rem 0.8rem 0;
  border-style: none solid solid;
  border-color: transparent transparent #fff;
  z-index: 9;
  border-radius: 0.07rem 0.3rem 0 0;
  text-align: center;
  line-height: 0.8rem;
}
.order-submission .allAddress .nav .item:nth-of-type(2).on:before {
  content: "到店自提";
  border-width: 0 0 0.8rem 0.2rem;
  border-radius: 0.3rem 0.07rem 0 0;
}
.order-submission .allAddress .nav .item.on2 {
  position: relative;
}
.order-submission .allAddress .nav .item.on2:before {
  position: absolute;
  bottom: 0;
  content: "到店自提";
  font-size: 0.28rem;
  display: block;
  height: 0;
  width: 4.6rem;
  border-width: 0 0 0.6rem 0.6rem;
  border-style: none solid solid;
  border-color: transparent transparent #f7c1bd;
  border-radius: 0.4rem 0.06rem 0 0;
  text-align: center;
  line-height: 0.6rem;
}
.order-submission .allAddress .nav .item:nth-of-type(1).on2:before {
  content: "快递配送";
  border-width: 0 0.6rem 0.6rem 0;
  border-radius: 0.06rem 0.4rem 0 0;
}
.order-submission .allAddress .address {
  width: 7.1rem;
  height: 1.5rem;
  margin: 0 auto;
}
.order-submission .allAddress .line {
  width: 7.1rem;
  margin: 0 auto;
}
.order-submission .wrapper .item .discount input::placeholder {
  color: #ccc;
}
</style>
<script>
import OrderGoods from "@components/OrderGoods";
import CouponListWindow from "@components/CouponListWindow";
import AddressWindow from "@components/AddressWindow";
import { postOrderConfirm, postOrderComputed, createOrder } from "@api/order";
import { getUser } from "@api/user";
import { pay } from "@libs/wechat";
import { isWeixin } from "@utils";

const NAME = "OrderSubmission",
  _isWeixin = isWeixin();
export default {
  name: NAME,
  components: {
    OrderGoods,
    CouponListWindow,
    AddressWindow
  },
  props: {},
  data: function() {
    return {
      offlinePayStatus: 2,
      from: _isWeixin ? "weixin" : "weixinh5",
      deduction: true,
      isWeixin: _isWeixin,
      pinkId: 0,
      active: _isWeixin ? "weixin" : "yue",
      showCoupon: false,
      showAddress: false,
      addressInfo: {},
      couponId: 0,
      orderGroupInfo: {
        priceGroup: {}
      },
      usableCoupon: {},
      addressLoaded: false,
      useIntegral: false,
      orderPrice: {
        pay_price: "计算中"
      },
      mark: "",
      system_store: {},
      shipping_type: 0,
      contacts: "",
      contactsTel: "",
      store_self_mention: 0,
      userInfo: {}
    };
  },
  watch: {
    useIntegral() {
      this.computedPrice();
    },
    $route(n) {
      if (n.name === NAME) {
        this.getUserInfo();
        this.getCartInfo();
      }
    },
    shipping_type() {
      this.computedPrice();
    }
  },
  mounted: function() {
    let that = this;
    that.getUserInfo();
    that.getCartInfo();
    if (that.$route.query.pinkid !== undefined)
      that.pinkId = that.$route.query.pinkid;
  },
  methods: {
    getUserInfo() {
      getUser()
        .then(res => {
          this.userInfo = res.data;
        })
        .catch(() => {});
    },
    addressType: function(index) {
      if (index && !this.system_store.id)
        return this.$dialog.error("暂无门店信息,您无法选择到店自提!");
      this.shipping_type = index;
    },
    computedPrice() {
      let shipping_type = this.shipping_type;
      postOrderComputed(this.orderGroupInfo.orderKey, {
        addressId: this.addressInfo.id,
        useIntegral: this.useIntegral ? 1 : 0,
        couponId: this.usableCoupon.id || 0,
        shipping_type: parseInt(shipping_type) + 1
      }).then(res => {
        const data = res.data;
        if (data.status === "EXTEND_ORDER") {
          this.$router.replace({
            path: "/order/detail/" + data.result.orderId
          });
        } else {
          this.orderPrice = data.result;
        }
      });
    },
    getCartInfo() {
      const cartIds = this.$route.params.id;
      if (!cartIds) {
        this.$dialog.error("参数有误");
        return this.$router.go(-1);
      }
      postOrderConfirm(cartIds)
        .then(res => {
          this.offlinePayStatus = res.data.offline_pay_status;
          this.orderGroupInfo = res.data;
          this.deduction = res.data.deduction;
          this.usableCoupon = res.data.usableCoupon || {};
          this.addressInfo = res.data.addressInfo || {};
          this.system_store = res.data.system_store || {};
          this.store_self_mention = res.data.store_self_mention;
          this.computedPrice();
        })
        .catch(() => {
          this.$dialog.error("加载订单数据失败");
        });
    },
    addressTap: function() {
      this.showAddress = true;
      if (!this.addressLoaded) {
        this.addressLoaded = true;
        this.$refs.mychild.getAddressList();
      }
    },
    addressRedirect() {
      this.addressLoaded = false;
      this.showAddress = false;
    },
    couponTap: function() {
      this.showCoupon = true;
    },
    changeCoupon: function(coupon) {
      if (!coupon) {
        this.usableCoupon = { coupon_title: "不使用优惠券", id: 0 };
      } else {
        this.usableCoupon = coupon;
      }
      this.computedPrice();
    },
    payItem: function(index) {
      this.active = index;
    },
    changeAddress(addressInfo) {
      this.addressInfo = addressInfo;
    },
    createOrder() {
      let shipping_type = this.shipping_type;
      if (!this.active) return this.$dialog.toast({ mes: "请选择支付方式" });
      if (!this.addressInfo.id && !this.shipping_type)
        return this.$dialog.toast({ mes: "请选择收货地址" });
      if (this.shipping_type) {
        if (
          (this.contacts === "" || this.contactsTel === "") &&
          this.shipping_type
        )
          return this.$dialog.toast({ mes: "请填写联系人或联系人电话" });
        if (!/^1(3|4|5|7|8|9|6)\d{9}$/.test(this.contactsTel)) {
          return this.$dialog.toast({ mes: "请填写正确的手机号" });
        }
        if (!/^[\u4e00-\u9fa5\w]{2,16}$/.test(this.contacts)) {
          return this.$dialog.toast({ mes: "请填写您的真实姓名" });
        }
      }
      this.$dialog.loading.open("生成订单中");
      createOrder(this.orderGroupInfo.orderKey, {
        real_name: this.contacts,
        phone: this.contactsTel,
        addressId: this.addressInfo.id,
        useIntegral: this.useIntegral ? 1 : 0,
        couponId: this.usableCoupon.id || 0,
        payType: this.active,
        pinkId: this.pinkId,
        seckill_id: this.orderGroupInfo.seckill_id,
        combinationId: this.orderGroupInfo.combination_id,
        bargainId: this.orderGroupInfo.bargain_id,
        from: this.from,
        mark: this.mark || "",
        shipping_type: parseInt(shipping_type) + 1
      })
        .then(res => {
          this.$dialog.loading.close();
          const data = res.data;
          let url = "/order/status/" + data.result.orderId;
          switch (data.status) {
            case "ORDER_EXIST":
            case "EXTEND_ORDER":
            case "PAY_DEFICIENCY":
            case "PAY_ERROR":
              this.$dialog.toast({ mes: res.msg });
              this.$router.replace({
                path: url + "/0?msg=" + res.msg
              });
              break;
            case "SUCCESS":
              this.$dialog.success(res.msg);
              this.$router.replace({
                path: url + "/1"
              });
              break;
            case "WECHAT_H5_PAY":
              this.$router.replace({
                path: url + "/2"
              });
              setTimeout(() => {
                location.href = data.result.jsConfig.mweb_url;
              }, 100);
              break;
            case "WECHAT_PAY":
              pay(data.result.jsConfig).finally(() => {
                this.$router.replace({
                  path: url + "/4"
                });
              });
          }
        })
        .catch(err => {
          console.log(err);
          this.$dialog.loading.close();
          this.$dialog.error(err.msg || "创建订单失败");
        });
    }
  }
};
</script>

PaymentStatus.vue

<template>
  <div class="payment-status" v-cloak>
    <!--失败时: 用icon-iconfontguanbi fail替换icon-duihao2 bg-color-red-->
    <div
      class="iconfont icon-duihao2 bg-color-red"
      v-if="!isWeixin || orderInfo.paid || orderInfo.pay_type == 'offline'"
    ></div>
    <div class="iconfont icon-iconfontguanbi fail" v-else></div>
    <!-- 失败时:订单支付失败 -->
    <div
      class="status"
      v-if="
        (!isWeixin && orderInfo.pay_type == 'weixin') ||
          orderInfo.pay_type == 'offline'
      "
    >
      订单创建成功
    </div>
    <div class="status" v-else-if="orderInfo.paid">订单支付成功</div>
    <div class="status" v-else>订单支付失败</div>
    <div class="wrapper">
      <div class="item acea-row row-between-wrapper">
        <div>订单编号</div>
        <div class="itemCom" v-text="orderInfo.order_id"></div>
      </div>
      <div class="item acea-row row-between-wrapper">
        <div>下单时间</div>
        <div class="itemCom" v-text="orderInfo.add_time"></div>
      </div>
      <div class="item acea-row row-between-wrapper">
        <div>支付方式</div>
        <div
          class="itemCom"
          v-if="orderInfo.pay_type == 'weixin' && orderInfo.is_channel == 2"
        >
          H5微信支付
        </div>
        <div
          class="itemCom"
          v-if="orderInfo.pay_type == 'weixin' && orderInfo.is_channel == 0"
        >
          微信支付
        </div>
        <div class="itemCom" v-if="orderInfo.pay_type == 'yue'">余额支付</div>
        <div class="itemCom" v-if="orderInfo.pay_type == 'offline'">
          线下支付
        </div>
      </div>
      <div class="item acea-row row-between-wrapper">
        <div>支付金额</div>
        <div class="itemCom" v-text="orderInfo.pay_price"></div>
      </div>
      <!--失败时加上这个  -->
      <div
        class="item acea-row row-between-wrapper"
        v-if="
          orderInfo.paid == 0 &&
            orderInfo.pay_type != 'offline' &&
            isWeixin &&
            msgContent
        "
      >
        <div>失败原因</div>
        <div class="itemCom" v-text="msgContent"></div>
      </div>
    </div>
    <!--失败时: 重新购买 -->
    <div v-if="orderInfo.pay_type == 'weixin' && orderInfo.is_channel == 2">
      <div class="returnBnt bg-color-red" @click="goPages()">查看支付结果</div>
      <div class="returnBnt cart-color" @click="goPages()">
        支付失败重新支付
      </div>
    </div>
    <div v-else>
      <div class="returnBnt bg-color-red" @click="goPages()">查看订单</div>
      <div class="returnBnt cart-color" @click="goPages('/')">返回首页</div>
    </div>
  </div>
</template>
<script>
import { mapGetters } from "vuex";
import { orderDetail } from "@api/order";
import { isWeixin } from "@utils";

const NAME = "PayMentStatus";

export default {
  name: NAME,
  props: {},
  data: function() {
    return {
      id: "",
      status: 0,
      msgContent: "",
      orderInfo: {},
      isWeixin: isWeixin()
    };
  },
  watch: {
    $route(n) {
      if (n.query.msg) this.msgContent = n.query.msg;
      if (n.name === NAME && this.id !== n.params.id) {
        this.id = n.params.id;
        this.status = parseInt(n.params.status);
        this.getOrderInfo();
      }
    }
  },
  computed: {
    ...mapGetters(["userInfo"])
  },
  mounted() {
    this.id = this.$route.params.id;
    this.msgContent = this.$route.query.msg;
    this.status = parseInt(this.$route.params.status);
    this.getOrderInfo();
  },
  methods: {
    goPages(route) {
      let routes =
        route !== undefined
          ? route
          : "/order/detail/" + this.orderInfo.order_id;
      if (this.status === 5 && route === undefined) routes = "/order/list/0";
      return this.$router.push({
        path: routes
      });
    },
    getOrderInfo() {
      orderDetail(this.id).then(res => {
        this.orderInfo = res.data;
        if (this.isWeixin) {
          document.title = this.orderInfo.paid ? "支付成功" : "支付失败";
        } else {
          document.title = "订单创建成功";
        }
      });
    }
  }
};
</script>

ReturnList.vue

<template>
  <div class="return-list" ref="container">
    <div class="goodWrapper" v-for="order in orderList" :key="order.order_id">
      <div
        class="iconfont icon-tuikuanzhong powder"
        v-if="order._status._type === -1"
      ></div>
      <div
        class="iconfont icon-yituikuan"
        v-if="order._status._type === -2"
      ></div>
      <div class="orderNum">订单号:{{ order.order_id }}</div>
      <div
        class="item acea-row row-between-wrapper"
        v-for="cart in order.cartInfo"
        :key="cart.id"
        @click="$router.push({ path: '/order/detail/' + order.order_id })"
      >
        <div class="pictrue">
          <img
            :src="cart.productInfo.image"
            class="image"
            @click.stop="
              $router.push({ path: '/detail/' + cart.productInfo.id })
            "
          />
        </div>
        <div class="text">
          <div class="acea-row row-between-wrapper">
            <div class="name line1">{{ cart.productInfo.store_name }}</div>
            <div class="num">x {{ cart.cart_num }}</div>
          </div>
          <div class="attr line1" v-if="cart.productInfo.attrInfo">
            {{ cart.productInfo.attrInfo.suk }}
          </div>
          <div class="attr line1" v-else>{{ cart.productInfo.store_name }}</div>
          <div class="money">¥{{ cart.productInfo.price }}</div>
        </div>
      </div>
      <div class="totalSum">
        共{{ order.cartInfo.length || 0 }}件商品,总金额
        <span class="font-color-red price">¥{{ order.pay_price }}</span>
      </div>
    </div>
    <div class="noCart" v-if="orderList.length === 0 && page > 1">
      <div class="pictrue"><img src="@assets/images/noOrder.png" /></div>
    </div>
    <Loading :loaded="loaded" :loading="loading"></Loading>
  </div>
</template>

<script>
import { getOrderList } from "@api/order";
import Loading from "@components/Loading";

export default {
  name: "ReturnList",
  components: {
    Loading
  },
  data() {
    return {
      orderList: [],
      page: 1,
      limit: 20,
      loading: false,
      loaded: false
    };
  },
  methods: {
    getOrderList() {
      const { page, limit } = this;
      if (this.loading || this.loaded) return;
      this.loading = true;
      getOrderList({
        page,
        limit,
        type: -3
      }).then(res => {
        this.orderList = this.orderList.concat(res.data);
        this.loading = false;
        this.loaded = res.data.length < limit;
        this.page++;
      });
    }
  },
  mounted() {
    this.getOrderList();
    this.$scroll(this.$refs.container, () => {
      !this.loading && this.getOrderList();
    });
  }
};
</script>

<style scoped>
.noCart {
  margin-top: 0.17rem;
  padding-top: 0.1rem;
}

.noCart .pictrue {
  width: 4rem;
  height: 3rem;
  margin: 0.7rem auto 0.5rem auto;
}

.noCart .pictrue img {
  width: 100%;
  height: 100%;
}
</style>

shop

EvaluateList.vue

<template>
  <div class="evaluate-list" ref="container">
    <div class="header">
      <div class="generalComment acea-row row-between-wrapper">
        <div class="acea-row row-middle font-color-red">
          <div class="evaluate">评分</div>
          <div class="start" :class="'star' + replyData.reply_star"></div>
        </div>
        <div>
          <span class="font-color-red">{{ replyData.reply_chance || 0 }}%</span
          >好评率
        </div>
      </div>
      <div class="nav acea-row row-middle">
        <div
          class="acea-row row-center-wrapper"
          v-for="(item, index) in navList"
          :key="index"
          @click="changeType(index)"
        >
          <div
            class="item"
            :class="currentActive === index ? 'bg-color-red' : ''"
            v-if="item.num"
          >
            {{ item.evaluate }}({{ item.num }})
          </div>
        </div>
      </div>
    </div>
    <UserEvaluation :reply="reply"></UserEvaluation>
    <Loading :loaded="loadend" :loading="loading"></Loading>
  </div>
</template>
<script>
import UserEvaluation from "@components/UserEvaluation";
import { getReplyConfig, getReplyList } from "@api/store";
import Loading from "@components/Loading";

let NAME = "EvaluateList";

export default {
  name: "EvaluateList",
  components: {
    UserEvaluation,
    Loading
  },
  props: {},
  data: function() {
    return {
      product_id: 0,
      replyData: {},
      navList: [
        { evaluate: "全部", num: 0 },
        { evaluate: "好评", num: 0 },
        { evaluate: "中评", num: 0 },
        { evaluate: "差评", num: 0 }
      ],
      currentActive: 0,
      page: 1,
      limit: 8,
      reply: [],
      loadTitle: "",
      loading: false,
      loadend: false
    };
  },
  watch: {
    $route(n) {
      if (n.name === NAME) {
        this.product_id = this.$route.params.id;
        this.loadend = false;
        this.page = 1;
        this.$set(this, "reply", []);
        this.getProductReplyCount();
        this.getProductReplyList();
      }
    }
  },
  mounted: function() {
    this.product_id = this.$route.params.id;
    this.getProductReplyCount();
    this.getProductReplyList();
    this.$scroll(this.$refs.container, () => {
      !this.loading && this.getProductReplyList();
    });
  },
  methods: {
    getProductReplyCount: function() {
      let that = this;
      getReplyConfig(that.product_id).then(res => {
        that.$set(that, "replyData", res.data);
        that.navList[0].num = res.data.sum_count;
        that.navList[1].num = res.data.good_count;
        that.navList[2].num = res.data.in_count;
        that.navList[3].num = res.data.poor_count;
      });
    },
    getProductReplyList: function() {
      let that = this;
      if (that.loading) return; //阻止下次请求(false可以进行请求);
      if (that.loadend) return; //阻止结束当前请求(false可以进行请求);
      that.loading = true;
      let q = { page: that.page, limit: that.limit, type: that.currentActive };
      getReplyList(that.product_id, q).then(res => {
        that.loading = false;
        //apply();js将一个数组插入另一个数组;
        that.reply.push.apply(that.reply, res.data);
        that.loadend = res.data.length < that.limit; //判断所有数据是否加载完成;
        that.page = that.page + 1;
      });
    },
    changeType: function(index) {
      let that = this;
      that.currentActive = index;
      that.page = 1;
      that.loadend = false;
      that.$set(that, "reply", []);
      that.getProductReplyList();
    }
  }
};
</script>
<style scoped>
.noCommodity {
  height: 8rem;
  background-color: #fff;
}
</style>

GoodsClass.vue

<template>
  <div class="productSort">
    <form @submit.prevent="submitForm">
      <div class="header acea-row row-center-wrapper" ref="header">
        <div class="acea-row row-between-wrapper input">
          <span class="iconfont icon-sousuo"></span>
          <input type="text" placeholder="搜索商品信息" v-model="search" />
        </div>
      </div>
    </form>
    <div class="aside">
      <div
        class="item acea-row row-center-wrapper"
        :class="index === navActive ? 'on' : ''"
        v-for="(item, index) in category"
        :key="index"
        @click="asideTap(index)"
      >
        <span>{{ item.cate_name }}</span>
      </div>
    </div>
    <div class="conter" @scroll.native="onScroll">
      <div class="listw" v-for="(item, index) in category" :key="index">
        <div class="title acea-row row-center-wrapper" ref="title">
          <div class="line"></div>
          <div class="name">{{ item.cate_name }}</div>
          <div class="line"></div>
        </div>
        <div class="list acea-row">
          <router-link
            class="item acea-row row-column row-middle"
            v-for="(child, index) in item.children"
            :key="index"
            :to="{
              path: '/goods_list',
              query: { id: child.id, title: child.cate_name }
            }"
          >
            <div class="picture"><img :src="child.pic" /></div>
            <div class="name line1">{{ child.cate_name }}</div>
          </router-link>
        </div>
      </div>
    </div>
    <div style="height:1.2rem;"></div>
  </div>
</template>
<script>
import debounce from "lodash.debounce";
import { getCategory } from "@api/store";
import { trim } from "../../utils";

export default {
  name: "GoodsClass",
  components: {},
  props: {},
  data: function() {
    return {
      category: [],
      navActive: 0,
      search: "",
      lock: false
    };
  },
  watch: {
    "$route.params.pid": function(n) {
      console.log(n);
      if (n) {
        this.activeCateId(n);
      }
    }
  },
  mounted: function() {
    document.addEventListener("scroll", this.onScroll, false);
    this.loadCategoryData();
  },
  methods: {
    activeCateId(n) {
      let index = 0;
      n = parseInt(n);
      if (!n) return;
      this.category.forEach((cate, i) => {
        if (cate.id === n) index = i;
      });

      if (index !== this.navActive) {
        this.asideTap(index);
      }
    },
    loadCategoryData() {
      getCategory().then(res => {
        this.category = res.data;
        this.$nextTick(() => {
          if (this.$route.params.pid) this.activeCateId(this.$route.params.pid);
          else this.onScroll();
        });
      });
    },
    submitForm: function() {
      var val = trim(this.search);
      if (val) {
        this.$router.push({
          path: "/goods_list",
          query: { s: val }
        });
        setTimeout(() => (this.search = ""), 500);
      }
    },
    asideTap(index) {
      const top =
        this.$refs.title[index].offsetTop -
        this.$refs.header.offsetHeight -
        window.scrollY;

      this.lock = true;

      window.scrollBy({ top, left: 0, behavior: "smooth" });
      this.navActive = index;
    },
    onScroll: debounce(function() {
      if (this.lock) {
        this.lock = false;
        return;
      }
      const headerHeight = this.$refs.header.offsetHeight,
        { scrollY } = window,
        titles = this.$refs.title;
      titles.reduce((initial, title, index) => {
        if (initial) return initial;
        const parent = title.parentNode || title.parentElement;
        if (
          scrollY + headerHeight + 15 <
          title.offsetTop + parent.offsetHeight
        ) {
          initial = true;
          this.navActive = index;
        }
        // else if (innerHeight + scrollY + 15 > offsetHeight) {
        //   this.navActive = titles.length - 1;
        //   initial = true;
        // }
        return initial;
      }, false);
    }, 500)
  },
  beforeDestroy: function() {
    document.removeEventListener("scroll", this.onScroll, false);
  }
};
</script>

GoodsCollection.vue

<template>
  <div ref="container">
    <div class="collectionGoods" v-if="collectProductList.length > 0">
      <router-link
        :to="{ path: '/detail/' + item.pid }"
        class="item acea-row row-between-wrapper"
        v-for="(item, index) in collectProductList"
        :key="index"
      >
        <div class="pictrue"><img :src="item.image" /></div>
        <div class="text acea-row row-column-between">
          <div class="infor line1">{{ item.store_name }}</div>
          <div class="acea-row row-between-wrapper">
            <div class="money font-color-red">¥{{ item.price }}</div>
            <div class="delete" @click.prevent="delCollection(index)">删除</div>
          </div>
        </div>
      </router-link>
    </div>
    <Loading :loaded="loadend" :loading="loading"></Loading>
    <div
      class="noCommodity"
      style="background-color:#fff;"
      v-if="collectProductList.length < 1 && page > 1"
    >
      <div class="noPictrue">
        <img src="@assets/images/noCollection.png" class="image" />
      </div>
      <Recommend></Recommend>
    </div>
  </div>
</template>
<script>
import Recommend from "@components/Recommend";
import { getCollectUser, getCollectDel } from "@api/user";
import Loading from "@components/Loading";
export default {
  name: "GoodsCollection",
  components: {
    Recommend,
    Loading
  },
  props: {},
  data: function() {
    return {
      page: 1,
      limit: 20,
      collectProductList: [],
      loadTitle: "",
      loading: false,
      loadend: false
    };
  },
  mounted: function() {
    this.get_user_collect_product();
    this.$scroll(this.$refs.container, () => {
      !this.loading && this.get_user_collect_product();
    });
  },
  methods: {
    get_user_collect_product: function() {
      let that = this;
      if (that.loading) return; //阻止下次请求(false可以进行请求);
      if (that.loadend) return; //阻止结束当前请求(false可以进行请求);
      that.loading = true;
      getCollectUser(that.page, that.limit).then(res => {
        that.loading = false;
        //apply();js将一个数组插入另一个数组;
        that.collectProductList.push.apply(that.collectProductList, res.data);
        that.loadend = res.data.length < that.limit; //判断所有数据是否加载完成;
        that.page = that.page + 1;
      });
    },
    //删除收藏;
    delCollection: function(index) {
      let that = this,
        id = that.collectProductList[index].pid,
        category = that.collectProductList[index].category;
      getCollectDel(id, category).then(function() {
        that.$dialog.toast({
          mes: "删除收藏成功!",
          callback: () => {
            that.collectProductList.splice(index, 1);
            that.$set(that, "collectProductList", that.collectProductList);
          }
        });
      });
    }
  }
};
</script>

GoodsCon.vue

<template>
  <div
    :class="[posterImageStatus ? 'noscroll product-con' : 'product-con']"
    ref="box"
  >
    <product-con-swiper :img-urls="storeInfo.slider_image"></product-con-swiper>
    <div class="wrapper">
      <div class="share acea-row row-between row-bottom">
        <div class="money font-color-red">
          ¥<span class="num">{{ storeInfo.price }}</span
          ><span
            class="vip-money"
            v-if="storeInfo.vip_price && storeInfo.vip_price > 0"
            >¥{{ storeInfo.vip_price }}</span
          ><img
            src="@assets/images/vip.png"
            class="image"
            v-if="storeInfo.vip_price && storeInfo.vip_price > 0"
          />
        </div>
        <div class="iconfont icon-fenxiang" @click="listenerActionSheet"></div>
      </div>
      <div class="introduce">{{ storeInfo.store_name }}</div>
      <div class="label acea-row row-between-wrapper">
        <div>原价:¥{{ storeInfo.ot_price }}</div>
        <div>库存:{{ storeInfo.stock }}{{ storeInfo.unit_name }}</div>
        <div>销量:{{ storeInfo.fsales }}{{ storeInfo.unit_name }}</div>
      </div>
      <div
        class="coupon acea-row row-between-wrapper"
        @click="couponTap"
        v-if="couponList.length"
      >
        <div class="hide line1 acea-row">
          优惠券:
          <div
            class="activity"
            v-for="(item, index) in couponList"
            :key="index"
          >
            满{{ item.use_min_price }}减{{ item.coupon_price }}
          </div>
        </div>
        <div class="iconfont icon-jiantou"></div>
      </div>
    </div>
    <div class="attribute acea-row row-between-wrapper" @click="selecAttrTap">
      <div>
        {{ attrTxt }}:<span class="atterTxt">{{ attrValue }}</span>
      </div>
      <div class="iconfont icon-jiantou"></div>
    </div>
    <div class="store-info" v-if="system_store.id !== undefined">
      <div class="title">门店信息</div>
      <div class="info acea-row row-between-wrapper">
        <div class="picTxt acea-row row-between-wrapper">
          <div class="pictrue"><img :src="system_store.image" /></div>
          <div class="text">
            <div class="name line1">
              {{ system_store.name }}
            </div>
            <div class="address acea-row row-middle" @click="showChang">
              <span class="addressTxt line1">{{
                system_store._detailed_address
              }}</span
              ><span class="iconfont icon-youjian"></span>
            </div>
          </div>
        </div>
        <a
          class="iconfont icon-dadianhua01 font-color-red"
          :href="'tel:' + system_store.phone"
        ></a>
      </div>
    </div>
    <div class="userEvaluation" v-if="replyCount">
      <div class="title acea-row row-between-wrapper">
        <div>用户评价({{ replyCount }})</div>
        <router-link :to="{ path: '/evaluate_list/' + id }" class="praise"
          ><span class="font-color-red">{{ replyChance }}%</span>好评率<span
            class="iconfont icon-jiantou"
          ></span
        ></router-link>
      </div>
      <user-evaluation :reply="reply"></user-evaluation>
    </div>
    <div class="superior" v-if="goodList.length > 0">
      <div class="title acea-row row-center-wrapper">
        <img src="@assets/images/ling.png" />
        <div class="titleTxt">优品推荐</div>
        <img src="@assets/images/ling.png" />
      </div>
      <template>
        <div class="slider-banner banner">
          <swiper :options="swiperRecommend">
            <swiper-slide v-for="(item, index) in goodList" :key="index">
              <div class="list acea-row row-middle">
                <div
                  class="item"
                  v-for="val in item.list"
                  :key="val.image"
                  @click="goGoods(val)"
                >
                  <div class="pictrue">
                    <img :src="val.image" />
                  </div>
                  <div class="name line1">{{ val.store_name }}}</div>
                  <div class="money font-color-red">¥{{ val.price }}</div>
                </div>
              </div>
            </swiper-slide>
            <div class="swiper-pagination" slot="pagination"></div>
          </swiper>
        </div>
      </template>
    </div>
    <div class="product-intro">
      <div class="title">产品介绍</div>
      <div class="conter" v-html="storeInfo.description"></div>
    </div>
    <div style="height:1.2rem;"></div>
    <div class="footer acea-row row-between-wrapper">
      <div class="item" @click="$router.push({ path: '/customer/list' })">
        <div class="iconfont icon-kefu"></div>
        <div>客服</div>
      </div>
      <div class="item" @click="setCollect">
        <div
          class="iconfont"
          :class="storeInfo.userCollect ? 'icon-shoucang1' : 'icon-shoucang'"
        ></div>
        <div>收藏</div>
      </div>
      <router-link
        :to="'/cart'"
        class="item animated"
        :class="animated === true ? 'bounceIn' : ''"
      >
        <div class="iconfont icon-gouwuche1">
          <span class="num bg-color-red" v-if="CartCount > 0">{{
            CartCount
          }}</span>
        </div>
        <div>购物车</div>
      </router-link>
      <div class="bnt acea-row">
        <div class="joinCart" @click="joinCart">加入购物车</div>
        <div class="buy" @click="tapBuy">立即购买</div>
      </div>
    </div>
    <Share-red-packets
      :priceName="priceName"
      v-on:changeFun="changeFun"
      v-if="priceName !== 0"
    ></Share-red-packets>
    <CouponPop v-on:changeFun="changeFun" :coupon="coupon"></CouponPop>
    <Product-window v-on:changeFun="changeFun" :attr="attr"></Product-window>
    <StorePoster
      v-on:setPosterImageStatus="setPosterImageStatus"
      :posterImageStatus="posterImageStatus"
      :posterData="posterData"
    ></StorePoster>
    <ShareInfo
      v-on:setShareInfoStatus="setShareInfoStatus"
      :shareInfoStatus="shareInfoStatus"
    ></ShareInfo>
    <div
      class="generate-posters acea-row row-middle"
      :class="posters ? 'on' : ''"
    >
      <div
        class="item"
        v-if="weixinStatus === true"
        @click="setShareInfoStatus"
      >
        <div class="iconfont icon-weixin3"></div>
        <div class="">发送给朋友</div>
      </div>
      <div class="item" @click="setPosterImageStatus">
        <div class="iconfont icon-haibao"></div>
        <div class="">生成海报</div>
      </div>
    </div>
    <div
      class="mask"
      @touchmove.prevent
      @click="listenerActionClose"
      v-show="posters"
    ></div>
    <div class="geoPage" v-if="mapShow">
      <iframe
        width="100%"
        height="100%"
        frameborder="0"
        scrolling="no"
        :src="
          'https://apis.map.qq.com/uri/v1/geocoder?coord=' +
            system_store.latitude +
            ',' +
            system_store.longitude +
            '&referer=' +
            mapKey
        "
      >
      </iframe>
    </div>
  </div>
</template>
<style scoped>
.geoPage {
  position: fixed;
  width: 100%;
  height: 100%;
  top: 0;
  z-index: 10000;
}
.product-con .store-info {
  margin-top: 0.2rem;
  background-color: #fff;
}
.product-con .store-info .title {
  padding: 0 0.3rem;
  font-size: 0.28rem;
  color: #282828;
  height: 0.8rem;
  line-height: 0.8rem;
  border-bottom: 0.01rem solid #f5f5f5;
}
.product-con .store-info .info {
  padding: 0 0.3rem;
  height: 1.26rem;
}
.product-con .store-info .info .picTxt {
  width: 6.15rem;
}
.product-con .store-info .info .picTxt .pictrue {
  width: 0.76rem;
  height: 0.76rem;
}
.product-con .store-info .info .picTxt .pictrue img {
  width: 100%;
  height: 100%;
  border-radius: 0.06rem;
}
.product-con .store-info .info .picTxt .text {
  width: 5.22rem;
}
.product-con .store-info .info .picTxt .text .name {
  font-size: 0.3rem;
  color: #282828;
}
.product-con .store-info .info .picTxt .text .address {
  font-size: 0.24rem;
  color: #666;
  margin-top: 0.03rem;
}
.product-con .store-info .info .picTxt .text .address .iconfont {
  color: #707070;
  font-size: 0.18rem;
  margin-left: 0.1rem;
}
.product-con .store-info .info .picTxt .text .address .addressTxt {
  max-width: 4.8rem;
  width: auto;
}
.product-con .store-info .info .iconfont {
  font-size: 0.4rem;
}
.product-con .superior {
  background-color: #fff;
  margin-top: 0.2rem;
}
.product-con .superior .title {
  height: 0.98rem;
}
.product-con .superior .title img {
  width: 0.3rem;
  height: 0.3rem;
}
.product-con .superior .title .titleTxt {
  margin: 0 0.2rem;
  font-size: 0.3rem;
  background-image: linear-gradient(to right, #f57a37 0%, #f21b07 100%);
  background-image: -webkit-linear-gradient(to right, #f57a37 0%, #f21b07 100%);
  background-image: -moz-linear-gradient(to right, #f57a37 0%, #f21b07 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}
.product-con .superior .slider-banner {
  width: 6.9rem;
  margin: 0 auto;
  padding-bottom: 0.2rem;
}
.product-con .superior .slider-banner .list {
  width: 100%;
  padding-bottom: 0.2rem;
}
.product-con .superior .slider-banner .list .item {
  width: 2.15rem;
  margin: 0 0.22rem 0.3rem 0;
  font-size: 0.26rem;
}
.product-con .superior .slider-banner .list .item:nth-of-type(3n) {
  margin-right: 0;
}
.product-con .superior .slider-banner .list .item .pictrue {
  width: 100%;
  height: 2.15rem;
}
.product-con .superior .slider-banner .list .item .pictrue img {
  width: 100%;
  height: 100%;
  border-radius: 0.06rem;
}
.product-con .superior .slider-banner .list .item .name {
  color: #282828;
  margin-top: 0.12rem;
}
.product-con .superior .slider-banner .swiper-pagination-bullet {
  background-color: #999;
}
.product-con .superior .slider-banner .swiper-pagination-bullet-active {
  background-color: #e93323;
}

.mask {
  -webkit-filter: blur(2px);
  -moz-filter: blur(2px);
  -ms-filter: blur(2px);
  filter: blur(2px);
}
.footer .icon-shoucang1 {
  color: #e93323;
}
.product-con .product-intro .conter div {
  width: 100% !important;
}
.generate-posters {
  width: 100%;
  height: 1.7rem;
  background-color: #fff;
  position: fixed;
  left: 0;
  bottom: 0;
  z-index: 99;
  transform: translate3d(0, 100%, 0);
  -webkit-transform: translate3d(0, 100%, 0);
  -ms-transform: translate3d(0, 100%, 0);
  -moz-transform: translate3d(0, 100%, 0);
  -o-transform: translate3d(0, 100%, 0);
  transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9);
  -webkit-transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9);
  -moz-transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9);
  -o-transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9);
}
.generate-posters.on {
  transform: translate3d(0, 0, 0);
  -webkit-transform: translate3d(0, 0, 0);
  -ms-transform: translate3d(0, 0, 0);
  -moz-transform: translate3d(0, 0, 0);
  -o-transform: translate3d(0, 0, 0);
}
.generate-posters .item {
  flex: 50%;
  -webkit-flex: 50%;
  -ms-flex: 50%;
  text-align: center;
}
.generate-posters .item .iconfont {
  font-size: 0.8rem;
  color: #5eae72;
}
.generate-posters .item .iconfont.icon-haibao {
  color: #5391f1;
}
.noscroll {
  height: 100%;
  overflow: hidden;
}
</style>
<script>
import { swiper, swiperSlide } from "vue-awesome-swiper";
import "@assets/css/swiper.min.css";
import ProductConSwiper from "@components/ProductConSwiper";
import UserEvaluation from "@components/UserEvaluation";
import ShareRedPackets from "@components/ShareRedPackets";
import CouponPop from "@components/CouponPop";
import ProductWindow from "@components/ProductWindow";
import StorePoster from "@components/StorePoster";
import ShareInfo from "@components/ShareInfo";
import {
  getProductDetail,
  postCartAdd,
  getCartCount,
  getProductCode
} from "@api/store";
import {
  getCoupon,
  getCollectAdd,
  getCollectDel,
  getUserInfo
} from "@api/user";
import { isWeixin } from "@utils/index";
import { wechatEvevt } from "@libs/wechat";
import { imageBase64 } from "@api/public";
import { mapGetters } from "vuex";
let NAME = "GoodsCon";
export default {
  name: NAME,
  components: {
    swiper,
    swiperSlide,
    ProductConSwiper,
    UserEvaluation,
    ShareRedPackets,
    CouponPop,
    ProductWindow,
    StorePoster,
    ShareInfo
  },
  data: function() {
    return {
      shareInfoStatus: false,
      weixinStatus: false,
      mapShow: false,
      mapKey: "",
      posterData: {
        image: "",
        title: "",
        price: "",
        code: ""
      },
      posterImageStatus: false,
      animated: false,
      coupon: {
        coupon: false,
        list: []
      },
      attr: {
        cartAttr: false,
        productAttr: [],
        productSelect: {}
      },
      isOpen: false, //是否打开属性组件
      productValue: [],
      id: 0,
      storeInfo: {},
      couponList: [],
      attrTxt: "请选择",
      attrValue: "",
      cart_num: 1, //购买数量
      replyCount: "",
      replyChance: "",
      reply: [],
      priceName: 0,
      CartCount: 0,
      posters: false,
      banner: [{}, {}],
      swiperRecommend: {
        pagination: {
          el: ".swiper-pagination",
          clickable: true
        },
        autoplay: false,
        loop: false,
        speed: 1000,
        observer: true,
        observeParents: true
      },
      goodList: [],
      system_store: {},
      qqmapsdk: null
    };
  },
  computed: mapGetters(["isLogin"]),
  watch: {
    $route(n) {
      if (n.name === NAME) {
        this.id = n.params.id;
        this.productCon();
      }
    }
  },
  updated() {
    window.scroll(0, 0);
  },
  mounted: function() {
    this.id = this.$route.params.id;
    this.productCon();
    this.coupons();
  },
  methods: {
    showChang: function() {
      if (isWeixin()) {
        let config = {
          latitude: parseFloat(this.system_store.latitude),
          longitude: parseFloat(this.system_store.longitude),
          name: this.system_store.name,
          address: this.system_store._detailed_address
        };
        wechatEvevt("openLocation", config)
          .then(res => {
            console.log(res);
          })
          .catch(res => {
            if (res.is_ready) {
              res.wx.openLocation(config);
            }
          });
      } else {
        if (!this.mapKey)
          return this.$dialog.error(
            "暂无法使用查看地图,请配置您的腾讯地图key"
          );
        this.mapShow = true;
      }
    },
    updateTitle() {
      document.title = this.storeInfo.store_name || this.$route.meta.title;
    },
    setOpenShare: function() {
      var data = this.storeInfo;
      var href = location.href;
      if (isWeixin()) {
        if (this.isLogin) {
          getUserInfo().then(res => {
            href =
              href.indexOf("?") === -1
                ? href + "?spread=" + res.data.uid
                : href + "&spread=" + res.data.uid;
            var configAppMessage = {
              desc: data.store_info,
              title: data.store_name,
              link: href,
              imgUrl: data.image
            };
            wechatEvevt(
              ["updateAppMessageShareData", "updateTimelineShareData"],
              configAppMessage
            )
              .then(res => {
                console.log(res);
              })
              .catch(res => {
                console.log(res);
                if (res.is_ready) {
                  res.wx.updateAppMessageShareData(configAppMessage);
                  res.wx.updateTimelineShareData(configAppMessage);
                }
              });
          });
        } else {
          var configAppMessage = {
            desc: data.store_info,
            title: data.store_name,
            link: href,
            imgUrl: data.image
          };
          wechatEvevt(
            ["updateAppMessageShareData", "updateTimelineShareData"],
            configAppMessage
          )
            .then(res => {
              console.log(res);
            })
            .catch(res => {
              if (res.is_ready) {
                res.wx.updateAppMessageShareData(configAppMessage);
                res.wx.updateTimelineShareData(configAppMessage);
              }
            });
        }
      }
    },
    setShareInfoStatus: function() {
      this.shareInfoStatus = !this.shareInfoStatus;
      this.posters = false;
    },
    shareCode: function(value) {
      var that = this;
      getProductCode(that.id).then(res => {
        if (res.data.code) that.posterData.code = res.data.code;
        value === false && that.listenerActionSheet();
      });
    },
    setPosterImageStatus: function() {
      var sTop = document.body || document.documentElement;
      sTop.scrollTop = 0;
      this.posterImageStatus = !this.posterImageStatus;
      this.posters = false;
    },
    //产品详情接口;
    productCon: function() {
      let that = this;
      getProductDetail(that.id)
        .then(res => {
          that.$set(that, "storeInfo", res.data.storeInfo);
          that.$set(that.attr, "productAttr", res.data.productAttr);
          that.$set(that, "productValue", res.data.productValue);
          that.$set(that, "replyCount", res.data.replyCount);
          that.$set(that, "replyChance", res.data.replyChance);
          that.reply = res.data.reply ? [res.data.reply] : [];
          that.$set(that, "reply", that.reply);
          that.$set(that, "priceName", res.data.priceName);
          that.posterData.image = that.storeInfo.image_base;
          if (that.storeInfo.store_name.length > 30) {
            that.posterData.title =
              that.storeInfo.store_name.substring(0, 30) + "...";
          } else {
            that.posterData.title = that.storeInfo.store_name;
          }
          that.posterData.price = that.storeInfo.price;
          that.posterData.code = that.storeInfo.code_base;
          that.system_store = res.data.system_store;
          let good_list = res.data.good_list || [];
          let goodArray = [];
          let count = Math.ceil(good_list.length / 6);
          for (let i = 0; i < count; i++) {
            var list = good_list.slice(i * 6, 6);
            if (list.length) goodArray.push({ list: list });
          }
          that.mapKey = res.data.mapKey;
          that.$set(that, "goodList", goodArray);
          that.updateTitle();
          that.DefaultSelect();
          that.getCartCount();
          that.getImageBase64();
          that.setOpenShare();
        })
        .catch(res => {
          that.$dialog.error(res.msg);
          that.$router.go(-1);
        });
    },
    getImageBase64: function() {
      let that = this;
      imageBase64(this.posterData.image, that.posterData.code)
        .then(res => {
          that.posterData.image = res.data.image;
          that.posterData.code = res.data.code;
          that.isLogin && that.shareCode();
        })
        .catch(() => {
          that.isLogin && that.shareCode();
        });
    },
    //默认选中属性;
    DefaultSelect: function() {
      let productAttr = this.attr.productAttr;
      let value = [];
      for (let i = 0; i < productAttr.length; i++) {
        this.$set(productAttr[i], "index", 0);
        value.push(productAttr[i].attr_values[0]);
      }
      //sort();排序函数:数字-英文-汉字;
      let productSelect = this.productValue[value.sort().join(",")];
      if (productSelect && productAttr.length) {
        this.$set(
          this.attr.productSelect,
          "store_name",
          this.storeInfo.store_name
        );
        this.$set(this.attr.productSelect, "image", productSelect.image);
        this.$set(this.attr.productSelect, "price", productSelect.price);
        this.$set(this.attr.productSelect, "stock", productSelect.stock);
        this.$set(this.attr.productSelect, "unique", productSelect.unique);
        this.$set(this.attr.productSelect, "cart_num", 1);
        this.$set(this, "attrValue", value.sort().join(","));
        this.$set(this, "attrTxt", "已选择");
      } else if (!productSelect && productAttr.length) {
        this.$set(
          this.attr.productSelect,
          "store_name",
          this.storeInfo.store_name
        );
        this.$set(this.attr.productSelect, "image", this.storeInfo.image);
        this.$set(this.attr.productSelect, "price", this.storeInfo.price);
        this.$set(this.attr.productSelect, "stock", 0);
        this.$set(this.attr.productSelect, "unique", "");
        this.$set(this.attr.productSelect, "cart_num", 0);
        this.$set(this, "attrValue", "");
        this.$set(this, "attrTxt", "请选择");
      } else if (!productSelect && !productAttr.length) {
        this.$set(
          this.attr.productSelect,
          "store_name",
          this.storeInfo.store_name
        );
        this.$set(this.attr.productSelect, "image", this.storeInfo.image);
        this.$set(this.attr.productSelect, "price", this.storeInfo.price);
        this.$set(this.attr.productSelect, "stock", this.storeInfo.stock);
        this.$set(
          this.attr.productSelect,
          "unique",
          this.storeInfo.unique || ""
        );
        this.$set(this.attr.productSelect, "cart_num", 1);
        this.$set(this, "attrValue", "");
        this.$set(this, "attrTxt", "请选择");
      }
    },
    //购物车;
    ChangeCartNum: function(changeValue) {
      //changeValue:是否 加|减
      //获取当前变动属性
      let productSelect = this.productValue[this.attrValue];
      //如果没有属性,赋值给商品默认库存
      if (productSelect === undefined && !this.attr.productAttr.length)
        productSelect = this.attr.productSelect;
      //无属性值即库存为0;不存在加减;
      if (productSelect === undefined) return;
      let stock = productSelect.stock || 0;
      let num = this.attr.productSelect;
      if (changeValue) {
        num.cart_num++;
        if (num.cart_num > stock) {
          this.$set(this.attr.productSelect, "cart_num", stock);
          this.$set(this, "cart_num", stock);
        }
      } else {
        num.cart_num--;
        if (num.cart_num < 1) {
          this.$set(this.attr.productSelect, "cart_num", 1);
          this.$set(this, "cart_num", 1);
        }
      }
    },
    //将父级向子集多次传送的函数合二为一;
    changeFun: function(opt) {
      if (typeof opt !== "object") opt = {};
      let action = opt.action || "";
      let value = opt.value === undefined ? "" : opt.value;
      this[action] && this[action](value);
    },
    //打开优惠券插件;
    couponTap: function() {
      let that = this;
      that.coupons();
      that.coupon.coupon = true;
    },
    changecoupon: function(msg) {
      this.coupon.coupon = msg;
      this.coupons();
    },
    currentcoupon: function(res) {
      let that = this;
      that.coupon.coupon = false;
      that.$set(that.coupon.list[res], "is_use", true);
    },
    //可领取优惠券接口;
    coupons: function() {
      let that = this,
        q = { page: 1, limit: 20 };
      getCoupon(q).then(res => {
        that.$set(that, "couponList", res.data || []);
        that.$set(that.coupon, "list", res.data);
      });
    },
    //打开属性插件;
    selecAttrTap: function() {
      this.attr.cartAttr = true;
      this.isOpen = true;
    },
    changeattr: function(msg) {
      this.attr.cartAttr = msg;
      this.isOpen = false;
    },
    //选择属性;
    ChangeAttr: function(res) {
      let productSelect = this.productValue[res];
      if (productSelect) {
        this.$set(this.attr.productSelect, "image", productSelect.image);
        this.$set(this.attr.productSelect, "price", productSelect.price);
        this.$set(this.attr.productSelect, "stock", productSelect.stock);
        this.$set(this.attr.productSelect, "unique", productSelect.unique);
        this.$set(this.attr.productSelect, "cart_num", 1);
        this.$set(this, "attrValue", res);
        this.$set(this, "attrTxt", "已选择");
      } else {
        this.$set(this.attr.productSelect, "image", this.storeInfo.image);
        this.$set(this.attr.productSelect, "price", this.storeInfo.price);
        this.$set(this.attr.productSelect, "stock", 0);
        this.$set(this.attr.productSelect, "unique", "");
        this.$set(this.attr.productSelect, "cart_num", 0);
        this.$set(this, "attrValue", "");
        this.$set(this, "attrTxt", "请选择");
      }
    },
    //收藏商品
    setCollect: function() {
      let that = this,
        id = that.storeInfo.id,
        category = "product";
      if (that.storeInfo.userCollect) {
        getCollectDel(id, category).then(function() {
          that.storeInfo.userCollect = !that.storeInfo.userCollect;
        });
      } else {
        getCollectAdd(id, category).then(function() {
          that.storeInfo.userCollect = !that.storeInfo.userCollect;
        });
      }
    },
    goGoods(val) {
      return this.$router.push({ path: "/detail/" + val.id });
    },
    //  点击加入购物车按钮
    joinCart: function() {
      //0=加入购物车
      this.goCat(0);
    },
    // 加入购物车;
    goCat: function(news) {
      let that = this,
        productSelect = that.productValue[this.attrValue];
      //打开属性
      if (that.attrValue) {
        //默认选中了属性,但是没有打开过属性弹窗还是自动打开让用户查看默认选中的属性
        that.attr.cartAttr = !that.isOpen ? true : false;
      } else {
        if (that.isOpen) that.attr.cartAttr = true;
        else that.attr.cartAttr = !that.attr.cartAttr;
      }
      //只有关闭属性弹窗时进行加入购物车
      if (that.attr.cartAttr === true && that.isOpen === false)
        return (that.isOpen = true);
      //如果有属性,没有选择,提示用户选择
      if (
        that.attr.productAttr.length &&
        productSelect === undefined &&
        that.isOpen === true
      )
        return that.$dialog.toast({ mes: "产品库存不足,请选择其它" });
      let q = {
        productId: that.id,
        cartNum: that.attr.productSelect.cart_num,
        new: news,
        uniqueId:
          that.attr.productSelect !== undefined
            ? that.attr.productSelect.unique
            : ""
      };
      postCartAdd(q)
        .then(function(res) {
          that.isOpen = false;
          that.attr.cartAttr = false;
          if (news) {
            that.$router.push({ path: "/order/submit/" + res.data.cartId });
          } else {
            that.$dialog.toast({
              mes: "添加购物车成功",
              callback: () => {
                that.getCartCount(true);
              }
            });
          }
        })
        .catch(res => {
          that.isOpen = false;
          return that.$dialog.toast({ mes: res.msg });
        });
    },
    //获取购物车数量
    getCartCount: function(isAnima) {
      let that = this;
      const isLogin = that.isLogin;
      if (isLogin) {
        getCartCount({ numType: 0 }).then(res => {
          that.CartCount = res.data.count;
          //加入购物车后重置属性
          if (isAnima) {
            that.animated = true;
            setTimeout(function() {
              that.animated = false;
            }, 500);
          }
        });
      }
    },
    //立即购买;
    tapBuy: function() {
      //  1=直接购买
      this.goCat(1);
    },
    listenerActionSheet: function() {
      if (isWeixin() === true) {
        this.weixinStatus = true;
      }
      this.posters = true;
    },
    listenerActionClose: function() {
      this.posters = false;
    }
  }
};
</script>

GoodSearch.vue

<template>
  <div>
    <div class="searchGood">
      <div class="search acea-row row-between-wrapper">
        <div class="input acea-row row-between-wrapper">
          <span class="iconfont icon-sousuo2"></span>
          <form @submit.prevent="submit"></form>
          <input type="text" placeholder="点击搜索商品" v-model="search" />
        </div>
        <div class="bnt" @click="submit">搜索</div>
      </div>
      <div v-if="keywords.length">
        <div class="title">热门搜索</div>
        <div class="list acea-row">
          <div
            class="item"
            v-for="key of keywords"
            :key="key"
            @click="toSearch(key)"
          >
            {{ key }}
          </div>
        </div>
      </div>
      <div class="line"></div>
      <!--      <GoodList></GoodList>-->
    </div>
    <!--<div class="noCommodity">-->
    <!--<div class="noPictrue">-->
    <!--<img src="@assets/images/noSearch.png" class="image" />-->
    <!--</div>-->
    <!--<recommend></recommend>-->
    <!--</div>-->
  </div>
</template>
<script>
// import GoodList from "@components/GoodList";
import { getSearchKeyword } from "@api/store";
import { trim } from "@utils";
// import Recommend from "@components/Recommend";
export default {
  name: "GoodSearch",
  components: {
    // Recommend,
    // GoodList
  },
  props: {},
  data: function() {
    return {
      keywords: [],
      search: ""
    };
  },
  mounted: function() {
    this.getData();
  },
  methods: {
    submit() {
      const search = trim(this.search) || "";
      if (!search) return;
      this.toSearch(search);
    },
    toSearch(s) {
      this.$router.push({ path: "/goods_list", query: { s } });
    },
    getData() {
      getSearchKeyword().then(res => {
        this.keywords = res.data;
      });
    }
  }
};
</script>
<style scoped>
.noCommodity {
  border-top: 0.05rem solid #f5f5f5;
}
</style>

GoodsEvaluate.vue

<template>
  <div class="evaluate-con">
    <div class="goodsStyle acea-row row-between" v-if="orderCon.productInfo">
      <div class="pictrue">
        <img :src="orderCon.productInfo.image" class="image" />
      </div>
      <div class="text acea-row row-between">
        <div class="name line2">
          {{ orderCon.productInfo.store_name }}
        </div>
        <div class="money">
          <div>¥{{ orderCon.productInfo.price }}</div>
          <div class="num">x{{ orderCon.cart_num }}</div>
        </div>
      </div>
    </div>
    <div class="score">
      <div
        class="item acea-row row-middle"
        v-for="(item, indexw) in scoreList"
        :key="indexw"
      >
        <div>{{ item.name }}</div>
        <div class="starsList">
          <span
            @click="stars(indexn, indexw)"
            v-for="(itemn, indexn) in item.stars"
            :key="indexn"
            class="iconfont"
            :class="
              item.index >= indexn
                ? 'icon-shitixing font-color-red'
                : 'icon-kongxinxing'
            "
          ></span>
        </div>
        <span class="evaluate">{{
          item.index === -1 ? "" : item.index + 1 + "分"
        }}</span>
      </div>
      <div class="textarea">
        <textarea
          placeholder="商品满足你的期待么?说说你的想法,分享给想买的他们吧~"
          v-model="expect"
        ></textarea>
        <div class="list acea-row row-middle">
          <div
            class="pictrue"
            v-for="(item, index) in uploadPictures"
            :key="index"
          >
            <img :src="item" />
            <span
              class="iconfont icon-guanbi1 font-color-red"
              @click="uploadPictures.splice(index, 1)"
            ></span>
          </div>
          <VueCoreImageUpload
            class="btn btn-primary"
            :crop="false"
            compress="80"
            @imageuploaded="imageuploaded"
            :headers="headers"
            :max-file-size="5242880"
            :credentials="false"
            inputAccept="image/*"
            inputOfFile="file"
            :url="url"
            v-if="uploadPictures.length < 8"
          >
            <div
              class="pictrue uploadBnt acea-row row-center-wrapper row-column"
            >
              <span class="iconfont icon-icon25201"></span>
              <div>上传图片</div>
            </div>
          </VueCoreImageUpload>
        </div>
      </div>
      <div class="evaluateBnt bg-color-red" @click="submit">立即评价</div>
    </div>
  </div>
</template>
<style scoped>
.evaluate-con .score .textarea .list .pictrue.uploadBnt {
  border: 1px solid #ddd;
}
</style>
<script>
import { postOrderProduct, postOrderComment } from "@api/store";
import { trim, VUE_APP_API_URL } from "@utils";
import { required } from "@utils/validate";
import VueCoreImageUpload from "vue-core-image-upload";
import { validatorDefaultCatch } from "@utils/dialog";

const NAME = "GoodsEvaluate";

export default {
  name: NAME,
  components: {
    VueCoreImageUpload
  },
  props: {},
  data: function() {
    return {
      orderCon: {
        cartProduct: {
          productInfo: {}
        }
      },
      scoreList: [
        {
          name: "商品质量",
          stars: ["", "", "", "", ""],
          index: -1
        },
        {
          name: "服务态度",
          stars: ["", "", "", "", ""],
          index: -1
        }
      ],
      url: `${VUE_APP_API_URL}/upload/image`,
      headers: {
        "Authori-zation": "Bearer " + this.$store.state.app.token
      },
      uploadPictures: [],
      expect: "",
      unique: this.$route.params.id
    };
  },
  mounted: function() {
    this.getOrderProduct();
  },
  watch: {
    $route(n) {
      if (n.name === NAME && this.unique !== n.params.id) {
        this.unique = n.params.id;
        this.$set(this.scoreList[0], "index", -1);
        this.$set(this.scoreList[1], "index", -1);
        this.expect = "";
        this.uploadPictures = [];
        this.getOrderProduct();
      }
    }
  },
  methods: {
    getOrderProduct: function() {
      let that = this,
        unique = that.unique;
      postOrderProduct(unique).then(res => {
        that.orderCon = res.data;
      });
    },
    stars: function(indexn, indexw) {
      this.scoreList[indexw].index = indexn;
    },
    imageuploaded(res) {
      if (res.status !== 200)
        return this.$dialog.error(res.msg || "上传图片失败");
      this.uploadPictures.push(res.data.url);
    },
    async submit() {
      const expect = trim(this.expect),
        product_score =
          this.scoreList[0].index + 1 === 0 ? "" : this.scoreList[0].index + 1,
        service_score =
          this.scoreList[1].index + 1 === 0 ? "" : this.scoreList[1].index + 1;
      try {
        await this.$validator({
          product_score: [
            required("请选择商品质量分数", {
              type: "number"
            })
          ],
          service_score: [
            required("请选择服务态度分数", {
              type: "number"
            })
          ]
        }).validate({ product_score, service_score });
      } catch (e) {
        return validatorDefaultCatch(e);
      }
      postOrderComment({
        product_score: product_score,
        service_score: service_score,
        unique: this.unique,
        pics: this.uploadPictures.join(","),
        comment: expect
      })
        .then(() => {
          this.$dialog.success("评价成功");
          this.$router.replace({
            path: "/order/detail/" + this.orderCon.order_id
          });
        })
        .catch(res => {
          this.$dialog.error(res.msg);
        });
    }
  }
};
</script>

GoodsList.vue

<template>
  <div class="productList" ref="container">
    <form @submit.prevent="submitForm">
      <div class="search bg-color-red acea-row row-between-wrapper">
        <div class="input acea-row row-between-wrapper">
          <span class="iconfont icon-sousuo"></span>
          <input placeholder="搜索商品信息" v-model="where.keyword" />
        </div>
        <div
          class="iconfont"
          :class="Switch === true ? 'icon-pailie' : 'icon-tupianpailie'"
          @click="switchTap"
        ></div>
      </div>
    </form>
    <div class="nav acea-row row-middle">
      <div
        class="item"
        :class="title ? 'font-color-red' : ''"
        @click="set_where(0)"
      >
        {{ title ? title : "默认" }}
      </div>
      <div class="item" @click="set_where(1)">
        价格
        <img src="@assets/images/horn.png" v-if="price === 0" />
        <img src="@assets/images/up.png" v-if="price === 1" />
        <img src="@assets/images/down.png" v-if="price === 2" />
      </div>
      <div class="item" @click="set_where(2)">
        销量
        <img src="@assets/images/horn.png" v-if="stock === 0" />
        <img src="@assets/images/up.png" v-if="stock === 1" />
        <img src="@assets/images/down.png" v-if="stock === 2" />
      </div>
      <!-- down -->
      <div
        class="item"
        :class="nows ? 'font-color-red' : ''"
        @click="set_where(3)"
      >
        新品
      </div>
    </div>
    <div
      class="list acea-row row-between-wrapper"
      :class="Switch === true ? '' : 'on'"
      ref="container"
    >
      <router-link
        :to="{
          path: '/detail/' + item.id
        }"
        class="item"
        :class="Switch === true ? '' : 'on'"
        v-for="(item, index) in productList"
        :key="index"
        :title="item.store_name"
      >
        <div class="pictrue" :class="Switch === true ? '' : 'on'">
          <img :src="item.image" :class="Switch === true ? '' : 'on'" />
        </div>
        <div class="text" :class="Switch === true ? '' : 'on'">
          <div class="name line1">{{ item.store_name }}</div>
          <div
            class="money font-color-red"
            :class="Switch === true ? '' : 'on'"
          >
            ¥<span class="num">{{ item.price }}</span>
          </div>
          <div
            class="vip acea-row row-between-wrapper"
            :class="Switch === true ? '' : 'on'"
          >
            <div class="vip-money" v-if="item.vip_price && item.vip_price > 0">
              ¥{{ item.vip_price }}<img src="@assets/images/vip.png" />
            </div>
            <div>已售{{ item.sales }}件</div>
          </div>
        </div>
      </router-link>
    </div>
    <Loading :loaded="loadend" :loading="loading"></Loading>
    <div
      class="noCommodity"
      v-cloak
      style="background-color: #fff;"
      v-if="productList.length === 0 && where.page > 1"
    >
      <div class="noPictrue">
        <img src="@assets/images/noGood.png" class="image" />
      </div>
    </div>
    <Recommend v-if="productList.length === 0 && where.page > 1"></Recommend>
  </div>
</template>
<script>
import Recommend from "@components/Recommend";
import { getProducts } from "@api/store";
import debounce from "lodash.debounce";
import Loading from "@components/Loading";

export default {
  name: "GoodsList",
  components: {
    Recommend,
    Loading
  },
  props: {},
  data: function() {
    const { s = "", id = 0, title = "" } = this.$route.query;

    return {
      hostProduct: [],
      productList: [],
      Switch: true,
      where: {
        page: 1,
        limit: 8,
        keyword: s,
        sid: id, //二级分类id
        news: 0,
        priceOrder: "",
        salesOrder: ""
      },
      title: title && id ? title : "",
      loadTitle: "",
      loading: false,
      loadend: false,
      price: 0,
      stock: 0,
      nows: false
    };
  },
  watch: {
    title() {
      this.updateTitle();
    },
    $route(to) {
      if (to.name !== "GoodsList") return;
      const { s = "", id = 0, title = "" } = to.query;

      if (s !== this.where.keyword || id !== this.where.sid) {
        this.where.keyword = s;
        this.loadend = false;
        this.loading = false;
        this.where.page = 1;
        this.where.sid = id;
        this.title = title && id ? title : "";
        this.nows = false;
        this.$set(this, "productList", []);
        this.price = 0;
        this.stock = 0;
        this.get_product_list();
      }
    }
  },
  mounted: function() {
    this.updateTitle();
    this.get_product_list();
    this.$scroll(this.$refs.container, () => {
      !this.loading && this.get_product_list();
    });
  },
  methods: {
    updateTitle() {
      document.title = this.title || this.$route.meta.title;
    },
    get_product_list: debounce(function() {
      var that = this;
      if (that.loading) return; //阻止下次请求(false可以进行请求);
      if (that.loadend) return; //阻止结束当前请求(false可以进行请求);
      that.loading = true;
      this.setWhere();
      let q = that.where;
      getProducts(q).then(res => {
        that.loading = false;
        that.productList.push.apply(that.productList, res.data);
        that.loadend = res.data.length < that.where.limit; //判断所有数据是否加载完成;
        that.where.page = that.where.page + 1;
      });
    }, 300),
    submitForm: function() {
      this.$set(this, "productList", []);
      this.where.page = 1;
      this.loadend = false;
      this.loading = false;
      this.get_product_list();
    },
    //点击事件处理
    set_where: function(index) {
      let that = this;
      switch (index) {
        case 0:
          return that.$router.push({ path: "/category" });
        case 1:
          if (that.price === 0) that.price = 1;
          else if (that.price === 1) that.price = 2;
          else if (that.price === 2) that.price = 0;
          that.stock = 0;
          break;
        case 2:
          if (that.stock === 0) that.stock = 1;
          else if (that.stock === 1) that.stock = 2;
          else if (that.stock === 2) that.stock = 0;
          that.price = 0;
          break;
        case 3:
          that.nows = !that.nows;
          break;
        default:
          break;
      }
      that.$set(that, "productList", []);
      that.where.page = 1;
      that.loadend = false;
      that.get_product_list();
    },
    //设置where条件
    setWhere: function() {
      let that = this;
      if (that.price === 0) {
        that.where.priceOrder = "";
      } else if (that.price === 1) {
        that.where.priceOrder = "asc";
      } else if (that.price === 2) {
        that.where.priceOrder = "desc";
      }
      if (that.stock === 0) {
        that.where.salesOrder = "";
      } else if (that.stock === 1) {
        that.where.salesOrder = "asc";
      } else if (that.stock === 2) {
        that.where.salesOrder = "desc";
      }
      that.where.news = that.nows ? "1" : "0";
    },
    switchTap: function() {
      let that = this;
      that.Switch = !that.Switch;
    }
  }
};
</script>
<style scoped>
.noCommodity {
  border-top: 3px solid #f5f5f5;
  padding-bottom: 1px;
}
</style>

GoodsPromotion.vue

<template>
  <div class="quality-recommend">
    <div class="slider-banner swiper">
      <swiper class="swiper-wrapper" :options="RecommendSwiper">
        <swiperSlide
          class="swiper-slide"
          v-for="(item, index) in imgUrls"
          :key="index"
        >
          <img :src="item.img" class="slide-image" />
        </swiperSlide>
      </swiper>
      <div class="swiper-pagination"></div>
    </div>
    <div class="title acea-row row-center-wrapper">
      <div class="line"></div>
      <div class="name">
        <span class="iconfont icon-cuxiaoguanli"></span>促销单品
      </div>
      <div class="line"></div>
    </div>
    <Promotion-good :benefit="goodsList"></Promotion-good>
  </div>
</template>
<script>
import { swiper, swiperSlide } from "vue-awesome-swiper";
import "@assets/css/swiper.min.css";
import PromotionGood from "@components/PromotionGood";
import { getGroomList } from "@api/store";
export default {
  name: "GoodsPromotion",
  components: {
    swiper,
    swiperSlide,
    PromotionGood
  },
  props: {},
  data: function() {
    return {
      imgUrls: [],
      goodsList: [],
      RecommendSwiper: {
        pagination: {
          el: ".swiper-pagination",
          clickable: true
        },
        autoplay: {
          disableOnInteraction: false,
          delay: 2000
        },
        loop: true,
        speed: 1000,
        observer: true,
        observeParents: true
      }
    };
  },
  mounted: function() {
    this.getIndexGroomList();
  },
  methods: {
    getIndexGroomList: function() {
      let that = this;
      getGroomList(4)
        .then(res => {
          that.imgUrls = res.data.banner;
          that.goodsList = res.data.list;
        })
        .catch(function(res) {
          this.$dialog.toast({ mes: res.msg });
        });
    }
  }
};
</script>

HotNewGoods.vue

<template>
  <div class="quality-recommend">
    <div class="slider-banner swiper">
      <swiper class="swiper-wrapper" :options="RecommendSwiper">
        <swiperSlide
          class="swiper-slide"
          v-for="(item, index) in imgUrls"
          :key="index"
        >
          <img :src="item.img" class="slide-image" />
        </swiperSlide>
      </swiper>
      <div class="swiper-pagination"></div>
    </div>
    <div class="title acea-row row-center-wrapper">
      <div class="line"></div>
      <div class="name">
        <span class="iconfont" :class="icon"></span>{{ name }}
      </div>
      <div class="line"></div>
    </div>
    <GoodList :good-list="goodsList" :is-sort="false"></GoodList>
  </div>
</template>
<script>
import { swiper, swiperSlide } from "vue-awesome-swiper";
import "@assets/css/swiper.min.css";
import GoodList from "@components/GoodList";
import { getGroomList } from "@api/store";
export default {
  name: "HotNewGoods",
  components: {
    swiper,
    swiperSlide,
    GoodList
  },
  props: {},
  data: function() {
    return {
      imgUrls: [],
      goodsList: [],
      name: "",
      icon: "",
      RecommendSwiper: {
        pagination: {
          el: ".swiper-pagination",
          clickable: true
        },
        autoplay: {
          disableOnInteraction: false,
          delay: 2000
        },
        loop: true,
        speed: 1000,
        observer: true,
        observeParents: true
      }
    };
  },
  mounted: function() {
    this.titleInfo();
    this.getIndexGroomList();
  },
  methods: {
    titleInfo: function() {
      let type = this.$route.params.type;
      if (type === "1") {
        this.name = "精品推荐";
        this.icon = "icon-jingpintuijian";
        document.title = "精品推荐";
      } else if (type === "2") {
        this.name = "热门榜单";
        this.icon = "icon-remen";
        document.title = "热门榜单";
      } else if (type === "3") {
        this.name = "首发新品";
        this.icon = "icon-xinpin";
        document.title = "首发新品";
      }
    },
    getIndexGroomList: function() {
      let that = this;
      let type = this.$route.params.type;
      console.log(type);
      getGroomList(type)
        .then(res => {
          that.imgUrls = res.data.banner;
          that.goodsList = res.data.list;
          console.log(res.data.list);
        })
        .catch(function(res) {
          this.$dialog.toast({ mes: res.msg });
        });
    }
  }
};
</script>

news
NewsDetail.vue

<template>
  <div class="newsDetail">
    <div class="title">{{ articleInfo.title }}</div>
    <div class="list acea-row row-middle">
      <div class="label cart-color line1">{{ articleInfo.cart_name }}</div>
      <div class="item">
        <span class="iconfont icon-shenhezhong"></span
        >{{ articleInfo.add_time }}
      </div>
      <div class="item">
        <span class="iconfont icon-liulan"></span>{{ articleInfo.visit }}
      </div>
    </div>
    <div class="conter" v-html="articleInfo.content"></div>
    <div class="picTxt acea-row row-between-wrapper" v-if="storeInfo.id">
      <div class="pictrue"><img :src="storeInfo.image" /></div>
      <div class="text">
        <div class="name line1">{{ storeInfo.store_name }}</div>
        <div class="money font-color-red">
          ¥<span class="num">{{ storeInfo.ot_price }}</span>
        </div>
        <div class="y_money">¥{{ storeInfo.price }}</div>
      </div>
      <router-link :to="{ path: '/detail/' + storeInfo.id }">
        <div class="label"><span class="span">查看商品</span></div>
      </router-link>
    </div>
    <div class="bnt bg-color-red" v-if="isWeixin" @click="setShareInfoStatus">
      和好友一起分享
    </div>
    <ShareInfo
      v-on:setShareInfoStatus="setShareInfoStatus"
      :shareInfoStatus="shareInfoStatus"
    ></ShareInfo>
  </div>
</template>
<style scoped>
.newsDetail .picTxt {
  width: 6.9rem;
  height: 2rem !important;
  border-radius: 0.2rem;
  border: 1px solid #e1e1e1;
  position: relative;
  margin: 0.3rem auto 0 auto;
}
.newsDetail .picTxt .pictrue {
  width: 2rem;
  height: 2rem;
}
.newsDetail .picTxt .pictrue img {
  width: 100%;
  height: 100%;
  border-radius: 0.2rem 0 0 0.2rem;
  display: block;
}
.newsDetail .picTxt .text {
  width: 4.6rem;
}
.newsDetail .picTxt .text .name {
  font-size: 0.3rem;
  color: #282828;
}
.newsDetail .picTxt .text .money {
  font-size: 0.24rem;
  margin-top: 0.4rem;
  font-weight: bold;
}
.newsDetail .picTxt .text .money .num {
  font-size: 0.36rem;
}
.newsDetail .picTxt .text .y_money {
  font-size: 0.26rem;
  color: #999;
  text-decoration: line-through;
}
.newsDetail .picTxt .label {
  position: absolute;
  background-color: #303131;
  width: 1.6rem;
  height: 0.5rem;
  right: -0.07rem;
  border-radius: 0.25rem 0 0.06rem 0.25rem;
  text-align: center;
  line-height: 0.5rem;
  bottom: 0.24rem;
}
.newsDetail .picTxt .label .span {
  background-image: linear-gradient(to right, #fff71e 0%, #f9b513 100%);
  background-image: -webkit-linear-gradient(to right, #fff71e 0%, #f9b513 100%);
  background-image: -moz-linear-gradient(to right, #fff71e 0%, #f9b513 100%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}
.newsDetail .picTxt .label:after {
  content: " ";
  position: absolute;
  width: 0;
  height: 0;
  border-bottom: 0.08rem solid #303131;
  border-right: 0.08rem solid transparent;
  top: -0.08rem;
  right: 0;
}
.newsDetail .bnt {
  color: #fff;
  font-size: 0.3rem;
  width: 6.9rem;
  height: 0.9rem;
  border-radius: 0.45rem;
  margin: 0.48rem auto 0 auto;
  text-align: center;
  line-height: 0.9rem;
}
</style>
<script>
import { getArticleDetails } from "@api/public";
import ShareInfo from "@components/ShareInfo";
import { isWeixin } from "@utils/index";
import { openShareAll } from "@libs/wechat";

export default {
  name: "NewsDetail",
  components: { ShareInfo },
  props: {},
  data: function() {
    return {
      articleInfo: {},
      storeInfo: {},
      shareInfoStatus: false,
      isWeixin: isWeixin()
    };
  },
  watch: {
    $route(to) {
      if (to.name === "NewsDetail") this.articleDetails();
    }
  },
  mounted: function() {
    this.articleDetails();
  },
  methods: {
    updateTitle() {
      document.title = this.articleInfo.title || this.$route.meta.title;
    },
    articleDetails: function() {
      let that = this,
        id = this.$route.params.id;
      getArticleDetails(id).then(res => {
        that.articleInfo = res.data;
        that.storeInfo = res.data.store_info || {};
        that.updateTitle();
        if (that.isWeixin) that.share();
      });
    },
    setShareInfoStatus: function() {
      this.shareInfoStatus = !this.shareInfoStatus;
    },
    share: function() {
      openShareAll({
        desc: this.articleInfo.synopsis,
        title: this.articleInfo.title,
        link: location.href,
        imgUrl: this.articleInfo.image_input.length
          ? this.articleInfo.image_input[0]
          : ""
      });
    }
  }
};
</script>

NewsList.vue

<template>
  <div class="newsList" ref="container">
    <div class="slider-banner swiperNews" v-if="imgUrls.length > 0">
      <swiper class="swiper-wrapper" :options="swiperNew">
        <swiperSlide
          class="swiper-slide"
          v-for="(item, index) in imgUrls"
          :key="index"
        >
          <img :src="item.image_input[0]" class="slide-image" />
        </swiperSlide>
      </swiper>
      <div class="swiper-pagination"></div>
    </div>
    <Tabs
      @click="onClick"
      class="newsSwitch"
      line-height="0.04rem"
      line-width="0.24rem"
      color="#e93323"
      v-model="active"
      animated
      title-inactive-color="2"
      nav-right="0.46rem"
      sticky
    >
      <Tab
        v-for="(item, index) in navLsit"
        :key="index"
        :title="item.title"
        title-inactive-color="#999"
        title-active-color="#282828"
      >
        <div class="list" v-for="(item, index) in articleList" :key="index">
          <router-link
            :to="{ path: '/news_detail/' + item.id }"
            class="item acea-row row-between-wrapper"
            v-if="item.image_input.length === 1"
          >
            <div class="text acea-row row-column-between">
              <div class="name line2">{{ item.title }}</div>
              <div>{{ item.add_time }}</div>
            </div>
            <div class="pictrue"><img :src="item.image_input[0]" /></div>
          </router-link>
          <router-link
            :to="{ path: '/news_detail/' + item.id }"
            class="item"
            v-if="item.image_input.length === 2"
          >
            <div class="title line1">
              {{ item.title }}
            </div>
            <div class="picList acea-row row-between-wrapper">
              <div
                class="pictrue"
                v-for="(itemImg, index) in item.image_input"
                :key="index"
              >
                <img :src="itemImg" />
              </div>
            </div>
            <div class="time">{{ item.add_time }}</div>
          </router-link>
          <router-link
            :to="{ path: '/news_detail/' + item.id }"
            class="item"
            v-if="item.image_input.length === 3"
          >
            <div class="title line1">
              {{ item.title }}
            </div>
            <div class="picList on acea-row row-between-wrapper">
              <div
                class="pictrue"
                v-for="(itemImg, index) in item.image_input"
                :key="index"
              >
                <img :src="itemImg" />
              </div>
            </div>
            <div class="time">{{ item.add_time }}</div>
          </router-link>
        </div>
        <Loading
          :loaded="loadend"
          :loading="loading"
          v-if="index > 0 && articleList.length > 0"
        ></Loading>
        <!--暂无新闻-->
        <div class="noCommodity" v-if="articleList.length === 0 && page > 1">
          <div class="noPictrue">
            <img src="@assets/images/noNews.png" class="image" />
          </div>
        </div>
      </Tab>
    </Tabs>
  </div>
</template>
<script>
import { swiper, swiperSlide } from "vue-awesome-swiper";
import "@assets/css/swiper.min.css";
import { Tab, Tabs } from "vant";
import {
  getArticleBanner,
  getArticleCategory,
  getArticleHotList,
  getArticleList
} from "@api/public";
import Loading from "@components/Loading";

export default {
  name: "NewsList",
  components: {
    swiper,
    swiperSlide,
    Tab,
    Tabs,
    Loading
  },
  props: {},
  data: function() {
    return {
      page: 1,
      limit: 20,
      loadTitle: "",
      loading: false,
      loadend: false,
      imgUrls: [],
      navLsit: [],
      articleList: [],
      active: 0,
      cid: 0,
      swiperNew: {
        pagination: {
          el: ".swiper-pagination",
          clickable: true
        },
        autoplay: {
          disableOnInteraction: false,
          delay: 2000
        },
        loop: true,
        speed: 1000,
        observer: true,
        observeParents: true
      }
    };
  },
  mounted: function() {
    this.articleBanner();
    this.articleCategory();
    this.articleHotList();
    this.$scroll(this.$refs.container, () => {
      !this.loading && this.getArticleLists();
    });
  },
  methods: {
    articleBanner: function() {
      let that = this;
      getArticleBanner().then(res => {
        that.imgUrls = res.data;
      });
    },
    articleCategory: function() {
      let that = this;
      getArticleCategory().then(res => {
        that.navLsit = res.data;
      });
    },
    articleHotList: function() {
      let that = this;
      getArticleHotList().then(res => {
        that.articleList = res.data;
      });
    },
    getArticleLists: function() {
      let that = this;
      if (that.loading) return; //阻止下次请求(false可以进行请求);
      if (that.loadend) return; //阻止结束当前请求(false可以进行请求);
      that.loading = true;
      let q = {
        page: that.page,
        limit: that.limit
      };
      getArticleList(q, that.cid).then(res => {
        that.loading = false;
        //apply();js将一个数组插入另一个数组;
        that.articleList.push.apply(that.articleList, res.data);
        that.loadend = res.data.length < that.limit; //判断所有数据是否加载完成;
        that.page = that.page + 1;
      });
    },
    onClick: function(name) {
      if (name === 0) this.articleHotList();
      else {
        this.cid = this.navLsit[name].id;
        this.articleList = [];
        this.page = 1;
        this.loadend = false;
        this.loading = false;
        this.getArticleLists(name);
      }
    }
  }
};
</script>

ShoppingCart.vue

<template>
  <div class="shoppingCart">
    <div class="labelNav acea-row row-around row-middle">
      <div class="item">
        <span class="iconfont icon-xuanzhong"></span>100%正品保证
      </div>
      <div class="item">
        <span class="iconfont icon-xuanzhong"></span>所有商品精挑细选
      </div>
      <div class="item">
        <span class="iconfont icon-xuanzhong"></span>售后无忧
      </div>
    </div>
    <div class="nav acea-row row-between-wrapper">
      <div>
        购物数量 <span class="num font-color-red">{{ count }}</span>
      </div>
      <div
        v-if="cartList.valid.length > 0"
        class="administrate acea-row row-center-wrapper"
        @click="manage"
      >
        {{ footerswitch ? "取消" : "管理" }}
      </div>
    </div>
    <div v-if="cartList.valid.length > 0 || cartList.invalid.length > 0">
      <div class="list">
        <div
          class="item acea-row row-between-wrapper"
          v-for="(item, index) in cartList.valid"
          :key="index"
        >
          <div class="select-btn">
            <div class="checkbox-wrapper">
              <label class="well-check">
                <input
                  type="checkbox"
                  name=""
                  value=""
                  :checked="item.checked"
                  @click="switchSelect(index)"
                />
                <i class="icon"></i>
              </label>
            </div>
          </div>
          <div class="picTxt acea-row row-between-wrapper">
            <div
              class="pictrue"
              @click="$router.push({ path: '/detail/' + item.product_id })"
            >
              <img
                :src="item.productInfo.attrInfo.image"
                v-if="item.productInfo.attrInfo"
              />
              <img :src="item.productInfo.image" v-else />
            </div>
            <div class="text">
              <div class="line1">{{ item.productInfo.store_name }}</div>
              <div class="infor line1" v-if="item.productInfo.attrInfo">
                属性:{{ item.productInfo.attrInfo.suk }}
              </div>
              <div class="money">¥{{ item.truePrice }}</div>
            </div>
            <div class="carnum acea-row row-center-wrapper">
              <div
                class="reduce"
                :class="cartList.valid[index].cart_num <= 1 ? 'on' : ''"
                @click.prevent="reduce(index)"
              >
                -
              </div>
              <div class="num">{{ item.cart_num }}</div>
              <div
                class="plus"
                v-if="cartList.valid[index].attrInfo"
                :class="
                  cartList.valid[index].cart_num >=
                  cartList.valid[index].attrInfo.stock
                    ? 'on'
                    : ''
                "
                @click.prevent="plus(index)"
              >
                +
              </div>
              <div
                class="plus"
                v-else
                :class="
                  cartList.valid[index].cart_num >= cartList.valid[index].stock
                    ? 'on'
                    : ''
                "
                @click.prevent="plus(index)"
              >
                +
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="invalidGoods" v-if="cartList.invalid.length > 0">
        <div class="goodsNav acea-row row-between-wrapper">
          <div @click="goodsOpen">
            <span
              class="iconfont"
              :class="goodsHidden === true ? 'icon-xiangyou' : 'icon-xiangxia'"
            ></span
            >失效商品
          </div>
          <div class="del" @click="delInvalidGoods">
            <span class="iconfont icon-shanchu1"></span>清空
          </div>
        </div>
        <div class="goodsList" :hidden="goodsHidden">
          <router-link
            :to="{ path: '/detail/' + item.product_id }"
            class="item acea-row row-between-wrapper"
            v-for="(item, index) in cartList.invalid"
            :key="index"
          >
            <div class="invalid acea-row row-center-wrapper">失效</div>
            <div class="pictrue">
              <img
                :src="item.productInfo.attrInfo.image"
                v-if="item.productInfo.attrInfo"
              />
              <img :src="item.productInfo.image" v-else />
            </div>
            <div class="text acea-row row-column-between">
              <div class="line1">{{ item.productInfo.store_name }}</div>
              <div class="infor line1" v-if="item.productInfo.attrInfo">
                属性:{{ item.productInfo.attrInfo.suk }}
              </div>
              <div class="acea-row row-between-wrapper">
                <div class="end">该商品已下架</div>
              </div>
            </div>
          </router-link>
        </div>
      </div>
    </div>
    <!--购物车暂无商品-->
    <div
      class="noCart"
      v-if="cartList.valid.length === 0 && cartList.invalid.length === 0"
    >
      <div class="pictrue"><img src="@assets/images/noCart.png" /></div>
      <Recommend></Recommend>
    </div>
    <div style="height:2.1rem"></div>
    <div
      class="footer acea-row row-between-wrapper"
      v-if="cartList.valid.length > 0"
    >
      <div>
        <div class="select-btn">
          <div class="checkbox-wrapper">
            <label class="well-check">
              <input
                type="checkbox"
                name=""
                value=""
                :checked="isAllSelect && cartCount > 0"
                @click="allChecked"
              />
              <i class="icon"></i>
              <span class="checkAll">全选 ({{ cartCount }})</span>
            </label>
          </div>
        </div>
      </div>
      <div class="money acea-row row-middle" v-if="footerswitch === false">
        <span class="font-color-red">¥{{ countmoney }}</span>
        <div class="placeOrder bg-color-red" @click="placeOrder">立即下单</div>
      </div>
      <div class="button acea-row row-middle" v-else>
        <div class="bnt cart-color" @click="collectAll">收藏</div>
        <div class="bnt" @click="delgoods">删除</div>
      </div>
    </div>
  </div>
</template>
<script>
import Recommend from "@components/Recommend";
import {
  getCartList,
  postCartDel,
  changeCartNum,
  getCartCount
} from "@api/store";
import { postCollectAll } from "@api/user";
import { mul, add } from "@utils/bc";
import cookie from "@utils/store/cookie";
import debounce from "lodash.debounce";

const CHECKED_IDS = "cart_checked";

export default {
  name: "ShoppingCart",
  components: {
    Recommend
  },
  props: {},
  data: function() {
    return {
      cartList: { invalid: [], valid: [] },
      isAllSelect: false,
      cartCount: 0,
      countmoney: 0,
      goodsHidden: true,
      footerswitch: false,
      count: 0,
      checkedIds: [],
      loaded: false
    };
  },
  watch: {
    $route(n) {
      if (n.name === "ShoppingCart") {
        this.carnum();
        this.countMoney();
        this.getCartList();
        this.gainCount();
        this.goodsHidden = true;
        this.footerswitch = false;
      }
    }
  },
  mounted: function() {
    let that = this;
    that.carnum();
    that.countMoney();
    that.getCartList();
    that.gainCount();
  },
  methods: {
    getCartList: function() {
      let that = this;
      getCartList().then(res => {
        that.cartList = res.data;
        let checkedIds = cookie.get(CHECKED_IDS) || [];
        if (!Array.isArray(checkedIds)) checkedIds = [];
        this.cartList.valid.forEach(cart => {
          if (checkedIds.length) {
            if (checkedIds.indexOf(cart.id) !== -1) cart.checked = true;
            else cart.checked = false;
          } else {
            cart.checked = true;
            that.checkedIds.push(cart.id);
          }
        });
        if (checkedIds.length) {
          that.checkedIds = checkedIds;
        }
        that.isAllSelect =
          that.checkedIds.length === this.cartList.valid.length;
        that.carnum();
        that.countMoney();
        this.loaded = true;
      });
    },
    //删除商品;
    delgoods: function() {
      let that = this,
        id = [],
        valid = [],
        list = that.cartList.valid;
      list.forEach(function(val) {
        if (val.checked === true) {
          id.push(val.id);
        }
      });
      if (id.length === 0) {
        that.$dialog.toast({ mes: "请选择产品" });
        return;
      }
      postCartDel(id).then(function() {
        list.forEach(function(val, i) {
          if (val.checked === false || val.checked === undefined)
            valid.push(list[i]);
        });
        that.$set(that.cartList, "valid", valid);
        that.carnum();
        that.countMoney();
        that.gainCount();
      });
    },
    // //获取数量
    gainCount: function() {
      let that = this;

      getCartCount().then(res => {
        that.count = res.data.count;
      });
    },
    //清除失效产品;
    delInvalidGoods: function() {
      let that = this,
        id = [],
        list = that.cartList.invalid;
      list.forEach(function(val) {
        id.push(val.id);
      });
      postCartDel(id).then(function() {
        list.splice(0, list.length);
        that.gainCount();
      });
    },
    //批量收藏;
    collectAll: function() {
      let that = this,
        data = { id: [], category: "" },
        list = that.cartList.valid;
      list.forEach(function(val) {
        if (val.checked === true) {
          data.id.push(val.product_id);
          data.category = val.type;
        }
      });
      if (data.id.length === 0) {
        that.$dialog.toast({ mes: "请选择产品" });
        return;
      }
      postCollectAll(data).then(function() {
        that.$dialog.toast({ mes: "收藏成功!" });
      });
    },
    //立即下单;
    placeOrder: function() {
      let that = this,
        list = that.cartList.valid,
        id = [];
      list.forEach(function(val) {
        if (val.checked === true) {
          id.push(val.id);
        }
      });
      if (id.length === 0) {
        that.$dialog.toast({ mes: "请选择产品" });
        return;
      }
      this.$router.push({ path: "/order/submit/" + id });
    },
    manage: function() {
      let that = this;
      that.footerswitch = !that.footerswitch;
    },
    goodsOpen: function() {
      let that = this;
      that.goodsHidden = !that.goodsHidden;
    },
    //加
    plus: function(index) {
      let that = this;
      let list = that.cartList.valid[index];
      list.cart_num++;
      if (list.attrInfo) {
        if (list.cart_num >= list.attrInfo.stock) {
          that.$set(list, "cart_num", list.attrInfo.stock);
        }
      } else {
        if (list.cart_num >= list.stock) {
          that.$set(list, "cart_num", list.stock);
        }
      }
      that.carnum();
      that.countMoney();
      that.syncCartNum(list);
    },
    //减
    reduce: function(index) {
      let that = this;
      let list = that.cartList.valid[index];
      list.cart_num--;
      if (list.cart_num < 1) {
        that.$set(list, "cart_num", 1);
      }
      that.carnum();
      that.countMoney();
      that.syncCartNum(list);
    },
    syncCartNum(cart) {
      if (!cart.sync)
        cart.sync = debounce(() => {
          changeCartNum(cart.id, Math.max(cart.cart_num, 1) || 1);
        }, 500);

      cart.sync();
    },
    //单选
    switchSelect: function(index) {
      let that = this,
        cart = that.cartList.valid[index],
        i = this.checkedIds.indexOf(cart.id);
      cart.checked = !cart.checked;

      if (i !== -1) this.checkedIds.splice(i, 1);
      if (cart.checked) {
        this.checkedIds.push(cart.id);
      }
      let len = that.cartList.valid.length;
      let selectnum = [];
      for (let i = 0; i < len; i++) {
        if (that.cartList.valid[i].checked === true) {
          selectnum.push(true);
        }
      }
      that.isAllSelect = selectnum.length === len;
      that.$set(that, "cartList", that.cartList);
      that.$set(that, "isAllSelect", that.isAllSelect);
      cookie.set(CHECKED_IDS, that.checkedIds);
      that.carnum();
      that.countMoney();
    },
    //全选
    allChecked: function() {
      let that = this;
      let selectAllStatus = that.isAllSelect;
      selectAllStatus = !selectAllStatus;
      let checkedIds = [];
      // for (let i = 0; i < array.length; i++) {
      //   array[i].checked = selectAllStatus;
      //   checked.push()
      // }
      that.cartList.valid.forEach(cart => {
        cart.checked = selectAllStatus;
        if (selectAllStatus) checkedIds.push(cart.id);
      });
      that.$set(that, "cartList", that.cartList);
      that.$set(that, "isAllSelect", selectAllStatus);
      this.checkedIds = checkedIds;
      cookie.set(CHECKED_IDS, checkedIds);
      that.carnum();
      that.countMoney();
    },
    //数量
    carnum: function() {
      let that = this;
      var carnum = 0;
      var array = that.cartList.valid;
      for (let i = 0; i < array.length; i++) {
        if (array[i].checked === true) {
          carnum += parseInt(array[i].cart_num);
        }
      }
      that.$set(that, "cartCount", carnum);
    },
    //总共价钱;
    countMoney: function() {
      let that = this;
      let carmoney = 0;
      let array = that.cartList.valid;
      for (let i = 0; i < array.length; i++) {
        if (array[i].checked === true) {
          carmoney = add(carmoney, mul(array[i].cart_num, array[i].truePrice));
        }
      }
      that.countmoney = carmoney;
    }
  }
};
</script>

user

address
AddAddress.vue

<template>
  <div class="addAddress absolute">
    <div class="list">
      <div class="item acea-row row-between-wrapper">
        <div class="name">姓名</div>
        <input
          type="text"
          placeholder="请输入姓名"
          v-model="userAddress.real_name"
          required
        />
      </div>
      <div class="item acea-row row-between-wrapper">
        <div class="name">联系电话</div>
        <input
          type="text"
          placeholder="请输入联系电话"
          v-model="userAddress.phone"
          required
        />
      </div>
      <div class="item acea-row row-between-wrapper">
        <div class="name">所在地区</div>
        <div
          class="picker acea-row row-between-wrapper select-value form-control"
        >
          <div class="address">
            <div slot="right" @click.stop="show2 = true">
              {{ model2 || "请选择收货地址" }}
            </div>
            <CitySelect
              v-model="show2"
              :callback="result2"
              :items="district"
              provance=""
              city=""
              area=""
            ></CitySelect>
          </div>
          <div class="iconfont icon-dizhi font-color-red"></div>
        </div>
      </div>
      <div class="item acea-row row-between-wrapper">
        <div class="name">详细地址</div>
        <input
          type="text"
          placeholder="请填写具体地址"
          v-model="userAddress.detail"
          required
        />
      </div>
    </div>
    <div class="default acea-row row-middle">
      <div class="select-btn">
        <div class="checkbox-wrapper">
          <label class="well-check"
            ><input
              type="checkbox"
              name=""
              value=""
              @click="ChangeIsDefault"
              :checked="userAddress.is_default ? true : false"
            /><i class="icon"></i><span class="def">设置为默认地址</span></label
          >
        </div>
      </div>
    </div>
    <div></div>
    <div class="keepBnt bg-color-red" @click="submit">立即保存</div>
    <div class="wechatAddress" v-if="isWechat && !id" @click="getAddress">
      导入微信地址
    </div>
  </div>
</template>
<script type="text/babel">
import { CitySelect } from "vue-ydui/dist/lib.rem/cityselect";
import District from "ydui-district/dist/jd_province_city_area_id";
import { getAddress, postAddress } from "@api/user";
import attrs, { required, chs_phone } from "@utils/validate";
import { validatorDefaultCatch } from "@utils/dialog";
import { openAddress } from "@libs/wechat";
import { isWeixin } from "@utils";

export default {
  components: {
    CitySelect
  },
  data() {
    return {
      show2: false,
      model2: "",
      district: District,
      id: 0,
      userAddress: { is_default: 0 },
      address: {},
      isWechat: isWeixin()
    };
  },
  mounted: function() {
    let id = this.$route.params.id;
    this.id = id;
    document.title = !id ? "添加地址" : "修改地址";
    this.getUserAddress();
  },
  methods: {
    getUserAddress: function() {
      if (!this.id) return false;
      let that = this;
      getAddress(that.id).then(res => {
        that.userAddress = res.data;
        that.model2 =
          res.data.province + " " + res.data.city + " " + res.data.district;
        that.address.province = res.data.province;
        that.address.city = res.data.city;
        that.address.district = res.data.district;
      });
    },
    getAddress() {
      openAddress().then(userInfo => {
        this.$dialog.loading.open();
        postAddress({
          id: this.id,
          real_name: userInfo.userName,
          phone: userInfo.telNumber,
          address: {
            province: userInfo.provinceName,
            city: userInfo.cityName,
            district: userInfo.countryName
          },
          detail: userInfo.detailInfo,
          is_default: 1,
          post_code: userInfo.postalCode
        })
          .then(() => {
            this.$dialog.loading.close();
            this.$dialog.toast({ mes: "添加成功" });
            this.$router.go(-1);
          })
          .catch(err => {
            this.$dialog.loading.close();
            this.$dialog.error(err.msg || "添加失败");
          });
      });
    },
    async submit() {
      let name = this.userAddress.real_name,
        phone = this.userAddress.phone,
        model2 = this.model2,
        detail = this.userAddress.detail,
        isDefault = this.userAddress.is_default;
      try {
        await this.$validator({
          name: [
            required(required.message("姓名")),
            attrs.range([2, 16], attrs.range.message("姓名"))
          ],
          phone: [
            required(required.message("联系电话")),
            chs_phone(chs_phone.message())
          ],
          model2: [required("请选择地址")],
          detail: [required(required.message("具体地址"))]
        }).validate({ name, phone, model2, detail });
      } catch (e) {
        return validatorDefaultCatch(e);
      }
      try {
        let that = this,
          data = {
            id: that.id,
            real_name: name,
            phone: phone,
            address: this.address,
            detail: detail,
            is_default: isDefault,
            post_code: ""
          };
        postAddress(data).then(function() {
          if (that.id) that.$dialog.toast({ mes: "修改成功" });
          else that.$dialog.toast({ mes: "添加成功" });
          that.$router.go(-1);
        });
      } catch (e) {
        this.$dialog.error(e.msg);
      }
    },
    ChangeIsDefault: function() {
      this.userAddress.is_default = !this.userAddress.is_default;
    },
    result2(ret) {
      this.model2 = ret.itemName1 + " " + ret.itemName2 + " " + ret.itemName3;
      this.address.province = ret.itemName1;
      this.address.city = ret.itemName2;
      this.address.district = ret.itemName3;
    }
  }
};
</script>

AddressManagement.vue

<template>
  <div
    class="address-management"
    :class="addressList.length < 1 && page > 1 ? 'on' : ''"
    ref="container"
  >
    <div class="line" v-if="addressList.length > 0">
      <img src="@assets/images/line.jpg" />
    </div>
    <div class="item" v-for="(item, index) in addressList" :key="index">
      <div class="address">
        <div class="consignee">
          收货人:{{ item.real_name
          }}<span class="phone">{{ item.phone }}</span>
        </div>
        <div>
          收货地址:{{ item.province }}{{ item.city }}{{ item.district
          }}{{ item.detail }}
        </div>
      </div>
      <div class="operation acea-row row-between-wrapper">
        <div class="select-btn">
          <div class="checkbox-wrapper">
            <label class="well-check"
              ><input
                type="radio"
                name="default"
                value=""
                :checked="item.is_default ? true : false"
                @click="radioChange(index)"
              /><i class="icon"></i><span class="default">设为默认</span></label
            >
          </div>
        </div>
        <div class="acea-row row-middle">
          <div @click="editAddress(index)">
            <span class="iconfont icon-bianji"></span>编辑
          </div>
          <div @click="delAddress(index)">
            <span class="iconfont icon-shanchu"></span>删除
          </div>
        </div>
      </div>
    </div>
    <Loading :loaded="loadend" :loading="loading"></Loading>
    <div class="noCommodity" v-if="addressList.length < 1 && page > 1">
      <div class="noPictrue">
        <img src="@assets/images/noAddress.png" class="image" />
      </div>
    </div>
    <div style="height:1.2rem;"></div>
    <div class="footer acea-row row-between-wrapper">
      <div class="addressBnt bg-color-red" v-if="isWechat" @click="addAddress">
        <span class="iconfont icon-tianjiadizhi"></span>添加新地址
      </div>
      <div class="addressBnt on bg-color-red" v-else @click="addAddress">
        <span class="iconfont icon-tianjiadizhi"></span>添加新地址
      </div>
      <div class="addressBnt wxbnt" v-if="isWechat" @click="getAddress">
        <span class="iconfont icon-weixin2"></span>导入微信地址
      </div>
    </div>
  </div>
</template>
<style scoped>
.address-management.on {
  background-color: #fff;
  height: 100vh;
}
</style>
<script type="text/babel">
import {
  getAddressList,
  getAddressRemove,
  getAddressDefaultSet,
  postAddress
} from "@api/user";
import Loading from "@components/Loading";
import { isWeixin } from "@utils";
import { openAddress } from "@libs/wechat";

export default {
  components: {
    Loading
  },
  data() {
    return {
      page: 1,
      limit: 20,
      addressList: [],
      loadTitle: "",
      loading: false,
      loadend: false,
      isWechat: isWeixin()
    };
  },
  mounted: function() {
    this.AddressList();
    this.$scroll(this.$refs.container, () => {
      !this.loading && this.AddressList();
    });
  },
  methods: {
    /**
     * 获取地址列表
     *
     */
    AddressList: function() {
      let that = this;
      if (that.loading) return; //阻止下次请求(false可以进行请求);
      if (that.loadend) return; //阻止结束当前请求(false可以进行请求);
      that.loading = true;
      getAddressList({ page: that.page, limit: that.limit }).then(res => {
        that.loading = false;
        //apply();js将一个数组插入另一个数组;
        that.addressList.push.apply(that.addressList, res.data);
        that.loadend = res.data.length < that.limit; //判断所有数据是否加载完成;
        that.page = that.page + 1;
      });
    },
    /**
     * 编辑地址
     */
    editAddress: function(index) {
      this.$router.push({
        path: "/user/add_address/" + this.addressList[index].id
      });
    },
    /**
     * 删除地址
     */
    delAddress: function(index) {
      let that = this;
      let address = this.addressList[index];
      let id = address.id;
      getAddressRemove(id).then(function() {
        that.$dialog.toast({
          mes: "删除成功!",
          callback: () => {
            that.addressList.splice(index, 1);
            that.$set(that, "addressList", that.addressList);
          }
        });
      });
    },
    /**
     * 设置默认地址
     */
    radioChange: function(index) {
      let that = this,
        address = this.addressList[index],
        id = address.id;
      getAddressDefaultSet(id).then(function() {
        for (var i = 0, len = that.addressList.length; i < len; i++) {
          if (i === index) that.addressList[i].is_default = 1;
          else that.addressList[i].is_default = 0;
        }
        that.$set(that, "addressList", that.addressList);
      });
    },
    /**
     * 新增地址
     */
    addAddress: function() {
      this.$router.push({
        path: "/user/add_address"
      });
    },
    getAddress() {
      openAddress().then(userInfo => {
        this.$dialog.loading.open();
        postAddress({
          real_name: userInfo.userName,
          phone: userInfo.telNumber,
          address: {
            province: userInfo.provinceName,
            city: userInfo.cityName,
            district: userInfo.countryName
          },
          detail: userInfo.detailInfo,
          post_code: userInfo.postalCode,
          wx_export: 1
        })
          .then(() => {
            this.page = 1;
            this.loading = false;
            this.loadend = false;
            this.addressList = [];
            this.AddressList();

            this.$dialog.loading.close();
            this.$dialog.toast({ mes: "添加成功" });
          })
          .catch(err => {
            this.$dialog.loading.close();
            this.$dialog.error(err.msg || "添加失败");
          });
      });
    }
  }
};
</script>

BindingPhone.vue

<template>
  <div class="ChangePassword">
    <div class="list">
      <div class="item">
        <input type="number" placeholder="填写手机号码" v-model="phone" />
      </div>
      <div class="item acea-row row-between-wrapper">
        <input
          type="text"
          placeholder="填写验证码"
          class="codeIput"
          v-model="captcha"
        />
        <button
          class="code font-color-red"
          :disabled="disabled"
          :class="disabled === true ? 'on' : ''"
          @click="code"
        >
          {{ text }}
        </button>
      </div>
    </div>
    <div class="confirmBnt bg-color-red" @click="confirm">确认绑定</div>
  </div>
</template>
<script>
import { mapGetters } from "vuex";
import sendVerifyCode from "@mixins/SendVerifyCode";
import { required, alpha_num, chs_phone } from "@utils/validate";
import { validatorDefaultCatch } from "@utils/dialog";
import { registerVerify, bindingPhone } from "@api/user";

export default {
  name: "BindingPhone",
  components: {},
  props: {},
  data: function() {
    return {
      captcha: "",
      phone: "" //手机号
    };
  },
  mixins: [sendVerifyCode],
  computed: mapGetters(["userInfo"]),
  mounted: function() {},
  methods: {
    async confirm() {
      let that = this;
      const { phone, captcha } = that;
      try {
        await that
          .$validator({
            phone: [
              chs_phone(chs_phone.message("手机号码")),
              alpha_num(alpha_num.message())
            ],
            captcha: [
              required(required.message("验证码")),
              alpha_num(alpha_num.message("验证码"))
            ]
          })
          .validate({ phone, captcha });
      } catch (e) {
        return validatorDefaultCatch(e);
      }
      bindingPhone({
        phone: this.phone,
        captcha: this.captcha
      })
        .then(res => {
          if (res.data !== undefined && res.data.is_bind) {
            that.$dialog.confirm({
              mes: res.msg,
              opts: [
                {
                  txt: "确认绑定",
                  color: false,
                  callback: () => {
                    bindingPhone({
                      phone: this.phone,
                      captcha: this.captcha,
                      step: 1
                    })
                      .then(res => {
                        that.$dialog.success(res.msg).then(() => {
                          that.$router.replace({ name: "PersonalData" });
                        });
                      })
                      .catch(res => {
                        that.$dialog.error(res.msg).then(() => {
                          that.$router.replace({ name: "PersonalData" });
                        });
                      });
                  }
                },
                {
                  txt: "取消",
                  color: false,
                  callback: () => {
                    that.$dialog.error("已取消绑定").then(() => {
                      that.$router.replace({ name: "PersonalData" });
                    });
                  }
                }
              ]
            });
          } else {
            that.$dialog.success(res.msg).then(() => {
              that.$router.replace({ name: "PersonalData" });
            });
          }
        })
        .catch(res => {
          that.$dialog.error(res.msg);
        });
    },
    async code() {
      let that = this;
      const { phone } = that;
      try {
        await that
          .$validator({
            phone: [
              required(required.message("手机号码")),
              chs_phone(chs_phone.message())
            ]
          })
          .validate({ phone });
      } catch (e) {
        return validatorDefaultCatch(e);
      }

      registerVerify({ phone: phone })
        .then(res => {
          that.$dialog.success(res.msg);
          that.sendCode();
        })
        .catch(res => {
          that.$dialog.error(res.msg);
        });
    }
  }
};
</script>

ChangePassword.vue

<template>
  <div class="ChangePassword">
    <div class="phone">
      当前手机号:<input type="text" v-model="phone" disabled />
    </div>
    <div class="list">
      <div class="item">
        <input type="password" placeholder="设置新密码" v-model="password" />
      </div>
      <div class="item">
        <input type="password" placeholder="确认新密码" v-model="password2" />
      </div>
      <div class="item acea-row row-between-wrapper">
        <input
          type="text"
          placeholder="填写验证码"
          class="codeIput"
          v-model="captcha"
        />
        <button
          class="code font-color-red"
          :disabled="disabled"
          :class="disabled === true ? 'on' : ''"
          @click="code"
        >
          {{ text }}
        </button>
      </div>
    </div>
    <div class="confirmBnt bg-color-red" @click="confirm">确认修改</div>
  </div>
</template>
<style scoped>
.ChangePassword .phone input {
  width: 2rem;
  text-align: center;
}
</style>
<script>
// import { mapGetters } from "vuex";
import sendVerifyCode from "@mixins/SendVerifyCode";
import attrs, { required, alpha_num, chs_phone } from "@utils/validate";
import { validatorDefaultCatch } from "@utils/dialog";
import { registerReset, registerVerify, getUserInfo } from "@api/user";

export default {
  name: "ChangePassword",
  components: {},
  props: {},
  data: function() {
    return {
      password: "",
      password2: "",
      captcha: "",
      phone: "", //隐藏几位数的手机号;
      yphone: "" //手机号;
    };
  },
  mixins: [sendVerifyCode],
  // computed: mapGetters(["userInfo"]),
  mounted: function() {
    this.getUserInfo();
  },
  methods: {
    getUserInfo: function() {
      let that = this;
      getUserInfo().then(res => {
        that.yphone = res.data.phone;
        let reg = /^(\d{3})\d*(\d{4})$/;
        that.phone = that.yphone.replace(reg, "$1****$2");
      });
    },
    async confirm() {
      let that = this;
      const { password, password2, captcha } = that;
      try {
        await that
          .$validator({
            password: [
              required(required.message("密码")),
              attrs.range([6, 16], attrs.range.message("密码")),
              alpha_num(alpha_num.message("密码"))
            ],
            captcha: [
              required(required.message("验证码")),
              alpha_num(alpha_num.message("验证码"))
            ]
          })
          .validate({ password, captcha });
      } catch (e) {
        return validatorDefaultCatch(e);
      }
      if (password !== password2) return that.$dialog.error("两次密码不一致");
      registerReset({
        account: that.yphone,
        captcha: that.captcha,
        password: that.password
      })
        .then(res => {
          that.$dialog.success(res.msg).then(() => {
            that.$router.push({ name: "Login" });
          });
        })
        .catch(res => {
          that.$dialog.error(res.msg);
        });
    },
    async code() {
      let that = this;
      const { yphone } = that;
      try {
        await that
          .$validator({
            yphone: [
              required(required.message("手机号码")),
              chs_phone(chs_phone.message())
            ]
          })
          .validate({ yphone });
      } catch (e) {
        return validatorDefaultCatch(e);
      }

      registerVerify({ phone: yphone })
        .then(res => {
          that.$dialog.success(res.msg);
          that.sendCode();
        })
        .catch(res => {
          that.$dialog.error(res.msg);
        });
    }
  }
};
</script>

coupon
GetCoupon.vue

<template>
  <div ref="container">
    <div class="coupon-list" v-if="couponsList.length > 0">
      <div
        class="item acea-row row-center-wrapper"
        v-for="(item, index) in couponsList"
        :key="index"
      >
        <div class="money" :class="item.is_use ? 'moneyGray' : ''">
          ¥<span class="num">{{ item.coupon_price }}</span>
        </div>
        <div class="text">
          <div class="condition line1">
            购物满{{ item.use_min_price }}元可用
          </div>
          <div class="data acea-row row-between-wrapper">
            <div v-if="item.end_time !== 0">
              {{ item.start_time ? item.start_time + "-" : ""
              }}{{ item.end_time }}
            </div>
            <div v-else>不限时</div>
            <div class="bnt gray" v-if="item.is_use === true">已领取</div>
            <div class="bnt gray" v-else-if="item.is_use === 2">已领完</div>
            <div
              class="bnt bg-color-red"
              v-else
              @click="getCoupon(item.id, index)"
            >
              立即领取
            </div>
          </div>
        </div>
      </div>
    </div>
    <Loading :loaded="loadend" :loading="loading"></Loading>
    <!--暂无优惠券-->
    <div
      class="noCommodity"
      v-cloak
      v-if="couponsList.length === 0 && page > 1"
    >
      <div class="noPictrue">
        <img src="@assets/images/noCoupon.png" class="image" />
      </div>
    </div>
  </div>
</template>
<script>
import { getCoupon, getCouponReceive } from "@api/user";
import Loading from "@components/Loading";
export default {
  name: "getCoupon",
  components: {
    Loading
  },
  props: {},
  data: function() {
    return {
      page: 1,
      limit: 10,
      couponsList: [],
      loading: false,
      loadend: false
    };
  },
  mounted: function() {
    this.getUseCoupons();
    this.$scroll(this.$refs.container, () => {
      !this.loading && this.getUseCoupons();
    });
  },
  methods: {
    getCoupon: function(id, index) {
      let that = this;
      let list = that.couponsList;
      getCouponReceive(id)
        .then(function() {
          list[index].is_use = true;
          that.$dialog.toast({ mes: "领取成功" });
        })
        .catch(function(res) {
          that.$dialog.toast({ mes: res.msg });
        });
    },
    getUseCoupons: function() {
      let that = this;
      if (that.loading) return; //阻止下次请求(false可以进行请求);
      if (that.loadend) return; //阻止结束当前请求(false可以进行请求);
      that.loading = true;
      let q = { page: that.page, limit: that.limit };
      getCoupon(q).then(res => {
        that.loading = false;
        //apply();js将一个数组插入另一个数组;
        that.couponsList.push.apply(that.couponsList, res.data);
        that.loadend = res.data.length < that.limit; //判断所有数据是否加载完成;
        that.page = that.page + 1;
      });
    }
  }
};
</script>

UserCoupon.vue

<template>
  <div ref="container">
    <div class="coupon-list" v-if="couponsList.length > 0">
      <div
        class="item acea-row row-center-wrapper"
        v-cloak
        v-for="(item, index) in couponsList"
        :key="index"
      >
        <div class="money" :class="item._type === 0 ? 'moneyGray' : ''">
          ¥<span class="num">{{ item.coupon_price }}</span>
        </div>
        <div class="text">
          <div class="condition line1">{{ item.coupon_title }}</div>
          <div class="data acea-row row-between-wrapper">
            <div v-if="item._end_time === 0">不限时</div>
            <div v-else>{{ item._add_time }}-{{ item._end_time }}</div>
            <div class="bnt gray" v-if="item._type === 0">{{ item._msg }}</div>
            <div class="bnt bg-color-red" v-else>{{ item._msg }}</div>
          </div>
        </div>
      </div>
    </div>
    <!--暂无优惠券-->
    <div
      class="noCommodity"
      v-if="couponsList.length === 0 && loading === true"
    >
      <div class="noPictrue">
        <img src="@assets/images/noCoupon.png" class="image" />
      </div>
    </div>
  </div>
</template>
<script>
import { getCouponsUser } from "@api/user";
const NAME = "UserCoupon";

export default {
  name: "UserCoupon",
  components: {},
  props: {},
  data: function() {
    return {
      couponsList: [],
      loading: false
    };
  },
  watch: {
    $route: function(n) {
      var that = this;
      if (n.name === NAME) {
        that.getUseCoupons();
      }
    }
  },
  mounted: function() {
    this.getUseCoupons();
  },
  methods: {
    getUseCoupons: function() {
      let that = this,
        type = 0;
      getCouponsUser(type).then(res => {
        that.couponsList = res.data;
        that.loading = true;
      });
    }
  }
};
</script>

CustomerList.vue

<template>
  <div class="CustomerList">
    <div
      class="item acea-row row-between-wrapper"
      v-for="item in list"
      :key="item.id"
      @click="$router.push('/customer/chat/' + item.uid)"
    >
      <div class="pictrue"><img :src="item.avatar" /></div>
      <div class="text line1">{{ item.nickname }}</div>
    </div>
  </div>
</template>
<script>
import { serviceList } from "@api/user";

export default {
  name: "CustomerList",
  data() {
    return {
      list: []
    };
  },
  methods: {
    getList() {
      serviceList().then(res => {
        this.list = res.data;
      });
    }
  },
  mounted() {
    this.getList();
  }
};
</script>
<style scoped>
.CustomerList {
  margin-top: 0.13rem;
}
.CustomerList .item {
  height: 1.38rem;
  border-bottom: 1px solid #eee;
  padding: 0 0.24rem;
  background-color: #fff;
}
.CustomerList .item .pictrue {
  width: 0.9rem;
  height: 0.9rem;
  border-radius: 50%;
  border: 0.03rem solid #fff;
  box-shadow: 0 0 0.1rem 0.05rem #f3f3f3;
  -webkit-box-shadow: 0 0 0.1rem 0.05rem #f3f3f3;
  -moz-box-shadow: 0 0 0.1rem 0.05rem #f3f3f3;
}
.CustomerList .item .pictrue img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
}
.CustomerList .item .text {
  width: 5.82rem;
  font-size: 0.32rem;
  color: #000;
}
</style>

CustomerService.vue

<template>
  <div class="broadcast-details">
    <div class="chat" ref="chat">
      <template v-for="item in history">
        <div
          class="item acea-row row-top"
          v-if="item.uid === toUid"
          :key="item.id"
        >
          <div class="pictrue"><img :src="item.avatar" /></div>
          <div class="text">
            <div class="name">{{ item.nickname }}</div>
            <div class="acea-row">
              <div
                class="conter acea-row row-middle"
                v-if="item.msn_type === 4"
              >
                <img
                  src="@assets/images/signal2.gif"
                  class="signal"
                  style="margin-right: 0.27rem;"
                />12’’
              </div>

              <div
                class="conter acea-row row-middle"
                v-if="item.msn_type === 3"
              >
                <img :src="item.msn" />
              </div>

              <div
                class="conter acea-row row-middle"
                v-if="item.msn_type === 2"
              >
                <i class="em" :class="item.msn"></i>
              </div>

              <div
                class="conter acea-row row-middle"
                v-if="item.msn_type === 1"
              >
                {{ item.msn }}
              </div>
            </div>
          </div>
        </div>

        <div class="item acea-row row-top row-right" v-else :key="item.id">
          <div class="text textR">
            <div class="name">{{ item.nickname }}</div>
            <div class="acea-row ">
              <div
                class="conter acea-row row-middle"
                v-if="item.msn_type === 4"
              >
                <img
                  src="@assets/images/signal2.gif"
                  class="signal"
                  style="margin-right: 0.27rem;"
                />12’’
              </div>

              <div
                class="conter acea-row row-middle"
                v-if="item.msn_type === 3"
              >
                <img :src="item.msn" />
              </div>

              <div
                class="conter acea-row row-middle"
                v-if="item.msn_type === 2"
              >
                <i class="em" :class="item.msn"></i>
              </div>

              <div
                class="conter acea-row row-middle"
                v-if="item.msn_type === 1"
              >
                {{ item.msn }}
              </div>
            </div>
          </div>
          <div class="pictrue"><img :src="item.avatar" /></div>
        </div>
      </template>
    </div>
    <div
      :style="
        active === true
          ? 'height:' + footerConH + 'rem;'
          : 'height:' + footerH + 'rem;'
      "
    ></div>
    <div
      class="footerCon"
      :class="active === true ? 'on' : ''"
      :style="'transform: translate3d(0,' + percent + '%,0);'"
      ref="footerCon"
    >
      <form>
        <div class="footer acea-row row-between row-bottom" ref="footer">
          <!--<img-->
          <!--:src="-->
          <!--voice === true-->
          <!--? require('@assets/images/keyboard.png')-->
          <!--: require('@assets/images/voice.png')-->
          <!--"-->
          <!--@click="voiceBnt"-->
          <!--/>-->
          <VueCoreImageUpload
            class="btn btn-primary"
            :crop="false"
            compress="80"
            @imageuploaded="imageuploaded"
            :headers="headers"
            :max-file-size="5242880"
            :credentials="false"
            inputAccept="image/*"
            inputOfFile="file"
            :url="url"
            ref="upImg"
          >
            <img src="@assets/images/plus.png" />
          </VueCoreImageUpload>
          <img
            :src="
              active === true
                ? require('@assets/images/keyboard.png')
                : require('@assets/images/face.png')
            "
            @click="emoticon"
          />
          <div
            class="voice acea-row row-center-wrapper"
            v-if="voice"
            @touchstart.prevent="start"
            @touchmove.prevent="move"
            @touchend.prevent="end"
          >
            {{ speak }}
          </div>
          <p
            contenteditable="true"
            class="input"
            ref="input"
            v-show="!voice"
            @keydown="keydown($event)"
            @keyup="keyup"
            @focus="focus"
          ></p>
          <div
            class="send"
            :class="sendColor === true ? 'font-color-red' : ''"
            @click="sendTest"
          >
            发送
          </div>
        </div>
      </form>
      <div class="banner slider-banner">
        <swiper
          class="swiper-wrapper"
          :options="swiperOption"
          v-if="emojiGroup.length > 0"
        >
          <swiper-slide
            class="swiper-slide acea-row"
            v-for="(emojiList, index) in emojiGroup"
            :key="index"
          >
            <i
              class="em"
              :class="emoji"
              v-for="emoji in emojiList"
              :key="emoji"
              @click="addEmoji(emoji)"
            ></i>
            <img src="@assets/images/del.png" class="emoji-outer" />
          </swiper-slide>
          <div class="swiper-pagination" slot="pagination"></div>
        </swiper>
      </div>
    </div>
    <div class="recording" v-if="recording">
      <img src="@assets/images/recording.png" />
    </div>
  </div>
</template>
<script>
import { swiper, swiperSlide } from "vue-awesome-swiper";
import "emoji-awesome/dist/css/google.min.css";
import emojiList from "@utils/emoji";
import Socket from "@libs/chat";
import { getChatRecord } from "@api/user";
import VueCoreImageUpload from "vue-core-image-upload";
import { VUE_APP_API_URL } from "@utils";

const chunk = function(arr, num) {
  num = num * 1 || 1;
  var ret = [];
  arr.forEach(function(item, i) {
    if (i % num === 0) {
      ret.push([]);
    }
    ret[ret.length - 1].push(item);
  });
  console.log(ret);
  return ret;
};

const NAME = "CustomerService";

export default {
  name: NAME,
  components: {
    swiper,
    swiperSlide,
    VueCoreImageUpload
  },
  props: {
    couponList: {
      type: Array,
      default: () => []
    }
  },
  data: function() {
    return {
      url: `${VUE_APP_API_URL}/upload/image`,
      headers: {
        "Authori-zation": "Bearer " + this.$store.state.app.token
      },
      emojiGroup: chunk(emojiList, 20),
      active: false,
      voice: false,
      speak: "按住 说话",
      recording: false,
      swiperOption: {
        pagination: {
          el: ".swiper-pagination",
          clickable: true
        },
        speed: 1000,
        observer: true,
        observeParents: true
      },
      percent: 0,
      footerConH: 0,
      footerH: 1.08,
      socket: null,
      toUid: parseInt(this.$route.params.id) || 0,
      page: 1,
      limit: 30,
      loading: false,
      loaded: false,
      history: [],
      sendColor: false,
      sendtxt: ""
    };
  },
  beforeDestroy() {
    this.socket && this.socket.close();
  },
  mounted: function() {
    this.height();
    this.getHistory();
    this.socket = new Socket();
    this.socket.vm(this);
    this.$on(["reply", "chat"], data => {
      this.history.push(data);
      this.$nextTick(function() {
        window.scrollTo(0, document.documentElement.scrollHeight + 999);
      });
    });
    this.$on("socket_error", () => {
      this.$dialog.error("连接失败");
    });
    this.$on("err_tip", data => {
      this.$dialog.error(data.msg);
    });
    this.$on("socket_open", () => {
      this.socket.send({
        data: { id: this.toUid },
        type: "to_chat"
      });
    });
    document.addEventListener("scroll", this.scroll, false);
  },
  destroyed() {
    document.removeEventListener("scroll", this.scroll);
  },
  methods: {
    scroll() {
      if (window.scrollY < 300 && !this.loaded && !this.loading)
        this.getHistory();
    },
    imageuploaded(res) {
      if (res.status !== 200)
        return this.$dialog.error(res.msg || "上传图片失败");
      this.sendMsg(res.data.url, 3);
    },
    getHistory() {
      if (this.loading || this.loaded) return;
      this.loading = true;
      getChatRecord(this.toUid, { page: this.page, limit: this.limit })
        .then(({ data }) => {
          this.history = data.concat(this.history);
          if (this.page === 1) {
            this.$nextTick(function() {
              window.scrollTo(0, document.documentElement.scrollHeight + 999);
              this.height();
            });
          }
          this.page++;
          this.loading = false;
          this.loaded = data.length < this.limit;
        })
        .catch(err => {
          console.log(err);
          this.$dialog.error(err.msg || "加载失败");
        });
    },
    focus: function() {
      this.active = false;
    },
    keyup: function() {
      console.log(this.$refs.input.innerHTML.length);
      if (this.$refs.input.innerHTML.length > 0) {
        this.sendColor = true;
      } else {
        this.sendColor = false;
      }
    },
    addEmoji(name) {
      this.sendMsg(name, 2);
    },
    height: function() {
      let footerConH = this.$refs.footerCon.offsetHeight;
      let footerH = this.$refs.footer.offsetHeight;
      let scale = 750 / window.screen.availWidth;
      this.footerConH = (footerConH * scale) / 100;
      this.footerH = (footerH * scale) / 100;
      this.percent = ((this.footerConH - this.footerH) / this.footerConH) * 100;
    },
    sendMsg(msn, type) {
      console.log(
        this.socket.send({
          data: { msn, type, to_uid: this.toUid },
          type: "chat"
        })
      );
    },
    sendTest() {
      if (this.$refs.input.innerHTML) {
        this.sendMsg(this.$refs.input.innerHTML, 1);
        this.$refs.input.innerHTML = "";
      }
    },
    keydown: function($event) {
      if ($event.keyCode === 13) {
        $event.preventDefault();
        if (this.$refs.input.innerHTML) {
          this.sendMsg(this.$refs.input.innerHTML, 1);
          this.$refs.input.innerHTML = "";
        }
      }
      this.height();
    },
    start() {
      var that = this;
      this.longClick = 0;
      this.timeOutEvent = setTimeout(function() {
        that.longClick = 1;
      }, 500);
      that.speak = "松开 结束";
      that.recording = true;
    },
    move() {
      clearTimeout(this.timeOutEvent);
      this.timeOutEvent = 0;
    },
    end() {
      clearTimeout(this.timeOutEvent);
      if (this.timeOutEvent !== 0 && this.longClick === 0) {
        //点击
        //此处为点击事件----在此处添加跳转详情页
        console.log("这是点击");
      }
      this.speak = "按住 说话";
      this.recording = false;
      return false;
    },
    voiceBnt: function() {
      this.active = false;
      if (this.voice === true) {
        this.voice = false;
        this.$nextTick(function() {
          this.$refs.input.focus();
        });
      } else {
        this.voice = true;
      }
      window.scrollTo(0, document.documentElement.scrollHeight);
      this.percent = 0;
      this.footerConH = 0;
      this.footerH = 0;
      this.$nextTick(function() {
        this.height();
      });
    },
    emoticon: function() {
      this.voice = false;
      if (this.active === true) {
        this.active = false;
        this.$nextTick(function() {
          this.$refs.input.focus();
        });
      } else {
        this.active = true;
        this.$nextTick(function() {
          this.$refs.input.blur();
        });
      }
      this.$nextTick(function() {
        window.scrollTo(0, document.documentElement.scrollHeight);
      });
      this.height();
    }
  }
};
</script>

<style scoped>
.broadcast-details .chat {
  padding: 0.01rem 0.23rem 0 0.3rem;
  margin-bottom: 0.3rem;
}

.broadcast-details .chat .item {
  margin-top: 0.37rem;
}

.broadcast-details .chat .item .pictrue {
  width: 0.8rem;
  height: 0.8rem;
  margin-top: 0.1rem;
}

.broadcast-details .chat .item .pictrue img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
}

.broadcast-details .chat .item .text {
  margin-left: 0.2rem;
}

.broadcast-details .chat .item .text.textR {
  text-align: right;
  margin: 0 0.2rem 0 0;
}

.broadcast-details .chat .item .text .name {
  font-size: 0.24rem;
  color: #999;
}

.broadcast-details .chat .item .text .name .return {
  color: #509efb;
  margin-left: 0.17rem;
}

.broadcast-details .chat .item .text.textR .name .return {
  margin: 0 0.17rem 0 0;
}

.broadcast-details .chat .item .text .conter {
  background-color: #fff;
  border-radius: 0.08rem;
  padding: 0.16rem 0.2rem;
  font-size: 0.3rem;
  color: #333;
  position: relative;
  max-width: 4.96rem;
  margin-top: 0.02rem;
}

.broadcast-details .chat .item .text .spot {
  width: 0.15rem;
  height: 0.15rem;
  background-color: #c00000;
  border-radius: 50%;
  margin-left: 0.2rem;
}

.broadcast-details .chat .item .text .conter:before {
  position: absolute;
  content: "";
  width: 0;
  height: 0;
  border-bottom: 0.09rem solid transparent;
  border-right: 0.14rem solid #fff;
  border-top: 0.09rem solid transparent;
  left: -0.14rem;
  top: 0.25rem;
}

.broadcast-details .chat .item .text.textR .conter:before {
  left: unset;
  right: -0.14rem;
  transform: rotateY(180deg);
}

.broadcast-details .chat .item .text .conter img {
  width: 100%;
  display: block;
}

.broadcast-details .chat .item .text .conter .signal {
  width: 0.48rem;
  height: 0.48rem;
}

.broadcast-details .chat .item .text .conter .signal.signalR {
  transform: rotate(180deg);
  -ms-transform: rotate(180deg);
  -webkit-transform: rotate(180deg);
}

.broadcast-details .footerCon {
  position: fixed;
  bottom: 0;
  left: 0;
  min-height: 1rem;
  z-index: 55;
  width: 100%;
  transition: all 0.005s cubic-bezier(0.25, 0.5, 0.5, 0.9);
  background-color: #fff;
}

.broadcast-details .footerCon.on {
  transform: translate3d(0, 0, 0) !important;
}

.broadcast-details .footerCon .banner .swiper-slide {
  flex-wrap: wrap;
  -webkit-flex-wrap: wrap;
  background-color: #fff;
  padding-bottom: 0.5rem;
  border-top: 1px solid #f5f5f5;
}

.broadcast-details .footerCon .banner .swiper-slide .emoji-outer,
.swiper-slide .em {
  display: block;
  width: 0.5rem;
  height: 0.5rem;
  margin: 0.4rem 0 0 0.5rem;
}

.broadcast-details
  .footerCon
  .banner
  .swiper-container-horizontal
  > .swiper-pagination-bullets {
  bottom: 0.1rem;
}

.broadcast-details .footerCon .slider-banner .swiper-pagination-bullet-active {
  background-color: #999;
}

.broadcast-details .recording {
  width: 3rem;
  height: 3rem;
  position: fixed;
  top: 40%;
  left: 50%;
  margin-left: -1.5rem;
}

.broadcast-details .recording img {
  width: 100%;
  height: 100%;
}

.broadcast-details .footer {
  width: 100%;
  background-color: #fff;
  padding: 0.17rem 0.26rem;
}

.broadcast-details .footer img {
  width: 0.61rem;
  height: 0.6rem;
  display: block;
}

.broadcast-details .footer .input,
.broadcast-details .footer .voice {
  width: 4.4rem;
  border-radius: 0.1rem;
  background-color: #e5e5e5;
  padding: 0.17rem 0.3rem;
}

.broadcast-details .footer .input {
  max-height: 1.5rem;
  overflow-y: auto;
  overflow-x: hidden;
}

.broadcast-details .footer .send {
  width: 0.7rem;
  text-align: center;
  height: 0.65rem;
  line-height: 0.65rem;
  font-weight: bold;
}
</style>

Login.vue

<template>
  <div class="register absolute">
    <div class="shading">
      <div class="pictrue acea-row row-center-wrapper">
        <img :src="logoUrl" v-if="logoUrl" />
        <img src="@assets/images/logo2.png" v-else />
      </div>
    </div>
    <div class="whiteBg" v-if="formItem === 1">
      <div class="title acea-row row-center-wrapper">
        <div
          class="item"
          :class="current === index ? 'on' : ''"
          v-for="(item, index) in navList"
          @click="navTap(index)"
          :key="index"
        >
          {{ item }}
        </div>
      </div>
      <div class="list" :hidden="current !== 0">
        <form @submit.prevent="submit">
          <div class="item">
            <div class="acea-row row-between-wrapper">
              <svg class="icon" aria-hidden="true">
                <use xlink:href="#icon-phone_"></use>
              </svg>
              <input
                type="text"
                placeholder="输入手机号码"
                v-model="account"
                required
              />
            </div>
          </div>
          <div class="item">
            <div class="acea-row row-between-wrapper">
              <svg class="icon" aria-hidden="true">
                <use xlink:href="#icon-code_"></use>
              </svg>
              <input
                type="password"
                placeholder="填写登录密码"
                v-model="password"
                required
              />
            </div>
          </div>
        </form>
        <div
          class="forgetPwd"
          @click="$router.push({ name: 'RetrievePassword' })"
        >
          <span class="iconfont icon-wenti"></span>忘记密码
        </div>
      </div>
      <div class="list" :hidden="current !== 1">
        <div class="item">
          <div class="acea-row row-between-wrapper">
            <svg class="icon" aria-hidden="true">
              <use xlink:href="#icon-phone_"></use>
            </svg>
            <input type="text" placeholder="输入手机号码" v-model="account" />
          </div>
        </div>
        <div class="item">
          <div class="align-left">
            <svg class="icon" aria-hidden="true">
              <use xlink:href="#icon-code_1"></use>
            </svg>
            <input
              type="text"
              placeholder="填写验证码"
              class="codeIput"
              v-model="captcha"
            />
            <button
              class="code"
              :disabled="disabled"
              :class="disabled === true ? 'on' : ''"
              @click="code"
            >
              {{ text }}
            </button>
          </div>
        </div>
      </div>
      <div class="logon" @click="loginMobile" :hidden="current !== 1">登录</div>
      <div class="logon" @click="submit" :hidden="current === 1">登录</div>
      <div class="tip">
        没有账号?
        <span @click="formItem = 2" class="font-color-red">立即注册</span>
      </div>
    </div>
    <div class="whiteBg" v-else>
      <div class="title">注册账号</div>
      <div class="list">
        <div class="item">
          <div>
            <svg class="icon" aria-hidden="true">
              <use xlink:href="#icon-phone_"></use>
            </svg>
            <input type="text" placeholder="输入手机号码" v-model="account" />
          </div>
        </div>
        <div class="item">
          <div class="align-left">
            <svg class="icon" aria-hidden="true">
              <use xlink:href="#icon-code_1"></use>
            </svg>
            <input
              type="text"
              placeholder="填写验证码"
              class="codeIput"
              v-model="captcha"
            />
            <button
              class="code"
              :disabled="disabled"
              :class="disabled === true ? 'on' : ''"
              @click="code"
            >
              {{ text }}
            </button>
          </div>
        </div>
        <div class="item">
          <div>
            <svg class="icon" aria-hidden="true">
              <use xlink:href="#icon-code_"></use>
            </svg>
            <input
              type="password"
              placeholder="填写您的登录密码"
              v-model="password"
            />
          </div>
        </div>
      </div>
      <div class="logon" @click="register">注册</div>
      <div class="tip">
        已有账号?
        <span @click="formItem = 1" class="font-color-red">立即登录</span>
      </div>
    </div>
    <div class="bottom"></div>
  </div>
</template>
<script>
import sendVerifyCode from "@mixins/SendVerifyCode";
import { login, loginMobile, registerVerify, register } from "@api/user";
import attrs, { required, alpha_num, chs_phone } from "@utils/validate";
import { validatorDefaultCatch } from "@utils/dialog";
import { getLogo } from "@api/public";
import dayjs from "dayjs";
import cookie from "@utils/store/cookie";

const BACK_URL = "login_back_url";

export default {
  name: "Login",
  mixins: [sendVerifyCode],
  data: function() {
    return {
      navList: ["账号登录", "快速登录"],
      current: 1,
      account: "",
      password: "",
      captcha: "",
      formItem: 1,
      type: "login",
      logoUrl: ""
    };
  },
  mounted: function() {
    this.getLogoImage();
  },
  methods: {
    async getLogoImage() {
      let that = this;
      getLogo(2).then(res => {
        that.logoUrl = res.data.logo_url;
      });
    },
    async loginMobile() {
      var that = this;
      const { account, captcha } = that;
      try {
        await that
          .$validator({
            account: [
              required(required.message("手机号码")),
              chs_phone(chs_phone.message())
            ],
            captcha: [
              required(required.message("验证码")),
              alpha_num(alpha_num.message("验证码"))
            ]
          })
          .validate({ account, captcha });
      } catch (e) {
        return validatorDefaultCatch(e);
      }
      loginMobile({
        phone: that.account,
        captcha: that.captcha,
        spread: cookie.get("spread")
      })
        .then(res => {
          let data = res.data;
          let newTime = Math.round(new Date() / 1000);
          that.$store.commit(
            "LOGIN",
            data.token,
            dayjs(data.expires_time) - newTime
          );
          const backUrl = cookie.get(BACK_URL) || "/";
          cookie.remove(BACK_URL);
          that.$router.replace({ path: backUrl });
        })
        .catch(res => {
          that.$dialog.error(res.msg);
        });
    },
    async register() {
      var that = this;
      const { account, captcha, password } = that;
      try {
        await that
          .$validator({
            account: [
              required(required.message("手机号码")),
              chs_phone(chs_phone.message())
            ],
            captcha: [
              required(required.message("验证码")),
              alpha_num(alpha_num.message("验证码"))
            ],
            password: [
              required(required.message("密码")),
              attrs.range([6, 16], attrs.range.message("密码")),
              alpha_num(alpha_num.message("密码"))
            ]
          })
          .validate({ account, captcha, password });
      } catch (e) {
        return validatorDefaultCatch(e);
      }
      register({
        account: that.account,
        captcha: that.captcha,
        password: that.password,
        spread: cookie.get("spread")
      })
        .then(res => {
          that.$dialog.success(res.msg);
          that.formItem = 1;
        })
        .catch(res => {
          that.$dialog.error(res.msg);
        });
    },
    async code() {
      var that = this;
      const { account } = that;
      try {
        await that
          .$validator({
            account: [
              required(required.message("手机号码")),
              chs_phone(chs_phone.message())
            ]
          })
          .validate({ account });
      } catch (e) {
        return validatorDefaultCatch(e);
      }
      if (that.formItem == 2) that.type = "register";
      await registerVerify({ phone: that.account, type: that.type })
        .then(res => {
          that.$dialog.success(res.msg);
          that.sendCode();
        })
        .catch(res => {
          that.$dialog.error(res.msg);
        });
    },
    navTap: function(index) {
      this.current = index;
    },
    async submit() {
      const { account, password } = this;
      try {
        await this.$validator({
          account: [
            required(required.message("账号")),
            attrs.range([5, 16], attrs.range.message("账号")),
            alpha_num(alpha_num.message("账号"))
          ],
          password: [
            required(required.message("密码")),
            attrs.range([6, 16], attrs.range.message("密码")),
            alpha_num(alpha_num.message("密码"))
          ]
        }).validate({ account, password });
      } catch (e) {
        return validatorDefaultCatch(e);
      }

      login({ account, password })
        .then(({ data }) => {
          this.$store.commit("LOGIN", data.token, dayjs(data.expires_time));
          const backUrl = cookie.get(BACK_URL) || "/";
          cookie.remove(BACK_URL);
          this.$router.replace({ path: backUrl });
        })
        .catch(e => {
          this.$dialog.error(e.msg);
        });
    }
  }
};
</script>

PersonalData.vue

<template>
  <div class="personal-data">
    <div class="wrapper">
      <div class="title">管理我的账号</div>
      <div class="wrapList">
        <div
          class="item acea-row row-between-wrapper"
          :class="item.uid === userInfo.uid ? 'on' : ''"
          v-for="(item, index) in switchUserInfo"
          :key="index"
        >
          <div class="picTxt acea-row row-between-wrapper">
            <div class="pictrue">
              <VueCoreImageUpload
                class="btn btn-primary"
                :crop="false"
                compress="80"
                @imageuploaded="imageuploaded"
                :headers="headers"
                :max-file-size="5242880"
                :credentials="false"
                inputAccept="image/*"
                inputOfFile="file"
                :url="url"
                ref="upImg"
                v-if="item.uid === userInfo.uid"
              >
                <div class="pictrue">
                  <img :src="item.avatar" />
                </div>
              </VueCoreImageUpload>
              <div class="pictrue" v-else>
                <img :src="item.avatar" />
              </div>
              <img
                src="@assets/images/alter.png"
                class="alter"
                v-if="item.uid === userInfo.uid"
              />
            </div>
            <div class="text">
              <div class="name line1">{{ item.nickname }}</div>
              <div class="phone">绑定手机号:{{ item.phone }}</div>
            </div>
          </div>
          <div
            class="currentBnt acea-row row-center-wrapper font-color-red"
            v-if="item.uid === userInfo.uid"
          >
            当前账号
          </div>
          <div
            class="bnt font-color-red acea-row row-center-wrapper"
            v-else
            @click="switchAccounts(index)"
          >
            使用账号
          </div>
        </div>
      </div>
    </div>
    <div class="list">
      <div class="item acea-row row-between-wrapper">
        <div>昵称</div>
        <div class="input">
          <input type="text" v-model="userInfo.nickname" />
        </div>
      </div>
      <div class="item acea-row row-between-wrapper">
        <div>ID号</div>
        <div class="input acea-row row-between-wrapper">
          <input type="text" :value="userInfo.uid" disabled class="id" /><span
            class="iconfont icon-suozi"
          ></span>
        </div>
      </div>
      <div v-if="!userInfo.phone">
        <router-link
          :to="'/user/binding'"
          class="item acea-row row-between-wrapper"
        >
          <div>绑定手机号</div>
          <div class="input">
            点击绑定手机号<span class="iconfont icon-xiangyou"></span>
          </div>
        </router-link>
      </div>
      <div class="item acea-row row-between-wrapper" v-else-if="userInfo.phone">
        <div>手机号码</div>
        <div class="input acea-row row-between-wrapper">
          <div class="input acea-row row-between-wrapper">
            <input
              type="text"
              :value="userInfo.phone"
              disabled
              class="id"
            /><span class="iconfont icon-suozi"></span>
          </div>
        </div>
      </div>
      <div v-if="userInfo.phone && userInfo.user_type === 'h5'">
        <router-link
          :to="'/change_password'"
          class="item acea-row row-between-wrapper"
        >
          <div>密码</div>
          <div class="input">
            点击修改密码<span class="iconfont icon-xiangyou"></span>
          </div>
        </router-link>
      </div>
    </div>
    <div class="modifyBnt bg-color-red" @click="submit">保存修改</div>
    <div
      class="logOut cart-color acea-row row-center-wrapper"
      @click="logout"
      v-if="!isWeixin"
    >
      退出登录
    </div>
  </div>
</template>
<script>
import { mapGetters } from "vuex";
import { trim, VUE_APP_API_URL, isWeixin } from "@utils";
import VueCoreImageUpload from "vue-core-image-upload";
import { postUserEdit, getLogout, switchH5Login, getUser } from "@api/user";
import { clearAuthStatus } from "@libs/wechat";
import cookie from "@utils/store/cookie";
import store from "@/store";
import dayjs from "dayjs";

export default {
  name: "PersonalData",
  components: {
    VueCoreImageUpload
  },
  data: function() {
    return {
      url: `${VUE_APP_API_URL}/upload/image`,
      headers: {
        "Authori-zation": "Bearer " + this.$store.state.app.token
      },
      avatar: "",
      isWeixin: false,
      currentAccounts: 0,
      switchUserInfo: [],
      userIndex: 0
    };
  },
  watch: {
    $route(n) {
      if (n.name === "PersonalData") this.$store.dispatch("USERINFO", true);
    }
  },
  computed: mapGetters(["userInfo"]),
  mounted: function() {
    this.avatar = this.userInfo.avatar;
    this.isWeixin = isWeixin();
    this.getUserInfo();
  },
  methods: {
    switchAccounts: function(index) {
      let that = this;
      this.userIndex = index;
      let userInfo = this.switchUserInfo[this.userIndex];
      if (this.switchUserInfo.length <= 1) return true;
      if (userInfo === undefined)
        return this.$dialog.toast({ mes: "切换的账号不存在" });
      if (userInfo.user_type === "h5") {
        switchH5Login()
          .then(({ data }) => {
            that.$dialog.loading.close();
            const expires_time = dayjs(data.expires_time);
            store.commit("LOGIN", data.token, expires_time);
            that.$emit("changeswitch", false);
            location.reload();
          })
          .catch(err => {
            that.$dialog.loading.close();
            return that.$dialog.toast({ mes: err });
          });
      } else {
        cookie.set("loginType", "wechat", 60);
        this.$dialog.loading.close();
        this.$store.commit("LOGOUT");
        clearAuthStatus();
        this.$emit("changeswitch", false);
        location.reload();
      }
    },
    getUserInfo: function() {
      let that = this;
      getUser().then(res => {
        let switchUserInfo = res.data.switchUserInfo;
        for (let i = 0; i < switchUserInfo.length; i++) {
          if (switchUserInfo[i].uid == that.userInfo.uid) that.userIndex = i;
          if (
            !that.isWeixin &&
            switchUserInfo[i].user_type != "h5" &&
            switchUserInfo[i].phone === ""
          )
            switchUserInfo.splice(i, 1);
        }
        that.$set(this, "switchUserInfo", switchUserInfo);
      });
    },
    imageuploaded(res) {
      if (res.status !== 200)
        return this.$dialog.error(res.msg || "上传图片失败");
      if (this.switchUserInfo[this.userIndex] === undefined) return;
      this.$set(this.switchUserInfo[this.userIndex], "avatar", res.data.url);
    },

    submit: function() {
      let userInfo = this.switchUserInfo[this.userIndex];
      postUserEdit({
        nickname: trim(this.userInfo.nickname),
        avatar: userInfo.avatar
      }).then(
        res => {
          this.$store.dispatch("USERINFO", true);
          this.$dialog.success(res.msg);
          this.$router.go(-1);
        },
        error => {
          this.$dialog.error(error.msg);
        }
      );
    },
    logout: function() {
      this.$dialog.confirm({
        mes: "确认退出登录?",
        opts: () => {
          getLogout()
            .then(res => {
              this.$store.commit("LOGOUT");
              clearAuthStatus();
              location.href = location.origin;
              console.log(res);
            })
            .catch(err => {
              console.log(err);
            });
        }
      });
    }
  }
};
</script>

promotion
CashAudit.vue

<template>
  <div class="cash-audit">
    <div class="pictrue"><img src="@assets/images/examine.png" /></div>
    <div class="tip">提现申请已提交,等待人工审核</div>
    <div class="time">{{ time }}</div>
    <div
      class="bnt bg-color-red"
      @click="$router.push({ path: '/user/user_promotion' })"
    >
      好的
    </div>
  </div>
</template>
<script>
export default {
  name: "CashAudit",
  components: {},
  props: {},
  data: function() {
    return {
      time: ""
    };
  },
  mounted: function() {
    let myData = new Date();
    this.time = myData.toLocaleString();
  },
  methods: {}
};
</script>

CashRecord.vue

<template>
  <div class="commission-details" ref="container">
    <div class="promoterHeader bg-color-red">
      <div class="headerCon acea-row row-between-wrapper">
        <div>
          <div class="name">提现记录</div>
          <div class="money">
            ¥<span class="num">{{ commission }}</span>
          </div>
        </div>
        <div class="iconfont icon-jinbi1"></div>
      </div>
    </div>
    <div class="sign-record" ref="content">
      <div class="list">
        <div class="item" v-for="(item, index) in info" :key="index">
          <div class="data">{{ item.time }}</div>
          <div class="listn" v-for="(val, indexn) in item.list" :key="indexn">
            <div class="itemn acea-row row-between-wrapper">
              <div>
                <div class="name line1">{{ val.title }}</div>
                <div>{{ val.add_time }}</div>
              </div>
              <div class="num" v-if="val.pm == 1">+{{ val.number }}</div>
              <div class="num font-color-red" v-if="val.pm == 0">
                -{{ val.number }}
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <Loading :loaded="loaded" :loading="loading"></Loading>
  </div>
</template>
<script>
import { getCommissionInfo, getSpreadInfo } from "../../../api/user";
import Loading from "@components/Loading";

export default {
  name: "CashRecord",
  components: {
    Loading
  },
  props: {},
  data: function() {
    return {
      info: [],
      commission: 0,
      where: {
        page: 1,
        limit: 3
      },
      types: 4,
      loaded: false,
      loading: false
    };
  },
  mounted: function() {
    this.getCommission();
    this.getIndex();
    this.$scroll(this.$refs.container, () => {
      this.loading === false && this.getIndex();
    });
  },
  methods: {
    getIndex: function() {
      let that = this;
      if (that.loading == true || that.loaded == true) return;
      that.loading = true;
      getCommissionInfo(that.where, that.types).then(
        res => {
          that.loading = false;
          that.loaded = res.data.length < that.where.limit;
          that.where.page = that.where.page + 1;
          that.info.push.apply(that.info, res.data);
        },
        error => {
          that.$dialog.message(error.msg);
        }
      );
    },
    getCommission: function() {
      let that = this;
      getSpreadInfo().then(
        res => {
          that.commission = res.data.commissionCount;
        },
        error => {
          this.$dialog.message(error.msg);
        }
      );
    }
  }
};
</script>

CommissionDetails.vue

<template>
  <div class="commission-details" ref="container">
    <div class="promoterHeader bg-color-red">
      <div class="headerCon acea-row row-between-wrapper">
        <div>
          <div class="name">佣金明细</div>
          <div class="money">
            ¥<span class="num">{{ commission }}</span>
          </div>
        </div>
        <div class="iconfont icon-jinbi1"></div>
      </div>
    </div>
    <div class="sign-record" ref="content">
      <div class="list">
        <div class="item" v-for="(item, index) in info" :key="index">
          <div class="data">{{ item.time }}</div>
          <div class="listn" v-for="(val, indexn) in item.list" :key="indexn">
            <div class="itemn acea-row row-between-wrapper">
              <div>
                <div class="name line1">{{ val.title }}</div>
                <div>{{ val.add_time }}</div>
              </div>
              <div class="num" v-if="val.pm == 1">+{{ val.number }}</div>
              <div class="num font-color-red" v-if="val.pm == 0">
                -{{ val.number }}
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <Loading :loaded="loaded" :loading="loading"></Loading>
  </div>
</template>
<script>
import { getCommissionInfo, getSpreadInfo } from "../../../api/user";
import Loading from "@components/Loading";

export default {
  name: "CommissionDetails",
  components: {
    Loading
  },
  props: {},
  data: function() {
    return {
      info: [],
      commission: 0,
      where: {
        page: 1,
        limit: 3
      },
      types: 3,
      loaded: false,
      loading: false
    };
  },
  mounted: function() {
    this.getCommission();
    this.getIndex();
    this.$scroll(this.$refs.container, () => {
      this.loading === false && this.getIndex();
    });
  },
  methods: {
    getIndex: function() {
      let that = this;
      if (that.loading == true || that.loaded == true) return;
      that.loading = true;
      getCommissionInfo(that.where, that.types).then(
        res => {
          that.loading = false;
          that.loaded = res.data.length < that.where.limit;
          that.loadTitle = that.loaded ? "人家是有底线的" : "上拉加载更多";
          that.where.page = that.where.page + 1;
          that.info.push.apply(that.info, res.data);
        },
        error => {
          that.$dialog.message(error.msg);
        }
      );
    },
    getCommission: function() {
      let that = this;
      getSpreadInfo().then(
        res => {
          that.commission = res.data.commissionCount;
        },
        error => {
          this.$dialog.message(error.msg);
        }
      );
    }
  }
};
</script>

CommissionRank.vue

<template>
  <div class="commission-rank" ref="container">
    <div class="header">
      <div class="rank" v-if="position">
        您目前的排名为:第<span class="num">{{ position }}</span
        >名
      </div>
      <div class="rank" v-else>
        您暂未上榜
      </div>
    </div>
    <div class="wrapper">
      <div class="nav acea-row row-around">
        <div
          class="item"
          :class="active === index ? 'font-color-red' : ''"
          v-for="(item, index) in navList"
          :key="index"
          @click="switchTap(index)"
        >
          {{ item }}
        </div>
      </div>
      <div class="list">
        <div
          class="item acea-row row-between-wrapper"
          v-for="(item, index) in rankList"
          :key="index"
        >
          <div class="num" v-if="index <= 2">
            <img src="@assets/images/medal01.png" v-if="index == 0" />
            <img src="@assets/images/medal02.png" v-else-if="index == 1" />
            <img src="@assets/images/medal03.png" v-else-if="index == 2" />
          </div>
          <div class="num" v-else>{{ index + 1 }}</div>
          <div class="picTxt acea-row row-between-wrapper">
            <div class="pictrue"><img :src="item.avatar" /></div>
            <div class="text line1">{{ item.nickname }}</div>
          </div>
          <div class="people font-color-red">¥{{ item.brokerage_price }}</div>
        </div>
      </div>
    </div>
  </div>
</template>
<style scoped>
.commission-rank .header {
  background: url("../../../assets/images/commission.jpg") no-repeat;
  width: 100%;
  height: 3.44rem;
  background-size: 100% 100%;
  position: relative;
  z-index: -1;
}
.commission-rank .header .rank {
  font-size: 0.33rem;
  color: #fff;
  position: absolute;
  top: 1.6rem;
  left: 0.48rem;
}
.commission-rank .header .rank .num {
  font-size: 0.51rem;
  font-weight: bold;
  margin: 0 0.1rem;
}
.commission-rank .wrapper {
  width: 7.1rem;
  background-color: #fff;
  border-radius: 0.2rem;
  margin: -0.76rem auto 0 auto;
}
.commission-rank .wrapper .nav {
  height: 0.99rem;
  border-bottom: 0.025rem solid #f3f3f3;
  font-size: 0.3rem;
  font-weight: bold;
  color: #999;
  line-height: 0.99rem;
}
.commission-rank .wrapper .nav .item.font-color-red {
  border-bottom: 0.04rem solid #e93323;
}
.commission-rank .wrapper .list {
  padding: 0 0.3rem;
}
.commission-rank .wrapper .list .item {
  border-bottom: 1px solid #f3f3f3;
  height: 1.01rem;
  font-size: 0.28rem;
}
.commission-rank .wrapper .list .item .num {
  color: #666;
  width: 0.7rem;
}
.commission-rank .wrapper .list .item .num img {
  width: 0.34rem;
  height: 0.4rem;
  display: block;
}
.commission-rank .wrapper .list .item .picTxt {
  width: 3.5rem;
}
.commission-rank .wrapper .list .item .picTxt .pictrue {
  width: 0.68rem;
  height: 0.68rem;
}
.commission-rank .wrapper .list .item .picTxt .pictrue img {
  width: 100%;
  height: 100%;
  display: block;
  border-radius: 50%;
}
.commission-rank .wrapper .list .item .picTxt .text {
  width: 2.62rem;
  color: #333;
}
.commission-rank .wrapper .list .item .people {
  width: 1.75rem;
  text-align: right;
}
</style>
<script>
import { getBrokerageRank } from "@api/user";
import { mapGetters } from "vuex";

const NAME = "CommissionRank";
export default {
  name: NAME,
  props: {},
  data: function() {
    return {
      navList: ["周排行", "月排行"],
      active: 0,
      rankList: [],
      page: 1,
      limit: 10,
      type: "week",
      position: 0,
      loading: false,
      loadend: false
    };
  },
  computed: mapGetters(["userInfo"]),
  watch: {
    $route(n) {
      if (n.name === NAME) {
        this.loaded = false;
        this.page = 1;
        this.$set(this, "rankList", []);
        this.getBrokerageRankList();
      }
    },
    active() {
      this.loaded = false;
      this.page = 1;
      this.$set(this, "rankList", []);
      this.getBrokerageRankList();
    }
  },
  mounted: function() {
    this.getBrokerageRankList();
    this.$scroll(this.$refs.container, () => {
      !this.loading && this.getBrokerageRankList();
    });
  },
  methods: {
    switchTap: function(index) {
      this.active = index;
    },
    getBrokerageRankList: function() {
      if (this.loading) return;
      if (this.loaded) return;
      this.loading = true;
      getBrokerageRank({
        page: this.page,
        limit: this.limit,
        type: this.active === 0 ? "week" : "month"
      })
        .then(res => {
          let list = res.data.rank;
          let loadend = list.length < this.limit;
          this.rankList.push.apply(this.rankList, list);
          this.loading = false;
          this.loaded = loadend;
          this.page++;
          this.position = res.data.position;
          this.$set(this, "rankList", this.rankList);
          this.getUserRank();
        })
        .catch(() => {
          this.loading = false;
        });
    },
    getUserRank() {
      this.rankList.forEach((item, index) => {
        if (this.userInfo.uid == item.uid) this.position = index + 1;
      });
    }
  }
};
</script>

Poster.vue

<template>
  <div class="distribution-posters">
    <div class="slider-banner banner">
      <swiper class="swiper-wrapper" :options="swiperPosters" ref="mySwiper">
        <swiperSlide
          class="swiper-slide"
          v-for="(item, index) in info"
          :key="index"
        >
          <img class="slide-image" :src="item.wap_poster" />
        </swiperSlide>
      </swiper>
    </div>
    <!--<div class="keep bg-color-red" @click="saveImg">保存海报</div>-->
    <div class="preserve acea-row row-center-wrapper">
      <div class="line"></div>
      <div class="tip">长按保存图片</div>
      <div class="line"></div>
    </div>
  </div>
</template>
<style>
.preserve {
  color: #fff;
  text-align: center;
  margin-top: 0.2rem;
}
.preserve .line {
  width: 1rem;
  height: 0.01rem;
  background-color: #fff;
}
.preserve .tip {
  margin: 0 0.3rem;
}
</style>
<script>
import { swiper, swiperSlide } from "vue-awesome-swiper";
import "@assets/css/swiper.min.css";
import { getSpreadImg } from "../../../api/user";
export default {
  name: "Poster",
  components: {
    swiper,
    swiperSlide
  },
  props: {},
  data: function() {
    return {
      swiperPosters: {
        speed: 1000,
        effect: "coverflow",
        slidesPerView: "auto",
        centeredSlides: true,
        coverflowEffect: {
          rotate: 0, // 旋转的角度
          stretch: -20, // 拉伸   图片间左右的间距和密集度
          depth: 100, // 深度   切换图片间上下的间距和密集度
          modifier: 3, // 修正值 该值越大前面的效果越明显
          slideShadows: false // 页面阴影效果
        },
        observer: true,
        observeParents: true
      },
      info: [],
      activeIndex: 0
    };
  },
  mounted: function() {
    this.getIndex();
    let that = this;
    this.swiper.on("slideChange", function() {
      that.activeIndex = that.swiper.activeIndex;
    });
  },
  computed: {
    swiper() {
      return this.$refs.mySwiper.swiper;
    }
  },
  methods: {
    getIndex: function() {
      let that = this;
      getSpreadImg().then(
        res => {
          that.info = res.data;
        },
        err => {
          that.$dialog.message(err.msg);
        }
      );
    }
    // downloadIamge: function(imgsrc, name) {
    //   let image = new Image();
    //   image.setAttribute("crossOrigin", "anonymous");
    //   image.onload = function() {
    //     let canvas = document.createElement("canvas");
    //     canvas.width = image.width;
    //     canvas.height = image.height;
    //     let context = canvas.getContext("2d");
    //     context.drawImage(image, 0, 0, image.width, image.height);
    //     let url = canvas.toDataURL("image/png"); //得到图片的base64编码数据
    //     let a = document.createElement("a"); // 生成一个a元素
    //     let event = new MouseEvent("click"); // 创建一个单击事件
    //     a.download = name || "photo"; // 设置图片名称
    //     a.href = url; // 将生成的URL设置为a.href属性
    //     a.dispatchEvent(event); // 触发a的单击事件
    //   };
    //   image.src = imgsrc;
    // },
    // saveImg: function() {
    //   console.log(this.info[this.activeIndex].wap_poster);
    //   this.downloadIamge(
    //     this.info[this.activeIndex].wap_poster,
    //     "poster" + this.activeIndex
    //   );
    // }
  }
};
</script>

PromoterList.vue

<template>
  <div class="promoter-list" ref="container">
    <div class="header">
      <div class="promoterHeader bg-color-red">
        <div class="headerCon acea-row row-between-wrapper">
          <div>
            <div class="name">推广人数</div>
            <div>
              <span class="num">{{ first + second }}</span
              >人
            </div>
          </div>
          <div class="iconfont icon-tuandui"></div>
        </div>
      </div>
      <div class="nav acea-row row-around">
        <div
          class="item"
          :class="screen.grade == 0 ? 'on' : ''"
          @click="checkGrade(0)"
        >
          一级({{ first }})
        </div>
        <div
          class="item"
          :class="screen.grade == 1 ? 'on' : ''"
          @click="checkGrade(1)"
        >
          二级({{ second }})
        </div>
      </div>
      <div class="search acea-row row-between-wrapper">
        <form @submit.prevent="submitForm">
          <div class="input">
            <input placeholder="点击搜索会员名称" v-model="screen.keyword" />
            <span class="iconfont icon-guanbi"></span>
          </div>
        </form>
        <div class="iconfont icon-sousuo2"></div>
      </div>
    </div>
    <div class="list">
      <div
        class="sortNav acea-row row-middle"
        :class="fixedState === true ? 'on' : ''"
      >
        <div class="sortItem" @click="sort('childCount')">
          团队排序
          <img src="@assets/images/sort1.png" v-if="childCount == 1" />
          <img src="@assets/images/sort2.png" v-if="childCount == 2" />
          <img src="@assets/images/sort3.png" v-if="childCount == 3" />
        </div>
        <div class="sortItem" @click="sort('numberCount')">
          金额排序
          <img src="@assets/images/sort1.png" v-if="numberCount == 1" />
          <img src="@assets/images/sort2.png" v-if="numberCount == 2" />
          <img src="@assets/images/sort3.png" v-if="numberCount == 3" />
        </div>
        <div class="sortItem" @click="sort('orderCount')">
          订单排序
          <img src="@assets/images/sort1.png" v-if="orderCount == 1" />
          <img src="@assets/images/sort2.png" v-if="orderCount == 2" />
          <img src="@assets/images/sort3.png" v-if="orderCount == 3" />
        </div>
      </div>
      <div :class="fixedState === true ? 'sortList' : ''">
        <div
          class="item acea-row row-between-wrapper"
          v-for="(val, index) in spreadList"
          :key="index"
        >
          <div class="picTxt acea-row row-between-wrapper">
            <div class="pictrue"><img :src="val.avatar" /></div>
            <div class="text">
              <div class="name line1">{{ val.nickname }}</div>
              <div>加入时间: {{ val.time }}</div>
            </div>
          </div>
          <div class="right">
            <div>
              <span class="font-color-red">{{ val.childCount }}</span> 人
            </div>
            <div>{{ val.orderCount }} 单</div>
            <div>{{ val.numberCount ? val.numberCount : 0 }} 元</div>
          </div>
        </div>
      </div>
    </div>
    <Loading :loaded="loaded" :loading="loading"></Loading>
  </div>
</template>
<script>
import { getSpreadUser } from "../../../api/user";
import Loading from "@components/Loading";
export default {
  name: "PromoterList",
  components: {
    Loading
  },
  props: {},
  data: function() {
    return {
      fixedState: false,
      screen: {
        page: 1,
        limit: 15,
        grade: 0,
        keyword: "",
        sort: ""
      },
      childCount: 2,
      numberCount: 2,
      orderCount: 2,
      loaded: false,
      loading: false,
      spreadList: [],
      loadTitle: "",
      first: "",
      second: ""
    };
  },
  mounted: function() {
    this.getSpreadUsers();
    this.$scroll(this.$refs.container, () => {
      !this.loading && this.getSpreadUsers();
    });
  },
  watch: {
    "screen.sort": function() {
      this.screen.page = 0;
      this.loaded = false;
      this.loading = false;
      this.spreadList = [];
      this.getSpreadUsers();
    }
  },
  methods: {
    handleScroll: function() {
      var scrollTop =
        document.documentElement.scrollTop || document.body.scrollTop;
      var offsetTop = document.querySelector(".header").clientHeight;
      if (scrollTop >= offsetTop) {
        this.fixedState = true;
      } else {
        this.fixedState = false;
      }
    },
    submitForm: function() {
      this.screen.page = 0;
      this.loaded = false;
      this.loading = false;
      this.spreadList = [];
      this.getSpreadUsers();
    },
    getSpreadUsers: function() {
      let that = this,
        screen = that.screen;
      if (that.loaded || that.loading) return;
      that.loading = true;
      getSpreadUser(screen).then(
        res => {
          that.loading = false;
          that.spreadList.push.apply(that.spreadList, res.data.list);
          that.loaded = res.data.list.length < that.screen.limit; //判断所有数据是否加载完成;
          that.loadTitle = that.loaded ? "人家是有底线的" : "上拉加载更多";
          that.screen.page = that.screen.page + 1;
          that.first = res.data.total;
          that.second = res.data.totalLevel;
        },
        error => {
          that.$dialog.message(error.msg);
        },
        300
      );
    },
    checkGrade: function(val) {
      if (val == this.screen.grade) return;
      else {
        this.screen.page = 1;
        this.screen.grade = val;
        this.loading = false;
        this.loaded = false;
        this.spreadList = [];
        this.getSpreadUsers();
      }
    },
    sort: function(types) {
      let that = this;
      switch (types) {
        case "childCount":
          if (that.childCount == 2) {
            that.childCount = 1;
            that.orderCount = 2;
            that.numberCount = 2;
            that.screen.sort = "childCount DESC";
          } else if (that.childCount == 1) {
            that.childCount = 3;
            that.orderCount = 2;
            that.numberCount = 2;
            that.screen.sort = "childCount ASC";
          } else if (that.childCount == 3) {
            that.childCount = 2;
            that.orderCount = 2;
            that.numberCount = 2;
            that.screen.sort = "";
          }
          break;
        case "numberCount":
          if (that.numberCount == 2) {
            that.numberCount = 1;
            that.orderCount = 2;
            that.childCount = 2;
            that.screen.sort = "numberCount DESC";
          } else if (that.numberCount == 1) {
            that.numberCount = 3;
            that.orderCount = 2;
            that.childCount = 2;
            that.screen.sort = "numberCount ASC";
          } else if (that.numberCount == 3) {
            that.numberCount = 2;
            that.orderCount = 2;
            that.childCount = 2;
            that.screen.sort = "";
          }
          break;
        case "orderCount":
          if (that.orderCount == 2) {
            that.orderCount = 1;
            that.numberCount = 2;
            that.childCount = 2;
            that.screen.sort = "orderCount DESC";
          } else if (that.orderCount == 1) {
            that.orderCount = 3;
            that.numberCount = 2;
            that.childCount = 2;
            that.screen.sort = "orderCount ASC";
          } else if (that.orderCount == 3) {
            that.orderCount = 2;
            that.numberCount = 2;
            that.childCount = 2;
            that.screen.sort = "";
          }
          break;
        default:
          that.screen.sort = "";
      }
    }
  }
};
</script>

PromoterOrder.vue

<template>
  <div class="promoter-order" ref="container">
    <div class="promoterHeader bg-color-red">
      <div class="headerCon acea-row row-between-wrapper">
        <div>
          <div class="name">累计推广订单</div>
          <div>
            <span class="num">{{ count }}</span
            >单
          </div>
        </div>
        <div class="iconfont icon-2"></div>
      </div>
    </div>
    <div class="list">
      <div class="item" v-for="(item, index) in list" :key="index">
        <div class="title acea-row row-column row-center">
          <div class="data">{{ item.time }}</div>
          <div>本月累计推广订单:{{ item.count ? item.count : 0 }}单</div>
        </div>
        <div class="listn">
          <div class="itenm" v-for="(val, indexn) in item.child" :key="indexn">
            <div class="top acea-row row-between-wrapper">
              <div class="pictxt acea-row row-between-wrapper">
                <div class="pictrue">
                  <img :src="val.avatar" />
                </div>
                <div class="text line1">{{ val.nickname }}</div>
              </div>
              <div class="money">
                返佣:<span class="font-color-red"
                  >¥{{ val.number ? val.number : 0 }}</span
                >
              </div>
            </div>
            <div class="bottom">
              <div><span class="name">订单号:</span>{{ val.order_id }}</div>
              <div><span class="name">下单时间:</span>{{ val.time }}</div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <Loading :loaded="loaded" :loading="loading"></Loading>
  </div>
</template>
<script>
import { getSpreadOrder } from "../../../api/user";
import Loading from "@components/Loading";
export default {
  name: "PromoterOrder",
  components: {
    Loading
  },
  props: {},
  data: function() {
    return {
      list: [],
      where: {
        page: 1,
        limit: 15
      },
      loaded: false,
      loading: false,
      loadTitle: "",
      count: ""
    };
  },
  mounted: function() {
    this.getIndex();
    this.$scroll(this.$refs.container, () => {
      !this.loading && this.getIndex();
    });
  },
  methods: {
    getIndex: function() {
      let there = this;
      if (there.loaded == true || there.loading == true) return;
      there.loading = true;
      getSpreadOrder(there.where).then(
        res => {
          there.loading = false;
          there.loaded = res.data.list.length < there.where.limit;
          there.loadTitle = there.loaded ? "人家是有底线的" : "上拉加载更多";
          there.where.page = there.where.page + 1;
          there.list.push.apply(there.list, res.data.list);
          there.count = res.data.count;
        },
        error => {
          there.$dialog.message(error.msg);
        },
        300
      );
    }
  }
};
</script>

PromoterRank.vue

<template>
  <div class="PromoterRank">
    <div class="redBg bg-color-red">
      <div class="header">
        <div class="nav acea-row row-center-wrapper">
          <div
            class="item"
            :class="active === index ? 'font-color-red' : ''"
            v-for="(item, index) in navList"
            :key="index"
            @click="active = index"
          >
            {{ item }}
          </div>
        </div>
        <div class="rank acea-row row-bottom row-around">
          <div class="item" v-show="Two.uid">
            <div class="pictrue"><img :src="Two.avatar" /></div>
            <div class="name line1">{{ Two.nickname }}</div>
            <div class="num">{{ Two.count }}人</div>
          </div>
          <div class="item" v-if="One.uid">
            <div class="pictrue"><img :src="One.avatar" /></div>
            <div class="name line1">{{ One.nickname }}</div>
            <div class="num">{{ One.count }}人</div>
          </div>
          <div class="item" v-if="Three.uid">
            <div class="pictrue"><img :src="Three.avatar" /></div>
            <div class="name line1">{{ Three.nickname }}</div>
            <div class="num">{{ Three.count }}人</div>
          </div>
        </div>
      </div>
    </div>
    <div class="list" v-if="rankList.length">
      <div
        class="item acea-row row-between-wrapper"
        v-for="(item, index) in rankList"
        :key="item.nickname"
      >
        <div class="num">{{ index + 4 }}</div>
        <div class="picTxt acea-row row-between-wrapper">
          <div class="pictrue"><img :src="item.avatar" /></div>
          <div class="text line1">{{ item.nickname }}</div>
        </div>
        <div class="people font-color-red">{{ item.count }}人</div>
      </div>
    </div>
  </div>
</template>
<style scoped>
.PromoterRank .redBg {
  padding: 0.45rem 0 0.3rem 0;
}
.PromoterRank .header {
  background: url("../../../assets/images/integralbg.jpg") no-repeat;
  width: 100%;
  height: 4.6rem;
  background-size: 100% 100%;
}
.PromoterRank .header .nav {
  width: 4.5rem;
  height: 0.66rem;
  border: 1px solid #fff;
  border-radius: 0.33rem;
  font-size: 0.3rem;
  color: #fff;
  margin: 0 auto;
}
.PromoterRank .header .nav .item {
  width: 2.23rem;
  height: 100%;
  text-align: center;
  line-height: 0.64rem;
}
.PromoterRank .header .nav .item.font-color-red:nth-of-type(1) {
  background-color: #fff;
  border-radius: 0.33rem 0 0 0.33rem;
}
.PromoterRank .header .nav .item.font-color-red:nth-of-type(2) {
  background-color: #fff;
  border-radius: 0 0.33rem 0.33rem 0;
}
.PromoterRank .header .rank {
  padding: 0 0.2rem;
  margin-top: 0.3rem;
}
.PromoterRank .header .rank .item .pictrue {
  background: url("../../../assets/images/twoT.png") no-repeat;
  background-size: 100% 100%;
  width: 1.36rem;
  height: 1.77rem;
  position: relative;
  margin: 0 auto;
}
.PromoterRank .header .rank .item .pictrue img {
  position: absolute;
  width: 1.3rem;
  height: 1.3rem;
  display: block;
  bottom: 0.02rem;
  border-radius: 50%;
  left: 50%;
  margin-left: -0.65rem;
}
.PromoterRank .header .rank .item:nth-of-type(2) .pictrue {
  background-image: url("../../../assets/images/oneT.png");
  width: 1.56rem;
  height: 2.05rem;
}
.PromoterRank .header .rank .item:nth-of-type(2) .pictrue img {
  width: 1.5rem;
  height: 1.5rem;
  margin-left: -0.75rem;
}
.PromoterRank .header .rank .item:nth-of-type(3) .pictrue {
  background-image: url("../../../assets/images/threeT.png");
}
.PromoterRank .header .rank .item:nth-of-type(3) .pictrue img {
  margin-left: -0.64rem;
}
.PromoterRank .header .rank .item .name {
  font-size: 0.3rem;
  color: #fff;
  margin-top: 0.22rem;
  text-align: center;
  width: 1.7rem;
}
.PromoterRank .header .rank .item .num {
  font-size: 0.3rem;
  color: #fff;
  text-align: center;
}
.PromoterRank .list {
  width: 7.1rem;
  background-color: #fff;
  border-radius: 0.2rem;
  margin: -0.6rem auto 0 auto;
  padding: 0 0.3rem;
}
.PromoterRank .list .item {
  border-bottom: 1px solid #f3f3f3;
  height: 1.01rem;
  font-size: 0.28rem;
}
.PromoterRank .list .item .num {
  color: #666;
  width: 0.7rem;
}
.PromoterRank .list .item .picTxt {
  width: 3.5rem;
}
.PromoterRank .list .item .picTxt .pictrue {
  width: 0.68rem;
  height: 0.68rem;
}
.PromoterRank .list .item .picTxt .pictrue img {
  width: 100%;
  height: 100%;
  display: block;
  border-radius: 50%;
}
.PromoterRank .list .item .picTxt .text {
  width: 2.62rem;
  color: #333;
}
.PromoterRank .list .item .people {
  width: 1.75rem;
  text-align: right;
}
</style>
<script>
import { getRankList } from "@api/user";
const NAME = "PromoterRank";
export default {
  name: NAME,
  props: {},
  data: function() {
    return {
      navList: ["周榜", "月榜"],
      active: 0,
      page: 1,
      limit: 10,
      loading: false,
      loadend: false,
      rankList: [],
      One: {},
      Two: {},
      Three: {},
      type: "week"
    };
  },
  watch: {
    $route(n) {
      if (n.name === NAME) {
        this.loaded = false;
        this.page = 1;
        this.$set(this, "rankList", []);
        this.getRankList();
      }
    },
    active: function(n) {
      this.type = n ? "month" : "week";
      this.page = 1;
      this.loaded = false;
      this.$set(this, "rankList", []);
      this.getRankList();
    }
  },
  mounted: function() {
    this.getRankList();
    this.$scroll(this.$refs.container, () => {
      !this.loading && this.getRankList();
    });
  },
  methods: {
    getRankList: function() {
      getRankList({
        page: this.page,
        limit: this.limit,
        type: this.type
      })
        .then(res => {
          let list = res.data;
          this.rankList.push.apply(this.rankList, list);
          if (this.page == 1) {
            this.One = this.rankList.shift() || {};
            this.Two = this.rankList.shift() || {};
            this.Three = this.rankList.shift() || {};
          }
          this.page++;
          this.loading = false;
          this.loaded = list.length < this.limit;
          this.$set(this, "rankList", this.rankList);
        })
        .catch(() => {
          this.loading = false;
        });
    }
  }
};
</script>

UserCash.vue

<template>
  <div class="cash-withdrawal">
    <div class="nav acea-row">
      <div
        v-for="(item, index) in navList"
        class="item font-color-red"
        @click="swichNav(index, item)"
        :key="index"
      >
        <div
          class="line bg-color-red"
          :class="currentTab === index ? 'on' : ''"
        ></div>
        <div
          class="iconfont"
          :class="item.icon + ' ' + (currentTab === index ? 'on' : '')"
        ></div>
        <div>{{ item.name }}</div>
      </div>
    </div>
    <div class="wrapper">
      <div :hidden="currentTab !== 0" class="list">
        <div class="item acea-row row-between-wrapper">
          <div class="name">持卡人</div>
          <div class="input">
            <input placeholder="请输入持卡人姓名" v-model="post.name" />
          </div>
        </div>
        <div class="item acea-row row-between-wrapper">
          <div class="name">卡号</div>
          <div class="input">
            <input placeholder="请填写卡号" v-model="post.cardnum" />
          </div>
        </div>
        <div class="item acea-row row-between-wrapper">
          <div class="name">银行</div>
          <div class="input">
            <select v-model="post.bankname">
              <option value="">请选择银行</option>
              <option
                v-for="(item, index) in banks"
                :key="index"
                value="item"
                >{{ item }}</option
              >
            </select>
          </div>
        </div>
        <div class="item acea-row row-between-wrapper">
          <div class="name">提现</div>
          <div class="input">
            <input
              :placeholder="'最低提现金额' + minPrice"
              v-model="post.money"
            />
          </div>
        </div>
        <div class="tip">当前可提现金额: {{ commissionCount }}</div>
        <div class="bnt bg-color-red" @click="submitted">提现</div>
      </div>
      <div :hidden="currentTab !== 1" class="list">
        <div class="item acea-row row-between-wrapper">
          <div class="name">微信号</div>
          <div class="input">
            <input placeholder="请输入微信号" v-model="post.weixin" />
          </div>
        </div>
        <div class="item acea-row row-between-wrapper">
          <div class="name">提现</div>
          <div class="input">
            <input
              :placeholder="'最低提现金额' + minPrice"
              v-model="post.money"
            />
          </div>
        </div>
        <div class="tip">当前可提现金额: {{ commissionCount }}</div>
        <div class="bnt bg-color-red" @click="submitted">提现</div>
      </div>
      <div :hidden="currentTab !== 2" class="list">
        <div class="item acea-row row-between-wrapper">
          <div class="name">用户名</div>
          <div class="input">
            <input placeholder="请填写您的支付宝用户名" v-model="post.name" />
          </div>
        </div>
        <div class="item acea-row row-between-wrapper">
          <div class="name">账号</div>
          <div class="input">
            <input
              placeholder="请填写您的支付宝账号"
              v-model="post.alipay_code"
            />
          </div>
        </div>
        <div class="item acea-row row-between-wrapper">
          <div class="name">提现</div>
          <div class="input">
            <input
              :placeholder="'最低提现金额' + minPrice"
              v-model="post.money"
            />
          </div>
        </div>
        <div class="tip">当前可提现金额: {{ commissionCount }}</div>
        <div class="bnt bg-color-red" @click="submitted">提现</div>
      </div>
    </div>
  </div>
</template>
<script>
import { getBank, postCashInfo } from "../../../api/user";
import { required } from "@utils/validate";
import { validatorDefaultCatch } from "@utils/dialog";

export default {
  name: "UserCash",
  components: {},
  props: {},
  data: function() {
    return {
      navList: [
        { name: "银行卡", type: "bank", icon: "icon-yinhangqia" },
        { name: "微信", type: "weixin", icon: "icon-weixin2" },
        { name: "支付宝", type: "alipay", icon: "icon-icon34" }
      ],
      post: {
        extract_type: "bank",
        alipay_code: "",
        money: "",
        name: "",
        bankname: "",
        cardnum: "",
        weixin: ""
      },
      currentTab: 0,
      minPrice: 0,
      banks: [],
      commissionCount: 0
    };
  },
  mounted: function() {
    this.getBank();
  },
  methods: {
    swichNav: function(index, item) {
      this.currentTab = index;
      this.post.extract_type = item.type;
    },
    getBank: function() {
      let that = this;
      getBank().then(
        res => {
          that.banks = res.data.extractBank;
          that.minPrice = res.data.minPrice;
          that.commissionCount = res.data.commissionCount;
        },
        function(err) {
          that.$dialog.message(err.msg);
        }
      );
    },
    async submitted() {
      let bankname = this.post.bankname,
        alipay_code = this.post.alipay_code,
        money = this.post.money,
        name = this.post.name,
        cardnum = this.post.cardnum,
        weixin = this.post.weixin,
        that = this;
      if (
        parseFloat(money) > parseFloat(that.commissionCount) ||
        parseFloat(that.commissionCount) == 0
      )
        return that.$dialog.message("余额不足");
      if (parseFloat(money) < parseFloat(that.minPrice))
        return that.$dialog.message("最低提现金额" + that.minPrice);
      switch (that.post.extract_type) {
        case "bank":
          try {
            await this.$validator({
              name: [required.message("持卡人姓名")],
              cardnum: [required(required.message("卡号"))],
              bankname: [required(required("请选择提现银行"))],
              money: [required.message("提现金额")]
            }).validate({ bankname, cardnum, name, money });
            let save = {
              extract_type: that.post.extract_type,
              bankname: bankname,
              cardnum: cardnum,
              name: name,
              money: money
            };
            that.save(save);
          } catch (e) {
            return validatorDefaultCatch(e);
          }
          break;
        case "alipay":
          try {
            await this.$validator({
              name: [required(required.message("支付宝用户名"))],
              alipay_code: [required(required.message("支付宝账号"))],
              money: [required(required.message("提现金额"))]
            }).validate({ name, alipay_code, money });
            let save = {
              extract_type: that.post.extract_type,
              alipay_code: alipay_code,
              name: name,
              money: money
            };
            that.save(save);
          } catch (e) {
            return validatorDefaultCatch(e);
          }
          break;
        case "weixin":
          try {
            await this.$validator({
              weixin: [required(required.message("提现微信号"))],
              money: [required(required.message("提现金额"))]
            }).validate({ weixin, money });
            let save = {
              extract_type: that.post.extract_type,
              weixin: weixin,
              money: money
            };
            that.save(save);
          } catch (e) {
            return validatorDefaultCatch(e);
          }
          break;
      }
    },
    save: function(info) {
      postCashInfo(info).then(
        res => {
          this.$dialog.message(res.msg);
          this.$router.push({ path: "/user/audit" });
        },
        error => {
          this.$dialog.message(error.msg);
        }
      );
    }
  }
};
</script>

UserPromotion.vue

<template>
  <div class="my-promotion">
    <div class="header">
      <div class="name acea-row row-center-wrapper">
        <div>当前佣金</div>
        <router-link class="record" :to="'/user/cashrecord'">
          提现记录<span class="iconfont icon-xiangyou"></span>
        </router-link>
      </div>
      <div class="num">{{ userInfo.brokerage_price || 0 }}</div>
      <div class="profit acea-row row-between-wrapper">
        <div class="item">
          <div>昨日收益</div>
          <div class="money">{{ userInfo.yesterDay || 0 }}</div>
        </div>
        <div class="item">
          <div>累积已提</div>
          <div class="money">{{ userInfo.extractTotalPrice || 0 }}</div>
        </div>
      </div>
    </div>
    <div class="bnt bg-color-red" @click="toCash">立即提现</div>
    <div class="list acea-row row-between-wrapper">
      <router-link
        class="item acea-row row-center-wrapper row-column"
        :to="'/user/poster'"
      >
        <span class="iconfont icon-erweima"></span>
        <div>推广名片</div>
      </router-link>
      <router-link
        class="item acea-row row-center-wrapper row-column"
        :to="'/user/promoter_list'"
      >
        <span class="iconfont icon-tongji"></span>
        <div>推广人统计</div>
      </router-link>
      <router-link
        class="item acea-row row-center-wrapper row-column"
        :to="'/user/commission'"
      >
        <span class="iconfont icon-qiandai"></span>
        <div>佣金明细</div>
      </router-link>
      <router-link
        class="item acea-row row-center-wrapper row-column"
        :to="'/user/promoter_order'"
      >
        <span class="iconfont icon-dingdan"></span>
        <div>推广人订单</div>
      </router-link>
      <router-link
        class="item acea-row row-center-wrapper row-column"
        :to="'/user/promoter_rank'"
      >
        <span class="iconfont icon-paihang1"></span>
        <div>推广人排行</div>
      </router-link>
      <router-link
        class="item acea-row row-center-wrapper row-column"
        :to="'/user/commission/rank'"
      >
        <span class="iconfont icon-paihang"></span>
        <div>佣金排行</div>
      </router-link>
    </div>
  </div>
</template>
<script>
import { getUser } from "../../../api/user";

export default {
  name: "UserPromotion",
  components: {},
  props: {},
  data: function() {
    return {
      userInfo: {}
    };
  },
  mounted: function() {
    this.getInfo();
  },
  methods: {
    getInfo: function() {
      let that = this;
      getUser().then(
        res => {
          that.userInfo = res.data;
          console.log(that.userInfo);
        },
        function(err) {
          that.$dialog.message(err.msg);
        }
      );
    },
    toCash: function() {
      this.$router.push({ path: "/user/user_cash" });
    }
  }
};
</script>

Recharge.vue

<template>
  <div>
    <div class="recharge">
      <div class="nav acea-row row-around row-middle">
        <div
          class="item"
          :class="active === index ? 'on' : ''"
          v-for="(item, index) in navRecharge"
          :key="index"
          @click="navRecharges(index)"
        >
          {{ item }}
        </div>
      </div>
      <div class="info-wrapper">
        <div class="money">
          <span>¥</span>
          <input type="number" placeholder="0.00" v-model="money" />
        </div>
        <div class="tips" v-if="!active">
          提示:当前余额为<span>¥{{ now_money || 0 }}</span>
        </div>
        <div class="tips" v-else>
          提示:当前佣金为<span>¥{{ userInfo.brokerage_price || 0 }}</span>
        </div>
        <div class="pay-btn bg-color-red" @click="recharge">
          {{ active ? "立即转入" : "立即充值" }}
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import { mapGetters } from "vuex";
import { pay } from "@libs/wechat";
import { isWeixin } from "@utils";
import { rechargeWechat } from "@api/user";
import { add, sub } from "@utils/bc";

export default {
  name: "Recharge",
  components: {},
  props: {},
  data: function() {
    return {
      navRecharge: ["账户充值", "佣金导入"],
      active: 0,
      payType: ["weixin"],
      from: isWeixin() ? "weixin" : "weixinh5",
      money: "",
      now_money: ""
    };
  },
  computed: mapGetters(["userInfo"]),
  mounted: function() {
    this.now_money = this.userInfo.now_money;
  },
  methods: {
    navRecharges: function(index) {
      this.active = index;
    },
    recharge: function() {
      let that = this,
        price = Number(this.money);
      if (that.active) {
        if (price === 0) {
          return that.$dialog.toast({ mes: "请输入您要转入的金额" });
        } else if (price < 0.01) {
          return that.$dialog.toast({ mes: "转入金额不能低于0.01" });
        }
        this.$dialog.confirm({
          mes: "转入余额无法在转出,请确认转入",
          title: "转入余额",
          opts: [
            {
              txt: "确认",
              color: false,
              callback: () => {
                rechargeWechat({ price: price, from: that.from, type: 1 })
                  .then(res => {
                    that.now_money = add(
                      price,
                      parseInt(that.userInfo.now_money)
                    );
                    that.userInfo.brokerage_price = sub(
                      that.userInfo.brokerage_price,
                      price
                    );
                    that.money = "";
                    return that.$dialog.toast({ mes: res.msg });
                  })
                  .catch(res => {
                    that.$dialog.toast({ mes: res.msg });
                  });
              }
            },
            {
              txt: "取消",
              color: false,
              callback: () => {
                return that.$dialog.toast({ mes: "已取消" });
              }
            }
          ]
        });
      } else {
        if (price === 0) {
          return that.$dialog.toast({ mes: "请输入您要充值的金额" });
        } else if (price < 0.01) {
          return that.$dialog.toast({ mes: "充值金额不能低于0.01" });
        }
        rechargeWechat({ price: price, from: that.from })
          .then(res => {
            var data = res.data;
            if (data.type == "weixinh5") {
              location.replace(data.data.mweb_url);
              this.$dialog.confirm({
                mes: "充值余额",
                opts: [
                  {
                    txt: "已充值",
                    color: false,
                    callback: () => {
                      that.$router.replace({
                        path: "/user/account"
                      });
                    }
                  },
                  {
                    txt: "查看余额",
                    color: false,
                    callback: () => {
                      that.$router.replace({
                        path: "/user/account"
                      });
                    }
                  }
                ]
              });
            } else {
              pay(data.data)
                .finally(() => {
                  that.now_money = add(
                    price,
                    parseInt(that.userInfo.now_money)
                  );
                  that.$dialog.toast({ mes: "支付成功" });
                })
                .catch(function() {
                  that.$dialog.toast({ mes: "支付失败" });
                });
            }
          })
          .catch(res => {
            that.$dialog.toast({ mes: res.msg });
          });
      }
    }
  }
};
</script>
<style scoped>
#iframe {
  display: none;
}
.recharge {
  width: 7.03rem;
  padding: 0.5rem 0.63rem 0.45rem;
  background-color: #fff;
  margin: 0.2rem auto 0 auto;
  border-radius: 0.1rem;
}
.recharge .nav {
  height: 0.75rem;
  line-height: 0.75rem;
  padding: 0 1rem;
}
.recharge .nav .item {
  font-size: 0.3rem;
  color: #333;
}
.recharge .nav .item.on {
  font-weight: bold;
  border-bottom: 0.04rem solid #e83323;
}
.recharge .info-wrapper {
  text-align: center;
}
.recharge .info-wrapper .money {
  margin-top: 0.6rem;
  padding-bottom: 0.2rem;
  border-bottom: 1px dashed #ddd;
}
.recharge .info-wrapper .money span {
  font-size: 0.56rem;
  color: #333;
  font-weight: bold;
}
.recharge .info-wrapper .money input {
  display: inline-block;
  width: 3rem;
  font-size: 0.84rem;
  text-align: center;
  color: #282828;
  font-weight: bold;
  padding-right: 0.7rem;
}
.recharge .info-wrapper .money input::placeholder {
  color: #ddd;
}
.recharge .info-wrapper .money input::-webkit-input-placeholder {
  color: #ddd;
}
.recharge .info-wrapper .money input:-moz-placeholder {
  color: #ddd;
}
.recharge .info-wrapper .money input::-moz-placeholder {
  color: #ddd;
}
.recharge .info-wrapper .money input:-ms-input-placeholder {
  color: #ddd;
}
.recharge .info-wrapper .tips {
  font-size: 0.26rem;
  color: #888;
  margin: 0.25rem auto 0 auto;
  line-height: 1.5;
  padding: 0 0.3rem;
}
.recharge .info-wrapper .tips span {
  color: #ef4a49;
}
.recharge .info-wrapper .pay-btn {
  display: block;
  width: 5.5rem;
  height: 0.86rem;
  margin: 0.5rem auto 0 auto;
  line-height: 0.86rem;
  text-align: center;
  color: #fff;
  border-radius: 0.5rem;
  font-size: 0.3rem;
  font-weight: bold;
}
</style>

Register.vue

<template>
  <div class="register absolute">
    <div class="shading">
      <div class="pictrue acea-row row-center-wrapper">
        <img src="@assets/images/logo2.png" />
      </div>
    </div>
    <div class="whiteBg">
      <div class="title">注册账号</div>
      <div class="list">
        <div class="item">
          <div>
            <svg class="icon" aria-hidden="true">
              <use xlink:href="#icon-phone_"></use>
            </svg>
            <input type="text" placeholder="输入手机号码" />
          </div>
        </div>
        <div class="item">
          <div class="align-left">
            <svg class="icon" aria-hidden="true">
              <use xlink:href="#icon-code_1"></use>
            </svg>
            <input type="text" placeholder="填写验证码" class="codeIput" />
            <button
              class="code"
              :disabled="disabled"
              :class="disabled === true ? 'on' : ''"
              @click="code"
            >
              {{ text }}
            </button>
          </div>
        </div>
        <div class="item">
          <div>
            <svg class="icon" aria-hidden="true">
              <use xlink:href="#icon-code_"></use>
            </svg>
            <input type="text" placeholder="填写您的登录密码" />
          </div>
        </div>
      </div>
      <div class="logon">注册</div>
      <div class="tip">
        已有账号?
        <span @click="$router.push({ name: 'Login' })" class="font-color-red"
          >立即登录</span
        >
      </div>
    </div>
    <div class="bottom"></div>
  </div>
</template>

<script>
import sendVerifyCode from "@mixins/SendVerifyCode";

export default {
  name: "Register",
  mixins: [sendVerifyCode],
  methods: {
    code: function() {
      this.sendCode();
    }
  }
};
</script>

RetrievePassword.vue

<template>
  <div class="register absolute">
    <div class="shading">
      <div class="pictrue acea-row row-center-wrapper">
        <img src="@assets/images/logo2.png" />
      </div>
    </div>
    <div class="whiteBg">
      <div class="title">找回密码</div>
      <div class="list">
        <div class="item">
          <div>
            <svg class="icon" aria-hidden="true">
              <use xlink:href="#icon-phone_"></use>
            </svg>
            <input type="text" placeholder="输入手机号码" v-model="account" />
          </div>
        </div>
        <div class="item">
          <div class="align-left">
            <svg class="icon" aria-hidden="true">
              <use xlink:href="#icon-code_1"></use>
            </svg>
            <input
              type="text"
              placeholder="填写验证码"
              class="codeIput"
              v-model="captcha"
            />
            <button
              class="code"
              :disabled="disabled"
              :class="disabled === true ? 'on' : ''"
              @click="code"
            >
              {{ text }}
            </button>
          </div>
        </div>
        <div class="item">
          <div>
            <svg class="icon" aria-hidden="true">
              <use xlink:href="#icon-code_"></use>
            </svg>
            <input
              type="password"
              placeholder="填写您的登录密码"
              v-model="password"
            />
          </div>
        </div>
      </div>
      <div class="logon" @click="registerReset">确认</div>
      <div class="tip">
        <span @click="$router.push({ name: 'Login' })" class="font-color-red"
          >立即登录</span
        >
      </div>
    </div>
    <div class="bottom"></div>
  </div>
</template>

<script>
import sendVerifyCode from "@mixins/SendVerifyCode";
import { registerVerify, registerReset } from "@api/user";
import { validatorDefaultCatch } from "@utils/dialog";
import attrs, { required, alpha_num, chs_phone } from "@utils/validate";

export default {
  name: "RetrievePassword",
  data: function() {
    return {
      account: "",
      password: "",
      captcha: ""
    };
  },
  mixins: [sendVerifyCode],
  methods: {
    async registerReset() {
      var that = this;
      const { account, captcha, password } = that;
      try {
        await that
          .$validator({
            account: [
              required(required.message("手机号码")),
              chs_phone(chs_phone.message())
            ],
            captcha: [
              required(required.message("验证码")),
              alpha_num(alpha_num.message("验证码"))
            ],
            password: [
              required(required.message("密码")),
              attrs.range([6, 16], attrs.range.message("密码")),
              alpha_num(alpha_num.message("密码"))
            ]
          })
          .validate({ account, captcha, password });
      } catch (e) {
        return validatorDefaultCatch(e);
      }
      registerReset({
        account: that.account,
        captcha: that.captcha,
        password: that.password
      })
        .then(res => {
          that.$dialog.success(res.msg).then(() => {
            that.$router.push({ name: "Login" });
          });
        })
        .catch(res => {
          that.$dialog.error(res.msg);
        });
    },
    async code() {
      var that = this;
      const { account } = that;
      try {
        await that
          .$validator({
            account: [
              required(required.message("手机号码")),
              chs_phone(chs_phone.message())
            ]
          })
          .validate({ account });
      } catch (e) {
        return validatorDefaultCatch(e);
      }
      registerVerify({ phone: that.account })
        .then(res => {
          that.$dialog.success(res.msg);
          that.sendCode();
        })
        .catch(res => {
          that.$dialog.error(res.msg);
        });
    }
  }
};
</script>

signIn
Integral.vue

<template>
  <div class="integral-details" ref="container">
    <div class="header">
      <div class="currentScore">当前积分</div>
      <div>{{ info.integral }}</div>
      <div class="line"></div>
      <div class="nav acea-row">
        <div class="item">
          <div class="num">{{ info.sum_integral }}</div>
          <div>累计积分</div>
        </div>
        <div class="item">
          <div class="num">{{ info.deduction_integral }}</div>
          <div>累计消费</div>
        </div>
        <div class="item">
          <div class="num">{{ info.today_integral }}</div>
          <div>今日获得</div>
        </div>
      </div>
    </div>
    <div class="wrapper">
      <div class="nav acea-row">
        <div
          class="item acea-row row-center-wrapper"
          :class="current === index ? 'on' : ''"
          v-for="(item, index) in navList"
          :key="index"
          @click="nav(index)"
        >
          <span class="iconfont" :class="item.icon"></span>{{ item.name }}
        </div>
      </div>
      <div class="list" :hidden="current !== 0">
        <div class="tip acea-row row-middle">
          <span class="iconfont icon-shuoming"></span
          >提示:积分数值的高低会直接影响您的会员等级
        </div>
        <div
          class="item acea-row row-between-wrapper"
          v-for="(item, index) in list"
          :key="index"
        >
          <div>
            <div class="state">{{ item.mark }}</div>
            <div>{{ item.add_time }}</div>
          </div>
          <div class="num" v-if="item.pm == 1">+{{ item.number }}</div>
          <div class="num font-color-red" v-if="item.pm == 0">
            -{{ item.number }}
          </div>
        </div>
      </div>
      <div class="list2" :hidden="current !== 1">
        <router-link class="item acea-row row-between-wrapper" :to="'/'">
          <div class="pictrue"><img src="@assets/images/score.png" /></div>
          <div class="name">购买商品可获得积分奖励</div>
          <div class="earn">赚积分</div>
        </router-link>
        <router-link
          class="item acea-row row-between-wrapper"
          :to="'/user/sign'"
        >
          <div class="pictrue"><img src="@assets/images/score.png" /></div>
          <div class="name">每日签到可获得积分奖励</div>
          <div class="earn">赚积分</div>
        </router-link>
      </div>
    </div>
    <Loading :loaded="loaded" :loading="loading"></Loading>
  </div>
</template>
<script>
import { getIntegralList, postSignUser } from "../../../api/user";
import Loading from "@components/Loading";
export default {
  name: "Integral",
  components: {
    Loading
  },
  props: {},
  data: function() {
    return {
      navList: [
        { name: "分值明细", icon: "icon-mingxi" },
        { name: "分值提升", icon: "icon-tishengfenzhi" }
      ],
      current: 0,
      where: {
        page: 1,
        limit: 15
      },
      data: {
        sign: 1,
        integral: 1,
        all: 1
      },
      list: [],
      info: [],
      loaded: false,
      loading: false
    };
  },
  mounted: function() {
    this.getIntegral();
    this.getInfo();
    this.$scroll(this.$refs.container, () => {
      !this.loading && this.getInfo();
    });
  },
  methods: {
    nav: function(index) {
      this.current = index;
    },
    getInfo: function() {
      let that = this;
      if (that.loaded == true || that.loading == true) return;
      that.loading = true;
      getIntegralList(that.where).then(
        res => {
          that.loading = false;
          that.loaded = res.data.length < that.where.limit;
          that.loadTitle = that.loaded ? "人家是有底线的" : "上拉加载更多";
          that.where.page = that.where.page + 1;
          that.list.push.apply(that.list, res.data);
        },
        err => {
          that.$dialog.message(err.msg);
        }
      );
    },
    getIntegral: function() {
      let that = this;
      postSignUser(that.data).then(
        res => {
          that.info = res.data;
        },
        err => {
          that.$dialog.message(err.msg);
        }
      );
    }
  }
};
</script>

Sign.vue

<template>
  <div class="sign">
    <div class="header bg-color-red">
      <div class="headerCon acea-row row-between-wrapper">
        <div class="left acea-row row-between-wrapper">
          <div class="pictrue"><img :src="userInfo.avatar" /></div>
          <div class="text">
            <div class="line1">{{ userInfo.nickname }}</div>
            <div class="integral acea-row">
              <span>积分: {{ userInfo.integral }}</span>
            </div>
          </div>
        </div>
        <router-link
          :to="'/user/sign_record'"
          class="right acea-row row-middle"
        >
          <div class="iconfont icon-caidan"></div>
          <div>明细</div>
        </router-link>
      </div>
    </div>
    <div class="wrapper">
      <div class="list acea-row row-between-wrapper">
        <div class="item" v-for="(item, index) in signSystemList" :key="index">
          <div :class="index + 1 === signSystemList.length ? 'rewardTxt' : ''">
            {{ item.day }}
          </div>
          <div
            class="venus"
            :class="
              (index + 1 === signSystemList.length ? 'reward' : '') +
                ' ' +
                (sign_index >= index + 1 ? 'venusSelect' : '')
            "
          ></div>
          <div class="num" :class="sign_index >= index + 1 ? 'on' : ''">
            +{{ item.sign_num }}
          </div>
        </div>
      </div>
      <!--加在 but 上 on 为已签到-->
      <div
        class="but bg-color-red"
        :class="userInfo.is_day_sgin ? 'on' : ''"
        @click="goSign"
      >
        {{ userInfo.is_day_sgin ? "已签到" : "立即签到" }}
      </div>
      <div class="lock"></div>
    </div>
    <div class="wrapper wrapper2">
      <div class="tip">已累计签到</div>
      <div class="list2 acea-row row-center row-bottom">
        <div class="item" v-for="(item, index) in signCount" :key="index">
          {{ item || 0 }}
        </div>
        <div class="data">天</div>
      </div>
      <div class="tip2">
        据说连续签到第{{ day }}天可获得超额积分,一定要坚持签到哦~~~
      </div>
      <div class="list3">
        <div
          class="item acea-row row-between-wrapper"
          v-for="(item, index) in signList"
          :key="index"
        >
          <div>
            <div class="name line1">{{ item.title }}</div>
            <div class="data">{{ item.add_time }}</div>
          </div>
          <div class="num font-color-red">+{{ item.number }}</div>
        </div>
        <router-link
          :to="'/user/sign_record'"
          class="Loads acea-row row-center-wrapper"
          v-if="signList.length > 0"
        >
          点击加载更多
          <div class="iconfont icon-xiangyou acea-row row-center-wrapper"></div>
        </router-link>
      </div>
    </div>
    <div
      class="signTip acea-row row-center-wrapper"
      :class="active === true ? 'on' : ''"
    >
      <div class="signTipLight loadingpic"></div>
      <div class="signTipCon">
        <div class="state">签到成功</div>
        <div class="integral">获得{{ integral }}积分</div>
        <div class="signTipBnt" @click="close">好的</div>
      </div>
    </div>
    <div class="mask" @touchmove.prevent :hidden="active === false"></div>
  </div>
</template>
<style scoped>
.Loads .iconfont {
  font-size: 0.25rem;
  margin: 0.02rem 0 0 0.1rem;
}
</style>
<script>
import {
  postSignUser,
  getSignConfig,
  postSignIntegral,
  getSignList
} from "@api/user";
import { add } from "@utils/bc";

export default {
  name: "Sign",
  components: {},
  props: {},
  data: function() {
    return {
      userInfo: {},
      integral: 0,
      signCount: [],
      sign_index: 0,
      signSystemList: [],
      signList: [],
      page: 1,
      limit: 3,
      active: false,
      day: ""
    };
  },
  mounted: function() {
    this.signUser();
    this.signConfig();
    this.getSignList();
  },
  methods: {
    // js给数字补0;num:需要补0的数字,length:长度(补到多少位);
    PrefixInteger: function(num, length) {
      return (Array(length).join("0") + num).slice(-length).split("");
    },
    //数字转中文
    Rp: function(n) {
      var cnum = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"];
      var s = "";
      n = "" + n; // 数字转为字符串
      for (var i = 0; i < n.length; i++) {
        s += cnum[parseInt(n.charAt(i))];
      }
      return s;
    },
    // 获取用户信息
    signUser: function() {
      let that = this;
      postSignUser({ sign: 1 }).then(res => {
        res.data.integral = parseInt(res.data.integral);
        var sumSginDay = res.data.sum_sgin_day;
        that.userInfo = res.data;
        that.signCount = that.PrefixInteger(sumSginDay, 4);
        that.sign_index = parseInt(res.data.sign_num);
      });
    },
    // 签到配置
    signConfig: function() {
      let that = this;
      getSignConfig().then(res => {
        that.signSystemList = res.data;
        that.day = that.Rp(that.signSystemList.length);
      });
    },
    //  用户签到
    goSign: function() {
      let that = this,
        sumSginDay = that.userInfo.sum_sgin_day;
      if (that.userInfo.is_day_sgin)
        return that.$dialog.toast({ mes: "您今日已签到!" });
      postSignIntegral().then(res => {
        that.active = true;
        that.integral = res.data.integral;
        let sign_index = parseInt(that.sign_index + 1);
        that.sign_index =
          sign_index > that.signSystemList.length ? 1 : sign_index;
        that.signCount = that.PrefixInteger(sumSginDay + 1, 4);
        that.userInfo.is_day_sgin = true;
        that.userInfo.integral = add(that.userInfo.integral, res.data.integral);
        that.getSignList();
      });
    },
    //  获取签到列表;
    getSignList: function() {
      let that = this;
      getSignList(that.page, that.limit).then(res => {
        that.signList = res.data;
      });
    },
    close: function() {
      this.active = false;
    }
  }
};
</script>

SignRecord.vue

<template>
  <div class="sign-record" ref="container">
    <div class="list">
      <div class="item" v-for="(item, index) in signList" :key="index">
        <div class="data">{{ item.month }}</div>
        <div class="listn">
          <div
            class="itemn acea-row row-between-wrapper"
            v-for="(itemn, indexn) in item.list"
            :key="indexn"
          >
            <div>
              <div class="name line1">{{ itemn.title }}</div>
              <div>{{ itemn.add_time }}</div>
            </div>
            <div class="num font-color-red">+{{ itemn.number }}</div>
          </div>
        </div>
      </div>
    </div>
    <Loading :loaded="loadend" :loading="loading"></Loading>
  </div>
</template>
<script>
import { getSignMonth } from "@api/user";
import Loading from "@components/Loading";
export default {
  name: "SignRecord",
  components: {
    Loading
  },
  props: {},
  data: function() {
    return {
      page: 1,
      limit: 3,
      signList: [],
      loading: false,
      loadend: false,
      active: false
    };
  },
  mounted: function() {
    this.signListTap();
    this.$scroll(this.$refs.container, () => {
      !this.loading && this.signListTap();
    });
  },
  methods: {
    signListTap: function() {
      let that = this;
      if (that.loading) return; //阻止下次请求(false可以进行请求);
      if (that.loadend) return; //阻止结束当前请求(false可以进行请求);
      that.loading = true;
      getSignMonth(that.page, that.limit).then(res => {
        that.loading = false;
        //apply();js将一个数组插入另一个数组;
        that.signList.push.apply(that.signList, res.data);
        that.loadend = res.data.length < that.limit; //判断所有数据是否加载完成;
        that.page = that.page + 1;
      });
    }
  }
};
</script>

User.vue

<template>
  <div class="user">
    <div class="header bg-color-red acea-row row-between-wrapper">
      <div class="picTxt acea-row row-between-wrapper">
        <div class="pictrue"><img :src="userInfo.avatar" /></div>
        <div class="text">
          <div class="acea-row row-middle">
            <div class="name line1">{{ userInfo.nickname }}</div>
            <div class="member acea-row row-middle" v-if="userInfo.vip">
              <img :src="userInfo.vip_icon" />{{ userInfo.vip_name }}
            </div>
          </div>
          <router-link :to="'/user/data'" class="id" v-if="userInfo.phone">
            ID:{{ userInfo.uid || 0
            }}<span class="iconfont icon-bianji1"></span>
          </router-link>
          <router-link :to="'/user/binding'" class="binding" v-else>
            <span>绑定手机号</span>
          </router-link>
        </div>
      </div>
      <span
        class="iconfont icon-shezhi"
        @click="$router.push({ path: '/user/data' })"
      ></span>
    </div>
    <div class="wrapper">
      <div class="nav acea-row row-middle">
        <router-link :to="{ path: '/user/account' }" class="item">
          <div>我的余额</div>
          <div class="num">{{ userInfo.now_money || 0 }}</div>
        </router-link>
        <router-link
          :to="'/user/user_promotion'"
          class="item"
          v-if="userInfo.is_promoter === 1 || userInfo.statu === 2"
        >
          <div>当前佣金</div>
          <div class="num">{{ userInfo.brokerage_price || 0 }}</div>
        </router-link>
        <router-link :to="'/user/integral'" class="item" v-else>
          <div>当前积分</div>
          <div class="num">{{ userInfo.integral || 0 }}</div>
        </router-link>
        <router-link :to="'/user/user_coupon'" class="item">
          <div>优惠券</div>
          <div class="num">{{ userInfo.couponCount || 0 }}</div>
        </router-link>
      </div>
      <div class="myOrder">
        <div class="title acea-row row-between-wrapper">
          <div>我的订单</div>
          <router-link :to="'/order/list/'" class="allOrder">
            全部订单<span class="iconfont icon-jiantou"></span>
          </router-link>
        </div>
        <div class="orderState acea-row row-middle">
          <router-link :to="{ path: '/order/list/' + 0 }" class="item">
            <div class="pictrue">
              <img src="@assets/images/dfk.png" />
              <span
                class="order-status-num"
                v-if="orderStatusNum.unpaid_count > 0"
                >{{ orderStatusNum.unpaid_count }}</span
              >
            </div>
            <div>待付款</div>
          </router-link>
          <router-link :to="{ path: '/order/list/' + 1 }" class="item">
            <div class="pictrue">
              <img src="@assets/images/dfh.png" />
              <span
                class="order-status-num"
                v-if="orderStatusNum.unshipped_count > 0"
                >{{ orderStatusNum.unshipped_count }}</span
              >
            </div>
            <div>待发货</div>
          </router-link>
          <router-link :to="{ path: '/order/list/' + 2 }" class="item">
            <div class="pictrue">
              <img src="@assets/images/dsh.png" />
              <span
                class="order-status-num"
                v-if="orderStatusNum.received_count > 0"
                >{{ orderStatusNum.received_count }}</span
              >
            </div>
            <div>待收货</div>
          </router-link>
          <router-link :to="{ path: '/order/list/' + 3 }" class="item">
            <div class="pictrue">
              <img src="@assets/images/dpj.png" />
              <span
                class="order-status-num"
                v-if="orderStatusNum.evaluated_count > 0"
                >{{ orderStatusNum.evaluated_count }}</span
              >
            </div>
            <div>待评价</div>
          </router-link>
          <router-link :to="'/order/refund_list'" class="item">
            <div class="pictrue">
              <img src="@assets/images/sh.png" />
              <span
                class="order-status-num"
                v-if="orderStatusNum.refund_count > 0"
                >{{ orderStatusNum.refund_count }}</span
              >
            </div>
            <div>售后/退款</div>
          </router-link>
        </div>
      </div>
      <div class="myService">
        <div class="title acea-row row-middle">我的服务</div>
        <div class="serviceList acea-row row-middle">
          <template v-for="(item, index) in MyMenus">
            <div
              class="item"
              :key="index"
              @click="goPages(index)"
              v-if="item.wap_url"
            >
              <div class="pictrue">
                <img :src="item.pic" />
              </div>
              <div>{{ item.name }}</div>
            </div>
          </template>
          <!--<div-->
          <!--class="item"-->
          <!--@click="changeswitch(true)"-->
          <!--v-if="userInfo.phone && isWeixin"-->
          <!--&gt;-->
          <!--<div class="pictrue"><img src="@assets/images/switch.png" /></div>-->
          <!--<div>账号切换</div>-->
          <!--</div>-->
        </div>
      </div>
    </div>
    <img src="@assets/images/support.png" class="support" />
    <div class="footer-line-height"></div>
    <SwitchWindow
      v-on:changeswitch="changeswitch"
      :switchActive="switchActive"
      :login_type="userInfo.login_type"
    ></SwitchWindow>
  </div>
</template>
<script>
import { getUser, getMenuUser } from "@api/user";
import { isWeixin } from "@utils";
import SwitchWindow from "@components/SwitchWindow";

const NAME = "User";

export default {
  name: NAME,
  components: {
    SwitchWindow
  },
  props: {},
  data: function() {
    return {
      userInfo: {},
      MyMenus: [],
      orderStatusNum: {},
      switchActive: false,
      isWeixin: false
    };
  },
  watch: {
    $route(n) {
      if (n.name === NAME) this.User();
    }
  },
  mounted: function() {
    this.User();
    this.MenuUser();
    this.isWeixin = isWeixin();
  },
  methods: {
    changeswitch: function(data) {
      this.switchActive = data;
    },
    User: function() {
      let that = this;
      getUser().then(res => {
        that.userInfo = res.data;
        that.orderStatusNum = res.data.orderStatusNum;
      });
    },
    MenuUser: function() {
      let that = this;
      getMenuUser().then(res => {
        that.MyMenus = res.data.routine_my_menus;
      });
    },
    goPages: function(index) {
      let url = this.MyMenus[index].wap_url;
      if (url === "/user/user_promotion" && this.userInfo.statu === 1) {
        if (!this.userInfo.is_promoter)
          return this.$dialog.toast({ mes: "您还没有推广权限!!" });
      }
      if (url === "/customer/index" && !this.userInfo.adminid) {
        return this.$dialog.toast({ mes: "您还不是客服!!" });
      }

      this.$router.push({ path: this.MyMenus[index].wap_url });
    }
  }
};
</script>

<style scoped>
.footer-line-height {
  height: 1rem;
}
.order-status-num {
  min-width: 0.33rem;
  background-color: #fff;
  color: #ee5a52;
  border-radius: 15px;
  position: absolute;
  right: -0.14rem;
  top: -0.15rem;
  font-size: 0.2rem;
  padding: 0 0.08rem;
  border: 1px solid #ee5a52;
}

.pictrue {
  position: relative;
}
.switch-h5 {
  margin-left: 0.2rem;
}
.binding {
  padding: 0.05rem 0.2rem;
  background-color: #ca1f10;
  border-radius: 50px;
  font-size: 0.14rem;
  border: 1px solid #e8695e;
  color: #ffffff;
}
</style>

UserAccount.vue

<template>
  <div class="my-account">
    <div class="wrapper">
      <div class="header">
        <div class="headerCon">
          <div class="account acea-row row-top row-between">
            <div class="assets">
              <div>总资产(元)</div>
              <div class="money">{{ now_money }}</div>
            </div>
            <router-link :to="'/user/Recharge'" class="recharge font-color-red"
              >充值</router-link
            >
          </div>
          <div class="cumulative acea-row row-top">
            <div class="item">
              <div>累计充值(元)</div>
              <div class="money">{{ recharge }}</div>
            </div>
            <div class="item">
              <div>累计消费(元)</div>
              <div class="money">{{ orderStatusSum }}</div>
            </div>
          </div>
        </div>
      </div>
      <div class="nav acea-row row-middle">
        <router-link class="item" :to="'/user/bill/0'">
          <div class="pictrue"><img src="@assets/images/record1.png" /></div>
          <div>账单记录</div>
        </router-link>
        <router-link class="item" :to="'/user/bill/1'">
          <div class="pictrue"><img src="@assets/images/record2.png" /></div>
          <div>消费记录</div>
        </router-link>
        <router-link class="item" :to="'/user/bill/2'">
          <div class="pictrue"><img src="@assets/images/record3.png" /></div>
          <div>充值记录</div>
        </router-link>
        <router-link class="item" :to="'/user/integral'">
          <div class="pictrue"><img src="@assets/images/record4.png" /></div>
          <div>积分中心</div>
        </router-link>
      </div>
      <div class="advert acea-row row-between-wrapper">
        <router-link
          class="item acea-row row-between-wrapper"
          :to="'/user/sign'"
        >
          <div class="text">
            <div class="name">签到领积分</div>
            <div>赚积分抵现金</div>
          </div>
          <div class="pictrue"><img src="@assets/images/gift.png" /></div>
        </router-link>
        <router-link
          class="item on acea-row row-between-wrapper"
          :to="'/user/get_coupon'"
        >
          <div class="text">
            <div class="name">领取优惠券</div>
            <div>满减享优惠</div>
          </div>
          <div class="pictrue"><img src="@assets/images/money.png" /></div>
        </router-link>
      </div>
      <div class="list">
        <div class="item acea-row row-between-wrapper">
          <div class="picTxt acea-row row-between-wrapper">
            <div class="iconfont icon-hebingxingzhuang"></div>
            <div class="text">
              <div class="line1">最新拼团活动</div>
              <div class="infor line1">最新的优惠商品上架拼团</div>
            </div>
          </div>
          <router-link
            class="bnt"
            :to="'/activity/group'"
            v-if="activity.is_pink"
            >立即参与</router-link
          >
          <div class="bnt end" v-else>已结束</div>
        </div>
        <div class="item acea-row row-between-wrapper">
          <div class="picTxt acea-row row-between-wrapper">
            <div class="iconfont icon-miaosha yellow"></div>
            <div class="text">
              <div class="line1">当前限时秒杀</div>
              <div class="infor line1">最新商品秒杀进行中</div>
            </div>
          </div>
          <router-link
            class="bnt"
            :to="'/activity/goods_seckill'"
            v-if="activity.is_seckill"
            >立即参与</router-link
          >
          <div class="bnt end" v-else>已结束</div>
        </div>
        <div class="item acea-row row-between-wrapper">
          <div class="picTxt acea-row row-between-wrapper">
            <div class="iconfont icon-kanjia1 green"></div>
            <div class="text">
              <div class="line1">砍价活动</div>
              <div class="infor line1">呼朋唤友来砍价</div>
            </div>
          </div>
          <router-link
            class="bnt"
            :to="'/activity/bargain'"
            v-if="activity.is_bargin"
            >立即参与</router-link
          >
          <div class="bnt end" v-else>已结束</div>
        </div>
      </div>
    </div>
    <Recommend></Recommend>
  </div>
</template>
<script>
import Recommend from "@components/Recommend";
import { getActivityStatus, getBalance } from "../../api/user";
export default {
  name: "UserAccount",
  components: {
    Recommend
  },
  props: {},
  data: function() {
    return {
      now_money: 0,
      orderStatusSum: 0,
      recharge: 0,
      activity: {
        is_bargin: false,
        is_pink: false,
        is_seckill: false
      }
    };
  },
  mounted: function() {
    this.getIndex();
    this.getActivity();
  },
  methods: {
    getIndex: function() {
      let that = this;
      getBalance().then(
        res => {
          that.now_money = res.data.now_money;
          that.orderStatusSum = res.data.orderStatusSum;
          that.recharge = res.data.recharge;
        },
        err => {
          that.$dialog.message(err.msg);
        }
      );
    },
    getActivity: function() {
      let that = this;
      getActivityStatus().then(
        res => {
          that.activity.is_bargin = res.data.is_bargin;
          that.activity.is_pink = res.data.is_pink;
          that.activity.is_seckill = res.data.is_seckill;
        },
        error => {
          that.$dialog.message(error.msg);
        }
      );
    }
  }
};
</script>

UserBill.vue

<template>
  <div class="bill-details" ref="container">
    <div class="nav acea-row">
      <div class="item" :class="types == 0 ? 'on' : ''" @click="changeTypes(0)">
        全部
      </div>
      <div class="item" :class="types == 1 ? 'on' : ''" @click="changeTypes(1)">
        消费
      </div>
      <div class="item" :class="types == 2 ? 'on' : ''" @click="changeTypes(2)">
        充值
      </div>
    </div>
    <div class="sign-record">
      <div class="list">
        <div class="item" v-for="(item, index) in list" :key="index">
          <div class="data">{{ item.time }}</div>
          <div class="listn" v-for="(val, key) in item.list" :key="key">
            <div class="itemn acea-row row-between-wrapper">
              <div>
                <div class="name line1">{{ val.title }}</div>
                <div>{{ val.add_time }}</div>
              </div>
              <div class="num" :class="val.pm == 0 ? 'font-color-red' : ''">
                {{ val.pm == 0 ? "-" : "+" }}{{ val.number }}
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <Loading :loaded="loaded" :loading="loading"></Loading>
  </div>
</template>
<script>
import { getCommissionInfo } from "../../api/user";
import Loading from "@components/Loading";
export default {
  name: "UserBill",
  components: {
    Loading
  },
  props: {},
  data: function() {
    return {
      types: "",
      where: {
        page: 1,
        limit: 5
      },
      list: [],
      loaded: false,
      loading: false
    };
  },
  watch: {
    "$route.params.types": function(newVal) {
      let that = this;
      if (newVal != undefined) {
        that.types = newVal;
        that.list = [];
        that.where.page = 1;
        that.loaded = false;
        that.loading = false;
        that.getIndex();
      }
    },
    types: function() {
      this.getIndex();
    }
  },
  mounted: function() {
    let that = this;
    that.types = that.$route.params.types;
    that.getIndex();
    that.$scroll(that.$refs.container, () => {
      !that.loading && that.getIndex();
    });
  },
  methods: {
    code: function() {
      this.sendCode();
    },
    changeTypes: function(val) {
      if (val != this.types) {
        this.types = val;
        this.list = [];
        this.where.page = 1;
        this.loaded = false;
        this.loading = false;
      }
    },
    getIndex: function() {
      let that = this;
      if (that.loaded == true || that.loading == true) return;
      that.loading = true;
      getCommissionInfo(that.where, that.types).then(
        res => {
          that.loading = false;
          that.loaded = res.data.length < that.where.limit;
          that.where.page = that.where.page + 1;
          that.list.push.apply(that.list, res.data);
        },
        error => {
          that.$dialog.message(error.msg);
        }
      );
    }
  }
};
</script>

UserVip.vue

<template>
  <div class="member-center">
    <div class="header">
      <div class="slider-banner banner">
        <swiper class="swiper-wrapper" :options="swiperVip" ref="mySwiper">
          <swiperSlide
            class="swiper-slide memberBg"
            :class="item.class"
            v-for="(item, index) in vipList"
            :key="index"
            :style="{ backgroundImage: 'url(' + item.image + ')' }"
          >
            <!--            <img :src="item.icon" />-->
            <div class="name">{{ item.name }}</div>
            <div class="discount">
              可享受商品折扣: {{ item.discount / 10 }}折<span
                class="iconfont icon-zhekou"
              ></span>
            </div>
            <div class="nav acea-row" v-if="item.grade == grade">
              <div
                class="item"
                v-for="(val, indexn) in vipComplete"
                :key="indexn"
              >
                <div class="num">{{ val.number }}</div>
                <div>{{ val.real_name }}</div>
              </div>
            </div>
            <div class="lock" v-if="item.grade > grade">
              <span class="iconfont icon-quanxianguanlisuozi"></span
              >该会员等级尚未解锁
            </div>
            <div class="lock" v-if="item.grade < grade">
              <span class="iconfont icon-xuanzhong1"></span>已解锁更高等级
            </div>
          </swiperSlide>
        </swiper>
      </div>
    </div>
    <div class="wrapper">
      <div class="title acea-row row-between-wrapper">
        <div><span class="iconfont icon-jingyanzhi"></span>会员升级要求</div>
        <div class="num">
          <span class="current">{{ taskCount }}</span
          >/{{ vipRequire.length }}
        </div>
      </div>
      <div class="list">
        <div class="item" v-for="(item, index) in vipComplete" :key="index">
          <div class="top acea-row row-between-wrapper">
            <div class="name">
              {{ item.name
              }}<span
                class="iconfont icon-wenti"
                v-if="item.illustrate"
                @click="showGrow(item)"
              ></span>
            </div>
            <div>{{ item.finish ? "已满足条件" : "未满足条件" }}</div>
          </div>
          <div class="cu-progress">
            <div class="bg-red" :style="{ width: item.speed + '%' }"></div>
          </div>
          <div class="experience acea-row row-between-wrapper">
            <div>{{ item.task_type_title }}</div>
            <div>
              <span class="num">{{ item.new_number }}</span
              >/{{ item.number }}
            </div>
          </div>
        </div>
      </div>
    </div>
    <Recommend></Recommend>
    <div class="growthValue" :class="growthValue === false ? 'on' : ''">
      <div class="pictrue">
        <img src="@assets/images/value.jpg" /><span
          class="iconfont icon-guanbi3"
          @click="growthTap"
        ></span>
      </div>
      <div class="conter">
        {{ illustrate }}
      </div>
    </div>
    <div class="mask" :hidden="growthValue" @click="growthTap"></div>
  </div>
</template>
<script>
import { swiper, swiperSlide } from "vue-awesome-swiper";
import "@assets/css/swiper.min.css";
import Recommend from "@components/Recommend";
import { getVipInfo, getVipTask, setDetection } from "../../api/user";
export default {
  name: "Poster",
  components: {
    swiper,
    swiperSlide,
    Recommend
  },
  props: {},
  data: function() {
    return {
      vipList: [], //等级列表
      vipRequire: [], //等级要求
      vipComplete: [], //完成情况
      taskCount: 0, //任务数
      grade: 0, //当前会员等级
      swiperVip: {
        speed: 1000,
        effect: "coverflow",
        slidesPerView: "auto",
        centeredSlides: true,
        // loop: true,
        coverflowEffect: {
          rotate: 0, // 旋转的角度
          stretch: -20, // 拉伸   图片间左右的间距和密集度
          depth: 100, // 深度   切换图片间上下的间距和密集度
          modifier: 2, // 修正值 该值越大前面的效果越明显
          slideShadows: false // 页面阴影效果
        },
        observer: true,
        observeParents: true
      },
      loading: false,
      growthValue: true,
      illustrate: "",
      activeIndex: 0
    };
  },
  watch: {
    vipList: function() {
      let that = this;
      if (that.vipList.length > 0) {
        that.vipList.forEach(function(item, index) {
          if (item.is_clear === false) {
            that.swiper.slideTo(index);
            that.activeIndex = index;
            that.grade = item.grade;
          }
        });
      }
    }
  },
  computed: {
    swiper() {
      return this.$refs.mySwiper.swiper;
    }
  },
  mounted: function() {
    let that = this;
    setDetection();
    that.getInfo();
    that.swiper.on("slideChange", function() {
      that.activeIndex = that.swiper.activeIndex;
      that.getTask();
    });
  },
  methods: {
    growthTap: function() {
      this.growthValue = true;
    },
    getInfo: function() {
      let that = this;
      getVipInfo().then(
        res => {
          that.vipList = res.data.list;
          that.vipRequire = res.data.task.list;
          that.vipComplete = res.data.task.task;
          that.taskCount = res.data.task.reach_count;
        },
        err => {
          that.$dialog.message(err.msg);
        }
      );
    },
    getTask: function() {
      let that = this;
      getVipTask(that.vipList[that.activeIndex].id).then(
        res => {
          that.vipRequire = res.data.list;
          that.vipComplete = res.data.task;
          that.taskCount = res.data.reach_count;
        },
        err => {
          that.$dialog.message(err.msg);
        }
      );
    },
    showGrow: function(item) {
      if (this.illustrate != item.illustrate) this.illustrate = item.illustrate;
      this.growthValue = false;
    }
  }
};
</script>

目录


   └── api

       ├── activity.js

       ├── order.js

       ├── public.js

       ├── store.js

       ├── user.js

   ├── App.vue

   └── assets

       └── css

               ├── base.css

               ├── reset.css

               ├── style.css

       └── images

       └── js

               ├── area.js

               ├── media_750.js

   └── components

       ├── AddressWindow.vue

       ├── CountDown.vue

       ├── CouponListWindow.vue

       ├── CouponPop.vue

       ├── CouponWindow.vue

       ├── Footer.vue

       ├── GoodList.vue

       ├── HelloWorld.vue

       ├── Home.vue

       ├── Loading.vue

       ├── OrderGoods.vue

       ├── Payment.vue

       ├── PriceChange.vue

       ├── ProductConSwiper.vue

       ├── ProductWindow.vue

       ├── PromotionGood.vue

       ├── Recommend.vue

       ├── ShareInfo.vue

       ├── ShareRedPackets.vue

       ├── StorePoster.vue

       ├── SwitchWindow.vue

       ├── UserEvaluation.vue

       ├── WriteOff.vue

   └── libs

       ├── chat.js

       ├── login.js

       ├── order.js

       ├── wechat.js

   ├── main.js

   └── mixins

       ├── SendVerifyCode.js

   └── router

       ├── index.js

       └── module

               ├── activity.js

               ├── index.js

               ├── order.js

               ├── user.js

   ├── s.php

   └── store

       ├── getters.js

       ├── index.js

       └── modules

               ├── app.js

               ├── index.js

   └── utils

       ├── bc.js

       ├── dialog.js

       ├── emoji.js

       ├── index.js

       ├── loading.js

       ├── request.js

       └── store

               ├── cookie.js

               ├── index.js

               ├── localStorage.js

       ├── validate.js

   └── views

       └── activity

               ├── GoodsSeckill.vue

               ├── SeckillDetails.vue

       └── home

               ├── Index.vue

       ├── Loading.vue

       ├── NotDefined.vue

       └── order

               ├── GoodsReturn.vue

               ├── Logistics.vue

               ├── MyOrder.vue

               ├── OrderDetails.vue

               ├── OrderSubmission.vue

               ├── PaymentStatus.vue

               ├── ReturnList.vue

       └── shop

               ├── EvaluateList.vue

               ├── GoodsClass.vue

               ├── GoodsCollection.vue

               ├── GoodsCon.vue

               ├── GoodSearch.vue

               ├── GoodsEvaluate.vue

               ├── GoodsList.vue

               ├── GoodsPromotion.vue

               ├── HotNewGoods.vue

               └── news

                               ├── NewsDetail.vue

                               ├── NewsList.vue

               ├── ShoppingCart.vue

       └── user

               └── address

                               ├── AddAddress.vue

                               ├── AddressManagement.vue

               ├── BindingPhone.vue

               ├── ChangePassword.vue

               └── coupon

                               ├── GetCoupon.vue

                               ├── UserCoupon.vue

               ├── CustomerList.vue

               ├── CustomerService.vue

               ├── Login.vue

               ├── PersonalData.vue

               └── promotion

                               ├── CashAudit.vue

                               ├── CashRecord.vue

                               ├── CommissionDetails.vue

                               ├── CommissionRank.vue

                               ├── Poster.vue

                               ├── PromoterList.vue

                               ├── PromoterOrder.vue

                               ├── PromoterRank.vue

                               ├── UserCash.vue

                               ├── UserPromotion.vue

               ├── Recharge.vue

               ├── Register.vue

               ├── RetrievePassword.vue

               └── signIn

                               ├── Integral.vue

                               ├── Sign.vue

                               ├── SignRecord.vue

               ├── User.vue

               ├── UserAccount.vue

               ├── UserBill.vue

               ├── UserVip.vue