Explorar o código

commit -m 项目初始化

zhengjinyi %!s(int64=2) %!d(string=hai) anos
pai
achega
542182d6b9
Modificáronse 100 ficheiros con 14936 adicións e 3308 borrados
  1. 5 1
      .gitignore
  2. 99 24
      App.vue
  3. 19 0
      README.md
  4. 0 45
      common/auth.js
  5. 0 113
      common/business.helper.js
  6. 54 0
      common/config/addressdata.js
  7. 173 0
      common/config/authorize.js
  8. 446 0
      common/config/caimeiApi.js
  9. 210 0
      common/config/common.js
  10. 60 0
      common/config/wxLogin.js
  11. 0 96
      common/couponUtils.js
  12. 0 26
      common/crypto.js
  13. 410 0
      common/css/common.scss
  14. 0 137
      common/css/global.scss
  15. 0 6
      common/css/icon.css
  16. 143 0
      common/css/iconfont.scss
  17. 2 0
      common/css/style/icon.css
  18. 2480 0
      common/css/style/thorui.css
  19. 0 65
      common/css/theme.scss
  20. 0 25
      common/filters.js
  21. BIN=BIN
      common/fonts/iconfont.ttf
  22. BIN=BIN
      common/fonts/iconfont.woff
  23. BIN=BIN
      common/fonts/iconfont.woff2
  24. 0 195
      common/goods.helper.js
  25. 47 0
      common/json/data.json.js
  26. 0 0
      common/libs/crypto-js.min.js
  27. 0 0
      common/libs/picker.city.js
  28. 0 105
      common/share.helper.js
  29. 0 54
      common/storage.js
  30. 0 89
      common/uniapp.api.js
  31. 0 219
      common/utils.js
  32. 0 92
      common/validation.js
  33. 7 0
      components/clipboard/clipboard.min.js
  34. 12 12
      components/clipboard/clipboard.thorui.js
  35. 267 0
      components/clipboard/formValidation.js
  36. 25 0
      components/clipboard/utils.js
  37. 107 0
      components/cm-custom/au-custom.vue
  38. 122 0
      components/cm-custom/cm-custom.vue
  39. 148 0
      components/cm-custom/cm-drag.vue
  40. 114 0
      components/cm-custom/cu-custom.vue
  41. 159 0
      components/cm-custom/custom-d.vue
  42. 221 0
      components/cm-custom/custom-floor.vue
  43. 229 0
      components/cm-custom/custom-p.vue
  44. 139 0
      components/cm-module/activity/activity.vue
  45. 256 0
      components/cm-module/activity/activityBean.vue
  46. 445 0
      components/cm-module/cm-cart/cm-unit-popup.vue
  47. 2516 0
      components/cm-module/cm-cart/index.vue
  48. 128 0
      components/cm-module/cm-cart/mixins/apisMixins.js
  49. 103 0
      components/cm-module/cm-cart/mixins/cartMixins.js
  50. 280 0
      components/cm-module/coupon/tui-tabs.vue
  51. 214 0
      components/cm-module/headerNavbar/header-back.vue
  52. 51 0
      components/cm-module/listTemplate/listSkeleton.vue
  53. 29 0
      components/cm-module/listTemplate/richTextTemplate.vue
  54. 125 0
      components/cm-module/modelAlert/errorAlert.vue
  55. 140 0
      components/cm-module/modelAlert/freightAlert.vue
  56. 135 0
      components/cm-module/modelAlert/modelAlert.vue
  57. 148 0
      components/cm-module/modelAlert/order-alert.vue
  58. 150 0
      components/cm-module/modelAlert/shareAlert.vue
  59. 140 0
      components/cm-module/modelAlert/shareModel.vue
  60. 235 0
      components/cm-module/orderDetails/activipopu.vue
  61. 523 0
      components/cm-module/orderDetails/goodsList.vue
  62. 197 0
      components/cm-module/orderDetails/invoiceTent.vue
  63. 181 0
      components/cm-module/orderDetails/logisticsRecord.vue
  64. 174 0
      components/cm-module/orderDetails/orderAddress.vue
  65. 234 0
      components/cm-module/orderDetails/orderButton.vue
  66. 329 0
      components/cm-module/orderDetails/orderInformation.vue
  67. 244 0
      components/cm-module/orderDetails/orderListButton.vue
  68. 159 0
      components/cm-module/orderDetails/paymentRecord.vue
  69. 120 0
      components/cm-module/orderDetails/refundRecord.vue
  70. 263 0
      components/cm-module/productDetails/cm-activipopu.vue
  71. 144 0
      components/cm-module/productDetails/cm-ladder-popup.vue
  72. 532 0
      components/cm-module/productDetails/cm-unit-popup.vue
  73. 233 0
      components/cm-module/productDetails/evaluate.vue
  74. 121 0
      components/cm-module/scrollTop/scrollTop.vue
  75. 6 4
      components/cm-simple-swiper/cm-simple-swiper.vue
  76. 0 0
      components/cm-simple-swiper/mixins/swiper.js
  77. 0 6
      components/common/tui-clipboard/clipboard.min.js
  78. 0 0
      components/common/tui-color-analysis/tui-color-analysis.js
  79. 0 314
      components/common/tui-validation/tui-validation.js
  80. 0 0
      components/common/tui-validation/tui-validation.min.js
  81. 0 0
      components/common/tui-zh-pinyin/tui-zh-pinyin.js
  82. 80 0
      components/empty.vue
  83. 33 0
      components/modal-layer.vue
  84. 242 0
      components/mpvue-citypicker/mpvueCityPicker.vue
  85. 2 4
      components/thorui/tui-actionsheet/tui-actionsheet.vue
  86. 0 1
      components/thorui/tui-alert/tui-alert.vue
  87. 0 1
      components/thorui/tui-badge/tui-badge.vue
  88. 13 12
      components/thorui/tui-bottom-navigation/tui-bottom-navigation.vue
  89. 13 24
      components/thorui/tui-bottom-popup/tui-bottom-popup.vue
  90. 0 1
      components/thorui/tui-bubble-popup/tui-bubble-popup.vue
  91. 39 192
      components/thorui/tui-button/tui-button.vue
  92. 1 1
      components/thorui/tui-calendar/tui-calendar.js
  93. 48 153
      components/thorui/tui-calendar/tui-calendar.vue
  94. 0 1
      components/thorui/tui-card/tui-card.vue
  95. 0 567
      components/thorui/tui-cascade-selection/tui-cascade-selection.vue
  96. 0 265
      components/thorui/tui-circular-progress/tui-circular-progress.vue
  97. 0 1
      components/thorui/tui-collapse/tui-collapse.vue
  98. 8 94
      components/thorui/tui-countdown/tui-countdown.vue
  99. 123 240
      components/thorui/tui-datetime/tui-datetime.vue
  100. 81 123
      components/thorui/tui-drawer/tui-drawer.vue

+ 5 - 1
.gitignore

@@ -1 +1,5 @@
-/unpackage/
+unpackage/
+.gitignore
+.idea/
+.hbuilderx/launch.json
+/services/config.env.js

+ 99 - 24
App.vue

@@ -1,30 +1,105 @@
 <script>
-export default {
-    onLaunch: function() {
-        const updateManager = uni.getUpdateManager()
-        updateManager.onCheckForUpdate(function(res) {
-            console.log(res.hasUpdate)
-        })
-        updateManager.onUpdateReady(function(res) {
-            uni.showModal({
-                title: '更新提示',
-                content: '新版本已经准备好,是否重启小程序?',
-                success(res) {
-                    if (res.confirm) {
-                        updateManager.applyUpdate()
-                    }
-                }
-            })
-        })
-        
-        this.$store.dispatch('app/initDevice')
-    }
-}
+	import appMixins from '@/mixins/appMixins.js'
+	export default {
+		mixins: [appMixins],
+		onLaunch() {
+			//小程序热更新代码
+			const updateManager = uni.getUpdateManager()
+			updateManager.onCheckForUpdate(function(res) {
+			    console.log(res.hasUpdate)
+			})
+			updateManager.onUpdateReady(function(res) {
+			    uni.showModal({
+			        title: '更新提示',
+			        content: '新版本已经准备好,是否重启小程序?',
+			        success(res) {
+			            if (res.confirm) {
+			                updateManager.applyUpdate()
+			            }
+			        }
+			    })
+			})
+			this.initSetSystemInfo()
+			this.appUpdataRefresh()
+		},
+		onShow() {
+			
+		},
+		onHide() {
+			console.log('App Hide')
+		},
+	}
 </script>
 
 <style lang="scss">
-page {
-    min-height: 100%;
-    background: #f7f7f7;
+	/*每个页面公共css */
+	@import "@/common/css/common.scss";
+	@import "@/common/css/iconfont.scss";
+	@import "@/common/css/style/thorui.css";
+	@import "@/common/css/style/icon.css";
+
+view,
+scroll-view,
+swiper,
+swiper-item,
+cover-view,
+cover-image,
+icon,
+text,
+rich-text,
+progress,
+button,
+checkbox,
+form,
+input,
+label,
+radio,
+slider,
+switch,
+textarea,
+navigator,
+audio,
+camera,
+image,
+video {
+	// box-sizing: border-box;
+}
+// page {
+//   width: 100%;
+//   height: 100%;
+//   background: #fff;
+//   filter: grayscale(100%);
+//   filter: gray;
+//   filter: progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);
+//   --toast-default-width: 114px;
+// }
+page{
+	height: 100%;
+	background-color: #FFFFFF;
+}
+/* 骨架屏替代方案 */
+.Skeleton {
+	background: #f3f3f3;
+	padding: 20upx 0;
+	border-radius: 8upx;
+}
+
+.clamp {
+	overflow: hidden;
+	text-overflow: ellipsis;
+	white-space: nowrap;
+	display: block;
+}
+
+.common-hover {
+	background: #f5f5f5;
+}
+/* input 样式 */
+.input-placeholder {
+	color: #999999;
+}
+
+.placeholder {
+	color: #999999;
 }
 </style>

+ 19 - 0
README.md

@@ -0,0 +1,19 @@
+caimei-applets-caimei --采美商城小程序
+
+项目介绍
+	-采美商城小程序是用Dcloud推出的uni-app开发的一款小程序
+软件架构
+	-HBuild-X  微信开发者工具
+前端框架API
+	-uni-app  Vue.js  微信Api
+目录结构
+			
+运行项目
+	-下载安装HBuild-X
+	-导入项目文件
+	-点击运行到小程序模拟器->微信开发者工具(自动会编译打包开大微信开发者工具运行)
+使用说明
+
+这是一个基于uni-app的项目,所以要用HBuild-X 来打开预览(支持小程序、安卓、苹果)
+
+

+ 0 - 45
common/auth.js

@@ -1,45 +0,0 @@
-/* 用户授权相关 */
-
-// 获取微信code(用户登录)
-export function wxLogin() {
-    return new Promise((resolve, reject) => {
-        uni.login({
-            provider: 'weixin',
-            success(res) {
-                resolve(res.code)
-            },
-            fail() {
-                reject()
-            }
-        })
-    })
-}
-
-export function authorize(scope, callback) {
-    uni.authorize({
-        scope: `scope.${scope}`,
-        success() {
-            console.log(1)
-            callback()
-        },
-        fail(err) {
-            console.log(err)
-        }
-    })
-}
-
-
-// 获取用户微信信息
-export function getUserProfile() {
-    return new Promise((resolve, reject) => {
-        uni.getUserProfile({
-            desc: '获取头像、昵称', 
-            success(res) {
-                resolve(res.userInfo)
-            },
-            fail(err) {
-                reject(err)
-            }
-        })
-    })
-}

+ 0 - 113
common/business.helper.js

@@ -1,113 +0,0 @@
-// 获取已选商品列表
-export function totalAllCheckedProduct(shopList) {
-    let productList = []
-    shopList.forEach(shop => {
-        productList.push(...shop.productList.filter(product => product.checked))
-    })
-    return productList
-}
-
-// 计算购物车商品价格
-export function computeTotalPrice(productList) {
-    const { allPrice } = productList.reduce((prevPrice, product) => {
-        // 已选商品总价
-        prevPrice.originalPrice += product.price * product.num
-        // 单品满减
-        if (product.promotion && product.promotion.type == 1 && product.promotion.mode == 2) {
-            // 是否满足 满减条件
-            if (product.price * product.num >= product.promotion.touchPrice) {
-                prevPrice.reducedPrice += product.promotion.reducedPrice
-            }
-        }
-        prevPrice.allPrice = prevPrice.originalPrice - prevPrice.reducedPrice
-        return prevPrice
-    }, {
-        originalPrice: 0, // 商品总价
-        reducedPrice: 0, // 优惠金额
-        allPrice: 0 // 组后后价格
-    })
-    return allPrice
-}
-
-// 处理优惠券列表: 排序,优惠券点击类型
-export function initFormatCouponList(couponList = [], controlType, sort) {
-    couponList = couponList.map((coupon, index) => {
-        coupon.controlType = controlType
-        coupon.checked = false
-        coupon.uniqueId = index + 1
-        return coupon
-    })
-
-    if (sort) {
-        return couponList.sort((a, b) => b.couponAmount - a.couponAmount)
-    }
-
-    return couponList
-}
-
-// 将优惠券列表拆分为满足条件和为满足条件列表
-export function splitCouponList(couponList = [], productList = []) {
-    const result = {
-        canUseCouponList: [],
-        notUseCouponList: []
-    }
-    couponList.forEach(coupon => {
-        if (
-            coupon.noThresholdFlag === 1 ||
-            (coupon.productType === 1 && allProdoctUseCheck(productList, coupon)) ||
-            (coupon.productType === 2 && someProductUseCheck(productList, coupon))
-        ) {
-            result.canUseCouponList.push(coupon)
-        } else {
-            result.notUseCouponList.push(coupon)
-        }
-    })
-    return result
-}
-
-// 判断全部商品可用 (全部商品价格总计 是否大于 当前优惠券的触发金额)
-export function allProdoctUseCheck(productList, coupon) {
-    const countPrice = productList.reduce((countPrice, product) => countPrice + product.price * product.num, 0)
-    console.log('all', countPrice)
-    return countPrice >= coupon.touchPrice
-}
-
-// 判断指定商品可用 (当前优惠券可用的商品的价格总计 是否大于 当前优惠券的触发金额)
-export function someProductUseCheck(productList, coupon) {
-    const countPrice = productList.reduce((countPrice, product) => {
-        // 当前优惠券可用的商品总价
-        const isIncludes = coupon.productIds.indexOf(product.productId.toString()) > -1
-        return isIncludes ? countPrice + product.price * product.num : countPrice
-    }, 0)
-    console.log('some', countPrice)
-    return countPrice >= coupon.touchPrice
-}
-
-// 优惠券使用提示
-export function makeCouponUseTip(currentCoupon, nextCoupon, allPrice) {
-    // 两者都不存在
-    if (!currentCoupon && !nextCoupon) return ''
-
-    // 只有可使用券时
-    if (currentCoupon && !nextCoupon) {
-        if (currentCoupon.noThresholdFlag === 1) {
-            return `已享“减${currentCoupon.couponAmount}元”优惠券`
-        }
-
-        return `已享“满${currentCoupon.touchPrice}元减${currentCoupon.couponAmount}元”优惠券`
-    }
-
-    // 只有下阶段券时
-    if (!currentCoupon && nextCoupon) {
-        const { couponAmount: nextCouponAmount, touchPrice: nextTouchPrice } = nextCoupon
-        return `还差¥${(nextTouchPrice - allPrice).toFixed(2)}元可用“满${nextTouchPrice}元减${nextCouponAmount}元”优惠券`
-    }
-
-    // 全部同时有时
-    if (currentCoupon && nextCoupon) {
-        const { couponAmount: currentCouponAmount, touchPrice: currentTouchPrice } = currentCoupon
-        const { couponAmount: nextCouponAmount, touchPrice: nextTouchPrice } = nextCoupon
-        return `还差¥${(nextTouchPrice - allPrice).toFixed(2)}元可用“满${nextTouchPrice}元减${nextCouponAmount}元”优惠券`
-    }
-
-}

+ 54 - 0
common/config/addressdata.js

@@ -0,0 +1,54 @@
+/*
+ *请求获取省市区
+ *已提供给地区选择picker组件使用
+ */ 
+import ajaxService from '@/services/ajax.service.js'
+import PublicService from '@/services/public.service'
+
+const _PublicService = new PublicService(ajaxService)
+
+const provinceData=[];
+const cityData=[];
+const areaData=[];
+
+_PublicService.GetAllAddressData().then(res =>{
+	let list = res.data;
+	list.forEach(item => {
+		let address = handleCitys(item);
+		provinceData.push(item);
+		cityData.push(address.e);
+		areaData.push(address.f);
+	})
+	//获取市后继续处理
+	function handleCitys(data) {
+	    const x = [];
+	    const s = [];
+	    if (data.children.length) {
+	        data.children.forEach(item => {
+				let city = handleTowns(item);
+				s.push(city);
+				x.push(item)
+	        })
+	    }else{
+			s.push([{name:''}]);
+			x.push([{name:''}]);
+		}
+	    return {
+	        e: x,
+	        f: s,
+	    };
+	}
+	//获取区后继续处理
+	function handleTowns(data) {
+	    const x = [];
+	    data.children.forEach(item => {
+	        x.push(item)
+	    })
+	    return x;
+	}
+})
+module.exports = {
+	provinceData,
+	cityData,
+	areaData
+}

+ 173 - 0
common/config/authorize.js

@@ -0,0 +1,173 @@
+//authorize.js
+import api from './caimeiApi.js'
+
+//判断是否登陆 通过检测sessionkey是否过期 1未过期 0已过期
+const checkSessionKey=()=>{	
+    return new Promise((resolve,reject) => {
+        const user = uni.getStorageSync('user')// 用户缓存信息
+        if(user){
+            uni.checkSession({
+			    success() {
+                    resolve(1) //状态未过期
+                }
+			    ,fail() {
+                    resolve(0) //状态已过期
+                }
+            })
+        }else{
+            resolve(2) //未存贮
+        }
+    })
+}
+
+// 登录授权
+const login = (params)=> {
+    return new Promise((resolve,reject) => {
+        authDo(params).then(res=>{
+            if ( res.statusCode && res.statusCode != 200 ) {
+                reject('网络错误,请检查一下网络');return
+            }
+            if (res.data.code != 0) {
+			    reject('登录失败');return
+            }
+            let user = res.data.data.user
+            uni.setStorageSync('user', user)//储存用户信息到本地
+            resolve(user)
+        })
+    })
+}
+
+// 查询用户信息 write by self
+const authDo = function(params) {
+    return new Promise(function (resolve, reject) {
+        uni.request({
+            url: api.requestUrl +'/login/doLogin',
+            data: params,
+            method:'POST',
+            header: {
+	        		'content-type': 'application/x-www-form-urlencoded'
+            },
+            success: function(res){ resolve(res) },
+            fail:function(){ reject('保存用户信息失败') }
+        })
+    })
+}
+
+// 获取服务商信息 uni-app是聚合开发 所以先获得是什么小程序 原生的不用这个
+const getProvider = () => {
+    return new Promise((resolve, reject) => {
+        uni.getProvider({
+            service: 'oauth', //服务类型  登录授权
+            success: function(res) {resolve(res.provider[0])},
+            fail:function() { reject('获取服务商失败') }
+        })
+    })
+}
+
+
+// 获取code
+const getCode = provider => {
+    return new Promise((resolve, reject) => {
+        if (!provider) { reject('获取缺少provider参数') }
+        uni.login({
+            provider: provider,
+            success: function(loginRes) {
+                if (loginRes && loginRes.code) { 
+                    resolve(loginRes.code) 
+                } else {
+                    reject('获取code失败') 
+                    uni.navigateTo({
+                        url:'/pages/tabBar/home/index'
+                    })
+                }
+            },
+            fail:function(error){ 
+                console.log('获取code失败',)
+                reject('获取code失败')
+            }
+        })
+    })
+}
+
+// 是否开启了获取用户名授权 当用户一开始拒绝了 需再次提醒授权
+const getSetting = function() {
+    return new Promise((resolve,reject) => {
+        uni.getSetting({
+            success:function(res) {
+                let authSetting=res.authSetting
+                if(authSetting['scope.userInfo']){resolve(1);return}//授权成功
+                if(authSetting['scope.userInfo']===false){resolve(0);return}//拒绝授权
+                resolve(2) //2未操作
+            },
+            fail:function(error) { 
+                console.log(error)
+                reject('获取用户授权失败') 
+            }
+        })
+    })
+}
+
+// 获取用户信息
+const getUserInfo = (provider)=>{
+    return new Promise( (resolve,reject)=>{
+        if (!provider) { reject('获取缺少provider参数');return }
+        uni.getUserInfo({
+            provider: provider,
+            success: (detail) => {
+                if(detail.iv != ''){
+                    resolve(detail)
+                }else{
+                    reject(0) //用户点击拒绝授权
+                }
+            }
+            ,fail: (error) => {
+                console.log('获取用户信息失败',error)
+                reject(0) //如果用户拒绝过授权 直接走fail
+            }
+        })
+    })
+}
+// 获取用户登录状态
+const checkLogin = () => {
+    return new Promise((resolve, reject) => {
+        uni.checkSession({
+            success() {
+                console.log('登录成功')
+                resolve(1)
+            },
+            fail(error) {
+                console.log('获取用户信息失败',error)
+                reject(0)
+            }
+        })
+    })
+}
+
+// util.js
+const getUserProfile = () =>{
+    wx.getUserProfile({
+        desc: '用于完善个人资料',
+        success: function(res) {
+            var userInfo = res.userInfo
+            // console.log('userInfo==>', userInfo)
+            wx.setStorageSync('storage_info', 1)//本地标记
+            //下面将userInfo存入服务器中的用户个人资料
+            //...
+		  },
+        fail() {
+            console.log('用户拒绝授权')
+        }
+    })
+}
+  
+
+export default {
+    getProvider,
+    getSetting,
+    checkSessionKey,
+    getCode,
+    login,
+    getUserInfo,
+    checkLogin,
+    getUserProfile
+}

+ 446 - 0
common/config/caimeiApi.js

@@ -0,0 +1,446 @@
+/**
+ * @Time 2019-12-12
+ * @Author Zhengjingyi
+ * @Action 全局公共方法
+ */
+import requestUrl from '@/services/config.env.js'
+const caimeiApi = {
+    /**
+	 * @封装公共get数据请求方法无加载动画
+	 * @方法参数:请求地址,请求后台需要的参数字段,回调函数
+	 * @自定义请求头信息
+	 */
+    get:function(url,data,callback){
+		 uni.request({
+            url: requestUrl + url,
+            data:data,
+            header: {
+                'Accept': 'application/json',
+                'Content-Type': 'application/x-www-form-urlencoded', 
+                'X-Token': uni.getStorageSync('token') ? uni.getStorageSync('token') : 'token',
+                'cookie': uni.getStorageSync('sessionid')
+            },
+            method: 'GET',
+            success: (response) => {
+                if(response.statusCode !== 200){
+                    uni.showToast({icon: 'none',title:'服务器连接错误',duration: 2000})
+                    callback(response.statusCode)
+                }else{
+                    callback(response.data)
+                }
+            },
+            fail: (error) => {
+                if (error) {
+                    uni.showToast({icon: 'none',title: '网络错误,请稍后重试',duration: 2000})
+                }
+            }
+		 })
+    },
+    /**
+	 * @封装公共get数据请求方法有加载动画
+	 * @方法参数:请求地址,请求后台需要的参数字段,回调函数
+	 * @自定义请求头信息
+	 */
+    lodingGet:function(url,data,callback){
+		 uni.showLoading({mask: true,title:'加载中~',})
+		 uni.request({
+            url: requestUrl + url,
+            data:data,
+            header: {
+                'Accept': 'application/json',
+                'Content-Type': 'application/x-www-form-urlencoded', 
+                'X-Token': uni.getStorageSync('token') ? uni.getStorageSync('token') : 'token',
+                'cookie': uni.getStorageSync('sessionid')
+            },
+            method: 'GET',
+            success: (response) => {
+                if(response.statusCode !== 200){
+                    uni.showToast({icon: 'none',title: '服务器连接错误',duration: 2000})
+                    callback(response.statusCode)
+                }else{
+                    callback(response.data)
+                }
+            },
+            fail: (error) => {
+                if (error) {
+                    uni.showToast({icon: 'none',title: '网络错误,请稍后重试',duration: 2000})
+                }
+            },
+            complete: () => {
+                setTimeout(function () {
+                    uni.hideLoading()
+                }, 250)
+            }
+		 })
+    },
+    /**
+	 * @封装公共post数据请求方法
+	 * @方法参数:请求地址,请求后台需要的参数字段,回调函数
+	 */
+    post:function(url,data,loadingStatus,callback){
+        if(loadingStatus){uni.showLoading({mask: true,title:'加载中~'})}
+        uni.request({
+            url: requestUrl+url,
+            data:data,
+            header: {
+                'Accept': 'application/json',
+                'Content-Type': 'application/x-www-form-urlencoded',
+                'X-Token': uni.getStorageSync('token') ? uni.getStorageSync('token') : 'token',
+                'cookie': uni.getStorageSync('sessionid')
+            },
+            method: 'POST',
+            success: (response) => {
+                if(loadingStatus){uni.hideLoading()}
+                const result = response.data
+                callback(result)
+            },
+            fail: (error) => {
+                uni.hideLoading()
+                if (error) {
+                    uni.showToast({icon: 'none',title: '网络错误,请稍后重试',duration: 2000})
+                }
+            }
+        })
+    },
+    getComStorage:function(key){// 获取本地Storage
+        return new Promise(function(resolve,reject) {
+            uni.getStorage({
+                key: key,
+                success: function (res){
+                    resolve(res.data)
+                },
+                fail: function(res){
+                    reject(false)
+                }
+            })
+        })
+    },
+    setStorage:function(key,data){// 存储本地Storage
+        return new Promise(function(resolve,reject) {
+            uni.setStorage({
+                key: key,
+                data:data,
+                success: function (res){
+                }
+            })
+        })
+    },
+    getStorage:function(){// 获取本地userInfo
+        return new Promise(function(resolve,reject) {
+            uni.getStorage({
+                key: 'userInfo',
+                success: function (res){
+                    resolve(res.data)
+                },
+                fail: function(res){
+                    reject(false)
+                }
+            })
+        })
+    },
+    removeStorage:function(key){// 获取本地userInfo
+        return new Promise(function(resolve,reject) {
+            uni.removeStorage({
+                key: key,
+                success: function (res) {
+                    console.log('success')
+                }
+            })
+        })
+    },
+    getStorageAddressKey:function(){// 获取本地地址信息
+        return new Promise(function(resolve,reject) {
+            uni.getStorage({
+                key: 'address_key',
+                success: function (res){
+                    resolve(res.data)
+                }
+            })
+        })
+    },
+    loginStatus:function(){
+        // 获取用户是否登陆 1:已登陆,否则未登陆
+        return new Promise(function(resolve,reject) {
+            uni.getStorage({
+                key: 'userInfo',
+                success: function (res){
+                    if(res.data.code == '1'){
+                        resolve(true)
+                    } else {
+                        resolve(false)
+                    }
+                }
+            })
+        })
+    },
+    navToListPage:function({type,value,id,lType} = {}){	
+        // 跳转到列表页
+        if(lType=='4'){
+            const pages = getCurrentPages()
+            const prevPage = pages[pages.length-2]
+            prevPage.refresh = true
+            prevPage.listData = {
+                type: type,
+                from: value,
+                id: id
+            }
+            uni.navigateBack({
+                delta: 1
+            })
+        }else{
+            uni.navigateTo({
+                url:`/pages/goods/goods?type=${type}&from=${value}&id=${id}`
+            })
+        }
+    },
+    navigateToGoods:function({type,value,id,lType} = {}){
+        // 跳转到列表页
+        if(lType=='4'){
+            const pages = getCurrentPages()
+            const prevPage = pages[pages.length-2]
+            prevPage.refresh = true
+            prevPage.listData = {
+                type: type,
+                from: value,
+                id: id
+            }
+            uni.navigateBack({
+                delta: 1
+            })
+        }else{
+            uni.navigateTo({
+                url:`/pages/goods/goods-classify?type=${type}&from=${value}&id=${id}`
+            })
+        }
+    },
+    FlooryNavigateTo:function(pros){
+        if(pros.listType == 1){
+            if(pros.product.productCategory == '1'){
+                uni.navigateTo({
+				  	url:`/pages/goods/product?id=${pros.product.productId}`
+                })
+            }else{
+                uni.navigateTo({
+				  	url:`/pages/second/product/product-details?id=${pros.product.productId}`
+                })
+            }
+        }else{
+            /**
+			 * 页面跳转类型
+			 * 1、二级页面,2、搜索项目仪器,3、直播页面,4、自由页面,5、商品详情,6、仪器项目详情,7、供应商主页
+			 * 8、专题活动页,9、二手市场介绍,10、二手商品列表,11、二手商品发布,12、商品搜索,13、信息详情
+			 * 14、品牌招商介绍页,15、维修保养介绍页,16、首页,17、注册页,18、信息中心,19、供应商列表
+			 **/
+            if(pros.linkType){
+                console.log(pros.linkType)
+                const typeMap = {
+				 	1:`/pages/goods/goods-instrument?linkId=${pros.linkParam.id}`,
+				 	2:`/pages/goods/instrument-details?id=${pros.linkParam.id}`,
+				 	3:`/pages/h5/article/page-image?image=${pros.adsImage}&title=专题直播`,
+                    4:`/pages/h5/activity/activity?link=${pros.crmLink}&linkId=${pros.linkParam.id}`,
+				 	5:`/pages/goods/product?id=${pros.linkParam.id}`,
+				 	7:`/pages/supplier/user/my-shop?shopId=${pros.linkParam.id}`,
+				 	8:'/pages/h5/activity/activity-list',
+				 	9:'/pages/second/form/introduce',
+				 	10:'/pages/second/product/product-list',
+				 	11:'/pages/second/form/form',
+				 	12:`/pages/search/search?keyWord=${pros.linkParam.keyword}`,
+				 	13:`/pages/h5/article/path?link=${pros.link}`,
+				 	14:`/pages/h5/article/path?link=${pros.link}`,
+				 	15:`/pages/h5/article/path?link=${pros.link}`,
+                    // '-1':`/pages/h5/article/path?link=${pros.link}`,
+				 	17:'/pages/login/register-select',
+				 	18:`/pages/h5/article/path?link=${pros.link}`,
+				 	19:`/pages/search/search-supplier?keyWord=${pros.linkParam.keyword}`,
+                    21:'/pages/h5/activity/meobohui',
+                    23:`/pages/h5/activity/activity-topic?linkId=${pros.linkParam.id}`,
+                    24:'/pages/user/coupon/coupon',
+                    25:'/pages/goods/goods-doc-list',//美业资料
+                    28:`/pages/h5/article/path?link=${pros.link}`, // 采美认证通
+                    29:'/pages/user/coupon/coupon-collection',//领券中心
+                }
+                const url = typeMap[pros.linkType]
+                uni.navigateTo({
+				  	url:url
+                })
+            }
+        }
+    },
+    BannerNavigateTo:function(linkType,linkId,linkHref,keyword){//楼层跳转判断
+        if(linkType){
+            const typeMap = {
+                1:`/pages/goods/goods-instrument?linkId=${linkId}`,
+                2:`/pages/goods/instrument-details?id=${linkId}`,
+                4:`/pages/h5/activity/activity?link=${linkHref}&linkId=${linkId}`,
+                5:`/pages/goods/product?id=${linkId}`, 
+                7:`/pages/supplier/user/my-shop?shopId=${linkId}`,
+                8:'/pages/h5/activity/activity-list',
+                9:'/pages/second/form/introduce',
+                10:'/pages/second/product/product-list',
+                11:'/pages/second/form/form',
+                12:`/pages/search/search?keyWord=${keyword}`,
+                13:`/pages/h5/article/path?link=${linkHref}`,
+                14:`/pages/h5/article/path?link=${linkHref}`,
+                15:`/pages/h5/article/path?link=${linkHref}`,
+                17:'/pages/login/register-select',
+                18:`/pages/h5/article/path?link=${linkHref}`,
+                19:`/pages/search/search-supplier?keyWord=${keyword}`,
+                21:'/pages/h5/activity/meobohui',
+                // '-1':`/pages/h5/article/path?link=${linkHref}`
+                24:'/pages/user/coupon/coupon',
+                25:'/pages/goods/goods-doc-list',  //美业资料
+                28:`/pages/h5/article/path?link=${linkHref}`, // 采美认证通
+                29:'/pages/user/coupon/coupon-collection',//领券中心
+
+            }
+            const url = typeMap[linkType]
+            uni.navigateTo({
+			 	url:url
+            })
+        }
+    },
+    navigateTo:function(url){
+        //路由跳转:页面之间路由跳转
+        uni.navigateTo({
+            url:url
+        })
+    },
+    redirectTo:function(url){
+        //路由跳转:关闭当前页跳转到新页面	
+        uni.redirectTo({
+            url:url
+        })
+    },
+    reLaunch:function(url){
+        //路由跳转:关闭当前页跳转到新页面	
+        uni.reLaunch({
+            url:url
+        })
+    },
+    switchTabTo:function(url){
+        //路由跳转:底部 tab页
+        uni.switchTab({
+            url:url
+        })
+    },
+    navigateBack:function(page){
+	    uni.navigateBack({
+		    delta: page
+	    })
+    },
+    isNumber:function(value){//验证是否为数字
+	    var patrn = /^(-)?\d+(\.\d+)?$/
+	    if (patrn.exec(value) == null || value == '') {
+	         return false
+	    } else {
+	         return true  
+        }	 
+    },
+    getWindowHeight:function(){
+        // 获取窗口高度
+        const {windowHeight, pixelRatio} = wx.getSystemInfoSync()
+        return windowHeight
+    },
+    adaptRichTextImg:function(res){
+        /**
+		 *@富文本实现图片自适应
+		 *@style再添加自适应样式
+		 */ 
+        const html = res.replace(/<img[^>]*>/gi,function(match,capture){			
+            let match1 = match.replace(/<img*/gi, '<img style="width:100% !important;height:auto !important;float:left !important;"'),
+                results = match1.replace(/style=/gi, 'style="width:100%;height:auto;float:left;"')
+            return results
+        })
+        return html	
+    },
+    FormatMoney:function(num){
+        // 金额千分位
+        return num.toString().replace(/\d+/, function (n) { // 先提取整数部分
+            return n.replace(/(\d)(?=(\d{3})+$)/g, function ($1) { // 对整数部分添加分隔符
+                return $1 + ','
+            })
+        })
+    },
+    formatDate:function(){
+        //获取当前时间
+        let date = new Date()
+        let y = date.getFullYear()
+        let MM = date.getMonth() + 1
+        MM = MM < 10 ? ('0' + MM) : MM
+        let d = date.getDate()
+        d = d < 10 ? ('0' + d) : d
+        let h = date.getHours()
+        h = h < 10 ? ('0' + h) : h
+        let m = date.getMinutes()
+        m = m < 10 ? ('0' + m) : m
+        let s = date.getSeconds()
+        s = s < 10 ? ('0' + s) : s
+	    return y + '-' + MM + '-' + d + ' ' + h + ':' + m + ':' + s
+    },
+    regexSets:function() {
+        let sets = {
+            'companyName': /^[\u4e00-\u9fa5\(\)()\s\da-zA-Z&]{2,50}$/gi,
+            'phoneAndTelephone': /^([1]\d{10}|([\((]?0[0-9]{2,3}[)\)]?[-]?)?([2-9][0-9]{6,7})+(\-[0-9]{1,4})?)$/,
+            'bankNum': /^([1-9]{1})(\d{18})$/,
+            'invalidChar': /^[\s\u4e00-\u9fa5a-z0-9_-]{0,}$/
+        }
+        return sets
+    },
+    timestampToTime:function(timestamp) {
+        // 时间戳转日期
+	   let date = new Date(timestamp * 1000)//时间戳为10位需*1000,时间戳为13位的话不需乘1000
+	   let Y = date.getFullYear() + '-'
+	   let M = (date.getMonth()+1 < 10 ? '0'+(date.getMonth()+1) : date.getMonth()+1) + '-'
+	   let D = (date.getDate() < 10 ? '0'+date.getDate() : date.getDate()) + ' '
+	   let h = (date.getHours() < 10 ? '0'+date.getHours() : date.getHours()) + ':'
+	   let m = (date.getMinutes() < 10 ? '0'+date.getMinutes() : date.getMinutes()) + ':'
+	   let s = (date.getSeconds() < 10 ? '0'+date.getSeconds() : date.getSeconds())
+	   return `${Y}${M}${D}${h}${m}${s}`
+    },
+    easyFormatData(timestamp){
+        //时间转换
+        let a = new Date(timestamp).getTime()
+        const date = new Date(a)
+        const Y = date.getFullYear() + '-'
+        const M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-'
+        const D = (date.getDate() < 10 ? '0'+date.getDate() : date.getDate()) + '  '
+        const h = (date.getHours() < 10 ? '0'+date.getHours() : date.getHours()) + ':'
+        const m = (date.getMinutes() <10 ? '0'+date.getMinutes() : date.getMinutes()) 
+        // const s = date.getSeconds(); // 秒
+        const dateString = Y + M + D + h + m
+        // console.log('dateString', dateString); // > dateString 2021-07-06 14:23
+        return dateString
+    }
+}
+
+/**
+ *@导出
+ */ 
+module.exports = {
+    get: caimeiApi.get,
+    post: caimeiApi.post,
+    lodingGet: caimeiApi.lodingGet,
+    isNumber: caimeiApi.isNumber,
+    FormatMoney: caimeiApi.FormatMoney,
+    navigateTo: caimeiApi.navigateTo,
+    reLaunch: caimeiApi.reLaunch,
+    redirectTo: caimeiApi.redirectTo,
+    switchTabTo: caimeiApi.switchTabTo,
+    navigateBack: caimeiApi.navigateBack,
+    formatDate: caimeiApi.formatDate,
+    loginStatus: caimeiApi.loginStatus,
+    setStorage: caimeiApi.setStorage,
+    getStorage: caimeiApi.getStorage,
+    removeStorage: caimeiApi.removeStorage,
+    getComStorage: caimeiApi.getComStorage,
+    navToListPage: caimeiApi.navToListPage,
+    navigateToGoods: caimeiApi.navigateToGoods,
+    getWindowHeight: caimeiApi.getWindowHeight,
+    adaptRichTextImg: caimeiApi.adaptRichTextImg,
+    getStorageAddressKey: caimeiApi.getStorageAddressKey,
+    regexSets: caimeiApi.regexSets,
+    timestampToTime: caimeiApi.timestampToTime,
+    BannerNavigateTo:caimeiApi.BannerNavigateTo,
+    FlooryNavigateTo:caimeiApi.FlooryNavigateTo,
+    easyFormatData:caimeiApi.easyFormatData
+}

+ 210 - 0
common/config/common.js

@@ -0,0 +1,210 @@
+//公共js,主要做表单验证,以及基本方法封装
+const utils = {
+    isNullOrEmpty: function(value) {
+        //是否为空
+        return (value === null || value === '' || value === undefined) ? true : false
+    },
+    trim: function(value) {
+        //去空格
+        return value.replace(/(^\s*)|(\s*$)/g, '')
+    },
+    isEmail: function(value){
+        //是否为邮箱
+		 return RegExp(/^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/).test(value)
+    },
+    isWebsite: function(value){
+        //是否为网址
+        return RegExp(/^((http|ftp|https):\/\/[a-zA-Z0-9]|[a-zA-Z0-9])[-a-zA-Z0-9]{0,62}(.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+.?$/).test(value)
+    },
+    isMobile: function(value) {
+        //是否为手机号
+        return RegExp(/^1[1-9][0-9]{9}$/).test(value)
+    },
+    isIdCard: function(value) {
+        //是否为手机号
+        return RegExp(/^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/).test(value)
+    },
+    isFloat: function(value) {
+        //金额,只允许保留两位小数
+        return RegExp(/^([0-9]*[.]?[0-9])[0-9]{0,1}$/).test(value)
+    },
+    isNum: function(value) {
+        //是否全为数字
+        return RegExp(/^[0-9]+$/).test(value)
+    },
+    isEmailCode:function(value) {
+	    return RegExp(/^\d{4}$/).test(value)
+    },
+    isMobileCode:function(value) {
+	    return RegExp(/^\d{6}$/).test(value)
+    },
+    isCredit:function(value) {//统一社会信用代码
+	    return RegExp(/^[0-9A-HJ-NPQRTUWXY]{2}\\d{6}[0-9A-HJ-NPQRTUWXY]{10}$/).test(value)
+    },
+    checkPwd: function(value) {//密码为8~20位数字和字母组合
+        return RegExp(/^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,16}$/).test(value)
+    },
+    isNoChinese: function(value) {//数字和字母组合
+        return RegExp(/^[A-Za-z0-9]+$/).test(value)
+    },
+    hidePhone:function(value) {
+        return value.replace(/^(\d{3})\d{4}(\d+)/,'$1****$2')
+    },
+    interceptHtmlFn: function(value){
+        return value ? value.replace(/<[^>]+>/g,'') : value
+    },
+    desensitizationName:function(value){
+        if(null != value && value != undefined){
+            if(value.length <= 3){
+                let ruten = value.substring(1)
+                return value.replace(ruten,'**')
+            } else if(value.length > 3 && value.length <= 6){
+                let ruten = value.substring(2)
+                return value.replace(ruten,'**')
+            } 
+        } else {
+            return ''
+        }
+    },
+    formatNum: function(num) {
+        //格式化手机号码
+        if (utils.isMobile(num)) {
+            num = num.replace(/^(\d{3})\d{4}(\d{4})$/, '$1****$2')
+        }
+        return num
+    },
+    rmoney: function(money) {
+        //金额格式化
+        return parseFloat(money).toFixed(2).toString().split('').reverse().join('').replace(/(\d{3})/g, '$1,').replace(
+            /\,$/, '').split('').reverse().join('')
+    },
+    bankRegex:function(num){
+        let bankNum = ''
+        bankNum = num.replace(/\D/g, '').replace(/(....)(?=.)/g, '$1 ')
+        return bankNum
+    },
+    checkData:function(value){
+        let data
+        if(value == null || value ==''){
+            data = ''
+        }else{
+            data = value
+        }
+        return data
+    },
+    formatAccMul:function(value1, value2) {// 修复数额丢失精度
+	    if (value1 == 0 || value2 == 0) {
+	      return 0
+	    }
+	    let m = 0
+	    let v1 = value1.toString()
+	    let v2 = value2.toString()
+	    m += v1.split('.')[1] ? v1.split('.')[1].length : 0
+	    m += v2.split('.')[1] ? v2.split('.')[1].length : 0
+	    let _v1 = Number(v1.replace('.', ''))
+	    let _v2 = Number(v2.replace('.', ''))
+	    return (_v1 * _v2) / Math.pow(10, m)
+    },
+    formatDate: function(formatStr, fdate) {
+        //日期格式化
+        if (fdate) {
+            if (~fdate.indexOf('.')) {
+                fdate = fdate.substring(0, fdate.indexOf('.'))
+            }
+            fdate = fdate.toString().replace('T', ' ').replace(/\-/g, '/')
+            var fTime, fStr = 'ymdhis'
+            if (!formatStr)
+                formatStr = 'y-m-d h:i:s'
+            if (fdate)
+                fTime = new Date(fdate)
+            else
+                fTime = new Date()
+            var month = fTime.getMonth() + 1
+            var day = fTime.getDate()
+            var hours = fTime.getHours()
+            var minu = fTime.getMinutes()
+            var second = fTime.getSeconds()
+            month = month < 10 ? '0' + month : month
+            day = day < 10 ? '0' + day : day
+            hours = hours < 10 ? ('0' + hours) : hours
+            minu = minu < 10 ? '0' + minu : minu
+            second = second < 10 ? '0' + second : second
+            var formatArr = [
+                fTime.getFullYear().toString(),
+                month.toString(),
+                day.toString(),
+                hours.toString(),
+                minu.toString(),
+                second.toString()
+            ]
+            for (var i = 0; i < formatArr.length; i++) {
+                formatStr = formatStr.replace(fStr.charAt(i), formatArr[i])
+            }
+            return formatStr
+        } else {
+            return ''
+        }
+    },
+    throttle: function(fn, gapTime) {
+	  if (gapTime == null || gapTime == undefined) {
+	    gapTime = 1500
+	  }
+	
+	  let _lastTime = null
+	
+	  // 返回新的函数
+	  return function () {
+	    let _nowTime = +new Date()
+	    if (_nowTime - _lastTime > gapTime || !_lastTime) {
+	      fn.apply(this, arguments) //将this和参数传给原函数
+	      _lastTime = _nowTime
+	    }
+	  }
+    },
+	
+    debounce: function(fn, delay, isImmediate) {
+	  var timer = null  //初始化timer,作为计时清除依据
+	  return function() {
+	    var context = this  //获取函数所在作用域this
+	    var args = arguments  //取得传入参数
+	    clearTimeout(timer)
+	    if(isImmediate && timer === null) {
+	        //时间间隔外立即执行
+	        fn.apply(context,args)
+	      timer = 0
+	      return
+	    }
+	    timer = setTimeout(function() {
+	      fn.apply(context,args)
+	      timer = null
+	    }, delay)
+	  }
+    }
+
+}
+
+module.exports = {
+    isNullOrEmpty: utils.isNullOrEmpty,
+    trim: utils.trim,
+    isMobile: utils.isMobile,
+    isEmail: utils.isEmail,
+    isWebsite:utils.isWebsite,
+    isIdCard:utils.isIdCard,
+    isFloat: utils.isFloat,
+    isNum: utils.isNum,
+    isEmailCode:utils.isEmailCode,
+    isMobileCode:utils.isMobileCode,
+    isNoChinese:utils.isNoChinese,
+    checkPwd: utils.checkPwd,
+    formatNum:utils.formatNum,
+    rmoney: utils.rmoney,
+    formatDate: utils.formatDate,
+    formatAccMul: utils.formatAccMul,
+    bankRegex: utils.bankRegex,
+    checkData:utils.checkData,
+    hidePhone:utils.hidePhone,
+    interceptHtmlFn:utils.interceptHtmlFn,
+    desensitizationName:utils.desensitizationName,
+    throttle: utils.throttle,
+    debounce: utils.debounce
+}

+ 60 - 0
common/config/wxLogin.js

@@ -0,0 +1,60 @@
+import store from '@/store/index.js'
+import authorize from '@/common/config/authorize.js'
+import ajaxService from '@/services/ajax.service.js'
+import UserService from '@/services/user.service'
+
+const newUserService = new UserService(ajaxService)
+
+// 根据微信的code获取用户登录状态:1已登录过 -1未登录过
+const wxLoginAuthorize = async function(){
+    const wechatCode = await authorize.getCode('weixin')// 根据微信的code获取用户登录状态:1已登录过 -1未登录过
+    const getUserInfo = await authorize.getUserInfo('weixin')
+    newUserService.UserLoginAuthApplets({ 
+        code:wechatCode,
+        encryptedData:getUserInfo.encryptedData,
+        iv:getUserInfo.iv
+    })
+        .then(response =>{
+            store.commit('updateStatus',response.data)
+            store.commit('login',response.data)
+            uni.setStorageSync('token',response.data.token)
+            uni.setStorageSync('unionId',response.data.unionId)
+        })
+        .catch(error =>{
+            uni.setStorageSync('unionId',error.data.unionId)
+            store.commit('logout',error.data)
+            store.commit('updateStatus',error.data)
+        })
+}
+const wxLoginQuick = async function(){// 根据微信的code获取用户登录状态:1已登录过 -1未登录过跳转
+    const wechatCode = await authorize.getCode('weixin')// 根据微信的code获取用户登录状态:1已登录过 -1未登录过
+    const getUserInfo = await authorize.getUserInfo('weixin')
+    newUserService.UserLoginAuthApplets({ 
+        code:wechatCode,
+        encryptedData:getUserInfo.encryptedData,
+        iv:getUserInfo.iv
+    })
+        .then(response =>{
+            console.log(response)
+            store.commit('updateStatus',response.data)
+            store.commit('login',response.data)
+            uni.setStorageSync('token',response.data.token)
+            uni.setStorageSync('unionId',response.data.unionId)
+            if(response.data.userIdentity ==1){
+                uni.navigateTo({url:'/pages/seller/index/index'})
+            }else if(response.data.userIdentity === 3){
+                uni.navigateTo({url:'/pages/supplier/index/index'})
+            }else{
+                uni.switchTab({url:'/pages/tabBar/user/user'})
+            }
+        })
+        .catch(error =>{
+            uni.setStorageSync('unionId',error.data.unionId)
+            store.commit('logout',error.data)
+            store.commit('updateStatus',error.data)
+        })
+}
+export default{
+    wxLoginAuthorize,
+    wxLoginQuick
+}

+ 0 - 96
common/couponUtils.js

@@ -1,96 +0,0 @@
-/**
- * 取出优惠券列表中的最优优惠券和次优优惠券 
- * */
-
-class CouponUtils {
-    constructor(couponList, productList) {
-        this.couponList = this.couponSort(this.getCanBeUseCouponList(couponList, productList))
-        this.productList = productList
-        this.bestCoupon = null
-        this.secondCoupon = null
-        this.currentIndex = this.couponList.length
-        this.fetchBestCoupon()
-    }
-
-    // 获取最高可用金额的优惠券
-    fetchBestCoupon() {
-        if (this.couponList.length === 0 || this.productList.length === 0) {
-            this.bestCoupon = null
-            return
-        }
-        this.bestCoupon = this.couponList.find(coupon => this.couponCanBeUse(coupon, this.productList)) || null
-        if (this.bestCoupon) {
-            this.currentIndex = this.couponList.findIndex(coupon => coupon.uniqueId === this.bestCoupon.uniqueId)
-        }
-        this.fetchSecondCoupon()
-    }
-
-    // 获取下一阶段可用优惠券
-    fetchSecondCoupon() {
-        if (this.couponList.length === 0 || this.productList.length === 0) {
-            this.secondCoupon = null
-            return
-        }
-        this.secondCoupon = this.currentIndex > 0 ? this.couponList[this.currentIndex - 1] : null
-    }
-
-    // 勾选商品满足优惠券使用条件 && 满足使用条件
-    couponCanBeUse(coupon, productList) {
-        return (
-            this.isNoThreshold(coupon) ||
-            this.isSomeProductUse(coupon, productList) ||
-            this.isAllProductUse(coupon, productList)
-        )
-    }
-
-    // 获取当前选中商品都能使用的优惠券
-    getCanBeUseCouponList(couponList, productList) {
-        return couponList.filter(coupon => coupon.productType === 1 || this.isCanUseByAllProduct(coupon,
-            productList))
-    }
-
-    // 全部商品可用
-    isCanUseByAllProduct(coupon, productList) {
-        return productList.every(product => coupon.productIds.indexOf(product.productId.toString()) > -1)
-    }
-
-    // 优惠券是否无门槛
-    isNoThreshold(coupon) {
-        return coupon.noThresholdFlag === 1
-    }
-
-    // 全部商品可用 && 满足使用条件
-    isAllProductUse(coupon, productList) {
-        if (coupon.productType !== 1) {
-            return false
-        }
-        const countPrice = productList.reduce((countPrice, product) => {
-            return countPrice + this.totalProductPrice(product)
-        }, 0)
-        return countPrice >= coupon.touchPrice
-    }
-
-    // 部分商品可用 && 满足使用条件
-    isSomeProductUse(coupon, productList) {
-        if (coupon.productType !== 2) {
-            return false
-        }
-        const countPrice = productList.reduce((countPrice, product) => {
-            const isIncludes = coupon.productIds.indexOf(product.productId.toString()) > -1
-            return isIncludes ? countPrice + this.totalProductPrice(product) : countPrice
-        }, 0)
-        return countPrice >= coupon.touchPrice
-    }
-
-    // 统计商品价格
-    totalProductPrice(product) {
-        return product.price * product.num
-    }
-
-    // 排序
-    couponSort(couponList) {
-        return couponList.sort((a, b) => b.couponAmount - a.couponAmount)
-    }
-}
-
-export default CouponUtils

+ 0 - 26
common/crypto.js

@@ -1,26 +0,0 @@
-import CryptoJS from './libs/crypto-js.min.js'
-
-const aseKey = 'HEHEMINI' //秘钥必须为:8/16/32位
-//加密
-export const encrypt = data => {
-    return CryptoJS.AES.encrypt(JSON.stringify(data), CryptoJS.enc.Utf8.parse(aseKey), {
-        mode: CryptoJS.mode.ECB,
-        padding: CryptoJS.pad.Pkcs7
-    }).toString()
-}
-//解密
-export const decrypt = encrypt => {
-    return CryptoJS.AES.decrypt(encrypt, CryptoJS.enc.Utf8.parse(aseKey), {
-        mode: CryptoJS.mode.ECB,
-        padding: CryptoJS.pad.Pkcs7
-    }).toString(CryptoJS.enc.Utf8)
-}
-
-const install = Vue => {
-    Vue.prototype.$crypto = {
-        encrypt,
-        decrypt
-    }
-}
-
-export default install

+ 410 - 0
common/css/common.scss

@@ -0,0 +1,410 @@
+.clearfix:after {
+  content: ".";
+  display: block;
+  height: 0;
+  clear: both;
+  visibility: hidden;
+}
+.container{
+	width: 100%;
+	height: 100%;
+}
+/*android一像素兼容*/
+::-webkit-scrollbar{
+	width: 0;
+	height: 0;
+	color: transparent;
+	display:none;
+}
+button {
+	display: block;
+	margin-left: auto;
+	margin-right: auto;
+	padding-left: 0;
+	padding-right: 0;
+	box-sizing: border-box;
+	font-size: $font-size-28;
+	text-align: center;
+	text-decoration: none;
+	line-height: 36rpx;
+	border-radius: 0;
+	-webkit-tap-highlight-color: transparent;
+	overflow: hidden;
+	color: $text-color;
+	background-color: #FFFFFF;
+}
+
+button::after{
+    border: none;
+    border-radius:  0;
+}
+/*输入框样式*/ 
+.text-input{
+	display: flex;
+	align-items: center;
+	position: relative;
+	width: 654rpx;
+	height: 40rpx;
+	padding: 24rpx;
+	margin: 0 auto;
+	background: #F7F7F7;
+	.input{
+		width: 100%;
+		height: 100%;
+		background: #F7F7F7;
+		font-size: $font-size-28;
+		line-height: 40rpx;
+		color: #333333;
+	}
+	&.b-b{
+		margin: 32rpx 0;
+	}
+}
+/*空列表显示样式*/ 
+.empty-container {
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	flex-direction: column;
+	position: fixed;
+	left: 0;
+	top: 0;
+	right: 0;
+	bottom: 0;
+	background: $bg-color;
+	// padding-bottom: 120rpx;
+	border-top: 1px solid #EBEBEB;
+	.club-empty-image{
+		width: 300rpx;
+		height: 180rpx;
+		margin-bottom: 20rpx;
+	}
+	&-image {
+		width: 332rpx;
+		height: 260rpx;
+		margin-bottom: 10rpx;
+		margin-top: -120rpx;
+	}
+	.error-text{
+		font-size: $font-size-28;
+		color: #999999;
+		line-height: 88rpx;
+	}
+	.txt{
+		font-size: $font-size-28;
+		color: #999999;
+		line-height: 44rpx;
+	}
+	.login-btn{
+		width: 600rpx;
+		height: 88rpx;
+		font-size: $font-size-28;
+		line-height: 88rpx;
+		color: #FFFFFF;
+		margin: 0 auto;
+		text-align: center;
+		background: $btn-confirm;
+		border-radius: 44rpx;
+		margin-top: 40rpx;
+	}
+}
+/*弹窗*/
+ .model-warp.none{
+	 display: none;
+ }
+ .model-warp.show{
+	 display: block;
+ }
+ .model-warp{
+	width: 100%;
+	height: 100%;
+	background: rgba(0,0,0,.5);
+	position: fixed;
+	top: 0;
+	left: 0;
+	z-index: 8888;
+	transition: all 0.4s;
+	&.none{
+		display: none;			
+	}
+	&.show{
+		display: block;
+	}
+	.model-alert{
+		width: 518rpx;
+		height: 280rpx;
+		position: absolute;
+		background: $bg-color;
+		left: 0;
+		right: 0;
+		bottom: 0;
+		top: 0;
+		margin: auto;
+		border-radius: 20rpx;
+		.alert-content{
+			width: 466rpx;
+			height: 100rpx;
+			padding: 40rpx 26rpx;
+			.t-h1,.t-p{
+				font-size: $font-size-28;
+				line-height: 40rpx;
+				color: #333333;
+				text-align:justify;
+				padding: 10rpx;
+			}
+			.t-h1{
+				border-bottom: 1px solid $border-color;
+			}
+		}
+		.model-content{
+			width: 466rpx;
+			height: 152rpx;
+			padding: 40rpx 26rpx;	
+			display: flex;
+			flex-direction: column;
+			align-items: center;
+			.sm{
+				display: flex;
+				flex: 1;
+				line-height: 152rpx;
+				flex-direction: column;
+				align-items: center;
+				text-align: center;
+				font-size: $font-size-28;
+				color: #333333;
+			}
+		}
+		.alert-btn{
+			width: 80%;
+			height: 70rpx;
+			display: flex;
+			margin: 0 auto;
+			.btn{
+				flex: 1;
+				line-height: 70rpx;
+				font-size: $font-size-28;
+				text-align: center;
+				color: #FFFFFF;
+				border-radius: 10rpx;
+				padding: 0;
+				margin: 0 15rpx;
+				&.btn-cancel{
+					background: $btn-cancel;
+				}
+				&.btn-confirm{
+					background: $btn-confirm;
+				}
+			}
+		}
+	}
+}
+/*
+ *上滑加载更多
+ */ 
+.load-more {
+    font-size: $font-size-24;
+    color: #666;
+    text-align: center;
+    width: 100%;
+}
+/*底部loading*/
+.loading-wrapper {
+	width: 100%;
+	height: 60rpx;
+	padding: 25rpx 0;
+	color: #333;
+	font-size: 24rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+}
+.loading-wrapper-now text {
+	margin-left: 6rpx;
+	font-weight: bold;
+}
+.loading-wrapper-btm {
+	color: #eee;
+	.btm-text {
+		color: #333;
+		padding: 0 10rpx;
+	}
+}
+.form-item {
+	display: flex;
+	color: $text-color;
+	margin-top: 74rpx;
+	font-size: 26rpx;
+	.asterisk {
+		color: #FF2A2A;
+		margin-right: 10rpx;
+	}
+}
+
+// 表单提交button
+.submit-btn {
+	position: fixed;
+	left: 24rpx;
+	right: 24rpx;
+	bottom: 34rpx;
+	z-index: 95;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	width: 702rpx;
+	height: 88rpx;
+	font-size: $font-size-28;
+	line-height: 88rpx;
+	color: #FFFFFF;
+	text-align: center;
+	background: $btn-confirm;
+	border-radius: 44rpx;
+}
+// 小红点
+.uni-badge--small {
+	-webkit-transform: scale(.8);
+	-ms-transform: scale(.8);
+	transform: scale(.8);
+	-webkit-transform-origin: center center;
+	-ms-transform-origin: center center;
+	transform-origin: center center;
+}
+.uni-badge {
+	font-family: 'Helvetica Neue', Helvetica, sans-serif;
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+	font-size: 12px;
+	line-height: 1;
+	display: inline-block;
+	padding: 3px 6px;
+	color: #333;
+	border-radius: 100px;
+	background-color: #f1f1f1;
+}
+.uni-badge-error {
+	color: #fff;
+	background-color: #dd524d;
+}
+/* 加入购物模态层*/
+	@keyframes showPopup {
+		0% {
+			opacity: 0;
+		}
+		100% {
+			opacity: 1;
+		}
+	}
+	@keyframes hidePopup {
+		0% {
+			opacity: 1;
+		}
+		100% {
+			opacity: 0;
+		}
+	}
+	@keyframes showLayer {
+		0% {
+			transform: translateY(0);
+		}
+		100% {
+			transform: translateY(-100%);
+		}
+	}
+	@keyframes hideLayer {
+		0% {
+			transform: translateY(-100%);
+		}
+		100% {
+			transform: translateY(0);
+		}
+	}
+	@keyframes showAmnation {
+		0% {
+			top: -12rpx;
+			opacity: 0;
+		}
+		50% {
+			top: -60rpx;
+			opacity: 1;
+		}
+		100% {
+			top: -100rpx;
+			opacity: 0;
+		}
+	}
+	@keyframes hideAmnation {
+		0% {
+			top: -100rpx;
+			opacity: 0;
+		}
+		100% {
+			top: -12rpx;
+			opacity: 0;
+		}
+	}
+/* 优惠券标签样式*/
+.coupon-tags {
+	height: 32rpx;
+	box-sizing: border-box;
+	border-radius: 8rpx;
+	background-color: #fff1eb;
+	line-height: 28rpx;
+	color: #f94b4b;
+	text-align: center;
+	display: inline-block;
+	padding: 0 4rpx;
+	font-size:18rpx;
+	border: 1px solid #f94b4b;
+	float: left;
+	margin-right: 10rpx;
+}
+/* 促销标签样式*/
+.floor-tags{
+	height: 32rpx;
+	box-sizing: border-box;
+	border-radius: 8rpx;
+	background-color: #FFFFFF;
+	line-height: 28rpx;
+	color: $color-system;
+	text-align: center;
+	display: inline-block;
+	padding:0 4rpx;
+	font-size: 18rpx !important;
+	border: 1px solid #F3B574;
+	float: left;
+	margin-right: 8rpx;
+}
+/* 会员标签样式*/
+.svip-tags{
+	padding-left: 44rpx;
+	height: 32rpx;
+	position: relative;
+	float: left;
+	.tags{
+		width: 60rpx;
+		height: 32rpx;
+		background-color: #333333;
+		text-align: center;
+		line-height: 32rpx;
+		font-size: 20rpx;
+		color: #F0CB72;
+		position: absolute;
+		left: 0;
+		top: 0;
+		border-radius: 8rpx 16rpx 0 8rpx;
+		&.none{
+			border-radius: 8rpx;
+		}
+	}
+	.price{
+		height: 32rpx;
+		box-sizing: border-box;
+		border-radius:0 8rpx 8rpx 0;
+		background-color: #F0CB72;
+		line-height: 32rpx !important;
+		color: #333333 !important;
+		text-align: center;
+		padding:0 9rpx 0 22rpx;
+		font-size: 20rpx;
+		float: left;
+	}
+}

+ 0 - 137
common/css/global.scss

@@ -1,137 +0,0 @@
-/* 文字缩略 $line: 保留几行文章 */
-@mixin ellipsis($line: 1) {
-    overflow: hidden;
-    text-overflow: ellipsis;
-    display: -webkit-box;
-    -webkit-line-clamp: $line;
-    -webkit-box-orient: vertical;
-}
-
-// page {
-//     -webkit-filter: grayscale(100%);
-//     -moz-filter: grayscale(100%);
-//     -o-filter: grayscale(100%);
-//     filter: grayscale(100%);
-//     filter: progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);
-// }
-// flex布局
-.cm-flex-center {
-    display: flex;
-    justify-content: center;
-
-    align-items: center;
-}
-.cm-flex-between {
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-}
-.cm-flex-around {
-    display: flex;
-    justify-content: space-around;
-    align-items: center;
-}
-// 标签
-.tags {
-    .tag {
-        display: inline-block;
-        margin-right: 8rpx;
-        height: 30rpx;
-        text-align: center;
-        line-height: 30rpx;
-        font-size: 18rpx;
-        padding: 0 4rpx;
-        vertical-align: middle;
-        &.cx {
-            // 促销 自营标签
-            background: #f83c6c;
-            border-radius: 4rpx;
-            color: #ffffff;
-        }
-        &.hd {
-            // 活动价标签
-            width: 80rpx;
-            box-sizing: border-box;
-            padding: 0;
-            background: url(https://static.caimei365.com/app/mini-hehe/icon/icon-active.png) top center no-repeat;
-            background-size: 80rpx 30rpx;
-            color: #f83c6c;
-        }
-        &.pt {
-            // 拼团价标签
-            background: linear-gradient(270deg, #ff457b 0%, #b03bb8 51%, #6431f2 100%);
-            color: #fff;
-            border-radius: 4rpx;
-        }
-        &.other {
-            // 其他标签
-            border: 1rpx solid #f83c6c;
-            height: 28rpx;
-            line-height: 28rpx;
-            color: #f83c6c;
-            border-radius: 4rpx;
-            max-width: 100%;
-            white-space: nowrap;
-            overflow: hidden;
-            text-overflow: ellipsis;
-        }
-    }
-}
-// 图标默认颜色
-.icon {
-    font-size: 36rpx;
-    color: #b2b2b2;
-    &.icon-xuanze {
-        color: #f83c6c;
-    }
-}
-// 列表为空的提示语样式
-.empty-tip {
-    font-size: 24rpx;
-    line-height: 1.6;
-    color: #999;
-}
-.placeholder {
-    font-size: 28rpx;
-    color: #999999;
-}
-.hover-class {
-    background-color: #eee !important;
-}
-// thorui 样式
-.tui-nodata-fixed {
-    transform: translate(-50%, -70%) !important;
-}
-.tui-divider {
-    .tui-divider-line {
-        background: #d4d4d4 !important;
-    }
-}
-// 定位
-.fixed-top {
-    position: fixed;
-    z-index: 90;
-    width: 100%;
-    left: 0;
-    top: 0;
-}
-.fixed-bottom {
-    position: fixed;
-    z-index: 90;
-    width: 100%;
-    left: 0;
-    bottom: 0;
-}
-.sticky-top {
-    position: sticky;
-    z-index: 90;
-    width: 100%;
-    left: 0;
-    top: 0;
-}
-// 清除浮动
-.clearfix::after {
-    content: '';
-    display: block;
-    clear: both;
-}

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 6
common/css/icon.css


+ 143 - 0
common/css/iconfont.scss

@@ -0,0 +1,143 @@
+@font-face {
+  font-family: "iconfont"; /* Project id 4053045 */
+  src: url('//at.alicdn.com/t/c/font_4053045_ww8z5uih1ve.woff2?t=1683552153840') format('woff2'),
+       url('//at.alicdn.com/t/c/font_4053045_ww8z5uih1ve.woff?t=1683552153840') format('woff'),
+       url('//at.alicdn.com/t/c/font_4053045_ww8z5uih1ve.ttf?t=1683552153840') format('truetype'),
+       url('//at.alicdn.com/t/c/font_4053045_ww8z5uih1ve.svg?t=1683552153840#iconfont') format('svg');
+}
+
+.iconfont {
+  font-family: "iconfont" !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-zhiding:before {
+  content: "\e6a5";
+}
+
+.icon-dui:before {
+  content: "\e616";
+}
+
+.icon-fenxiang1:before {
+  content: "\e6a2";
+}
+
+.icon-shouye:before {
+  content: "\e638";
+}
+
+.icon-jiahao:before {
+  content: "\eaf3";
+}
+
+.icon-jianhao:before {
+  content: "\eaf5";
+}
+
+.icon-hr:before {
+  content: "\e60a";
+}
+
+.icon-1_round_solid:before {
+  content: "\e64e";
+}
+
+.icon-2_round_solid:before {
+  content: "\e64f";
+}
+
+.icon-jigou:before {
+  content: "\e759";
+}
+
+.icon-dizhi:before {
+  content: "\e75a";
+}
+
+.icon-shezhi:before {
+  content: "\e75b";
+}
+
+.icon-shoucang:before {
+  content: "\e75c";
+}
+
+.icon-kefu:before {
+  content: "\e75d";
+}
+
+.icon-shouhuodizhi:before {
+  content: "\e758";
+}
+
+.icon-anniu_guanbi:before {
+  content: "\e756";
+}
+
+.icon-anniu_kaiqi:before {
+  content: "\e757";
+}
+
+.icon-xuanzhong:before {
+  content: "\e752";
+}
+
+.icon-bianji:before {
+  content: "\e753";
+}
+
+.icon-a-shanchu:before {
+  content: "\e754";
+}
+
+.icon-tishi:before {
+  content: "\e755";
+}
+
+.icon-weixuanze:before {
+  content: "\e750";
+}
+
+.icon-yixuanze:before {
+  content: "\e751";
+}
+
+.icon-shangchuantupian:before {
+  content: "\e74e";
+}
+
+.icon-shanchu:before {
+  content: "\e74f";
+}
+
+.icon-guanbi:before {
+  content: "\e74d";
+}
+
+.icon-fenxiang:before {
+  content: "\e74c";
+}
+
+.icon-xiangyou:before {
+  content: "\e74a";
+}
+
+.icon-fanhui:before {
+  content: "\e74b";
+}
+
+.icon-mima:before {
+  content: "\e747";
+}
+
+.icon-duanxin:before {
+  content: "\e748";
+}
+
+.icon-shoujihao:before {
+  content: "\e749";
+}

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 2 - 0
common/css/style/icon.css


+ 2480 - 0
common/css/style/thorui.css

@@ -0,0 +1,2480 @@
+/* Thor UI 基础组件 样式*/
+
+/*!
+ * =====================================================
+ * Thor UI v1.5.0 (https://www.thorui.cn/)
+ * =====================================================
+ */
+.tui-mask {
+	width: 100%;
+	height: 100%;
+	position: fixed;
+	top: 0;
+	left: 0;
+	background: rgba(0, 0, 0, 0.4);
+	z-index: 999;
+}
+
+.tui-ellipsis {
+	overflow: hidden;
+	white-space: nowrap;
+	text-overflow: ellipsis;
+}
+
+.tui-ellipsis-2 {
+	display: -webkit-box;
+	overflow: hidden;
+	white-space: normal !important;
+	text-overflow: ellipsis;
+	word-wrap: break-word;
+	-webkit-line-clamp: 2;
+	-webkit-box-orient: vertical;
+}
+
+.tui-opcity {
+	opacity: 0.5;
+}
+
+.tui-scale-small {
+	transform: scale(0.9);
+	transform-origin: center center;
+}
+
+.tui-height-full {
+	height: 100%;
+}
+
+.tui-width-full {
+	width: 100%;
+}
+
+.tui-ptop-zero {
+	padding-top: 0;
+}
+
+.tui-pbottom-zero {
+	padding-bottom: 0;
+}
+
+.tui-pleft-zero {
+	padding-left: 0;
+}
+
+.tui-pright-zero {
+	padding-right: 0;
+}
+
+
+/* color start*/
+
+.tui-color-primary {
+	color: #5677fc;
+}
+
+.tui-color-success {
+	color: #19be6b;
+}
+
+.tui-color-warning {
+	color: #ff7900;
+}
+
+.tui-color-error {
+	color: #EB0909;
+}
+
+.tui-color-blue {
+	color: #007AFF;
+}
+
+.tui-color-blue {
+	color: #007AFF;
+}
+
+.tui-color-white {
+	color: #ffffff;
+}
+
+.tui-color-pink {
+	color: #f74d54;
+}
+
+.tui-primary {
+	background-color: #5677fc !important;
+	color: #fff;
+}
+
+.tui-light-primary {
+	background-color: #5c8dff !important;
+	color: #fff;
+}
+
+.tui-dark-primary {
+	background-color: #4a67d6 !important;
+	color: #fff;
+}
+
+.tui-dLight-primary {
+	background-color: #4e77d9 !important;
+	color: #fff;
+}
+
+.tui-danger {
+	background-color: #ed3f14 !important;
+	color: #fff;
+}
+
+.tui-warning {
+	background-color: #ff7900 !important;
+	color: #fff;
+}
+
+.tui-blue {
+	background-color: #007AFF !important;
+	color: #fff;
+}
+
+.tui-green {
+	background-color: #19be6b !important;
+	color: #fff;
+}
+
+.tui-black {
+	background-color: #000 !important;
+	color: #fff;
+}
+
+.tui-white {
+	background-color: #fff !important;
+	color: #333 !important;
+}
+
+.tui-translucent {
+	background-color: rgba(0, 0, 0, 0.7);
+}
+
+.tui-light-black {
+	background-color: #333 !important;
+}
+
+.tui-gray {
+	background-color: #80848f;
+}
+
+.tui-phcolor-gray {
+	background-color: #ccc !important;
+}
+
+.tui-divider-gray {
+	background-color: #eaeef1 !important;
+}
+
+.tui-btn-gray {
+	background-color: #ededed !important;
+	color: #999 !important;
+}
+
+.tui-hover-gray {
+	background-color: #f7f7f9 !important;
+}
+
+.tui-bg-gray {
+	background-color: #fafafa !important;
+}
+
+.tui-light-blue {
+	background-color: #ecf6fd;
+	color: #4dabeb !important;
+}
+
+.tui-light-brownish {
+	background-color: #fcebef;
+	color: #8a5966 !important;
+}
+
+.tui-light-orange {
+	background-color: #fef5eb;
+	color: #faa851 !important;
+}
+
+.tui-light-green {
+	background-color: #e8f6e8;
+	color: #44cf85 !important;
+}
+
+/* color end*/
+
+
+/* flex start */
+
+.tui-flex {
+	display: -webkit-flex;
+	display: flex;
+}
+
+.tui-flex-1 {
+	flex: 1;
+}
+
+.tui-align-center {
+	justify-content: center;
+}
+
+.tui-align-left {
+	justify-content: flex-start !important;
+}
+
+.tui-align-right {
+	justify-content: flex-end !important;
+}
+
+.tui-align-between {
+	justify-content: space-between !important;
+}
+
+.tui-align-around {
+	justify-content: space-around !important;
+}
+
+.tui-vertical-center {
+	align-items: center;
+}
+
+.tui-vertical-top {
+	align-items: flex-start;
+}
+
+.tui-vertical-top {
+	align-items: flex-end;
+}
+
+.tui-center {
+	display: flex;
+	align-items: center;
+	justify-content: center;
+}
+
+.tui-line-feed {
+	flex-direction: row;
+	flex-wrap: wrap;
+}
+
+.tui-col-12 {
+	width: 100%;
+}
+
+.tui-col-11 {
+	width: 91.66666667%;
+}
+
+.tui-col-10 {
+	width: 83.33333333%;
+}
+
+.tui-col-9 {
+	width: 75%;
+}
+
+.tui-col-8 {
+	width: 66.66666667%;
+}
+
+.tui-col-7 {
+	width: 58.33333333%;
+}
+
+.tui-col-6 {
+	width: 50%;
+}
+
+.tui-col-5 {
+	width: 41.66666667%;
+}
+
+.tui-col-4 {
+	width: 33.33333333%;
+}
+
+.tui-col-3 {
+	width: 25%;
+}
+
+.tui-col-2 {
+	width: 16.66666667%;
+}
+
+.tui-col-1 {
+	width: 8.33333333%;
+}
+
+/* flex end */
+
+
+/* icon start */
+.tui-icon {
+	font-family: 'thoruiFont' !important;
+	font-style: normal;
+	-webkit-font-smoothing: antialiased;
+	text-align: center;
+	text-decoration: none;
+	font-size: 32px;
+	color: #999;
+}
+
+.tui-icon-about:before {
+	content: '\e772';
+}
+
+.tui-icon-about-fill:before {
+	content: '\e771';
+}
+
+.tui-icon-add:before {
+	content: '\e770';
+}
+
+.tui-icon-add-fill:before {
+	content: '\e76f';
+}
+
+.tui-icon-addmessage:before {
+	content: '\e76e';
+}
+
+.tui-icon-addressbook:before {
+	content: '\e76d';
+}
+
+.tui-icon-agree:before {
+	content: '\e76c';
+}
+
+.tui-icon-agree-fill:before {
+	content: '\e76b';
+}
+
+.tui-icon-alarm:before {
+	content: '\e76a';
+}
+
+.tui-icon-alarm-fill:before {
+	content: '\e769';
+}
+
+.tui-icon-alipay:before {
+	content: '\e768';
+}
+
+.tui-icon-android:before {
+	content: '\e767';
+}
+
+.tui-icon-applets:before {
+	content: '\e766';
+}
+
+.tui-icon-arrowdown:before {
+	content: '\e765';
+}
+
+.tui-icon-arrowleft:before {
+	content: '\e764';
+}
+
+.tui-icon-arrowright:before {
+	content: '\e763';
+}
+
+.tui-icon-arrowup:before {
+	content: '\e762';
+}
+
+.tui-icon-attestation:before {
+	content: '\e761';
+}
+
+.tui-icon-back:before {
+	content: '\e760';
+}
+
+.tui-icon-bag:before {
+	content: '\e75f';
+}
+
+.tui-icon-bag-fill:before {
+	content: '\e75e';
+}
+
+.tui-icon-balloon:before {
+	content: '\e75d';
+}
+
+.tui-icon-bankcard:before {
+	content: '\e75c';
+}
+
+.tui-icon-bankcard-fill:before {
+	content: '\e75b';
+}
+
+.tui-icon-bottom:before {
+	content: '\e75a';
+}
+
+.tui-icon-calendar:before {
+	content: '\e759';
+}
+
+.tui-icon-camera:before {
+	content: '\e758';
+}
+
+.tui-icon-camera-fill:before {
+	content: '\e757';
+}
+
+.tui-icon-camera-add:before {
+	content: '\e756';
+}
+
+.tui-icon-card:before {
+	content: '\e755';
+}
+
+.tui-icon-card-fill:before {
+	content: '\e754';
+}
+
+.tui-icon-cart:before {
+	content: '\e753';
+}
+
+.tui-icon-cart-fill:before {
+	content: '\e752';
+}
+
+.tui-icon-category:before {
+	content: '\e751';
+}
+
+.tui-icon-category-fill:before {
+	content: '\e750';
+}
+
+.tui-icon-check:before {
+	content: '\e74f';
+}
+
+.tui-icon-circle:before {
+	content: '\e74e';
+}
+
+.tui-icon-circle-fill:before {
+	content: '\e74d';
+}
+
+.tui-icon-circle-selected:before {
+	content: '\e74c';
+}
+
+.tui-icon-clock:before {
+	content: '\e74b';
+}
+
+.tui-icon-clock-fill:before {
+	content: '\e74a';
+}
+
+.tui-icon-close:before {
+	content: '\e749';
+}
+
+.tui-icon-close-fill:before {
+	content: '\e748';
+}
+
+.tui-icon-community:before {
+	content: '\e747';
+}
+
+.tui-icon-community-fill:before {
+	content: '\e746';
+}
+
+.tui-icon-computer:before {
+	content: '\e745';
+}
+
+.tui-icon-computer-fill:before {
+	content: '\e744';
+}
+
+.tui-icon-coupon:before {
+	content: '\e743';
+}
+
+.tui-icon-delete:before {
+	content: '\e742';
+}
+
+.tui-icon-deletekey:before {
+	content: '\e741';
+}
+
+.tui-icon-dingtalk:before {
+	content: '\e740';
+}
+
+.tui-icon-dissatisfied:before {
+	content: '\e73f';
+}
+
+.tui-icon-down:before {
+	content: '\e73e';
+}
+
+.tui-icon-download:before {
+	content: '\e73d';
+}
+
+.tui-icon-edit:before {
+	content: '\e73c';
+}
+
+.tui-icon-ellipsis:before {
+	content: '\e73b';
+}
+
+.tui-icon-enlarge:before {
+	content: '\e73a';
+}
+
+.tui-icon-evaluate:before {
+	content: '\e739';
+}
+
+.tui-icon-exchange:before {
+	content: '\e738';
+}
+
+.tui-icon-explain:before {
+	content: '\e737';
+}
+
+.tui-icon-explain-fill:before {
+	content: '\e736';
+}
+
+.tui-icon-explore:before {
+	content: '\e735';
+}
+
+.tui-icon-explore-fill:before {
+	content: '\e734';
+}
+
+.tui-icon-eye:before {
+	content: '\e733';
+}
+
+.tui-icon-feedback:before {
+	content: '\e732';
+}
+
+.tui-icon-fingerprint:before {
+	content: '\e730';
+}
+
+.tui-icon-friendadd:before {
+	content: '\e72f';
+}
+
+.tui-icon-friendadd-fill:before {
+	content: '\e72e';
+}
+
+.tui-icon-gps:before {
+	content: '\e72d';
+}
+
+.tui-icon-histogram:before {
+	content: '\e72c';
+}
+
+.tui-icon-home:before {
+	content: '\e72b';
+}
+
+.tui-icon-home-fill:before {
+	content: '\e72a';
+}
+
+.tui-icon-house:before {
+	content: '\e729';
+}
+
+.tui-icon-imface:before {
+	content: '\e728';
+}
+
+.tui-icon-imkeyboard:before {
+	content: '\e727';
+}
+
+.tui-icon-immore:before {
+	content: '\e726';
+}
+
+.tui-icon-imvoice:before {
+	content: '\e725';
+}
+
+.tui-icon-ios:before {
+	content: '\e724';
+}
+
+.tui-icon-kefu:before {
+	content: '\e723';
+}
+
+.tui-icon-label:before {
+	content: '\e722';
+}
+
+.tui-icon-label-fill:before {
+	content: '\e721';
+}
+
+.tui-icon-like:before {
+	content: '\e720';
+}
+
+.tui-icon-like-fill:before {
+	content: '\e71f';
+}
+
+.tui-icon-link:before {
+	content: '\e71e';
+}
+
+.tui-icon-listview:before {
+	content: '\e71d';
+}
+
+.tui-icon-loading:before {
+	content: '\e71c';
+}
+
+.tui-icon-location:before {
+	content: '\e71b';
+}
+
+.tui-icon-mail:before {
+	content: '\e71a';
+}
+
+.tui-icon-mail-fill:before {
+	content: '\e719';
+}
+
+.tui-icon-manage:before {
+	content: '\e718';
+}
+
+.tui-icon-manage-fill:before {
+	content: '\e717';
+}
+
+.tui-icon-member:before {
+	content: '\e716';
+}
+
+.tui-icon-member-fill:before {
+	content: '\e715';
+}
+
+.tui-icon-message:before {
+	content: '\e714';
+}
+
+.tui-icon-message-fill:before {
+	content: '\e713';
+}
+
+.tui-icon-mobile:before {
+	content: '\e712';
+}
+
+.tui-icon-moments:before {
+	content: '\e711';
+}
+
+.tui-icon-more:before {
+	content: '\e710';
+}
+
+.tui-icon-more-fill:before {
+	content: '\e70f';
+}
+
+.tui-icon-narrow:before {
+	content: '\e70e';
+}
+
+.tui-icon-news:before {
+	content: '\e70d';
+}
+
+.tui-icon-news-fill:before {
+	content: '\e70c';
+}
+
+.tui-icon-nodata:before {
+	content: '\e70b';
+}
+
+.tui-icon-notice:before {
+	content: '\e699';
+}
+
+.tui-icon-notice-fill:before {
+	content: '\e698';
+}
+
+.tui-icon-offline:before {
+	content: '\e697';
+}
+
+.tui-icon-offline-fill:before {
+	content: '\e696';
+}
+
+.tui-icon-oppose:before {
+	content: '\e695';
+}
+
+.tui-icon-oppose-fill:before {
+	content: '\e694';
+}
+
+.tui-icon-order:before {
+	content: '\e693';
+}
+
+.tui-icon-partake:before {
+	content: '\e692';
+}
+
+.tui-icon-people:before {
+	content: '\e691';
+}
+
+.tui-icon-people-fill:before {
+	content: '\e690';
+}
+
+.tui-icon-pic:before {
+	content: '\e68f';
+}
+
+.tui-icon-pic-fill:before {
+	content: '\e68e';
+}
+
+.tui-icon-picture:before {
+	content: '\e68d';
+}
+
+.tui-icon-pie:before {
+	content: '\e68c';
+}
+
+.tui-icon-play:before {
+	content: '\e68b';
+}
+
+.tui-icon-plus:before {
+	content: '\e689';
+}
+
+.tui-icon-polygonal:before {
+	content: '\e688';
+}
+
+.tui-icon-position:before {
+	content: '\e687';
+}
+
+.tui-icon-position-fill:before {
+	content: '\e686';
+}
+
+.tui-icon-pwd:before {
+	content: '\e685';
+}
+
+.tui-icon-qq:before {
+	content: '\e684';
+}
+
+.tui-icon-qrcode:before {
+	content: '\e682';
+}
+
+.tui-icon-redpacket:before {
+	content: '\e681';
+}
+
+.tui-icon-redpacket-fill:before {
+	content: '\e680';
+}
+
+.tui-icon-reduce:before {
+	content: '\e67f';
+}
+
+.tui-icon-refresh:before {
+	content: '\e67e';
+}
+
+.tui-icon-revoke:before {
+	content: '\e67d';
+}
+
+.tui-icon-satisfied:before {
+	content: '\e67c';
+}
+
+.tui-icon-screen:before {
+	content: '\e67b';
+}
+
+.tui-icon-search:before {
+	content: '\e67a';
+}
+
+.tui-icon-search-2:before {
+	content: '\e679';
+}
+
+.tui-icon-send:before {
+	content: '\e678';
+}
+
+.tui-icon-service:before {
+	content: '\e677';
+}
+
+.tui-icon-service-fill:before {
+	content: '\e676';
+}
+
+.tui-icon-setup:before {
+	content: '\e675';
+}
+
+.tui-icon-setup-fill:before {
+	content: '\e674';
+}
+
+.tui-icon-share:before {
+	content: '\e673';
+}
+
+.tui-icon-share-fill:before {
+	content: '\e672';
+}
+
+.tui-icon-shield:before {
+	content: '\e671';
+}
+
+.tui-icon-shop:before {
+	content: '\e670';
+}
+
+.tui-icon-shop-fill:before {
+	content: '\e66f';
+}
+
+.tui-icon-shut:before {
+	content: '\e66e';
+}
+
+.tui-icon-signin:before {
+	content: '\e66d';
+}
+
+.tui-icon-sina:before {
+	content: '\e66c';
+}
+
+.tui-icon-skin:before {
+	content: '\e66b';
+}
+
+.tui-icon-soso:before {
+	content: '\e669';
+}
+
+.tui-icon-square:before {
+	content: '\e668';
+}
+
+.tui-icon-square-fill:before {
+	content: '\e667';
+}
+
+.tui-icon-square-selected:before {
+	content: '\e666';
+}
+
+.tui-icon-star:before {
+	content: '\e665';
+}
+
+.tui-icon-star-fill:before {
+	content: '\e664';
+}
+
+.tui-icon-strategy:before {
+	content: '\e663';
+}
+
+.tui-icon-sweep:before {
+	content: '\e662';
+}
+
+.tui-icon-time:before {
+	content: '\e661';
+}
+
+.tui-icon-time-fill:before {
+	content: '\e660';
+}
+
+.tui-icon-todown:before {
+	content: '\e65f';
+}
+
+.tui-icon-toleft:before {
+	content: '\e65e';
+}
+
+.tui-icon-tool:before {
+	content: '\e65d';
+}
+
+.tui-icon-top:before {
+	content: '\e65c';
+}
+
+.tui-icon-toright:before {
+	content: '\e65b';
+}
+
+.tui-icon-towardsleft:before {
+	content: '\e65a';
+}
+
+.tui-icon-towardsright:before {
+	content: '\e659';
+}
+
+.tui-icon-towardsright-fill:before {
+	content: '\e658';
+}
+
+.tui-icon-transport:before {
+	content: '\e657';
+}
+
+.tui-icon-transport-fill:before {
+	content: '\e656';
+}
+
+.tui-icon-turningdown:before {
+	content: '\e654';
+}
+
+.tui-icon-turningleft:before {
+	content: '\e653';
+}
+
+.tui-icon-turningright:before {
+	content: '\e652';
+}
+
+.tui-icon-turningup:before {
+	content: '\e651';
+}
+
+.tui-icon-unreceive:before {
+	content: '\e650';
+}
+
+.tui-icon-unseen:before {
+	content: '\e64f';
+}
+
+.tui-icon-up:before {
+	content: '\e64e';
+}
+
+.tui-icon-upload:before {
+	content: '\e64c';
+}
+
+.tui-icon-video:before {
+	content: '\e64b';
+}
+
+.tui-icon-voice:before {
+	content: '\e649';
+}
+
+.tui-icon-voice-fill:before {
+	content: '\e648';
+}
+
+.tui-icon-voipphone:before {
+	content: '\e647';
+}
+
+.tui-icon-wallet:before {
+	content: '\e646';
+}
+
+.tui-icon-warning:before {
+	content: '\e645';
+}
+
+.tui-icon-wealth:before {
+	content: '\e644';
+}
+
+.tui-icon-wealth-fill:before {
+	content: '\e643';
+}
+
+.tui-icon-weather:before {
+	content: '\e642';
+}
+
+.tui-icon-wechat:before {
+	content: '\e641';
+}
+
+.tui-icon-wifi:before {
+	content: '\e640';
+}
+
+/* icon end */
+
+/*Button start*/
+.tui-btn-primary {
+	background: #5677fc !important;
+	color: #fff;
+}
+
+.tui-shadow-primary {
+	box-shadow: 0 10rpx 14rpx 0 rgba(86, 119, 252, 0.2);
+}
+
+.tui-btn-danger {
+	background: #eb0909 !important;
+	color: #fff;
+}
+
+.tui-shadow-danger {
+	box-shadow: 0 10rpx 14rpx 0 rgba(235, 9, 9, 0.2);
+}
+
+.tui-btn-warning {
+	background: #fc872d !important;
+	color: #fff;
+}
+
+.tui-shadow-warning {
+	box-shadow: 0 10rpx 14rpx 0 rgba(252, 135, 45, 0.2);
+}
+
+.tui-btn-green {
+	background: #35b06a !important;
+	color: #fff;
+}
+
+.tui-shadow-green {
+	box-shadow: 0 10rpx 14rpx 0 rgba(53, 176, 106, 0.2);
+}
+
+.tui-btn-blue {
+	background: #007AFF !important;
+	color: #fff;
+}
+
+.tui-shadow-blue {
+	box-shadow: 0 10rpx 14rpx 0 rgba(0, 122, 255, 0.2);
+}
+
+.tui-btn-white {
+	background: #fff !important;
+	color: #333 !important;
+}
+
+.tui-btn-gray {
+	background: #bfbfbf !important;
+	color: #fff !important;
+}
+
+.tui-btn-black {
+	background: #333 !important;
+	color: #fff !important;
+}
+
+.tui-shadow-gray {
+	box-shadow: 0 10rpx 14rpx 0 rgba(191, 191, 191, 0.2);
+}
+
+.tui-hover-gray {
+	background: #f7f7f9 !important;
+}
+
+.tui-black-hover {
+	background: #555 !important;
+	color: #e5e5e5 !important;
+}
+
+/* button start 
+ * 宽高通过覆盖样式改变
+**/
+
+.tui-btn {
+	width: 100%;
+	height: 96rpx;
+	line-height: 96rpx;
+	font-size: 32rpx;
+	position: relative;
+	border: 0 !important;
+	border-radius: 6rpx;
+	padding-left: 0;
+	padding-right: 0;
+	overflow: visible;
+}
+
+.tui-btn-base {
+	width: auto;
+	/* #ifdef MP-ALIPAY */
+	min-width: 200rpx;
+	/* #endif */
+	font-size: 30rpx;
+	height: 70rpx;
+	line-height: 70rpx;
+}
+
+.tui-btn-small {
+	width: auto;
+	/* #ifdef MP-ALIPAY */
+	min-width: 140rpx;
+	/* #endif */
+	font-size: 30rpx;
+	height: 60rpx;
+	line-height: 60rpx;
+}
+
+.tui-btn::after {
+	content: '';
+	position: absolute;
+	width: 200%;
+	height: 200%;
+	transform-origin: 0 0;
+	transform: scale(0.5, 0.5) translateZ(0);
+	box-sizing: border-box;
+	left: 0;
+	top: 0;
+	border-radius: 12rpx;
+	border: 0;
+}
+
+.tui-btn-white::after {
+	border: 1rpx solid #bfbfbf;
+}
+
+.tui-white-hover {
+	background: #e5e5e5 !important;
+	color: #2e2e2e !important;
+}
+
+.tui-dark-disabled {
+	opacity: 0.6 !important;
+	color: #fafbfc !important;
+}
+
+.tui-dark-disabled-outline {
+	opacity: 0.5 !important;
+}
+
+.tui-gray-disabled {
+	background: #f3f3f3 !important;
+	color: #919191 !important;
+	box-shadow: none;
+}
+
+.tui-outline-hover {
+	opacity: 0.5;
+}
+
+.tui-primary-hover {
+	background: #4a67d6 !important;
+	color: #e5e5e5 !important;
+}
+
+.tui-primary-outline::after {
+	border: 1rpx solid #5677fc !important;
+}
+
+.tui-primary-outline {
+	color: #5677fc !important;
+	background: transparent;
+}
+
+.tui-danger-hover {
+	background: #c80808 !important;
+	color: #e5e5e5 !important;
+}
+
+.tui-danger-outline {
+	color: #eb0909 !important;
+	background: transparent;
+}
+
+.tui-danger-outline::after {
+	border: 1rpx solid #eb0909 !important;
+}
+
+.tui-warning-hover {
+	background: #d67326 !important;
+	color: #e5e5e5 !important;
+}
+
+.tui-warning-outline {
+	color: #fc872d !important;
+	background: transparent;
+}
+
+.tui-warning-outline::after {
+	border: 1px solid #fc872d !important;
+}
+
+.tui-green-hover {
+	background: #2d965a !important;
+	color: #e5e5e5 !important;
+}
+
+.tui-green-outline {
+	color: #35b06a !important;
+	background: transparent;
+}
+
+.tui-green-outline::after {
+	border: 1rpx solid #35b06a !important;
+}
+
+.tui-blue-hover {
+	background: #0062CC !important;
+	color: #e5e5e5 !important;
+}
+
+.tui-blue-outline {
+	color: #007AFF !important;
+	background: transparent;
+}
+
+.tui-blue-outline::after {
+	border: 1rpx solid #007AFF !important;
+}
+
+/* #ifndef APP-NVUE */
+.tui-btn-gradual {
+	background: linear-gradient(90deg, rgb(255, 89, 38), rgb(240, 14, 44)) !important;
+	color: #fff !important;
+}
+
+.tui-shadow-gradual {
+	box-shadow: 0 10rpx 14rpx 0 rgba(235, 9, 9, 0.15);
+}
+
+/* #endif */
+
+.tui-gray-hover {
+	background: #a3a3a3 !important;
+	color: #898989;
+}
+
+/* #ifndef APP-NVUE */
+.tui-gradual-hover {
+	background: linear-gradient(90deg, #d74620, #cd1225) !important;
+	color: #fff !important;
+}
+
+/* #endif */
+
+.tui-gray-outline {
+	color: #999 !important;
+	background: transparent !important;
+}
+
+.tui-white-outline {
+	color: #fff !important;
+	background: transparent !important;
+}
+
+.tui-black-outline {
+	background: transparent !important;
+	color: #333 !important;
+}
+
+.tui-gray-outline::after {
+	border: 1rpx solid #ccc !important;
+}
+
+.tui-white-outline::after {
+	border: 1px solid #fff !important;
+}
+
+.tui-black-outline::after {
+	border: 1px solid #333 !important;
+}
+
+/*圆角 */
+
+.tui-fillet {
+	border-radius: 50rpx;
+}
+
+.tui-btn-white.tui-fillet::after {
+	border-radius: 98rpx;
+}
+
+.tui-outline-fillet::after {
+	border-radius: 98rpx;
+}
+
+/*平角*/
+.tui-rightAngle {
+	border-radius: 0;
+}
+
+.tui-btn-white.tui-rightAngle::after {
+	border-radius: 0;
+}
+
+.tui-outline-rightAngle::after {
+	border-radius: 0;
+}
+
+/*Button end*/
+
+/*Tag start*/
+
+.tui-tag {
+	padding: 16rpx 26rpx;
+	font-size: 28rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	border-radius: 6rpx;
+}
+
+.tui-tag-outline {
+	position: relative;
+	background-color: none;
+	color: #5677fc;
+}
+
+.tui-tag-outline::after {
+	content: '';
+	position: absolute;
+	width: 200%;
+	height: 200%;
+	-webkit-transform-origin: 0 0;
+	transform-origin: 0 0;
+	-webkit-transform: scale(0.5, 0.5);
+	transform: scale(0.5, 0.5);
+	-webkit-box-sizing: border-box;
+	box-sizing: border-box;
+	left: 0;
+	top: 0;
+	border-radius: 12rpx;
+}
+
+.tui-tag-fillet {
+	border-radius: 50rpx;
+}
+
+.tui-white.tui-tag-fillet::after {
+	border-radius: 80rpx;
+}
+
+.tui-tag-outline-fillet::after {
+	border-radius: 80rpx;
+}
+
+.tui-tag-fillet-left {
+	border-radius: 50rpx 0 0 50rpx;
+}
+
+.tui-tag-fillet-right {
+	border-radius: 0 50rpx 50rpx 0;
+}
+
+.tui-tag-fillet-left.tui-tag-outline::after {
+	border-radius: 100rpx 0 0 100rpx;
+}
+
+.tui-tag-fillet-right.tui-tag-outline::after {
+	border-radius: 0 100rpx 100rpx 0;
+}
+
+/*Tag end*/
+
+/*Badge start*/
+.tui-badge-dot {
+	height: 16rpx;
+	width: 16rpx;
+	border-radius: 50%;
+}
+
+.tui-badge {
+	font-size: 24rpx;
+	height: 36rpx;
+	min-width: 12rpx;
+	padding: 0 12rpx;
+	border-radius: 36rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	z-index: 10;
+}
+
+.tui-badge-scale {
+	transform-origin: center center;
+}
+
+/*Badge end*/
+
+/*List start*/
+.tui-list-cell {
+	position: relative;
+	width: 100%;
+	padding: 26rpx 30rpx;
+	background-color: #fff;
+	box-sizing: border-box;
+}
+
+.tui-list-radius {
+	border-radius: 6rpx;
+	overflow: hidden;
+}
+
+.tui-cell-hover {
+	background-color: #f1f1f1 !important;
+}
+
+.tui-list-cell::after {
+	content: '';
+	position: absolute;
+	border-bottom: 1rpx solid #eaeef1;
+	-webkit-transform: scaleY(0.5) translateZ(0);
+	transform: scaleY(0.5) translateZ(0);
+	transform-origin: 0 100%;
+	bottom: 0;
+	right: 0;
+	left: 0;
+}
+
+.tui-line-left::after {
+	left: 30rpx !important;
+}
+
+.tui-line-right::after {
+	right: 30rpx !important;
+}
+
+.tui-cell-unlined::after {
+	border-bottom: 0 !important;
+}
+
+.tui-cell-arrow::before {
+	content: ' ';
+	height: 10px;
+	width: 10px;
+	border-width: 2px 2px 0 0;
+	border-color: #c0c0c0;
+	border-style: solid;
+	-webkit-transform: matrix(0.5, 0.5, -0.5, 0.5, 0, 0);
+	transform: matrix(0.5, 0.5, -0.5, 0.5, 0, 0);
+	position: absolute;
+	top: 50%;
+	margin-top: -6px;
+	right: 30rpx;
+}
+
+.tui-arrow-right::before {
+	right: 0 !important;
+}
+
+.tui-arrow-gray::before {
+	border-color: #666666 !important;
+}
+
+.tui-arrow-white::before {
+	border-color: #ffffff !important;
+}
+
+.tui-arrow-warning::before {
+	border-color: #ff7900 !important;
+}
+
+.tui-arrow-success::before {
+	border-color: #19be6b !important;
+}
+
+.tui-arrow-danger::before {
+	border-color: #eb0909 !important;
+}
+
+/*List end*/
+
+/*Card start*/
+.tui-card {
+	margin: 0 30rpx;
+	font-size: 28rpx;
+	background-color: #fff;
+	border-radius: 10rpx;
+	box-shadow: 0 0 10rpx #eee;
+	box-sizing: border-box;
+	overflow: hidden;
+}
+
+.tui-card-full {
+	margin: 0 !important;
+	border-radius: 0 !important;
+}
+
+.tui-card-full::after {
+	border-radius: 0 !important;
+}
+
+.tui-card-border {
+	position: relative;
+	box-shadow: none !important
+}
+
+.tui-card-border::after {
+	content: ' ';
+	position: absolute;
+	height: 200%;
+	width: 200%;
+	border: 1px solid #ddd;
+	transform-origin: 0 0;
+	-webkit-transform-origin: 0 0;
+	-webkit-transform: scale(0.5);
+	transform: scale(0.5);
+	left: 0;
+	top: 0;
+	border-radius: 20rpx;
+	box-sizing: border-box;
+	pointer-events: none;
+}
+
+.tui-card-header {
+	width: 100%;
+	padding: 20rpx;
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	position: relative;
+	box-sizing: border-box;
+	overflow: hidden;
+	border-top-left-radius: 10rpx;
+	border-top-right-radius: 10rpx;
+}
+
+.tui-card-header::after {
+	content: '';
+	position: absolute;
+	border-bottom: 1rpx solid #eaeef1;
+	-webkit-transform: scaleY(0.5);
+	transform: scaleY(0.5);
+	bottom: 0;
+	right: 0;
+	left: 0;
+	pointer-events: none;
+}
+
+.tui-header-line::after {
+	border-bottom: 0 !important;
+}
+
+.tui-header-thumb {
+	height: 60rpx;
+	width: 60rpx;
+	vertical-align: middle;
+	margin-right: 20rpx;
+	border-radius: 6rpx;
+}
+
+.tui-thumb-circle {
+	border-radius: 50% !important;
+}
+
+.tui-header-title {
+	display: inline-block;
+	font-size: 30rpx;
+	color: #7a7a7a;
+	vertical-align: middle;
+	max-width: 460rpx;
+	overflow: hidden;
+	white-space: nowrap;
+	text-overflow: ellipsis;
+}
+
+.tui-header-right {
+	font-size: 24rpx;
+	color: #b2b2b2;
+}
+
+.tui-card-body {
+	font-size: 32rpx;
+	color: #262b3a;
+	box-sizing: border-box;
+}
+
+.tui-card-footer {
+	font-size: 28rpx;
+	color: #596d96;
+	border-bottom-left-radius: 10rpx;
+	border-bottom-right-radius: 10rpx;
+	box-sizing: border-box;
+}
+
+/*Card end*/
+
+/*Grid start*/
+.tui-grids {
+	width: 100%;
+	position: relative;
+	overflow: hidden;
+}
+
+.tui-grids::after {
+	content: " ";
+	position: absolute;
+	left: 0;
+	top: 0;
+	width: 100%;
+	height: 1px;
+	border-top: 1px solid #eaeef1;
+	-webkit-transform-origin: 0 0;
+	transform-origin: 0 0;
+	-webkit-transform: scaleY(0.5);
+	transform: scaleY(0.5);
+}
+
+.tui-border-top::after {
+	border-top: 0 !important;
+}
+
+.tui-grid {
+	position: relative;
+	padding: 40rpx 20rpx;
+	box-sizing: border-box;
+	background: #fff;
+	float: left;
+}
+
+.tui-grid-2 {
+	width: 50%;
+}
+
+.tui-grid-3 {
+	width: 33.333333333%;
+}
+
+.tui-grid-4 {
+	width: 25%;
+	padding: 30rpx 20rpx !important;
+}
+
+.tui-grid-5 {
+	width: 20%;
+	padding: 20rpx !important;
+}
+
+.tui-grid-2:nth-of-type(2n)::before {
+	width: 0;
+	border-right: 0;
+}
+
+.tui-grid-3:nth-of-type(3n)::before {
+	width: 0;
+	border-right: 0;
+}
+
+.tui-grid-4:nth-of-type(4n)::before {
+	width: 0;
+	border-right: 0;
+}
+
+.tui-grid-5:nth-of-type(5n)::before {
+	width: 0;
+	border-right: 0;
+}
+
+.tui-grid::before {
+	content: " ";
+	position: absolute;
+	right: 0;
+	top: 0;
+	width: 1px;
+	bottom: 0;
+	border-right: 1px solid #eaeef1;
+	-webkit-transform-origin: 100% 0;
+	transform-origin: 100% 0;
+	-webkit-transform: scaleX(0.5);
+	transform: scaleX(0.5);
+}
+
+.tui-grid::after {
+	content: " ";
+	position: absolute;
+	left: 0;
+	bottom: 0;
+	right: 0;
+	height: 1px;
+	border-bottom: 1px solid #eaeef1;
+	-webkit-transform-origin: 0 100%;
+	transform-origin: 0 100%;
+	-webkit-transform: scaleY(0.5);
+	transform: scaleY(0.5);
+}
+
+.tui-grid-bottom::after {
+	height: 0 !important;
+	border-bottom: 0 !important
+}
+
+.tui-grid-bg {
+	position: relative;
+	padding: 0;
+	width: 100%;
+	box-sizing: border-box;
+}
+
+.tui-item-hover {
+	background-color: #f7f7f9 !important;
+}
+
+/*Grid end*/
+
+/*Loading start*/
+.tui-loading-init {
+	min-width: 200rpx;
+	min-height: 200rpx;
+	max-width: 500rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	flex-direction: column;
+	position: fixed;
+	top: 50%;
+	left: 50%;
+	transform: translate(-50%, -50%);
+	z-index: 9999;
+	font-size: 26rpx;
+	color: #fff;
+	background-color: rgba(0, 0, 0, 0.7);
+	border-radius: 10rpx;
+}
+
+.tui-loading-center {
+	width: 50rpx;
+	height: 50rpx;
+	border: 3px solid #fff;
+	border-radius: 50%;
+	margin: 0 6px;
+	display: inline-block;
+	vertical-align: middle;
+	clip-path: polygon(0% 0%, 100% 0%, 100% 40%, 0% 40%);
+	animation: rotate 1s linear infinite;
+	margin-bottom: 36rpx;
+}
+
+.tui-loadmore-tips {
+	text-align: center;
+	padding: 0 20rpx;
+	box-sizing: border-box;
+}
+
+@-webkit-keyframes rotate {
+	from {
+		transform: rotatez(0deg);
+	}
+
+	to {
+		transform: rotatez(360deg);
+	}
+}
+
+@keyframes rotate {
+	from {
+		transform: rotatez(0deg);
+	}
+
+	to {
+		transform: rotatez(360deg);
+	}
+}
+
+.tui-loadmore {
+	width: 48%;
+	margin: 1.5em auto;
+	line-height: 1.5em;
+	font-size: 24rpx;
+	text-align: center;
+}
+
+.tui-loading-1 {
+	margin: 0 5px;
+	width: 20px;
+	height: 20px;
+	display: inline-block;
+	vertical-align: middle;
+	-webkit-animation: a 1s steps(12) infinite;
+	animation: a 1s steps(12) infinite;
+	background: transparent url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAiIGhlaWdodD0iMTIwIiB2aWV3Qm94PSIwIDAgMTAwIDEwMCI+PHBhdGggZmlsbD0ibm9uZSIgZD0iTTAgMGgxMDB2MTAwSDB6Ii8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTlFOUU5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAgLTMwKSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iIzk4OTY5NyIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgzMCAxMDUuOTggNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjOUI5OTlBIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDYwIDc1Ljk4IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0EzQTFBMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSg5MCA2NSA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNBQkE5QUEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoMTIwIDU4LjY2IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0IyQjJCMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgxNTAgNTQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjQkFCOEI5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDE4MCA1MCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDMkMwQzEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTE1MCA0NS45OCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDQkNCQ0IiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTEyMCA0MS4zNCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNEMkQyRDIiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTkwIDM1IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0RBREFEQSIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgtNjAgMjQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTJFMkUyIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKC0zMCAtNS45OCA2NSkiLz48L3N2Zz4=) no-repeat;
+	background-size: 100%;
+}
+
+@-webkit-keyframes a {
+	0% {
+		-webkit-transform: rotate(0deg);
+		transform: rotate(0deg);
+	}
+
+	to {
+		-webkit-transform: rotate(1turn);
+		transform: rotate(1turn);
+	}
+}
+
+@keyframes a {
+	0% {
+		-webkit-transform: rotate(0deg);
+		transform: rotate(0deg);
+	}
+
+	to {
+		-webkit-transform: rotate(1turn);
+		transform: rotate(1turn);
+	}
+}
+
+.tui-loadmore-tips {
+	display: inline-block;
+	vertical-align: middle;
+}
+
+.tui-loading-2 {
+	width: 28rpx;
+	height: 28rpx;
+	border: 1px solid #8f8d8e;
+	border-radius: 50%;
+	margin: 0 6px;
+	display: inline-block;
+	vertical-align: middle;
+	clip-path: polygon(0% 0%, 100% 0%, 100% 30%, 0% 30%);
+	animation: rotate 1s linear infinite;
+}
+
+@-webkit-keyframes rotate {
+	from {
+		transform: rotatez(0deg);
+	}
+
+	to {
+		transform: rotatez(360deg);
+	}
+}
+
+@keyframes rotate {
+	from {
+		transform: rotatez(0deg);
+	}
+
+	to {
+		transform: rotatez(360deg);
+	}
+}
+
+.tui-loading-3 {
+	display: inline-block;
+	margin: 0 6px;
+	vertical-align: middle;
+	width: 28rpx;
+	height: 28rpx;
+	background: 0 0;
+	border-radius: 50%;
+	border: 2px solid;
+	border-color: #e5e5e5 #e5e5e5 #e5e5e5 #8f8d8e;
+	animation: tui-rotate 0.7s linear infinite;
+}
+
+.tui-loading-3.tui-loading-primary {
+	border-color: #e5e5e5 #e5e5e5 #e5e5e5 #5677fc;
+}
+
+.tui-loading-3.tui-loading-green {
+	border-color: #e5e5e5 #e5e5e5 #e5e5e5 #19be6b;
+}
+
+.tui-loading-3.tui-loading-orange {
+	border-color: #e5e5e5 #e5e5e5 #e5e5e5 #ff7900;
+}
+
+.tui-loading-3.tui-loading-red {
+	border-color: #ededed #ededed #ededed #ed3f14;
+}
+
+@-webkit-keyframes tui-rotate {
+	0% {
+		transform: rotate(0);
+	}
+
+	100% {
+		transform: rotate(360deg);
+	}
+}
+
+@keyframes tui-rotate {
+	0% {
+		transform: rotate(0);
+	}
+
+	100% {
+		transform: rotate(360deg);
+	}
+}
+
+.tui-loadmore-none {
+	width: 50%;
+	margin: 1.5em auto;
+	line-height: 1.5em;
+	font-size: 24rpx;
+	display: flex;
+	justify-content: center;
+}
+
+.tui-nomore {
+	width: 100%;
+	height: 100%;
+	position: relative;
+	display: flex;
+	justify-content: center;
+	margin-top: 10rpx;
+	padding-bottom: 6rpx;
+}
+
+.tui-nomore::before {
+	content: ' ';
+	position: absolute;
+	border-bottom: 1rpx solid #e5e5e5;
+	-webkit-transform: scaleY(0.5);
+	transform: scaleY(0.5);
+	width: 100%;
+	top: 18rpx;
+	left: 0;
+}
+
+.tui-nomore-text {
+	color: #999;
+	font-size: 24rpx;
+	text-align: center;
+	padding: 0 18rpx;
+	height: 36rpx;
+	line-height: 36rpx;
+	position: relative;
+	z-index: 1;
+}
+
+.tui-nomore-dot {
+	position: relative;
+	text-align: center;
+	-webkit-display: flex;
+	display: flex;
+	-webkit-justify-content: center;
+	justify-content: center;
+	margin-top: 10rpx;
+	padding-bottom: 6rpx;
+}
+
+.tui-nomore-dot::before {
+	content: '';
+	position: absolute;
+	border-bottom: 1rpx solid #e5e5e5;
+	-webkit-transform: scaleY(0.5);
+	transform: scaleY(0.5);
+	width: 360rpx;
+	top: 18rpx;
+}
+
+.tui-dot-text {
+	position: relative;
+	color: #e5e5e5;
+	font-size: 10px;
+	text-align: center;
+	width: 50rpx;
+	height: 36rpx;
+	line-height: 36rpx;
+	-webkit-transform: scale(0.8);
+	transform: scale(0.8);
+	-webkit-transform-origin: center center;
+	transform-origin: center center;
+	z-index: 1;
+}
+
+/*Loading end*/
+
+/*Footer start*/
+.tui-footer {
+	width: 100%;
+	overflow: hidden;
+	padding: 30rpx 24rpx;
+	box-sizing: border-box;
+	font-size: 24rpx;
+	color: #A7A7A7;
+}
+
+.tui-fixed {
+	position: fixed;
+	z-index: 9999;
+	/* #ifdef H5 */
+	bottom: 0;
+	/* #endif */
+	/* #ifndef H5 */
+	bottom: env(safe-area-inset-bottom);
+	/* #endif */
+}
+
+.tui-footer-link {
+	color: #596d96;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	font-size: 28rpx;
+}
+
+.tui-link {
+	position: relative;
+	padding: 0 18rpx;
+	line-height: 1;
+}
+
+.tui-link::before {
+	content: " ";
+	position: absolute;
+	right: 0;
+	top: 0;
+	width: 1px;
+	bottom: 0;
+	border-right: 1px solid #d3d3d3;
+	-webkit-transform-origin: 100% 0;
+	transform-origin: 100% 0;
+	-webkit-transform: scaleX(0.5);
+	transform: scaleX(0.5);
+}
+
+.tui-link:last-child::before {
+	border-right: 0 !important
+}
+
+.tui-link-hover {
+	opacity: 0.5
+}
+
+.tui-footer-copyright {
+	font-size: 24rpx;
+	color: #A7A7A7;
+	line-height: 1;
+	text-align: center;
+	padding-top: 16rpx
+}
+
+/*Footer end*/
+
+
+/*layout start*/
+
+/*形状*/
+.tui-triangle {
+	border: 16rpx solid;
+	width: 0;
+	height: 0;
+}
+
+.tui-triangle-left {
+	border-color: transparent #5c8dff transparent transparent;
+}
+
+.tui-triangle-right {
+	border-color: transparent transparent transparent #5c8dff;
+}
+
+.tui-triangle-top {
+	border-color: transparent transparent #5c8dff transparent;
+}
+
+.tui-triangle-bottom {
+	border-color: #5c8dff transparent transparent transparent;
+}
+
+
+.tui-parallelogram {
+	width: 100rpx;
+	height: 50rpx;
+	transform: skew(-10deg);
+	background: #19be6b;
+	margin-left: 10rpx;
+}
+
+.tui-crescent {
+	width: 60rpx;
+	height: 60rpx;
+	border-radius: 50%;
+	box-shadow: 12rpx 12rpx 0 0 yellowgreen;
+}
+
+/*聊天框*/
+.tui-chatbox {
+	max-width: 60%;
+	border-radius: 10rpx;
+	position: relative;
+	padding: 20rpx 26rpx;
+	font-size: 28rpx;
+	color: #fff;
+	/* word-break: break-all;
+  word-wrap: break-word; */
+}
+
+.tui-chatbox-left {
+	background: #5c8dff;
+	border: 1rpx solid #5c8dff;
+	display: inline-block;
+}
+
+.tui-chatbox-right {
+	background: #19be6b;
+	border: 1rpx solid #19be6b;
+}
+
+.tui-chatbox::before {
+	content: "";
+	position: absolute;
+	width: 0;
+	height: 0;
+	top: 20rpx;
+	border: 16rpx solid;
+}
+
+.tui-chatbox-left::before {
+	right: 100%;
+	border-color: transparent #5c8dff transparent transparent;
+}
+
+.tui-chatbox-right::before {
+	left: 100%;
+	border-color: transparent transparent transparent #19be6b;
+}
+
+/*checkbox 整体大小  */
+
+/* #ifdef MP-WEIXIN */
+.tui-checkbox .wx-checkbox-input {
+	width: 36rpx;
+	height: 36rpx;
+	border-radius: 50%;
+	margin: 0;
+}
+
+.tui-checkbox .wx-checkbox-input.wx-checkbox-input-checked {
+	background: #F82400;
+	width: 40rpx;
+	height: 40rpx;
+	border: none;
+}
+
+/* #endif */
+
+/* #ifndef MP-WEIXIN */
+>>>.tui-checkbox .uni-checkbox-input {
+	width: 36rpx;
+	height: 36rpx;
+	border-radius: 50% !important;
+	margin: 0;
+	border-color: #d1d1d1 !important;
+}
+
+>>>.tui-checkbox .uni-checkbox-input.uni-checkbox-input-checked {
+	background: #F82400;
+	width: 40rpx;
+	height: 40rpx;
+	border: none;
+}
+
+/* #endif */
+
+/*textarea*/
+
+.tui-textarea-box {
+	border-radius: 4rpx;
+	height: 280rpx;
+	box-sizing: border-box;
+	padding: 20rpx 20rpx 0 20rpx;
+	position: relative;
+}
+
+.tui-textarea-box::after {
+	content: '';
+	position: absolute;
+	height: 200%;
+	width: 200%;
+	border: 1px solid #e6e6e6;
+	transform-origin: 0 0;
+	-webkit-transform-origin: 0 0;
+	-webkit-transform: scale(0.5);
+	transform: scale(0.5);
+	left: 0;
+	top: 0;
+	border-radius: 8rpx;
+	pointer-events: none;
+}
+
+.tui-textarea {
+	height: 210rpx;
+	width: 100%;
+	color: #666;
+	font-size: 28rpx;
+	z-index: 2;
+}
+
+.tui-phcolor-color {
+	color: #ccc !important;
+}
+
+.tui-textarea-counter {
+	font-size: 24rpx;
+	color: #999;
+	text-align: right;
+	height: 40rpx;
+	line-height: 40rpx;
+	padding-top: 4rpx;
+}
+
+/*Input输入框*/
+.tui-input-item {
+	width: 100%;
+	display: flex;
+	align-items: center;
+	font-size: 32rpx;
+
+}
+
+.tui-input {
+	flex: 1;
+	font-size: 32rpx;
+	overflow: visible;
+}
+
+.tui-input-title {
+	min-width: 140rpx;
+	padding-right: 12rpx;
+	flex-shrink: 0;
+}
+
+.tui-phcolor {
+	color: #ccc;
+	font-size: 32rpx;
+	overflow: visible;
+}
+
+.tui-input-border {
+	/* border: 1rpx solid #eaeef1; */
+	padding: 20rpx 30rpx;
+	border-radius: 4rpx;
+	position: relative;
+	font-size: 32rpx;
+}
+
+.tui-input-border::after {
+	content: '';
+	position: absolute;
+	height: 200%;
+	width: 200%;
+	border: 1px solid #e6e6e6;
+	transform-origin: 0 0;
+	-webkit-transform-origin: 0 0;
+	-webkit-transform: scale(0.5);
+	transform: scale(0.5);
+	left: 0;
+	top: 0;
+	border-radius: 8rpx;
+	pointer-events: none;
+}
+
+.tui-text-right {
+	text-align: right;
+}
+
+/*上传*/
+.tui-upload-box {
+	width: 100%;
+	display: flex;
+	flex-wrap: wrap;
+}
+
+.tui-upload-item {
+	width: 220rpx;
+	height: 220rpx;
+	position: relative;
+	margin-right: 20rpx;
+	margin-bottom: 20rpx;
+}
+
+.tui-upload-item:nth-of-type(3n) {
+	margin-right: 0;
+}
+
+.tui-upload-img {
+	width: 220rpx;
+	height: 220rpx;
+	display: block;
+}
+
+.tui-upload-del {
+	position: absolute;
+	right: -18rpx;
+	top: -18rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+}
+
+.tui-upload-add {
+	width: 220rpx;
+	height: 220rpx;
+	font-size: 68rpx;
+	font-weight: 100;
+	color: #888;
+	background-color: #F7F7F7;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	padding: 0;
+}
+
+/* 操作条*/
+.tui-operation {
+	width: 100%;
+	height: 100rpx;
+	box-sizing: border-box;
+	overflow: hidden;
+	background: rgba(255, 255, 255, 0.9);
+	position: relative;
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+}
+
+.tui-operation::before {
+	content: '';
+	position: absolute;
+	top: 0px;
+	right: 0;
+	left: 0;
+	border-top: 1rpx solid #eaeef1;
+	-webkit-transform: scaleY(0.5);
+	transform: scaleY(0.5);
+}
+
+.tui-operation-left {
+	display: flex;
+	align-items: center;
+}
+
+.tui-operation-item {
+	flex: 1;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	flex-direction: column;
+	position: relative;
+}
+
+.tui-operation-text {
+	font-size: 22rpx;
+	color: #333;
+}
+
+.tui-operation-right {
+	flex: 1;
+	height: 100rpx;
+	box-sizing: border-box;
+	padding-top: 0;
+}
+
+.tui-relative {
+	position: relative;
+}
+
+.tui-btn-comment {
+	height: 64rpx;
+	width: 84%;
+	background: #ededed;
+	color: #999;
+	border-radius: 8rpx;
+	font-size: 28rpx;
+	display: flex;
+	align-items: center;
+	padding-left: 20rpx;
+	box-sizing: border-box;
+	padding-top: 0;
+	margin-left: 30rpx;
+}
+
+.tui-chat-operation {
+	background: #F6F6F6 !important;
+	padding-right: 18rpx;
+	box-sizing: border-box;
+}
+
+.tui-input-box {
+	width: 78%;
+	justify-content: flex-start;
+}
+
+.tui-chat-input {
+	background: #fff;
+	height: 72rpx;
+	border-radius: 6rpx;
+	padding-left: 20rpx;
+	padding-right: 20rpx;
+	flex: 1;
+}
+
+.tui-voice-icon {
+	margin-left: 20rpx;
+	margin-right: 20rpx
+}
+
+/*layout end*/

+ 0 - 65
common/css/theme.scss

@@ -1,65 +0,0 @@
-// 产品相关
-$cm-price-color: #ff457b;
-$cm-name-color: #333333;
-$cm-color: #ff457b;
-
-/* 行为相关颜色 */
-$cm-color-primary: #007aff;
-$cm-color-success: #4cd964;
-$cm-color-warning: #f0ad4e;
-$cm-color-error: #dd524d;
-
-/* 文字基本颜色 */
-$cm-text-color: #333; //基本色
-$cm-text-color-inverse: #fff; //反色
-$cm-text-color-grey: #999; //辅助灰色,如加载更多的提示信息
-$cm-text-color-placeholder: #808080;
-$cm-text-color-disable: #c0c0c0;
-
-/* 背景颜色 */
-$cm-bg-color: #ffffff;
-$cm-bg-color-grey: #f7f7f7;
-$cm-bg-color-hover: #f1f1f1; //点击状态颜色
-$cm-bg-color-mask: rgba(0, 0, 0, 0.4); //遮罩颜色
-
-/* 边框颜色 */
-$cm-border-color: #c8c7cc;
-$cm-border-color-active: #ff457b;
-
-/* 文字尺寸 */
-$cm-font-size-sm: 24rpx;
-$cm-font-size-base: 28rpx;
-$cm-font-size-lg: 32rpx;
-
-/* 图片尺寸 */
-$cm-img-size-sm: 40rpx;
-$cm-img-size-base: 52rpx;
-$cm-img-size-lg: 80rpx;
-
-/* Border Radius */
-$cm-border-radius-sm: 4rpx;
-$cm-border-radius-base: 6rpx;
-$cm-border-radius-lg: 12rpx;
-$cm-border-radius-circle: 50%;
-
-/* 水平间距 */
-$cm-spacing-row-sm: 8rpx;
-$cm-spacing-row-base: 16rpx;
-$cm-spacing-row-lg: 24rpx;
-
-/* 垂直间距 */
-$cm-spacing-col-sm: 8rpx;
-$cm-spacing-col-base: 16rpx;
-$cm-spacing-col-lg: 24rpx;
-
-/* 透明度 */
-$cm-opacity-disabled: 0.3; // 组件禁用态的透明度
-
-/* 文章场景相关 */
-$cm-color-title: #2c405a; // 文章标题颜色
-$cm-font-size-title: 40rpx;
-$cm-color-subtitle: #555555; // 二级标题颜色
-$cm-font-size-subtitle: 52rpx;
-$cm-color-paragraph: #3f536e; // 文章段落颜色
-$cm-font-size-paragraph: 30rpx;
-

+ 0 - 25
common/filters.js

@@ -1,25 +0,0 @@
-import { dateFormat } from '@/common/utils.js'
-
-const install = Vue => {
-    // 格式化金额
-    Vue.filter('priceFormat', function(value) {
-        if (typeof value === 'undefined') return '未知'
-        if (typeof value !== 'number') {
-            value = parseFloat(value)
-        }
-        return value.toFixed(2) > 0 ? value.toFixed(2) : 0
-    })
-
-    // 格式化时间
-    Vue.filter('dateFormat', function(value) {
-        if (!value) return '未知'
-        if (value instanceof Date) {
-            return dateFormat(value, 'yyyy-MM-dd')
-        } else {
-            value = new Date(value)
-            return dateFormat(value, 'yyyy-MM-dd')
-        }
-    })
-}
-
-export default install

BIN=BIN
common/fonts/iconfont.ttf


BIN=BIN
common/fonts/iconfont.woff


BIN=BIN
common/fonts/iconfont.woff2


+ 0 - 195
common/goods.helper.js

@@ -1,195 +0,0 @@
-import { fetchProductDetail } from '@/services/api/goods.js'
-import { fetchCouponListByProductId } from '@/services/api/coupon.js'
-import store from '@/store/index.js'
-
-/* 获取产品活动类型 (拼团 活动价 限时特价) */
-export function generateActivityType(productData) {
-    const { collageStatus = 0, activeStatus = 0, discountStatus = 0 } = productData
-    // 拼团价
-    if (collageStatus > 0) {
-        return 'group' // 拼团价
-    }
-    // 限时活动
-    else if (discountStatus > 0) {
-        return 'time-limit'
-    }
-    // 普通活动价
-    else if (activeStatus > 0) {
-        return 'activity'
-    }
-    // 普通商品
-    return 'normal' // 普通价
-}
-
-/* 获取产品价格类型 */
-export function generatePriceType(productData) {
-    const { couponStatus = 0, collageStatus = 0, activeStatus = 0, discountStatus = 0, couponId } = productData
-    // 拼团价
-    if (collageStatus > 0) {
-        if (couponStatus === 1 && couponId) {
-            return 'groupWithCoupon' // 拼团券后价
-        } else {
-            return 'group' // 拼团价
-        }
-    }
-    // 限时活动
-    else if (discountStatus > 0 || activeStatus > 0) {
-        if (couponStatus === 1 && couponId) {
-            return 'activityWithCoupon' // 券后价
-        } else {
-            return 'normal' // 限时活动价格
-        }
-    }
-    // 无活动价
-    else {
-        if (couponStatus === 1 && couponId) {
-            return 'normalWithCoupon' // 普通券后价
-        } else {
-            return 'normal' // 普通价
-        }
-    }
-}
-
-/* 导航栏按钮类别 */
-const navbarButtonGroup = {
-    // 仅拼团
-    group: {
-        left: ['单独购买', '¥1000.00'],
-        right: ['拼团购买', '¥1000.00']
-    },
-
-    // 拼团 + 优惠券
-    groupWithCoupon: {
-        left: ['领券单独购买', '¥1000.00'],
-        right: ['领券拼团购买', '¥1000.00']
-    },
-
-    // 限时活动 / 活动价 + 优惠券
-    activityWithCoupon: {
-        left: ['加入购物车'],
-        right: ['领券购买', '¥1000.00']
-    },
-
-    // 限时活动 / 活动价 + 优惠券
-    normalWithCoupon: {
-        left: ['加入购物车'],
-        right: ['领券购买', '¥1000.00']
-    },
-
-    // 普通方式 不使用优惠券
-    normal: {
-        left: ['加入购物车'],
-        right: ['立即购买']
-    }
-}
-
-/* 导航按钮文本 */
-export function generateNavbarButtonText(productData) {
-    const { priceType } = productData
-    const navbarButton = navbarButtonGroup[priceType]
-    // 拼团券后价购买
-    if (priceType === 'groupWithCoupon') {
-        navbarButton.left[1] = `¥${productData.normalCouponPrice.toFixed(2)}`
-        navbarButton.right[1] = `¥${productData.couponPrice.toFixed(2)}`
-    }
-    // 拼团价购买
-    else if (priceType === 'group') {
-        navbarButton.left[1] = `¥${productData.normalPrice.toFixed(2)}`
-        navbarButton.right[1] = `¥${productData.price.toFixed(2)}`
-    }
-    // 活动价券后价购买(限时特价|普通活动)
-    else if (priceType === 'activityWithCoupon') {
-        navbarButton.right[1] = `¥${productData.couponPrice.toFixed(2)}`
-    }
-    // 普通价券后价购买
-    else if (priceType === 'normalWithCoupon') {
-        navbarButton.right[1] = `¥${productData.couponPrice.toFixed(2)}`
-    } else {
-        navbarButton.right[1] = ''
-    }
-    return navbarButton
-}
-
-/* 生成导航菜单类型 */
-export function generateNavbarType(productInfo) {
-    const { couponStatus = 0, collageStatus = 0, activeStatus = 0, discountStatus = 0 } = productInfo
-    // 拼团价
-    if (collageStatus > 0) {
-        if (couponStatus === 1) {
-            return 'groupWithCoupon' // 拼团券后价
-        } else {
-            return 'group' // 拼团价
-        }
-    }
-    // 限时活动
-    else if (discountStatus > 0 || activeStatus > 0) {
-        if (couponStatus === 1) {
-            return 'activityWithCoupon' // 券后价
-        } else {
-            return 'normal' // 限时活动价格
-        }
-    }
-    // 无活动价
-    else {
-        if (couponStatus === 1) {
-            return 'normalWithCoupon' // 普通券后价
-        } else {
-            return 'normal' // 普通价
-        }
-    }
-}
-
-/* 处理商品信息 */
-function generateProductInfo(product) {
-    if (!product) return product
-    // 商品活动类型
-    product.activityType = generateActivityType(product)
-    product.priceType = generatePriceType(product)
-    product.skus = product.skus.map(sku => {
-        sku.activityType = generateActivityType(sku)
-        sku.priceType = generatePriceType(sku)
-        return sku
-    })
-    return product
-}
-
-/* 创建优惠券 */
-function generateCoupon(coupon) {
-    const obj = Object.assign({}, coupon)
-    // 添加标题
-    if (coupon.noThresholdFlag > 0) {
-        obj.couponTitle = `减¥${coupon.couponAmount}元`
-    } else {
-        obj.couponTitle = `满¥${coupon.touchPrice}元减¥${coupon.couponAmount}元`
-    }
-    // 添加优惠券状态
-    if (obj.useStatus === 0) {
-        obj.controlType = 'receive'
-    } else if (obj.useStatus === 1) {
-        obj.couponStatus = 'received'
-        obj.controlType = 'search'
-    }
-    return obj
-}
-
-/* 获取商品详情 */
-export async function fetchPorductInfo(productId) {
-    try {
-        const userId = store.getters.userId
-        const res = await fetchProductDetail({ productId, userId })
-        return generateProductInfo(res.data)
-    } catch (e) {
-        console.log(e)
-    }
-}
-
-/* 获取商品可用优惠券 */
-export async function fetchCouponListByProduct(productId) {
-    try {
-        const userId = store.getters.userId
-        const res = await fetchCouponListByProductId({ productId, userId })
-        return res.data.map(coupon => generateCoupon(coupon))
-    } catch (e) {
-        console.log(e)
-    }
-}

+ 47 - 0
common/json/data.json.js

@@ -0,0 +1,47 @@
+const beautyList = [
+    { value: 1, name: '诊所' },
+    { value: 2, name: '门诊' },
+    { value: 3, name: '医院' },
+    { value: 4, name: '其他' }
+]
+const beautyLists = [
+    { value: 5, name: '美容院' },
+    { value: 6, name: '养生馆' },
+    { value: 7, name: '其他' }
+]
+const mentuzCampNullList = [
+    { value: '1', name: '整形' },
+    { value: '2', name: '轻医美' },
+    { value: '3', name: '皮肤科' }
+]
+const medicaCampNullList = [
+    { value: '1', name: '美容' },
+    { value: '2', name: '美体' },
+    { value: '3', name: '美发' },
+    { value: '4', name: '皮肤管理' },
+    { value: '5', name: '光电' },
+    { value: '6', name: '综合类' },
+    { value: '7', name: '中医养生' },
+    { value: '8', name: 'spa' },
+    { value: '9', name: '产后修复' }
+]
+
+const supplierList = [
+    { value: 1, name: '一类器械' },
+    { value: 2, name: '二类器械' },
+    { value: 3, name: '三类器械' },
+    { value: 4, name: '其他' }
+]
+const supplierMedicaCampNullList = [
+    { value: '1', name: '产品' },
+    { value: '2', name: '仪器' },
+    { value: '3', name: '服务' }
+]
+module.exports = {
+    beautyList,
+    beautyLists,
+    mentuzCampNullList,
+    medicaCampNullList,
+    supplierList,
+    supplierMedicaCampNullList
+}

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
common/libs/crypto-js.min.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
common/libs/picker.city.js


+ 0 - 105
common/share.helper.js

@@ -1,105 +0,0 @@
-import { encrypt } from '@/common/crypto.js'
-/* 小程序码 */
-import store from '@/store/index.js'
-import { wxUnlimited } from '@/services/api/auth.js'
-const fs = uni.getFileSystemManager()
-const qrcodePath = `${wx.env.USER_DATA_PATH}/qrcodePath`
-
-const defalutOptions = {
-    title: '护肤上颜选,正品有好货~',
-    path: '/pages/index/index',
-    imageUrl: 'https://static.caimei365.com/app/mini-hehe/icon/icon-share.png'
-}
-
-export function shareDataResult(shareData, title, coverUrl) {
-    const state_str = encodeURIComponent(encrypt(shareData))
-    const result = {
-        title: title || defalutOptions.title,
-        path: `${defalutOptions.path}?state_str=${state_str}`,
-        imageUrl: coverUrl || defalutOptions.imageUrl
-    }
-    return result
-}
-
-const queryKeyOfMap = {
-    'type': 't',
-    'inviteUserId': 'i',
-    'activityId': 'a',
-    'dealerUserId': 'd',
-    'keyWord': 'k',
-    'productId': 'p',
-    'jumpState': 'j',
-    'collageId': 'c'
-}
-
-const enQueryKeyOfMap = {
-    't': 'type',
-    'i': 'inviteUserId',
-    'a': 'activityId',
-    'd': 'dealerUserId',
-    'k': 'keyWord',
-    'p': 'productId',
-    'j': 'jumpState',
-    'c': 'collageId'
-}
-
-// 创建二维码保存路径
-function createQrcodeDir(callback) {
-    try {
-        fs.accessSync(qrcodePath)
-        console.log('已存在文件夹')
-        callback(qrcodePath)
-    } catch (e) {
-        fs.mkdirSync(qrcodePath)
-        console.log('不存在文件夹')
-        callback(qrcodePath)
-    }
-}
-
-
-/* 生成二维码链接 */
-export async function generateWxUnlimited(params) {
-    try {
-        // 从服务端获取二维码arrayBuffer
-        return await wxUnlimited({
-            page: params.pagePath || 'pages/index/index',
-            scene: codeQueryStr(params.queryStr),
-            check_path: process.env.NODE_ENV === 'production', // 是否校验页面
-            env_version: process.env.NODE_ENV === 'production' ? 'release' : 'trial', // 正式版 or 开发版
-            width: 200, // 二维码宽度
-            auto_color: false, // 自动颜色
-            line_color: { 'r': 0, 'g': 0, 'b': 0 }, // 线条颜色
-            is_hyaline: true // 透明底
-        })
-    } catch (e) {
-        return Promise.reject(e)
-    }
-}
-
-// 编码查询参数
-export function codeQueryStr(query = '') {
-    const keys = Object.keys(queryKeyOfMap)
-    return query.split('&').map(str => {
-        return str.split('=').map((substr, index) => {
-            if (!index) {
-                return queryKeyOfMap[keys.find(item => substr === item)]
-            } else {
-                return substr
-            }
-        }).join('=')
-    }).join('&')
-}
-
-// 反编码查询参数
-export function enCodeQueryStr(query) {
-    const keys = Object.keys(enQueryKeyOfMap)
-    return query.split('&').map(str => {
-        return str.split('=').map((substr, index) => {
-            if (!index) {
-                return enQueryKeyOfMap[keys.find(item => substr === item)]
-            } else {
-                return substr
-            }
-        }).join('=')
-    }).join('&')
-}

+ 0 - 54
common/storage.js

@@ -1,54 +0,0 @@
-import { encrypt, decrypt } from '@/common/crypto.js'
-
-// 在开发环境下不需要加密数据
-const encryptFlag = false
-
-// 预设字段头
-const prefix = 'HEHE_'
-
-// 缓存有效期 默认有效期为15天
-const expiredTime = 15 * 24 * 60 * 60 * 1000
-
-
-// 从缓存中读取数据(期限)
-export function setStorage(key, value, options = {}) {
-    if (!options.expiredTime) {
-        options.expiredTime = expiredTime
-    }
-    const nowTime = Date.now()
-    // 加密
-    if (encryptFlag) {
-        value = encrypt(value)
-    }
-    const payload = {
-        expiredTime: nowTime + options.expiredTime,
-        data: value
-    }
-    key = prefix + key
-    uni.setStorageSync(key, payload)
-}
-
-// 将数据添加到缓存中(期限)
-export function getStorage(key) {
-    key = prefix + key
-    const nowTime = Date.now()
-    const payload = uni.getStorageSync(key)
-    if (nowTime > payload.expiredTime) {
-        uni.removeStorageSync(key)
-        return null
-    }
-
-    // 解密
-    if (encryptFlag) {
-        payload.data = decrypt(payload.data)
-    }
-
-    return payload.data
-}
-
-const install = Vue => {
-    Vue.prototype.$setStorage = setStorage
-    Vue.prototype.$getStorage = getStorage
-}
-
-export default install

+ 0 - 89
common/uniapp.api.js

@@ -1,89 +0,0 @@
-export function toast(options) {
-    uni.showToast({
-        icon: options.icon || 'none',
-        mask: options.mask || true,
-        title: options.title || 'title'
-    })
-}
-toast.prototype.success = (message) => toast({ icon: 'success', title: message })
-toast.prototype.error = (message) => toast({ icon: 'error', title: message })
-
-const install = (Vue, options = {}) => {
-
-    const prefix = options.prefix || '/pages/views/'
-
-    /* tabbar 切换 */
-    const switchTab = (url, success, fail) => {
-        uni.switchTab({
-            url: `/pages/tabBar/${url}/${url}`,
-            success: success,
-            fail: fail
-        })
-    }
-
-    /* 保留当前页面跳转 */
-    const navigateTo = (url, success, fail) => {
-        uni.navigateTo({
-            url: `${prefix}${url}`,
-            success: success,
-            fail: fail
-        })
-    }
-
-    /* 关闭当前页面跳转 */
-    const redirectTo = (url, success, fail) => {
-        uni.redirectTo({
-            url: `${prefix}${url}`,
-            success: success,
-            fail: fail
-        })
-    }
-
-    /* 关闭所有页面跳转 */
-    const reLaunchTo = (url, success, fail) => {
-        uni.reLaunch({
-            url: `${prefix}${url}`,
-            success: success,
-            fail: fail
-        })
-    }
-
-    /* 关闭当前页面,返回上一页面或多级页面 */
-    const navigateBack = (delta, success, fail) => {
-        uni.navigateBack({
-            delta: delta || 1,
-            success: success,
-            fail: fail
-        })
-    }
-
-    /* 设置页面刷新标识 */
-    const addRefreshType = (mark = '') => {
-        uni.setStorageSync(`REFRESH_TYPE_${mark.toUpperCase()}`, true)
-    }
-
-    /* 获取页面刷新标识并判断是否需要刷新当前页面 */
-    const checkRefreshType = (mark = '') => {
-        const key = `REFRESH_TYPE_${mark.toUpperCase()}`
-        const type = uni.getStorageSync(key)
-        uni.removeStorageSync(key)
-        return type
-    }
-
-    Vue.prototype.$toast = (message) => toast({ title: message })
-    Vue.prototype.$toast.success = (message) => toast({ icon: 'success', title: message })
-    Vue.prototype.$toast.error = (message) => toast({ icon: 'error', title: message })
-
-    Vue.prototype.$router = {
-        switchTab,
-        navigateTo,
-        redirectTo,
-        reLaunchTo,
-        navigateBack,
-        addRefreshType,
-        checkRefreshType
-    }
-}
-
-
-export default install

+ 0 - 219
common/utils.js

@@ -1,219 +0,0 @@
-/**
- * @description 防抖
- * @param {Function} func 需要包装的函数
- * @param {string} wait 等待执行时间
- * @param {boolean} immediate 是否是立即执行 默认不立即执行
- * @returns {Function} 返回包装后的函数
- */
-export function debounce(func, wait, immediate = true) {
-    let timeout, result
-
-    return function() {
-        const context = this
-        const args = arguments
-        if (timeout) clearTimeout(timeout)
-        if (immediate) {
-            const callNow = !timeout
-            timeout = setTimeout(function() {
-                timeout = null
-            }, wait)
-            if (callNow) result = func.apply(context, args)
-        } else {
-            timeout = setTimeout(function() {
-                func.apply(context, args)
-            }, wait)
-        }
-        return result
-    }
-}
-
-
-/**
- * @description 节流
- * @param {Function} func 需要包装的函数
- * @param {string} wait 间隔时间
- * @returns {Function} 返回包装后的函数
- */
-export function throttle(func, wait) {
-    let timeout
-    return function() {
-        const context = this
-        const args = arguments
-        if (!timeout) {
-            timeout = setTimeout(function() {
-                timeout = null
-                func.apply(context, args)
-            }, wait)
-        }
-    }
-}
-
-
-/**
- * @description 深度克隆
- * @param {object} obj 克隆目标
- * @returns {object} 返回目标对象深度克隆后的结果
- */
-export function deepClone(obj, cache = new WeakMap()) {
-    if (typeof obj !== 'object') return obj // 普通类型,直接返回
-    if (obj === null) return obj
-    if (cache.get(obj)) return cache.get(obj) // 防止循环引用,程序进入死循环
-    if (obj instanceof Date) return new Date(obj)
-    if (obj instanceof RegExp) return new RegExp(obj)
-
-    // 找到所属原型上的constructor,所属原型上的constructor指向当前对象的构造函数
-    let cloneObj = new obj.constructor()
-    cache.set(obj, cloneObj) // 缓存拷贝的对象,用于处理循环引用的情况
-    for (let key in obj) {
-        if (obj.hasOwnProperty(key)) {
-            cloneObj[key] = deepClone(obj[key], cache) // 递归拷贝
-        }
-    }
-    return cloneObj
-}
-
-
-/** 
- * @description 时间日期格式化
- * @param {dateTime} date 标准时间格式 -> new Date()
- * @param {string} format 时间格式化的格式 'yyyy-MM-dd hh:mm:ss'
- * @returns {string} 格式化后的时间  '2017-01-01 01:00:00'
- */
-export function dateFormat(date = new Date(), format = 'yyyy-MM-dd hh:mm:ss') {
-    var o = {
-        'M+': date.getMonth() + 1, // month
-        'd+': date.getDate(), // day
-        'h+': date.getHours(), // hour
-        'm+': date.getMinutes(), // minute
-        's+': date.getSeconds(), // second
-        'q+': Math.floor((date.getMonth() + 3) / 3), // quarter
-        S: date.getMilliseconds(), // millisecond
-    }
-    if (/(y+)/.test(format)) {
-        format = format.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
-    }
-    for (var k in o) {
-        if (new RegExp('(' + k + ')').test(format)) {
-            format = format.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k])
-                .length))
-        }
-    }
-    return format
-}
-
-
-/**
- * @description 倒计时
- * @param diff 倒计时时间(s)
- * @param loadTime 运行时的当前时间(s)
- * @param item 倒计时对象 默认:{ speed: 1000 }
- * @param callback 回调
- */
-export function countDown(diff, loadTime, item, callback) {
-    function round($diff) {
-        let dd = parseInt($diff / 1000 / 60 / 60 / 24, 10) // 计算剩余的天数
-        let hh = parseInt(($diff / 1000 / 60 / 60) % 24, 10) // 计算剩余的小时数
-        let mm = parseInt(($diff / 1000 / 60) % 60, 10) // 计算剩余的分钟数
-        let ss = parseInt(($diff / 1000) % 60, 10) // 计算剩余的秒数
-
-        function checkTime(_a) {
-            let a = _a
-            if (a < 10) {
-                a = '0' + a
-            }
-            return a.toString()
-        }
-
-        item.conttainer = {
-            ddhh: checkTime(dd * 24 + hh),
-            dd: checkTime(dd),
-            hh: checkTime(hh),
-            mm: checkTime(mm),
-            ss: checkTime(ss)
-        }
-
-        if (
-            item.conttainer.dd > 0 ||
-            item.conttainer.hh > 0 ||
-            item.conttainer.mm > 0 ||
-            item.conttainer.ss > 0
-        ) {
-            item.t = setTimeout(function() {
-                round($diff - (item.speed || 1000))
-            }, item.speed || 1000)
-        }
-        // 回调
-        callback && callback(item)
-    }
-    round(diff - loadTime)
-}
-
-
-/* 对象循环赋值 */
-export function objAssign(target = {}, source = {}) {
-    for (let key in target) {
-        if (source.hasOwnProperty(key)) {
-            target[key] = source[key]
-        }
-    }
-}
-
-/* 数组去重 */
-export function arrayUnique(arr) {
-    if (!Array.isArray(arr)) {
-        console.log('type error!')
-        return
-    }
-    return Array.from(new Set(arr))
-}
-
-
-/*
- * 反序列化URL参数
- * { age: "25", name: "Tom" }
- */
-export function parseUrlSearch(location) {
-    return location.search
-        .replace(/(^\?)|(&$)/g, '')
-        .split('&')
-        .reduce((t, v) => {
-            const [key, val] = v.split('=')
-            t[key] = decodeURIComponent(val)
-            return t
-        }, {})
-}
-/*
- * getQueryParams('id')
- * 获取url上某个key的值
- */
-export function getParam(param) {
-    // 获取浏览器参数
-    const r = new RegExp(`\\?(?:.+&)?${param}=(.*?)(?:&.*)?$`)
-    const m = window.location.toString().match(r)
-    return m ? decodeURI(m[1]) : ''
-}
-/*
- * queryStringify
- * 将k-v的对象序列化转成 url?k=v&k1=v1;
- */
-export function queryStringify(search = {}) {
-    return Object.entries(search)
-        .reduce((t, v) => `${t}${v[0]}=${encodeURIComponent(v[1])}&`, '')
-        .replace(/&$/, '')
-}
-
-/*
- * queryStringify
- * 将url?k=v&k1=v1的序列化转成k-v对象
- */
-export function queryParse(query = '') {
-    if (query.startsWith('?')) {
-        query = query.slice(0)
-    }
-    const obj = Object.create(null)
-    query.split('&').forEach(str => {
-        const v = str.split('=')
-        obj[v[0]] = v[1]
-    })
-    return obj
-}

+ 0 - 92
common/validation.js

@@ -1,92 +0,0 @@
-/**
- * 是否是外部调用链接
- * @param {string} path
- * @returns {Boolean}
- */
-export function isExternal(path) {
-	return /^(https?:|mailto:|tel:)/.test(path)
-}
-
-/**
- * 是否是URL链接
- * @param {string} url
- * @returns {Boolean}
- */
-export function validURL(url) {
-	const reg =
-		/^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
-	return reg.test(url)
-}
-
-/**
- * 是否是小写字母
- * @returns {Boolean}
- */
-export function validLowerCase(str) {
-	const reg = /^[a-z]+$/
-	return reg.test(str)
-}
-
-/**
- * 是否是大写字母
- * @param {string} str
- * @returns {Boolean}
- */
-export function validUpperCase(str) {
-	const reg = /^[A-Z]+$/
-	return reg.test(str)
-}
-
-/**
- * 是否是英文
- * @param {string} str
- * @returns {Boolean}
- */
-export function validAlphabets(str) {
-	const reg = /^[A-Za-z]+$/
-	return reg.test(str)
-}
-
-/**
- * 是否是邮箱
- * @param {string} email
- * @returns {Boolean}
- */
-export function validEmail(email) {
-	const reg =
-		/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
-	return reg.test(email)
-}
-
-/**
- * 是否是手机号
- * @param {string} mobile
- * @returns {Boolean}
- */
-export function validMobile(mobile) {
-	return /^1[23456789]\d{9}$/.test(mobile)
-}
-
-/**
- * 是否是字符串
- * @param {string} str
- * @returns {Boolean}
- */
-export function isString(str) {
-	if (typeof str === 'string' || str instanceof String) {
-		return true
-	}
-	return false
-}
-
-/**
- * 是否是数组
- * @param {Array} arg
- * @returns {Boolean}
- */
-export function isArray(arg) {
-	if (typeof Array.isArray === 'undefined') {
-		return Object.prototype.toString.call(arg) === '[object Array]'
-	}
-	return Array.isArray(arg)
-}

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 7 - 0
components/clipboard/clipboard.min.js


+ 12 - 12
components/common/tui-clipboard/tui-clipboard.js → components/clipboard/clipboard.thorui.js

@@ -5,20 +5,22 @@
  * @version 1.0.0
  **/
 // #ifdef H5
-import ClipboardJS from "./clipboard.min.js"
+import ClipboardJS from "@/components/clipboard/clipboard.min.js"
 // #endif
 const thorui = {
-	/**
-	 * data 需要复制的数据
-	 * callback 回调
-	 * e 当用户点击后需要先请求接口再进行复制时,需要传入此参数,或者将异步请求转为同步 (H5端)
-	 * **/
-	getClipboardData: function(data,callback,e) {
+	getClipboardData: function(data, callback) {
 		// #ifdef APP-PLUS || MP
 		uni.setClipboardData({
 			data: data,
 			success(res) {
-				("function" == typeof callback) && callback(true)
+				uni.getClipboardData({
+					success(res) {
+						("function" == typeof callback) && callback(true)
+					},
+					fail(res) {
+						("function" == typeof callback) && callback(false)
+					}
+				})
 			},
 			fail(res) {
 				("function" == typeof callback) && callback(false)
@@ -27,7 +29,7 @@ const thorui = {
 		// #endif
 
 		// #ifdef H5
-		let event = window.event || e || {}
+		let event = window.event || {}
 		let clipboard = new ClipboardJS("", {
 			text: () => data
 		})
@@ -48,8 +50,6 @@ const thorui = {
 	}
 };
 
-export default {
+module.exports = {
 	getClipboardData: thorui.getClipboardData
 };
-
-

+ 267 - 0
components/clipboard/formValidation.js

@@ -0,0 +1,267 @@
+/**
+ * 表单验证
+ * @author dingyong
+ * @version 1.4.0
+ **/
+
+const form = {
+	//当出现错误时返回错误消息,否则返回空即为验证通过
+	/*
+	 formData:Object 表单对象。{key:value,key:value},key==rules.name
+	 rules: Array [{name:name,rule:[],msg:[]},{name:name,rule:[],msg:[]}]
+			name:name 属性=> 元素的名称
+			rule:字符串数组 ["required","isMobile","isEmail","isCarNo","isIdCard","isAmount","isNum","isChinese","isEnglish",isEnAndNo","isSpecial","isEmoji",""isDate","isUrl","isSame:key","range:[1,9]","minLength:9","maxLength:Number"]
+			msg:数组 []。 与数组 rule 长度相同,对应的错误提示信息
+	*/
+	validation: function(formData, rules) {
+		for (let item of rules) {
+			let key = item.name;
+			let rule = item.rule;
+			let msgArr = item.msg;
+			if (!key || !rule || rule.length === 0 || !msgArr || msgArr.length === 0) {
+				continue;
+			}
+			for (let i = 0, length = rule.length; i < length; i++) {
+				let ruleItem = rule[i];
+				let msg = msgArr[i];
+				if (!ruleItem || !msg) {
+					continue;
+				}
+				//数据处理
+				let value = null;
+				if (~ruleItem.indexOf(":")) {
+					let temp = ruleItem.split(":");
+					ruleItem = temp[0];
+					value = temp[1];
+				}
+				let isError = false;
+				switch (ruleItem) {
+					case "required":
+						isError = form._isNullOrEmpty(formData[key]);
+						break;
+					case "isMobile":
+						isError = !form._isMobile(formData[key]);
+						break;
+					case "isEmail":
+						isError = !form._isEmail(formData[key]);
+						break;
+					case "isCarNo":
+						isError = !form._isCarNo(formData[key]);
+						break;
+					case "isIdCard":
+						isError = !form._isIdCard(formData[key]);
+						break;
+					case "isAmount":
+						isError = !form._isAmount(formData[key]);
+						break;
+					case "isNum":
+						isError = !form._isNum(formData[key]);
+						break;
+					case "isChinese":
+						isError = !form._isChinese(formData[key]);
+						break;
+					case "isEnglish":
+						isError = !form._isEnglish(formData[key]);
+						break;
+					case "isEnAndNo":
+						isError = !form._isEnAndNo(formData[key]);
+						break;
+					case "isEnOrNo":
+						isError = !form._isEnOrNo(formData[key]);
+						break;
+					case "isSpecial":
+						isError = form._isSpecial(formData[key]);
+						break;
+					case "isEmoji":
+						isError = form._isEmoji(formData[key]);
+						break;
+					case "isDate":
+						isError = !form._isDate(formData[key]);
+						break;
+					case "isUrl":
+						isError = !form._isUrl(formData[key]);
+						break;
+					case "isSame":
+						isError = !form._isSame(formData[key], formData[value]);
+						break;
+					case "range":
+						let range = null;
+						try {
+							range = JSON.parse(value);
+							if (range.length <= 1) {
+								throw new Error("range值传入有误!")
+							}
+						} catch (e) {
+							return "range值传入有误!"
+						}
+						isError = !form._isRange(formData[key], range[0], range[1])
+						break;
+					case "minLength":
+						isError = !form._minLength(formData[key], value)
+						break;
+					case "maxLength":
+						isError = !form._maxLength(formData[key], value)
+						break;
+					default:
+						break;
+				}
+				if (isError) {
+					return msg;
+				}
+			}
+		}
+		return "";
+	},
+	_isNullOrEmpty: function(value) {
+		return (value === null || value === '' || value === undefined) ? true : false;
+	},
+	_isMobile: function(value) {
+		return /^(?:13\d|14\d|15\d|16\d|17\d|18\d|19\d)\d{5}(\d{3}|\*{3})$/.test(value);
+	},
+	_isEmail: function(value) {
+		return /^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/.test(value);
+	},
+	_isCarNo: function(value) {
+		// 新能源车牌
+		const xreg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/;
+		// 旧车牌
+		const creg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$/;
+		if (value.length === 7) {
+			return creg.test(value);
+		} else if (value.length === 8) {
+			return xreg.test(value);
+		} else {
+			return false;
+		}
+	},
+	_isIdCard: function(value) {
+		let idCard = value;
+		if (idCard.length == 15) {
+			return this.__isValidityBrithBy15IdCard;
+		} else if (idCard.length == 18) {
+			let arrIdCard = idCard.split("");
+			if (this.__isValidityBrithBy18IdCard(idCard) && this.__isTrueValidateCodeBy18IdCard(arrIdCard)) {
+				return true;
+			} else {
+				return false;
+			}
+		} else {
+			return false;
+		}
+	},
+	__isTrueValidateCodeBy18IdCard: function(arrIdCard) {
+		let sum = 0;
+		let Wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1];
+		let ValideCode = [1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2];
+		if (arrIdCard[17].toLowerCase() == 'x') {
+			arrIdCard[17] = 10;
+		}
+		for (let i = 0; i < 17; i++) {
+			sum += Wi[i] * arrIdCard[i];
+		}
+		let valCodePosition = sum % 11;
+		if (arrIdCard[17] == ValideCode[valCodePosition]) {
+			return true;
+		} else {
+			return false;
+		}
+	},
+	__isValidityBrithBy18IdCard: function(idCard18) {
+		let year = idCard18.substring(6, 10);
+		let month = idCard18.substring(10, 12);
+		let day = idCard18.substring(12, 14);
+		let temp_date = new Date(year, parseFloat(month) - 1, parseFloat(day));
+		if (temp_date.getFullYear() != parseFloat(year) || temp_date.getMonth() != parseFloat(month) - 1 || temp_date.getDate() !=
+			parseFloat(day)) {
+			return false;
+		} else {
+			return true;
+		}
+	},
+	__isValidityBrithBy15IdCard: function(idCard15) {
+		let year = idCard15.substring(6, 8);
+		let month = idCard15.substring(8, 10);
+		let day = idCard15.substring(10, 12);
+		let temp_date = new Date(year, parseFloat(month) - 1, parseFloat(day));
+
+		if (temp_date.getYear() != parseFloat(year) || temp_date.getMonth() != parseFloat(month) - 1 || temp_date.getDate() !=
+			parseFloat(day)) {
+			return false;
+		} else {
+			return true;
+		}
+	},
+	_isAmount: function(value) {
+		//金额,只允许保留两位小数
+		return /^([0-9]*[.]?[0-9])[0-9]{0,1}$/.test(value);
+	},
+	_isNum: function(value) {
+		//只能为数字
+		return /^[0-9]+$/.test(value);
+	},
+	_isChinese: function(value) {
+		let reg = /.*[\u4e00-\u9fa5]+.*$/;
+		return value !== "" && reg.test(value) && !form._isSpecial(value) && !form._isEmoji(value)
+	},
+	_isEnglish: function(value) {
+		return /^[a-zA-Z]*$/.test(value)
+	},
+	_isEnAndNo: function(value) {
+		//8~20位数字和字母组合
+		return /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,20}$/.test(value);
+	},
+	_isEnOrNo: function(value) {
+		//英文或者数字
+		let reg = /.*[\u4e00-\u9fa5]+.*$/;
+		let result = true;
+		if (reg.test(value) || form._isSpecial(value) || form._isEmoji(value)) {
+			result = false
+		}
+		return result
+	},
+	_isSpecial: function(value) {
+		//是否包含特殊字符
+		let regEn = /[`~!@#$%^&*()_+<>?:"{},.\/;'[\]]/im,
+			regCn = /[·!#¥(——):;“”‘、,|《。》?、【】[\]]/im;
+		if (regEn.test(value) || regCn.test(value)) {
+			return true;
+		}
+		return false;
+	},
+	_isEmoji: function(value) {
+		//是否包含表情
+		return /\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F]/g.test(value);
+	},
+	_isDate: function(value) {
+		//2019-10-12
+		const reg =
+			/^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$/;
+		return reg.test(value);
+	},
+	_isUrl: function(value) {
+		return /^((https?|ftp|file):\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/.test(value);
+	},
+	_isSame: function(value1, value2) {
+		return value1 === value2
+	},
+	_isRange: function(value, range1, range2) {
+		if ((!range1 && range1 != 0) && (!range2 && range2 != 0)) {
+			return true;
+		} else if (!range1 && range1 != 0) {
+			return value <= range2
+		} else if (!range2 && range2 != 0) {
+			return value >= range1
+		} else {
+			return value >= range1 && value <= range2
+		}
+	},
+	_minLength: function(value, min) {
+		return value.length >= Number(min)
+	},
+	_maxLength: function(value, max) {
+		return value.length <= Number(max)
+	}
+};
+module.exports = {
+	validation: form.validation
+};

+ 25 - 0
components/clipboard/utils.js

@@ -0,0 +1,25 @@
+const utils = {
+  getComponent: function(selector) {
+    const pages = getCurrentPages();
+    const current = pages[pages.length - 1];
+    //const component = current.selectAllComponents(selector);
+    const component = current.selectComponent(selector);
+    if (!component) {
+      return null;
+    }
+    return component;
+  },
+  toast: function(options) {
+    const {
+      //selector = '.tui-tips-ctx'
+      selector = '#tui-tips-ctx'
+    } = options;
+    const component = utils.getComponent(selector);
+    if (component) {
+      component.showTips(options);
+    }
+  }
+};
+module.exports = {
+  toast: utils.toast
+};

+ 107 - 0
components/cm-custom/au-custom.vue

@@ -0,0 +1,107 @@
+<template name="headerNavbar">
+	<!-- 自定义导航栏 -->
+	<view class='navbar-wrap' :style="{height:CustomBar+'px',paddingTop:StatusBar+'px'}"> 
+	  	<view class="navbar-text" 
+			  :style="{color:navbarData.textColor ? navbarData.textColor:'',lineHeight:(CustomBar - StatusBar)+'px;',fontSize:fontSizeSetting+'px;',paddingLeft:navbarData.textLeft ? '' : (capsule.height+10)+'px'}" :class="platformClass">
+	    	  {{navbarData.title ? navbarData.title : " "}}
+	  	</view>
+	  	<view class="navbar-icon" v-if="navbarData.showCapsule == 1 ? true : false" 
+			  :style="{color:navbarData.textColor ? navbarData.textColor:'',top:capsule.top +'px;',left:((screenWidth-capsule.right)+5)+'px;',height:capsule.height+'px;',lineHeight:capsule.height+'px;'}">
+			  <text v-if="navbarData.haveBack" @tap="BackPage" class="iconfont icon-fanhui"></text>
+	  	</view>
+	</view>
+</template>
+
+<script>
+	var self;
+	export default{
+		name:'headerNavbar',
+		props:{
+		    navbarData: { // 由父页面传递的数据
+				type: Object
+		    }
+		},
+		data() {
+			return{
+				CustomBar:this.CustomBar,// 顶部导航栏高度
+				StatusBar: this.StatusBar,
+				fontSizeSetting:this.fontSizeSetting,
+				screenWidth:this.screenWidth,
+				capsule:this.capsule,
+				platformClass:this.platformClass,
+			}
+		},
+		created() {
+			if (getCurrentPages().length === 1) { // 当只有一个页面时
+			      this.navbarData.haveBack = false;
+			} else {
+			      this.navbarData.haveBack = true;
+			}
+		},
+		onLoad(){
+			
+		},
+		methods:{
+			BackPage: function () {
+				this.$emit('navigateBack')
+		    },
+			_goSearchPath:function () {
+				this.$emit('goSearchPath')
+			},
+			_goHome:function(){
+				uni.switchTab({
+		        	url: '/pages/tabBar/home/index'
+		      	})
+			}
+		},
+		onShow(){
+	
+		}
+	}
+</script>
+
+<style lang="scss">
+	.navbar-wrap {
+		 position: fixed;
+		 width: 100%;
+		 top: 0;
+		 z-index: 100000;
+		 box-sizing: border-box;
+	}
+	.navbar-text {
+		 font-size: 30rpx;
+		 color: #000000;
+		 font-weight: 500;
+	}
+	.navbar-text.center{
+		text-align: center;
+	}
+	.navbar-text.left{
+		text-align: left;
+		padding-left: 45px;
+	}
+	.navbar-icon {
+		 position: fixed;
+		 display: flex;
+		 box-sizing: border-box;
+	}
+	.navbar-icon .iconfont {
+		 display: inline-block;
+		 overflow: hidden;
+		 font-size: 44rpx;
+		 padding-right:40rpx;
+		 margin-top: 1px;
+	}
+	.navbar-icon .icon-iconfonticonfontsousuo1 {
+		color: #000000;
+	}
+	.navbar-icon view {
+		 height: 18px;
+		 border-left: 0.5px solid rgba(0,0,0, 0.3);
+		 margin-top: 6px;
+	}
+	.navbar-loading {
+		 background: #fff;
+		 text-align: center;
+	}
+</style>

+ 122 - 0
components/cm-custom/cm-custom.vue

@@ -0,0 +1,122 @@
+<template name="headerNavbar">
+	<!-- 自定义导航栏 -->
+	<view class='navbar-wrap' :style="{height:CustomBar+'px',paddingTop:StatusBar+'px',background:navbarData.bgColor ? navbarData.bgColor : ''}"> 
+	  	<view class="navbar-text" 
+			  :style="{color:navbarData.textColor ? navbarData.textColor:'',lineHeight:(CustomBar - StatusBar)+'px;',fontSize:fontSizeSetting+'px;',paddingLeft:navbarData.textLeft ? '' : 12+'px'}" :class="platformClass">
+	    	  {{navbarData.title ? navbarData.title : " "}}
+	  	</view>
+	  	<view class="navbar-icon" v-if="navbarData.showCapsule == 1 ? true : false" 
+			  :style="{top:capsule.top +'px;',left:((screenWidth-capsule.right)+5)+'px;',height:capsule.height+'px;',lineHeight:capsule.height+'px;'}">
+			  <text v-if="navbarData.haveBack" @tap="BackPage" class="iconfont icon-fanhui"></text>
+			  <text v-if="navbarData.haveHome" @tap="_goHome" class="iconfont icon-shouye"></text>
+	  	</view>
+		<view class="navbar-icon" v-if="navbarData.showSearch == 1 ? true : false"
+			  :style="{top:capsule.top+'px;',right:(capsule.width)+'px;',height:capsule.height+'px;',lineHeight:capsule.height+'px;'}">
+			  <text @click.stop="_goSearchPath" class="iconfont icon-iconfonticonfontsousuo1"></text>
+	  	</view>
+	</view>
+</template>
+
+<script>
+	var self;
+	export default{
+		name:'headerNavbar',
+		props:{
+		    navbarData: { // 由父页面传递的数据
+				type: Object,
+				default: () =>({
+					showCapsule: 1, // 是否显示左上角图标  1表示显示  0表示不显示,
+					showSearch: 0,
+					title: '', // 导航栏 中间的标题
+					haveBack:false,
+					home:false,
+					textLeft:false,
+					bgColor:'',
+					textColor:'#000000'
+				})
+		    }
+		},
+		data() {
+			return{
+				CustomBar:this.CustomBar,// 顶部导航栏高度
+				StatusBar: this.StatusBar,
+				fontSizeSetting:this.fontSizeSetting,
+				screenWidth:this.screenWidth,
+				capsule:this.capsule,
+				platformClass:this.platformClass,
+			}
+		},
+		created() {
+			if (getCurrentPages().length === 1) { // 当只有一个页面时
+			      this.navbarData.haveBack = false;
+			} else {
+			      this.navbarData.haveBack = true;
+			}
+		},
+		onLoad(){
+			
+		},
+		methods:{
+			BackPage: function () {
+				this.$emit('navigateBack')
+		    },
+			_goSearchPath:function () {
+				this.$emit('goSearchPath')
+			},
+			_goHome:function(){
+				uni.switchTab({
+		        	url: '/pages/tabBar/home/index'
+		      	})
+			}
+		},
+		onShow(){
+	
+		}
+	}
+</script>
+
+<style lang="scss">
+	.navbar-wrap {
+		 position: fixed;
+		 width: 100%;
+		 top: 0;
+		 z-index: 100000;
+		 box-sizing: border-box;
+	}
+	.navbar-text {
+		 font-size: 30rpx;
+		 color: #000000;
+		 font-weight: 500;
+	}
+	.navbar-text.center{
+		text-align: center;
+	}
+	.navbar-text.left{
+		text-align: left;
+		padding-left: 45px;
+	}
+	.navbar-icon {
+		 position: fixed;
+		 display: flex;
+		 box-sizing: border-box;
+	}
+	.navbar-icon .iconfont {
+		 display: inline-block;
+		 overflow: hidden;
+		 font-size: 44rpx;
+		 padding-right:40rpx;
+		 margin-top: 1px;
+	}
+	.navbar-icon .icon-iconfonticonfontsousuo1 {
+		color: #000000;
+	}
+	.navbar-icon view {
+		 height: 18px;
+		 border-left: 0.5px solid rgba(0,0,0, 0.3);
+		 margin-top: 6px;
+	}
+	.navbar-loading {
+		 background: #fff;
+		 text-align: center;
+	}
+</style>

+ 148 - 0
components/cm-custom/cm-drag.vue

@@ -0,0 +1,148 @@
+<template>
+	<view>
+		<view
+			id="_drag_button"
+			class="cart-icon"
+			:style="'left: ' + left + 'px; top:' + top + 'px;'"
+			@touchstart="touchstart"
+			@touchmove.stop.prevent="touchmove"
+			@touchend="touchend"
+			@click.stop.prevent="click"
+			:class="{transition: isDock && !isMove }"
+		>
+			<text v-if="cartNum > 0" class="uni-badge uni-badge-error uni-small uni-badge--small icon-num">
+				{{cartNum >= 100 ? '99+' : cartNum}}
+			</text>
+			<image src='https://static.caimei365.com/app/img/icon/icon-cart-active@3x.png' mode="widthFix"></image>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'drag-button',
+		props: {
+			cartNum:{
+				type: Number,
+				default: 0
+			},
+			isDock:{
+				type: Boolean,
+				default: false
+			},
+			existTabBar:{
+				type: Boolean,
+				default: false
+			}
+		},
+		data() {
+			return {
+				top:300,
+				left:150,
+				width: 0,
+				height: 0,
+				offsetWidth: 0,
+				offsetHeight: 0,
+				windowWidth: 0,
+				windowHeight: 0,
+				isMove: true,
+				edge: 10,
+			}
+		},
+		mounted() {
+			const sys = uni.getSystemInfoSync();
+			this.windowWidth = sys.windowWidth;
+			this.windowHeight = sys.windowHeight;
+			// #ifdef APP-PLUS
+				this.existTabBar && (this.windowHeight -= 50);
+			// #endif
+			if (sys.windowTop) {
+				this.windowHeight += sys.windowTop;
+			}
+			// console.log(sys)
+			const query = uni.createSelectorQuery().in(this);
+			query.select('#_drag_button').boundingClientRect(data => {
+				this.width = data.width;
+				this.height = data.height;
+				this.offsetWidth = data.width / 2;
+				this.offsetHeight = data.height / 2;
+				this.left = this.windowWidth - this.width - this.edge-5;
+				this.top = this.windowHeight - this.height - this.edge-150;
+			}).exec();
+		},
+		methods: {
+			click() {
+				this.$emit('btnClick');
+			},
+			touchstart(e) {
+				this.$emit('btnTouchstart');
+			},
+			touchmove(e) {
+				// 单指触摸
+				if (e.touches.length !== 1) {
+					return false;
+				}
+				this.isMove = true;
+				this.left = e.touches[0].clientX - this.offsetWidth;
+				let clientY = e.touches[0].clientY - this.offsetHeight;
+				// #ifdef H5
+					clientY += this.height;
+				// #endif
+				let edgeBottom = this.windowHeight - this.height - this.edge;
+				// 上下触及边界
+				if (clientY < this.edge) {
+					this.top = this.edge;
+				} else if (clientY > edgeBottom) {
+					this.top = edgeBottom;
+				} else {
+					this.top = clientY
+				}
+			},
+			touchend(e) {
+				if (this.isDock) {
+					let edgeRigth = this.windowWidth - this.width - this.edge;
+					
+					if (this.left < this.windowWidth / 2 - this.offsetWidth) {
+						this.left = this.edge;
+					} else {
+						this.left = edgeRigth;
+					}
+					
+				}
+				
+				this.isMove = false;
+				this.$emit('btnTouchend');
+			},
+		}}
+</script>
+
+<style lang="scss">
+	.cart-icon {
+		width: 92rpx;
+		height: 92rpx;
+		border-radius: 50%;
+		background: $btn-confirm;
+		position: fixed;
+		right: 24rpx;
+		bottom: 28%;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		cursor: pointer;
+		z-index: 20;
+		image {
+			width: 58rpx;
+			height: 58rpx;
+		}
+		text {
+			font-size: 28rpx;
+			position: absolute;
+			top: -10rpx;
+			right: 0;
+		}
+		&.transition {
+			transition: left .3s ease,top .3s ease;
+		}
+	}
+	
+</style>

+ 114 - 0
components/cm-custom/cu-custom.vue

@@ -0,0 +1,114 @@
+<template name="headerNavbar">
+	<!-- 自定义导航栏 -->
+	<view class='navbar-wrap' :style="{height:CustomBar+'px',paddingTop:StatusBar+'px',background:navbarData.bgColor ? navbarData.bgColor : '#FFFFFF'}"> 
+	  	<view class="navbar-text" 
+			  :style="{color:navbarData.textColor ? navbarData.textColor:'',lineHeight:(CustomBar - StatusBar)+'px;',fontSize:fontSizeSetting+'px;',paddingLeft:navbarData.textLeft ? '' : (capsule.height+10)+'px'}" :class="platformClass">
+	    	  {{navbarData.title ? navbarData.title : " "}}
+	  	</view>
+	  	<view class="navbar-icon" v-if="navbarData.showCapsule == 1 ? true : false" 
+			  :style="{top:capsule.top +'px;',left:((screenWidth-capsule.right)+5)+'px;',height:capsule.height+'px;',lineHeight:capsule.height+'px;'}">
+			  <text v-if="navbarData.haveBack" @tap="BackPage" class="iconfont icon-fanhui"></text>
+			  <text v-if="navbarData.haveHome" @tap="_goHome" class="iconfont icon-shouye"></text>
+	  	</view>
+		<view class="navbar-icon" v-if="navbarData.showSearch == 1 ? true : false"
+			  :style="{top:capsule.top+'px;',right:(capsule.width)+'px;',height:capsule.height+'px;',lineHeight:capsule.height+'px;'}">
+			  <text @click.stop="_goSearchPath" class="iconfont icon-iconfonticonfontsousuo1"></text>
+	  	</view>
+	</view>
+</template>
+
+<script>
+	var self;
+	export default{
+		name:'headerNavbar',
+		props:{
+		    navbarData: { // 由父页面传递的数据
+				type: Object
+		    }
+		},
+		data() {
+			return{
+				CustomBar:this.CustomBar,// 顶部导航栏高度
+				StatusBar: this.StatusBar,
+				fontSizeSetting:this.fontSizeSetting,
+				screenWidth:this.screenWidth,
+				capsule:this.capsule,
+				platformClass:this.platformClass,
+			}
+		},
+		created() {
+			if (getCurrentPages().length === 1) { // 当只有一个页面时
+			      this.navbarData.haveBack = false;
+			} else {
+			      this.navbarData.haveBack = true;
+			}
+		},
+		onLoad(){
+			
+		},
+		methods:{
+			BackPage: function () {
+				this.$emit('navigateBack')
+		    },
+			_goSearchPath:function () {
+				this.$emit('goSearchPath')
+			},
+			_goHome:function(){
+				uni.switchTab({
+		        	url: '/pages/tabBar/home/index'
+		      	})
+			}
+		},
+		onShow(){
+	
+		}
+	}
+</script>
+
+<style lang="scss">
+	.navbar-wrap {
+		 position: fixed;
+		 width: 100%;
+		 top: 0;
+		 z-index: 100000;
+		 box-sizing: border-box;
+		 background: #FFFFFF;
+		 border-bottom: 1px solid #F7F7F7;
+	}
+	.navbar-text {
+		 font-size: 30rpx;
+		 color: #000000;
+		 font-weight: 500;
+	}
+	.navbar-text.center{
+		text-align: center;
+	}
+	.navbar-text.left{
+		text-align: left;
+		padding-left: 45px;
+	}
+	.navbar-icon {
+		 position: fixed;
+		 display: flex;
+		 box-sizing: border-box;
+	}
+	.navbar-icon .iconfont {
+		 display: inline-block;
+		 overflow: hidden;
+		 font-size: 40rpx;
+		 padding-right:40rpx;
+		 margin-top: 1px;
+	}
+	.navbar-icon .icon-iconfonticonfontsousuo1 {
+		color: #000000;
+	}
+	.navbar-icon view {
+		 height: 18px;
+		 border-left: 0.5px solid rgba(0,0,0, 0.3);
+		 margin-top: 6px;
+	}
+	.navbar-loading {
+		 background: #fff;
+		 text-align: center;
+	}
+</style>

+ 159 - 0
components/cm-custom/custom-d.vue

@@ -0,0 +1,159 @@
+<template name="headerNavbar">
+	<!-- 发货记录自定义导航栏 -->
+	<view class='navbar-wrap' :style="{height:navbarHeight+'px',paddingTop:statusBarHeight+'px'}"> 
+	  	<view class="navbar-text" :style="{lineHeight:(navbarHeight - statusBarHeight)+'px;',fontSize:fontSizeSetting+'px;'}">
+	    	{{navbarData.title ? navbarData.title : " "}}
+	  	</view>
+	  	<view class="navbar-icon" :style="{width:headerBtnPosi.width+'px',lineHeight:(navbarBtn.height)+'px',top:navbarBtn.top + statusBarHeight+'px',left:navbarBtn.right+'px',height:(navbarBtn.height)+'px'}">
+			  <text @click="_goBack" class="iconfont icon-shangyibu" :style="{width:headerBtnPosi.width/2+'px',height:navbarBtn.height+'px'}"></text>
+	      	  <text class="iconfont icon-vertical_line" :style="{borderColor:navbarData.borderColor ? navbarData.borderColor : 'rgba(0,0,0,0.4)'}"></text>
+			  <text @click="_goDetails" class="iconfont icon-shouye" :style="{width:headerBtnPosi.width/2+'px',height:navbarBtn.height+'px'}"></text>
+	  	</view>
+	</view>
+</template>
+
+<script>
+	var self;
+	export default{
+		name:'headerNavbar',
+		props:{
+		    navbarData: { // 由父页面传递的数据
+				type: Object
+		    },
+			systeminfo:{
+				type:Object
+			},
+			headerBtnPosi:{
+				type:Object
+			},
+			page:{
+				type:Number
+			}
+		},
+		data() {
+			return{
+				haveBack: true, // 是否有返回按钮,true 有 false 没有 若从分享页进入则为 false
+			    statusBarHeight: 0, // 状态栏高度
+			    navbarHeight: 0, // 顶部导航栏高度
+			    navbarBtn: { // 胶囊位置信息
+			      height: 0,
+			      width: 0,
+			      top: 0,
+			      bottom: 0,
+			      right: 0
+				},
+				platform:'',
+				fontSizeSetting:0,
+				screenWidth:0
+			}
+		},
+		created() {
+			this.fontSizeSetting = this.systeminfo.fontSizeSetting
+			let statusBarHeight = this.systeminfo.statusBarHeight // 状态栏高度
+			let headerPosi = this.headerBtnPosi // 胶囊位置信息
+		    /**
+		     * wx.getMenuButtonBoundingClientRect() 坐标信息以屏幕左上角为原点
+		     * 菜单按键宽度: 87
+		     * 菜单按键高度: 32
+		     * 菜单按键左边界坐标: 278
+		     * 菜单按键上边界坐标: 26
+		     * 菜单按键右边界坐标: 365
+		     * 菜单按键下边界坐标: 58
+		     */
+			let btnPosi = { // 胶囊实际位置,坐标信息不是左上角原点
+			      height: headerPosi.height,
+			      width: headerPosi.width,
+			      // 胶囊top - 状态栏高度
+			      top: headerPosi.top - statusBarHeight,
+			      // 胶囊bottom - 胶囊height - 状态栏height (现胶囊bottom 为距离导航栏底部的长度)
+			      bottom: headerPosi.bottom - headerPosi.height - statusBarHeight,
+			      // 屏幕宽度 - 胶囊right
+			      right: this.systeminfo.screenWidth - headerPosi.right
+			}
+			let haveBack;
+			if (getCurrentPages().length === 1) { // 当只有一个页面时
+			     haveBack = false;
+			} else {
+			     haveBack = true;
+			}
+		    this.haveBack=haveBack, // 获取是否是通过分享进入的小程序
+		    this.statusBarHeight=statusBarHeight,
+		    this.navbarHeight= headerPosi.bottom + btnPosi.bottom, // 原胶囊bottom + 现胶囊bottom
+		    this.navbarBtn=btnPosi
+		},
+		onLoad(){
+			
+		},
+		methods:{
+			_goBack: function () {
+		      	uni.navigateBack({
+		        	delta: this.page
+		      	});
+		    },
+		    _goDetails: function () {
+		      this.$emit('pageDetails')
+		    }
+		},
+		onShow(){
+	
+		}
+	}
+</script>
+
+<style lang="scss">
+	.navbar-wrap {
+		 position: fixed;
+		 width: 100%;
+		 top: 0;
+		 z-index: 9999;
+		 box-sizing: border-box;
+		 background: #FFFFFF;
+		 border-bottom: 1px solid #F8F8F8;
+	}
+	.navbar-text {
+		 text-align: center;
+		 color: #000000;
+		 font-weight: 500;
+	}
+	.navbar-icon {
+		 position: fixed;
+		 display: flex;
+		 border-radius: 64rpx;
+		 border: 0.5px solid rgba(0,0,0, 0.2);
+		 box-sizing: border-box;
+	}
+	.navbar-icon .iconfont {
+		 text-align: center;
+		 display: inline-block;
+		 overflow: hidden;
+		 margin-bottom: 1px;
+	}
+	.navbar-icon .icon-vertical_line {
+		color: #999999;
+	}
+	.navbar-loading {
+		 background: #fff;
+		 text-align: center;
+	}
+</style>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 221 - 0
components/cm-custom/custom-floor.vue

@@ -0,0 +1,221 @@
+<template name="headerNavbar">
+	<!-- 二级楼层导航栏 -->
+	<view class='navbar-wrap' :style="{height:navbarHeight+'px',paddingTop:statusBarHeight+'px'}"> 
+	  	<view class="navbar-icon" v-if="navbarData.showCapsule ? navbarData.showCapsule : true" 
+			  :style="{top:navbarBtn.top + statusBarHeight+'px;',lineHeight:navbarBtn.height+'px;',left:navbarBtn.right+'px;',width:navbarBtn.height+'px;',height:navbarBtn.height+'px;'}">
+			  <text v-if='haveBack' @click="_goBack" class="iconfont icon-fanhui"></text>
+			  <text v-else  @click="_goHome" class="iconfont icon-shouye"></text>
+	  	</view>
+		<view class="navbar-text" :style="{top:navbarBtn.top + statusBarHeight+'px;',height:navbarBtn.height+'px;',fontSize:fontSizeSetting+'px;'}">
+	    	<view class="gosearch-btn" :style="{paddingLeft:navbarBtn.height+'px;',right:(navbarBtn.width+20)+'px;',borderRadius:(navbarBtn.height/2)+'px;',width:(375-navbarBtn.width*2)+'px;',lineHeight:navbarBtn.height+'px;'}">
+				<text class="iconfont icon-sousuo" :style="{width:navbarBtn.height+'px;',height:navbarBtn.height+'px;',lineHeight:navbarBtn.height+'px;'}"></text>
+				<view class="input" @click="this.$api.navigateTo(clickPath)">搜索商品/项目仪器</view>
+			</view>
+	  	</view>
+	</view>
+</template>
+
+<script>
+	var self;
+	export default{
+		name:'headerNavbar',
+		props:{
+		    navbarData: { // 由父页面传递的数据
+				type: Object
+		    },
+			systeminfo:{
+				type:Object
+			},
+			headerBtnPosi:{
+				type:Object
+			},
+			page:{
+				type:Number,
+				default:1
+			},
+			headerTitle:{
+				type:String
+			},
+			type:{
+				type:String
+			},
+		},
+		data() {
+			return{
+				headerType:'',
+				clickPath:'/pages/search/search', 
+				haveBack: true, // 是否有返回按钮,true 有 false 没有 若从分享页进入则为 false
+			    statusBarHeight: 0, // 状态栏高度
+			    navbarHeight: 0, // 顶部导航栏高度,
+			    navbarBtn: { // 胶囊位置信息
+			      height: 0,
+			      width: 0,
+			      top: 0,
+			      bottom: 0,
+			      right: 0
+				},
+				platform:'',
+				fontSizeSetting:0
+			}
+		},
+		created() {
+			this.headerType = this.type
+			this.fontSizeSetting = this.systeminfo.fontSizeSetting
+			let statusBarHeight = this.systeminfo.statusBarHeight // 状态栏高度
+			let headerPosi = this.headerBtnPosi // 胶囊位置信息
+		    /**
+		     * wx.getMenuButtonBoundingClientRect() 坐标信息以屏幕左上角为原点
+		     * 菜单按键宽度: 87
+		     * 菜单按键高度: 32
+		     * 菜单按键左边界坐标: 278
+		     * 菜单按键上边界坐标: 26
+		     * 菜单按键右边界坐标: 365
+		     * 菜单按键下边界坐标: 58
+		     */
+			let btnPosi = { // 胶囊实际位置,坐标信息不是左上角原点
+			      height: headerPosi.height,
+			      width: headerPosi.width,
+			      // 胶囊top - 状态栏高度
+			      top: headerPosi.top - statusBarHeight,
+			      // 胶囊bottom - 胶囊height - 状态栏height (现胶囊bottom 为距离导航栏底部的长度)
+			      bottom: headerPosi.bottom - headerPosi.height - statusBarHeight,
+			      // 屏幕宽度 - 胶囊right
+			      right: this.systeminfo.screenWidth - headerPosi.right
+			}
+			console.log(btnPosi)
+			let haveBack;
+			if (getCurrentPages().length === 1) { // 当只有一个页面时
+			     haveBack = false;
+			} else {
+			     haveBack = true;
+			}
+		    this.haveBack=haveBack, // 获取是否是通过分享进入的小程序
+		    this.statusBarHeight=statusBarHeight,
+		    this.navbarHeight= headerPosi.bottom + btnPosi.bottom, // 原胶囊bottom + 现胶囊bottom
+			this.$parent.navbarHeight = this.navbarHeight
+			this.$parent.statusBarHeight = this.statusBarHeight
+			// console.log(this.navbarHeight);
+		    this.navbarBtn=btnPosi
+		},
+		onLoad(){
+			
+		},
+		methods:{
+			_goBack: function () {
+		      	uni.navigateBack({
+		        	delta: this.page
+		      	});
+		    },
+		    _goHome: function () {
+		      	uni.switchTab({
+		        	url: '/pages/tabBar/home/index'
+		      	})
+		    }
+		},
+		onShow(){
+	
+		}
+	}
+</script>
+
+<style lang="scss">
+	.navbar-wrap {
+		 position: fixed;
+		 width: 100%;
+		 top: 0;
+		 z-index: 100000;
+		 background-color: #FFFFFF;
+		 box-sizing: border-box;
+	}
+	.navbar-text {
+		 width: 100%;
+		 color: #000000;
+		 font-weight: 500;
+		 position: fixed;
+	}
+	.gosearch-btn{
+		height: 100%;
+		background: rgba(255, 255, 255, 0.6);
+		font-size: 28rpx;
+		color: #999999;
+		position: relative;
+		box-sizing: border-box;
+		position:absolute ;
+		top: 0;
+		border: 0.5px solid rgba(0, 0, 0, 0.1);
+		.icon-sousuo{
+			height: 100%;
+			text-align: center;
+			display: block;
+			position: absolute;
+			left: 0;
+			top: 0;
+			font-size: 34rpx;
+			color: #999999;
+			z-index: 10;
+		}
+		.input{
+			height: 100%;
+			float: left;
+			font-size: $font-size-24;
+			text-align: left;
+		}
+	}
+	.navbar-icon {
+		 position: fixed;
+		 display: flex;
+		 border-radius: 50%;
+		 text-align: center;
+		 background: rgba(255,255,255,0.6);
+		 box-sizing: border-box;
+		 z-index: 9999;
+	}
+	.navbar-icon .iconfont {
+		 height: 100%;
+		 width: 100%;
+		 font-size: 38rpx;
+		 font-weight: bold;
+		 display: inline-block;
+		 overflow: hidden;
+	}
+	.navbar-icon view {
+		 height: 18px;
+		 border-left: 0.5px solid rgba(0,0,0, 0.3);
+		 margin-top: 6px;
+	}
+	.navbar-loading {
+		 background: #fff;
+		 text-align: center;
+	}
+	@keyframes showColor {
+		0% {background: rgba(255,255,255,0);}
+		50% {background: rgba(255,255,255,0.5);}
+		100% {background: rgba(255,255,255,1);}
+	}
+	@keyframes hideColor {
+		0% {background: rgba(255,255,255,1);}
+		50% {background: rgba(255,255,255,0.5);}
+		100% {background: rgba(255,255,255,0);}
+	}
+</style>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 229 - 0
components/cm-custom/custom-p.vue

@@ -0,0 +1,229 @@
+<template name="headerNavbar">
+	<!-- 自定义导航栏 -->
+	<view class='navbar-wrap' :class="[headerColor? 'bg-color' : 'no-color']" :style="{height:navbarHeight+'px',paddingTop:statusBarHeight+'px'}"> 
+	  	<view class="navbar-icon" v-if="navbarData.showCapsule ? navbarData.showCapsule : true" 
+			  :style="{top:navbarBtn.top + statusBarHeight+'px;',lineHeight:navbarBtn.height+'px;',left:navbarBtn.right+'px;',width:navbarBtn.height+'px;',height:navbarBtn.height+'px;'}">
+			  <text v-if='haveBack' @click="_goBack" class="iconfont icon-fanhui"></text>
+			  <text v-else  @click="_goHome" class="iconfont icon-shouye"></text>
+	  	</view>
+		<view class="navbar-text" :style="{top:navbarBtn.top + statusBarHeight+'px;',height:navbarBtn.height+'px;',fontSize:fontSizeSetting+'px;'}">
+	    	<view class="gosearch-btn" :style="{paddingLeft:navbarBtn.height+'px;',right:(navbarBtn.width+20)+'px;',borderRadius:(navbarBtn.height/2)+'px;',width:(375-navbarBtn.width*2)+'px;',lineHeight:navbarBtn.height+'px;'}">
+				<text class="iconfont icon-sousuo" :style="{width:navbarBtn.height+'px;',height:navbarBtn.height+'px;',lineHeight:navbarBtn.height+'px;'}"></text>
+				<view class="input" @click="this.$api.navigateTo(clickPath)">搜索商品/项目仪器</view>
+			</view>
+	  	</view>
+	</view>
+</template>
+
+<script>
+	var self;
+	export default{
+		name:'headerNavbar',
+		props:{
+		    navbarData: { // 由父页面传递的数据
+				type: Object
+		    },
+			systeminfo:{
+				type:Object
+			},
+			headerBtnPosi:{
+				type:Object
+			},
+			page:{
+				type:Number
+			},
+			headerColor:{
+				type:Boolean
+			},
+			headerTitle:{
+				type:String
+			},
+			type:{
+				type:String
+			},
+		},
+		data() {
+			return{
+				headerType:'',
+				clickPath:'/pages/search/search', 
+				haveBack: true, // 是否有返回按钮,true 有 false 没有 若从分享页进入则为 false
+			    statusBarHeight: 0, // 状态栏高度
+			    navbarHeight: 0, // 顶部导航栏高度,
+			    navbarBtn: { // 胶囊位置信息
+			      height: 0,
+			      width: 0,
+			      top: 0,
+			      bottom: 0,
+			      right: 0
+				},
+				platform:'',
+				fontSizeSetting:0
+			}
+		},
+		created() {
+			this.headerType = this.type
+			this.fontSizeSetting = this.systeminfo.fontSizeSetting
+			let statusBarHeight = this.systeminfo.statusBarHeight // 状态栏高度
+			let headerPosi = this.headerBtnPosi // 胶囊位置信息
+		    /**
+		     * wx.getMenuButtonBoundingClientRect() 坐标信息以屏幕左上角为原点
+		     * 菜单按键宽度: 87
+		     * 菜单按键高度: 32
+		     * 菜单按键左边界坐标: 278
+		     * 菜单按键上边界坐标: 26
+		     * 菜单按键右边界坐标: 365
+		     * 菜单按键下边界坐标: 58
+		     */
+			let btnPosi = { // 胶囊实际位置,坐标信息不是左上角原点
+			      height: headerPosi.height,
+			      width: headerPosi.width,
+			      // 胶囊top - 状态栏高度
+			      top: headerPosi.top - statusBarHeight,
+			      // 胶囊bottom - 胶囊height - 状态栏height (现胶囊bottom 为距离导航栏底部的长度)
+			      bottom: headerPosi.bottom - headerPosi.height - statusBarHeight,
+			      // 屏幕宽度 - 胶囊right
+			      right: this.systeminfo.screenWidth - headerPosi.right
+			}
+			console.log(btnPosi)
+			let haveBack;
+			if (getCurrentPages().length === 1) { // 当只有一个页面时
+			     haveBack = false;
+			} else {
+			     haveBack = true;
+			}
+		    this.haveBack=haveBack, // 获取是否是通过分享进入的小程序
+		    this.statusBarHeight=statusBarHeight,
+		    this.navbarHeight= headerPosi.bottom + btnPosi.bottom, // 原胶囊bottom + 现胶囊bottom
+			this.$parent.navbarHeight = this.navbarHeight
+			this.$parent.statusBarHeight = this.statusBarHeight
+			// console.log(this.navbarHeight);
+		    this.navbarBtn=btnPosi
+		},
+		onLoad(){
+			
+		},
+		methods:{
+			_goBack: function () {
+		      	uni.navigateBack({
+		        	delta: this.page
+		      	});
+		    },
+		    _goHome: function () {
+		      	uni.switchTab({
+		        	url: '/pages/tabBar/home/index'
+		      	})
+		    }
+		},
+		onShow(){
+	
+		}
+	}
+</script>
+
+<style lang="scss">
+	.navbar-wrap {
+		 position: fixed;
+		 width: 100%;
+		 top: 0;
+		 z-index: 100000;
+		 box-sizing: border-box;
+		 &.bg-color{
+			animation: showColor 0.3s ease-in-out both;
+		 }
+		 &.no-color{
+		    animation: hideColor 0.3s ease-in-out both;
+		 }
+	}
+	.navbar-text {
+		 width: 100%;
+		 color: #000000;
+		 font-weight: 500;
+		 position: fixed;
+	}
+	.gosearch-btn{
+		height: 100%;
+		background: rgba(255, 255, 255, 0.6);
+		font-size: 28rpx;
+		color: #999999;
+		position: relative;
+		box-sizing: border-box;
+		position:absolute ;
+		top: 0;
+		border: 0.5px solid rgba(0, 0, 0, 0.1);
+		.icon-sousuo{
+			height: 100%;
+			text-align: center;
+			display: block;
+			position: absolute;
+			left: 0;
+			top: 0;
+			font-size: 34rpx;
+			color: #999999;
+			z-index: 10;
+		}
+		.input{
+			height: 100%;
+			float: left;
+			font-size: $font-size-24;
+			text-align: left;
+		}
+	}
+	.navbar-icon {
+		 position: fixed;
+		 display: flex;
+		 border-radius: 50%;
+		 text-align: center;
+		 background: rgba(255,255,255,0.6);
+		 border: 0.5px solid rgba(0,0,0, 0.1);
+		 box-sizing: border-box;
+		 z-index: 9999;
+	}
+	.navbar-icon .iconfont {
+		 height: 100%;
+		 width: 100%;
+		 font-size: 38rpx;
+		 font-weight: bold;
+		 display: inline-block;
+		 overflow: hidden;
+	}
+	.navbar-icon view {
+		 height: 18px;
+		 border-left: 0.5px solid rgba(0,0,0, 0.3);
+		 margin-top: 6px;
+	}
+	.navbar-loading {
+		 background: #fff;
+		 text-align: center;
+	}
+	@keyframes showColor {
+		0% {background: rgba(255,255,255,0);}
+		50% {background: rgba(255,255,255,0.5);}
+		100% {background: rgba(255,255,255,1);}
+	}
+	@keyframes hideColor {
+		0% {background: rgba(255,255,255,1);}
+		50% {background: rgba(255,255,255,0.5);}
+		100% {background: rgba(255,255,255,0);}
+	}
+</style>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 139 - 0
components/cm-module/activity/activity.vue

@@ -0,0 +1,139 @@
+<template>
+	<view>
+		<view class="tui-alert-class tui-alert-box" :class="[show?'tui-alert-show':'tui-alert-hide']"  @touchmove.stop.prevent="discard">
+			<image src="https://static.caimei365.com/app/img/icon/icon-coupon-alert@2x.png" mode="" @click.stop="handleClick"></image>
+			<text class="iconfont icon-2guanbi" @click.stop="handleClickCancel"></text>
+		</view>
+	</view> 
+</template>
+
+<script>
+	export default {
+		name:"tuiAlert",
+		props: {
+			//控制显示
+			show: {
+				type: Boolean,
+				default: false
+			},
+			//提示信息字体大小
+			size: {
+				type: Number,
+				default: 30
+			},
+			//提示信息字体颜色
+			color: {
+				type: String,
+				default: "#333"
+			},
+			//按钮字体颜色
+			btnColor: {
+				type: String,
+				default: "#EB0909"
+			},
+			btnText:{
+				type: String,
+				default: ""
+			},
+			//点击遮罩 是否可关闭
+			maskClosable: {
+				type: Boolean,
+				default: false
+			}
+		},
+		methods: {
+			handleClick(e) {
+				console.log(e);
+				if (!this.show) return;
+				this.$emit('click',false);
+			},
+			handleClickCancel() {
+				this.$emit('cancel',false);
+			},
+			discard(){
+				//丢弃
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.tui-alert-box {
+		width: 100%;
+		height: 100%;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		flex-direction: column;
+		position: fixed;
+		left: 0;
+		top: 100%;
+		opacity: 0;
+		background: rgba(0,0,0,.2);
+		z-index: 99999;
+		image{
+			width: 580rpx;
+			height: 802rpx;
+			margin-top: 100rpx;
+		}
+	}
+	.tui-alert-show {
+		top: 0;
+		opacity: 1;
+		// animation:rundtop 0.5s;
+	}
+	.tui-alert-hide{
+		top: 100%;
+		opacity: 0;
+		// animation:rundbottom 0.5s;
+	}
+	.icon-2guanbi{
+		display: block;
+		width: 100rpx;
+		height: 100rpx;
+		line-height: 100rpx;
+		text-align: center;
+		color: #FFFFFF;
+		position: absolute;
+		top: 25%;
+		right: 4%;
+		font-size: 52rpx;
+	}
+	.tui-alert-mask-show {
+		visibility: visible;
+		opacity: 1;
+	}
+	.tui-alert-btn {
+		width: 100%;
+		height: 90rpx;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		background-color: #fff;
+		box-sizing: border-box;
+		position: relative;
+		font-size: 32rpx;
+		line-height: 32rpx;
+	}
+	.tui-alert-btn-hover {
+		background-color: #f7f7f7;
+	}
+	.tui-alert-btn::before {
+		width: 100%;
+		content: "";
+		position: absolute;
+		border-top: 1rpx solid #E0E0E0;
+		-webkit-transform: scaleY(0.5);
+		transform: scaleY(0.5);
+		left: 0;
+		top: 0;
+	}
+	@keyframes rundtop{
+		0%{top: 100%;opacity: 0;}
+		100%{top:0;opacity: 1;}
+	}
+	@keyframes rundbottom{
+		0%{top: 0;opacity: 1;}
+		100%{top:100%;opacity: 0;}
+	}
+</style>

+ 256 - 0
components/cm-module/activity/activityBean.vue

@@ -0,0 +1,256 @@
+ <template>
+	<view>
+		<view class="tui-alert-class tui-alert-box" :class="[show?'tui-alert-show':'tui-alert-hide']"  @touchmove.stop.prevent="discard">
+			<template v-if="beansType == 12">
+				<view class="tui-alert-image">
+					<image :src="bgImagePath" mode=""></image>
+				</view>
+			</template>
+			<template v-else>
+				<view class="tui-alert-content" :style="{'background-image': 'url('+bgImagePath+')'}">
+					<view class="tui-alert-content-text">恭喜您获得采美豆!</view>
+					<view class="tui-alert-content-bean">
+						<view class="tui-alert-main">
+							<image class="tui-alert-icon" src="https://static.caimei365.com/app/img/icon/bean-icon@2x.png" mode=""></image>
+							<view class="tui-alert-text">
+								<text class="icon-add">+</text>
+								<text class="icon-text">{{ beanNumber }}</text>
+							</view>
+						</view>
+					</view>
+					<view class="tui-alert-content-tips">
+						<view class="tips">采美豆可抵扣运费</view>
+					</view>
+				</view>
+			</template>
+			<text class="iconfont icon-2guanbi" :style="{bottom :beansType == 12 ? '25%' : '10%'}" @click.stop="handleClickCancel"></text>
+		</view>
+	</view> 
+</template>
+
+<script>
+	export default {
+		name:'tuiAlert',
+		props: {
+			//控制显示
+			show: {
+				type: Boolean,
+				default: false
+			},
+			//提示信息字体大小
+			size: {
+				type: Number,
+				default: 30
+			},
+			//提示信息字体颜色
+			color: {
+				type: String,
+				default: '#333'
+			},
+			//按钮字体颜色
+			btnColor: {
+				type: String,
+				default: '#EB0909'
+			},
+			btnText:{
+				type: String,
+				default: ''
+			},
+			beansType:{//根据类型设置背景图片:1注册机构,2升级资质机构,3个人机构修改资料,4资质机构修改资料,5下单成功,6线上支付成功,7确认收货成功
+				type: Number,
+				default: 1
+			},
+			beanNumber:{//采美豆显示数量
+				type:Number,
+				default:100
+			}
+		},
+		data() {
+			return{
+				bgImagePath:'https://static.caimei365.com/app/img/icon/bean-icon-2@2x.png',
+			}
+		},
+		created() {
+			this.handInitType(this.beansType)
+		},
+		methods: {
+			handInitType(type){
+				this.bgImagePath = `https://static.caimei365.com/app/img/icon/bean-icon-${type}@2x.png`
+			},
+			handleClick(e) {
+				console.log(e)
+				if (!this.show) return
+				this.$emit('click',false)
+			},
+			handleClickCancel() {
+				this.$emit('cancel',false)
+			},
+			discard(){
+				//丢弃
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.tui-alert-box {
+		width: 100%;
+		height: 100%;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		flex-direction: column;
+		position: fixed;
+		left: 0;
+		top: 100%;
+		opacity: 0;
+		background: rgba(51,51,51,0.7);
+		z-index: 99999;
+	}
+	.tui-alert-show {
+		top: 0;
+		opacity: 1;
+		// animation:rundtop 0.5s;
+	}
+	.tui-alert-hide{
+		top: 100%;
+		opacity: 0;
+		// animation:rundbottom 0.5s;
+	}
+	.tui-alert-image{
+		width: 626rpx;
+		height: 532rpx;
+		position: absolute;
+		top: 0;
+		left: 0;
+		bottom: 0;
+		right: 0;
+		margin: auto;
+		image{
+			width: 626rpx;
+			height: 532rpx;
+			display: block;
+		}
+	}
+	.tui-alert-content{
+		width: 580rpx;
+		height: 790rpx;
+		position: absolute;
+		top: 0;
+		left: 0;
+		bottom: 0;
+		right: 0;
+		margin: auto;
+		box-sizing: border-box;
+		padding-top: 485rpx;
+		background-size: cover;
+		.tui-alert-content-text{
+			height: 118rpx;
+			line-height: 118rpx;
+			text-align: center;
+			width: 100%;
+			font-size: $font-size-36;
+			color: #333333;
+		}
+		.tui-alert-content-bean{
+			width: 100%;
+			height: 74rpx;
+			line-height: 74rpx;
+			box-sizing: border-box;
+			display: flex;
+			flex-direction: column;
+			align-items: center;
+			.tui-alert-main{
+				.tui-alert-icon{
+					width: 94rpx;
+					height: 74rpx;
+					display: block;
+					float: left;
+				}
+				.tui-alert-text{
+					color: $color-system;
+					line-height: 74rpx;
+					float: left;
+					.icon-add{
+						font-size:40rpx;
+						margin:0 15rpx;
+					}
+					.icon-text{
+						font-weight: bold;
+						font-size:48rpx;
+					}
+				}
+			}
+		}
+		.tui-alert-content-tips{
+			width: 100%;
+			height: 40rpx;
+			line-height: 40rpx;
+			margin-top: 41rpx;
+			box-sizing: border-box;
+			display: flex;
+			flex-direction: column;
+			align-items: center;
+			.tips{
+				width: 224rpx;
+				height: 40rpx;
+				background-color: rgba(226, 91, 28, 0.1);
+				border-radius: 36rpx;
+				line-height: 40rpx;
+				font-size: $font-size-24;
+				color: $color-system;
+				text-align: center;
+			}
+		}
+	}
+	.icon-2guanbi{
+		display: block;
+		width: 100rpx;
+		height: 100rpx;
+		line-height: 100rpx;
+		text-align: center;
+		color: #FFFFFF;
+		position: absolute;
+		bottom: 13%;
+		left: 50%;
+		font-size: 58rpx;
+		margin-left: -50rpx;
+	}
+	.tui-alert-mask-show {
+		visibility: visible;
+		opacity: 1;
+	}
+	.tui-alert-btn {
+		width: 100%;
+		height: 90rpx;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		background-color: #fff;
+		box-sizing: border-box;
+		position: relative;
+		font-size: 32rpx;
+		line-height: 32rpx;
+	}
+	.tui-alert-btn-hover {
+		background-color: #f7f7f7;
+	}
+	.tui-alert-btn::before {
+		width: 100%;
+		content: "";
+		position: absolute;
+		border-top: 1rpx solid #E0E0E0;
+		-webkit-transform: scaleY(0.5);
+		transform: scaleY(0.5);
+		left: 0;
+		top: 0;
+	}
+	@keyframes rundtop{
+		0%{top: 100%;opacity: 0;}
+		100%{top:0;opacity: 1;}
+	}
+	@keyframes rundbottom{
+		0%{top: 0;opacity: 1;}
+		100%{top:100%;opacity: 0;}
+	}
+</style>

+ 445 - 0
components/cm-module/cm-cart/cm-unit-popup.vue

@@ -0,0 +1,445 @@
+<template name="cm-parameter">
+	<!-- 相关规格 -->
+	<tui-bottom-popup :radius="true" :show="popupShow" @close="hidePopup()">
+		<view class="tui-popup-box clearfix">
+			<view class="tui-shopping-main" :style="{ paddingBottom: isIphoneX ? '68rpx' : '34rpx' }">
+				<view class="tui-sku-title">
+					<view class="tui-sku-image"> <image :src="skuProduct.image" mode=""></image> </view>
+					<view class="tui-sku-price">
+						<view class="sku-price-viw">
+							<view class="sku-price-text"
+								  :class="PromotionsFormat(skuProduct.promotions) || skuProduct.svipProductFlag == 1 ? 'none' : ''"
+							>
+								¥{{
+									(PromotionsFormat(skuProduct.promotions) || skuProduct.svipProductFlag == 1
+										? skuProduct.originalPrice
+										: skuProduct.price) | NumFormat
+								}}
+							</view>
+						</view>
+						<view class="sku-price-vip">
+							<view class="floor-item-act">
+								<view class="coupon-tags" v-if="skuProduct.couponsLogo">优惠券</view>
+								<template v-if="skuProduct.actStatus == 1 && skuProduct.promotions">
+									<view v-if="PromotionsFormat(skuProduct.promotions)" class="floor-tags">
+										{{ skuProduct.promotions.name }}
+										<text v-if="skuProduct.promotions != null && skuProduct.promotions.type != 3">
+											:¥{{
+												skuProduct.promotions == null
+													? '0.00'
+													: skuProduct.promotions.touchPrice | NumFormat
+											}}
+										</text>
+									</view>
+									<view v-else-if="skuProduct.promotions.type != 3" class="floor-tags">
+										{{ skuProduct.promotions.name }}
+									</view>
+								</template>
+								<template v-if="skuProduct.actStatus == null && skuProduct.ladderFlag == 1">
+									<view class="floor-tags">阶梯价格</view>
+								</template>
+								<template v-if="skuProduct.svipProductFlag == 1">
+									<view class="svip-tags">
+										<view class="tags" :class="{ none: vipFlag != 1 }">SVIP</view>
+										<view class="price" v-if="isShowVipFlag(skuProduct)">{{
+											skuProduct.svipPriceTag
+										}}</view>
+									</view>
+								</template>
+							</view>
+						</view>
+					</view>
+				</view>
+				<view class="tui-sku-unit">
+					<view class="sku-unit-h1">规格:</view>
+					<view class="sku-unit-li">
+						<view
+							class="unit-li"
+							v-for="(sku, index) in skuList"
+							@click="handleChoisSku(sku, index)"
+							:key="index"
+							:class="skuIndex === index ? 'active' : ''"
+						>
+							{{ sku.unit }} <text class="tips" v-if="sku.stock === 0">缺货</text>
+						</view>
+					</view>
+				</view>
+				<view class="sku-unit-nunbox">
+					<view class="sku-unit-nunbox" v-if="skuProduct.step === 2">
+						<view class="text">*该商品只能以起订量的整数倍购买</view>
+					</view>
+					<view class="sku-unit-nunbox-t">
+						<view class="sku-unit-nunbox-text">购买数量:</view>
+						<view class="sku-unit-nunbox-num">
+							<view class="number-box">
+								<view
+									class="iconfont icon-jianhao"
+									@click="skuChangNumberSub"
+								></view>
+								<input
+									class="btn-input"
+									type="number"
+									v-model="addParams.count"
+									maxlength="4"
+									@blur="skuChangNumberChange($event)"
+								/>
+								<view
+									class="iconfont icon-jiahao"
+									@click="skuChangNumberAdd"
+								></view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="tui-right-flex tui-popup-btn" :style="{ paddingBottom: isIphoneX ? '68rpx' : '34rpx' }">
+				<view class="tui-modal-flex">
+					<view class="tui-modal-button cancel" @click="hidePopup">取消</view>
+					<view class="tui-modal-button confirm" :class="isBtnDisable ? 'disabled' :''" @click="handleConfirm">确定</view>
+				</view>
+			</view>
+		</view>
+	</tui-bottom-popup>
+</template>
+
+<script>
+import { mapState, mapMutations } from 'vuex'
+import uniGrader from '@/components/uni-grade/uni-grade.vue'
+export default {
+	name: 'cm-unit-popup',
+	components: {
+		uniGrader
+	},
+	props: {
+		skuProduct: {
+			type: Object
+		},
+		popupShow: {
+			type: Boolean,
+			default: false
+		},
+		type: {
+			type: Number,
+			default: 1
+		}
+	},
+	data() {
+		return {
+			isBtnDisable:false,
+			vipFlag: 0, // 是否是超级会员 0否 1是
+			skuIndex: 0,
+			number: 0,
+			ladderPriceList: [],
+			isQuantity: false,
+			skuList: [],
+			handleStock:0,// 规格库存
+			handleMinNumber:1, // 规格起订量
+			addParams:{
+				oldSkuId:0,
+				newSkuId:0,
+				count:0,
+				productId:0,
+				userId:0,
+				source:1
+			},
+		}
+	},
+	filters: {
+		NumFormat(value) {
+			//处理金额
+			return Number(value).toFixed(2)
+		}
+	},	
+	created() {
+		this.skuList = this.skuProduct.skus
+		this.addParams.productId = this.skuProduct.productId
+		this.addParams.oldSkuId = this.skuProduct.skuId
+		this.addParams.count = this.skuList[0].minBuyNumber
+		this.handleMinNumber = this.skuList[0].minBuyNumber
+		this.handleStock = this.skuList[0].stock
+		this.skuProduct.price = this.skuList[0].price;
+		this.isBtnDisable = this.skuList[0].stock === 0;
+		this.initData()
+	},
+	computed: {
+		...mapState(['hasLogin'])
+	},
+	methods: {
+		async initData(data) {
+			const userInfo = await this.$api.getStorage()
+			this.vipFlag = userInfo.vipFlag ? userInfo.vipFlag : 0
+			this.addParams.userId = userInfo.userId ? userInfo.userId : 0
+			this.userIdentity = userInfo.userIdentity ? userInfo.userIdentity : 0
+		},
+		PromotionsFormat(promo) {
+			//促销活动类型数据处理
+			if (promo != null) {
+				if (promo.type == 1 && promo.mode == 1) {
+					return true
+				} else {
+					return false
+				}
+			}
+			return false
+		},
+		isShowVipFlag(pros) {
+			// 未登录 || 非会员
+			if (!this.hasLogin || !this.vipFlag === 1) return false
+			// 商品所有机构可见
+			if (pros.priceFlag === 0) return true
+			// 商品价格仅资质机构可见
+			if (pros.priceFlag === 2 && this.userIdentity === 2) return true
+			// 商品价格仅医美机构可见
+			if (pros.priceFlag === 3 && this.userIdentity === 2 && this.firstClubType == 1) return true
+			// 其它
+			return false
+		}, 
+		skuChangNumberSub() {// 减数
+			if ( this.addParams.count <= this.handleMinNumber) {
+				this.addParams.count = this.handleMinNumber
+			} else {
+				if (this.skuProduct.step == 2) {
+					this.addParams.count -= this.handleMinNumber
+				} else {
+					this.addParams.count--
+				}
+			}
+		},
+		skuChangNumberAdd() {// 加数
+			if(this.addParams.count === this.handleStock){ return }
+			if (this.skuProduct.step === 2) {
+				this.addParams.count += this.handleMinNumber;
+			} else {
+				this.addParams.count++;
+			}
+		},
+		skuChangNumberChange() {// 修改
+			if (this.addParams.count < this.handleMinNumber || this.addParams.count % this.handleMinNumber != 0) {
+				this.addParams.count = this.handleMinNumber;
+			}else if(this.addParams.count > this.handleStock) {
+				this.addParams.count = this.handleStock;
+			}
+		},
+		handleConfirm() {
+			if(this.isBtnDisable){ return }
+			this.$emit('skuBtnConfirm', this.addParams)
+			this.$parent.popupShow2 = false
+		},
+		handleChoisSku(sku, index) {
+			// 选择SKU
+			this.skuIndex = index
+			this.addParams.newSkuId = sku.skuId;
+			this.addParams.count = sku.minBuyNumber;
+			this.handleStock = sku.stock;
+			this.handleMinNumber = sku.minBuyNumber;
+			this.skuProduct.price = sku.price;
+			this.skuProduct.originalPrice = sku.originalPrice;
+			this.isBtnDisable = sku.stock === 0;
+		},
+		hidePopup() {
+			this.$parent.popupShow2 = false
+		}
+	}
+}
+</script>
+
+<style lang="scss">
+.tui-popup-box {
+	padding: 40rpx 24rpx 0 24rpx;
+}
+.tui-shopping-main {
+	width: 100%;
+	.tui-sku-title {
+		width: 100%;
+		height: 136rpx;
+		float: left;
+		margin-bottom: 30rpx;
+		.tui-sku-image {
+			width: 138rpx;
+			height: 138rpx;
+			float: left;
+			border-radius: 8rpx;
+			margin-right: 30rpx;
+			box-sizing: border-box;
+			border: 1px dashed #e1e1e1;
+			image {
+				width: 134rpx;
+				height: 134rpx;
+				border-radius: 10rpx;
+			}
+		}
+		.tui-sku-price {
+			height: 136rpx;
+			float: left;
+			.sku-price-viw {
+				width: 100%;
+				height: 40rpx;
+				margin-bottom: 24rpx;
+				.sku-price-text {
+					font-size: 28rpx;
+					line-height: 40rpx;
+					color: #f94b4b;
+					font-weight: bold;
+					.sku-price-l{
+						float: left;
+						font-weight: normal;
+					}
+					&.none {
+						text-decoration: line-through;
+						color: #999999;
+						font-weight: normal;
+					}
+				}
+			}
+			.sku-price-vip {
+				width: 100%;
+				height: 40rpx;
+			}
+		}
+	}
+	.tui-sku-unit {
+		width: 100%;
+		height: auto;
+		float: left;
+		.sku-unit-h1 {
+			font-size: 28rpx;
+			line-height: 40rpx;
+			color: #333333;
+			font-weight: bold;
+		}
+		.sku-unit-li {
+			width: 100%;
+			height: auto;
+			.unit-li {
+				padding: 0 24rpx;
+				line-height: 48rpx;
+				text-align: center;
+				font-size: 24rpx;
+				color: #666666;
+				background: #f5f5f5;
+				float: left;
+				margin-right: 16rpx;
+				margin-top: 12rpx;
+				margin-bottom: 12rpx;
+				border-radius: 24rpx;
+				position: relative;
+				box-sizing: border-box;
+				border: 1px solid #f5f5f5;
+				&.active {
+					border-color: $color-system;
+					background: #fff1eb;
+					color: $color-system;
+					.tips {
+						background: #F3B574;
+					}
+				}
+				.tips {
+					padding: 0 10rpx;
+					line-height: 32rpx;
+					text-align: center;
+					font-size: 22rpx;
+					color: #ffffff;
+					background: #cccccc;
+					float: left;
+					border-radius: 16rpx;
+					position: absolute;
+					right: -12rpx;
+					top: -15rpx;
+				}
+			}
+		}
+	}
+	.sku-unit-nunbox {
+		justify-content: space-between;
+		align-items: center;
+		width: 100%;
+		height: auto;
+		float: left;
+		margin-top: 30rpx; 
+		.sku-unit-nunbox-t {
+			width: 100%;
+			height: 44rpx;
+			position: relative;
+			margin-bottom: 20rpx;
+			.text {
+				font-size: $font-size-24;
+				line-height: 48rpx;
+				color: #999999;
+			}
+			.sku-unit-nunbox-text {
+				line-height: 44rpx;
+				font-size: $font-size-28;
+				float: left;
+				font-weight: bold;
+			}
+			.sku-unit-nunbox-num{
+				float: right;
+				.number-box {
+					display: flex;
+					justify-content: center;
+					align-items: center;
+					border: 2rpx solid #ffe6dc;
+					border-radius: 30rpx;
+					height: 48rpx;
+					margin-left: 20rpx;
+					.iconfont {
+						font-size: $font-size-24;
+						padding: 0 18rpx;
+						color: #999999;
+						text-align: center;
+						line-height: 48rpx;
+						font-weight: bold;
+						background: #fef6f3;
+						&.icon-jianhao {
+							border-radius: 30rpx 0 0 30rpx;
+						}
+						&.icon-jiahao {
+							border-radius: 0 30rpx 30rpx 0;
+						}
+					}
+					.btn-input {
+						width: 62rpx;
+						height: 48rpx;
+						line-height: 48rpx;
+						background: #ffffff;
+						border-radius: 4rpx;
+						text-align: center;
+						font-size: $font-size-28;
+					}
+				}
+			}
+		}
+	}
+}
+.tui-popup-btn{
+	width: 100%;
+	float: left;
+	.tui-modal-flex {
+		width: 100%;
+		height: 84rpx;
+		margin-top: 40rpx;
+		display: flex;
+		.tui-modal-button {
+			flex: 1;
+			line-height: 84rpx;
+			font-size: $font-size-28;
+			text-align: center;
+			border-radius: 42rpx;
+			padding: 0;
+			margin: 0 15rpx;
+			box-sizing: border-box;
+			&.cancel {
+				background: #ffe6dc;
+				color: #F3B574;
+			}
+			&.confirm {
+				background: $btn-confirm;
+				color: #ffffff;
+				&.disabled {
+					background: linear-gradient(135deg, rgba(242, 143, 49, 0.5) 0%, rgba(225, 86, 22, 0.5) 100%);
+				}
+			}
+		}
+	}
+}
+</style>

+ 2516 - 0
components/cm-module/cm-cart/index.vue

@@ -0,0 +1,2516 @@
+<template name="navbars">
+	<view>
+		<tui-skeleton
+			v-if="skeletonShow"
+			backgroundColor="#fafafa"
+			borderRadius="10rpx"
+			:isLoading="true"
+			:loadingType="5"
+		></tui-skeleton>
+		<view class="container-cart-main tui-skeleton" :style="{ paddingTop: isshowDelbtn ? '0rpx' : '80rpx' }">
+			<template v-if="pathType == 0">
+				<view class="foot-check-delbtn" v-if="!isshowDelbtn && goodsList.length > 0">
+					<view class="foot-text"
+						>共<text>{{ kindCount }}</text
+						>件商品</view
+					>
+					<view class="delBtn" @tap.stop="showDelManager">删除</view>
+				</view>
+			</template>
+			<template v-else>
+				<view
+					class="foot-check-delbtn"
+					v-if="!isshowDelbtn && goodsList.length > 0"
+					:style="{ top: CustomBar + 'px' }"
+				>
+					<view class="foot-text"
+						>共<text>{{ kindCount }}</text
+						>件商品</view
+					>
+					<view class="delBtn" @tap.stop="showDelManager">删除</view>
+				</view>
+			</template>
+			<view v-if="!isEmpty" class="container-cart">
+				<view class="cart-content" :style="{ paddingBottom: isIphoneX ? '130rpx' : '100rpx' }">
+					<view class="goods-list">
+						<view v-for="(item, index) in goodsList" :key="index" class="goods-item clearfix">
+							<view class="shoptitle">
+								<!--选择商店的全部商品"-->
+								<view class="checkbox-box" @click.stop="handleCheckShop(item)">
+									<view
+										class="checkbox iconfont"
+										:style="{color : item.isDisable ? '#efefef' : ''}"
+										:class="[item.isChecked ? 'icon-yixuanze' : 'icon-weixuanze']"
+									></view>
+								</view>
+								<view v-if="item.promotions" class="floor-item-act">
+									<view class="floor-tags" @click.stop="clickPopupShow(item, 2)">{{
+										item.promotions.name
+									}}</view>
+								</view>
+								<view class="text" @click.stop="goSuppile(item)">{{ item.shopName }} </view>
+								<view class="text-coupon" @click="showPopup(0, item)" v-if="item.couponsLogo"
+									>领券</view
+								>
+							</view>
+							<view class="productlist">
+								<view class="goods-pros" v-for="(pros, idx) in item.cartList" :key="idx">
+									<view class="goods-pros-t">
+										<!--选择商品-->
+										<view class="checkbox-box" @click.stop="handlsCkecdPros(item, pros)">
+											<view
+												class="checkbox iconfont"
+												:style="{color : pros.isDisable ? '#EFEFEF' : ''}"
+												:class="[pros.isChecked ? 'icon-yixuanze' : 'icon-weixuanze']"
+											></view>
+										</view>
+										<view class="pros-img" @click.stop="navToListPage(pros.productId)"
+											><image :src="pros.image ? pros.image : ''" alt="" /><view
+												class="pros-type"
+												v-if="pros.productType == 2"
+												>医疗器械</view
+											>
+										</view>
+										<view class="pros-product">
+											<view class="producttitle" @click.stop="navToListPage(pros.productId)">{{
+												pros.name
+											}}</view>
+											<view class="productspec">规格:{{ pros.unit ? pros.unit : '' }}</view>
+											<template v-if="pros.number > pros.stock || pros.stock === 0">
+												<view class="cart-sku-temp" @click.stop="handleShouUnitPopup(pros)">
+													<view class="cart-sku-text">重新选择商品规格</view>
+													<view class="cart-sku-btn">重选</view>
+												</view>	
+											</template>
+											<template v-else>
+												<view class="productprice">
+													<!--使用过滤器对总价改变-->
+													<view
+														class="price"
+														:class="
+															PromotionsFormat(pros.promotions) ||
+															(pros.svipProductFlag == 1 && vipFlag == 1)
+																? 'disabled'
+																: ''
+														"
+													>
+														<text>¥</text>
+														{{
+															(PromotionsFormat(pros.promotions) || pros.svipProductFlag == 1
+																? pros.originalPrice
+																: pros.price) | NumFormat
+														}}
+													</view>
+													<view
+														class="count"
+														v-if="pros.validFlag == 2"
+														:class="[isshowDelbtn ? 'none' : 'show']"
+													>
+														<text class="count-tips" v-if="pros.number < pros.min"
+															>起订量:{{ pros.min }}</text
+														>
+														<text class="count-tips step" v-if="pros.isStep"
+															>购买量必须为起订量的整数倍</text
+														>
+														<view class="number-box">
+															<view
+																class="iconfont icon-jianhao"
+																@click="changeCountSub(item, pros)"
+															></view>
+															<input
+																class="btn-input"
+																type="number"
+																maxlength="4"
+																v-model="pros.number"
+																@blur="changeNnmber($event, item, pros)"
+																@focus="changeInput(pros)"
+															/>
+															<view
+																class="iconfont icon-jiahao"
+																@click="changeCountAdd(item, pros)"
+															></view>
+														</view>
+													</view>
+												</view>
+												<view class="floor-item-act">
+													<template v-if="pros.actStatus == 1 && pros.promotions">
+														<view
+															v-if="PromotionsFormat(pros.promotions)"
+															class="floor-tags"
+															@click.stop="clickPopupShow(pros, 1)"
+														>
+															{{ pros.promotions.name }}
+															<text
+																v-if="pros.promotions != null && pros.promotions.type != 3"
+															>
+																:¥{{
+																	pros.promotions == null
+																		? '0.00'
+																		: pros.promotions.touchPrice | NumFormat
+																}}
+															</text>
+														</view>
+														<view
+															v-else-if="pros.promotions.type != 3"
+															class="floor-tags"
+															@click.stop="clickPopupShow(pros, 2)"
+														>
+															{{ pros.promotions.name }}
+														</view>
+													</template>
+													<template v-if="pros.actStatus == null && pros.ladderFlag == 1">
+														<view class="floor-tags" @click.stop="clickPopupShow(pros, 2)"
+															>阶梯价格</view
+														>
+													</template>
+													<template v-if="pros.svipProductFlag == 1">
+														<view class="svip-tags">
+															<view class="tags" :class="{ none: vipFlag != 1 }">SVIP</view>
+															<view class="price" v-if="isShowVipFlag(pros)">{{
+																pros.svipPriceTag
+															}}</view>
+														</view>
+													</template>
+												</view>
+											</template>
+										</view>
+									</view>
+								</view>
+							</view>
+							<view class="goods-pros-b clearfix" :class="[isshowDelbtn ? 'none' : 'show']">
+								<view class="sum-none" v-if="item.reducedPrice > 0">
+									<text class="money-sign">¥</text>
+									<text class="money">{{ item.totalOriginalPrice | NumFormat }}</text>
+									<text class="money-reduced"
+										>减<text>¥{{ item.reducedPrice | NumFormat }}</text></text
+									>
+								</view>
+								<view class="sum"
+									>合计:<text class="money"
+										><text class="money-sign">¥</text>{{ item.totalPrice | NumFormat }}</text
+									></view
+								>
+							</view>
+						</view>
+					</view>
+					<view class="failure-list" v-if="failureList.length > 0">
+						<view class="failure-title">
+							<view class="title-txt"
+								>失效商品<text>{{ failureList.length }}件</text></view
+							>
+							<view class="title-btn" @click.stop="handleDeletefailures"
+								><text class="butto">清空失效商品</text></view
+							>
+						</view>
+						<view class="productlist">
+							<view class="goods-pros" v-for="(failure, failureIdx) in failureList" :key="failureIdx">
+								<view class="goods-pros-t" @click.stop="failureToProduct(failure)">
+									<!--选择商品-->
+									<view
+										class="checkbox-box"
+										@click.stop="handleCheckFailure(failure)"
+										v-if="isshowDelbtn"
+									>
+										<button
+											class="checkbox iconfont"
+											:class="[failure.isChecked ? 'icon-yixuanze' : 'icon-weixuanze']"
+										></button>
+									</view>
+									<text class="img-tip">失效</text>
+									<view class="pros-img">
+										<image :src="failure.image ? failure.image : ''" alt="" />
+										<view class="pros-type" v-if="failure.productType == 2">医疗器械</view>
+									</view>
+									<view class="pros-product">
+										<view class="producttitle">{{ failure.name }}</view>
+										<view class="productspec">规格:{{ failure.unit ? failure.unit : '' }}</view>
+										<view class="productstate">{{ failureStateText(failure.status) }}</view>
+									</view>
+									<view class="pros-marks" v-if="failure.isFailureLayer"></view>
+								</view>
+							</view>
+						</view>
+					</view>
+				</view>
+				<!-- 脚部菜单 -->
+				<template v-if="pathType == 0">
+					<view class="footer">
+						<view class="footer-le">
+							<view class="foot-check checkbox-box" @tap.stop="handleCheckAll">
+								<button
+									class="checkbox iconfont"
+									:class="[isCheckAll ? 'icon-yixuanze' : 'icon-weixuanze']"
+								></button>
+								<view class="text">全选</view>
+							</view>
+
+							<view class="sum">
+								<view class="sum-price" :class="isDiscount ? '' : 'none'">
+									总价:<text class="money-sign">¥</text
+									><text class="money">{{ (allPrice - couponPrice) | NumFormat }}</text>
+								</view>
+								<view class="sum-none" v-if="isDiscount">
+									<text class="money-reduced"
+										>共减<text>¥{{ totalDiscountAmount | NumFormat }}</text></text
+									>
+									<text class="money-popup" @click="showPopup(1)"
+										>优惠明细<text class="iconfont icon-xiangshangjiantou"></text
+									></text>
+								</view>
+							</view>
+						</view>
+						<view v-if="!isshowDelbtn" class="footer-ri">
+							<view class="btn hanld-btn" @tap="hanldlerToConfirm">去结算({{ allCount }})</view>
+						</view>
+						<view v-else class="footer-del">
+							<view class="btn btn-cancel" @tap.stop="hideDelManage">取消</view>
+							<view class="btn btn-confirm" @tap.stop="handleDeleteCart">删除</view>
+						</view>
+					</view>
+				</template>
+				<template v-else>
+					<view class="footer" :style="{ paddingBottom: isIphoneX ? '68rpx' : '0rpx' }">
+						<view class="footer-le">
+							<view class="foot-check checkbox-box" @tap.stop="handleCheckAll">
+								<button
+									class="checkbox iconfont"
+									:class="[isCheckAll ? 'icon-yixuanze' : 'icon-weixuanze']"
+								></button>
+								<view class="text">全选</view>
+							</view>
+							<view class="sum">
+								<view class="sum-price" :class="isDiscount ? '' : 'none'">
+									总价:<text class="money-sign">¥</text
+									><text class="money">{{ (allPrice - couponPrice) | NumFormat }}</text>
+								</view>
+								<view class="sum-none" v-if="isDiscount">
+									<text class="money-reduced"
+										>共减<text>¥{{ totalDiscountAmount | NumFormat }}</text></text
+									>
+									<text class="money-popup" @click="showPopup(1)"
+										>优惠明细<text class="iconfont icon-xiangshangjiantou"></text
+									></text>
+								</view>
+							</view>
+						</view>
+						<view v-if="!isshowDelbtn" class="footer-ri">
+							<view class="btn hanld-btn" @tap="hanldlerToConfirm">去结算({{ allCount }})</view>
+						</view>
+						<view v-else class="footer-del">
+							<view class="btn btn-cancel" @tap.stop="hideDelManage">取消</view>
+							<view class="btn btn-confirm" @tap.stop="handleDeleteCart">删除</view>
+						</view>
+					</view>
+				</template>
+			</view>
+			<view v-else class="cart-content empty">
+				<view class="empty-container">
+					<image
+						class="empty-container-image"
+						src="https://img.caimei365.com/group1/M00/03/71/Cmis2F3wna6AWdWzAAGlgAP0das422.png"
+						mode="aspectFit"
+					></image>
+					<text class="error-text">购物车空空如也,快去商城逛逛吧~</text>
+					<view class="login-btn" @click="goIndex">去商城</view>
+				</view>
+			</view>
+		</view>
+		<!-- 选择规格弹窗 -->
+		<cm-unit-popup
+			v-if="popupShow2"
+			:popupShow="popupShow2"
+			:skuProduct="handlePros"
+			@skuBtnConfirm="handleBtnConfirm"
+		></cm-unit-popup>
+		<!-- 促销活动弹窗 -->
+		<activi-popup :product="handlerPros" :popupShow="popupShow"></activi-popup>
+		<!-- 透明模态层 -->
+		<modal-layer v-if="modallayer"></modal-layer>
+		<!-- 优惠券 -->
+		<tui-bottom-popup :radius="true" :show="popupShow0" @close="hidePopup(0)">
+			<view class="tui-popup-box clearfix">
+				<view class="title">优惠券</view>
+				<view class="tui-popup-close" @click="hidePopup(0)">
+					<text class="iconfont icon-iconfontguanbi"></text>
+				</view>
+				<view class="tui-popup-tabs">
+					<coupon-tabs
+						:tabs="navbar"
+						:currentTab="currentTab > 2 ? 0 : currentTab"
+						@change="couponChange"
+						:itemWidth="100 / navbar.length + '%'"
+						selectedColor="#F3B574"
+						sliderBgColor="#F3B574"
+					>
+					</coupon-tabs>
+				</view>
+				<div class="tui-popup-main coupon">
+					<scroll-view class="tui-popup-scroll" scroll-y="true">
+						<view class="coupon-empty" v-if="isCouponEmpty">
+							<image
+								class="empty-container-image"
+								:src="StaticUrl + '/icon/icon-coupon-empty@2x.png'"
+							></image>
+							<text class="error-text">暂无优惠券~</text>
+						</view>
+						<template v-else>
+							<view
+								v-for="(coupon, index) in productCouponList"
+								:key="index"
+								:id="coupon.couponId"
+								class="coupon-list"
+							>
+								<view class="list-cell-le">
+									<view class="coupon-maxMoney"
+										><text class="small">¥</text>{{ coupon.couponAmount }}</view
+									>
+									<view class="coupon-minMoney">满{{ coupon.touchPrice }}可用</view>
+								</view>
+								<view class="list-cell-ri">
+									<view class="list-cell-top">
+										<view class="list-cell-type">
+											<view class="list-cell-tags">
+												<template v-if="coupon.moneyCouponFlag == 1">
+													<text class="tags" v-if="coupon.moneyCouponType == 1"
+														>意向{{ coupon.couponType | TypeFormat }}</text
+													>
+													<text class="tags" v-else
+														>定向{{ coupon.couponType | TypeFormat }}</text
+													>
+												</template>
+												<template v-else>
+													<text class="tags">{{ coupon.couponType | TypeFormat }}</text>
+												</template>
+											</view>
+											<view
+												class="list-cell-texts"
+												:class="currentTab == 1 || currentTab == 2 ? 'none' : ''"
+											>
+												<text v-if="coupon.couponType == 0">
+													{{
+														coupon.productType && coupon.productType == 1
+															? '全商城商品通用'
+															: '仅可购买指定商品'
+													}}
+												</text>
+												<text v-if="coupon.couponType == 1">
+													{{
+														coupon.categoryType == 1
+															? '仅限购买产品类商品'
+															: '仅限购买仪器类商品'
+													}}
+												</text>
+												<text v-if="coupon.couponType == 3"
+													>仅限购买店铺【{{ coupon.shopName }}】的商品</text
+												>
+												<text v-if="coupon.couponType == 4 || coupon.couponType == 2"
+													>全商城商品通用</text
+												>
+											</view>
+										</view>
+										<view class="list-cell-btn">
+											<view class="icon-used">
+												<template v-if="coupon.couponBtnType == 0">
+													<template v-if="coupon.couponPayWay == 2">
+														<view class="icon-used-text"
+															>{{ coupon.moneyCouponPrice }}采美豆</view
+														>
+														<view
+															class="icon-used-btn receive"
+															@click="handleToDeductCoupon(coupon)"
+															>抵扣</view
+														>
+													</template>
+													<template v-else-if="coupon.couponPayWay == 1">
+														<view class="icon-used-text">购买</view>
+														<view class="icon-used-btn receive" @click="handlePayCoupon(coupon)"
+															>¥{{ coupon.moneyCouponPrice }}</view
+														>
+													</template>
+													<template v-else>
+														<view
+															class="icon-used-btn receive"
+															@click="receiveCoupon(coupon)"
+															>领取</view
+														>
+													</template>
+												</template>
+												<view class="icon-used-btn make" v-if="coupon.couponBtnType == 1"
+													>已领取</view
+												>
+											</view>
+										</view>
+									</view>
+									<view class="list-cell-time">{{ coupon.startDate }} - {{ coupon.endDate }}</view>
+								</view>
+							</view>
+						</template>
+					</scroll-view>
+				</div>
+			</view>
+		</tui-bottom-popup>
+		<!-- 优惠明细 -->
+		<tui-bottom-popup :radius="true" :show="popupShow1" @close="hidePopup(1)">
+			<view class="tui-popup-box clearfix">
+				<view class="title">优惠明细</view>
+				<view class="tui-popup-close" @click="hidePopup(1)">
+					<text class="iconfont icon-iconfontguanbi"></text>
+				</view>
+				<div class="tui-popup-main coupon">
+					<view class="tui-popup-coupon">
+						<view class="tui-popup-h1">
+							<view class="tui-popup-text left">商品总额</view>
+							<view class="tui-popup-text right bold">¥{{ totalAmount | NumFormat }}</view>
+						</view>
+						<view class="tui-popup-h1" v-if="reducedPrice > 0">
+							<view class="tui-popup-text left">促销满减</view>
+							<view class="tui-popup-text right bold red">-¥{{ reducedPrice | NumFormat }}</view>
+						</view>
+						<view class="tui-popup-h1" v-if="couponPrice > 0">
+							<view class="tui-popup-text left">优惠券</view>
+							<view class="tui-popup-text right bold red">-¥{{ couponPrice | NumFormat }}</view>
+						</view>
+						<view class="tui-popup-h1" v-if="svipReducedPrice > 0">
+							<view class="tui-popup-text left">超级会员优惠</view>
+							<view class="tui-popup-text right bold red">-¥{{ svipReducedPrice | NumFormat }}</view>
+						</view>
+						<view class="tui-popup-h1">
+							<view class="tui-popup-text left bold">共减</view>
+							<view class="tui-popup-text right bold red">-¥{{ totalDiscountAmount | NumFormat }}</view>
+						</view>
+						<view class="tui-popup-h1">
+							<view class="tui-popup-text left bold">总价</view>
+							<view class="tui-popup-text right bold"
+								>¥{{ (totalAmount - totalDiscountAmount) | NumFormat }}</view
+							>
+						</view>
+					</view>
+				</div>
+			</view>
+		</tui-bottom-popup>
+		<!-- 弹窗提示 -->
+		<tui-modal
+			:show="modal"
+			@click="handleClick"
+			@cancel="hideMobel"
+			:content="contentModalText"
+			:button="modalButton"
+			color="#333"
+			:size="32"
+			shape="circle"
+			:maskClosable="false"
+		>
+		</tui-modal>
+	</view>
+</template>
+
+<script>
+import authorize from '@/common/config/authorize.js'
+import tuiLoadmore from '@/components/tui-components/loadmore/loadmore'
+import tuiNomore from '@/components/tui-components/nomore/nomore'
+import activiPopup from '@/components/cm-module/productDetails/cm-activipopu'
+import couponTabs from '@/components/cm-module/coupon/tui-tabs.vue'
+import cmUnitPopup from './cm-unit-popup.vue'
+import modalLayer from '@/components/modal-layer'
+import payMixins from '@/mixins/payMixins.js'
+import cartMixins from './mixins/cartMixins.js'
+import apisMixins from './mixins/apisMixins.js'
+import { mapState, mapMutations } from 'vuex'
+export default {
+	name: 'cartComponents',
+	mixins: [payMixins,apisMixins,cartMixins],
+	props: {
+		pathType: {
+			type: Number
+		}
+	},
+	components: {
+		tuiLoadmore,
+		tuiNomore,
+		activiPopup,
+		couponTabs,
+		cmUnitPopup,
+		modalLayer
+	},
+	data() {
+		return {
+			StaticUrl: this.$Static, // 静态图片路径
+			CustomBar: this.CustomBar, // 顶部导航栏高度
+			isIphoneX: this.$store.state.isIphoneX,
+			userId: 0,
+			userIdentity: 0,
+			alertType: '',
+			isStock: '',
+			handlerPros: {}, // 监听单挑促销商品
+			failureList: [], // 失效商品列表
+			goodsList: [], // 购物车的商品
+			promotionsList: [], // 促销列表
+			totalCouponList: [], // 优惠券算列表
+			eligibleCoupons: [], // 最终需要用到优惠券
+			setGoodData: '', // 确认订单的商品
+			isCheckAll: false, // 是否全选
+			kindCount: 0, // 购物车宝贝数量
+			totalAmount: 0, // 商品最终合计总价
+			allPrice: 0, // 所有价格
+			totalOriginalPrice: 0, // 所有原价价
+			reducedPrice: 0, // 促销满减
+			couponPrice: 0, // 优惠金额
+			svipReducedPrice: 0, // 超级会员优惠金额
+			totalDiscountAmount: 0, // 总共减去金额
+			isDiscount: false, // 控制显示优惠明细
+			allCount: 0, // 被选中的产品数量
+			isModallayer: false,
+			skeletonShow: true,
+			isshowDelbtn: false,
+			isDisabled: false, // 供应商/店铺全选是否禁用状态
+			isNoConfim: false,
+			isEmpty: false, // 显示空购物车
+			scrollHeight: 'auto',
+			nomoreText: '上拉显示更多',
+			hasNextPage: false,
+			loadding: false,
+			pullUpOn: true,
+			pullFlag: true,
+			pageSize: 10,
+			pageNum: 1,
+			submitIds: [],
+			checkenProsList: [],
+			popupShow: false,
+			popupShow0: false,
+			popupShow1: false,
+			popupShow2: false,
+			currentTab: 1,
+			navbar: [{ name: '未领取', num: 0 }, { name: '已领取', num: 0 }],
+			couponParam: {
+				// 获取弹窗优惠券领取参数
+				userId: 0,
+				shopId: 0,
+				status: 1,
+				source: 2
+			},
+			productCouponList: [], // 优惠券弹窗列表
+			isCouponEmpty: false,
+			contentModalText: '', //操作文字提示语句
+			modal: false,
+			modalButton: [
+				{
+					text: '取消',
+					type: 'gray',
+					plain: true //是否空心
+				},
+				{
+					text: '去升级',
+					customStyle: {
+						color: '#fff',
+						bgColor: 'linear-gradient(90deg, #F28F31 0%, #F3B574 100%)'
+					},
+					plain: false
+				}
+			],
+			handlePros:{}
+		}
+	},
+	created() {
+		this.setScrollHeight()
+		console.log('pathType', this.pathType)
+	},
+	computed: {
+		...mapState(['hasLogin', 'userInfo', 'isWxAuthorize'])
+	},
+	watch: {
+		//深度监听所有数据,每次改变重新计算总价和总数
+		goodsList: {
+			deep: true,
+			handler(val, oldval) {
+				this.totalPeice()
+				this.totalCount()
+			}
+		}
+	},
+	filters: {
+		NumFormat(value) {
+			//处理金额
+			return Number(value).toFixed(2)
+		},
+		totalprice(val, count) {
+			//单件商品的价格 × 数量
+			return (val * count).toFixed(2)
+		},
+		TypeFormat(value) {
+			switch (value) {
+				case 0:
+					return '活动券'
+					break
+				case 1:
+					return '品类券'
+					break
+				case 2:
+					return '用户专享券'
+					break
+				case 3:
+					return '店铺券'
+					break
+				case 4:
+					return '新用户券'
+					break
+			}
+		}
+	},
+	methods: {
+		async initData() {
+			const userInfo = await this.$api.getStorage()
+			this.isModallayer = false //遮罩层 防止多次点击
+			this.skeletonShow = true //预加载圆圈
+			this.isCheckAll = false //是否全选
+			this.submitIds = []
+			this.checkenProsList = []
+			this.couponPrice = 0
+			this.reducedPrice = 0
+			this.totalDiscountAmount = 0
+			this.isDiscount = false
+			this.eligibleCoupons = []
+			this.userId = this.couponParam.userId = userInfo.userId ? userInfo.userId : 0
+			this.userIdentity = userInfo.userIdentity ? userInfo.userIdentity : 0
+			this.vipFlag = userInfo.vipFlag ? userInfo.vipFlag : 0
+			this.initGetCartGoodsList()
+		},
+		isShowVipFlag(pros) {
+			if (pros.priceFlag != 1) {
+				if (this.userIdentity == 4 && this.vipFlag == 1) {
+					return true
+				} else if (this.userIdentity == 2) {
+					return true
+				}
+			}
+		},
+		initLogin() {
+			this.$api.redirectTo('/pages/login/login')
+		},
+		clickPopupShow(pros, type) {
+			this.popupShow = true
+			this.handlerPros = pros
+		},
+		setScrollHeight() {
+			// 窗口高度-footer高度
+			const { windowHeight, pixelRatio } = uni.getSystemInfoSync()
+			setTimeout(() => {
+				const query = uni.createSelectorQuery().in(this)
+				query.selectAll('.footer').boundingClientRect()
+				query.exec(res => {
+					this.windowHeight = windowHeight
+					if (res[0][0]) {
+						this.scrollHeight = windowHeight - res[0][0].height
+					}
+				})
+			}, 500)
+		},
+		initGetCartGoodsList() {
+			//初始化购物车 index:1
+			this.ProductService.QueryShoppingCartList({ userId: this.userId, source: 2 })
+				.then(response => {
+					this.skeletonShow = false
+					let data = response.data
+					this.kindCount = data.kindCount
+					this.promotionsList = data.promotions
+					this.totalCouponList = data.couponList
+					this.$store.commit('updateAllNum', data.kindCount)
+					if (data.list.length > 0 || data.invalid.length > 0) {
+						this.isEmpty = false
+					} else {
+						this.isEmpty = true
+					}
+					if (data.list && data.list.length > 0) {
+						this.goodsList = data.list
+						this.goodsList.forEach((supplier, index) => {
+							supplier.cartList.forEach(pros => {
+								pros.shopId = supplier.shopId
+								pros.isStep = false
+								if(pros.stock === 0 || pros.number > pros.stock ){
+								    supplier.isDisable = true
+								    pros.isDisable = true
+								}else{
+								    pros.isDisable = false
+								}
+								if (pros.step === 2) {
+									if (pros.number % pros.min != 0) {
+										pros.number = pros.min
+										this.totalShopPeice()
+										this.updateShoppogNum(pros)
+									}
+								}
+							})
+						})
+						this.totalShopPeice()
+					} else {
+						this.goodsList = []
+					}
+					if (data.invalid && data.invalid.length > 0) {
+						let newFailureList = [],
+							isFailureLayer
+						data.invalid.forEach((failure, index) => {
+							if (failure.status == 1 || failure.status == 2) {
+								isFailureLayer = true
+							} else {
+								isFailureLayer = false
+							}
+							newFailureList.push(Object.assign({}, failure, { isFailureLayer: isFailureLayer }))
+						})
+						this.failureList = newFailureList
+					} else {
+						this.failureList = []
+					}
+				})
+				.catch(error => {
+					this.$util.msg(error.msg, 2000)
+				})
+		},
+		handleCheckFailure(failure) {//  选择失效商品
+			failure.isChecked = !failure.isChecked
+			this.updateCheckAllBtn()
+		},
+		handlsCkecdPros(item, pro) {
+			//为未选中的时候改变为true,反之为true
+			if (!this.isshowDelbtn) {
+				if(pro.isDisable){ return }
+			}
+			pro.isChecked = !pro.isChecked
+			if (pro.isChecked) {
+				if (!this.submitIds.includes(pro.skuId * 1)) {
+					this.submitIds.push(pro.skuId)
+					this.checkenProsList.push(pro)
+				}
+			} else {
+				var lent = this.submitIds.indexOf(pro.skuId * 1)
+				if (lent >= 0) {
+					this.submitIds.splice(lent, 1)
+					this.checkenProsList.splice(lent, 1)
+				}
+			}
+			this.updateProductCheckedAllBtn(item)
+			this.updateCheckAllBtn()
+		},
+		updateProductCheckedAllBtn(item) {
+			// 单独每个供应商的勾选判断
+			let productsList = item.cartList,
+				productsCheckedLength = 0,
+				disabledLength = 0
+			if (this.isshowDelbtn) {
+				productsList.forEach(pros => {
+					if (pros.isChecked) {
+						productsCheckedLength++
+					}
+				})
+			} else {
+				productsList.forEach(pros => {
+					if (pros.isChecked) {
+						productsCheckedLength++
+					}
+				})
+			}
+			item.isChecked = productsCheckedLength === productsList.length
+		},
+		updateCheckAllBtn() {
+			// 全选勾选判断
+			let goodsCheckedLength = 0,
+				goodsList = this.goodsList,
+				failureList = this.failureList
+			goodsList.forEach(item => {
+				if (item.isChecked) {
+					goodsCheckedLength++
+				}
+			})
+			failureList.forEach(failureItem => {
+				if (failureItem.isChecked) {
+					goodsCheckedLength++
+				}
+			})
+			if (this.isshowDelbtn) {
+				this.isCheckAll = goodsCheckedLength === goodsList.length + failureList.length
+			} else {
+				this.isCheckAll = goodsCheckedLength === goodsList.length
+			}
+		},
+		handleCheckShop(supplier) {
+			//与单选商品类似
+			if (!this.isshowDelbtn) {
+				if(supplier.isDisable){ return }
+			}
+			supplier.isChecked = !supplier.isChecked
+			this.setProductChecked(supplier)
+			this.updateCheckAllBtn()
+		},
+		setProductChecked(supplier) {
+			supplier.cartList.forEach(pros => {
+				if (this.isshowDelbtn) {
+					if (supplier.isChecked) {
+						pros.isChecked = true
+						if (!this.submitIds.includes(pros.skuId * 1)) {
+							this.submitIds.push(pros.skuId)
+							this.checkenProsList.push(pros)
+						}
+					} else {
+						pros.isChecked = false
+						let lent = this.submitIds.indexOf(pros.skuId * 1)
+						if (lent >= 0) {
+							this.submitIds.splice(lent, 1)
+							this.checkenProsList.splice(lent, 1)
+						}
+					}
+				}else{
+					if (supplier.isChecked && (pros.stock !== 0 || pros.number < pros.stock)) {
+						pros.isChecked = true
+						if (!this.submitIds.includes(pros.skuId * 1)) {
+							this.submitIds.push(pros.skuId)
+							this.checkenProsList.push(pros)
+						}
+					} else {
+						pros.isChecked = false
+						let lent = this.submitIds.indexOf(pros.skuId * 1)
+						if (lent >= 0) {
+							this.submitIds.splice(lent, 1)
+							this.checkenProsList.splice(lent, 1)
+						}
+					}
+				}
+			})
+		},
+		updateBothCheckBtn() {
+			if (this.isshowDelbtn) {
+				// 当管理删除按钮出现时,失效的商品可被选择
+				this.goodsList.forEach(supplier => {
+					supplier.isChecked = this.isCheckAll
+					this.setProductChecked(supplier)
+				})
+				//删除按钮 全选包括失效商品勾选
+				this.failureList.forEach(failureItem => {
+					failureItem.isChecked = this.isCheckAll
+				})
+			} else {
+				this.goodsList.forEach(supplier => {
+					if(supplier.isDisable){ 
+						supplier.isChecked = false
+					}else{
+						supplier.isChecked = this.isCheckAll && !supplier.isDisabled
+					}
+					this.setProductChecked(supplier)
+				})
+			}
+		},
+		handleCheckAll() {
+			//全选方法内调用方法
+			this.isCheckAll = !this.isCheckAll
+			if (!this.isCheckAll) {
+				this.popupShow1 = false
+			}
+			this.updateBothCheckBtn()
+		},
+		totalShopPeice() {
+			//每次所属会所下的商品增减重新计算合计价格&减去含有下架的商品
+			let touchPrice = 0
+			let reducedPrice = 0 //商铺合计满减价
+			this.goodsList.map((item, index) => {
+				//计算店铺满减后店铺合计
+				if (item.promotions && item.promotions.mode == 2) {
+					let prosPrice = 0 // 店铺价格合计
+					let prosDiscountNum = 0 // 店铺促销叠加次数
+					let totalOriginalPrice = 0 //店铺原价合计
+					item.cartList.forEach(pros => {
+						prosPrice += pros.price * pros.number
+						totalOriginalPrice += pros.originalPrice * pros.number
+					})
+					if (item.promotions.discount == 1) {
+						// 支持促销叠加条件的店铺满减 执行
+						prosDiscountNum = parseInt(prosPrice / item.promotions.touchPrice) // 店铺满减促销叠加次数 = 店铺合计价格/满减促销价格
+						console.log('店铺满减促销叠加通道叠加次数', `${prosDiscountNum}次`)
+						if (prosPrice >= item.promotions.touchPrice) {
+							// 满足店铺满减条件下执行
+							item.totalPrice = prosPrice - item.promotions.reducedPrice * prosDiscountNum
+							item.reducedPrice = item.promotions.reducedPrice * prosDiscountNum
+							item.totalOriginalPrice = totalOriginalPrice
+						} else {
+							item.reducedPrice = 0 //统计合计价格
+							item.totalPrice = prosPrice
+						}
+					} else {
+						console.log('店铺满减促销非叠加通道')
+						if (prosPrice >= item.promotions.touchPrice) {
+							// 满足店铺满减条件下执行
+							item.totalPrice = prosPrice - item.promotions.reducedPrice
+							item.reducedPrice = item.promotions.reducedPrice
+							item.totalOriginalPrice = totalOriginalPrice
+						} else {
+							item.reducedPrice = 0 //统计合计价格
+							item.totalPrice = prosPrice
+						}
+					}
+				} else {
+					//以下为计算除店铺满减以外的单品满减以及正常商品合计
+					let _totalPrice = 0
+					let _reducedPrice = 0
+					let discountNum = 0
+					let _totalOriginalPrice = 0
+					item.cartList.forEach(pros => {
+						let _price = pros.price * pros.number
+						_totalOriginalPrice += _price
+						if (pros.promotions && pros.promotions.type != 2 && pros.promotions.mode == 2) {
+							if (pros.promotions.discount == 1) {
+								discountNum = parseInt(_price / pros.promotions.touchPrice)
+								console.log('单品满减促销叠加通道叠加次数', `${discountNum}次`)
+								if (_price >= pros.promotions.touchPrice) {
+									_price = _price - pros.promotions.reducedPrice * discountNum
+									_reducedPrice += pros.promotions.reducedPrice * discountNum
+								}
+								_totalPrice += _price
+							} else {
+								console.log('单品满减非促销叠加通道')
+								if (_price >= pros.promotions.touchPrice) {
+									_price = _price - pros.promotions.reducedPrice
+									_reducedPrice += pros.promotions.reducedPrice
+								}
+								_totalPrice += _price
+							}
+						} else {
+							_reducedPrice = 0
+							_totalPrice += pros.price * pros.number
+						}
+					})
+					item.reducedPrice = _reducedPrice
+					item.totalOriginalPrice = _totalOriginalPrice
+					item.totalPrice = _totalPrice
+				}
+			})
+		},
+		totalPeice() {
+			//计算总价格,每次调用此方法,将初始值为0,遍历价格并累加
+			let totalPrice = 0
+			let reducedPrice = 0
+			let originalPrice = 0
+			let svipReducedPrice = 0
+			let totalAmount = 0
+			this.goodsList.forEach((item, index) => {
+				let supplierPrice = 0
+				let supplierReducedPrice = 0
+				item.totalprice = 0
+				item.reducedprice = 0
+				item.originalprice = 0
+				item.cartList.forEach(pros => {
+					if (pros.isChecked) {
+						supplierPrice += pros.price * pros.number
+						svipReducedPrice += item.svipReducedPrice
+						if (pros.svipProductFlag == 1) {
+							totalAmount += item.originalPrice
+						} else {
+							item.totalprice = supplierPrice
+							totalAmount += item.totalprice
+						}
+						// 单品满减
+						if (pros.promotions && pros.promotions.type * 1 === 1 && pros.promotions.mode * 1 === 2) {
+							let _price = pros.price * pros.number
+							if (pros.promotions.discount == 1) {
+								let discountNum = parseInt(_price / pros.promotions.touchPrice)
+								console.log('单品满减促销叠加通道叠加次数', `${discountNum}次`)
+								// 单品满减-重新计算供应商总价/满减金额
+								if (_price >= pros.promotions.touchPrice) {
+									supplierPrice -= pros.promotions.reducedPrice * discountNum
+									supplierReducedPrice += pros.promotions.reducedPrice * discountNum
+								}
+							} else {
+								console.log(' 单品满减非促销叠加通道')
+								// 单品满减-重新计算供应商总价/满减金额
+								if (_price >= pros.promotions.touchPrice) {
+									supplierPrice -= pros.promotions.reducedPrice
+									supplierReducedPrice += pros.promotions.reducedPrice
+								}
+							}
+						}
+					}
+				})
+				// 店铺满减
+				if (item.promotions && item.promotions.mode * 1 === 2) {
+					if (item.promotions.discount == 1) {
+						// 支持促销叠加条件的店铺满减 执行
+						let prosDiscountNum = parseInt(supplierPrice / item.promotions.touchPrice) // 店铺满减促销叠加次数 = 店铺合计价格/满减促销价格
+						console.log('店铺满减促销叠加通道叠加次数', `${prosDiscountNum}次`)
+						if (supplierPrice >= item.promotions.touchPrice) {
+							supplierPrice -= item.promotions.reducedPrice * prosDiscountNum
+							supplierReducedPrice += item.promotions.reducedPrice * prosDiscountNum
+						}
+					} else {
+						console.log('店铺满减非促销叠加通道')
+						// 店铺满减-计算供应商总价/满减金额
+						if (supplierPrice >= item.promotions.touchPrice) {
+							supplierPrice -= item.promotions.reducedPrice
+							supplierReducedPrice += item.promotions.reducedPrice
+						}
+					}
+				}
+				item.totalprice = supplierPrice
+				item.reducedprice = supplierReducedPrice
+				item.originalprice = supplierPrice + supplierReducedPrice
+				totalPrice += item.totalprice
+				reducedPrice += item.reducedprice
+				originalPrice += item.originalprice
+				this.totalAmount = totalAmount
+			})
+			// 总促销计算
+			this.promotionsList.forEach(promotions => {
+				// 凑单满减
+				if (promotions.mode === 2 && promotions.type === 2) {
+					let collecTotal = 0
+					let collecDiscountNum = 0
+					promotions.productList.forEach(pros => {
+						collecTotal += this.collecTotalPrice(pros)
+					})
+					if (promotions.discount == 1) {
+						// 支持凑单满减促销叠加条件的执行
+						collecDiscountNum += parseInt(collecTotal / promotions.touchPrice) // 凑单满减促销叠加次数 = 凑单商品合计价格/凑单满减促销价格
+						console.log('凑单促销满减叠加通道叠加次数', `${collecDiscountNum}次`)
+						if (collecTotal >= promotions.touchPrice) {
+							totalPrice -= promotions.reducedPrice * collecDiscountNum
+							reducedPrice += promotions.reducedPrice * collecDiscountNum
+						}
+					} else {
+						console.log('凑单促销满减非叠加通道')
+						if (collecTotal >= promotions.touchPrice) {
+							totalPrice -= promotions.reducedPrice
+							reducedPrice += promotions.reducedPrice
+						}
+					}
+				}
+			})
+			// 最后勾选的超级会员优惠价
+			this.svipReducedPrice = svipReducedPrice
+			// 最后统计商品原价
+			this.totalOriginalPrice = originalPrice
+			// 最后满减金额 = 店铺减去金额 + 单品减去金额 + 凑单减去金额
+			this.reducedPrice = reducedPrice
+			// 最终合计价格 = 	店铺满减合计 + 单品满减  + 正常合计 + 凑单满减
+			this.allPrice = totalPrice
+			console.log('最后统计商品原价', `${this.totalOriginalPrice}元`)
+			console.log('最后满减金额', `${this.reducedPrice}元`)
+			console.log('最终合计价格', `${this.allPrice}元`)
+			// 计算优惠券
+			if (this.totalCouponList.length > 0) {
+				let eligibleCoupons = this.calculationCoupon()
+				if (eligibleCoupons.length > 0) {
+					this.eligibleCoupons.splice(0, this.eligibleCoupons.length)
+					this.eligibleCoupons = eligibleCoupons.sort((a, b) => b.couponAmount - a.couponAmount)
+					this.couponPrice = this.eligibleCoupons[0].couponAmount
+				} else {
+					this.couponPrice = 0
+				}
+			}
+			// 最终优惠金额 = 促销优惠金额 + 优惠券优惠金额 + 超级会员优惠金额
+			this.totalDiscountAmount = this.reducedPrice + this.couponPrice + this.svipReducedPrice
+			console.log('最终优惠金额', `${this.totalDiscountAmount}元`)
+			// 控制显示优惠明细
+			this.isDiscount = this.totalDiscountAmount > 0 ? true : false
+		},
+		collecTotalPrice(pros) {
+			// 凑单满减计算勾选的凑单商品总价
+			let price
+			this.checkenProsList.find(el => {
+				if (pros.skuId == el.skuId) {
+					price = el.number * el.price
+				}
+			})
+			return price
+		},
+		totalCount() {
+			//计算总数量
+			this.allCount = 0
+			let prosAllCount = 0
+			let validCount = 0
+			let validList = []
+			let productsList = []
+			this.goodsList.forEach(item => {
+				productsList = item.cartList
+				productsList.forEach(pros => {
+					if (pros.isChecked) {
+						prosAllCount += parseInt(pros.number)
+						this.allCount = prosAllCount
+					}
+				})
+			})
+		},
+		calculationCoupon() {
+			// 优惠券计算
+			let eligibleCoupons = []
+			this.goodsList.forEach(shop => {
+				shop.cartList.forEach(pros => {
+					if (pros.isChecked) {
+						this.totalCouponList.forEach(coupon => {
+							//循环优惠券
+							switch (coupon.couponType) {
+								case 0: // 活动券
+									if (coupon.productType == 1) {
+										// 活动券-全商城商品
+										if (this.allPrice >= coupon.touchPrice) {
+											eligibleCoupons.push(coupon)
+										}
+									} else if (coupon.productType == 2) {
+										// 活动券-指定商品
+										if (coupon.productIds && coupon.productIds.includes(pros.productId)) {
+											if (this.allPrice >= coupon.touchPrice) {
+												eligibleCoupons.push(coupon)
+											}
+										}
+									}
+									break
+								case 1: // 品类券适用于产品或者仪器 categoryType(commodityType) : 1 产品  2 仪器
+									if (coupon.categoryType && coupon.categoryType == pros.commodityType) {
+										if (this.allPrice >= coupon.touchPrice) {
+											eligibleCoupons.push(coupon)
+										}
+									}
+									break
+								case 2: // 用户专享券 适用于商城全部商品
+									if (this.allPrice >= coupon.touchPrice) {
+										eligibleCoupons.push(coupon)
+									}
+									break
+								case 3: // 店铺券适用于某个供应商的全部商品
+									if (coupon.shopId && pros.supplierId == coupon.shopId) {
+										if (this.allPrice >= coupon.touchPrice) {
+											eligibleCoupons.push(coupon)
+										}
+									}
+									break
+								case 4: //新用户券 适用于商城全部商品
+									if (this.allPrice >= coupon.touchPrice) {
+										eligibleCoupons.push(coupon)
+									}
+									break
+							}
+						})
+					} else {
+						console.log('没有选择商品')
+						return
+					}
+				})
+			})
+			return eligibleCoupons
+		},
+		changeCountAdd(item, pros) {
+			//商品数量加加
+			if (pros.step === 2) {
+				pros.isStep = false
+				pros.number += pros.min
+				this.processActivityPrice(pros)
+				this.isStock = false
+			} else {
+				pros.number++
+				this.processActivityPrice(pros)
+				this.isStock = false
+			}
+			this.updateShoppogNum(pros)
+			this.totalShopPeice()
+		},
+		changeCountSub(item, pros) {
+			//商品数量减减
+			if (pros.number <= pros.min) {
+				pros.number = pros.min
+				this.$util.msg(`该商品最小起订量为${pros.min}`, 2000)
+				return
+			} else {
+				if (pros.step === 2) {
+					pros.isStep = false
+					pros.number -= pros.min
+				} else {
+					pros.number--
+				}
+				this.processActivityPrice(pros)
+			}
+			this.updateShoppogNum(pros)
+			this.totalShopPeice()
+		},
+		changeInput(pros) {
+			//输入商品数量更新
+			pros.isStep = false
+		},
+		changeNnmber(e, item, pros) {
+			//输入商品数量更新
+			let _value = Number(e.detail.value)
+			if (!this.$api.isNumber(_value)) {
+				pros.number = pros.min
+			} else if (_value < pros.min) {
+				this.$util.msg(`该商品最小起订量为${pros.min}`, 2000)
+				pros.number = pros.min
+			} else if (_value % pros.min != 0) {
+				pros.isStep = true
+				pros.number = pros.min
+			} else {
+				pros.isStep = false
+				pros.number = e.detail.value
+				this.processActivityPrice(pros)
+			}
+			this.updateShoppogNum(pros)
+			this.totalShopPeice()
+		},
+		processActivityPrice(pros) {
+			//单独处理活动价格和阶梯价格
+			let ladderPriceList = pros.ladderPrices
+			if (pros.ladderFlag == 0 || pros.actStatus == 1) {
+				pros.price = pros.price
+			} else {
+				ladderPriceList.forEach((item, index) => {
+					if (pros.number >= item.buyNum) {
+						pros.price = item.buyPrice
+					}
+				})
+			}
+		},
+		setCartisDisable(){// 删除取消设置不能选的商品
+			this.goodsList = this.goodsList.map(suppler=>{
+				suppler.isDisable = false
+				suppler.cartList.forEach(pros => {
+					pros.isDisable = false
+				})
+				return suppler
+			})
+		},
+		clearCartisDisable(){// 取消删除设置不能选的商品
+			this.goodsList = this.goodsList.map((supplier) => {
+				supplier.cartList.forEach(pros => {
+					if(pros.stock === 0 || pros.number > pros.stock ){
+					    supplier.isDisable = true
+					    pros.isDisable = true
+					}else{
+					    pros.isDisable = false
+					}
+				})
+				return supplier
+			})
+		},
+		showDelManager() {
+			//显示删除商品管理
+			this.isshowDelbtn = true
+			this.setCartisDisable()
+			if (this.isCheckAll) {
+				this.updateBothCheckBtn()
+			} else {
+				this.goodsList = this.goodsList.map(suppler=>{
+					if (suppler.isChecked) {
+						suppler.cartList.forEach(pros => {
+							pros.isChecked = true
+						})
+					}
+					return suppler
+				})
+				this.updateCheckAllBtn()
+			}
+			// 失效也被勾选
+			this.failureList = this.failureList.map(el=>{
+				if (el.isFailureLayer) {
+					el.isFailureLayer = false
+				}
+				return el
+			})
+		},
+		hideDelManage() {
+			//隐藏删除商品管理
+			this.isshowDelbtn = false
+			this.isCheckAll = false
+			this.clearCartisDisable()
+			this.goodsList = this.goodsList.map(suppler=>{
+				suppler.isChecked = false
+				suppler.cartList.forEach(pros => {
+						pros.isChecked = false
+				})
+				return suppler
+			})
+			this.failureList = this.failureList.map(el=>{
+				if (el.failureState == 1 || el.failureState == 2) {
+					el.isFailureLayer = true
+				} else {
+					el.isFailureLayer = false
+				}
+				return el
+			})
+		},
+		
+		goIndex() {
+			uni.switchTab({
+				url: '/pages/tabBar/home/index'
+			})
+		},
+		goSuppile(shop) {
+			//跳转店铺
+			if (shop.shopType === 2) {
+				return
+			}
+			this.$api.navigateTo(`/pages/supplier/user/my-shop?shopId=${shop.shopId}`)
+		},
+		goNavto(url) {
+			uni.navigateTo({
+				url
+			})
+		},
+		navToListPage(id) {
+			this.isModallayer = true
+			this.$api.navigateTo(`/pages/goods/product?id=${id}`)
+		},
+		failureToProduct(failure) {
+			if (failure.status == 1) {
+				this.$util.msg('商品已丢失,不能查看', 2000)
+				return
+			} else if (failure.status == 2) {
+				this.$util.msg('商品已停售,不能查看', 2000)
+				return
+			} else {
+				this.isModallayer = true
+				this.$api.navigateTo(`/pages/goods/product?id=${failure.productId}`)
+			}
+		},
+		failureStateText(state) {
+			let stateText = '',
+				stateTextObject = {
+					1: '商品已丢失',
+					2: '商品已停售',
+					3: '商品已下架',
+					4: '商品已售罄',
+					5: '价格仅会员可见,您不能购买',
+					6: '未公开价格',
+					7: '库存不足',
+					8: '价格仅医美机构可见'
+				}
+			Object.keys(stateTextObject).forEach(key => {
+				if (key == state) {
+					stateText = stateTextObject[key]
+				}
+			})
+			return stateText
+		},
+		setHeaderBtnPosi() {
+			// 获得胶囊按钮位置信息
+			let headerBtnPosi = uni.getMenuButtonBoundingClientRect()
+			return headerBtnPosi
+		},
+		setSysteminfo() {
+			let systeminfo
+			uni.getSystemInfo({
+				// 获取设备信息
+				success: res => {
+					systeminfo = res
+				}
+			})
+			return systeminfo
+		},
+		PromotionsFormat(promo) {
+			//促销活动类型数据处理
+			if (promo != null) {
+				if (promo.type == 1 && promo.mode == 1) {
+					return true
+				} else {
+					return false
+				}
+			}
+			return false
+		},
+		queryPopupCoupons() {
+			// 获取优惠券列表调用 apisMixins -> apiShoppingCartGetCoupon
+			this.apiShoppingCartGetCoupon(this.couponParam)
+		},
+		receiveCoupon(coupon) {
+			// 点击优惠券领取按钮,友盟埋点收集领取优惠券
+			if (process.env.NODE_ENV != 'development') {
+				this.$uma.trackEvent('Um_Event_cartCouponReceive', {
+					Um_Key_PageName: '机构购物车',
+					Um_Key_EvenName: '领取优惠券',
+					Um_Key_CouponId: `${coupon.couponId}`
+				})
+			}
+			// 领取优惠券调用 apisMixins -> apiReceiveCoupon
+			this.apiReceiveCoupon({userId: this.couponParam.userId,couponId: coupon.couponId,source: 1})
+		},
+		handleToDeductCoupon(coupon) {
+			// 点击采美豆抵扣优惠券
+			if (process.env.NODE_ENV != 'development') {
+				this.$uma.trackEvent('Um_Event_userCouponCollectionBuy', {
+					Um_Key_PageName: '领券中心',
+					Um_Key_EvenName: '抵扣优惠券',
+					Um_Key_CouponId: `${coupon.couponId}`
+				})
+			}
+			if (this.hasLogin) {
+				if (this.userIdentity === 1 || this.userIdentity === 3) {
+					this.$util.msg('您的身份暂不支持领取优惠券', 2000)
+					return
+				}
+				// 调用 apisMixins -> apiWeChatPayCouponBeans
+				this.apiWeChatPayCouponBeans({ source: 1, userId: this.couponParam.userId,couponId: coupon.couponId })
+			} else {
+				this.$api.navigateTo('/pages/login/login')
+			}
+		},
+		handlePayCoupon(coupon) {
+			// 点击购买优惠券,友盟埋点收集购买优惠券
+			if (process.env.NODE_ENV != 'development') {
+				this.$uma.trackEvent('Um_Event_cartCouponBuy', {
+					Um_Key_PageName: '机构购物车',
+					Um_Key_EvenName: '购买优惠券',
+					Um_Key_CouponId: `${coupon.couponId}`
+				})
+			}
+			// 生成购买优惠券记录Id调用 apisMixins -> apiReceiveCoupon
+			this.apiWeChatCouponRecord({ userId: this.userId,couponId: coupon.couponId },coupon)
+		},
+		hideMobel() {
+			this.modal = false
+		},
+		handleClick(e) {
+			//个人机构跳转升级页面
+			if (e.index == 1) {
+				this.$api.navigateTo('/pages/login/apply')
+			}
+			this.modal = false
+		},
+		showPopup(index, shop) {
+			// 显示popup弹窗
+			switch (index) {
+				case 0:
+					// 友盟埋点收集领券按钮
+					if (process.env.NODE_ENV != 'development') {
+						this.$uma.trackEvent('Um_Event_cartCouponButton', {
+							Um_Key_PageName: '机构购物车',
+							Um_Key_EvenName: '点击领券按钮',
+							Um_Key_userId: `${this.userId}`
+						})
+					}
+					this.currentTab = 0
+					this.couponParam.status = 1
+					this.couponParam.shopId = shop.shopId
+					this.queryPopupCoupons()
+					this.popupShow0 = true
+					break
+				case 1:
+					this.popupShow1 = true
+					break
+			}
+		},
+		handleShouUnitPopup(pros){// 规格弹窗
+			this.popupShow2 = true
+			this.handlePros = pros
+		},
+		hidePopup(index) {
+			// 隐藏popup弹窗
+			switch (index) {
+				case 0:
+					this.popupShow0 = false
+					break
+				case 1:
+					this.popupShow1 = false
+					break
+			}
+		},
+		couponChange(e) {
+			this.currentTab = e.index
+			switch (this.currentTab) {
+				case 0:
+					this.couponParam.status = 1
+					this.queryPopupCoupons()
+					break
+				case 1:
+					this.couponParam.status = 2
+					this.queryPopupCoupons()
+					break
+			}
+		}
+	}
+}
+</script>
+
+<style lang="scss">
+page {
+	background: #f7f7f7;
+	height: auto;
+}
+.cart-content {
+	position: relative;
+}
+.container-cart-main.none {
+	display: none;
+}
+.container-cart-main.show {
+	display: block;
+}
+.cart-content.empty.none {
+	display: none;
+}
+.cart-content.empty.show {
+	display: block;
+}
+.container-cart.show {
+	display: block;
+}
+.container-cart.none {
+	display: none;
+}
+.empty-container.none {
+	display: none;
+}
+.empty-container.show {
+	display: flex;
+}
+.foot-check-delbtn {
+	width: 100%;
+	height: 80rpx;
+	position: fixed;
+	top: 0;
+	left: 0;
+	box-sizing: border-box;
+	padding: 15rpx 24rpx;
+	background-color: #f7f7f7;
+	z-index: 990;
+	.foot-text {
+		font-size: $font-size-26;
+		height: 50rpx;
+		line-height: 50rpx;
+		color: #666666;
+		float: left;
+		padding-left: 10rpx;
+		text {
+			margin: 0 6rpx;
+		}
+	}
+	.delBtn {
+		width: 100rpx;
+		display: inline-block;
+		padding: 0 15rpx;
+		font-size: $font-size-26;
+		height: 50rpx;
+		line-height: 50rpx;
+		border-radius: 30rpx;
+		background: #ffffff;
+		border: 1px solid #F3B574;
+		color: #F3B574;
+		float: right;
+		text-align: center;
+		&.none {
+			display: none;
+		}
+	}
+}
+.checkbox-box {
+	display: flex;
+	align-items: center;
+	.checkbox {
+		display: flex;
+		margin: 0;
+		padding: 5rpx;
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		box-sizing: border-box;
+		text-align: center;
+		text-decoration: none;
+		border-radius: 0;
+		-webkit-tap-highlight-color: transparent;
+		overflow: hidden;
+		background-color: #ffffff;
+		font-size: 36rpx;
+		color: #999999;
+		&.icon-yixuanze {
+			color: $color-system;
+		}
+	}
+	&.disabled {
+		.checkbox {
+			color: #999999;
+		}
+	}
+	.text {
+		font-size: $font-size-24;
+		margin-left: 10rpx;
+	}
+}
+.goods-list {
+	width: 100%;
+	height: auto;
+	background-color: #f7f7f7;
+	.goods-item {
+		width: 702rpx;
+		padding: 0 24rpx;
+		background: #ffffff;
+		margin-bottom: 24rpx;
+	}
+	.shoptitle {
+		height: 80rpx;
+		line-height: 80rpx;
+		.checkbox-box {
+			float: left;
+			line-height: 80rpx;
+			display: inline-block;
+			box-sizing: border-box;
+		}
+		.text {
+			width: 400rpx;
+			float: left;
+			display: block;
+			overflow: hidden;
+			text-overflow: ellipsis;
+			white-space: nowrap;
+			line-height: 80rpx;
+			margin-left: 20rpx;
+			font-size: $font-size-28;
+			color: $text-color;
+			text-align: left;
+			font-weight: bold;
+		}
+		.text-coupon {
+			float: right;
+			line-height: 80rpx;
+			font-size: $font-size-30;
+			color: #F3B574;
+		}
+		.floor-item-act {
+			width: 120rpx;
+			height: 80rpx;
+			text-align: center;
+			box-sizing: border-box;
+			float: left;
+			padding: 24rpx 0;
+			margin-left: 20rpx;
+		}
+	}
+	.goods-pros {
+		width: 100%;
+		height: auto;
+		margin-bottom: 20rpx;
+	}
+	.goods-pros-t {
+		display: flex;
+		align-items: center;
+		width: 100%;
+		height: 210rpx;
+		padding: 0 0 26rpx 0;
+		.checkbox-box {
+			// padding: 10rpx;
+		}
+		.pros-img {
+			width: 210rpx;
+			height: 100%;
+			border-radius: 10rpx;
+			margin: 0 20rpx;
+			border: 1px solid #f3f3f3;
+			position: relative;
+			image {
+				width: 100%;
+				height: 100%;
+				border-radius: 10rpx;
+			}
+			.pros-type {
+				width: 64rpx;
+				height: 64rpx;
+				text-align: justify;
+				box-sizing: border-box;
+				padding: 10rpx;
+				border-radius: 0 0 8rpx 8rpx;
+				background-color: #33ccbf;
+				font-size: $font-size-22;
+				color: #ffffff;
+				line-height: 25rpx;
+				position: absolute;
+				top: 0;
+				right: 10rpx;
+			}
+		}
+	}
+	.goods-pros-b {
+		width: 100%;
+		height: auto;
+		padding: 0 0 24rpx 0;
+		box-sizing: border-box;
+		&.show {
+			display: block;
+		}
+		&.none {
+			display: none;
+		}
+		.sum-none {
+			width: 100%;
+			height: 48rpx;
+			line-height: 48rpx;
+			color: $text-color;
+			float: left;
+			text-align: right;
+			.money {
+				font-size: $font-size-26;
+				color: #999999;
+				text-decoration: line-through;
+			}
+			.money-sign {
+				font-size: $font-size-26;
+				color: #999999;
+				text-decoration: line-through;
+			}
+			.money-reduced {
+				margin-left: 10rpx;
+				font-size: $font-size-26;
+				color: $color-system;
+				.iconfont {
+					font-size: $font-size-34;
+				}
+			}
+		}
+		.sum {
+			width: 100%;
+			height: 40rpx;
+			font-size: $font-size-26;
+			line-height: 40rpx;
+			color: $text-color;
+			float: left;
+			display: flex;
+			justify-content: flex-end;
+			font-weight: bold;
+			.money {
+				color: #ff2a2a;
+				font-size: $font-size-26;
+			}
+			.money-sign {
+				font-size: $font-size-24;
+				color: #ff2a2a;
+			}
+		}
+	}
+	.pros-product {
+		width: 416rpx;
+		height: 100%;
+		line-height: 36rpx;
+		font-size: $font-size-28;
+		position: relative;
+		.producttitle {
+			width: 100%;
+			display: inline-block;
+			height: auto;
+			text-overflow: ellipsis;
+			display: -webkit-box;
+			word-break: break-all;
+			-webkit-box-orient: vertical;
+			-webkit-line-clamp: 2;
+			overflow: hidden;
+			margin-bottom: 15rpx;
+			.no-text {
+				display: inline-block;
+				height: 36rpx;
+				padding: 0 12rpx;
+				line-height: 36rpx;
+				background: linear-gradient(315deg, rgba(231, 0, 0, 1) 0%, rgba(255, 104, 1, 1) 100%);
+				border-radius: 18rpx;
+				text-align: center;
+				color: #ffffff;
+				font-size: $font-size-28;
+				margin-right: 24rpx;
+			}
+		}
+		.productspec {
+			height: 36rpx;
+			color: #999999;
+			font-size: $font-size-26;
+		}
+		.cart-sku-temp{
+			width: 100%;
+			height: 48rpx;
+			margin: 30rpx 0 0 0;
+			.cart-sku-text{
+				font-size: 28rpx;
+				line-height: 48rpx;
+				color: #666666;
+				float: left;
+			}
+			.cart-sku-btn{
+				padding: 0 16rpx;
+				text-align: center;
+				line-height: 40rpx;
+				font-size: 24rpx;
+				box-sizing: border-box;
+				border: 1px solid #F3B574;
+				color: #F3B574;
+				float: left;
+				border-radius: 20rpx;
+				margin-left: 16rpx;
+			}
+		}
+		.productprice {
+			width: 100%;
+			height: 48rpx;
+			margin: 30rpx 0 0 0;
+			.price {
+				line-height: 48rpx;
+				font-size: $font-size-26;
+				width: 48%;
+				color: #ff2a2a;
+				float: left;
+				font-weight: bold;
+				&.disabled {
+					color: #999999;
+					text-decoration: line-through;
+				}
+				.money-sign {
+					font-size: $font-size-24;
+					color: #ff2a2a;
+				}
+			}
+			.count {
+				height: 100%;
+				float: right;
+				position: relative;
+				&.show {
+					display: block;
+				}
+				&.none {
+					display: none;
+				}
+				.count-tips {
+					width: auto;
+					display: inline-block;
+					padding: 0 15rpx;
+					line-height: 44rpx;
+					height: 44rpx;
+					border-radius: 22rpx;
+					background: $btn-confirm;
+					font-size: $font-size-24;
+					text-align: center;
+					color: #ffffff;
+					position: absolute;
+					top: -60rpx;
+					left: -5rpx;
+					z-index: 5;
+					&.step {
+						left: -217rpx;
+					}
+					&::before {
+						content: '';
+						position: absolute;
+						bottom: -30rpx;
+						right: 15rpx;
+						z-index: 1;
+						width: 0;
+						height: 0;
+						border-width: 18rpx;
+						border-style: solid;
+						border-color: $color-system transparent transparent transparent;
+					}
+				}
+				.number-box {
+					display: flex;
+					justify-content: center;
+					align-items: center;
+					border: 2rpx solid #ffe6dc;
+					border-radius: 30rpx;
+					.iconfont {
+						font-size: $font-size-24;
+						padding: 0 18rpx;
+						color: #999999;
+						text-align: center;
+						line-height: 48rpx;
+						font-weight: bold;
+						background: #fef6f3;
+						&.icon-jianhao {
+							border-radius: 30rpx 0 0 30rpx;
+						}
+						&.icon-jiahao {
+							border-radius: 0 30rpx 30rpx 0;
+						}
+					}
+					.btn-input {
+						width: 62rpx;
+						height: 48rpx;
+						line-height: 48rpx;
+						background: #fff;
+						border-radius: 4rpx;
+						text-align: center;
+						font-size: $font-size-24;
+					}
+				}
+				.uni-numbox {
+					position: absolute;
+					left: 45rpx;
+					bottom: 0;
+					.uni-numbox-minus,
+					.uni-numbox-plus {
+						width: 50rpx;
+						line-height: 40rpx;
+					}
+					.uni-numbox-value {
+						font-size: $font-size-28;
+						width: 60rpx;
+					}
+				}
+			}
+		}
+		.floor-item-act {
+			width: 100%;
+			height: 56rpx;
+			text-align: center;
+			box-sizing: border-box;
+			float: left;
+			padding: 0 0 10rpx 0;
+			margin-left: 10rpx;
+		}
+	}
+}
+.failure-list {
+	width: 702rpx;
+	height: auto;
+	padding: 0 24rpx;
+	margin-top: 20rpx;
+	background: #ffffff;
+	.failure-title {
+		width: 100%;
+		height: 82rpx;
+		line-height: 82rpx;
+		font-size: $font-size-28;
+		border-bottom: 1px solid #ebebeb;
+		.title-txt {
+			float: left;
+			color: #666666;
+			text-align: left;
+		}
+		.title-btn {
+			float: right;
+			color: $color-system;
+			text-align: right;
+			line-height: 80rpx;
+			.butto {
+				display: inline-block;
+				padding: 0 15rpx;
+				font-size: $font-size-26;
+				height: 50rpx;
+				line-height: 50rpx;
+				border-radius: 30rpx;
+				background: #ffffff;
+				// border: 1px solid #C9C9C9;
+				// color: #999999;
+				margin-top: 15rpx;
+			}
+		}
+	}
+	.productlist {
+		padding-top: 10rpx;
+		.goods-pros {
+			width: 100%;
+			height: auto;
+			padding: 20rpx 0;
+		}
+		.goods-pros-t {
+			display: flex;
+			align-items: center;
+			width: 100%;
+			height: 210rpx;
+			position: relative;
+			.img-tip {
+				display: block;
+				width: 72rpx;
+				height: 36rpx;
+				line-height: 36rpx;
+				font-size: $font-size-24;
+				text-align: center;
+				color: #ffffff;
+				border-radius: 24rpx;
+				background: rgba(51, 51, 51, 0.3);
+				// position: absolute;
+				// left: 0;
+				// top: 0;
+			}
+			.checkbox-box {
+				padding: 10rpx;
+			}
+			.pros-img {
+				width: 180rpx;
+				height: 100%;
+				border-radius: 10rpx;
+				margin: 0 20rpx;
+				border: 1px solid #f3f3f3;
+				position: relative;
+				image {
+					width: 100%;
+					height: 100%;
+					border-radius: 10rpx;
+				}
+				.pros-type {
+					width: 64rpx;
+					height: 64rpx;
+					text-align: justify;
+					box-sizing: border-box;
+					padding: 10rpx;
+					border-radius: 0 0 8rpx 8rpx;
+					background-color: #33ccbf;
+					font-size: $font-size-22;
+					color: #ffffff;
+					line-height: 25rpx;
+					position: absolute;
+					top: 0;
+					right: 10rpx;
+				}
+			}
+			.pros-marks {
+				width: 730rpx;
+				height: 250rpx;
+				z-index: 90;
+				background: rgba(0, 0, 0, 0.05);
+				position: absolute;
+				left: -20rpx;
+				top: -20rpx;
+			}
+		}
+		.goods-pros-b {
+			width: 622rpx;
+			margin-left: 84rpx;
+			height: 40rpx;
+			padding: 0 0 26rpx 0;
+			// border-top: 1px solid #EBEBEB;
+			&.show {
+				display: block;
+			}
+			&.none {
+				display: none;
+			}
+			.sum {
+				font-size: $font-size-28;
+				line-height: 40rpx;
+				color: $text-color;
+				display: flex;
+				justify-content: flex-end;
+				.money {
+					color: #ff2a2a;
+					font-size: $font-size-28;
+				}
+				.money-sign {
+					font-size: $font-size-24;
+					color: #ff2a2a;
+				}
+			}
+		}
+		.pros-product {
+			width: 402rpx;
+			height: 100%;
+			line-height: 36rpx;
+			font-size: $font-size-28;
+			position: relative;
+			.producttitle {
+				width: 100%;
+				display: inline-block;
+				height: auto;
+				text-overflow: ellipsis;
+				display: -webkit-box;
+				word-break: break-all;
+				-webkit-box-orient: vertical;
+				-webkit-line-clamp: 2;
+				overflow: hidden;
+				margin-bottom: 8rpx;
+				.no-text {
+					display: inline-block;
+					height: 36rpx;
+					padding: 0 12rpx;
+					line-height: 36rpx;
+					background: linear-gradient(315deg, rgba(231, 0, 0, 1) 0%, rgba(255, 104, 1, 1) 100%);
+					border-radius: 18rpx;
+					text-align: center;
+					color: #ffffff;
+					font-size: $font-size-28;
+					margin-right: 24rpx;
+				}
+			}
+			.productspec {
+				height: 36rpx;
+				color: #999999;
+				font-size: $font-size-26;
+				margin-top: 20rpx;
+			}
+			.productstate {
+				font-size: $font-size-28;
+				height: 44rpx;
+				color: #ff2a2a;
+				position: absolute;
+				bottom: 0;
+				left: 0;
+			}
+		}
+	}
+}
+.tui-popup-box {
+	position: relative;
+	box-sizing: border-box;
+	min-height: 220rpx;
+	padding: 24rpx 24rpx 0 24rpx;
+	.tui-popup-close {
+		width: 90rpx;
+		height: 90rpx;
+		position: absolute;
+		right: 0;
+		top: 24rpx;
+		line-height: 90rpx;
+		text-align: center;
+		color: #b2b2b2;
+		.icon-iconfontguanbi {
+			font-size: $font-size-40;
+		}
+	}
+	.title {
+		font-size: $font-size-34;
+		color: $text-color;
+		line-height: 88rpx;
+		text-align: center;
+		float: left;
+		width: 100%;
+		height: 88rpx;
+		font-weight: bold;
+	}
+	.tui-popup-main {
+		width: 100%;
+		float: left;
+		&.coupon {
+			padding-bottom: 40rpx;
+			.coupon-empty {
+				width: 100%;
+				height: 600rpx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				flex-direction: column;
+				position: fixed;
+				background: $bg-color;
+				.empty-container-image {
+					width: 150rpx;
+					height: 150rpx;
+					margin-bottom: 0;
+					margin-top: 0;
+				}
+				.error-text {
+					font-size: $font-size-28;
+					color: #999999;
+					line-height: 88rpx;
+				}
+			}
+		}
+		.tui-popup-scroll {
+			width: 100%;
+			height: 600rpx;
+			.coupon-list {
+				width: 100%;
+				height: 200rpx;
+				margin-top: 24rpx;
+				box-sizing: border-box;
+				background: url(https://static.caimei365.com/app/img/icon/icon-coupon-uesb@2x.png);
+				background-size: cover;
+				&:last-child {
+					margin-bottom: 24rpx;
+				}
+				.list-cell-le {
+					width: 224rpx;
+					height: 100%;
+					box-sizing: border-box;
+					padding: 37rpx 0;
+					float: left;
+					.coupon-maxMoney {
+						width: 100%;
+						height: 78rpx;
+						line-height: 78rpx;
+						font-size: 56rpx;
+						color: #ffffff;
+						text-align: center;
+						.small {
+							font-size: $font-size-24;
+						}
+					}
+					.coupon-minMoney {
+						width: 100%;
+						height: 33rpx;
+						line-height: 33rpx;
+						font-size: $font-size-24;
+						color: #ffffff;
+						text-align: center;
+					}
+				}
+				.list-cell-ri {
+					width: 478rpx;
+					height: 100%;
+					box-sizing: border-box;
+					padding: 20rpx 24rpx 0 24rpx;
+					float: right;
+					.list-cell-top {
+						width: 100%;
+						height: 121rpx;
+						float: left;
+						border-bottom: 1px solid #e1e1e1;
+						.list-cell-type {
+							width: 286rpx;
+							height: 100%;
+							float: left;
+							.list-cell-tags {
+								width: 100%;
+								height: 32rpx;
+								margin-bottom: 7rpx;
+								.tags {
+									display: inline-block;
+									padding: 0 10rpx;
+									height: 32rpx;
+									line-height: 32rpx;
+									background-color: #ffdcce;
+									color: #f94b4b;
+									font-size: $font-size-20;
+									border-radius: 8rpx;
+									text-align: center;
+									float: left;
+								}
+							}
+							.list-cell-texts {
+								width: 100%;
+								height: auto;
+								line-height: 35rpx;
+								text-overflow: ellipsis;
+								display: -webkit-box;
+								word-break: break-all;
+								-webkit-box-orient: vertical;
+								-webkit-line-clamp: 2;
+								overflow: hidden;
+								font-size: 26rpx;
+								color: #333333;
+							}
+						}
+						.list-cell-btn {
+							width: 128rpx;
+							height: 100%;
+							float: right;
+							.icon-used {
+								width: 100%;
+								height: 100%;
+								box-sizing: border-box;
+								padding-top: 28rpx;
+								.icon-used-text {
+									width: 100%;
+									text-align: center;
+									line-height: 26rpx;
+									font-size: $font-size-20;
+									color: #f94b4b;
+								}
+								.icon-used-btn {
+									width: 128rpx;
+									height: 48rpx;
+									border-radius: 28rpx;
+									line-height: 48rpx;
+									font-size: $font-size-26;
+									text-align: center;
+									&.receive {
+										background-image: linear-gradient(270deg, #f94b4b 0%, #feb673 100%);
+										color: #ffffff;
+									}
+									&.make {
+										border: solid 1px #f94b4b;
+										color: #f94b4b;
+									}
+								}
+							}
+						}
+					}
+					.list-cell-time {
+						width: 100%;
+						height: 58rpx;
+						line-height: 58rpx;
+						text-align: left;
+						font-size: $font-size-20;
+						color: #999999;
+					}
+				}
+			}
+		}
+		.tui-popup-coupon {
+			width: 100%;
+			height: 500rpx;
+			box-sizing: border-box;
+			padding: 30rpx 20rpx;
+			.tui-popup-h1 {
+				width: 100%;
+				height: 66rpx;
+				display: flex;
+				align-items: center;
+				.tui-popup-text {
+					flex: 1;
+					height: 66rpx;
+					line-height: 66rpx;
+					font-size: $font-size-30;
+					color: #333333;
+					&.red {
+						color: #f94b4b;
+					}
+					&.bold {
+						font-weight: bold;
+					}
+					&.left {
+						text-align: left;
+					}
+					&.right {
+						text-align: right;
+					}
+				}
+			}
+		}
+	}
+}
+.footer {
+	width: 100%;
+	background-color: #ffffff;
+	height: 110rpx;
+	position: fixed;
+	bottom: 0rpx;
+	z-index: 990;
+	.footer-le {
+		width: 520rpx;
+		height: 100%;
+		padding-left: 24rpx;
+		float: left;
+		box-sizing: border-box;
+		.foot-check {
+			width: 100rpx;
+			float: left;
+			line-height: 110rpx;
+			font-size: $font-size-24;
+			.checkbox {
+				width: 40rpx;
+				text-align: center;
+			}
+			.text {
+				width: 60rpx;
+				float: right;
+			}
+		}
+		.sum {
+			width: 360rpx;
+			height: 110rpx;
+			float: right;
+			box-sizing: border-box;
+			padding: 10rpx;
+			.sum-none {
+				width: 100%;
+				height: 45rpx;
+				line-height: 45rpx;
+				color: $text-color;
+				float: left;
+				text-align: left;
+				.money {
+					font-size: $font-size-24;
+					color: #999999;
+					text-decoration: line-through;
+				}
+				.money-sign {
+					font-size: $font-size-24;
+					color: #999999;
+					text-decoration: line-through;
+				}
+				.money-reduced {
+					margin-left: 10rpx;
+					font-size: $font-size-24;
+					color: #ff2a2a;
+				}
+				.money-popup {
+					height: 45rpx;
+					line-height: 45rpx;
+					display: inline-block;
+					float: right;
+					font-size: $font-size-24;
+					color: #ff2a2a;
+					.icon-xiangshangjiantou {
+						font-size: $font-size-30;
+						margin-left: 5rpx;
+					}
+				}
+			}
+			.sum-price {
+				width: 100%;
+				height: 45rpx;
+				line-height: 45rpx;
+				font-size: $font-size-30;
+				color: $text-color;
+				float: left;
+				font-weight: normal;
+				text-align: left;
+				&.none {
+					height: 90rpx;
+					line-height: 90rpx;
+				}
+				.money {
+					color: #ff2a2a;
+				}
+				.money-sign {
+					font-size: $font-size-24;
+					color: #ff2a2a;
+				}
+			}
+		}
+	}
+	.footer-ri {
+		width: 230rpx;
+		height: 100%;
+		float: right;
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		z-index: 999;
+		box-sizing: border-box;
+		padding: 13rpx 15rpx 13rpx 5rpx;
+		&.none {
+			display: none;
+		}
+		.btn {
+			width: 200rpx;
+			height: 100%;
+			background: linear-gradient(135deg, rgba(242, 143, 49, 1) 0%, rgba(225, 86, 22, 1) 100%);
+			font-size: $font-size-28;
+			line-height: 84rpx;
+			color: #ffffff;
+			display: flex;
+			border-radius: 42rpx;
+			justify-content: center;
+			align-items: center;
+		}
+	}
+	.footer-del {
+		width: 400rpx;
+		height: 110rpx;
+		position: absolute;
+		padding-left: 200rpx;
+		background: #ffffff;
+		right: 0;
+		top: 0;
+		z-index: 1000;
+		&.show {
+			animation: showDelbtn 0s linear both;
+		}
+		&.none {
+			animation: hideDelbtn 0s linear both;
+		}
+		.btn {
+			width: 50%;
+			height: 100%;
+			line-height: 110rpx;
+			font-size: $font-size-28;
+			color: #ffffff;
+			text-align: center;
+			float: left;
+		}
+		.btn.btn-cancel {
+			background: #eec1ab;
+		}
+		.btn.btn-confirm {
+			background: #ff2a2a;
+		}
+		@keyframes showDelbtn {
+			0% {
+				transform: translateX(0);
+			}
+			100% {
+				transform: translateX(-100%);
+			}
+		}
+		@keyframes hideDelbtn {
+			0% {
+				transform: translateX(-100%);
+			}
+			100% {
+				transform: translateX(0);
+			}
+		}
+	}
+}
+</style>

+ 128 - 0
components/cm-module/cm-cart/mixins/apisMixins.js

@@ -0,0 +1,128 @@
+import Vue from 'vue'
+const apisMixins = {
+    methods: {
+        apiUserClubCheckSku(params){
+            this.ProductService.ShoppingCheckSku(params)
+			    .then(response => {
+			        setTimeout(() => {
+			           this.initGetCartGoodsList()
+			        }, 1500)
+			    })
+			    .catch(error => {
+			        this.$util.msg(error.msg, 2000)
+			    })
+        },
+        apiWeChatCouponRecord(params,coupon){
+            //调用购买优惠券
+            this.PayService.WeChatCouponRecord(params)
+                .then(response => {
+                    this.MiniWxPayFor(coupon, response.data.couponRecordId)
+                })
+                .catch(error => {
+                    if (error.code == -1) {
+                        //个人机构不能购买
+                        this.contentModalText = '该优惠券仅限医美机构购买,请升级为医美机构后再次购买。'
+                        this.modal = true
+                    } else if (error.code == -2) {
+                        //会员机构不是医美机构不能购买
+                        this.$util.msg('该优惠券仅限医美机构购买', 2000)
+                    }
+                })
+			
+        },
+        async MiniWxPayFor(coupon, couponRecordId) {
+            // 微信支付
+		    const wechatcode = await authorize.getCode('weixin')
+		    const params = {
+		        userId: this.userId,
+		        couponId: coupon.couponId,
+		        couponRecordId: couponRecordId,
+		        payType: 'XCX',
+		        code: wechatcode,
+		        source: 1 //支付来源 1 小程序 2 WWW
+		    }
+		    this.weChatMiniCouponWxPay(
+		        params,
+		        'Um_Event_cartCouponPay',
+		        '机构购物车',
+		        '线上支付优惠券',
+		        coupon.couponId,
+		        this.userId
+		    )
+        },
+        apiWeChatPayCouponBeans(params){
+            //调用采美豆抵扣优惠券
+            this.PayService.WeChatPayCouponBeans(params)
+                .then(response => {
+                    this.$util.msg('抵扣成功', 1500)
+                    setTimeout(() => {
+                        this.currentTab = 1
+                        this.couponParam.status = 2
+                        this.queryPopupCoupons()
+                    }, 1500)
+                })
+                .catch(error => {
+                    this.$util.msg(error.msg, 2000)
+                })
+        },
+        apiReceiveCoupon(params){
+            //领取优惠券
+            this.ProductService.ReceiveCoupon(params)
+                .then(response => {
+                    this.$util.msg('领取成功', 1500, true, 'success')
+                    setTimeout(() => {
+                        this.currentTab = 1
+                        this.couponParam.status = 2
+                        this.queryPopupCoupons()
+                    }, 1500)
+                })
+                .catch(error => {
+                    this.$util.msg(error.msg, 2000)
+                })
+        },
+        apiShoppingCartGetCoupon(params){
+            // 获取弹窗优惠券列表
+            this.ProductService.ShoppingCartGetCoupon(params)
+                .then(response => {
+                    let data = response.data
+                    this.navbar[0].num = data.notCouponNum
+                    this.navbar[1].num = data.couponNum
+                    if (data.couponList && data.couponList.length > 0) {
+                        this.productCouponList = data.couponList
+                        this.isCouponEmpty = false
+                    } else {
+                        this.isCouponEmpty = true
+                    }
+                })
+                .catch(error => {
+                    console.log('获取优惠券列表失败')
+                })
+        },
+        apiShoppingCartUpdate(params) {
+            //更新购物车商品
+            this.ProductService.ShoppingCartUpdate(params)
+                .then(response => {
+                    this.isshowDelbtn = false
+                })
+                .catch(error => {
+                    this.$util.msg(error.msg, 2000)
+                })
+        },
+        shoppingCartDelete(params) { 
+            // 删除购物车商品
+            this.ProductService.ShoppingCartDelete(params)
+                .then(response => {
+                    this.$util.msg('删除成功', 2000)
+                    setTimeout(() => {
+                        this.isshowDelbtn = false
+                        this.initGetCartGoodsList()
+                    }, 2000)
+                })
+                .catch(error => {
+                    this.$util.msg(error.msg, 2000)
+                })
+        }
+    }
+}
+
+export default apisMixins

+ 103 - 0
components/cm-module/cm-cart/mixins/cartMixins.js

@@ -0,0 +1,103 @@
+// 统计数据
+// 统计类型 1:首页banner;2:直播模块;3:最新活动;4:热门文章;5:新品橱窗;6:活动列表
+import Vue from 'vue'
+const cartMixins = {
+    data() {
+        return {
+			
+        }
+    },
+    methods: {
+        hanldlerToConfirm() {
+            //跳转确认订单页面
+            let skuIds = ''
+            this.isNoConfim = false
+            this.goodsList.forEach(supper => {
+                supper.cartList.forEach(pros => {
+                    if (pros.isChecked) {
+                        // 获取勾选的商品ID拼接字符串逗号隔开,最后一个逗号去掉
+                        skuIds += pros.skuId + ','
+                        // 有商品的购买量没达到最小起订量
+                        if (pros.number < pros.min) {
+                            this.isNoConfim = true
+                        }
+                    }
+                })
+            })
+            if (skuIds === '') {
+                this.$util.msg('请先选择结算商品~', 2000)
+                return
+            }
+            if (this.isNoConfim) {
+                this.$util.modal(
+                    '',
+                    '有商品的购买量没达到最小起订量,请修改数量后再次提交结算',
+                    '去修改',
+                    '',
+                    false,
+                    () => {}
+                )
+                return
+            }
+            // 友盟埋点购物车去结算点击事件
+            if (process.env.NODE_ENV != 'development') {
+                this.$uma.trackEvent('Um_Event_shoppingCartConfirmOrder', {
+                    Um_Key_PageName: '去结算',
+                    Um_Key_SourcePage: '底部菜单购物车'
+                })
+            }
+            let cartSkuIds = { skuIds: skuIds.substring(0, skuIds.lastIndexOf(',')) }
+            this.$api.navigateTo(
+                `/pages/user/order/create-order?type=2&data=${JSON.stringify({ data: cartSkuIds })}`
+            )
+        },
+        handleBtnConfirm(data) {
+            console.log('data', data)
+            // 确认重选规格调用 apisMixins -> apiQueryShoppingCartList
+            this.apiUserClubCheckSku(data)
+        },
+        updateShoppogNum(pros) {
+            const params = {
+                userId: this.userId,
+                skuId: pros.skuId,
+                productCount: pros.number,
+                source: 2
+            }
+            // 更新购物车调用 apisMixins -> apiQueryShoppingCartList
+            this.apiShoppingCartUpdate(params)
+        },
+        handleDeleteCart() { //删除购物车商品
+            let delSkuIds = ''
+            this.goodsList.forEach(delitem => {
+                delitem.cartList.forEach(pros => {
+                    if (pros.isChecked) {
+                        delSkuIds += pros.skuId + ','
+                    }
+                })
+            })
+            this.failureList.forEach(failure => {
+                if (failure.isChecked) {
+                    delSkuIds += failure.skuId + ','
+                }
+            })
+            if (delSkuIds.length == 0) {
+                this.$util.msg('请选择要删除的商品~', 2000)
+                return
+            }
+            this.$util.modal('', '确定删除选中的商品吗?', '确定', '取消', true, () => {
+                this.shoppingCartDelete({ userId: this.userId, skuIds: delSkuIds })
+            })
+        },
+        handleDeletefailures() { // 一键清楚所有失效商品
+            let delSkuIds = ''
+            this.failureList.forEach(failure => {
+                delSkuIds += failure.skuId + ','
+            })
+            this.$util.modal('', '确定清空全部失效商品吗?', '确定', '取消', true, () => {
+                this.shoppingCartDelete({ userId: this.userId, skuIds: delSkuIds })
+            })
+        }
+    }
+}
+
+export default cartMixins

+ 280 - 0
components/cm-module/coupon/tui-tabs.vue

@@ -0,0 +1,280 @@
+<template>
+	<view class="tui-tabs-view"
+		:class="[isFixed ? 'tui-tabs-fixed' : 'tui-tabs-relative', unlined ? 'tui-unlined' : '']" :style="{
+			width: tabsWidth + 'px',
+			height: height + 'rpx',
+			padding: `0 ${padding}rpx`,
+			background: backgroundColor,
+			top: isFixed ? top + 'px' : 'auto',
+			zIndex: isFixed ? zIndex : 'auto'
+		}" v-if="tabsWidth>0">
+		<view v-for="(item, index) in tabs" :key="index" class="tui-tabs-item" :style="{ width: itemWidth }"
+			@tap.stop="swichTabs(index)">
+			<view class="tui-tabs-title"
+				:class="{ 'tui-tabs-active': currentTab == index, 'tui-tabs-disabled': item.disabled }" :style="{
+					color: currentTab == index ? selectedColor : color,
+					fontSize: size + 'rpx',
+					fontWeight: bold && currentTab == index ? 'bold' : 'normal'
+				}">
+				{{ item.name }}
+				{{ item.num ? item.num : 0 }}
+			</view>
+		</view>
+		<view class="tui-tabs-slider" :style="{
+				transform: 'translateX(' + scrollLeft + 'px)',
+				width: sliderWidth + 'rpx',
+				height: sliderHeight + 'rpx',
+				borderRadius: sliderRadius,
+				bottom: bottom,
+				background: sliderBgColor,
+				marginBottom: bottom == '50%' ? '-' + sliderHeight / 2 + 'rpx' : 0
+			}"></view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'tuiTabs',
+		props: {
+			//标签页
+			tabs: {
+				type: Array,
+				default () {
+					return [];
+				}
+			},
+			//tabs宽度,不传值则默认使用windowWidth,单位px
+			width: {
+				type: Number,
+				default: 0
+			},
+			//rpx
+			height: {
+				type: Number,
+				default: 80
+			},
+			//rpx 只对左右padding起作用,上下为0
+			padding: {
+				type: Number,
+				default: 30
+			},
+			//背景色
+			backgroundColor: {
+				type: String,
+				default: '#FFFFFF'
+			},
+			//是否固定
+			isFixed: {
+				type: Boolean,
+				default: false
+			},
+			//px
+			top: {
+				type: Number,
+				// #ifndef H5
+				default: 0,
+				// #endif
+				// #ifdef H5
+				default: 44
+				// #endif
+			},
+			//是否去掉底部线条
+			unlined: {
+				type: Boolean,
+				default: false
+			},
+			//当前选项卡
+			currentTab: {
+				type: Number,
+				default: 0
+			},
+			//滑块宽度
+			sliderWidth: {
+				type: Number,
+				default: 68
+			},
+			//滑块高度
+			sliderHeight: {
+				type: Number,
+				default: 6
+			},
+			//滑块背景颜色
+			sliderBgColor: {
+				type: String,
+				default: '#5677fc'
+			},
+			sliderRadius: {
+				type: String,
+				default: '50rpx'
+			},
+			//滑块bottom
+			bottom: {
+				type: String,
+				default: '0'
+			},
+			//标签页宽度
+			itemWidth: {
+				type: String,
+				default: '25%'
+			},
+			//字体颜色
+			color: {
+				type: String,
+				default: '#666'
+			},
+			//选中后字体颜色
+			selectedColor: {
+				type: String,
+				default: '#5677fc'
+			},
+			//字体大小
+			size: {
+				type: Number,
+				default: 28
+			},
+			//选中后 是否加粗 ,未选中则无效
+			bold: {
+				type: Boolean,
+				default: false
+			},
+			//角标字体颜色
+			badgeColor: {
+				type: String,
+				default: '#fff'
+			},
+			//角标背景颜色
+			badgeBgColor: {
+				type: String,
+				default: '#F74D54'
+			},
+			zIndex: {
+				type: [Number, String],
+				default: 996
+			}
+		},
+		watch: {
+			currentTab() {
+				this.checkCor();
+			},
+			tabs() {
+				this.checkCor();
+			},
+			width(val) {
+				this.tabsWidth = val;
+				this.checkCor();
+			}
+		},
+		created() {
+			// 高度自适应
+			setTimeout(() => {
+				uni.getSystemInfo({
+					success: res => {
+						this.winWidth = res.windowWidth;
+						this.tabsWidth = this.width == 0 ? this.winWidth : this.width;
+						this.checkCor();
+					}
+				});
+			}, 0);
+		},
+		data() {
+			return {
+				winWidth: 0,
+				tabsWidth: 0,
+				scrollLeft: 0
+			};
+		},
+		methods: {
+			checkCor: function() {
+				let tabsNum = this.tabs.length;
+				let padding = (this.winWidth / 750) * this.padding;
+				let width = this.tabsWidth - padding * 2;
+				let left = (width / tabsNum - (this.winWidth / 750) * this.sliderWidth) / 2 + padding;
+				let scrollLeft = left;
+				if (this.currentTab > 0) {
+					scrollLeft = scrollLeft + (width / tabsNum) * this.currentTab;
+				}
+				this.scrollLeft = scrollLeft;
+			},
+			// 点击标题切换当前页时改变样式
+			swichTabs: function(index) {
+				let item = this.tabs[index];
+				if (item && item.disabled) return;
+				if (this.currentTab == index) {
+					return false;
+				} else {
+					this.$emit('change', {
+						index: Number(index)
+					});
+				}
+			}
+		}
+	};
+</script>
+
+<style scoped>
+	.tui-tabs-view {
+		width: 100%;
+		box-sizing: border-box;
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+	}
+
+	.tui-tabs-relative {
+		position: relative;
+	}
+
+	.tui-tabs-fixed {
+		position: fixed;
+		left: 0;
+	}
+
+	.tui-tabs-fixed::before,
+	.tui-tabs-relative::before {
+		content: '';
+		position: absolute;
+		border-bottom: 1rpx solid #eaeef1;
+		-webkit-transform: scaleY(0.5) translateZ(0);
+		transform: scaleY(0.5) translateZ(0);
+		transform-origin: 0 100%;
+		bottom: 0;
+		right: 0;
+		left: 0;
+	}
+
+	.tui-unlined::before {
+		border-bottom: 0 !important;
+	}
+
+	.tui-tabs-item {
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		overflow: visible;
+	}
+
+	.tui-tabs-disabled {
+		opacity: 0.6;
+	}
+
+	.tui-tabs-title {
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		position: relative;
+		z-index: 3;
+		overflow: visible;
+	}
+
+	.tui-tabs-active {
+		transition: all 0.15s ease-in-out;
+	}
+
+	.tui-tabs-slider {
+		position: absolute;
+		left: 0;
+		transition: all 0.15s ease-in-out;
+		z-index: 1;
+		transform-style: preserve-3d;
+	}
+</style>

+ 214 - 0
components/cm-module/headerNavbar/header-back.vue

@@ -0,0 +1,214 @@
+<template name="headerNavbar">
+	<!-- 自定义导航栏 -->
+	<view class='navbar-wrap' :style="{height:navbarHeight+'px',paddingTop:statusBarHeight+'px'}"> 
+	  	<view class="navbar-text" :style="{lineHeight:(navbarHeight - statusBarHeight)+'px;',fontSize:fontSizeSetting+'px;'}" :class="platformClass">
+	    	{{navbarData.title ? navbarData.title : " "}}
+	  	</view>
+	  	<view class="navbar-icon" v-if="navbarData.showCapsule == 1 ? true : false" 
+			  :style="{top:navbarBtn.top + statusBarHeight+'px;',left:(navbarBtn.right)+'px;',height:navbarBtn.height+'px;',lineHeight:navbarBtn.height+'px;'}">
+			  <text v-if='haveBack' @click="_goBack" class="iconfont icon-fanhui"></text>
+			  <text v-if='isShare' @click="_goBack" class="iconfont icon-shouye"></text>
+	  	</view>
+		<view class="navbar-icon" v-if="navbarData.showSearch == 1 ? true : false"
+			  :style="{top:navbarBtn.top + statusBarHeight+'px;',right:(navbarBtn.width)+'px;',height:navbarBtn.height+'px;',lineHeight:navbarBtn.height+'px;'}">
+			  <text @click.stop="_goSearchPath" class="iconfont icon-iconfonticonfontsousuo1"></text>
+			  <text v-if="screenTab === 3" @click.stop="_showRightDrawer" class="iconfont icon-shaixuan"></text>
+	  	</view>
+	</view>
+</template>
+
+<script>
+	var self
+	export default{
+		name:'headerNavbar',
+		props:{ 
+		    navbarData: { // 由父页面传递的数据
+				type: Object
+		    },
+			systeminfo:{
+				type:Object
+			},
+			headerBtnPosi:{
+				type:Object
+			},
+			isShare:{
+				type:Boolean
+			},
+			isDelete:{
+				type:Boolean
+			},
+			isUsertype:{
+				type:Number
+			},
+			screenTab:{
+				type:Number
+			}
+		},
+		data() {
+			return{
+				haveBack: true,     // 是否有返回按钮,true 有 false 没有 若从分享页进入则为 false
+			    statusBarHeight: 0, // 状态栏高度
+			    navbarHeight: 0,    // 顶部导航栏高度
+			    navbarBtn: {        // 胶囊位置信息
+			      height: 0,
+			      width: 0,
+			      top: 0,
+			      bottom: 0,
+			      right: 0
+				},
+				platformClass:'',
+				fontSizeSetting:0,
+				
+			}
+		},
+		created() {
+			let statusBarHeight = this.systeminfo.statusBarHeight // 状态栏高度
+			let headerPosi = this.headerBtnPosi // 胶囊位置信息
+			this.fontSizeSetting = this.systeminfo.fontSizeSetting
+			if(this.systeminfo.platform == 'android'){
+				this.platformClass = 'left'
+			}else{
+				this.platformClass = 'center'
+			}
+		    /**
+		     * wx.getMenuButtonBoundingClientRect() 坐标信息以屏幕左上角为原点
+		     * 菜单按键宽度: 87
+		     * 菜单按键高度: 32
+		     * 菜单按键左边界坐标: 278
+		     * 菜单按键上边界坐标: 26
+		     * 菜单按键右边界坐标: 365
+		     * 菜单按键下边界坐标: 58
+		     */
+			let btnPosi = { // 胶囊实际位置,坐标信息不是左上角原点
+			      height: headerPosi.height,
+			      width: headerPosi.width,
+			      // 胶囊top - 状态栏高度
+			      top: headerPosi.top - statusBarHeight,
+			      // 胶囊bottom - 胶囊height - 状态栏height (现胶囊bottom 为距离导航栏底部的长度)
+			      bottom: headerPosi.bottom - headerPosi.height - statusBarHeight,
+			      // 屏幕宽度 - 胶囊right
+			      right: this.systeminfo.screenWidth - headerPosi.right
+			}
+			let haveBack
+			if (getCurrentPages().length === 1) { // 当只有一个页面时
+			     haveBack = false
+			} else {
+			     haveBack = true
+			}
+		    this.haveBack=haveBack, // 获取是否是通过分享进入的小程序
+		    this.statusBarHeight=statusBarHeight,
+		    this.navbarHeight= headerPosi.bottom + btnPosi.bottom, // 原胶囊bottom + 现胶囊bottom
+		    this.navbarBtn=btnPosi
+		},
+		watch: {
+		  screenTab(newVal, oldVal){
+		    // newVal是新值,oldVal是旧值
+		    this.screenTab = newVal
+		  }
+		},
+		methods:{
+			_goBack() {
+				if(this.isShare){
+					this._goHome()
+				}else if(this.isDelete){
+					this._goUser()
+				}else{
+					uni.navigateBack({
+			        	delta: 1
+			      	})
+				}
+		    },
+		    _goHome() {
+		      	uni.switchTab({
+		        	url: '/pages/tabBar/home/index'
+		      	})
+		    },
+		    _goUser() {
+		      	uni.switchTab({
+		        	url: '/pages/tabBar/user/user'
+		      	})
+		    },
+			_goSearchPath() {
+				this.$emit('goSearchPath')
+			},
+			_showRightDrawer() {
+				//显示筛选抽屉
+				this.$parent.rightDrawer = true
+			},
+		},
+		onShow(){
+	
+		}
+	}
+</script>
+
+<style lang="scss">
+	.navbar-wrap {
+		 position: fixed;
+		 width: 100%;
+		 top: 0;
+		 z-index: 100000;
+		 box-sizing: border-box;
+		 background: #FFFFFF;
+	}
+	.navbar-text {
+		 font-size: 30rpx;
+		 color: #000000;
+		 font-weight: 500;
+	}
+	.navbar-text.center{
+		text-align: center;
+	}
+	.navbar-text.left{
+		text-align: left;
+		padding-left: 38px;
+	}
+	.navbar-icon {
+		 position: fixed;
+		 display: flex;
+		 box-sizing: border-box;
+	}
+	.navbar-icon .iconfont {
+		 display: inline-block;
+		 overflow: hidden;
+		 font-size: 42rpx;
+		 padding-right:40rpx;
+		 margin-top: 1px;
+	}
+	.navbar-icon .icon-iconfonticonfontsousuo1 {
+		color: #000000;
+	}
+	.navbar-icon .icon-shaixuan {
+		color: #000000;
+	}
+	.navbar-icon view {
+		 height: 18px;
+		 border-left: 0.5px solid rgba(0,0,0, 0.3);
+		 margin-top: 6px;
+	}
+	.navbar-loading {
+		 background: #fff;
+		 text-align: center;
+	}
+</style>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 51 - 0
components/cm-module/listTemplate/listSkeleton.vue

@@ -0,0 +1,51 @@
+<template>
+	<view class="skeleton-template">
+		 <image :src="setSrc" mode="widthFix"></image>
+	</view>
+</template>
+
+<script>
+	var self;
+	export default{
+		data() {
+			return{
+				skeletonList: {
+					empty: 'https://img.caimei365.com/group1/M00/03/71/Cmis2F3wna6AaQCxAAB0ju39mYk608.png',				
+				},
+				skeletonMemList: {
+					empty: 'https://img.caimei365.com/group1/M00/03/72/Cmis2F3xt_CALrJcAAEE4AHIZ1g310.png',				
+				},
+			}
+		},
+		props:{
+			listType:String,
+			src: {
+				type: String,
+				default: 'empty'
+			}
+		},
+		created(){
+			
+		},
+		computed: {
+			setSrc() {
+				let url;
+				if(this.listType== 0){					
+					url = this.skeletonList[this.src]
+				}else{
+					url = this.skeletonMemList[this.src]
+				}
+				return url;
+			},
+		},
+	}
+</script>
+
+<style lang="scss">
+	.skeleton-template {
+		image {
+			width: 100%;
+			height: 100%;
+		}
+	}
+</style>

+ 29 - 0
components/cm-module/listTemplate/richTextTemplate.vue

@@ -0,0 +1,29 @@
+<template>
+	<view class="content"> <mp-html :content="html" :tag-style="tagStyle" /> </view>
+</template>
+
+<script>
+import { articleTagStyle } from '@/plugins/mp-html/config.js'
+export default {
+	data() {
+		return {
+			serverUrl: '',
+			type: '',
+			html: '',
+			tagStyle: articleTagStyle
+		}
+	},
+	created() {},
+	methods: {}
+}
+</script>
+
+<style lang="scss">
+page {
+	background: #ffffff;
+	border-top: 1px solid #ebebeb;
+}
+.content {
+	padding: 40rpx 24rpx;
+}
+</style>

+ 125 - 0
components/cm-module/modelAlert/errorAlert.vue

@@ -0,0 +1,125 @@
+<template name="alert">
+	<view class="alert spec" :class="specClass">
+		<!-- 运费弹窗说明 -->
+		<view class="freight-alert"  @tap="hideFreight">
+			<view class="content">
+				<view class="title">
+					<text>提示</text>
+				</view>
+				<view class="text-content">
+					<view class="text">
+						<text>系统检测到您的微信已绑定供应商账户,不能继续登录</text>
+					</view>
+					<view class="exit-btn">
+						<navigator open-type="exit" target="miniProgram" class="btn">退出</navigator>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default{
+		name:'alert',
+		props:{},
+		data() {
+			return{
+				
+			}
+		},
+		created() {
+			
+		},
+		onLoad(){
+			
+		},
+		methods:{
+			hideFreight(){
+				this.$parent.isErrorAlert = false
+			},
+		},
+		onShow(){
+	
+		}
+	}
+</script>
+
+<style lang="scss">
+	/*弹窗*/
+	.model-warp.none{
+		display: none;
+	}
+	.model-warp.show{
+		display: block;
+	}
+	.freight-alert{
+		width: 100%;
+		height: 100%;
+		background: rgba(0,0,0,.5);
+		position: fixed;
+		top: 0;
+		left: 0;
+		z-index: 8888;
+		transition: all 0.4s;
+		&.none{
+			display: none;			
+		}
+		&.show{
+			display: block;
+		}
+		.content{
+			width: 530rpx;
+			height: 300rpx;
+			position: absolute;
+			background: $bg-color;
+			left: 0;
+			right: 0;
+			bottom: 0;
+			top: 0;
+			margin: auto;
+			padding: 20rpx 25rpx;
+			border-radius: 12rpx;
+			.title{
+				width: 100%;
+				height: 68rpx;
+				line-height: 68rpx;
+				font-size: $font-size-30;
+				color: $text-color;
+				text-align: center;
+				margin-bottom: 20rpx;
+				position: relative;
+			}
+			.text-content{
+				width: 70%;
+				height: auto;
+				margin: 0 auto;
+				.text{
+					line-height: 44rpx;
+					font-size: $font-size-28;
+					color:#666666;
+					text-align: center;
+				}
+				.exit-btn{
+					width: 100%;
+					height: 70rpx;
+					display: flex;
+					align-items: center;
+					flex-direction:column;
+					margin-top: 30rpx;
+					.btn{
+						width: 200rpx;
+						line-height: 70rpx;
+						font-size: $font-size-28;
+						text-align: center;
+						color: #FFFFFF;
+						border-radius: 35rpx;
+						padding: 0;
+						background: $btn-confirm;
+					}
+				}
+			}
+		}
+	}
+	
+</style>

+ 140 - 0
components/cm-module/modelAlert/freightAlert.vue

@@ -0,0 +1,140 @@
+<template name="alert">
+	<view class="alert spec" :class="specClass">
+		<!-- 运费弹窗说明 -->
+		<view class="freight-alert"  @tap="hideFreight">
+			<view class="content">
+				<view class="title">
+					<text>运费规则</text>
+					<text class="iconfont icon-iconfontguanbi" @click.stop="hideFreight"></text>
+				</view>
+				<view class="text-content">
+					<view class="text-h1">一、除含有仪器类、家具类等指定商品的订单,运费规则如下:</view>
+					<view class="text">
+						<text>1、首单,全国包邮(注:如果首单中含有不包邮的指定商品,则首单只能"到付");</text>
+						<text>2、订单商品总额满1000元,全国包邮;</text>
+						<text>3、订单商品总额不足1000元,深圳市内运费10元,广东省内深圳市外运费15元,其它地方运费到付;</text>
+						<text>4、地推送货上门无需运费(注:下单可选择运费是否到付)。</text>
+					</view>
+					<view class="text-h1">二、含有仪器类、家具类等指定商品的订单,运费到付。</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default{
+		name:'alert',
+		props:{},
+		data() {
+			return{
+				
+			}
+		},
+		created() {
+			
+		},
+		onLoad(){
+			
+		},
+		methods:{
+			hideFreight(){
+				this.$parent.isfreightTip = false
+			},
+		},
+		onShow(){
+	
+		}
+	}
+</script>
+
+<style lang="scss">
+	/*弹窗*/
+	.model-warp.none{
+		display: none;
+	}
+	.model-warp.show{
+		display: block;
+	}
+	.freight-alert{
+		width: 100%;
+		height: 100%;
+		background: rgba(0,0,0,.5);
+		position: fixed;
+		top: 0;
+		left: 0;
+		z-index: 8888;
+		transition: all 0.4s;
+		&.none{
+			display: none;			
+		}
+		&.show{
+			display: block;
+		}
+		.content{
+			width: 530rpx;
+			height: 710rpx;
+			position: absolute;
+			background: $bg-color;
+			left: 0;
+			right: 0;
+			bottom: 0;
+			top: 0;
+			margin: auto;
+			padding: 20rpx 25rpx;
+			border-radius: 12rpx;
+			.title{
+				width: 100%;
+				height: 68rpx;
+				line-height: 68rpx;
+				font-size: $font-size-28;
+				color: $text-color;
+				text-align: center;
+				margin-bottom: 32rpx;
+				position: relative;
+				.icon-iconfontguanbi{
+					width: 68rpx;
+					height: 68rpx;
+					text-align: center;
+					line-height: 68rpx;
+					position: absolute;
+					right: 0;
+					top: 0;
+					font-size: $font-size-36;
+					color: #999999;
+				}
+			}
+			.text-content{
+				width: 100%;
+				height: auto;
+				.text{
+					padding: 40rpx 0;
+					line-height: 44rpx;
+					font-size: $font-size-26;
+					color:#666666;
+					text-align: justify;
+				}
+				.text-h1{
+					line-height: 44rpx;
+					font-size: $font-size-28;
+					color: $text-color;
+					text-align: justify;
+				}
+			}
+			.btn{
+				width: 100%;
+				height: 88rpx;
+				float: left;
+				background: $btn-confirm;
+				line-height: 88rpx;
+				font-size: $font-size-28;
+				text-align: center;
+				color: #FFFFFF;
+				border-radius: 0;
+				padding: 0;
+				margin-top: 2rpx;
+			}
+		}
+	}
+	
+</style>

+ 135 - 0
components/cm-module/modelAlert/modelAlert.vue

@@ -0,0 +1,135 @@
+<template name="alert">
+	<view class="alert spec" :class="specClass">
+		<view class="model-warp">
+			<view class="model-alert">
+				<view class="model-content">
+					<view class="sm"><text>{{alertText}}</text></view>
+				</view>
+				<view class="alert-btn">
+					<view class="btn btn-cancel" @click="hideConfirm">取消</view>
+					<view class="btn btn-confirm" @click="btnConfirm(alertType)">确定</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default{
+		name:'alert',
+		props:['isShowDelModal','alertText','alertType'],
+		data() {
+			return{
+
+			}
+		},
+		created() {
+			
+		},
+		onLoad(){
+			
+		},
+		methods:{
+			hideConfirm(){
+				this.$parent.isShowDelModal = false
+			},
+			//点击事件
+			btnConfirm(type){
+				this.$emit('btnConfirm',type)
+			}
+		},
+		onShow(){
+	
+		}
+	}
+</script>
+
+<style lang="scss">
+	/*弹窗*/
+	 .model-warp.none{
+		 display: none;
+	 }
+	 .model-warp.show{
+		 display: block;
+	 }
+	 .model-warp{
+		width: 100%;
+		height: 100%;
+		background: rgba(0,0,0,.5);
+		position: fixed;
+		top: 0;
+		left: 0;
+		z-index: 8888;
+		transition: all 0.4s;
+		&.none{
+			display: none;			
+		}
+		&.show{
+			display: block;
+		}
+		.model-alert{
+			width: 518rpx;
+			height: 316rpx;
+			position: absolute;
+			background: $bg-color;
+			left: 0;
+			right: 0;
+			bottom: 0;
+			top: 0;
+			margin: auto;
+			.alert-content{
+				width: 466rpx;
+				height: 152rpx;
+				padding: 40rpx 26rpx;					
+				.t-h1,.t-p{
+					font-size: $font-size-28;
+					line-height: 40rpx;
+					color: #333333;
+					text-align:justify;
+					padding: 10rpx;
+				}
+				.t-h1{
+					border-bottom: 1px solid $border-color;
+				}
+			}
+			.model-content{
+				width: 466rpx;
+				height: 152rpx;
+				padding: 40rpx 26rpx;	
+				display: flex;
+				flex-direction: column;
+				align-items: center;
+				.sm{
+					display: flex;
+					flex: 1;
+					line-height: 152rpx;
+					flex-direction: column;
+					align-items: center;
+					text-align: center;
+					font-size: $font-size-28;
+					color: #333333;
+				}
+			}
+			.alert-btn{
+				width: 100%;
+				height: 88rpx;
+				display: flex;
+				.btn{
+					flex: 1;
+					line-height: 88rpx;
+					font-size: $font-size-28;
+					text-align: center;
+					color: #FFFFFF;
+					border-radius: 0;
+					padding: 0;
+					&.btn-cancel{
+						background: $btn-cancel;
+					}
+					&.btn-confirm{
+						background: $btn-confirm;
+					}
+				}
+			}
+		}
+	}
+</style>

+ 148 - 0
components/cm-module/modelAlert/order-alert.vue

@@ -0,0 +1,148 @@
+<template name="sharealert">
+	<view class="alert spec" >
+		<view class="model-warp" @click.stop="hideConfirm">
+			<view class="content" v-if="modelType == 1">
+				<view class="content-title"></view>
+				<view class="text-content clearfix">
+					<view class="text">
+						<text>您有采美余额¥{{payModelData.ableUserMoney}}暂未使用,是否需要抵扣订单?</text>
+						<text>抵扣后您只需再支付¥{{payModelData.pendingPayments}}</text></view>
+					<view class="alert-btn" @click="cancelConfirm(dataInfo)">不抵扣,继续付款</view>
+					<view class="alert-btn" @click="paymentConfirm(1,dataInfo)">抵扣,继续付款</view>
+				</view>				
+			</view>
+			<view class="content" v-if="modelType == 2">
+				<view class="content-title"></view>
+				<view class="text-content clearfix">
+					<view class="text">您有采美余额¥{{payModelData.ableUserMoney}}暂未使用,是否需要抵扣订单?抵扣后订单支付完成</view>
+					<view class="alert-btn" @click="cancelConfirm(dataInfo)">不抵扣,继续付款</view>
+					<view class="alert-btn" @click="paymentConfirm(2,dataInfo)">抵扣</view>
+				</view>				
+			</view>
+			<view class="content" v-if="modelType == 3">
+				<view class="content-title"></view>
+				<view class="text-content clearfix">
+					<view class="text">目前机构余额剩余¥{{payModelData.ableUserMoney.toFixed(2)}}是否抵扣订单?</view>
+					<view class="alert-btn" @click="hideConfirm">取消,不抵扣</view>
+					<view class="alert-btn" @click="paymentConfirm(3,dataInfo)">抵扣</view>
+				</view>				
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default{
+		name:'sharealert',
+		props:{
+			modelType:{
+				type:Number,
+				default:3
+			},
+			payModelData:{
+				type:Object
+			}
+		},
+		data() {
+			return{
+				dataInfo:{}
+			}
+		},
+		created() {
+			this.infoData(this.payModelData)
+		},
+		methods:{
+			infoData(el){
+				this.dataInfo = el
+			},
+			hideConfirm(){
+				this.$parent.isPayModel = false
+			},
+			cancelConfirm(data){
+				this.$emit('cancelConfirm',data)
+			},
+			paymentConfirm(type,data){
+				this.$parent.isPayModel = false
+				let _data = {type:type,order:data}
+				this.$emit('paymentConfirm',_data)
+			},
+			btnConfirm(data){//点击事件
+				this.$emit('btnConfirm',data)
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	/*弹窗*/
+	 .model-warp.none{
+		 display: none;
+	 }
+	 .model-warp.show{
+		 display: block;
+	 }
+	 .model-warp{
+		width: 100%;
+		height: 100%;
+		background: rgba(0,0,0,0.3);
+		position: fixed;
+		top: 0;
+		left: 0;
+		z-index: 10000;
+		transition: all 0.4s;
+		&.none{
+			display: none;			
+		}
+		&.show{
+			display: block;
+		}
+		.content{
+			width: 540rpx;
+			min-height: 310rpx;
+			box-sizing: border-box;
+			position: absolute;
+			left: 50%;
+			top: 50%;
+			transform: translate(-50%,-50%);
+			border-radius: 14rpx;
+			background-color: #FFFFFF;
+			padding-top: 180rpx;
+			.content-title{
+				position: absolute;
+				left: 0;
+				top: -53rpx;
+				width: 100%;
+				height: 232rpx;
+				background: url(https://static.caimei365.com/app/img/icon/icon-orderAlert@2x.png) no-repeat;
+				background-size: contain;
+			}
+			.text-content{
+				width: 100%;
+				min-height: 208rpx;
+				box-sizing: border-box;
+				padding:24rpx;
+				float: left;
+				background-color: #FFFFFF;
+				border-radius:0 0 14rpx 14rpx;
+				.text{
+					letter-spacing: 2rpx;
+					line-height: 50rpx;
+					font-size: $font-size-26;
+					color: $text-color;
+					text-align: justify;
+					margin-bottom: 30rpx;
+				}
+			}
+			.alert-btn{
+				width: 492rpx;
+				height: 88rpx;
+				background: $btn-confirm;
+				line-height: 88rpx;
+				text-align: center;
+				border-radius: 44rpx;
+				color: #FFFFFF;
+				margin-top: 20rpx;
+			}
+		}	
+	}
+</style>

+ 150 - 0
components/cm-module/modelAlert/shareAlert.vue

@@ -0,0 +1,150 @@
+<template name="sharealert">
+	<view class="alert spec" :class="specClass">
+		<view class="model-warp">
+			<view class="content">
+				<view class="text-content">
+					<view class="title">分享订单</view>
+					<view class="share">您的分享码:<text class="txt">{{shareCode}}</text></view>
+					<view class="text">
+						<text>有效期为24小时。如果对方不是您机构的运营人员,需要输入该分享码才能查看本订单</text>
+					</view>
+				</view>				
+				<view class="alert-btn">
+					<view class="btn btn-cancel" @click="hideConfirm">取消</view>
+					<!-- #ifdef MP-WEIXIN -->
+					<button class="btn btn-confirm" open-type="share" @click="btnConfirm(shareCode)">去分享</button>
+					<!-- #endif -->
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default{
+		name:'sharealert',
+		props:{
+			orderId:{
+				type:Number
+			}
+		},
+		data() {
+			return{
+				shareCode:'',
+			}
+		},
+		created() {
+			this.getShareCode(this.orderId)
+		},
+		methods:{
+			getShareCode(res){
+				this.OrderService.QueryOrderShareCode({orderId:res}).then(response =>{
+					this.shareCode = response.data
+					this.$parent.shareCode = this.shareCode;
+				}).catch(error =>{
+					this.$parent.isShareModal = false;
+					this.$util.modal('提示',error.msg,'确定','',false,() =>{})
+				})
+			},
+			hideConfirm(){
+				this.$parent.isShareModal = false
+			},
+			btnConfirm(code){//点击事件
+				this.$emit('btnConfirm')
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	/*弹窗*/
+	 .model-warp.none{
+		 display: none;
+	 }
+	 .model-warp.show{
+		 display: block;
+	 }
+	 .model-warp{
+		width: 100%;
+		height: 100%;
+		background: rgba(0,0,0,0.3);
+		position: fixed;
+		top: 0;
+		left: 0;
+		z-index: 10000;
+		transition: all 0.4s;
+		&.none{
+			display: none;			
+		}
+		&.show{
+			display: block;
+		}
+		.content{
+			width: 518rpx;
+			height: 418rpx;
+			position: absolute;
+			background: $bg-color;
+			left: 0;
+			right: 0;
+			bottom: 0;
+			top: 0;
+			margin: auto;
+			border-radius: 24rpx;
+			.text-content{
+				width: 448rpx;
+				height: 264rpx;
+				padding: 20rpx 35rpx;
+				float: left;
+				.title{
+					line-height: 40rpx;
+					font-size: $font-size-28;
+					color: $text-color;
+					text-align: center;
+					font-weight: bold;
+					margin-bottom: 36rpx;
+				}
+				.share{
+					line-height: 36rpx;
+					font-size: $font-size-26;
+					color: $text-color;
+					text-align: justify;
+					margin-top: 22rpx;
+					font-weight: normal;
+					.txt{
+						margin-left: 10rpx;
+						color: #FF2A2A;
+					}
+				}
+				.text{
+					line-height: 36rpx;
+					font-size: $font-size-26;
+					color: $text-color;
+					text-align: justify;
+					margin-top: 22rpx;
+				}
+			}
+			.alert-btn{
+				width: 80%;
+				height: 70rpx;
+				display: flex;
+				margin: 0 auto;
+				.btn{
+					flex: 1;
+					line-height: 70rpx;
+					font-size: $font-size-28;
+					text-align: center;
+					color: #FFFFFF;
+					border-radius: 35rpx;
+					padding: 0;
+					margin: 0 15rpx;
+					&.btn-cancel{
+						background: $btn-cancel;
+					}
+					&.btn-confirm{
+						background: $btn-confirm;
+					}
+				}
+			}
+		}	
+	}
+</style>

+ 140 - 0
components/cm-module/modelAlert/shareModel.vue

@@ -0,0 +1,140 @@
+<template name="sharealert">
+	<view class="alert spec" :class="specClass">
+		<view class="model-warp">
+			<view class="content">
+				<view class="text-content">
+					<view class="title">分享登录</view>
+					<view class="text">
+						<text>分享后,机构联系人可直接通过分享页面登录并绑定微信成为运营人员</text>
+					</view>
+				</view>				
+				<view class="alert-btn">
+					<view class="btn btn-cancel" @click="hideConfirm">取消</view>
+					<!-- #ifdef MP-WEIXIN -->
+					<button class="btn btn-confirm" open-type="share" @click="btnConfirm(bindId)">去分享</button>
+					<!-- #endif -->
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default{
+		name:'sharealert',
+		props:{
+			bindId:{
+				type:Number
+			}
+		},
+		data() {
+			return{
+				shareCode:'',
+			}
+		},
+		created() {
+			
+		},
+		methods:{
+			hideConfirm(){
+				this.$parent.isShareModal = false
+			},
+			btnConfirm(orderID){//点击事件
+				this.$emit('btnConfirm')
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	/*弹窗*/
+	 .model-warp.none{
+		 display: none;
+	 }
+	 .model-warp.show{
+		 display: block;
+	 }
+	 .model-warp{
+		width: 100%;
+		height: 100%;
+		background: rgba(0,0,0,0.3);
+		position: fixed;
+		top: 0;
+		left: 0;
+		z-index: 10000;
+		transition: all 0.4s;
+		&.none{
+			display: none;			
+		}
+		&.show{
+			display: block;
+		}
+		.content{
+			width: 518rpx;
+			height: 360rpx;
+			position: absolute;
+			background: $bg-color;
+			left: 0;
+			right: 0;
+			bottom: 0;
+			top: 0;
+			margin: auto;
+			border-radius: 24rpx;
+			.text-content{
+				width: 448rpx;
+				height: 200rpx;
+				padding: 30rpx 35rpx;
+				float: left;
+				.title{
+					line-height: 44rpx;
+					font-size: $font-size-28;
+					color: $text-color;
+					text-align: center;
+					font-weight: bold;
+					margin-bottom: 36rpx;
+				}
+				.share{
+					line-height: 36rpx;
+					font-size: $font-size-26;
+					color: $text-color;
+					text-align: justify;
+					margin-top: 22rpx;
+					font-weight: normal;
+					.txt{
+						margin-left: 10rpx;
+						color: #FF2A2A;
+					}
+				}
+				.text{
+					line-height: 44rpx;
+					font-size: $font-size-28;
+					color: $text-color;
+					text-align: justify;
+					margin-top: 22rpx;
+				}
+			}
+			.alert-btn{
+				width: 80%;
+				height: 70rpx;
+				display: flex;
+				margin: 0 auto;
+				.btn{
+					flex: 1;
+					line-height: 70rpx;
+					font-size: $font-size-28;
+					text-align: center;
+					color: #FFFFFF;
+					border-radius: 35rpx;
+					padding: 0;
+					margin: 0 15rpx;
+					&.btn-cancel{
+						background: #e1e1e1;
+					}
+					&.btn-confirm{
+						background: #4ad04c;
+					}
+				}
+			}
+		}	
+	}
+</style>

+ 235 - 0
components/cm-module/orderDetails/activipopu.vue

@@ -0,0 +1,235 @@
+<template name="cm-price">
+	<!--促销活动弹窗提示-->
+	<tui-bottom-popup :radius="true" :show="popupShow" @close="hidePopup()">
+		<view class="tui-popup-box clearfix">
+			<view class="tui-scrollview-box">
+				<view class="box-text">
+					<text>促销时间:</text>
+					<text class="txt" v-if="Promotion.status == 1">不限时</text>
+					<text class="txt" v-else>{{ Promotion.beginTime }} ~ {{ Promotion.endTime }}</text>
+				</view>
+				<view class="box-title" v-show="Promotion.mode ==2">
+					<text>此商品参与{{Promotion.name}},满</text>
+					<text class="txt">¥{{Promotion == null ? '0.00' : Promotion.touchPrice | NumFormat}}</text>减
+					<text class="txt">¥{{Promotion == null ? '0.00' : Promotion.reducedPrice | NumFormat}}</text>
+				</view>
+				<view class="box-title" v-show="Promotion.mode==3">
+					<text>此商品参与{{Promotion.name}},满</text>
+					<text class="txt">¥{{Promotion.touchPrice}}</text>赠送商品(赠品见订单详情)
+				</view>
+			</view>
+			<view class="tui-right-flex tui-popup-btn" :style="{ paddingBottom :isIphoneX ? '68rpx' : '0rpx' }">
+				<view class="tui-flex-1">
+					<view class="tui-button" @click="hidePopup()">了解</view>
+				</view>
+			</view>
+		</view>	
+	</tui-bottom-popup>
+</template>
+
+<script>
+	import { mapState,mapMutations } from 'vuex'
+	export default{
+		name:'cm-price',
+		props:{
+			Promotion:{
+				type:Object,
+			},
+			popupShow:{
+				type:Boolean,
+				default:false
+			}
+		},
+		data() {
+			return{
+				isIphoneX:this.$store.state.isIphoneX,
+			}
+		},
+		filters: {
+			NumFormat:function(text) {//处理金额
+				return Number(text).toFixed(2);
+			},
+		},
+		created() {
+			
+		},
+		computed: {
+			...mapState(['hasLogin','isWxAuthorize'])
+		},
+		methods:{
+			hidePopup(){
+				this.$parent.popupShow = false
+			},
+			goGoodActiveFn(id){
+				this.$parent.popupShow = false
+				this.$api.navigateTo('/pages/goods/goods-active?id='+id)
+			}
+		},
+		
+	}
+</script>
+
+<style lang="scss">	
+	.tui-flex-1 {
+		flex: 1;
+	}
+	.tui-popup-box {
+		position: relative;
+		box-sizing: border-box;
+		min-height: 220rpx;
+		padding:24rpx 24rpx 0 24rpx;
+	}
+	.tui-scrollview-box{
+		width: 100%;
+		height: auto;
+		float: left;
+		box-sizing: border-box;
+		.ladder-main{
+			width: 100%;
+			height: 320rpx;
+			border: 1px solid rgba(225,86,22,0.3);
+			border-radius: 10rpx;
+			.ladder-item{
+				width: 100%;
+				height: 80rpx;
+				float: left;
+				border-bottom: 1px solid rgba(225,86,22,0.3);
+				&:nth-child(1){
+					.ladder-item-td{
+						color: #333333;
+					}
+				}
+				&:last-child{
+					border-bottom: none;
+				}
+				.ladder-item-td{
+					width:50%;
+					text-align: center;
+					line-height: 80rpx;
+					font-size: $font-size-24;
+					color: $color-system;
+					box-sizing: border-box;
+					float: left;
+					&:nth-child(1){
+						border-right: 1px solid rgba(225,86,22,0.3);
+					}
+				}
+			}
+		}
+		.box-title{
+			font-size: $font-size-26;
+			color: $text-color;
+			text-align: left;
+			line-height: 56rpx;
+			.txt{
+				color: $color-system;
+				margin: 0 8rpx;
+			}
+		}
+		.box-text{
+			font-size: $font-size-26;
+			color: $text-color;
+			text-align: left;
+			line-height: 56rpx;
+			.txt{
+				color: $color-system;
+			}
+		}
+		.box-product{
+			width: 100%;
+			height: auto;
+			margin-top: 20rpx;
+			.title{
+				font-size: $font-size-24;
+				color: $text-color;
+				text-align: left;
+				line-height: 54rpx;
+			}
+			.box-product-main{
+				width: 100%;
+				height: 136rpx;
+				.image{
+					width: 134rpx;
+					height: 134rpx;
+					border: 1px solid #EBEBEB;
+					float: left;
+					image{
+						width: 100%;
+						height: 100%;
+						display: block;
+					}
+				}
+				.info{
+					width: 540rpx;
+					height: 134rpx;
+					float: left;
+					margin-left: 16rpx;
+					position: relative;
+					.name{
+						width: 100%;
+						float: left;
+						line-height: 40rpx;
+						font-size: $font-size-28;
+						color: $text-color;
+						-o-text-overflow: ellipsis;
+						text-overflow: ellipsis;
+						display: -webkit-box;
+						word-break: break-all;
+						-webkit-box-orient: vertical;
+						-webkit-line-clamp: 2;
+						overflow: hidden;
+					}
+					.num{
+						width: 100%;
+						height: 44rpx;
+						font-size: $font-size-24;
+						color: $text-color;
+						text-align: left;
+						line-height: 44rpx;
+						position: absolute;
+						bottom: 0;
+						left: 0;
+					}
+				}
+			}
+		}
+	}
+	
+	.tui-popup-btn {
+		width: 100%;
+		height: auto;
+		float: left;
+		margin-top: 24rpx;
+		.tui-button{
+			width: 100%;
+			height: 88rpx;
+			background: $btn-confirm;
+			line-height: 88rpx;
+			text-align: center;
+			color: #FFFFFF;
+			font-size: $font-size-28;
+			border-radius: 14rpx;
+		}
+	}
+</style>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 523 - 0
components/cm-module/orderDetails/goodsList.vue

@@ -0,0 +1,523 @@
+<template name="goods">
+	<view class="goods-template">
+		<!-- 商品列表 -->
+		<view class="goods-list">
+			<view v-for="(item, index) in list" :key="index" class="goods-item clearfix">
+				<view class="shoptitle">
+					<view v-if="item.shopPromotion" class="floor-item-act">
+						<view class="floor-tags" @click.stop="clickPopupShow(item.shopPromotion)">{{
+							item.shopPromotion.name
+						}}</view>
+					</view>
+					<view class="title-text" v-if="information.secondHandOrderFlag == 1"
+						>{{ item.shopName }}
+						<label class="paymenttext" v-if="information.affirmPaymentFlag == 1">已确认打款供应商</label>
+					</view>
+					<view class="title-text" v-else @click="goShophome(item)">
+						{{ item.shopName }} <label class="iconfont icon-jinrudianpu"></label>
+					</view>
+				</view>
+				<view class="productlist" v-for="(pros, idx) in item.orderProductList" :key="idx">
+					<view class="goods-pros-t " @click="details(pros)">
+						<view class="pros-left">
+							<view class="pros-img">
+								<image :src="pros.image" alt="" />
+								<text class="tips" v-if="pros.giftType == 2 || pros.giftType == 1">赠品</text>
+							</view>
+						</view>
+						<view class="pros-product">
+							<view class="producttitle">{{ pros.name }}</view>
+							<view class="productspec product-view" v-if="pros.productCategory != 2"
+								>规格:{{ pros.productUnit ? pros.productUnit : '' }}</view
+							>
+							<view class="product-view">
+								<view
+									class="view-num red"
+									:class="
+										pros.svipPriceFlag == 1 || PromotionsFormat(pros.productPromotion) ? 'none' : ''
+									"
+									>¥{{ pros.price | NumFormat }}</view
+								>
+								<view class="view-num right">x {{ pros.num }}</view>
+							</view>
+							<view class="floor-item-act">
+								<template v-if="pros.productPromotion">
+									<view
+										v-if="PromotionsFormat(pros.productPromotion)"
+										class="floor-tags"
+										@click.stop="clickPopupShow(pros.productPromotion)"
+									>
+										{{ pros.productPromotion.name }}
+										<text v-if="pros.productPromotion != null && pros.productPromotion.type != 3">
+											:¥{{
+												pros.productPromotion == null
+													? '0.00'
+													: pros.productPromotion.touchPrice | NumFormat
+											}}
+										</text>
+									</view>
+									<view
+										v-else-if="pros.productPromotion.type != 3"
+										class="floor-tags"
+										@click.stop="clickPopupShow(pros.productPromotion)"
+										>{{ pros.productPromotion.name }}</view
+									>
+								</template>
+								<template v-if="pros.svipPriceFlag == 1">
+									<view class="svip-tags">
+										<view class="tags">SVIP</view>
+										<view class="price">{{ pros.svipPriceTag }}</view>
+									</view>
+								</template>
+							</view>
+						</view>
+					</view>
+					<view class=" product-info clearfix"> 
+						<view class="product-view" v-if="pros.returnedNum > 0 || pros.actualCancelNum > 0">
+							<view class="view-num">已退货/已取消:<text class="text">{{ pros.returnedNum }}/{{ pros.actualCancelNum }}</text></view>
+						</view>
+						<view class="product-view" v-if="pros.svipPriceType != 1">
+							<view class="view-num">折扣:<text class="text">{{ pros.discount == null ? '0' : pros.discount }}%</text></view>
+						</view>
+						<view class="product-view">
+							<view class="view-num">税率:<text class="text">{{ pros.taxRate }}%</text></view>
+						</view>
+						<view class="product-view">
+							<view class="view-num">折后单价:<text class="text">¥{{ pros.discountPrice | NumFormat }}</text></view>
+						</view>
+						<view class="product-view allPrice">
+							<view class="view-num">合计:<text class="text">¥{{ pros.totalFee | NumFormat }}</text></view>
+						</view>
+					</view>
+				</view>
+				<view class="goods-pros-m" v-if="item.note">
+					<view class="m-text">留言:</view>
+					<view class="m-input">
+						<view class="text">{{ item.note ? item.note : '' }}</view>
+					</view>
+				</view>
+				<view class="goods-pros-b clearfix" v-if="information.onlinePayFlag == 0">
+					<view class="pros-price-view" v-if="item.isHandelShow">
+						<view class="price-view-le">商品总额:</view>
+						<view class="price-view-ri">¥{{ item.totalAmount | NumFormat }}</view>
+					</view>
+					<view class="pros-price-view" v-if="item.isHandelShow">
+						<view class="price-view-le">优惠:</view>
+						<view class="price-view-ri">¥{{ item.eachDiscount | NumFormat }}</view>
+					</view>
+					<view class="pros-price-view" v-if="item.isHandelShow">
+						<view class="price-view-le">应付金额:</view>
+						<view class="price-view-ri">¥{{ item.realPay | NumFormat }}</view>
+					</view>
+					<view class="pros-price-view" v-if="item.isHandelShow">
+						<view class="price-view-le">已付金额:</view>
+						<view class="price-view-ri">¥{{ item.receiptAmount | NumFormat }}</view>
+					</view>
+					<view class="pros-price-view">
+						<view class="price-view-le">待付金额:</view>
+						<view class="price-view-ri red">¥{{ item.obligation | NumFormat }}</view>
+					</view>
+					<view class="pros-price-btn">
+						<view class="btn" @click="handelShowDetails(item)">
+							{{ item.isHandelShow ? '收起' : '查看更多' }}
+							<text class="iconfont" :class="item.isHandelShow ? 'icon-xiangshangjiantou' : 'icon-xiangxiajiantou'"></text>
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	name: 'goods',
+	props: {
+		shopOrderData: {
+			type: Array
+		},
+		information: {
+			type: Object
+		}
+	},
+	data() {
+		return {
+			list: [],
+			vipFlag: 0,
+		}
+	},
+	created() {
+		this.initGetStotage(this.shopOrderData)
+	},
+	filters: {
+		NumFormat(value) {
+			//处理金额
+			return Number(value).toFixed(2)
+		},
+		formatIncludedTax(value) {
+			if (value === '1') {
+				return '不含税 '
+			} else if (value === '2') {
+				return '含税'
+			} else {
+				return ''
+			}
+		}
+	},
+	computed: {},
+	methods: {
+		async initGetStotage(data) {
+			const userInfo = await this.$api.getStorage()
+			this.vipFlag = userInfo.vipFlag ? userInfo.vipFlag : 0
+			this.list = data.map((el,index)=>{
+				el.isHandelShow = false
+				return el
+			})
+		},
+		handelShowDetails(item){
+			item.isHandelShow = !item.isHandelShow
+		},
+		goShophome(shop) {
+			if(shop.shopType === 2){
+				return
+			}
+			this.$api.navigateTo(`/pages/supplier/user/my-shop?shopId=${shop.shopId}`)
+		},
+		details(pros) {
+			if (pros.validFlag == 9) {
+				return
+			} else {
+				this.$api.navigateTo(`/pages/goods/product?id=${pros.productId}`)
+			}
+		},
+		clickPopupShow(pros) {
+			console.log(pros)
+			this.$emit('popupClick', pros)
+		},
+		PromotionsFormat(promo) {
+			//促销活动类型数据处理
+			if (promo != null) {
+				if (promo.type == 1 && promo.mode == 1) {
+					return true
+				} else {
+					return false
+				}
+			}
+			return false
+		}
+	}
+}
+</script>
+
+<style lang="scss">
+.goods-template {
+	width: 100%;
+	height: auto;
+	background: #ffffff;
+	float: left;
+	margin-top: 24rpx;
+	.goods-list {
+		width: 100%;
+		height: auto;
+		background: #f7f7f7;
+		.goods-item {
+			width: 702rpx;
+			padding: 24rpx;
+			height: auto;
+			background: #ffffff;
+			margin-bottom: 24rpx;
+			&:last-child {
+				margin-bottom: 0;
+			}
+		}
+		.shoptitle {
+			width: 100%;
+			float: left;
+			height: 56rpx;
+			line-height: 56rpx;
+			margin-bottom: 12rpx;
+            .floor-item-act{
+                height: 56rpx;
+                text-align: center;
+                box-sizing: border-box;
+                float: left;
+                padding: 10rpx 0;
+                margin-right: 12rpx;
+                .floor-tags{
+                    height: 28rpx;
+                    border-radius: 6rpx;
+                    background-color: #FFFFFF;
+                    line-height: 28rpx;
+                    color: $color-system;
+                    text-align: center;
+                    display: inline-block;
+                    padding:0 6rpx;
+                    font-size: $font-size-20;
+                    border: 1px solid #F3B574;
+                    float: left;
+                }
+            }
+			.title-text {
+				width: 400rpx;
+				overflow: hidden;
+				text-overflow: ellipsis;
+				white-space: nowrap;
+				float: left;
+				font-size: $font-size-28;
+				color: $text-color;
+				text-align: left;
+				line-height: 56rpx;
+				font-weight: bold;
+				.iconfont {
+					color: #999999;
+					font-size: 28rpx;
+					margin-left: 10rpx;
+				}
+				.paymenttext {
+					color: #f9a94b;
+					font-size: $font-size-22;
+					margin-left: 20rpx;
+				}
+			}
+		}
+		.productlist {
+			width: 100%;
+			height: auto;
+			padding: 0;
+			box-sizing: border-box;
+			border-bottom: 1px solid #E1E1E1;
+		}
+		.goods-pros-t {
+			display: flex;
+			width: 100%;
+			height: auto;
+			margin: 20rpx 0;
+			.pros-left {
+				width: 210rpx;
+				height: 100%;
+				margin: 0 26rpx 0 0;
+			}
+			.pros-img {
+				width: 210rpx;
+				height: 210rpx;
+				border-radius: 10rpx;
+				border: 1px solid #f3f3f3;
+				position: relative;
+				.tips {
+					display: inline-block;
+					width: 80rpx;
+					height: 40rpx;
+					background-image: linear-gradient(214deg, #ff4500 0%, #ff5800 53%, #ff4367 100%);
+					line-height: 40rpx;
+					text-align: center;
+					font-size: $font-size-24;
+					color: #ffffff;
+					border-radius: 10rpx 0 10rpx 0;
+					position: absolute;
+					top: 0;
+					left: 0;
+				}
+				image {
+					width: 210rpx;
+					height: 210rpx;
+					border-radius: 10rpx;
+				}
+			}
+		}
+		.product-info {
+			padding: 10rpx 0;
+			.product-view {
+				font-size: $font-size-24;
+				color: #999999;
+				overflow: hidden;
+				height: 44rpx;
+				line-height: 44rpx;
+				float: left;
+				width: 50%;
+				.view-num {
+					float: left;
+					.text{
+						color: #333333;
+					}
+				}
+			}
+		}
+		.pros-product {
+			width: 468rpx;
+			height: 100%;
+			line-height: 36rpx;
+			font-size: $font-size-26;
+			position: relative;
+			.product-view {
+				&.allPrice {
+					width: 100%;
+				}
+				.view-num {
+					flex: 1;
+					text-align: left;
+					font-size: $font-size-26;
+					color: #999999;
+					line-height: 44rpx;
+					float: left;
+					&.right {
+						float: right;
+					}
+					&.red {
+						color: #ff2000;
+						font-weight: bold;
+						&.none {
+							text-decoration: line-through;
+							color: #999999;
+						}
+					}
+				}
+			}
+			.producttitle {
+				width: 100%;
+				display: inline-block;
+				height: auto;
+				text-overflow: ellipsis;
+				display: -webkit-box;
+				word-break: break-all;
+				-webkit-box-orient: vertical;
+				-webkit-line-clamp: 2;
+				overflow: hidden;
+				margin-bottom: 8rpx;
+			}
+			.productspec {
+				height: 44rpx;
+				color: #999999;
+				line-height: 44rpx;
+				text-overflow: ellipsis;
+				display: -webkit-box;
+				word-break: break-all;
+				-webkit-box-orient: vertical;
+				-webkit-line-clamp: 1;
+				overflow: hidden;
+			}
+			.productprice {
+				height: 48rpx;
+				position: absolute;
+				width: 100%;
+				bottom: 0;
+				.price {
+					line-height: 48rpx;
+					font-size: $font-size-28;
+					width: 48%;
+					color: #ff2a2a;
+					float: left;
+					.price {
+						line-height: 48rpx;
+						font-size: $font-size-28;
+						width: 48%;
+						color: #ff2a2a;
+						float: left;
+						font-weight: bold;
+					}
+				}
+				.count {
+					height: 100%;
+					float: right;
+					position: relative;
+					.small {
+						color: #666666;
+					}
+				}
+			}
+			.floor-item-act {
+				width: 100%;
+				height: 56rpx;
+				text-align: center;
+				box-sizing: border-box;
+				float: left;
+				padding: 10rpx 0 0 0;
+			}
+			.floor-item-act {
+				height: 56rpx;
+				text-align: center;
+				box-sizing: border-box;
+				float: left;
+				padding: 10rpx 0;
+				margin-right: 12rpx;
+			}
+		}
+		.goods-pros-m {
+			width: 100%;
+			height: auto;
+			line-height: 76rpx;
+			font-size: $font-size-26;
+			color: $text-color;
+			float: left;
+			.m-text {
+				width: 62rpx;
+				float: left;
+				padding-right: 20rpx;
+				font-weight: bold;
+			}
+			.m-input {
+				display: -webkit-box;
+				display: -webkit-flex;
+				display: flex;
+				-webkit-box-align: center;
+				-webkit-align-items: center;
+				align-items: center;
+				position: relative;
+				width: 620rpx;
+				height: auto;
+				padding: 20rpx 0 10rpx 0;
+				background: #ffffff;
+				.text {
+					width: 100%;
+					height: 100%;
+					font-size: $font-size-26;
+					line-height: 36rpx;
+					color: #333333;
+				}
+			}
+		}
+		.goods-pros-b {
+			width: 100%;
+			padding-top: 12rpx;
+			float: left;
+			.pros-price-view{
+				width: 100%;
+				height: 44rpx;
+				font-size: 24rpx;
+				line-height: 44rpx;
+				.price-view-le{
+					float: left;
+					color: #999999;
+					text-align: left;
+				}
+				.price-view-ri{
+					float: right;
+					color: #333333;
+					text-align: right;
+					&.red{
+						color: #F94B4B;
+					}
+				}
+			}
+			.pros-price-btn{
+				width: 100%;
+				height: 48rpx;
+				.btn{
+					width: 168rpx;
+					height: 48rpx;
+					line-height: 46rpx;
+					box-sizing: border-box;
+					border: 2rpx solid #e1e1e1;
+					border-radius: 8rpx;
+					text-align: center;
+					color: #b2b2b2;
+					margin: 0 auto;
+					font-size: $font-size-24;
+					.iconfont {
+						
+					}
+				}
+			}
+		}
+	}
+}
+</style>

+ 197 - 0
components/cm-module/orderDetails/invoiceTent.vue

@@ -0,0 +1,197 @@
+<template name="invoice">
+	<view class="invoice-template">
+		 <!-- 发票信息 -->
+		 <view class="invoice-content">
+		 	<view class="invoice-title">发票信息</view>
+			<view class="invoice-empty" v-if="isEmpty">
+			 	<text>不要发票</text></text>
+			</view>
+			<view class="invoice-text" v-else>
+				<view class="invoice-top" @click="showInvoice">
+					<view class="name">{{orderInvoice.invoiceTitle ? orderInvoice.invoiceTitle : ''}}</view>
+					<text class="iconfont icon-web_xiangxiazhankai" :class="{'icon-web_xiangxiazhankai-active':isOpen}"></text>
+				</view>
+				<view :class="{'invoice-warp--hide':!isOpen}" class="invoice-warp">
+					<view  class="invoice-warp__wrapper invoice-animation" 
+						   :style="{'transform':isOpen?'translateY(0)':'translateY(-50%)','-webkit-transform':isOpen?'translateY(0)':'translateY(-50%)'}">
+						<view class="table">
+							<text class="label-name">单位名称:</text>
+							<text>{{orderInvoice.invoiceTitle ? orderInvoice.invoiceTitle : ''}}</text>
+						</view>
+						<view class="table long">
+							<text class="label-name">纳锐人识别号:</text>
+							<text>{{orderInvoice.corporationTaxNum ? orderInvoice.corporationTaxNum :''}}</text> 
+						</view>
+						<view class="table">
+							<text class="label-name">注册地址:</text>
+							<text>{{orderInvoice.registeredAddress ? orderInvoice.registeredAddress : ''}}</text> 
+						</view>
+						<view class="table">
+							<text class="label-name">注册电话:</text>
+							<text>{{orderInvoice.registeredPhone ? orderInvoice.registeredPhone : ''}}</text>
+						</view>
+						<view class="table">
+							<text class="label-name">开户银行:</text>
+							<text>{{orderInvoice.openBank ? orderInvoice.openBank : ''}}</text>
+						</view>
+						<view class="table">
+							<text class="label-name">银行账号:</text>
+							<text>{{bankAccountNo ? bankAccountNo : ''}}</text>
+						</view>
+					</view>
+				</view>
+			</view>
+		 </view>
+	</view>
+</template>
+
+<script>
+	export default{
+		name:"invoice",
+		props:{
+			orderInvoice:{
+				type:Object
+			}
+		},
+		data() {
+			return{
+				isEmpty:false,
+				title:'发票信息',
+				isOpen:false,
+				bankAccountNo:''
+			}
+		},
+		created(){
+			this.initData(this.orderInvoice)
+		},
+		computed: {
+
+		},
+		methods:{
+			initData(res) {
+				if(res == null || res.type == 0){
+					this.isEmpty = true
+				}else{
+					this.isEmpty = false
+					this.bankAccountNo = this.$reg.bankRegex(res.bankAccountNo)
+				}
+			},
+			onMessage(pros){
+			},
+			showInvoice(){
+				this.isOpen = !this.isOpen
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.invoice-template{
+		width: 100%;
+		height: auto;
+		background: #FFFFFF;
+		float: left;
+		margin-top: 24rpx;
+		.invoice-content{
+			width: 702rpx;
+			padding: 20rpx 24rpx;
+		}
+		.invoice-title{
+			font-size: $font-size-28;
+			color: $text-color;
+			text-align: left;
+			line-height: 40rpx;
+			font-weight: bold;
+			margin-bottom: 30rpx;
+		}
+		.invoice-empty{
+			font-size: $font-size-28;
+			color: $text-color;
+			text-align: left;
+			line-height: 40rpx;
+			.txt{
+				font-size: $font-size-24;
+				color: #999999;
+			}
+		}
+		.invoice-animation {
+			/* transition: transform 0.3s ease;*/
+			transition-property: transform;
+			transition-duration: 0.3s;
+			transition-timing-function: ease;
+		}
+		.invoice-text{
+			width: 100%;
+			height: auto;
+			.invoice-top{
+				width: 100%;
+				height: 40rpx;
+				line-height: 40rpx;
+				font-size: $font-size-28;
+				color: $text-color;
+				text-align: left;
+				.name{
+					width: 400rpx;
+					float: left;
+					-o-text-overflow: ellipsis;
+					text-overflow: ellipsis;
+					display: -webkit-box;
+					word-break: break-all;
+					-webkit-box-orient: vertical;
+					-webkit-line-clamp: 1;
+					overflow: hidden;
+				}
+				.icon-web_xiangxiazhankai{
+					transform: rotate(0deg);
+					transform-origin: center center;
+					float: right;
+					font-size: $font-size-32;
+					color: #000000;
+					/* transition: transform 0.3s ease;*/
+					transition-property: transform;
+					transition-duration: 0.3s;
+					transition-timing-function: ease;
+				}
+				.icon-web_xiangxiazhankai-active{
+					transform: rotate(180deg);
+				}
+			}
+			.invoice-warp{
+				width: 100%;
+				padding: 24rpx 0 0 0;
+				overflow: hidden;
+				.table{
+					padding-left: 130rpx;
+					height: auto;
+					line-height: 64rpx;
+					font-size: $font-size-26;
+					color: $text-color;
+					text-align: left;
+					position: relative;
+					.label-name{
+						display: inline-block;
+						line-height: 64rpx;
+						position: absolute;
+						left: 0;
+						top: 0;
+					}
+					&.long{
+						padding-left: 180rpx;
+					}
+				}
+			}	
+			.invoice-warp__wrapper{
+				/* #ifndef APP-NVUE */
+				display: flex;
+				/* #endif */
+				flex-direction: column;
+				padding-top: 20rpx;
+			}
+			.invoice-warp--hide {
+				padding: 0 0;
+				height: 0px;
+				line-height: 0px;
+			}		
+		}
+	}
+</style>

+ 181 - 0
components/cm-module/orderDetails/logisticsRecord.vue

@@ -0,0 +1,181 @@
+<template name="logistics">
+	<view class="logistics-template">
+		<!-- 物流信息 -->
+		<view class="logistics-content" v-if="logisticsData.length > 0" v-for="(item,index) in logisticsData" :key="index">
+			<view class="logistics-top">
+				<text class="name">物流信息</text>
+			</view>
+			<view class="logistics-warp">
+				<view  class="logistics-warp__wrapper">
+					<view class="logistics-main">
+					 	<view class="logistics-main-top">
+					 		<view class="main-top" @click="showlogistics(index)">
+								{{item.expressname}}:{{item.expressNumber}}
+								<text class="clipboard" @click="clipboard(item.expressNumber)">复制</text>
+								<text class="arrow-showMore iconfont icon-web_xiangxiazhankai" :style="{'transform':item.isOpen?'rotate(180deg)':'rotate(0)'}"></text>
+							</view>
+					 		<view class="main-bot">
+								发货时间:{{item.expressNewtime}}
+							</view>
+					 	</view>
+						<view v-if="item.expressRecord.length > 0" v-for="(infoItem,infoIndex) in item.expressRecord" :key="infoIndex" :class="{'logistics-warp--hide':!item.isOpen}" class="logistics-main-bot logistics-animation" :style="{'transform':item.isOpen?'translateY(0)':'translateY(-50%)','-webkit-transform':item.isOpen?'translateY(0)':'translateY(-50%)'}" >
+							{{infoItem.time}}  {{infoItem.desc}}
+						</view>
+						<view v-if="item.expressRecord" :class="{'logistics-warp--hide':!item.isOpen}" class="logistics-main-bot logistics-animation" :style="{'transform':item.isOpen?'translateY(0)':'translateY(-50%)','-webkit-transform':item.isOpen?'translateY(0)':'translateY(-50%)'}">
+							暂无物流信息
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+		<view class="logistics-content" v-else>
+			暂无物流信息
+		 </view>
+	</view>
+</template>
+
+<script>
+	const thorui = require("@/components/clipboard/clipboard.thorui.js")
+	export default{
+		name:"logistics",
+		data() {
+			return{
+				title:'发票信息',
+				logisticsData:''
+			}
+		},
+		created(){
+			
+		},
+		computed: {
+
+		},
+		methods:{
+			initData(res) {
+				this.logisticsData = res;
+			},
+			showlogistics(index){
+				let isOpen = this.logisticsData[index]['isOpen'];
+				this.logisticsData[index]['isOpen'] = !isOpen;
+			},
+			clipboard(data) {
+				thorui.getClipboardData(data, (res) => {
+					if (res) {
+						this.$util.msg("复制成功",2000,true,'success');
+					} else {
+						this.$util.msg("复制失败",2000,true,'none');
+					}
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.logistics-template{
+		width: 100%;
+		height: 100%;
+		background: #FFFFFF;
+		float: left;
+		.logistics-content{
+			width: 702rpx;
+			padding: 20rpx 24rpx;
+			height: auto;
+			.arrow-showMore {
+				position: absolute;
+				right: 24rpx;
+				z-index: 99;
+			}
+			.logistics-top{
+				width: 100%;
+				height: 40rpx;
+				line-height: 40rpx;
+				font-size: $font-size-28;
+				color: $text-color;
+				text-align: left;
+				padding-bottom: 24rpx;
+				border-bottom: 1px solid #F8F8F8;
+				.name{
+					float: left;
+					font-weight: bold;
+				}
+				.icon-web_xiangxiazhankai{
+					transform: rotate(0deg);
+					transform-origin: center center;
+					float: right;
+					font-size: $font-size-32;
+					color: #000000;
+					/* transition: transform 0.3s ease;*/
+					transition-property: transform;
+					transition-duration: 0.3s;
+					transition-timing-function: ease;
+				}
+				.icon-web_xiangxiazhankai-active{
+					transform: rotate(180deg);
+				}
+			}
+			.logistics-warp{
+				width: 100%;
+				overflow: hidden;
+				.table{
+					height: 76rpx;
+					line-height: 76rpx;
+					font-size: $font-size-26;
+					color: $text-color;
+					text-align: left;
+				}
+			}	
+			.logistics-main-top{
+				width: 100%;
+				height: auto;
+				float: left;
+				padding-top: 24rpx;
+				margin-bottom: 14rpx;
+				.main-top,.main-bot{
+					font-size: $font-size-28;
+					color: $text-color;
+					line-height: 40rpx;
+					margin: 4rpx 0;
+				}
+			}
+			.logistics-main-bot{
+				width: 100%;
+				height: auto;
+				font-size: $font-size-24;
+				color: $text-color;
+				line-height: 56rpx;
+				text-align: justify;
+			}
+			.logistics-animation {
+				/* transition: transform 0.3s ease;*/
+				transition-property: transform;
+				transition-duration: 0.3s;
+				transition-timing-function: ease;
+			}
+			.logistics-warp__wrapper{
+				/* #ifndef APP-NVUE */
+				display: flex;
+				/* #endif */
+				flex-direction: column;
+			}
+			.logistics-warp--hide {
+				// padding: 0 0;
+				// height: 0px;
+				// line-height: 0px;
+				display: none;
+			}	
+			.clipboard{
+				width: 84rpx;
+				height: 36rpx;
+				background: linear-gradient(34deg,rgba(255,41,41,1) 0%,rgba(255,109,27,1) 100%);
+				text-align: center;
+				font-size: $font-size-24;
+				color: #FFFFFF;
+				border-radius: 6rpx;
+				line-height: 36rpx;
+				display: inline-block;
+				margin-left: 42rpx;
+			}
+		}
+	}
+</style>

+ 174 - 0
components/cm-module/orderDetails/orderAddress.vue

@@ -0,0 +1,174 @@
+<template name="address">
+	<view class="address-template">
+		 <!-- 地址信息 -->
+		 <view class="address-section">
+		 	<view class="address-content">
+				<view class="address-cen">
+					<view class="top">
+						<view class="name">{{addressData.receiver ? addressData.receiver : ''}}</view>
+						<view class="mobile">{{addressData.mobile ? addressData.mobile : ''}}</view>
+					</view>
+					<view class="address">
+						<view class="address-icon">
+							<text class="iconfont icon-shouhuodizhi"></text>
+						</view>
+						<view class="address-text">
+							{{addressData.province ? addressData.province : ''}}
+							{{addressData.city ? addressData.city : ''}}
+							{{addressData.town ? addressData.town : ''}}
+							{{addressData.address ? addressData.address : ''}}
+						</view>
+					</view>
+				</view>
+		 	</view>
+		 </view>
+		 <image  src="../../../static/temp/line@3x.png" mode=""></image>
+	</view>
+</template>
+
+<script>
+	import { mapState, mapMutations } from 'vuex'	
+	export default{
+		name:'address',
+		props:{
+			addressData:{
+				type:Object
+			}
+		},
+		data() {
+			return{
+				initData:''
+			}
+		},
+		created(){
+			this.initData = this.addressData
+		},
+		computed: {
+			...mapState(['isManage'])
+		},
+		methods:{
+			
+		}
+	}
+</script>
+
+<style lang="scss">
+	.address-template{
+		width: 100%;
+		height: auto;
+		background: #FFFFFF;
+        
+        &::after{
+            content: "";
+            display: block;
+            clear: both;
+        }
+		// border-top: 1px solid #F8F8F8;
+		image{
+			float: left;
+			width: 100%;
+			height: 6rpx;
+		}
+	}
+	.address-section {
+		width: 100%;
+		height: auto;
+		float: left;
+		position: relative;
+		
+		.address-empty{
+			width: 100%;
+			height: 84rpx;
+			line-height: 84rpx;
+			color: $color-system;
+			text-align: center;
+			font-size: $font-size-26;
+			font-weight: bold;
+			background: #fff;
+			float: left;
+			.icon-tianjiadizhi{
+				font-size: 30rpx;
+				margin: 0 8rpx;
+			}
+		}
+		.address-content {
+			display: flex;
+			align-items: center;
+			padding:20rpx 24rpx;
+			background: #fff;
+		}
+		
+		.icon-shouhuodizhi {
+			flex-shrink: 0;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			width: 40rpx;
+			color: $color-system;
+			font-size: 46rpx;
+			margin-right: 10rpx;
+		}	
+		.address-cen {
+			width: 100%;
+			height: auto;
+			position: relative;
+			.top{
+				padding-left: 50rpx;
+				height: 42rpx;
+				line-height: 42rpx;
+				text-align: left;
+				font-size: $font-size-30;
+				color: $text-color;
+				padding-bottom: 8rpx;
+				display: flex;
+				float: left;
+				.name{
+					margin-right: 48rpx;
+				}
+				.mobile{
+					margin-right: 40rpx;
+				}
+			}
+			.address {
+				width: 100%;
+				height: auto;
+				float: left;
+				.address-icon{
+					width: 40rpx;
+					height: auto;
+					float: left;
+					line-height: 40rpx;
+				}
+				.address-text{
+					width: 650rpx;
+					padding-left: 10rpx;
+					float: left;
+					line-height: 40rpx;
+					font-size: $font-size-28;
+					color: #666666;
+					text-align: left;
+					-o-text-overflow: ellipsis;
+					text-overflow: ellipsis;
+					display: -webkit-box;
+					word-break: break-all;
+					-webkit-box-orient: vertical;
+					-webkit-line-clamp: 2;
+					overflow: hidden;
+				}
+			}
+		}
+		.icon-xiangyou {
+			font-size: 32rpx;
+			color: $text-color;
+			margin-right: 30rpx;
+		}
+		.a-bg {
+			position: absolute;
+			left: 0;
+			bottom: 0;
+			display: block;
+			width: 100%;
+			height: 5rpx;
+		}
+	}
+</style>

+ 234 - 0
components/cm-module/orderDetails/orderButton.vue

@@ -0,0 +1,234 @@
+<template name="button">
+	<view class="button-template" :style="{paddingBottom :isIphoneX ? '68rpx' : '0rpx'}">
+		<!-- 底部按钮 -->
+		<view class="button-content">
+			<view class="btn btn-payment" v-if="order.affirmPaymentFlag == 10" @click.stop="btnConfirm('payment',order)">确认打款<text>供应商</text></view>
+			<view class="btn btn-confirm" v-if="btnState.isConfirmation" @click.stop="btnConfirm('confirmation',order)">确认订单</view>
+			<view class="btn btn-pay" v-if="btnState.isPay" @click.stop="btnConfirm('pay',order)">付款</view>
+			<view class="btn btn-share" @click.stop="onShareCode">
+				<view class="tips" v-if="shareCode">分享码:{{shareCode}}</view>
+				分享订单
+			</view>
+			<view class="btn btn-cancel" v-if="btnState.isCancel" @click.stop="btnConfirm('cancel',order)">取消订单</view>
+			<!-- <view class="btn btn-delete" v-if="btnState.isDelete" @click.stop="btnConfirm('delete',order)">删除订单</view> -->
+			<view class="btn btn-query" v-if="btnState.isQuery && order.secondHandOrderFlag!=1" @click.stop="btnConfirm('query',order)">查看物流</view>
+			<view class="btn btn-firm" v-if="btnState.isConfirm" @click.stop="btnConfirm('confirm',order)">
+				确认收货
+				<view class="tips">采美豆<text class="line"></text></view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default{
+		name:'button',
+		props:{
+			status:{
+				type:Number
+			},
+			order: {
+				type:Object
+			},
+			shareCode:{
+				type:String
+			},
+		},
+		watch:{
+			status:{
+				handler:function(val){
+					this.initData(val)
+				},
+				deep:true//对象内部的属性监听,也叫深度监听
+			}
+		},
+		data() {
+			return{
+				btnState:this.initStatus(),
+				isIphoneX:this.$store.state.isIphoneX,
+				mapStateArr:[
+					{label:'isQuery',val:[4,5,12,13,33,22,23,32,77],status: true},
+					{label:'isDelete',val:[6],status: true},
+					{label:'isCancel',val:[0,111],status: true},
+					{label:'isConfirm',val:[33],status: true},
+					{label:'isConfirmation',val:[0],status: true},
+					{label:'isPay',val:[11,12,13,21,22,23,111],status: true},
+				]
+			}
+		},
+		created(){
+			this.initData(this.status)
+		},
+		computed: {
+
+		},
+		methods:{
+			initData(resVal) {
+				/**
+				 * @分享按钮统一显示
+				 * @按钮根据状态显示
+				 * @(4、5、7、12、22、23、32)显示[查看物流]按钮,其他隐藏
+				 * @(6)显示[删除订单],其他隐藏
+				 * @(0、111)显示[取消订单],其他隐藏
+				 * @(21,31)只显示分享
+				 * @(13,33)显示[确认收货]和[查看物流]
+				 */
+				this.btnState = this.initStatus()
+				this.mapStateArr.forEach(el => {
+					el.val.forEach(value => {
+						if(resVal === value){
+							this.btnState[el.label] = el.status
+						}
+					})
+				})
+			},
+			initStatus(){
+				let btnState= {
+						isQuery: false,
+						isDelete: false,
+						isCancel: false,
+						isConfirm: false,
+						isConfirmation:false,
+					}
+				return 	btnState
+			},
+			getShareCode(code){
+				this.shareCode = code
+			},
+			onShareCode(){
+				this.$parent.isShareModal = true
+				this.$emit('shareConfirm')
+			},
+			btnConfirm(type,order){
+				let data = {
+						type:type,
+						orderId:order.orderId,
+						order:order
+					}
+				this.$emit('buttonConfirm',data)
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.button-template{
+		width: 100%;
+		height: auto;
+		position: fixed;
+		bottom: 0;
+		left: 0;
+		background: #FFFFFF;
+		.button-content{
+			padding:0 24rpx;
+			height: auto;
+			float: right;
+			position: relative;
+			.share-code{
+				width: 200rpx;
+				height:  64rpx;
+				line-height: 64rpx;
+				color: #2A45FF;
+				text-align: left;
+				position: absolute;
+				font-size: $font-size-28;
+				font-weight: bold;
+				left: 24rpx;
+				top: 24rpx;
+			}
+			.btn{
+				width: 160rpx;
+				height:  64rpx;
+				margin:22rpx 22rpx 22rpx 0;
+				line-height: 64rpx;
+				font-size:$font-size-26;
+				color: #666666;
+				text-align: center;
+				float: right;
+				border: 2rpx solid #999999;
+				border-radius: 34rpx;
+				&.btn-payment{
+					line-height: 38rpx;
+					font-size: 24rpx;
+					background: #f9a94b;
+					color: #fff;
+					border: 2rpx solid #f9a94b;
+					text{
+						display: block;
+						line-height: 15rpx;
+					}
+				}
+				&.btn-share{
+					position: relative;
+				}
+			}
+			.btn-confirm{
+				background:#ff7a51;
+				border-color:#ff7a51;
+				color: #FFFFFF;
+			}
+			.btn-pay{
+				background:#f94b4b;
+				margin-right: 0;
+				border: 2rpx solid #f94b4b;
+				color: #fff;
+			}
+			.btn-firm{
+				position:relative;
+				.tips{
+					width: 74rpx;
+					height: 32rpx;
+					line-height: 32rpx;
+					padding: 0 7rpx;
+					border-radius: 16rpx;
+					background-color: #ffe6dc;
+					color: $color-system;
+					text-align: center;
+					font-size: $font-size-20;
+					position:absolute;
+					right: 0;
+					top: -40rpx;
+					z-index: 90;
+					.line{
+						display: block;
+						width: 20rpx;
+						height: 20rpx;
+						background-color: #ffe6dc;
+						position: relative;
+						bottom: 18rpx;
+						left: 15rpx;
+						z-index: -1;
+						transform:rotate(45deg);
+					}
+				}
+			}
+			.btn-share{
+				.tips{
+					width: 160rpx;
+					height: 34rpx;
+					padding: 10rpx 10rpx;
+					background:#F3B574;
+					border-radius: 8rpx;
+					position: absolute;
+					color: #FFFFFF;
+					line-height: 34rpx;
+					font-size: $font-size-24;
+					text-align: left;
+					right: 0;
+					top: -65rpx;
+					&:before{
+						content: "";
+						width: 25rpx;
+						height: 25rpx;
+						background:#F3B574;
+						position: absolute;
+						bottom: -8rpx;
+						left: 30rpx;
+						z-index: -1;
+						transform:rotate(45deg);
+					}
+				}
+			}
+		}
+	}
+</style>

+ 329 - 0
components/cm-module/orderDetails/orderInformation.vue

@@ -0,0 +1,329 @@
+<template name="information">
+	<view class="information-template">
+		<!-- 订单信息 -->
+		<view class="information-content">
+			<view class="information-view title">
+				<view class="view-num">
+					<view class="bage-text">
+						订单编号:<label class="label">{{ orderData.orderNo ? orderData.orderNo : '' }}</label>
+					</view>
+				</view>
+			</view>
+			<view class="information-view same">
+				<view class="view-num">
+					订单总额:<label class="label">¥{{ orderData.payTotalFee | NumFormat }}</label>
+				</view>
+			</view>
+			<view class="information-view">
+				<view class="view-num bold">
+					订单标识:<label class="label">{{ orderData.orderMark ? orderData.orderMark : '' }}</label>
+					<text class="clipboard" @click="clipboard(orderData.orderMark)">复制</text>
+				</view>
+			</view>
+			<view class="information-view same">
+				<view class="view-num">
+					待付金额:<text class="red">¥{{ orderData.pendingPayments | NumFormat }}</text>
+				</view>
+				<view class="view-man"></view>
+			</view>
+			<template v-if="openShowflag">
+				<view class="information-view">
+					<view class="view-num time">
+						下单时间:<label class="label">{{ orderData.orderTime ? orderData.orderTime : '' }}</label>
+					</view>
+					<!-- <view class="view-type">{{ orderData.status | TextFormat }}</view> -->
+				</view>
+				<view class="information-view same">
+					<view class="view-num">
+						余额抵扣:<label class="label">¥{{ orderData.balancePayFee | NumFormat }}</label>
+					</view>
+				</view>
+				<view class="information-view ">
+					<view class="view-num" v-if="orderData.postageFlag == 0">
+						运费:<label class="label">包邮</label>
+					</view>
+					<view class="view-num" v-if="orderData.postageFlag == -1">
+						运费:<label class="label">到付</label>
+					</view>
+					<view class="view-num" v-if="orderData.postageFlag == 1">
+						运费:<label class="label">¥{{ orderData.postage | NumFormat }}</label>
+					</view>
+				</view>
+				<view class="information-view same" v-if="orderData.svipFullReduction > 0">
+					<view class="view-man">
+						超级会员优惠:<label class="label">¥{{ orderData.svipFullReduction | NumFormat }}</label>
+					</view>
+				</view>
+				<view class="information-view" v-if="orderData.userBeans > 0">
+					<view class="view-man">
+						采美豆抵用运费:<label class="label">{{ orderData.userBeans }}</label>
+					</view>
+				</view>
+				<view class="information-view same" v-if="orderData.discountFee && orderData.discountFee > 0">
+					<view class="view-num">
+						经理折扣:<label class="label">¥{{ orderData.discountFee | NumFormat }}</label>
+					</view>
+				</view>
+				<view
+					class="information-view"
+					v-if="orderData.promotionFullReduction && orderData.promotionFullReduction > 0"
+				>
+					<view class="view-man">
+						促销满减:<label class="label">¥{{ orderData.promotionFullReduction | NumFormat }}</label>
+					</view>
+				</view>
+				<view class="information-view same">
+					<view class="view-man">
+						优惠券:<label class="label">¥{{ orderData.couponAmount | NumFormat }}</label>
+					</view>
+				</view>
+				<view class="information-view">
+					<view class="view-man">
+						赠品总数:<label class="label">{{
+							orderData.presentCount + orderData.promotionalGiftsCount
+						}}</label>
+					</view>
+				</view>
+				<view class="information-view same">
+					<view class="view-man">
+						应付总额:<label class="red">¥{{ orderData.payableAmount | NumFormat }}</label>
+					</view>
+				</view>
+				<view class="information-view">
+					<view class="view-num">
+						已支付:<label class="red">¥{{ orderData.receiptAmount | NumFormat }}</label>
+					</view>
+					<view class="view-man"></view>
+				</view>
+			</template>
+		</view>
+		<view class="openinfo" v-if="infoflag">
+			<view class="btnInfo" @click="openShow">
+				查看更多
+				<text class="iconfont icon-xiangxiajiantou"></text>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+const thorui = require('@/components/clipboard/clipboard.thorui.js')
+export default {
+	name: 'information',
+	props: {
+		information: {
+			type: Object
+		}
+	},
+	data() {
+		return {
+			orderData: '',
+			openShowflag: false,
+			infoflag: true
+		}
+	},
+	created() {
+		this.initData(this.information)
+	},
+	filters: {
+		NumFormat(value) {
+			//处理金额
+			if (!value) return '0.00'
+			let number = Number(value)
+			return number.toFixed(2)
+		},
+		TextFormat(status) {
+			//处理金额
+			let HtmlText,
+				typeTextObject = {
+					0: '待确认',
+					4: '交易完成',
+					5: '订单完成',
+					6: '已关闭',
+					7: '交易全退',
+					77: '交易全退',
+					11: '待付款待发货',
+					12: '待付款部分发货',
+					13: '待付款已发货',
+					21: '部分付款待发货',
+					22: '部分付款部分发货',
+					23: '部分付款已发货',
+					31: '已付款待发货',
+					32: '已付款部分发货',
+					33: '已付款已发货',
+					111: '待付款待发货'
+				}
+
+			Object.keys(typeTextObject).forEach(key => {
+				if (key == status) {
+					HtmlText = typeTextObject[key]
+				}
+			})
+			return HtmlText
+		}
+	},
+	computed: {},
+	watch: {
+		information: {
+			handler: function(val) {
+				this.initData(val)
+			},
+			deep: true //对象内部的属性监听,也叫深度监听
+		}
+	},
+	methods: {
+		openShow() {
+			this.openShowflag = true
+			this.infoflag = false
+		},
+		initData(res) {
+			this.orderData = res
+		},
+		clipboard(data) {
+			thorui.getClipboardData(data, res => {
+				if (res) {
+					this.$util.msg('复制成功', 2000, true, 'success')
+				} else {
+					this.$util.msg('复制失败', 2000, true, 'none')
+				}
+			})
+		}
+	}
+}
+</script>
+
+<style lang="scss">
+.information-template {
+	width: 100%;
+	height: auto;
+	background: #ffffff;
+	float: left;
+	margin-top: 24rpx;
+	.information-content {
+		width: 702rpx;
+		padding: 15rpx 24rpx 20rpx 24rpx;
+		.information-view {
+			height: 50rpx;
+			line-height: 50rpx;
+			font-size: $font-size-24;
+			margin: 4rpx 0;
+			// display: flex;
+			width: 55%;
+			display: inline-block;
+			&.same {
+				width: 45%;
+				text-align: right;
+			}
+			// &.title{
+			// 	height: 68rpx;
+			// 	line-height: 68rpx;
+			// 	margin-bottom: 5rpx;
+			// }
+			view {
+				// flex: 1;
+				color: $text-color;
+				color: #999999;
+				.label {
+					color: #666666;
+				}
+			}
+			.view-num.title {
+				height: 68rpx;
+				line-height: 68rpx;
+				position: relative;
+				.bage-icon {
+					width: 50rpx;
+					height: 50rpx;
+					display: block;
+					position: absolute;
+					right: 0;
+					top: 9rpx;
+				}
+				.bage-buss {
+					display: inline-block;
+					width: 72rpx;
+					height: 30rpx;
+					background: radial-gradient(circle, rgba(255, 39, 180, 1) 0%, rgba(193, 77, 245, 1) 100%);
+					border-radius: 4rpx;
+					line-height: 30rpx;
+					font-size: $font-size-24;
+					text-align: center;
+					color: #ffffff;
+					margin-top: 10rpx;
+				}
+				.bage-auto {
+					display: inline-block;
+					width: 72rpx;
+					height: 30rpx;
+					background: radial-gradient(circle, rgba(255, 180, 39, 1) 0%, rgba(245, 142, 77, 1) 100%);
+					border-radius: 4rpx;
+					line-height: 30rpx;
+					font-size: $font-size-24;
+					text-align: center;
+					color: #ffffff;
+					margin-top: 10rpx;
+				}
+				.bage-text {
+					display: inline-block;
+					font-size: $font-size-28;
+					line-height: 68rpx;
+					text-align: left;
+					color: $color-system;
+					// margin-left: 10rpx;
+				}
+			}
+			.view-num.ord {
+				color: $color-system;
+				text-align: left;
+				flex: 3;
+				font-weight: bold;
+			}
+			.view-num.time {
+				color: #999999;
+				flex: 6;
+			}
+			// .bold{
+			// 	font-weight: bold;
+			// }
+			.red {
+				color: #ff2a2a;
+			}
+			.view-type {
+				float: right;
+				text-align: right;
+				color: #ff2a2a;
+				flex: 4;
+			}
+			.clipboard {
+				width: 84rpx;
+				height: 36rpx;
+				background: linear-gradient(34deg, rgba(255, 41, 41, 1) 0%, rgba(255, 109, 27, 1) 100%);
+				text-align: center;
+				font-size: $font-size-24;
+				color: #ffffff;
+				border-radius: 6rpx;
+				line-height: 36rpx;
+				display: inline-block;
+				margin-left: 42rpx;
+			}
+		}
+	}
+}
+.openinfo {
+	width: 100%;
+	height: 48rpx;
+	margin-bottom: 30rpx;
+	.btnInfo{
+		width: 168rpx;
+		height: 48rpx;
+		line-height: 46rpx;
+		box-sizing: border-box;
+		border: 2rpx solid #e1e1e1;
+		border-radius: 8rpx;
+		text-align: center;
+		color: #b2b2b2;
+		margin: 0 auto;
+		font-size: $font-size-24;
+	}
+}
+</style>

+ 244 - 0
components/cm-module/orderDetails/orderListButton.vue

@@ -0,0 +1,244 @@
+<template name="button">
+	<view class="button-template">
+		<!-- 底部按钮 -->
+		<view class="button-content">
+			<view class="btn btn-payment" v-if="order.affirmPaymentFlag == 10" @click.stop="btnConfirm('payment',order)">确认打款<text>供应商</text></view>
+			<view class="btn btn-pay" v-if="btnState.isPay" @click.stop="btnConfirm('pay',order)">付款</view>
+			<view class="btn btn-confirm" v-if="btnState.isConfirmation" @click.stop="btnConfirm('confirmation',order)">确认订单</view>
+			<view class="btn btn-share"  @click.stop="onShareCode(order.orderId)">分享订单</view>
+			<view class="btn btn-cancel" v-if="btnState.isCancel" @click.stop="btnConfirm('cancel',order)">取消订单</view>
+			<!-- <view class="btn btn-delete" v-if="btnState.isDelete" @click.stop="btnConfirm('delete',order)">删除订单</view> -->
+			<view class="btn btn-query" v-if="btnState.isQuery && order.secondHandOrderFlag!=1" @click.stop="btnConfirm('query',order)">查看物流</view>
+			<view class="btn btn-firm" v-if="btnState.isConfirm" @click.stop="btnConfirm('confirm',order)">
+				确认收货
+				<view class="tips">采美豆<text class="line"></text></view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default{
+		name:"button",
+		props:{
+			status: {
+				type:Number
+			},
+			order: {
+				type:Object
+			},
+		},
+		data() {
+			return{
+				isShare:true,
+				shareCode:'',
+				btnState:this.initStatus(),
+				mapStateArr:[
+					{label:'isQuery',val:[4,5,12,13,33,22,23,32,77],status: true},
+					{label:'isDelete',val:[6],status: true},
+					{label:'isCancel',val:[0,111],status: true},
+					{label:'isConfirm',val:[33],status: true},
+					{label:'isConfirmation',val:[0],status: true},
+					{label:'isPay',val:[11,12,13,21,22,23,111],status: true},
+				]
+			}
+		},
+		created(){
+			this.initData(this.status)
+		},
+		computed: {
+
+		},
+		watch:{
+			status:{
+				handler:function(val){
+					this.initData(val)
+				},
+				deep:true//对象内部的属性监听,也叫深度监听
+			}
+		},
+		methods:{
+			initData(resVal) {
+				/**
+				 * @分享按钮统一显示
+				 * @按钮根据状态显示
+				 * @(4、5、7、12、22、23、32)显示[查看物流]按钮,其他隐藏
+				 * @(6)显示[删除订单],其他隐藏
+				 * @(0、111)显示[取消订单],其他隐藏
+				 * @(21,31)只显示分享
+				 * @(13,33)显示[确认收货]和[查看物流]
+				 */
+				this.btnState = this.initStatus()
+				this.mapStateArr.forEach(el => {
+					el.val.forEach(value => {
+						if(resVal === value){
+							this.btnState[el.label] = el.status
+						}
+					})
+				})
+			},
+			initStatus(){
+				let btnState= {
+						isQuery: false,
+						isDelete: false,
+						isCancel: false,
+						isConfirm: false,
+						isShare: true,
+						isConfirmation:false,
+					}
+				return 	btnState
+			},
+			getShareCode(code){
+				this.shareCode = code
+			},
+			onShareCode(orderId){
+				this.$parent.isShareModal = true
+				this.$parent.btnoRderID = orderId
+				this.$emit('shareConfirm')
+			},
+			btnConfirm(type,order){
+				let data = {
+						type:type,
+						orderId:order.orderId,
+						order:order
+					}
+				this.$emit('buttonConfirm',data)
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.button-template{
+		width: 100%;
+		height: auto;
+		float: left;
+		background: #FFFFFF;
+		.button-content{
+			height: auto;
+			float: right;
+			position: relative;
+			.share-code{
+				width: 200rpx;
+				height:  64rpx;
+				line-height: 64rpx;
+				color: #2A45FF;
+				text-align: left;
+				position: absolute;
+				font-size: $font-size-28;
+				font-weight: bold;
+				left: 24rpx;
+				top: 24rpx;
+			}
+			.btn{
+				width: 150rpx;
+				height:  64rpx;
+				margin: 22rpx 0 20rpx 20rpx;
+				line-height: 64rpx;
+				font-size:$font-size-26;
+				color: #999999;
+				text-align: center;
+				float: right;
+				border-radius: 34rpx;
+				border: 2rpx solid #999999;
+				&.btn-payment{
+					line-height: 38rpx;
+					font-size: 24rpx;
+					background: #f9a94b;
+					color: #fff;
+					border: 2rpx solid #f9a94b;
+					text{
+						display: block;
+						line-height: 15rpx;
+					}
+				}
+			}
+			.btn-color{
+				background: $btn-confirm;
+				// margin: 22rpx 0 22rpx 22rpx;
+			}
+			.btn-cancel{
+				// background:#FFFFFF;
+				// color: #999999;
+				// float: left;
+				// margin: 22rpx 0;
+				text-align: center;
+			}
+			// .btn-delete{
+			// 	background:linear-gradient(315deg,rgba(255,163,3,1) 0%,rgba(255,53,1,1) 100%);
+			// }
+			// .btn-query{
+			// 	background:linear-gradient(135deg,rgba(255,212,129,1) 0%,rgba(198,129,0,1) 100%);
+			// }
+			.btn-confirm{
+				background:#ff7a51;
+				border-color:#ff7a51;
+				color: #FFFFFF;
+			}
+			.btn-pay{
+				background:#f94b4b;
+				color: #FFFFFF;
+				border: 2rpx solid #f94b4b;
+			}
+			.btn-firm{
+				position:relative;
+				.tips{
+					width: 74rpx;
+					height: 32rpx;
+					line-height: 32rpx;
+					padding: 0 7rpx;
+					border-radius: 16rpx;
+					background-color: #ffe6dc;
+					color: $color-system;
+					text-align: center;
+					font-size: $font-size-20;
+					position:absolute;
+					right: 0;
+					top: -40rpx;
+					z-index: 90;
+					.line{
+						display: block;
+						width: 20rpx;
+						height: 20rpx;
+						background-color: #ffe6dc;
+						position: relative;
+						bottom: 18rpx;
+						left: 15rpx;
+						z-index: -1;
+						transform:rotate(45deg);
+					}
+				}
+			}
+			.btn-share{
+				// background:linear-gradient(315deg,rgba(0,212,150,1) 0%,rgba(126,243,174,1) 100%);
+				position: relative;
+				.tips{
+					width: 160rpx;
+					height: 34rpx;
+					padding: 10rpx 10rpx;
+					background:linear-gradient(45deg,rgba(0,0,0,1) 0%,rgba(87,87,87,1) 100%);
+					box-shadow:0px 2px 4px 0px rgba(0,0,0,0.2);
+					border-radius: 8rpx;
+					position: absolute;
+					color: #FFFFFF;
+					line-height: 34rpx;
+					font-size: $font-size-24;
+					text-align: left;
+					right: 0;
+					top: -65rpx;
+					&:before{
+						content: "";
+						width: 25rpx;
+						height: 25rpx;
+						background:linear-gradient(45deg,rgba(0,0,0,1) 0%,rgba(87,87,87,1) 100%);
+						position: absolute;
+						bottom: -8rpx;
+						right: 30rpx;
+						z-index: -1;
+						transform:rotate(45deg);
+					}
+				}
+			}
+		}
+	}
+</style>

+ 159 - 0
components/cm-module/orderDetails/paymentRecord.vue

@@ -0,0 +1,159 @@
+<template name="record">
+	<view class="record-template">
+		<!-- 支付记录 -->
+		<view class="record-content">
+			<view class="record-title">
+				<view class="record-title-l">支付记录</view>
+				<view class="record-title-r" v-if="!isEmpty">
+					已支付:<text class="red">¥{{ receiptAmount != null ? receiptAmount.toFixed(2): '0.00'}}</text>
+				</view>
+			</view>
+			<view class="record-empty" v-if="isEmpty">
+			 	<text>暂无支付记录</text>
+			</view>
+			<view class="record-list" v-else>
+				<view class="record-item" v-for="(record,index) in discernReceiptList" :key="index">
+					<view class="record-item-t">
+						<view class="item-time mm">¥{{record.associateAmount.toFixed(2)}}</view>
+					</view>
+					<view class="record-item-t">
+						<view class="item-time tt">{{ record.receiptDate }}</view>
+						<view class="item-time pp">{{ payTypeText(record) }}</view>
+					</view>	
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default{
+		name:'record',
+		props:{
+			discernReceiptList:{
+				type:Array
+			},
+			receiptAmount:{
+				type:Number
+			}
+		},
+		data() {
+			return{
+				isEmpty:false,
+				paymentData:'',
+				typeText:'',
+				isOpen:false,
+			}
+		},
+		created(){
+			this.initData(this.discernReceiptList)
+		},
+		computed: {
+
+		},
+		methods:{
+			initData(res) {
+				if(res!=''){
+					this.isEmpty = false
+					this.paymentData = res
+				}else{
+					this.isEmpty = true
+				}
+			},
+			payTypeText(record) {
+				//处理支付记录文字
+				const map = {
+					12: '企业网银',
+					13: '微信支付',
+					14: '支付宝',
+					15: '微信支付',
+					16: '余额抵扣',
+				}
+				if(record.payType === 28 || record.payType === 29 ){
+					return record.quickPayStr
+				}else{
+					return map[record.payType]
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.record-template{
+		width: 100%;
+		height: auto;
+		background: #FFFFFF;
+		float: left;
+		margin-top: 24rpx;
+		.record-content{
+			width: 702rpx;
+			padding: 20rpx 24rpx;
+			height: auto;
+			.record-title{
+				width: 100%;
+				font-size: $font-size-28;
+				color: $text-color;
+				text-align: left;
+				line-height: 40rpx;
+				margin-bottom: 12rpx;
+				float: left;
+				.record-title-l{
+					font-weight: bold;
+					float: left;
+				}
+				.record-title-r{
+					float: right;
+					.red{
+						color: #FF2A2A;
+						font-weight: bold;
+					}
+				}
+			}
+			.record-empty{
+				font-size: $font-size-28;
+				color: $text-color;
+				text-align: left;
+				line-height: 40rpx;
+			}
+			.record-list{
+				width: 100%;
+				height: auto;
+				float: left;
+				margin-top: 12rpx;
+				.record-item{
+					height: auto;
+					width: 100%;
+					padding: 12rpx 0;
+					font-size: $font-size-28;
+					float: left;
+					.record-item-t{
+						width: 100%;
+						height: 40rpx;
+						display: flex;
+						justify-content: center;
+						flex-direction: row;
+						.item-time{
+							line-height: 48rpx;
+							&.mm{
+								flex: 1;
+								color: $text-color;
+								text-align: left;
+							}
+							&.pp{
+								flex: 5;
+								color: #999999;
+								text-align: right;
+							}
+							&.tt{
+								flex: 5;
+								color: #999999;
+								text-align: left;
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+</style>

+ 120 - 0
components/cm-module/orderDetails/refundRecord.vue

@@ -0,0 +1,120 @@
+<template name="refund">
+	<view class="record-template" v-if="isEmpty">
+		<!-- 支付记录 -->
+		<view class="record-content">
+			<view class="record-title">
+				<view class="record-title-l">退款记录</view>
+				<view class="record-title-r">
+					已退款:<text class="red">¥{{ returnedPurchaseFee != null ? returnedPurchaseFee.toFixed(2) : '0.00'}}</text>
+				</view>
+			</view>
+			<view class="record-list">
+				<view class="record-item" v-for="(item,index) in returnedPurchaseList" :key="index">
+					<view class="item-nums">{{item.returnedWay =='4' ? '无支付无退款' : '¥'+item.refundFee.toFixed(2)}}</view>
+					<view class="item-time">{{item.confirmReturnTime}}</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default{
+		name:"refund",
+		props:{
+			returnedPurchaseList:{
+				type:Array
+			},
+			returnedPurchaseFee:{
+				type:Number
+			}
+		},
+		data() {
+			return{
+				isEmpty:false,
+				isOpen:false,
+			}
+		},
+		created(){
+			this.initData(this.returnedPurchaseList)
+		},
+		computed: {
+		
+		},
+		methods:{
+			initData(res) {
+				if(res!=''){
+					this.isEmpty = true
+				}else{
+					this.isEmpty = false
+					this.refundData = res;
+				}
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	.record-template{
+		width: 100%;
+		height: auto;
+		background: #FFFFFF;
+		float: left;
+		margin-top: 24rpx;
+		padding-bottom: 40rpx;
+		.record-content{
+			width: 702rpx;
+			padding: 20rpx 24rpx;
+			height: auto;
+			.record-title{
+				width: 100%;
+				font-size: $font-size-28;
+				color: $text-color;
+				text-align: left;
+				line-height: 40rpx;
+				margin-bottom: 12rpx;
+				float: left;
+				.record-title-l{
+					font-weight: bold;
+					float: left;
+				}
+				.record-title-r{
+					float: right;
+					.red{
+						color: #FF2A2A;
+						font-weight: bold;
+					}
+				}
+			}
+			.record-empty{
+				font-size: $font-size-28;
+				color: $text-color;
+				text-align: left;
+				line-height: 40rpx;
+			}
+			.record-list{
+				width: 100%;
+				height: auto;
+				float: left;
+				margin-top: 12rpx;
+				.record-item{
+					height: 40rpx;
+					width: 100%;
+					padding: 12rpx 0;
+					font-size: $font-size-28;
+					line-height: 40rpx;
+					float: left;
+					.item-time{
+						float: right;
+						color: #999999;
+					}
+					.item-nums{
+						font-weight: bold;
+						float: left;
+						color: $text-color;
+					}
+				}
+			}
+		}
+	}
+</style>

+ 263 - 0
components/cm-module/productDetails/cm-activipopu.vue

@@ -0,0 +1,263 @@
+<template name="cm-price">
+	<!--促销活动弹窗提示-->
+	<tui-bottom-popup :radius="true" :show="popupShow" @close="hidePopup()">
+		<view class="tui-popup-box clearfix">
+			<template v-if="product.actStatus == null  &&  product.ladderFlag == 1">
+				<view class="tui-scrollview-box">
+					<view class="ladder-main clearfix">
+						<view class="ladder-item">
+							<view class="ladder-item-td">起订量</view>
+							<view class="ladder-item-td">价格</view>
+						</view>
+						<view class="ladder-item" v-for="(ladd, index) in product.ladderPrices" :key="index">
+							<view class="ladder-item-td">{{ ladd.numRange }}</view>
+							<view class="ladder-item-td">{{ ladd.buyPrice | NumFormat }}</view>
+						</view>
+					</view>
+				</view>	
+			</template>	
+			<template v-else>
+				<view class="tui-scrollview-box">
+					<view class="box-text">
+						<text>促销时间:</text>
+						<text class="txt" v-if="product.promotions.status == 1">不限时</text>
+						<text class="txt" v-else>{{ product.promotions.beginTime }} ~ {{ product.promotions.endTime }}</text>
+					</view>
+					<view class="box-title" v-show="product.promotions.mode ==2">
+						<text>购买{{product.promotions.name}}商品,满</text>
+						<text class="txt">¥{{product.promotions == null ? '0.00' : product.promotions.touchPrice | NumFormat}}</text>减
+						<text class="txt">¥{{product.promotions == null ? '0.00' : product.promotions.reducedPrice | NumFormat}}</text>
+					</view>
+					<view class="box-title" v-show="product.promotions.mode==3">
+						<text>购买{{product.promotions.name}}商品,满</text>
+						<text class="txt">¥{{product.promotions.touchPrice}}</text>赠送商品
+					</view>
+					<view class="box-product" v-show="product.promotions.mode==3">
+						<view class="box-product-main"  v-for="(item, index) in product.promotions.giftList" :key="index">
+							<view class="image"><image :src="item.image" mode=""></image></view>
+							<view class="info">
+								<view class="name">{{ item.name }}</view>
+								<view class="num">X{{ item.number }}</view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</template>
+			<view class="tui-right-flex tui-popup-btn" :style="{ paddingBottom :isIphoneX ? '68rpx' : '0rpx' }">
+				<view class="tui-flex-1">
+					<view class="tui-button" v-if="product.promotions.type == 2" @click="goGoodActiveFn(product.promotions.id)">更多凑单商品</view>
+					<view class="tui-button" v-else @click="hidePopup()">了解</view>
+				</view>
+			</view>
+		</view>	
+	</tui-bottom-popup>
+</template>
+
+<script>
+	import { mapState,mapMutations } from 'vuex'
+	export default{
+		name:'cm-price',
+		props:{
+			product:{
+				type:Object,
+			},
+			popupShow:{
+				type:Boolean,
+				default:false
+			}
+		},
+		data() {
+			return{
+				isIphoneX:this.$store.state.isIphoneX,
+			}
+		},
+		filters: {
+			NumFormat:function(text) {//处理金额
+				return Number(text).toFixed(2);
+			},
+		},
+		created() {
+			console.log(this.product)
+		},
+		computed: {
+			...mapState(['hasLogin','isWxAuthorize'])
+		},
+		methods:{
+			hidePopup(){
+				this.$parent.popupShow = false
+			},
+			goGoodActiveFn(id){
+				this.$parent.popupShow = false
+				this.$api.navigateTo('/pages/goods/goods-active?id='+id)
+			}
+		},
+		
+	}
+</script>
+
+<style lang="scss">	
+	.tui-flex-1 {
+		flex: 1;
+	}
+	.tui-popup-box {
+		position: relative;
+		box-sizing: border-box;
+		min-height: 220rpx;
+		padding:24rpx 24rpx 0 24rpx;
+	}
+	.tui-scrollview-box{
+		width: 100%;
+		height: auto;
+		float: left;
+		box-sizing: border-box;
+		.ladder-main{
+			width: 100%;
+			min-height: 240rpx;
+			border: 1px solid rgba(225,86,22,0.3);
+			border-radius: 10rpx;
+			.ladder-item{
+				width: 100%;
+				height: 80rpx;
+				float: left;
+				border-bottom: 1px solid rgba(225,86,22,0.3);
+				&:nth-child(1){
+					.ladder-item-td{
+						color: #333333;
+					}
+				}
+				&:last-child{
+					border-bottom: none;
+				}
+				.ladder-item-td{
+					width:50%;
+					text-align: center;
+					line-height: 80rpx;
+					font-size: $font-size-24;
+					color: $color-system;
+					box-sizing: border-box;
+					float: left;
+					&:nth-child(1){
+						border-right: 1px solid rgba(225,86,22,0.3);
+					}
+				}
+			}
+		}
+		.box-title{
+			font-size: $font-size-26;
+			color: $text-color;
+			text-align: left;
+			line-height: 56rpx;
+			.txt{
+				color: $color-system;
+				margin: 0 8rpx;
+			}
+		}
+		.box-text{
+			font-size: $font-size-26;
+			color: $text-color;
+			text-align: left;
+			line-height: 56rpx;
+			.txt{
+				color: $color-system;
+			}
+		}
+		.box-product{
+			width: 100%;
+			height: auto;
+			margin-top: 20rpx;
+			.title{
+				font-size: $font-size-24;
+				color: $text-color;
+				text-align: left;
+				line-height: 54rpx;
+			}
+			.box-product-main{
+				width: 100%;
+				height: 136rpx;
+				float: left;
+				margin: 10rpx 0;
+				.image{
+					width: 134rpx;
+					height: 134rpx;
+					border: 1px solid #EBEBEB;
+					float: left;
+					image{
+						width: 100%;
+						height: 100%;
+						display: block;
+					}
+				}
+				.info{
+					width: 540rpx;
+					height: 134rpx;
+					float: left;
+					margin-left: 16rpx;
+					position: relative;
+					.name{
+						width: 100%;
+						float: left;
+						line-height: 40rpx;
+						font-size: $font-size-28;
+						color: $text-color;
+						-o-text-overflow: ellipsis;
+						text-overflow: ellipsis;
+						display: -webkit-box;
+						word-break: break-all;
+						-webkit-box-orient: vertical;
+						-webkit-line-clamp: 2;
+						overflow: hidden;
+					}
+					.num{
+						width: 100%;
+						height: 44rpx;
+						font-size: $font-size-24;
+						color: $text-color;
+						text-align: left;
+						line-height: 44rpx;
+						position: absolute;
+						bottom: 0;
+						left: 0;
+					}
+				}
+			}
+		}
+	}
+	
+	.tui-popup-btn {
+		width: 100%;
+		height: auto;
+		float: left;
+		margin-top: 24rpx;
+		.tui-button{
+			width: 100%;
+			height: 88rpx;
+			background: $btn-confirm;
+			line-height: 88rpx;
+			text-align: center;
+			color: #FFFFFF;
+			font-size: $font-size-28;
+			border-radius: 44rpx;
+		}
+	}
+</style>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 144 - 0
components/cm-module/productDetails/cm-ladder-popup.vue

@@ -0,0 +1,144 @@
+<template name="cm-ladder-popup">
+	<!-- 规格阶梯价 -->
+	<view class="tui-popup-maskmodel" v-show="show" @click.stop="hidePopup">
+		<view class="tui-popup-ladder">
+			<view class="tui-scrollview-box">
+				<view class="ladder-main clearfix">
+					<view class="ladder-item">
+						<view class="ladder-item-td">起订量</view> <view class="ladder-item-td">价格</view>
+					</view>
+					<view class="ladder-item" v-for="(ladd, index) in ladderPriceList" :key="index">
+						<view class="ladder-item-td">{{ ladd.numRange }}</view>
+						<view class="ladder-item-td">¥{{ ladd.buyPrice | NumFormat }}</view>
+					</view>
+				</view>
+			</view>
+			<view class="tui-right-flex tui-popup-btn" :style="{ paddingBottom: isIphoneX ? '68rpx' : '34rpx' }">
+				<view class="tui-flex-1">
+					<view class="tui-button" @click.stop="hidePopup">了解</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+import { mapState, mapMutations } from 'vuex'
+export default {
+	name: 'cm-ladder-popup',
+	props: {
+		list: {
+			type: Array
+		},
+		show: {
+			type: Boolean,
+			default: false
+		},
+		type: { 
+			type: Number,
+			default: 1
+		}
+	},
+	data() {
+		return {
+			ladderPriceList:[]
+		}
+	},
+	filters: {
+		NumFormat: function(value) {
+			//处理金额
+			if (!value) return '0.00'
+			let number = Number(value).toFixed(2)
+			return number
+		}
+	},
+	created() {
+		this.ladderPriceList = this.list
+	},
+	methods: {
+		hidePopup() {
+			this.$parent.laddePopupShow = false
+		}
+	}
+}
+</script>
+
+<style lang="scss">
+.tui-popup-maskmodel{
+	width: 100%;
+	height: 100%;
+	position: fixed;
+	top: 0;
+	left: 0;
+	background: rgba(0, 0, 0, 0.6);
+	z-index: 1000;
+}
+.tui-popup-ladder {
+	width: 100%;
+	height: 700rpx;
+	box-sizing: border-box;
+	padding: 40rpx 24rpx 0 24rpx;
+	border-radius: 16rpx;
+	background-color: #ffffff;
+	box-shadow: 0px 10rpx 12rpx 0px rgba(0, 0, 0, 0.2);
+	position: absolute;
+	bottom: 0;
+	left: 0;
+	z-index: 1009;
+	.tui-scrollview-box {
+		width: 100%;
+		height: auto;
+		float: left;
+		box-sizing: border-box;
+		.ladder-main {
+			width: 100%;
+			min-height: 240rpx;
+			border: 1px solid rgba(225, 86, 22, 0.6);
+			border-radius: 10rpx;
+			.ladder-item {
+				width: 100%;
+				height: 80rpx;
+				float: left;
+				border-bottom: 1px solid rgba(225, 86, 22, 0.6);
+				&:nth-child(1) {
+					.ladder-item-td {
+						color: #333333;
+					}
+				}
+				&:last-child {
+					border-bottom: none;
+				}
+				.ladder-item-td {
+					width: 50%;
+					text-align: center;
+					line-height: 80rpx;
+					font-size: $font-size-28;
+					color: $color-system;
+					box-sizing: border-box;
+					float: left;
+					&:nth-child(1) {
+						border-right: 1px solid rgba(225, 86, 22, 0.6);
+					}
+				}
+			}
+		}
+	}	
+}
+
+.tui-popup-btn {
+	width: 100%;
+	height: auto;
+	float: left;
+	margin-top: 200rpx;
+	.tui-button {
+		width: 100%;
+		height: 88rpx;
+		background: $btn-confirm;
+		line-height: 88rpx;
+		text-align: center;
+		color: #ffffff;
+		font-size: $font-size-28;
+		border-radius: 44rpx;
+	}
+}
+</style>

+ 532 - 0
components/cm-module/productDetails/cm-unit-popup.vue

@@ -0,0 +1,532 @@
+<template name="cm-parameter">
+	<!-- 相关规格 -->
+	<tui-bottom-popup :radius="true" :show="popupShow" @close="hidePopup">
+		<view class="tui-popup-box clearfix">
+			<view class="tui-shopping-main" :style="{ paddingBottom: isIphoneX ? '68rpx' : '34rpx' }">
+				<view class="tui-sku-title">
+					<view class="tui-sku-image"> <image :src="skuProduct.image" mode=""></image> </view>
+					<view class="tui-sku-price">
+						<view class="sku-price-viw">
+							<view
+								class="sku-price-text"
+								:class="
+									PromotionsFormat(skuProduct.promotions) || skuProduct.svipProductFlag == 1
+										? 'none'
+										: ''
+								"
+							>
+								¥{{
+									(PromotionsFormat(skuProduct.promotions) || skuProduct.svipProductFlag == 1
+										? skuProduct.originalPrice
+										: skuProduct.price) | NumFormat
+								}}
+							</view>
+						</view>
+						<view class="sku-price-vip">
+							<view class="floor-item-act">
+								<view class="coupon-tags" v-if="skuProduct.couponsLogo">优惠券</view>
+								<template v-if="skuProduct.actStatus == 1 && skuProduct.promotions">
+									<view v-if="PromotionsFormat(skuProduct.promotions)" class="floor-tags">
+										{{ skuProduct.promotions.name }}
+										<text v-if="skuProduct.promotions != null && skuProduct.promotions.type != 3">
+											:¥{{
+												skuProduct.promotions == null
+													? '0.00'
+													: skuProduct.promotions.touchPrice | NumFormat
+											}}
+										</text>
+									</view>
+									<view v-else-if="skuProduct.promotions.type != 3" class="floor-tags">
+										{{ skuProduct.promotions.name }}
+									</view>
+								</template>
+								<template v-if="skuProduct.actStatus == null && skuProduct.ladderFlag == 1">
+									<view class="floor-tags">阶梯价格</view>
+								</template>
+								<template v-if="skuProduct.svipProductFlag == 1">
+									<view class="svip-tags">
+										<view class="tags" :class="{ none: vipFlag != 1 }">SVIP</view>
+										<view class="price" v-if="isShowVipFlag(skuProduct)">{{
+											skuProduct.svipPriceTag
+										}}</view>
+									</view>
+								</template>
+							</view>
+						</view>
+					</view>
+				</view>
+				<view class="tui-sku-unit">
+					<view class="sku-unit-h1">规格:</view>
+					<view class="sku-unit-li">
+						<view
+							class="unit-li"
+							v-for="(sku, index) in skuList"
+							@click="handleChoisSku(sku, index)"
+							:key="index"
+							:class="skuIndex === index ? 'active' : ''"
+						>
+							{{ sku.unit }} <text class="tips" v-if="sku.stock === 0">缺货</text>
+						</view>
+					</view>
+				</view>
+				<view class="sku-unit-nunbox">
+					<view class="sku-unit-nunbox" v-if="skuProduct.step === 2">
+						<view class="text">*该商品只能以起订量的整数倍购买</view>
+					</view>
+					<view class="sku-unit-nunbox-t">
+						<view class="sku-unit-nunbox-text">购买数量:</view>
+						<view class="sku-unit-nunbox-num">
+							<view class="number-box">
+								<view
+									class="iconfont icon-jianhao"
+									@click="changeCountSub"
+									:class="[isQuantity == true ? 'disabled' : '']"
+								></view>
+								<input
+									class="btn-input"
+									type="number"
+									v-model="productCount"
+									maxlength="4"
+									@blur="changeNumber($event)"
+								/>
+								<view
+									class="iconfont icon-jiahao"
+									@click="changeCountAdd"
+									:class="[isStock == true ? 'disabled' : '']"
+								></view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="tui-right-flex tui-popup-btn" :style="{ paddingBottom: isIphoneX ? '68rpx' : '34rpx' }">
+				<view class="tui-modal-flex">
+					<button
+						class="tui-modal-button cancel"
+						@click="handleBuyConfirm('add')"
+						:disabled="isBtnDisabled"
+						:class="[isBtnDisabled ? 'disabled' : '']"
+					>
+						加入购物车
+					</button>
+					<button
+						class="tui-modal-button confirm"
+						@click="handleBuyConfirm('buy')"
+						:disabled="isBtnDisabled"
+						:class="[isBtnDisabled ? 'disabled' : '']"
+					>
+						立即购买
+					</button>
+				</view>
+			</view>
+		</view>
+	</tui-bottom-popup>
+</template>
+
+<script>
+import { mapState, mapMutations } from 'vuex'
+import uniGrader from '@/components/uni-grade/uni-grade.vue'
+export default {
+	name: 'cm-unit-popup',
+	components: {
+		uniGrader
+	},
+	props: {
+		skuProduct: {
+			type: Object
+		},
+		popupShow: {
+			type: Boolean,
+			default: false
+		},
+		type: {
+			type: Number,
+			default: 1
+		}
+	},
+	data() {
+		return {
+			vipFlag: 0, // 是否是超级会员 0否 1是
+			skuIndex: 0,
+			isStock: false, //
+			isQuantity: false, 
+			handleStock: 0, // 规格库存
+			handleMinNumber: 1, // 规格起订量
+			productCount: 0,
+			skuList: [],
+			addParams: {
+				skuId: 0,
+				productCount: 0,
+				productId: 0,
+				userId: 0,
+				source: 1
+			},
+			isBtnDisabled: false
+		}
+	},
+	filters: {
+		NumFormat(value) {
+			//处理金额
+			return Number(value).toFixed(2)
+		}
+	},
+	created() {
+		this.initData()
+	},
+	computed: {
+		...mapState(['hasLogin'])
+	},
+	methods: {
+		async initData() {
+			const userInfo = await this.$api.getStorage()
+			this.vipFlag = userInfo.vipFlag ? userInfo.vipFlag : 0
+			this.addParams.userId = userInfo.userId ? userInfo.userId : 0
+			this.addParams.productId = this.skuProduct.productId
+			this.skuList = this.skuProduct.skus
+			this.productCount = this.skuList[0].minBuyNumber
+			this.addParams.skuId = this.skuList[0].skuId
+			this.handleMinNumber = this.skuList[0].minBuyNumber
+			this.handleStock = this.skuList[0].stock
+			//处理禁用按钮商品
+			this.isBtnDisabled = this.isDisabledFlag(this.skuProduct)
+			this.isBtnDisabled = this.skuList[0].stock === 0 
+		},
+		isDisabledFlag(pros) {
+			// 非会员
+			if (!this.vipFlag === 1) return true
+			// 商品已下架 || 库存为0
+			if (pros.validFlag == 3 || pros.stock == 0) return true
+			// 商品价格不公开
+			if (pros.priceFlag === 1) return true
+			// 商品价格仅资质机构可见 && 机构为普通机构
+			if (pros.priceFlag === 2 && this.userIdentity === 4) return true
+			// 商品价格仅医美机构可见 && 机构为普通机构
+			if (pros.priceFlag === 3 && this.userIdentity === 4) return true
+			// 商品价格仅医美机构可见 && 机构为资质机构 && 不是医美机构
+			if (pros.priceFlag === 3 && this.userIdentity === 2 && this.firstClubType != 1) return true
+			//其他
+			return false
+		},
+		isShowVipFlag(pros) {
+			// 未登录 || 非会员
+			if (!this.hasLogin || !this.vipFlag === 1) return false
+			// 商品所有机构可见
+			if (pros.priceFlag === 0) return true
+			// 商品价格仅资质机构可见
+			if (pros.priceFlag === 2 && this.userIdentity === 2) return true
+			// 商品价格仅医美机构可见
+			if (pros.priceFlag === 3 && this.userIdentity === 2 && this.firstClubType == 1) return true
+			// 其它
+			return false
+		},
+		PromotionsFormat(promo) {
+			//促销活动类型数据处理
+			if (promo != null) {
+				if (promo.type == 1 && promo.mode == 1) {
+					return true
+				} else {
+					return false
+				}
+			}
+			return false
+		},
+		//popup弹窗数量增加按钮
+		changeCountAdd() {
+			if (this.productCount === this.handleStock) {
+				this.isStock = true
+				return
+			}
+			if (this.skuProduct.step == 2) {
+				this.productCount += this.handleMinNumber
+			} else {
+				this.productCount++
+			}
+		},
+		//popup弹窗数量减按钮
+		changeCountSub() {
+			if (this.productCount <= this.handleMinNumber) {
+				this.productCount = this.handleMinNumber
+				this.isQuantity = true
+				this.$util.msg(`该商品最小起订量为${this.handleMinNumber}`, 2000)
+				return
+			} else {
+				if (this.skuProduct.step == 2) {
+					this.productCount -= this.handleMinNumber
+				} else {
+					this.productCount--
+				}
+				this.isQuantity = false
+			}
+		},
+		changeNumber(e) {
+			let _value = e.detail.value
+			if (!this.$api.isNumber(_value)) {
+				this.productCount = this.handleMinNumber
+			} else if (_value < this.handleMinNumber) {
+				this.$util.msg(`该商品最小起订量为${this.handleMinNumber}`, 2000)
+				this.productCount = this.handleMinNumber
+			} else if (_value % this.handleMinNumber != 0) {
+				this.$util.msg('购买量必须为起订量的整数倍', 2000)
+				this.productCount = this.handleMinNumber
+			} else if (_value > this.handleStock) {
+				this.productCount = this.handleStock
+			} else {
+				this.productCount = e.detail.value
+			}
+		},
+		handleBuyConfirm(type) {
+			// 监听确定选择规格
+			if (type == 'buy') {
+				this.handleToConfirm({
+					productIds: this.addParams.productId,
+					skuId: this.addParams.skuId,
+					productCount: this.productCount
+				})
+			} else {
+				this.addParams.productCount = this.productCount
+				this.handleAddClubCart(this.addParams)
+			}
+		},
+		handleToConfirm(data) {
+			//跳转确认订单页面
+			this.$api.navigateTo(`/pages/user/order/create-order?type=1&data=${JSON.stringify({ data: data })}`)
+			this.hidePopup()
+		},
+		handleAddClubCart(params) {
+			//增加购物车成功和toast弹窗提示成功
+			this.ProductService.shoppingAddCart(params)
+				.then(response => {
+					this.$util.msg('加入购物车成功', 1500, true, 'success')
+					this.$parent.GetUserCartNumber()
+					this.hidePopup()
+				})
+				.catch(error => {
+					console.log('error', error.msg)
+				})
+		},
+		handleChoisSku(sku, index) {
+			// 选择SKU
+			this.skuIndex = index
+			this.addParams.productCount = this.handleMinNumber = sku.minBuyNumber
+			this.addParams.skuId = sku.skuId
+			this.handleStock = sku.stock
+			this.isBtnDisabled = sku.stock === 0
+			this.$emit('skuClick', sku)
+		},
+		hidePopup() {
+			this.$parent.popupShow1 = false
+		}
+	}
+}
+</script>
+
+<style lang="scss">
+.tui-popup-box {
+	padding: 40rpx 24rpx 0 24rpx;
+}
+.tui-shopping-main {
+	width: 100%;
+	.tui-sku-title {
+		width: 100%;
+		height: 136rpx;
+		float: left;
+		margin-bottom: 30rpx;
+		.tui-sku-image {
+			width: 138rpx;
+			height: 138rpx;
+			float: left;
+			border-radius: 8rpx;
+			margin-right: 30rpx;
+			box-sizing: border-box;
+			border: 1px dashed #e1e1e1;
+			image {
+				width: 134rpx;
+				height: 134rpx;
+				border-radius: 10rpx;
+			}
+		}
+		.tui-sku-price {
+			height: 136rpx;
+			float: left;
+			.sku-price-viw {
+				width: 100%;
+				height: 40rpx;
+				margin-bottom: 24rpx;
+				.sku-price-text {
+					font-size: 28rpx;
+					line-height: 40rpx;
+					color: #f94b4b;
+					font-weight: bold;
+					.sku-price-l {
+						float: left;
+						font-weight: normal;
+					}
+					&.none {
+						text-decoration: line-through;
+						color: #999999;
+						font-weight: normal;
+					}
+				}
+			}
+			.sku-price-vip {
+				width: 100%;
+				height: 40rpx;
+			}
+		}
+	}
+	.tui-sku-unit {
+		width: 100%;
+		height: auto;
+		float: left;
+		.sku-unit-h1 {
+			font-size: 28rpx;
+			line-height: 40rpx;
+			color: #333333;
+			font-weight: bold;
+		}
+		.sku-unit-li {
+			width: 100%;
+			height: auto;
+			.unit-li {
+				padding: 0 24rpx;
+				line-height: 48rpx;
+				text-align: center;
+				font-size: 24rpx;
+				color: #666666;
+				background: #f5f5f5;
+				float: left;
+				margin-right: 16rpx;
+				margin-top: 12rpx;
+				margin-bottom: 12rpx;
+				border-radius: 24rpx;
+				position: relative;
+				box-sizing: border-box;
+				border: 1px solid #f5f5f5;
+				&.active {
+					border-color: $color-system;
+					background: #fff1eb;
+					color: $color-system;
+					.tips {
+						background: #F3B574;
+					}
+				}
+				.tips {
+					padding: 0 10rpx;
+					line-height: 32rpx;
+					text-align: center;
+					font-size: 22rpx;
+					color: #ffffff;
+					background: #cccccc;
+					float: left;
+					border-radius: 16rpx;
+					position: absolute;
+					right: -12rpx;
+					top: -15rpx;
+				}
+			}
+		}
+	}
+	.sku-unit-nunbox {
+		justify-content: space-between;
+		align-items: center;
+		width: 100%;
+		height: auto;
+		float: left;
+		margin-top: 30rpx;
+		.sku-unit-nunbox-t {
+			width: 100%;
+			height: 44rpx;
+			position: relative;
+			margin-bottom: 20rpx;
+			.text {
+				font-size: $font-size-24;
+				line-height: 48rpx;
+				color: #999999;
+			}
+			.sku-unit-nunbox-text {
+				line-height: 44rpx;
+				font-size: $font-size-28;
+				float: left;
+				font-weight: bold;
+			}
+			.sku-unit-nunbox-num {
+				float: right;
+				.number-box {
+					display: flex;
+					justify-content: center;
+					align-items: center;
+					border: 2rpx solid #D5D5D5;
+					border-radius: 30rpx;
+					height: 48rpx;
+					margin-left: 20rpx;
+					.iconfont {
+						font-size: $font-size-24;
+						padding: 0 18rpx;
+						color: #D5D5D5;
+						text-align: center;
+						line-height: 48rpx;
+						font-weight: bold;
+						background: #F7F7F7;
+						&.icon-jianhao {
+							border-radius: 30rpx 0 0 30rpx;
+							&.disabled {
+								background: #f5f5f5;
+							}
+						}
+						&.icon-jiahao {
+							border-radius: 0 30rpx 30rpx 0;
+							&.disabled {
+								background: #f5f5f5;
+							}
+						}
+					}
+					.btn-input {
+						width: 62rpx;
+						height: 48rpx;
+						line-height: 48rpx;
+						background: #ffffff;
+						border-radius: 4rpx;
+						text-align: center;
+						font-size: $font-size-28;
+					}
+				}
+			}
+		}
+	}
+}
+.tui-popup-btn {
+	width: 100%;
+	float: left;
+	.tui-modal-flex {
+		width: 100%;
+		height: 84rpx;
+		margin-top: 40rpx;
+		display: flex;
+		.tui-modal-button {
+			flex: 1;
+			line-height: 84rpx;
+			font-size: $font-size-28;
+			text-align: center;
+			border-radius: 42rpx;
+			padding: 0;
+			margin: 0 15rpx;
+			box-sizing: border-box;
+			&.cancel {
+				background: #FFF4E6;
+				color: #F3B574;
+				&.disabled {
+					background-color: #e1e1e1;
+					color: #ffffff;
+				}
+			}
+			&.confirm {
+				background: $btn-confirm;
+				color: #ffffff;
+				&.disabled {
+					background: rgba(243,181,116,0.5);
+				}
+			}
+		}
+	}
+}
+</style>

+ 233 - 0
components/cm-module/productDetails/evaluate.vue

@@ -0,0 +1,233 @@
+<template name="evaluate">
+	<!-- 供应商信息 -->
+	<view class="evaluate clearfix">
+		<view class="evaluate-header">评价({{evaluateList.length}})</view>
+		<view class="evaluate-empty" v-if="isEmpty">该商品暂无评价</view>
+		<view class="evaluate-list" v-else>
+			<scroll-view scroll-y :style="{'height':scrollHeight+'px'}" @scrolltolower="scrolltolower">
+				<view class="row-list" v-for="(item, index) in evaluateList" :key="index">
+					<view class="list-title">
+						<view class="name">{{item.name}}</view>
+						<view class="stars">
+							<uni-stars :stars="item.score2" :icon-class='iconClass' :icon-color='iconColor' :font-size='36' :width-info="178"></uni-stars>
+						</view>
+					</view>
+					<view class="list-content">
+						{{item.commentContent}}
+					</view>
+					<view class="list-time">
+						<text>{{item.postTime }}</text>
+					</view>
+				</view>
+				<!--加载loadding-->
+				<tui-loadmore :visible="loadding" :index="3" type="black"></tui-loadmore>
+				<tui-nomore :visible="!pullUpOn" bgcolor="#FFFFFF" :text='nomoreText'></tui-nomore>
+				<!--加载loadding-->
+			</scroll-view>	
+		</view>
+	</view>
+</template>
+
+<script>
+	import authorize from '@/common/config/authorize.js'
+	import tuiLoadmore from "@/components/tui-components/loadmore/loadmore"
+	import tuiNomore from "@/components/tui-components/nomore/nomore"
+	import uniStars from '@/components/uni-stars/uni-stars.vue'
+	
+	export default{
+		name:'evaluate',
+		props:{
+			queryProductid: {
+				// Unistars类型
+				type: Number,
+				default: 0
+			}
+		},
+		components:{
+			tuiLoadmore,
+			tuiNomore,
+			uniStars
+		},
+		data() {
+			return{
+				evaluateList:[],
+				iconClass:'icon-aixin',
+				iconColor:'#FF7800',
+				isEmpty:false,
+				pageNum:1,
+				pageSize:10,
+				hasNextPage:false,
+				loadding: false,
+				pullUpOn: true,
+				nomoreText: '上拉显示更多',
+				productID:'',
+				scrollHeight: '',
+			}
+		},
+		created() {
+			this.productID = this.queryProductid
+			this.infoEvaluate()
+			this.setScrollHeight();		
+		},
+		methods:{
+			infoEvaluate(){
+				this.ProductService.GetProductEvaluate({productID:this.productID,pageNum:this.pageNum,pageSize:this.pageSize}).then(response =>{
+					let responseData = response.data
+					if(responseData.results&&responseData.results.length > 0){
+						this.isEmpty = false
+						this.hasNextPage = responseData.hasNextPage
+						this.evaluateList =responseData.results
+						this.pullFlag = false;
+						setTimeout(()=>{this.pullFlag = true;},500)
+						if(this.hasNextPage){
+							this.pullUpOn = false
+							this.nomoreText = '上拉显示更多'
+						}else{
+							this.pullUpOn = true
+							this.loadding = false
+							this.nomoreText = '已至底部'
+						}
+					}else{
+						this.isEmpty = true
+					}
+				}).catch(error =>{
+					this.$util.msg(error.msg,2000)
+				})
+			},
+			getOnReachBottomData(){
+				this.pageNum+=1
+				let params = {productID:this.productID,pageNum:this.pageNum,pageSize:this.pageSize}
+				this.ProductService.GetProductEvaluate(params).then(response =>{
+					let responseData = response.data
+					if(responseData.results&&responseData.results.length > 0){
+						this.hasNextPage = responseData.hasNextPage
+						this.evaluateList = this.evaluateList.concat(responseData.results) 
+						this.pullFlag = false;// 防上拉暴滑
+						setTimeout(()=>{this.pullFlag = true;},500)
+						if(this.hasNextPage){
+							this.pullUpOn = false
+							this.nomoreText = '上拉显示更多'
+						}else{
+							this.pullUpOn = false
+							this.loadding = false
+							this.nomoreText = '已至底部'
+						}
+					}
+				}).catch(error =>{
+					this.$util.msg(error.msg,2000)
+				})
+			},
+			scrolltolower() {
+				if(this.hasNextPage){
+					this.loadding = true
+					this.pullUpOn = true
+					this.getOnReachBottomData(this.currentTab);
+				}	
+			},
+			setScrollHeight() {
+				const {windowHeight, pixelRatio} = wx.getSystemInfoSync();
+				this.windowHeight = windowHeight - 1;
+				this.scrollHeight = windowHeight - 1;
+			}
+		},
+		
+	}
+</script>
+
+<style lang="scss">	
+.evaluate{
+	background: #FFFFFF;
+	width: 100%;
+	.scoll-y {
+		height: 100%;
+	}
+	.evaluate-empty{
+		width: 702rpx;
+		height: 100rpx;
+		line-height: 100rpx;
+		padding: 0 24rpx;
+		font-size: $font-size-28;
+		color: #999999;
+		text-align: center;
+	}
+	.evaluate-header{
+		width: 702rpx;
+		height: 88rpx;
+		line-height: 88rpx;
+		padding: 0 24rpx;
+		font-size: $font-size-32;
+		color: $text-color;
+		border-bottom: 1px solid #F2F2F2;
+		text-align: left;
+	}
+	.evaluate-list{
+		width: 702rpx;
+		height: auto;
+		padding: 24rpx;
+		.row-list{
+			width: 100%;
+			height: auto;
+			float: left;
+			padding: 15rpx 0;
+			border-bottom: 1px solid #F2F2F2;
+			&:last-child{
+				margin-bottom: 30rpx;
+			}
+			.list-title{
+				height: 40rpx;
+				line-height: 40rpx;
+				font-size: $font-size-28;
+				color: $text-color;
+				padding: 20rpx 0;
+				.name{
+					float: left;
+					margin-right: 30rpx;
+				}
+				.stars{
+					width: 178rpx;
+					float: right;
+				}
+			}
+			.list-content{
+				width: 100%;
+				min-height: 80rpx;
+				height: auto;
+				font-size: $font-size-24;
+				line-height: 30rpx;
+				text-align: justify;
+				padding: 10rpx 0;
+				color: #999999;
+			}
+			.list-time{
+				width: 100%;
+				height: 40rpx;
+				font-size: $font-size-24;
+				line-height: 40rpx;
+				text-align: right;
+				color: #999999;
+			}
+		}
+	}
+}
+</style>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 121 - 0
components/cm-module/scrollTop/scrollTop.vue

@@ -0,0 +1,121 @@
+<template name="scrollTop">
+	<!-- 商品详情价格判断 -->
+	<view>
+		<view class="scrollTop" :style="{bottom:bottom+'rpx'}">
+			<view class="icon msg">
+				<!-- #ifdef MP-WEIXIN -->
+				<button class="contact-btn" open-type="contact" @bindcontact="handleContact">
+					<text class="iconfont icon-kefu"></text>
+				</button>	
+				<!-- #endif -->
+			</view>
+			<view class="icon top" @click="onPageScrollTop" :class="isScrollTop ? 'show' : 'none'">
+				<text class="iconfont icon-zhiding"></text>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default{
+		name:'scrollTop',
+		props:{
+			bottom:{
+				type:Number,
+				default:100
+			},
+			isScrollTop:{
+				type:Boolean,
+				default:false
+			}
+		},
+		data() {
+			return{
+				isPhone:false,
+				telPhone:'0755-22907771',
+				mobilePhone:'15338851365'
+			}
+		},
+		created() {
+			
+		},
+		methods:{
+			onPageScrollTop(){
+				uni.pageScrollTo({
+				    scrollTop: 0,
+				    duration: 600
+				})
+			},
+			handleContact(e){
+				console.log(e.detail.path)
+				console.log(e.detail.query)
+			},
+		},		
+	}
+</script>
+
+<style lang="scss">	
+	.scrollTop{
+		width: 80rpx;
+		height: 200rpx;
+		position: fixed;
+		right: 20rpx;
+		z-index: 99;
+		.icon{
+			width: 80rpx;
+			height: 80rpx;
+			border-radius: 50%;
+			float: left;
+			margin: 10rpx 0;
+			line-height: 80rpx;
+			text-align: center;
+			.contact-btn{
+				width: 80rpx;
+				height: 80rpx;
+				background-color: rgba(0,0,0,0);
+				line-height: 80rpx;
+				.iconfont{
+					font-size: $font-size-44;
+					color: #FFFFFF;
+				}
+			}
+			&.msg{
+				background: $btn-confirm;
+			}
+			&.top{
+				background-color: rgba(0,0,0,0.4);
+				&.show{
+					opacity: 1;
+				}
+				&.none{
+					opacity: 0;
+				}
+			}
+			.iconfont{
+				font-size: $font-size-44;
+				color: #FFFFFF;
+			}
+		}
+	}
+</style>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 6 - 4
components/views/cm-simple-swiper/cm-simple-swiper.vue → components/cm-simple-swiper/cm-simple-swiper.vue

@@ -1,6 +1,6 @@
 <template>
     <view class="simple-swiper">
-        <uni-swiper-dot :info="mapList" :current="current" mode="dot" :dotsStyles="dotsStyles">
+        <uni-swiper-dot :info="mapList" :current="current" :mode="mode" :dotsStyles="dotsStyles">
             <swiper
                 class="swiper"
                 :style="{ height: swiperHeight + 'rpx' }"
@@ -82,17 +82,19 @@ export default {
         // 真正渲染的列表
         mapList() {
             const result = this.formatSwiperList(this.data)
-            console.log(result)
             return result
         },
         // 宽
         width() {
             return 100 / this.columns + '%'
         },
+		mode(){
+			return 'round'
+		},
         dotsStyles() {
             return {
-                width: 6,
-                bottom: 8,
+                width: 4,
+                bottom: 0,
                 color: 'background: rgba(255, 255, 255, 0.39)',
                 backgroundColor: 'background: rgba(255, 255, 255, 0.39)',
                 border: '0',

+ 0 - 0
components/views/cm-simple-swiper/mixins/swiper.js → components/cm-simple-swiper/mixins/swiper.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 6
components/common/tui-clipboard/clipboard.min.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
components/common/tui-color-analysis/tui-color-analysis.js


+ 0 - 314
components/common/tui-validation/tui-validation.js

@@ -1,314 +0,0 @@
-/**
- * 表单验证
- * @author echo.
- * @version 1.6.5
- **/
-
-const form = {
-	//非必填情况下,如果值为空,则不进行校验
-	//当出现错误时返回错误消息,否则返回空即为验证通过
-	/*
-	 formData:Object 表单对象。{key:value,key:value},key==rules.name
-	 rules: Array [{name:name,rule:[],msg:[],validator:[],{name:name,rule:[],msg:[],validator:[]}]
-			name:name 属性=> 元素的名称
-			rule:字符串数组 ["required","isMobile","isEmail","isCarNo","isIdCard","isAmount","isNum","isChinese","isNotChinese","isEnglish",isEnAndNo","isSpecial","isEmoji",""isDate","isUrl","isSame:key","range:[1,9]","minLength:9","maxLength:Number","isKeyword:key1,key2,key3..."]
-			msg:数组 []。 与数组 rule 长度相同,对应的错误提示信息
-			validator:[{msg:'错误消息',method:Function}],自定义验证方法组,函数约定:(value)=>{ return true or false}
-	*/
-	validation: function(formData, rules) {
-		for (let item of rules) {
-			let key = item.name
-			let rule = item.rule
-			let validator = item.validator
-			let msgArr = item.msg
-			if (!key || !rule || rule.length === 0 || !msgArr || msgArr.length === 0 || (!~rule.indexOf(
-						'required') && formData[key].toString()
-					.length === 0)) {
-				continue
-			}
-			for (let i = 0, length = rule.length; i < length; i++) {
-				let ruleItem = rule[i]
-				let msg = msgArr[i]
-				if (!msg || !ruleItem) continue
-				//数据处理
-				let value = null
-				if (~ruleItem.indexOf(':')) {
-					let temp = ruleItem.split(':')
-					ruleItem = temp[0]
-					value = temp[1]
-				}
-				let isError = false
-				switch (ruleItem) {
-					case 'required':
-						isError = form._isNullOrEmpty(formData[key])
-						break
-					case 'isMobile':
-						isError = !form._isMobile(formData[key])
-						break
-					case 'isEmail':
-						isError = !form._isEmail(formData[key])
-						break
-					case 'isCarNo':
-						isError = !form._isCarNo(formData[key])
-						break
-					case 'isIdCard':
-						isError = !form._isIdCard(formData[key])
-						break
-					case 'isAmount':
-						isError = !form._isAmount(formData[key])
-						break
-					case 'isNum':
-						isError = !form._isNum(formData[key])
-						break
-					case 'isChinese':
-						isError = !form._isChinese(formData[key])
-						break
-					case 'isNotChinese':
-						isError = !form._isNotChinese(formData[key])
-						break
-					case 'isEnglish':
-						isError = !form._isEnglish(formData[key])
-						break
-					case 'isEnAndNo':
-						isError = !form._isEnAndNo(formData[key])
-						break
-					case 'isEnOrNo':
-						isError = !form._isEnOrNo(formData[key])
-						break
-					case 'isSpecial':
-						isError = form._isSpecial(formData[key])
-						break
-					case 'isEmoji':
-						isError = form._isEmoji(formData[key])
-						break
-					case 'isDate':
-						isError = !form._isDate(formData[key])
-						break
-					case 'isUrl':
-						isError = !form._isUrl(formData[key])
-						break
-					case 'isSame':
-						isError = !form._isSame(formData[key], formData[value])
-						break
-					case 'range':
-						let range = null
-						try {
-							range = JSON.parse(value)
-							if (range.length <= 1) {
-								throw new Error('range值传入有误!')
-							}
-						} catch (e) {
-							return 'range值传入有误!'
-						}
-						isError = !form._isRange(formData[key], range[0], range[1])
-						break
-					case 'minLength':
-						isError = !form._minLength(formData[key], value)
-						break
-					case 'maxLength':
-						isError = !form._maxLength(formData[key], value)
-						break
-					case 'isKeyword':
-						isError = !form._isKeyword(formData[key], value)
-						break
-					default:
-						break
-				}
-
-				if (isError) {
-					return msg
-				}
-			}
-			if (validator && validator.length > 0) {
-				for (let model of validator) {
-					let func = model.method
-					if (func && !func(formData[key])) {
-						return model.msg
-					}
-				}
-			}
-		}
-		return ''
-	},
-	//允许填写字符串null或者undefined
-	_isNullOrEmpty: function(value) {
-		return (value === null || value === '' || value === undefined) ? true : false
-	},
-	_isMobile: function(value) {
-		// return /^(?:13\d|14\d|15\d|16\d|17\d|18\d|19\d)\d{5}(\d{3}|\*{3})$/.test(value);
-        return /^1[23456789]\d{9}$/.test(value)
-	},
-	_isEmail: function(value) {
-		return /^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/.test(value)
-	},
-	_isCarNo: function(value) {
-		// 新能源车牌
-		const xreg =
-			/^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/
-		// 旧车牌
-		const creg =
-			/^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$/
-		if (value.length === 7) {
-			return creg.test(value)
-		} else if (value.length === 8) {
-			return xreg.test(value)
-		} else {
-			return false
-		}
-	},
-	_isIdCard: function(value) {
-		let idCard = value
-		if (idCard.length == 15) {
-			return this.__isValidityBrithBy15IdCard
-		} else if (idCard.length == 18) {
-			let arrIdCard = idCard.split('')
-			if (this.__isValidityBrithBy18IdCard(idCard) && this.__isTrueValidateCodeBy18IdCard(arrIdCard)) {
-				return true
-			} else {
-				return false
-			}
-		} else {
-			return false
-		}
-	},
-	__isTrueValidateCodeBy18IdCard: function(arrIdCard) {
-		let sum = 0
-		let Wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1]
-		let ValideCode = [1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2]
-		if (arrIdCard[17].toLowerCase() == 'x') {
-			arrIdCard[17] = 10
-		}
-		for (let i = 0; i < 17; i++) {
-			sum += Wi[i] * arrIdCard[i]
-		}
-		let valCodePosition = sum % 11
-		if (arrIdCard[17] == ValideCode[valCodePosition]) {
-			return true
-		} else {
-			return false
-		}
-	},
-	__isValidityBrithBy18IdCard: function(idCard18) {
-		let year = idCard18.substring(6, 10)
-		let month = idCard18.substring(10, 12)
-		let day = idCard18.substring(12, 14)
-		let temp_date = new Date(year, parseFloat(month) - 1, parseFloat(day))
-		if (temp_date.getFullYear() != parseFloat(year) || temp_date.getMonth() != parseFloat(month) - 1 ||
-			temp_date.getDate() !=
-			parseFloat(day)) {
-			return false
-		} else {
-			return true
-		}
-	},
-	__isValidityBrithBy15IdCard: function(idCard15) {
-		let year = idCard15.substring(6, 8)
-		let month = idCard15.substring(8, 10)
-		let day = idCard15.substring(10, 12)
-		let temp_date = new Date(year, parseFloat(month) - 1, parseFloat(day))
-
-		if (temp_date.getYear() != parseFloat(year) || temp_date.getMonth() != parseFloat(month) - 1 ||
-			temp_date.getDate() !=
-			parseFloat(day)) {
-			return false
-		} else {
-			return true
-		}
-	},
-	_isAmount: function(value) {
-		//金额,只允许保留两位小数
-		return /^([0-9]*[.]?[0-9])[0-9]{0,1}$/.test(value)
-	},
-	_isNum: function(value) {
-		//只能为数字
-		return /^[0-9]+$/.test(value)
-	},
-	//是否全部为中文
-	_isChinese: function(value) {
-		let reg = /^[\u4e00-\u9fa5]+$/
-		return value !== '' && reg.test(value) && !form._isSpecial(value) && !form._isEmoji(value)
-	},
-	//是否不包含中文,可以有特殊字符
-	_isNotChinese: function(value) {
-		let reg = /.*[\u4e00-\u9fa5]+.*$/
-		let result = true
-		if (reg.test(value)) {
-			result = false
-		}
-		return result
-	},
-	_isEnglish: function(value) {
-		return /^[a-zA-Z]*$/.test(value)
-	},
-	_isEnAndNo: function(value) {
-		//8~20位数字和字母组合
-		return /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,20}$/.test(value)
-	},
-	_isEnOrNo: function(value) {
-		//英文或者数字
-		let reg = /.*[\u4e00-\u9fa5]+.*$/
-		let result = true
-		if (reg.test(value) || form._isSpecial(value) || form._isEmoji(value)) {
-			result = false
-		}
-		return result
-	},
-	_isSpecial: function(value) {
-		//是否包含特殊字符
-		let regEn = /[`~!@#$%^&*()_+<>?:"{},.\/;'[\]]/im,
-			regCn = /[·!#¥(——):;“”‘、,|《。》?、【】[\]]/im
-		if (regEn.test(value) || regCn.test(value)) {
-			return true
-		}
-		return false
-	},
-	_isEmoji: function(value) {
-		//是否包含表情
-		return /\uD83C[\uDF00-\uDFFF]|\uD83D[\uDC00-\uDE4F]/g.test(value)
-	},
-	_isDate: function(value) {
-		//2019-10-12
-		const reg =
-			/^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$/
-		return reg.test(value)
-	},
-	_isUrl: function(value) {
-		return /^((https?|ftp|file):\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})(:[0-9]{1,5})?((\/?)|(\/[\\\w_!~*\\'()\\\.;?:@&=+$,%#-]+)+\/?)$/.test(value)
-	},
-	_isSame: function(value1, value2) {
-		return value1 === value2
-	},
-	_isRange: function(value, range1, range2) {
-		if ((!range1 && range1 != 0) && (!range2 && range2 != 0)) {
-			return true
-		} else if (!range1 && range1 != 0) {
-			return value <= range2
-		} else if (!range2 && range2 != 0) {
-			return value >= range1
-		} else {
-			return value >= range1 && value <= range2
-		}
-	},
-	_minLength: function(value, min) {
-		return value.length >= Number(min)
-	},
-	_maxLength: function(value, max) {
-		return value.length <= Number(max)
-	},
-	_isKeyword: function(value, keywords) {
-		//是否包含关键词,敏感词,多个以英文逗号分隔,包含则为false,弹出提示语!
-		let result = true
-		if (!keywords) return result
-		let key = keywords.split(',')
-		for (let i = 0, len = key.length; i < len; i++) {
-			if (~value.indexOf(key[i])) {
-				result = false
-				break
-			}
-		}
-		return result
-	}
-}
-export default {
-	validation: form.validation
-}

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
components/common/tui-validation/tui-validation.min.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
components/common/tui-zh-pinyin/tui-zh-pinyin.js


+ 80 - 0
components/empty.vue

@@ -0,0 +1,80 @@
+<template>
+	<view class="empty-content">
+		<image class="empty-content-image" :src="setSrc" mode="aspectFit"></image>
+		<text class="error-text">{{EmptyText}}</text>
+	</view>
+</template>
+
+<script>
+	export default {
+		props: {
+			src: {
+				type: String,
+				default: 'empty'
+			},
+			typeIndex:{
+				type:String,
+				default: 'empty'
+			},
+			navbarHeight:{
+				type:Number
+			}
+		},
+
+		data() {
+			return {
+				typeSrcall: {
+					empty: 'https://img.caimei365.com/group1/M00/03/71/Cmis2F3wna6AcewRAAEtqt4jZmU397.png',				
+				},
+				typeSrc: {
+					empty: 'https://img.caimei365.com/group1/M00/03/71/Cmis2F3wna6AJZvwAAGWWe4DnXk371.png',				
+				},
+				EmptyText:'',
+			}
+		},
+		created(){
+			if(this.typeIndex==0){
+				this.EmptyText = '您还没有任何的订单哟~'
+			}else{
+				this.EmptyText = '您还没有相关的订单哟~'
+			}
+		},
+		computed: {
+			setSrc() {
+				let url;
+				if(this.typeIndex==0){					
+					url = this.typeSrcall[this.src]
+				}else{
+					url = this.typeSrc[this.src]
+				}
+				return url;
+			},
+		},
+	}
+</script>
+
+<style lang="scss">
+	.empty-content {
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		flex-direction: column;
+		position: fixed;
+		top: 0;
+		left: 0;
+		bottom: 0;
+		right: 0;
+		margin: auto;
+		background: $bg-color;
+		z-index: 999;
+		&-image {
+			width: 382rpx;
+			height: 310rpx;
+		}
+		.error-text{
+			font-size: $font-size-28;
+			color: $text-color;
+			line-height: 88rpx;
+		}
+	}
+</style>

+ 33 - 0
components/modal-layer.vue

@@ -0,0 +1,33 @@
+<template name="modal">
+	<view class="modal">
+		<view class="modal-content"></view>
+	</view>
+</template>
+<script>
+	export default {
+		name:'modal',
+		data() {
+			return {
+
+			}
+		},
+		created() {
+
+		},
+		computed: {
+
+		},
+	}
+</script>
+
+<style lang="scss">
+	.modal-content {
+		width: 100%;
+		height: 100%;
+		position: fixed;
+		left: 0;
+		top: 0;
+		background:rgba(255,255,255,0);
+		z-index: 7777;
+	}
+</style>

+ 242 - 0
components/mpvue-citypicker/mpvueCityPicker.vue

@@ -0,0 +1,242 @@
+<template>
+	<div class="mpvue-picker">
+		<div :class="{'pickerMask':showPicker}" @click="maskClick" catchtouchmove="true"></div>
+		<div class="mpvue-picker-content " :class="{'mpvue-picker-view-show':showPicker}">
+			<div class="mpvue-picker__hd" catchtouchmove="true">
+				<div class="mpvue-picker__action" @click="pickerCancel">取消</div>
+				<div class="mpvue-picker__action" :style="{color:themeColor}" @click="pickerConfirm">确定</div>
+			</div>
+			<picker-view indicator-style="height: 40px;" class="mpvue-picker-view" :value="pickerValue" @change="pickerChange">
+				<block>
+					<picker-view-column>
+						<div class="picker-item" v-for="(item,index) in provinceDataList" :key="index">{{item.name}}</div>
+					</picker-view-column>
+					<picker-view-column>
+						<div class="picker-item" v-for="(item,index) in cityDataList" :key="index">{{item.name}}</div>
+					</picker-view-column>
+					<picker-view-column>
+						<div class="picker-item" v-for="(item,index) in areaDataList" :key="index">{{item.name}}</div>
+					</picker-view-column>
+				</block>
+			</picker-view>
+		</div>
+	</div>
+</template>
+
+<script>	
+	import { provinceData,cityData,areaData } from '@/common/config/addressdata.js';
+	export default {
+		data() {
+			return {
+				pickerValue: [0, 0, 0],
+				provinceDataList: provinceData,
+				cityDataList: cityData[1],
+				areaDataList: areaData&&areaData[0]&&areaData[0][0],
+				/* 是否显示控件 */
+				showPicker: false,
+			};
+		},
+		created() {
+			// console.log('provinceData',provinceData)
+			// console.log('cityData',cityData)
+			// console.log('areaData',areaData)
+			// this.init()
+		},
+		props: {
+			/* 默认值 */
+			pickerValueDefault: {
+				type: Array,
+				default () {
+					return [1, 1, 2]
+				}
+			},
+			/* 主题色 */
+			themeColor: String
+		},
+		watch: {
+			pickerValueDefault() {
+				// this.init();
+			}
+		},
+		methods: {
+			init() {
+				this.handPickValueDefault(); // 对 pickerValueDefault 做兼容处理
+				const pickerValueDefault = this.pickerValueDefault
+				this.cityDataList = cityData[pickerValueDefault[0]];
+				this.areaDataList = areaData[pickerValueDefault[0]][pickerValueDefault[1]];
+				this.pickerValue = pickerValueDefault;
+			},
+			show() {
+				setTimeout(() => {
+					this.showPicker = true;
+				}, 0);
+			},
+			showAddrDetails() {
+				this.$parent.isShowInput = false;
+			},
+			maskClick() {
+				this.showAddrDetails();
+				this.pickerCancel();
+			},
+			pickerCancel() {
+				this.showAddrDetails();
+				this.showPicker = false;
+				// this._$emit('onCancel');
+			},
+			pickerConfirm(e) {
+				this.showAddrDetails();
+				this.showPicker = false;
+				this._$emit('onConfirm');
+			},
+			showPickerView() {
+				this.showPicker = true;
+			},
+			handPickValueDefault() {
+				const pickerValueDefault = this.pickerValueDefault
+				let provinceIndex = pickerValueDefault[0]
+				let cityIndex = pickerValueDefault[1]
+				const areaIndex = pickerValueDefault[2]
+				if (
+					provinceIndex !== 0 ||
+					cityIndex !== 0 ||
+					areaIndex !== 0
+				) {
+					if (provinceIndex > provinceData.length - 1) {
+						this.pickerValueDefault[0] = provinceIndex = provinceData.length - 1;
+					}
+					// if (cityIndex > cityData[provinceIndex].length - 1) {
+					// 	this.pickerValueDefault[1] = cityIndex = cityData[provinceIndex].length - 1;
+					// }
+					// if (areaIndex > areaData[provinceIndex][cityIndex].length - 1) {
+					// 	this.pickerValueDefault[2] = areaData[provinceIndex][cityIndex].length - 1;
+					// }
+				}
+			},
+			pickerChange(e) {
+				let changePickerValue = e.mp.detail.value;
+				if (this.pickerValue[0] !== changePickerValue[0]) {
+					// 第一级发生滚动
+					this.cityDataList = cityData[changePickerValue[0]];
+					this.areaDataList = areaData[changePickerValue[0]][0];
+					changePickerValue[1] = 0;
+					changePickerValue[2] = 0;
+				} else if (this.pickerValue[1] !== changePickerValue[1]) {
+					// 第二级滚动
+					this.areaDataList =
+						areaData[changePickerValue[0]][changePickerValue[1]];
+					changePickerValue[2] = 0;
+				}
+				this.pickerValue = changePickerValue;
+				this._$emit('onChange');
+			},
+			_$emit(emitName) {
+				let pickObj = {
+					name: this._getLabel(),
+					value: this.pickerValue,
+					townCode: this._getTownCode(),
+					cityCode: this._getCityCode(),
+					provinceCode: this._getProvinceCode()
+				};
+				this.$emit(emitName, pickObj);
+			},
+			_getLabel() {
+				let pcikerLabel =
+					this.provinceDataList[this.pickerValue[0]].name +
+					'-' +
+					this.cityDataList[this.pickerValue[1]].name +
+					'-' +
+					this.areaDataList[this.pickerValue[2]].name;
+				return pcikerLabel;
+			},
+			_getTownCode() {
+				return this.areaDataList[this.pickerValue[2]].id;
+			},
+			_getCityCode() {
+				return this.cityDataList[this.pickerValue[1]].id;
+			},
+			_getProvinceCode() {
+				return this.provinceDataList[this.pickerValue[0]].id;
+			}
+		}
+	};
+</script>
+
+<style>
+	.pickerMask {
+		position: fixed;
+		z-index: 2888;
+		top: 0;
+		right: 0;
+		left: 0;
+		bottom: 0;
+		background: rgba(0, 0, 0, 0.6);
+	}
+
+	.mpvue-picker-content {
+		position: fixed;
+		bottom: 0;
+		left: 0;
+		width: 100%;
+		transition: all 0.3s ease;
+		transform: translateY(100%);
+		z-index: 3000;
+	}
+
+	.mpvue-picker-view-show {
+		transform: translateY(0);
+	}
+
+	.mpvue-picker__hd {
+		display: flex;
+		padding: 9px 15px;
+		background-color: #fff;
+		position: relative;
+		text-align: center;
+		font-size: 17px;
+	}
+
+	.mpvue-picker__hd:after {
+		content: ' ';
+		position: absolute;
+		left: 0;
+		bottom: 0;
+		right: 0;
+		height: 1px;
+		border-bottom: 1px solid #e5e5e5;
+		color: #e5e5e5;
+		transform-origin: 0 100%;
+		transform: scaleY(0.5);
+	}
+
+	.mpvue-picker__action {
+		display: block;
+		flex: 1;
+		color: #1aad19;
+	}
+
+	.mpvue-picker__action:first-child {
+		text-align: left;
+		color: #888;
+	}
+
+	.mpvue-picker__action:last-child {
+		text-align: right;
+	}
+
+	.picker-item {
+		text-align: center;
+		line-height: 40px;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+		font-size: 16px;
+	}
+
+	.mpvue-picker-view {
+		position: relative;
+		bottom: 0;
+		left: 0;
+		width: 100%;
+		height: 238px;
+		background-color: rgba(255, 255, 255, 1);
+	}
+</style>

+ 2 - 4
components/thorui/tui-actionsheet/tui-actionsheet.vue

@@ -21,7 +21,6 @@
 <script>
 	export default {
 		name: "tuiActionsheet",
-		emits: ['click','cancel'],
 		props: {
 			//点击遮罩 是否可关闭
 			maskClosable: {
@@ -76,10 +75,9 @@
 			},
 			handleClickItem(e) {
 				if (!this.show) return;
-				const index = Number(e.currentTarget.dataset.index);
+				const dataset = e.currentTarget.dataset;
 				this.$emit('click', {
-					index: index,
-					...this.itemList[index]
+					index: Number(dataset.index)
 				});
 			},
 			handleClickCancel() {

+ 0 - 1
components/thorui/tui-alert/tui-alert.vue

@@ -14,7 +14,6 @@
 <script>
 	export default {
 		name:"tuiAlert",
-		emits: ['click','cancel'],
 		props: {
 			//控制显示
 			show: {

+ 0 - 1
components/thorui/tui-badge/tui-badge.vue

@@ -8,7 +8,6 @@
 <script>
 	export default {
 		name: 'tuiBadge',
-		emits: ['click'],
 		props: {
 			//primary,warning,green,danger,white,black,gray,white_red
 			type: {

+ 13 - 12
components/thorui/tui-bottom-navigation/tui-bottom-navigation.vue

@@ -10,7 +10,7 @@
 			>
 				<view class="tui-item-inner" @tap="menuClick(index, item.parameter, item.type)">
 					<image
-						:src="getIcon(current,index, item)"
+						:src="current | getIcon(index, item)"
 						class="tui-navigation-img"
 						v-if="item.iconPath || (current == index && item.selectedIconPath && item.type == 1)"
 					></image>
@@ -38,7 +38,7 @@
 						:hover-stay-time="150"
 						v-for="(subItem, subIndex) in item.itemList || []"
 						:key="subIndex"
-						@tap="subMenuClick(index, item.type, subIndex, subItem.parameter || '')"
+						@tap="subMenuClick(index, item.type, subIndex, subItem.parameter)"
 					>
 						<text class="tui-ellipsis" :style="{ color: isDarkMode ? '#fff' : subMenuColor, fontSize: subMenufontSize, lineHeight: subMenufontSize }">
 							{{ subItem.text }}
@@ -55,7 +55,6 @@
 <script>
 export default {
 	name: 'tuiBottomNavigation',
-	emits: ['click'],
 	props: {
 		//当前索引
 		current: {
@@ -161,19 +160,21 @@ export default {
 			default: false
 		}
 	},
-	data() {
-		return {
-			showMenuIndex: -1 //显示的菜单index
-		};
-	},
-	methods: {
+	filters: {
 		getIcon: function(current, index, item) {
 			let url = item.iconPath;
 			if (item.type == 1) {
 				url = current == index ? item.selectedIconPath || item.iconPath : item.iconPath;
 			}
 			return url;
-		},
+		}
+	},
+	data() {
+		return {
+			showMenuIndex: -1 //显示的菜单index
+		};
+	},
+	methods: {
 		stop() {
 			return false;
 		},
@@ -229,7 +230,7 @@ export default {
 .tui-bottom-navigation::after {
 	content: '';
 	width: 100%;
-	border-top: 1px solid #bfbfbf;
+	border-top: 1rpx solid #bfbfbf;
 	position: absolute;
 	top: 0;
 	left: 0;
@@ -261,7 +262,7 @@ export default {
 	height: 100%;
 	content: '';
 	position: absolute;
-	border-right: 1px solid #bfbfbf;
+	border-right: 1rpx solid #bfbfbf;
 	transform: scaleX(0.5) translateZ(0);
 	right: 0;
 	top: 0;

+ 13 - 24
components/thorui/tui-bottom-popup/tui-bottom-popup.vue

@@ -1,16 +1,15 @@
 <template>
 	<view @touchmove.stop.prevent>
-		<view class="tui-popup-class tui-bottom-popup" :class="{ 'tui-popup-show': show, 'tui-popup-radius': radius }" :style="{ backgroundColor: backgroundColor, height: height ? height + 'rpx' : 'auto', zIndex: zIndex,transform:`translate3d(0, ${show?translateY:'100%'}, 0)`}">
+		<view class="tui-popup-class tui-bottom-popup" :class="{'tui-popup-show':show,'tui-popup-radius':radius}" :style="{backgroundColor:backgroundColor,height:height?height+'rpx':'auto'}">
 			<slot></slot>
 		</view>
-		<view class="tui-popup-mask" :class="[show ? 'tui-mask-show' : '']" :style="{ zIndex: maskZIndex }" v-if="mask" @tap="handleClose"></view>
+		<view class="tui-popup-mask" :class="[show?'tui-mask-show':'']" v-if="mask" @tap="handleClose"></view>
 	</view>
 </template>
 
 <script>
 	export default {
-		name: 'tuiBottomPopup',
-		emits: ['close'],
+		name: "tuiBottomPopup",
 		props: {
 			//是否需要mask
 			mask: {
@@ -25,7 +24,7 @@
 			//背景颜色
 			backgroundColor: {
 				type: String,
-				default: '#fff'
+				default: "#fff"
 			},
 			//高度 rpx
 			height: {
@@ -33,22 +32,9 @@
 				default: 0
 			},
 			//设置圆角
-			radius: {
-				type: Boolean,
-				default: true
-			},
-			zIndex: {
-				type: [Number, String],
-				default: 997
-			},
-			maskZIndex: {
-				type: [Number, String],
-				default: 996
-			},
-			//弹层显示时,垂直方向移动的距离
-			translateY: {
-				type: String,
-				default: '0'
+			radius:{
+				type:Boolean,
+				default:true
 			}
 		},
 		methods: {
@@ -59,7 +45,7 @@
 				this.$emit('close', {});
 			}
 		}
-	};
+	}
 </script>
 
 <style scoped>
@@ -69,13 +55,14 @@
 		left: 0;
 		right: 0;
 		bottom: 0;
+		z-index: 997;
+		/* visibility: hidden; */
 		opacity: 0;
 		transform: translate3d(0, 100%, 0);
 		transform-origin: center;
 		transition: all 0.3s ease-in-out;
 		min-height: 20rpx;
 	}
-
 	.tui-popup-radius {
 		border-top-left-radius: 24rpx;
 		border-top-right-radius: 24rpx;
@@ -84,8 +71,9 @@
 	}
 
 	.tui-popup-show {
+		transform: translate3d(0, 0, 0);
 		opacity: 1;
-		/* transform: translate3d(0, 0, 0); */
+		/* visibility: visible; */
 	}
 
 	.tui-popup-mask {
@@ -95,6 +83,7 @@
 		right: 0;
 		bottom: 0;
 		background-color: rgba(0, 0, 0, 0.6);
+		z-index: 996;
 		transition: all 0.3s ease-in-out;
 		opacity: 0;
 		visibility: hidden;

+ 0 - 1
components/thorui/tui-bubble-popup/tui-bubble-popup.vue

@@ -46,7 +46,6 @@
 <script>
 	export default {
 		name: 'tuiBubblePopup',
-		emits: ['close'],
 		props: {
 			//宽度
 			width: {

+ 39 - 192
components/thorui/tui-button/tui-button.vue

@@ -3,14 +3,10 @@
 			plain ? 'tui-' + type + '-outline' : 'tui-btn-' + (type || 'primary'),
 			getDisabledClass(disabled, type, plain),
 			getShapeClass(shape, plain),
-			getShadowClass(type, shadow, plain),
-			bold ? 'tui-text-bold' : '',
-			link ? 'tui-btn__link' : ''
-		]" :hover-class="getHoverClass(disabled, type, plain)"
-		:style="{ width: width, height: height, lineHeight: height, fontSize: size + 'rpx', margin: margin }"
-		:loading="loading" :form-type="formType" :open-type="openType" @getuserinfo="bindgetuserinfo"
-		@getphonenumber="bindgetphonenumber" @contact="bindcontact" @error="binderror" :disabled="disabled"
-		@tap="handleClick">
+			getShadowClass(type, shadow, plain)
+		]"
+	 :hover-class="getHoverClass(disabled, type, plain)" :style="{ width: width, height: height, lineHeight: height, fontSize: size + 'rpx',margin:margin }"
+	 :loading="loading" :open-type="openType" @getuserinfo="bindgetuserinfo" :disabled="disabled" @tap="handleClick">
 		<slot></slot>
 	</button>
 </template>
@@ -18,14 +14,8 @@
 <script>
 	export default {
 		name: 'tuiButton',
-		emits: ['click', 'getuserinfo', 'contact', 'getphonenumber', 'error'],
-		// #ifndef VUE3
-		// #ifndef MP-QQ
-		behaviors: ['wx://form-field-button'],
-		// #endif
-		// #endif
 		props: {
-			//样式类型 primary, white, danger, warning, green,blue, gray,black,brown,gray-primary,gray-danger,gray-warning,gray-green
+			//样式类型 primary, white, danger, warning, green,blue, gray,black
 			type: {
 				type: String,
 				default: 'primary'
@@ -50,13 +40,9 @@
 				type: Number,
 				default: 32
 			},
-			bold: {
-				type: Boolean,
-				default: false
-			},
 			margin: {
 				type: String,
-				default: '0'
+				default: "0"
 			},
 			//形状 circle(圆角), square(默认方形),rightAngle(平角)
 			shape: {
@@ -67,11 +53,6 @@
 				type: Boolean,
 				default: false
 			},
-			//link样式,去掉边框,结合plain一起使用
-			link: {
-				type: Boolean,
-				default: false
-			},
 			disabled: {
 				type: Boolean,
 				default: false
@@ -85,10 +66,6 @@
 				type: Boolean,
 				default: false
 			},
-			formType: {
-				type: String,
-				default: ''
-			},
 			openType: {
 				type: String,
 				default: ''
@@ -96,112 +73,56 @@
 			index: {
 				type: [Number, String],
 				default: 0
-			},
-			//是否需要阻止重复点击【默认200ms】
-			preventClick: {
-				type: Boolean,
-				default: false
-			}
-		},
-		data() {
-			return {
-				time: 0
 			}
 		},
 		methods: {
 			handleClick() {
-				if (this.disabled) return
-				if (this.preventClick) {
-					if (new Date().getTime() - this.time <= 200) return
-					this.time = new Date().getTime()
-					setTimeout(() => {
-						this.time = 0
-					}, 200)
-				}
+				if (this.disabled) return false;
 				this.$emit('click', {
 					index: Number(this.index)
-				})
+				});
 			},
 			bindgetuserinfo({
 				detail = {}
 			} = {}) {
-				this.$emit('getuserinfo', detail)
-			},
-			bindcontact({
-				detail = {}
-			} = {}) {
-				this.$emit('contact', detail)
-			},
-			bindgetphonenumber({
-				detail = {}
-			} = {}) {
-				this.$emit('getphonenumber', detail)
-			},
-			binderror({
-				detail = {}
-			} = {}) {
-				this.$emit('error', detail)
+				this.$emit('getuserinfo', detail);
 			},
 			getShadowClass: function(type, shadow, plain) {
-				let className = ''
+				let className = '';
 				if (shadow && type != 'white' && !plain) {
-					className = 'tui-shadow-' + type
+					className = 'tui-shadow-' + type;
 				}
-				return className
+				return className;
 			},
 			getDisabledClass: function(disabled, type, plain) {
-				let className = ''
-				if (disabled && type != 'white' && type.indexOf('-') == -1) {
-					let classVal = this.disabledGray ? 'tui-gray-disabled' : 'tui-dark-disabled'
-					className = plain ? 'tui-dark-disabled-outline' : classVal
+				let className = '';
+				if (disabled && type != 'white') {
+					let classVal = this.disabledGray ? 'tui-gray-disabled' : 'tui-dark-disabled';
+					className = plain ? 'tui-dark-disabled-outline' : classVal;
 				}
-				return className
+				return className;
 			},
 			getShapeClass: function(shape, plain) {
-				let className = ''
+				let className = '';
 				if (shape == 'circle') {
-					className = plain ? 'tui-outline-fillet' : 'tui-fillet'
+					className = plain ? 'tui-outline-fillet' : 'tui-fillet';
 				} else if (shape == 'rightAngle') {
-					className = plain ? 'tui-outline-rightAngle' : 'tui-rightAngle'
+					className = plain ? 'tui-outline-rightAngle' : 'tui-rightAngle';
 				}
-				return className
+				return className;
 			},
 			getHoverClass: function(disabled, type, plain) {
-				let className = ''
+				let className = '';
 				if (!disabled) {
-					className = plain ? 'tui-outline-hover' : 'tui-' + (type || 'primary') + '-hover'
+					className = plain ? 'tui-outline-hover' : 'tui-' + (type || 'primary') + '-hover';
 				}
-				return className
+				return className;
 			}
 		}
-	}
+	};
 </script>
 
 <style scoped>
-	
-	.tui-btn-base {
-		background: linear-gradient(270deg, #f83c6c 0%, #fc32b4 100%) !important;
-		color: #fff;
-	}
-	
-	.tui-shadow-base {
-		box-shadow: 0 10rpx 14rpx 0 rgba(86, 119, 252, 0.2);
-	}
-    
-    .tui-base-hover {
-    	background: linear-gradient(270deg, #f8335e 0%, #fc2aa1 100%) !important;
-    	color: #e5e5e5 !important;
-    }
-    
-    .tui-base-outline::after {
-    	border: 1px solid #f83c6c !important;
-    }
-    
-    .tui-base-outline {
-    	color: #f83c6c !important;
-    	background: transparent;
-    }
-	
 	.tui-btn-primary {
 		background: #5677fc !important;
 		color: #fff;
@@ -230,16 +151,16 @@
 	}
 
 	.tui-btn-green {
-		background: #07c160 !important;
+		background: #35b06a !important;
 		color: #fff;
 	}
 
 	.tui-shadow-green {
-		box-shadow: 0 10rpx 14rpx 0 rgba(7, 193, 96, 0.2);
+		box-shadow: 0 10rpx 14rpx 0 rgba(53, 176, 106, 0.2);
 	}
 
 	.tui-btn-blue {
-		background: #007aff !important;
+		background: #007AFF !important;
 		color: #fff;
 	}
 
@@ -262,52 +183,6 @@
 		color: #fff !important;
 	}
 
-	.tui-btn-brown {
-		background: #ac9157 !important;
-		color: #fff !important;
-	}
-
-	.tui-btn-gray-black {
-		background: #f2f2f2 !important;
-		color: #333;
-	}
-
-	.tui-btn-gray-primary {
-		background: #f2f2f2 !important;
-		color: #5677fc !important;
-	}
-
-	.tui-gray-primary-hover {
-		background: #d9d9d9 !important;
-	}
-
-	.tui-btn-gray-green {
-		background: #f2f2f2 !important;
-		color: #07c160 !important;
-	}
-
-	.tui-gray-green-hover {
-		background: #d9d9d9 !important;
-	}
-
-	.tui-btn-gray-danger {
-		background: #f2f2f2 !important;
-		color: #eb0909 !important;
-	}
-
-	.tui-gray-danger-hover {
-		background: #d9d9d9 !important;
-	}
-
-	.tui-btn-gray-warning {
-		background: #f2f2f2 !important;
-		color: #fc872d !important;
-	}
-
-	.tui-gray-warning-hover {
-		background: #d9d9d9 !important;
-	}
-
 	.tui-shadow-gray {
 		box-shadow: 0 10rpx 14rpx 0 rgba(191, 191, 191, 0.2);
 	}
@@ -321,11 +196,6 @@
 		color: #e5e5e5 !important;
 	}
 
-	.tui-brown-hover {
-		background: #A37F49 !important;
-		color: #e5e5e5 !important;
-	}
-
 	/* button start*/
 
 	.tui-btn {
@@ -336,9 +206,6 @@
 		padding-left: 0;
 		padding-right: 0;
 		overflow: visible;
-		display: flex;
-		align-items: center;
-		justify-content: center;
 	}
 
 	.tui-btn::after {
@@ -355,12 +222,8 @@
 		border: 0;
 	}
 
-	.tui-text-bold {
-		font-weight: bold;
-	}
-
 	.tui-btn-white::after {
-		border: 1px solid #bfbfbf;
+		border: 1rpx solid #bfbfbf;
 	}
 
 	.tui-white-hover {
@@ -386,17 +249,14 @@
 	.tui-outline-hover {
 		opacity: 0.5;
 	}
-	
-	
+
 	.tui-primary-hover {
 		background: #4a67d6 !important;
 		color: #e5e5e5 !important;
 	}
-    
-    
 
 	.tui-primary-outline::after {
-		border: 1px solid #5677fc !important;
+		border: 1rpx solid #5677fc !important;
 	}
 
 	.tui-primary-outline {
@@ -415,7 +275,7 @@
 	}
 
 	.tui-danger-outline::after {
-		border: 1px solid #eb0909 !important;
+		border: 1rpx solid #eb0909 !important;
 	}
 
 	.tui-warning-hover {
@@ -433,31 +293,31 @@
 	}
 
 	.tui-green-hover {
-		background: #06ad56 !important;
+		background: #2d965a !important;
 		color: #e5e5e5 !important;
 	}
 
 	.tui-green-outline {
-		color: #07c160 !important;
+		color: #35b06a !important;
 		background: transparent;
 	}
 
 	.tui-green-outline::after {
-		border: 1px solid #07c160 !important;
+		border: 1rpx solid #35b06a !important;
 	}
 
 	.tui-blue-hover {
-		background: #0062cc !important;
+		background: #0062CC !important;
 		color: #e5e5e5 !important;
 	}
 
 	.tui-blue-outline {
-		color: #007aff !important;
+		color: #007AFF !important;
 		background: transparent;
 	}
 
 	.tui-blue-outline::after {
-		border: 1px solid #007aff !important;
+		border: 1rpx solid #007AFF !important;
 	}
 
 	/* #ifndef APP-NVUE */
@@ -501,7 +361,7 @@
 	}
 
 	.tui-gray-outline::after {
-		border: 1px solid #ccc !important;
+		border: 1rpx solid #ccc !important;
 	}
 
 	.tui-white-outline::after {
@@ -512,15 +372,6 @@
 		border: 1px solid #333 !important;
 	}
 
-	.tui-brown-outline {
-		color: #ac9157 !important;
-		background: transparent;
-	}
-
-	.tui-brown-outline::after {
-		border: 1px solid #ac9157 !important;
-	}
-
 	/*圆角 */
 
 	.tui-fillet {
@@ -547,8 +398,4 @@
 	.tui-outline-rightAngle::after {
 		border-radius: 0;
 	}
-
-	.tui-btn__link::after {
-		border: 0 !important;
-	}
 </style>

+ 1 - 1
components/thorui/tui-calendar/tui-calendar.js

@@ -556,7 +556,7 @@ let calendar = {
 	}
 };
 
-export default {
+module.exports = {
 	solar2lunar: calendar.solar2lunar,
 	lunar2solar: calendar.lunar2solar
 };

+ 48 - 153
components/thorui/tui-calendar/tui-calendar.vue

@@ -1,22 +1,21 @@
 <template>
-	<view @touchmove.stop.prevent="stop" v-if="isFixed">
-		<view class="tui-bottom-popup" :class="{'tui-popup-show': isShow}">
-			<view class="tui-calendar-header" :class="{ 'tui-calendar-radius': radius }">
-				<view>{{title}}</view>
-				<view class="tui-iconfont tui-font-close" hover-class="tui-opacity" :hover-stay-time="150" @tap="hide">
-				</view>
+	<view>
+		<view :class="{ 'tui-bottom-popup': isFixed, 'tui-popup-show': isShow && isFixed }">
+			<view class="tui-calendar-header" :class="{ 'tui-calendar-radius': radius }" @touchmove.stop.prevent="stop" v-if="isFixed">
+				<view>日期选择</view>
+				<view class="tui-iconfont tui-font-close" hover-class="tui-opacity" :hover-stay-time="150" @tap="hide"></view>
 			</view>
 
 			<view class="tui-date-box">
-				<view class="tui-iconfont tui-font-arrowleft" :style="{ color: yearArrowColor }"
-					hover-class="tui-opacity" :hover-stay-time="150" v-if="arrowType == 1" @tap="changeYear(0)"></view>
-				<view class="tui-iconfont tui-font-arrowleft" :style="{ color: monthArrowColor }"
-					hover-class="tui-opacity" :hover-stay-time="150" @tap="changeMonth(0)"></view>
+				<view class="tui-iconfont tui-font-arrowleft" :style="{ color: yearArrowColor }" hover-class="tui-opacity"
+				 :hover-stay-time="150" v-if="arrowType == 1" @tap="changeYear(0)"></view>
+				<view class="tui-iconfont tui-font-arrowleft" :style="{ color: monthArrowColor }" hover-class="tui-opacity"
+				 :hover-stay-time="150" @tap="changeMonth(0)"></view>
 				<view class="tui-date_time">{{ showTitle }}</view>
-				<view class="tui-iconfont tui-font-arrowright" :style="{ color: monthArrowColor }"
-					hover-class="tui-opacity" :hover-stay-time="150" @tap="changeMonth(1)"></view>
-				<view class="tui-iconfont tui-font-arrowright" :style="{ color: yearArrowColor }"
-					hover-class="tui-opacity" :hover-stay-time="150" v-if="arrowType == 1" @tap="changeYear(1)"></view>
+				<view class="tui-iconfont tui-font-arrowright" :style="{ color: monthArrowColor }" hover-class="tui-opacity"
+				 :hover-stay-time="150" @tap="changeMonth(1)"></view>
+				<view class="tui-iconfont tui-font-arrowright" :style="{ color: yearArrowColor }" hover-class="tui-opacity"
+				 :hover-stay-time="150" v-if="arrowType == 1" @tap="changeYear(1)"></view>
 			</view>
 			<view class="tui-date-header">
 				<view class="tui-date">日</view>
@@ -27,8 +26,7 @@
 				<view class="tui-date">五</view>
 				<view class="tui-date">六</view>
 			</view>
-			<view class="tui-date-content" :class="{ 'tui-flex-start': isFixed && fixedHeight }"
-				:style="{ height: isFixed && fixedHeight ? dateHeight * 6 + 'px' : 'auto' }">
+			<view class="tui-date-content" :class="{ 'tui-flex-start': isFixed && fixedHeight }" :style="{ height: isFixed && fixedHeight ? dateHeight * 6 + 'px' : 'auto' }">
 				<block v-for="(item, index) in weekdayArr" :key="index">
 					<view class="tui-date"></view>
 				</block>
@@ -37,101 +35,43 @@
 						'tui-opacity': openDisAbled(year, month, index + 1),
 						'tui-start-date': (type == 2 && startDate == `${year}-${month}-${index + 1}`) || type == 1,
 						'tui-end-date': (type == 2 && endDate == `${year}-${month}-${index + 1}`) || type == 1
-					}" :style="{ backgroundColor: isFixed ? getColor(index, 1) : 'transparent', height: isFixed && fixedHeight ? dateHeight + 'px' : 'auto' }"
-					v-for="(item, index) in daysArr" :key="index" @tap="dateClick(index)">
-					<view class="tui-date-text"
-						:style="{ color: isFixed ? getColor(index, 2) : getStatusData(3, index), backgroundColor: getStatusData(2, index) }">
+					}"
+				 :style="{ backgroundColor: isFixed ? getColor(index, 1) : 'transparent', height: isFixed && fixedHeight ? dateHeight + 'px' : 'auto' }"
+				 v-for="(item, index) in daysArr" :key="index" @tap="dateClick(index)">
+					<view class="tui-date-text" :style="{ color: isFixed ? getColor(index, 2) : getStatusData(3, index), backgroundColor: getStatusData(2, index) }">
 						<view v-if="isFixed || !getStatusData(4, index)">{{ index + 1 }}</view>
-						<view v-if="!getStatusData(4, index)" class="tui-custom-desc"
-							:class="{ 'tui-lunar-unshow': !lunar && isFixed }">
-							{{ getDescText(index, startDate, endDate) }}
-						</view>
+						<view v-if="!getStatusData(4, index)" class="tui-custom-desc" :class="{'tui-lunar-unshow':!lunar && isFixed}">{{ getDescText(index,startDate,endDate)}}</view>
 						<text class="tui-iconfont tui-font-check" v-if="getStatusData(4, index)"></text>
 					</view>
-					<view class="tui-date-desc" :style="{ color: activeColor }"
-						v-if="!lunar && type == 2 && startDate == `${year}-${month}-${index + 1}` && startDate != endDate">
+					<view class="tui-date-desc" :style="{ color: activeColor }" v-if="!lunar && type == 2 && startDate == `${year}-${month}-${index + 1}` && startDate != endDate">
 						{{ startText }}
 					</view>
-					<view class="tui-date-desc" :style="{ color: activeColor }"
-						v-if="!lunar && type == 2 && endDate == `${year}-${month}-${index + 1}`">{{ endText }}</view>
+					<view class="tui-date-desc" :style="{ color: activeColor }" v-if="!lunar && type == 2 && endDate == `${year}-${month}-${index + 1}`">{{ endText }}</view>
 				</view>
 				<view class="tui-bg-month">{{ month }}</view>
 			</view>
 
-			<view class="tui-calendar-op">
+			<view class="tui-calendar-op" v-if="isFixed" @touchmove.stop.prevent="stop">
 				<view class="tui-calendar-result">
 					<text>{{ type == 1 ? activeDate : startDate }}</text>
 					<text v-if="endDate">至{{ endDate }}</text>
 				</view>
 				<view class="tui-calendar-btn_box">
-					<tui-button :type="btnType" height="72rpx" shape="circle" :size="28" :disabled="disabled"
-						@click="btnFix(false)">确定
-					</tui-button>
+					<tui-button :type="btnType" height="72rpx" shape="circle" :size="28" @click="btnFix(false)">确定</tui-button>
 				</view>
 			</view>
 		</view>
 
-		<view class="tui-popup-mask" :class="[isShow ? 'tui-mask-show' : '']" @tap="hide"></view>
-	</view>
-	<view v-else>
-		<view class="tui-date-box">
-			<view class="tui-iconfont tui-font-arrowleft" :style="{ color: yearArrowColor }" hover-class="tui-opacity"
-				:hover-stay-time="150" v-if="arrowType == 1" @tap="changeYear(0)"></view>
-			<view class="tui-iconfont tui-font-arrowleft" :style="{ color: monthArrowColor }" hover-class="tui-opacity"
-				:hover-stay-time="150" @tap="changeMonth(0)"></view>
-			<view class="tui-date_time">{{ showTitle }}</view>
-			<view class="tui-iconfont tui-font-arrowright" :style="{ color: monthArrowColor }" hover-class="tui-opacity"
-				:hover-stay-time="150" @tap="changeMonth(1)"></view>
-			<view class="tui-iconfont tui-font-arrowright" :style="{ color: yearArrowColor }" hover-class="tui-opacity"
-				:hover-stay-time="150" v-if="arrowType == 1" @tap="changeYear(1)"></view>
-		</view>
-		<view class="tui-date-header">
-			<view class="tui-date">日</view>
-			<view class="tui-date">一</view>
-			<view class="tui-date">二</view>
-			<view class="tui-date">三</view>
-			<view class="tui-date">四</view>
-			<view class="tui-date">五</view>
-			<view class="tui-date">六</view>
-		</view>
-		<view class="tui-date-content" :style="{ height: isFixed && fixedHeight ? dateHeight * 6 + 'px' : 'auto' }">
-			<block v-for="(item, index) in weekdayArr" :key="index">
-				<view class="tui-date"></view>
-			</block>
-			<view class="tui-date" :class="{
-					'tui-date-pd_0': isFixed && fixedHeight,
-					'tui-opacity': openDisAbled(year, month, index + 1),
-					'tui-start-date': (type == 2 && startDate == `${year}-${month}-${index + 1}`) || type == 1,
-					'tui-end-date': (type == 2 && endDate == `${year}-${month}-${index + 1}`) || type == 1
-				}" :style="{ backgroundColor: isFixed ? getColor(index, 1) : 'transparent', height: isFixed && fixedHeight ? dateHeight + 'px' : 'auto' }"
-				v-for="(item, index) in daysArr" :key="index" @tap="dateClick(index)">
-				<view class="tui-date-text"
-					:style="{ color: isFixed ? getColor(index, 2) : getStatusData(3, index), backgroundColor: getStatusData(2, index) }">
-					<view v-if="isFixed || !getStatusData(4, index)">{{ index + 1 }}</view>
-					<view v-if="!getStatusData(4, index)" class="tui-custom-desc"
-						:class="{ 'tui-lunar-unshow': !lunar && isFixed }">
-						{{ getDescText(index, startDate, endDate) }}
-					</view>
-					<text class="tui-iconfont tui-font-check" v-if="getStatusData(4, index)"></text>
-				</view>
-				<view class="tui-date-desc" :style="{ color: activeColor }"
-					v-if="!lunar && type == 2 && startDate == `${year}-${month}-${index + 1}` && startDate != endDate">
-					{{ startText }}
-				</view>
-				<view class="tui-date-desc" :style="{ color: activeColor }"
-					v-if="!lunar && type == 2 && endDate == `${year}-${month}-${index + 1}`">{{ endText }}</view>
-			</view>
-			<view class="tui-bg-month">{{ month }}</view>
-		</view>
+		<view class="tui-popup-mask" :class="[isShow ? 'tui-mask-show' : '']" @touchmove.stop.prevent="stop" v-if="isFixed"
+		 @tap="hide"></view>
 	</view>
 </template>
 <script>
 	//easycom组件模式 无需手动引入
 	// import tuiButton from "../tui-button/tui-button"
-	import calendar from './tui-calendar.js';
+	const calendar = require("./tui-calendar.js")
 	export default {
 		name: 'tuiCalendar',
-		emits: ['hide', 'change'],
 		// components:{
 		// 	tuiButton
 		// },
@@ -141,7 +81,7 @@
 				type: [Number, String],
 				default: 1
 			},
-			//1-单个日期选择 2-开始日期+结束日期选择 3-多个日期
+			//1-单个日期选择 2-开始日期+结束日期选择
 			type: {
 				type: Number,
 				default: 1
@@ -170,10 +110,6 @@
 				type: String,
 				default: ''
 			},
-			title:{
-				type:String,
-				default:'日期选择'
-			},
 			//显示圆角
 			radius: {
 				type: Boolean,
@@ -181,16 +117,16 @@
 			},
 			//状态 数据顺序与当月天数一致,index=>day
 			/**
-					 * [{
-						 * text:"", 描述:2字以内
-						 * value:"",状态值 
-						 * bgColor:"",背景色
-						 * color:""  文字颜色,
-						 * check:false //是否显示对勾
-						 * 
-					 }]
+				 * [{
+					 * text:"", 描述:2字以内
+					 * value:"",状态值 
+					 * bgColor:"",背景色
+					 * color:""  文字颜色,
+					 * check:false //是否显示对勾
 					 * 
-					 * **/
+				 }]
+				 * 
+				 * **/
 			status: {
 				type: Array,
 				default () {
@@ -271,16 +207,6 @@
 			lunar: {
 				type: Boolean,
 				default: false
-			},
-			//初始化起始选中日期 格式: 2020-06-06 或 2020/06/06 【type=1 or 2】
-			initStartDate: {
-				type: [String,Array],
-				default: ''
-			},
-			//初始化结束日期 格式: 2020-06-06 或 2020/06/06【type=2】
-			initEndDate: {
-				type: String,
-				default: ''
 			}
 		},
 		data() {
@@ -312,10 +238,7 @@
 		},
 		computed: {
 			dataChange() {
-				return `${this.type}-${this.minDate}-${this.maxDate}-${this.initStartDate}-${this.initEndDate}`;
-			},
-			disabled() {
-				return this.type == 2 && (!this.startDate || !this.endDate)
+				return `${this.type}-${this.minDate}-${this.maxDate}`;
 			}
 		},
 		watch: {
@@ -324,7 +247,7 @@
 			},
 			fixedHeight(val) {
 				if (val) {
-					this.initDateHeight();
+					this.initDateHeight()
 				}
 			}
 		},
@@ -374,26 +297,27 @@
 				return val;
 			},
 			getDescText(index, startDate, endDate) {
-				let text = this.lunar ? this.getLunar(this.year, this.month, index + 1) : '';
+				let text = this.lunar ? this.getLunar(this.year, this.month, index + 1) : "";
 				if (this.isFixed && this.type == 2) {
 					//此判断不能与上面条件一起判断
-					if (this.lunar) {
+					if(this.lunar){
 						let date = `${this.year}-${this.month}-${index + 1}`;
 						if (startDate == date && startDate != endDate) {
-							text = this.startText;
+							text = this.startText
 						} else if (endDate == date) {
-							text = this.endText;
+							text = this.endText
 						}
 					}
 				} else {
 					let status = this.getStatusData(1, index);
-					if (status) text = status;
+					if (status)
+						text = status;
 				}
 				return text;
 			},
 			getLunar(year, month, day) {
 				let obj = calendar.solar2lunar(year, month, day);
-				return obj.IDayCn;
+				return obj.IDayCn
 			},
 			initDateHeight() {
 				if (this.fixedHeight && this.isFixed) {
@@ -414,37 +338,10 @@
 				this.startYear = 0;
 				this.startMonth = 0;
 				this.startDay = 0;
-				if (this.initStartDate) {
-					let start = new Date(this.initStartDate.replace(/\-/g, '/'));
-					if (this.type == 1) {
-						this.year = start.getFullYear();
-						this.month = start.getMonth() + 1;
-						this.day = start.getDate();
-						this.activeDate = `${start.getFullYear()}-${start.getMonth() + 1}-${start.getDate()}`;
-					} else {
-						this.startDate = `${start.getFullYear()}-${start.getMonth() + 1}-${start.getDate()}`;
-						this.startYear = start.getFullYear();
-						this.startMonth = start.getMonth() + 1;
-						this.startDay = start.getDate();
-						this.activeDate = '';
-					}
-
-				}
 				this.endYear = 0;
 				this.endMonth = 0;
 				this.endDay = 0;
 				this.endDate = '';
-				if (this.initEndDate && this.type == 2) {
-					let end = new Date(this.initEndDate.replace(/\-/g, '/'));
-					this.endDate = `${end.getFullYear()}-${end.getMonth() + 1}-${end.getDate()}`;
-					this.endYear = end.getFullYear();
-					this.endMonth = end.getMonth() + 1;
-					this.endDay = end.getDate();
-					this.activeDate = '';
-					this.year = end.getFullYear();
-					this.month = end.getMonth() + 1;
-					this.day = end.getDate();
-				}
 				this.isStart = true;
 				this.changeData();
 			},
@@ -476,7 +373,7 @@
 				return num < 10 ? '0' + num : num + '';
 			},
 			stop() {
-				return false;
+				return !this.isFixed;
 			},
 			//一个月有多少天
 			getMonthDay(year, month) {
@@ -542,8 +439,7 @@
 					if (this.type == 1) {
 						this.activeDate = date;
 					} else {
-						let compare = new Date(date.replace(/\-/g, '/')).getTime() < new Date(this.startDate.replace(
-							/\-/g, '/')).getTime();
+						let compare = new Date(date.replace(/\-/g, '/')).getTime() < new Date(this.startDate.replace(/\-/g, '/')).getTime();
 						if (this.isStart || compare) {
 							this.startDate = date;
 							this.startYear = this.year;
@@ -573,7 +469,6 @@
 			},
 			hide() {
 				this.isShow = false;
-				this.$emit('hide', {})
 			},
 			getWeekText(date) {
 				date = new Date(`${date.replace(/\-/g, '/')} 00:00:00`);
@@ -598,7 +493,7 @@
 						//今天
 						isToday = true;
 					}
-					let lunar = calendar.solar2lunar(year, month, day);
+					let lunar = calendar.solar2lunar(year, month, day)
 					this.$emit('change', {
 						year: year,
 						month: month,

+ 0 - 1
components/thorui/tui-card/tui-card.vue

@@ -23,7 +23,6 @@
 <script>
 	export default {
 		name: "tuiCard",
-		emits: ['click','longclick'],
 		props: {
 			//是否铺满
 			full: {

+ 0 - 567
components/thorui/tui-cascade-selection/tui-cascade-selection.vue

@@ -1,567 +0,0 @@
-<template>
-	<view class="tui-cascade-selection">
-		<scroll-view scroll-x scroll-with-animation :scroll-into-view="scrollViewId"
-			:style="{ backgroundColor: headerBgColor }" class="tui-bottom-line"
-			:class="{ 'tui-btm-none': !headerLine }">
-			<view class="tui-selection-header" :style="{ height: tabsHeight, backgroundColor: backgroundColor }">
-				<view class="tui-header-item" :class="{ 'tui-font-bold': idx === currentTab && bold }"
-					:style="{ color: idx === currentTab ? activeColor : color, fontSize: size + 'rpx' }"
-					:id="`id_${idx}`" @tap.stop="swichNav" :data-current="idx" v-for="(item, idx) in selectedArr"
-					:key="idx">
-					{{ item.text }}
-					<view class="tui-active-line" :style="{ backgroundColor: lineColor }"
-						v-if="idx === currentTab && showLine"></view>
-				</view>
-			</view>
-		</scroll-view>
-		<swiper class="tui-selection-list" :current="currentTab" duration="300" @change="switchTab"
-			:style="{ height: height, backgroundColor: backgroundColor }">
-			<swiper-item v-for="(item, index) in selectedArr" :key="index">
-				<scroll-view scroll-y :scroll-into-view="item.scrollViewId" class="tui-selection-item"
-					:style="{ height: height }">
-					<view class="tui-first-item" :style="{ height: firstItemTop }"></view>
-					<view class="tui-selection-cell" :style="{ padding: padding, backgroundColor: backgroundColor }"
-						:id="`id_${subIndex}`" v-for="(subItem, subIndex) in item.list" :key="subIndex"
-						@tap="change(index, subIndex, subItem)">
-						<icon type="success_no_circle" v-if="item.index === subIndex" :color="checkMarkColor"
-							:size="checkMarkSize" class="tui-icon-success"></icon>
-						<image :src="subItem.src" v-if="subItem.src" class="tui-cell-img"
-							:style="{ width: imgWidth, height: imgHeight, borderRadius: radius }"></image>
-						<view class="tui-cell-title"
-							:class="{ 'tui-font-bold': item.index === subIndex && textBold, 'tui-flex-shrink': nowrap }"
-							:style="{ color: item.index === subIndex ? textActiveColor : textColor, fontSize: textSize + 'rpx' }">
-							{{ subItem.text }}
-						</view>
-						<view class="tui-cell-sub_title" :style="{ color: subTextColor, fontSize: subTextSize + 'rpx' }"
-							v-if="subItem.subText">{{ subItem.subText }}</view>
-					</view>
-				</scroll-view>
-			</swiper-item>
-		</swiper>
-	</view>
-</template>
-
-<script>
-	export default {
-		name: 'tuiCascadeSelection',
-		emits: ['change', 'complete'],
-		props: {
-			/**
-				 * 如果下一级是请求返回,则为第一级数据,否则所有数据
-				 * 数据格式
-				  [{
-					  src: "",
-					  text: "",
-					  subText: "",
-					  value: 0,
-					  children:[{
-						  text: "",
-						  subText: "",
-						  value: 0,
-						  children:[]
-				   }]
-				  }]
-				 * */
-			itemList: {
-				type: Array,
-				default: () => {
-					return [];
-				}
-			},
-			/*
-			   初始化默认选中数据
-			   [{
-				text: "",//选中text
-				subText: '',//选中subText
-				value: '',//选中value
-				src: '', //选中src,没有则传空或不传
-				index: 0, //选中数据在当前layer索引
-				list: [{src: "", text: "", subText: "", value: 101}] //当前layer下所有数据集合
-			  }];
-			    
-			   */
-			defaultItemList: {
-				type: Array,
-				value: []
-			},
-			defaultKey: {
-				type: String,
-				default: 'text'
-			},
-			//是否显示header底部细线
-			headerLine: {
-				type: Boolean,
-				default: true
-			},
-			//header背景颜色
-			headerBgColor: {
-				type: String,
-				default: '#FFFFFF'
-			},
-			//顶部标签栏高度
-			tabsHeight: {
-				type: String,
-				default: '88rpx'
-			},
-			//默认显示文字
-			text: {
-				type: String,
-				default: '请选择'
-			},
-			//tabs 文字大小
-			size: {
-				type: Number,
-				default: 28
-			},
-			//tabs 文字颜色
-			color: {
-				type: String,
-				default: '#555'
-			},
-			//选中颜色
-			activeColor: {
-				type: String,
-				default: '#5677fc'
-			},
-			//选中后文字加粗
-			bold: {
-				type: Boolean,
-				default: true
-			},
-			//选中后是否显示底部线条
-			showLine: {
-				type: Boolean,
-				default: true
-			},
-			//线条颜色
-			lineColor: {
-				type: String,
-				default: '#5677fc'
-			},
-			//icon 大小
-			checkMarkSize: {
-				type: Number,
-				default: 15
-			},
-			//icon 颜色
-			checkMarkColor: {
-				type: String,
-				default: '#5677fc'
-			},
-			//item 图片宽度
-			imgWidth: {
-				type: String,
-				default: '40rpx'
-			},
-			//item 图片高度
-			imgHeight: {
-				type: String,
-				default: '40rpx'
-			},
-			//图片圆角
-			radius: {
-				type: String,
-				default: '50%'
-			},
-			//item text颜色
-			textColor: {
-				type: String,
-				default: '#333'
-			},
-			textActiveColor: {
-				type: String,
-				default: '#333'
-			},
-			//选中后字体是否加粗
-			textBold: {
-				type: Boolean,
-				default: true
-			},
-			//item text字体大小
-			textSize: {
-				type: Number,
-				default: 28
-			},
-			//text 是否不换行
-			nowrap: {
-				type: Boolean,
-				default: false
-			},
-			//item subText颜色
-			subTextColor: {
-				type: String,
-				default: '#999'
-			},
-			//item subText字体大小
-			subTextSize: {
-				type: Number,
-				default: 24
-			},
-			// item padding
-			padding: {
-				type: String,
-				default: '20rpx 30rpx'
-			},
-			//占位高度,第一条数据距离顶部距离
-			firstItemTop: {
-				type: String,
-				default: '20rpx'
-			},
-			//swiper 高度
-			height: {
-				type: String,
-				default: '300px'
-			},
-			//item  swiper 内容部分背景颜色
-			backgroundColor: {
-				type: String,
-				default: '#FFFFFF'
-			},
-			//子集数据是否请求返回(默认false,一次性返回所有数据)
-			request: {
-				type: Boolean,
-				default: false
-			},
-			//子级数据(当有改变时,默认当前选中项新增子级数据,request=true时生效)
-			receiveData: {
-				type: Array,
-				default: () => {
-					return [];
-				}
-			},
-			//改变值则重置数据
-			reset: {
-				type: [Number, String],
-				default: 0
-			}
-		},
-		watch: {
-			itemList(val) {
-				this.initData(val, -1);
-			},
-			receiveData(val) {
-				this.subLevelData(val, this.currentTab);
-			},
-			reset() {
-				this.initData(this.itemList, -1);
-			},
-			defaultItemList(val) {
-				this.setDefaultData(val)
-			}
-		},
-		created() {
-			this.setDefaultData(this.defaultItemList)
-		},
-		data() {
-			return {
-				currentTab: 0,
-				//tab栏scrollview滚动的位置
-				scrollViewId: 'id__1',
-				selectedArr: []
-			};
-		},
-		methods: {
-			setDefaultData(val) {
-				let defaultItemList = val || [];
-				if (defaultItemList.length > 0) {
-					if ((typeof defaultItemList[0] === 'string' || typeof defaultItemList[0] === 'number') && !this
-						.request) {
-						let subi = -1
-						let selectedArr = []
-						for (let j = 0, len = defaultItemList.length; j < len; j++) {
-							let item = defaultItemList[j]
-							let list = []
-							let obj = {}
-							if (j === 0) {
-								list = this.getItemList(-1)
-							} else {
-								list = this.getItemList(j - 1, subi,selectedArr)
-							}
-							subi = this.getDefaultIndex(list, item)
-							if (subi !== -1) {
-								obj = list[subi]
-								selectedArr.push({
-									text: obj.text || this.text,
-									value: obj.value || '',
-									src: obj.src || '',
-									subText: obj.subText || '',
-									index: subi,
-									scrollViewId: `id_${subi}`,
-									list: list
-								})
-							}
-
-							if (subi === -1) break;
-						}
-						this.selectedArr = selectedArr;
-						this.currentTab = selectedArr.length - 1;
-						this.$nextTick(() => {
-							this.checkCor();
-						});
-					} else {
-						defaultItemList.map(item => {
-							item.scrollViewId = `id_${item.index}`;
-						});
-						this.selectedArr = defaultItemList;
-						this.currentTab = defaultItemList.length - 1;
-						this.$nextTick(() => {
-							this.checkCor();
-						});
-					}
-
-				} else {
-					this.initData(this.itemList, -1);
-				}
-			},
-			getDefaultIndex(arr, val) {
-				if (!arr || arr.length === 0 || val === undefined) return -1;
-				let index = -1;
-				let key = this.defaultKey || 'text'
-				for (let i = 0, len = arr.length; i < len; i++) {
-					if (arr[i][key] == val) {
-						index = i;
-						break;
-					}
-				}
-				return index;
-			},
-			initData(data, layer) {
-				if (!data || data.length === 0) return;
-				if (this.request) {
-					//第一级数据
-					this.subLevelData(data, layer);
-				} else {
-					let selectedValue = this.selectedValue || {};
-					if (selectedValue.type) {
-						this.setDefaultData(selectedValue);
-					} else {
-						this.subLevelData(this.getItemList(layer, -1), layer);
-					}
-				}
-			},
-			removeChildren(data) {
-				let list = data.map(item => {
-					delete item['children'];
-					return item;
-				});
-				return list;
-			},
-			getItemList(layer, index, selectedArr) {
-				let list = [];
-				let arr = JSON.parse(JSON.stringify(this.itemList));
-				selectedArr = selectedArr || this.selectedArr
-				if (layer == -1) {
-					list = this.removeChildren(arr);
-				} else {
-					let value = selectedArr[0].index;
-					value = value == -1 ? index : value;
-					list = arr[value].children || [];
-					if (layer > 0) {
-						for (let i = 1; i < layer + 1; i++) {
-							let val = layer === i ? index : selectedArr[i].index;
-							list = list[val].children || [];
-							if (list.length === 0) break;
-						}
-					}
-					list = this.removeChildren(list);
-				}
-				return list;
-			},
-			//滚动切换
-			switchTab: function(e) {
-				this.currentTab = e.detail.current;
-				this.checkCor();
-			},
-			//点击标题切换当
-			swichNav: function(e) {
-				let cur = e.currentTarget.dataset.current;
-				if (this.currentTab != cur) {
-					this.currentTab = cur;
-				}
-			},
-			checkCor: function() {
-				let item = this.selectedArr[this.currentTab];
-				item.scrollViewId = 'id__1';
-				this.$nextTick(() => {
-					setTimeout(() => {
-						let val = item.index < 2 ? 0 : Number(item.index - 2);
-						item.scrollViewId = `id_${val}`;
-					}, 2);
-				});
-
-				if (this.currentTab > 1) {
-					this.scrollViewId = `id_${this.currentTab - 1}`;
-				} else {
-					this.scrollViewId = `id_0`;
-				}
-			},
-			change(index, subIndex, subItem) {
-				let item = this.selectedArr[index];
-				if (item.index == subIndex) return;
-				item.index = subIndex;
-				item.text = subItem.text;
-				item.value = subItem.value;
-				item.subText = subItem.subText || '';
-				item.src = subItem.src || '';
-				this.$emit('change', {
-					layer: index,
-					subIndex: subIndex, //layer=> Array index
-					...subItem
-				});
-
-				if (!this.request) {
-					let data = this.getItemList(index, subIndex);
-					this.subLevelData(data, index);
-				}
-			},
-			//新增子级数据时处理
-			subLevelData(data, layer) {
-				if (!data || data.length === 0) {
-					if (layer == -1) return;
-					//完成选择
-					let arr = this.selectedArr;
-					if (layer < arr.length - 1) {
-						let newArr = arr.slice(0, layer + 1);
-						this.selectedArr = newArr;
-					}
-					let result = JSON.parse(JSON.stringify(this.selectedArr));
-					let lastItem = result[result.length - 1] || {};
-					let text = '';
-					result.map(item => {
-						text += item.text;
-						delete item['list'];
-						//delete item['index'];
-						delete item['scrollViewId'];
-						return item;
-					});
-					this.$emit('complete', {
-						result: result,
-						value: lastItem.value,
-						text: text,
-						subText: lastItem.subText,
-						src: lastItem.src
-					});
-				} else {
-					//重置数据( >layer层级)
-					let item = [{
-						text: this.text,
-						subText: '',
-						value: '',
-						src: '',
-						index: -1,
-						scrollViewId: 'id__1',
-						list: data
-					}];
-					if (layer == -1) {
-						this.selectedArr = item;
-					} else {
-						let retainArr = this.selectedArr.slice(0, layer + 1);
-						this.selectedArr = retainArr.concat(item);
-					}
-					this.$nextTick(() => {
-						this.currentTab = this.selectedArr.length - 1;
-					});
-				}
-			}
-		}
-	};
-</script>
-
-<style scoped>
-	.tui-cascade-selection {
-		width: 100%;
-		box-sizing: border-box;
-	}
-
-	.tui-selection-header {
-		width: 100%;
-		display: flex;
-		align-items: center;
-		position: relative;
-		box-sizing: border-box;
-	}
-
-	.tui-bottom-line {
-		position: relative;
-	}
-
-	.tui-bottom-line::after {
-		width: 100%;
-		content: '';
-		position: absolute;
-		border-bottom: 1rpx solid #eaeef1;
-		-webkit-transform: scaleY(0.5) translateZ(0);
-		transform: scaleY(0.5) translateZ(0);
-		transform-origin: 0 100%;
-		bottom: 0;
-		right: 0;
-		left: 0;
-	}
-
-	.tui-btm-none::after {
-		border-bottom: 0 !important;
-	}
-
-	.tui-header-item {
-		max-width: 240rpx;
-		padding: 15rpx 30rpx;
-		box-sizing: border-box;
-		flex-shrink: 0;
-		overflow: hidden;
-		white-space: nowrap;
-		text-overflow: ellipsis;
-		position: relative;
-	}
-
-	.tui-font-bold {
-		font-weight: bold;
-	}
-
-	.tui-active-line {
-		width: 60rpx;
-		height: 6rpx;
-		border-radius: 4rpx;
-		position: absolute;
-		bottom: 0;
-		right: 0;
-		left: 50%;
-		transform: translateX(-50%);
-	}
-
-	.tui-selection-cell {
-		width: 100%;
-		box-sizing: border-box;
-		display: flex;
-		align-items: center;
-	}
-
-	.tui-icon-success {
-		margin-right: 12rpx;
-	}
-
-	.tui-cell-img {
-		margin-right: 12rpx;
-		flex-shrink: 0;
-	}
-
-	.tui-cell-title {
-		word-break: break-all;
-	}
-
-	.tui-flex-shrink {
-		flex-shrink: 0;
-	}
-
-	.tui-font-bold {
-		font-weight: bold;
-	}
-
-	.tui-cell-sub_title {
-		margin-left: 20rpx;
-		word-break: break-all;
-	}
-
-	.tui-first-item {
-		width: 100%;
-	}
-</style>

+ 0 - 265
components/thorui/tui-circular-progress/tui-circular-progress.vue

@@ -1,265 +0,0 @@
-<template>
-	<view class="tui-circular-container" :style="{ width: diam + 'px', height: (height || diam) + 'px' }">
-		<canvas
-			class="tui-circular-default"
-			:canvas-id="defaultCanvasId"
-			:id="defaultCanvasId"
-			:style="{ width: diam + 'px', height: (height || diam) + 'px' }"
-			v-if="defaultShow"
-		></canvas>
-		<canvas class="tui-circular-progress" :canvas-id="progressCanvasId" :id="progressCanvasId" :style="{ width: diam + 'px', height: (height || diam) + 'px' }"></canvas>
-		<slot />
-	</view>
-</template>
-
-<script>
-export default {
-	name: 'tuiCircularProgress',
-	emits: ['change','end'],
-	props: {
-		/*
-			  传值需使用rpx进行转换保证各终端兼容
-			  px = rpx / 750 * wx.getSystemInfoSync().windowWidth
-			  圆形进度条(画布)宽度,直径 [px]
-			*/
-		diam: {
-			type: Number,
-			default: 60
-		},
-		//圆形进度条(画布)高度,默认取diam值[当画半弧时传值,height有值时则取height]
-		height: {
-			type: Number,
-			default: 0
-		},
-		//进度条线条宽度[px]
-		lineWidth: {
-			type: Number,
-			default: 4
-		},
-		/*
-			 线条的端点样式
-			 butt:向线条的每个末端添加平直的边缘
-			 round	向线条的每个末端添加圆形线帽
-			 square	向线条的每个末端添加正方形线帽
-			*/
-		lineCap: {
-			type: String,
-			default: 'round'
-		},
-		//圆环进度字体大小 [px]
-		fontSize: {
-			type: Number,
-			default: 12
-		},
-		//圆环进度字体颜色
-		fontColor: {
-			type: String,
-			default: '#5677fc'
-		},
-		//是否显示进度文字
-		fontShow: {
-			type: Boolean,
-			default: true
-		},
-		/*
-			 自定义显示文字[默认为空,显示百分比,fontShow=true时生效]
-			 可以使用 slot自定义显示内容
-			*/
-		percentText: {
-			type: String,
-			default: ''
-		},
-		//是否显示默认(背景)进度条
-		defaultShow: {
-			type: Boolean,
-			default: true
-		},
-		//默认进度条颜色
-		defaultColor: {
-			type: String,
-			default: '#CCC'
-		},
-		//进度条颜色
-		progressColor: {
-			type: String,
-			default: '#5677fc'
-		},
-		//进度条渐变颜色[结合progressColor使用,默认为空]
-		gradualColor: {
-			type: String,
-			default: ''
-		},
-		//起始弧度,单位弧度
-		sAngle: {
-			type: Number,
-			default: -Math.PI / 2
-		},
-		//指定弧度的方向是逆时针还是顺时针。默认是false,即顺时针
-		counterclockwise: {
-			type: Boolean,
-			default: false
-		},
-		//进度百分比 [10% 传值 10]
-		percentage: {
-			type: Number,
-			default: 0
-		},
-		//进度百分比缩放倍数[使用半弧为100%时,则可传2]
-		multiple: {
-			type: Number,
-			default: 1
-		},
-		//动画执行时间[单位毫秒,低于50无动画]
-		duration: {
-			type: Number,
-			default: 800
-		},
-		//backwards: 动画从头播;forwards:动画从上次结束点接着播
-		activeMode: {
-			type: String,
-			default: 'backwards'
-		}
-	},
-	watch: {
-		percentage(val) {
-			this.initDraw();
-		}
-	},
-	data() {
-		return {
-			// #ifdef MP-WEIXIN
-			progressCanvasId: 'progressCanvasId',
-			defaultCanvasId: 'defaultCanvasId',
-			// #endif
-			// #ifndef MP-WEIXIN
-			progressCanvasId: this.getCanvasId(),
-			defaultCanvasId: this.getCanvasId(),
-			// #endif
-			progressContext: null,
-			linearGradient: null,
-			//起始百分比
-			startPercentage: 0
-			// dpi
-			//pixelRatio: uni.getSystemInfoSync().pixelRatio
-		};
-	},
-	mounted() {
-		this.initDraw(true);
-	},
-	methods: {
-		//初始化绘制
-		initDraw(init) {
-			let start = this.activeMode === 'backwards' ? 0 : this.startPercentage;
-			start = start > this.percentage ? 0 : start;
-			if (this.defaultShow && init) {
-				this.drawDefaultCircular();
-			}
-			this.drawProgressCircular(start);
-		},
-		//默认(背景)圆环
-		drawDefaultCircular() {
-			let ctx = uni.createCanvasContext(this.defaultCanvasId, this);
-			ctx.setLineWidth(this.lineWidth);
-			ctx.setStrokeStyle(this.defaultColor);
-			//终止弧度
-			let eAngle = Math.PI * (this.height ? 1 : 2) + this.sAngle;
-			this.drawArc(ctx, eAngle);
-		},
-		//进度圆环
-		drawProgressCircular(startPercentage) {
-			let ctx = this.progressContext;
-			let gradient = this.linearGradient;
-			if (!ctx) {
-				ctx = uni.createCanvasContext(this.progressCanvasId, this);
-				//创建一个线性的渐变颜色 CanvasGradient对象
-				gradient = ctx.createLinearGradient(0, 0, this.diam, 0);
-				gradient.addColorStop('0', this.progressColor);
-				if (this.gradualColor) {
-					gradient.addColorStop('1', this.gradualColor);
-				}
-				// #ifdef APP-PLUS || MP
-				const res = uni.getSystemInfoSync();
-				if (!this.gradualColor && res.platform.toLocaleLowerCase() == 'android') {
-					gradient.addColorStop('1', this.progressColor);
-				}
-				// #endif
-				this.progressContext = ctx;
-				this.linearGradient = gradient;
-			}
-			ctx.setLineWidth(this.lineWidth);
-			ctx.setStrokeStyle(gradient);
-			let time = this.percentage == 0 || this.duration < 50 ? 0 : this.duration / this.percentage;
-			if (this.percentage > 0) {
-				startPercentage = this.duration < 50 ? this.percentage - 1 : startPercentage;
-				startPercentage++;
-			}
-			if (this.fontShow) {
-				ctx.setFontSize(this.fontSize);
-				ctx.setFillStyle(this.fontColor);
-				ctx.setTextAlign('center');
-				ctx.setTextBaseline('middle');
-				let percentage = this.percentText;
-				if (!percentage) {
-					percentage = this.counterclockwise ? 100 - startPercentage * this.multiple : startPercentage * this.multiple;
-					percentage = `${percentage}%`;
-				}
-				let radius = this.diam / 2;
-				ctx.fillText(percentage, radius, radius);
-			}
-			if (this.percentage == 0 || (this.counterclockwise && startPercentage == 100)) {
-				ctx.draw();		
-			}else{
-				let eAngle = ((2 * Math.PI) / 100) * startPercentage + this.sAngle;
-				this.drawArc(ctx, eAngle);
-			}
-			setTimeout(() => {
-				this.startPercentage = startPercentage;
-				if (startPercentage == this.percentage) {
-					this.$emit('end', {
-						canvasId: this.progressCanvasId,
-						percentage: startPercentage
-					});
-				} else {
-					this.drawProgressCircular(startPercentage);
-				}
-				this.$emit('change', {
-					percentage: startPercentage
-				});
-			}, time);
-			// #ifdef H5
-			// requestAnimationFrame(()=>{})
-			// #endif
-		},
-		//创建弧线
-		drawArc(ctx, eAngle) {
-			ctx.setLineCap(this.lineCap);
-			ctx.beginPath();
-			let radius = this.diam / 2; //x=y
-			ctx.arc(radius, radius, radius - this.lineWidth, this.sAngle, eAngle, this.counterclockwise);
-			ctx.stroke();
-			ctx.draw();
-		},
-		//生成canvasId
-		getCanvasId() {
-			let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
-				return (c === 'x' ? (Math.random() * 16) | 0 : 'r&0x3' | '0x8').toString(16);
-			});
-			return uuid;
-		}
-	}
-};
-</script>
-
-<style scoped>
-.tui-circular-container,
-.tui-circular-default {
-	position: relative;
-}
-
-.tui-circular-progress {
-	position: absolute;
-	left: 0;
-	top: 0;
-	z-index: 10;
-}
-</style>

+ 0 - 1
components/thorui/tui-collapse/tui-collapse.vue

@@ -17,7 +17,6 @@
 <script>
 	export default {
 		name: "tuiCollapse",
-		emits: ['click'],
 		props: {
 			//collapse背景颜色
 			bgColor: {

+ 8 - 94
components/thorui/tui-countdown/tui-countdown.vue

@@ -60,43 +60,22 @@
 		>
 			{{ unitEn ? 's' : '秒' }}
 		</view>
-
-		<view class="tui-countdown-colon" :style="{ lineHeight: colonSize + 'rpx', fontSize: colonSize + 'rpx', color: colonColor }" v-if="seconds && isMs && isColon">.</view>
-		<view
-			class="tui-countdown__ms"
-			:style="{
-				background: backgroundColor,
-				borderColor: borderColor,
-				fontSize: msSize + 'rpx',
-				color: msColor,
-				height: height + 'rpx',
-				width: msWidth > 0 ? msWidth + 'rpx' : 'auto'
-			}"
-			v-if="seconds && isMs"
-		>
-			<view :class="{ 'tui-ms__list': ani }">
-				<view class="tui-ms__item" :style="{ height: height + 'rpx' }" v-for="(item, index) in ms" :key="index">
-					<view :class="[scale ? 'tui-countdown-scale' : '']">{{item}}</view>
-				</view>
-			</view>
-		</view>
 	</view>
 </template>
 
 <script>
 export default {
 	name: 'tuiCountdown',
-	emits: ['end','time'],
 	props: {
 		//数字框宽度
 		width: {
 			type: Number,
-			default: 32
+			default: 25
 		},
 		//数字框高度
 		height: {
 			type: Number,
-			default: 32
+			default: 25
 		},
 		//数字框border颜色
 		borderColor: {
@@ -167,33 +146,11 @@ export default {
 		isColon: {
 			type: Boolean,
 			default: true
-		},
-		//是否返回剩余时间
-		returnTime: {
-			type: Boolean,
-			default: false
-		},
-		//是否显示毫秒
-		isMs: {
-			type: Boolean,
-			default: false
-		},
-		msWidth: {
-			type: Number,
-			default: 32
-		},
-		msSize: {
-			type: Number,
-			default: 24
-		},
-		msColor: {
-			type: String,
-			default: '#333'
 		}
 	},
 	watch: {
 		time(val) {
-			this.clearTimer();
+			clearInterval(this.countdown);
 			this.doLoop();
 		}
 	},
@@ -203,42 +160,27 @@ export default {
 			d: '0',
 			h: '00',
 			i: '00',
-			s: '00',
-			//此处若从9到1,结束需要特殊处理
-			ms: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
-			ani: false
+			s: '00'
 		};
 	},
 	created() {
-		this.clearTimer();
 		this.doLoop();
 	},
-	// #ifndef VUE3
 	beforeDestroy() {
-		this.clearTimer();
+		clearInterval(this.countdown);
+		this.countdown = null;
 	},
-	// #endif
-	// #ifdef VUE3
-	beforeUnmount(){
-		this.clearTimer();
-	},
-	// #endif
 	methods: {
 		getWidth: function(num, width) {
 			return num > 99 ? (width / 2) * num.toString().length : width;
 		},
-		clearTimer() {
+		endOfTime() {
 			clearInterval(this.countdown);
 			this.countdown = null;
-		},
-		endOfTime() {
-			this.ani = false;
-			this.clearTimer();
 			this.$emit('end', {});
 		},
 		doLoop: function() {
 			let seconds = this.time || 0;
-			this.ani = true;
 			this.countDown(seconds);
 			this.countdown = setInterval(() => {
 				seconds--;
@@ -247,9 +189,6 @@ export default {
 					return;
 				}
 				this.countDown(seconds);
-				if (this.returnTime) {
-					this.$emit('time', { seconds: seconds });
-				}
 			}, 1000);
 		},
 		countDown(seconds) {
@@ -290,6 +229,7 @@ export default {
 	display: flex;
 	align-items: center;
 	justify-content: center;
+	padding: 2rpx;
 	border-radius: 6rpx;
 	white-space: nowrap;
 	transform: translateZ(0);
@@ -314,30 +254,4 @@ export default {
 	transform: scale(0.9);
 	transform-origin: center center;
 }
-.tui-countdown__ms {
-	border: 1rpx solid;
-	overflow: hidden;
-	border-radius: 6rpx;
-}
-
-/*ms使用css3代替js频繁更新操作,性能优化*/
-.tui-ms__list {
-	animation: loop 1s steps(10) infinite;
-}
-
-@keyframes loop {
-	from {
-		transform: translateY(0);
-	}
-
-	to {
-		transform: translateY(-100%);
-	}
-}
-
-.tui-ms__item {
-	display: flex;
-	align-items: center;
-	justify-content: center;
-}
 </style>

+ 123 - 240
components/thorui/tui-datetime/tui-datetime.vue

@@ -1,68 +1,62 @@
 <template>
 	<view class="tui-datetime-picker">
-		<view class="tui-mask" :class="{ 'tui-mask-show': isShow }" @touchmove.stop.prevent="stop" catchtouchmove="stop"
-			@tap="maskClick"></view>
+		<view class="tui-mask" :class="{ 'tui-mask-show': isShow }" @touchmove.stop.prevent="stop" catchtouchmove="stop" @tap="hide"></view>
 		<view class="tui-header" :class="{ 'tui-show': isShow }">
-			<view class="tui-picker-header" :class="{ 'tui-date-radius': radius }"
-				:style="{ backgroundColor: headerBackground }" @touchmove.stop.prevent="stop" catchtouchmove="stop">
-				<view class="tui-btn-picker" :style="{ color: cancelColor }" hover-class="tui-opacity"
-					:hover-stay-time="150" @tap="hide">取消</view>
-				<view class="tui-pickerdate__title" :style="{fontSize:titleSize+'rpx',color:titleColor}">{{title}}
-				</view>
-				<view class="tui-btn-picker" :style="{ color: color }" hover-class="tui-opacity" :hover-stay-time="150"
-					@tap="btnFix">确定</view>
+			<view class="tui-picker-header" :class="{ 'tui-date-radius': radius }" @touchmove.stop.prevent="stop" catchtouchmove="stop">
+				<view class="tui-btn-picker" :style="{ color: cancelColor }" hover-class="tui-opacity" :hover-stay-time="150"
+				 @tap="hide">取消</view>
+				<view class="tui-btn-picker" :style="{ color: color }" hover-class="tui-opacity" :hover-stay-time="150" @tap="btnFix">确定</view>
 			</view>
-			<view class="tui-date-header" :style="{ backgroundColor: unitBackground }" v-if="unitTop">
-				<view class="tui-date-unit" v-if="type < 4 || type == 7 || type==8">年</view>
-				<view class="tui-date-unit" v-if="type < 4 || type == 7 || type==8">月</view>
-				<view class="tui-date-unit" v-if="type == 1 || type == 2 || type == 7 || type==8">日</view>
-				<view class="tui-date-unit" v-if="type == 1 || type == 4 || type == 5 || type == 7 || type==8">时</view>
-				<view class="tui-date-unit" v-if="(type == 1 || type > 3) && type!=8">分</view>
-				<view class="tui-date-unit" v-if="type > 4 && type !=8">秒</view>
+			<view class="tui-date-header" v-if="unitTop">
+				<view class="tui-date-unit" v-if="type < 4 || type == 7">年</view>
+				<view class="tui-date-unit" v-if="type < 4 || type == 7">月</view>
+				<view class="tui-date-unit" v-if="type == 1 || type == 2 || type == 7">日</view>
+				<view class="tui-date-unit" v-if="type == 1 || type == 4 || type == 5 || type == 7">时</view>
+				<view class="tui-date-unit" v-if="type == 1 || type > 3">分</view>
+				<view class="tui-date-unit" v-if="type > 4">秒</view>
 			</view>
-			<view @touchstart.stop="pickerstart" class="tui-date__picker-body"
-				:style="{ backgroundColor: bodyBackground,height:height+'rpx' }">
+			<view class="tui-picker-body">
 				<picker-view :value="value" @change="change" class="tui-picker-view">
-					<picker-view-column v-if="!reset && (type < 4 || type == 7 || type==8)">
-						<view class="tui-date__column-item" :class="{ 'tui-font-size_32': !unitTop && type == 7 }"
-							v-for="(item, index) in years" :key="index">
+					<picker-view-column v-if="!reset && (type < 4 || type == 7)">
+						<view class="tui-column-item" :class="{ 'tui-font-size_32': !unitTop && type == 7 }" v-for="(item, index) in years"
+						 :key="index">
 							{{ item }}
-							<text class="tui-date__unit-text" v-if="!unitTop">年</text>
+							<text class="tui-unit-text" v-if="!unitTop">年</text>
 						</view>
 					</picker-view-column>
-					<picker-view-column v-if="!reset && (type < 4 || type == 7 || type==8)">
-						<view class="tui-date__column-item" :class="{ 'tui-font-size_32': !unitTop && type == 7 }"
-							v-for="(item, index) in months" :key="index">
+					<picker-view-column v-if="!reset && (type < 4 || type == 7)">
+						<view class="tui-column-item" :class="{ 'tui-font-size_32': !unitTop && type == 7 }" v-for="(item, index) in months"
+						 :key="index">
 							{{ formatNum(item) }}
-							<text class="tui-date__unit-text" v-if="!unitTop">月</text>
+							<text class="tui-unit-text" v-if="!unitTop">月</text>
 						</view>
 					</picker-view-column>
-					<picker-view-column v-if="!reset && (type == 1 || type == 2 || type == 7 || type==8)">
-						<view class="tui-date__column-item" :class="{ 'tui-font-size_32': !unitTop && type == 7 }"
-							v-for="(item, index) in days" :key="index">
+					<picker-view-column v-if="!reset && (type == 1 || type == 2 || type == 7)">
+						<view class="tui-column-item" :class="{ 'tui-font-size_32': !unitTop && type == 7 }" v-for="(item, index) in days"
+						 :key="index">
 							{{ formatNum(item) }}
-							<text class="tui-date__unit-text" v-if="!unitTop">日</text>
+							<text class="tui-unit-text" v-if="!unitTop">日</text>
 						</view>
 					</picker-view-column>
-					<picker-view-column v-if="!reset && (type == 1 || type == 4 || type == 5 || type == 7 || type==8)">
-						<view class="tui-date__column-item" :class="{ 'tui-font-size_32': !unitTop && type == 7 }"
-							v-for="(item, index) in hours" :key="index">
+					<picker-view-column v-if="!reset && (type == 1 || type == 4 || type == 5 || type == 7)">
+						<view class="tui-column-item" :class="{ 'tui-font-size_32': !unitTop && type == 7 }" v-for="(item, index) in hours"
+						 :key="index">
 							{{ formatNum(item) }}
-							<text class="tui-date__unit-text" v-if="!unitTop">时</text>
+							<text class="tui-unit-text" v-if="!unitTop">时</text>
 						</view>
 					</picker-view-column>
-					<picker-view-column v-if="!reset && (type == 1 || type > 3)  && type!=8">
-						<view class="tui-date__column-item" :class="{ 'tui-font-size_32': !unitTop && type == 7 }"
-							v-for="(item, index) in minutes" :key="index">
+					<picker-view-column v-if="!reset && (type == 1 || type > 3)">
+						<view class="tui-column-item" :class="{ 'tui-font-size_32': !unitTop && type == 7 }" v-for="(item, index) in minutes"
+						 :key="index">
 							{{ formatNum(item) }}
-							<text class="tui-date__unit-text" v-if="!unitTop">分</text>
+							<text class="tui-unit-text" v-if="!unitTop">分</text>
 						</view>
 					</picker-view-column>
-					<picker-view-column v-if="!reset && type > 4 && type!=8">
-						<view class="tui-date__column-item" :class="{ 'tui-font-size_32': !unitTop && type == 7 }"
-							v-for="(item, index) in seconds" :key="index">
+					<picker-view-column v-if="!reset && type > 4">
+						<view class="tui-column-item" :class="{ 'tui-font-size_32': !unitTop && type == 7 }" v-for="(item, index) in seconds"
+						 :key="index">
 							{{ formatNum(item) }}
-							<text class="tui-date__unit-text" v-if="!unitTop">秒</text>
+							<text class="tui-unit-text" v-if="!unitTop">秒</text>
 						</view>
 					</picker-view-column>
 				</picker-view>
@@ -74,9 +68,8 @@
 <script>
 	export default {
 		name: 'tuiDatetime',
-		emits: ['cancel', 'confirm'],
 		props: {
-			//1-日期+时间(年月日+时分) 2-日期(年月日) 3-日期(年月) 4-时间(时分) 5-时分秒 6-分秒 7-年月日 时分秒 8-年月日+小时
+			//1-日期+时间(年月日+时分) 2-日期(年月日) 3-日期(年月) 4-时间(时分) 5-时分秒 6-分秒 7-年月日 时分秒
 			type: {
 				type: Number,
 				default: 1
@@ -91,21 +84,6 @@
 				type: Number,
 				default: 2050
 			},
-			//显示标题
-			title: {
-				type: String,
-				default: ''
-			},
-			//标题字体大小
-			titleSize: {
-				type: [Number, String],
-				default: 34
-			},
-			//标题字体颜色
-			titleColor: {
-				type: String,
-				default: '#333'
-			},
 			//"取消"字体颜色
 			cancelColor: {
 				type: String,
@@ -130,32 +108,7 @@
 			radius: {
 				type: Boolean,
 				default: false
-			},
-			//头部背景色
-			headerBackground: {
-				type: String,
-				default: '#fff'
-			},
-			//根据实际调整,不建议使用深颜色
-			bodyBackground: {
-				type: String,
-				default: '#fff'
-			},
-			//单位置顶时,单位条背景色
-			unitBackground: {
-				type: String,
-				default: '#fff'
-			},
-			height: {
-				type: [Number, String],
-				default: 520
-			},
-			//点击遮罩 是否可关闭
-			maskClosable: {
-				type: Boolean,
-				default: true
 			}
-
 		},
 		data() {
 			return {
@@ -175,14 +128,11 @@
 				startDate: '',
 				endDate: '',
 				value: [0, 0, 0, 0, 0, 0],
-				reset: false,
-				isEnd: true
+				reset: false
 			};
 		},
 		mounted() {
-			setTimeout(() => {
-				this.initData();
-			}, 20)
+			this.initData();
 		},
 		computed: {
 			yearOrMonth() {
@@ -200,7 +150,7 @@
 				this.reset = true;
 				setTimeout(() => {
 					this.initData();
-				}, 20);
+				}, 10);
 			}
 		},
 		methods: {
@@ -215,17 +165,9 @@
 				let index = arr.indexOf(val);
 				return ~index ? index : 0;
 			},
-			getCharCount(str) {
-				let regex = new RegExp('/', 'g');
-				let result = str.match(regex);
-				return !result ? 0 : result.length;
-			},
 			//日期时间处理
 			initSelectValue() {
 				let fdate = this.setDateTime.replace(/\-/g, '/');
-				if (this.type == 3 && this.getCharCount(fdate) === 1) {
-					fdate += '/01'
-				}
 				fdate = fdate && fdate.indexOf('/') == -1 ? `2020/01/01 ${fdate}` : fdate;
 				let time = null;
 				if (fdate) time = new Date(fdate);
@@ -285,13 +227,6 @@
 						this.setMinutes();
 						this.setSeconds();
 						break;
-					case 8:
-						this.value = [0, 0, 0, 0];
-						this.setYears();
-						this.setMonths();
-						this.setDays();
-						this.setHours();
-						break;
 					default:
 						break;
 				}
@@ -311,7 +246,6 @@
 			setDays() {
 				if (this.type == 3 || this.type == 4) return;
 				let totalDays = new Date(this.year, this.month, 0).getDate();
-				totalDays = !totalDays || totalDays < 1 ? 1 : totalDays
 				this.days = this.generateArray(1, totalDays);
 				setTimeout(() => {
 					this.$set(this.value, 2, this.getIndex(this.days, this.day));
@@ -320,12 +254,7 @@
 			setHours() {
 				this.hours = this.generateArray(0, 23);
 				setTimeout(() => {
-					let index = 0
-					if (this.type == 8) {
-						index = this.value.length - 1
-					} else {
-						index = this.type == 5 || this.type == 7 ? this.value.length - 3 : this.value.length - 2;
-					}
+					let index = this.type == 5 || this.type == 7 ? this.value.length - 3 : this.value.length - 2;
 					this.$set(this.value, index, this.getIndex(this.hours, this.hour));
 				}, 8);
 			},
@@ -349,11 +278,6 @@
 			},
 			hide() {
 				this.isShow = false;
-				this.$emit('cancel', {});
-			},
-			maskClick() {
-				if (!this.maskClosable) return;
-				this.hide()
 			},
 			change(e) {
 				this.value = e.detail.value;
@@ -395,115 +319,84 @@
 						this.minute = this.minutes[this.value[4]];
 						this.second = this.seconds[this.value[5]];
 						break;
-					case 8:
-						this.year = this.years[this.value[0]];
-						this.month = this.months[this.value[1]];
-						this.day = this.days[this.value[2]];
-						this.hour = this.hours[this.value[3]];
-						break;
 					default:
 						break;
 				}
-				this.isEnd = true
-			},
-			selectResult() {
-				let result = {};
-				let year = this.year;
-				let month = this.formatNum(this.month || 0);
-				let day = this.formatNum(this.day || 0);
-				let hour = this.formatNum(this.hour || 0);
-				let minute = this.formatNum(this.minute || 0);
-				let second = this.formatNum(this.second || 0);
-				switch (this.type) {
-					case 1:
-						result = {
-							year: year,
-							month: month,
-							day: day,
-							hour: hour,
-							minute: minute,
-							result: `${year}-${month}-${day} ${hour}:${minute}`
-						};
-						break;
-					case 2:
-						result = {
-							year: year,
-							month: month,
-							day: day,
-							result: `${year}-${month}-${day}`
-						};
-						break;
-					case 3:
-						result = {
-							year: year,
-							month: month,
-							result: `${year}-${month}`
-						};
-						break;
-					case 4:
-						result = {
-							hour: hour,
-							minute: minute,
-							result: `${hour}:${minute}`
-						};
-						break;
-					case 5:
-						result = {
-							hour: hour,
-							minute: minute,
-							second: second,
-							result: `${hour}:${minute}:${second}`
-						};
-						break;
-					case 6:
-						result = {
-							minute: minute,
-							second: second,
-							result: `${minute}:${second}`
-						};
-						break;
-					case 7:
-						result = {
-							year: year,
-							month: month,
-							day: day,
-							hour: hour,
-							minute: minute,
-							second: second,
-							result: `${year}-${month}-${day} ${hour}:${minute}:${second}`
-						};
-						break;
-					case 8:
-						result = {
-							year: year,
-							month: month,
-							day: day,
-							hour: hour,
-							result: `${year}-${month}-${day} ${hour}:00`
-						};
-						break;
-					default:
-						break;
-				}
-				this.$emit('confirm', result);
-			},
-			waitFix() {
-				if (this.isEnd) {
-					this.selectResult()
-				} else {
-					setTimeout(() => {
-						this.waitFix()
-					}, 50)
-				}
 			},
 			btnFix() {
 				setTimeout(() => {
-					this.waitFix()
+					let result = {};
+					let year = this.year;
+					let month = this.formatNum(this.month || 0);
+					let day = this.formatNum(this.day || 0);
+					let hour = this.formatNum(this.hour || 0);
+					let minute = this.formatNum(this.minute || 0);
+					let second = this.formatNum(this.second || 0);
+					switch (this.type) {
+						case 1:
+							result = {
+								year: year,
+								month: month,
+								day: day,
+								hour: hour,
+								minute: minute,
+								result: `${year}-${month}-${day} ${hour}:${minute}`
+							};
+							break;
+						case 2:
+							result = {
+								year: year,
+								month: month,
+								day: day,
+								result: `${year}-${month}-${day}`
+							};
+							break;
+						case 3:
+							result = {
+								year: year,
+								month: month,
+								result: `${year}-${month}`
+							};
+							break;
+						case 4:
+							result = {
+								hour: hour,
+								minute: minute,
+								result: `${hour}:${minute}`
+							};
+							break;
+						case 5:
+							result = {
+								hour: hour,
+								minute: minute,
+								second: second,
+								result: `${hour}:${minute}:${second}`
+							};
+							break;
+						case 6:
+							result = {
+								minute: minute,
+								second: second,
+								result: `${minute}:${second}`
+							};
+							break;
+						case 7:
+							result = {
+								year: year,
+								month: month,
+								day: day,
+								hour: hour,
+								minute: minute,
+								second: second,
+								result: `${year}-${month}-${day} ${hour}:${minute}:${second}`
+							};
+							break;
+						default:
+							break;
+					}
+					this.$emit('confirm', result);
 					this.hide();
 				}, 80);
-			},
-			pickerstart() {
-				this.isEnd = false
 			}
 		}
 	};
@@ -512,7 +405,7 @@
 <style scoped>
 	.tui-datetime-picker {
 		position: relative;
-		z-index: 996;
+		z-index: 999;
 	}
 
 	.tui-picker-view {
@@ -522,7 +415,7 @@
 
 	.tui-mask {
 		position: fixed;
-		z-index: 997;
+		z-index: 9998;
 		top: 0;
 		right: 0;
 		bottom: 0;
@@ -539,7 +432,7 @@
 	}
 
 	.tui-header {
-		z-index: 998;
+		z-index: 9999;
 		position: fixed;
 		bottom: 0;
 		left: 0;
@@ -554,8 +447,10 @@
 		display: flex;
 		align-items: center;
 		justify-content: space-between;
+		background-color: #fff;
 		font-size: 26rpx;
 		line-height: 26rpx;
+		color: #555;
 		/* #ifdef MP */
 		box-shadow: 0 15rpx 10rpx -15rpx #efefef;
 		/* #endif */
@@ -584,6 +479,7 @@
 		align-items: center;
 		box-sizing: border-box;
 		font-size: 32rpx;
+		background-color: #fff;
 		position: relative;
 	}
 
@@ -604,13 +500,14 @@
 		left: 0;
 	}
 
-	.tui-date__picker-body {
+	.tui-picker-body {
 		width: 100%;
-		/* height: 520rpx; */
+		height: 520rpx;
 		overflow: hidden;
+		background-color: #fff;
 	}
 
-	.tui-date__column-item {
+	.tui-column-item {
 		display: flex;
 		align-items: center;
 		justify-content: center;
@@ -622,7 +519,7 @@
 		font-size: 32rpx !important;
 	}
 
-	.tui-date__unit-text {
+	.tui-unit-text {
 		font-size: 24rpx !important;
 		padding-left: 8rpx;
 	}
@@ -632,23 +529,9 @@
 		box-sizing: border-box;
 		text-align: center;
 		text-decoration: none;
-		flex-shrink: 0;
-		/* #ifdef H5 */
-		cursor: pointer;
-		/* #endif */
 	}
 
 	.tui-opacity {
 		opacity: 0.5;
 	}
-
-	.tui-pickerdate__title {
-		white-space: nowrap;
-		overflow: hidden;
-		text-overflow: ellipsis;
-		flex: 1;
-		padding: 0 30rpx;
-		box-sizing: border-box;
-		text-align: center;
-	}
 </style>

+ 81 - 123
components/thorui/tui-drawer/tui-drawer.vue

@@ -1,140 +1,98 @@
 <template>
-	<!-- @touchmove.stop.prevent -->
-	<view>
-		<view v-if="mask" class="tui-drawer-mask" :class="{ 'tui-drawer-mask_show': visible }" :style="{ zIndex: maskZIndex }" @tap="handleMaskClick"></view>
-		<view
-			class="tui-drawer-container"
-			:class="[`tui-drawer-container_${mode}`, visible ? `tui-drawer-${mode}__show` : '']"
-			:style="{ zIndex: zIndex, backgroundColor: backgroundColor }"
-		>
+	<view  @touchmove.stop.prevent>
+		<view v-if="mask" class="tui-drawer-mask" :class="{'tui-drawer-mask_show':visible}" @tap="handleMaskClick"></view>
+		<view class="tui-drawer-container" :class="[mode=='left'?'tui-drawer-container_left':'tui-drawer-container_right',visible?'tui-drawer-container_show':'']">
 			<slot></slot>
 		</view>
 	</view>
+
 </template>
 
 <script>
-/**
- * 超过一屏时插槽使用scroll-view
- **/
-export default {
-	name: 'tuiDrawer',
-	emits: ['close'],
-	props: {
-		visible: {
-			type: Boolean,
-			default: false
-		},
-		mask: {
-			type: Boolean,
-			default: true
-		},
-		maskClosable: {
-			type: Boolean,
-			default: true
-		},
-		// left right bottom top
-		mode: {
-			type: String,
-			default: 'right'
-		},
-		//drawer z-index
-		zIndex: {
-			type: [Number, String],
-			default: 9999
-		},
-		//mask z-index
-		maskZIndex: {
-			type: [Number, String],
-			default: 9998
+	/**
+	 * 超过一屏时插槽使用scroll-view
+	 **/
+	export default {
+		name:"tuiDrawer",
+		props: {
+			visible: {
+				type: Boolean,
+				default: false
+			},
+			mask: {
+				type: Boolean,
+				default: true
+			},
+			maskClosable: {
+				type: Boolean,
+				default: true
+			},
+			mode: {
+				type: String,
+				default: 'true' // left right
+			}
 		},
-		backgroundColor: {
-			type: String,
-			default: '#fff'
-		}
-	},
-	methods: {
-		handleMaskClick() {
-			if (!this.maskClosable) {
-				return;
+		methods: {
+			handleMaskClick() {
+				if (!this.maskClosable) {
+					return;
+				}
+				this.$emit('close', {});
 			}
-			this.$emit('close', {});
 		}
 	}
-};
 </script>
 
 <style scoped>
-.tui-drawer-mask {
-	opacity: 0;
-	visibility: hidden;
-	position: fixed;
-	top: 0;
-	left: 0;
-	right: 0;
-	bottom: 0;
-	background-color: rgba(0, 0, 0, 0.6);
-	transition: all 0.3s ease-in-out;
-}
-.tui-drawer-mask_show {
-	display: block;
-	visibility: visible;
-	opacity: 1;
-}
-
-.tui-drawer-container {
-	position: fixed;
-	left: 50%;
-	height: 100.2%;
-	top: 0;
-	transform: translate3d(-50%, -50%, 0);
-	transform-origin: center;
-	transition: all 0.3s ease-in-out;
-	opacity: 0;
-	overflow-y: scroll;
-	-webkit-overflow-scrolling: touch;
-	-ms-touch-action: pan-y cross-slide-y;
-	-ms-scroll-chaining: none;
-	-ms-scroll-limit: 0 50 0 50;
-}
-.tui-drawer-container_left {
-	left: 0;
-	top: 50%;
-	transform: translate3d(-100%, -50%, 0);
-}
+	.tui-drawer-mask {
+		opacity: 0;
+		visibility: hidden;
+		position: fixed;
+		top: 0;
+		left: 0;
+		right: 0;
+		bottom: 0;
+		z-index: 8888;
+		background-color: rgba(0, 0, 0, 0.6);
+		transition: all 0.3s ease-in-out;
+	}
+	.tui-drawer-mask_show {
+		display: block;
+		visibility: visible;
+		opacity: 1;
+	}
 
-.tui-drawer-container_right {
-	right: 0;
-	top: 50%;
-	left: auto;
-	transform: translate3d(100%, -50%, 0);
-}
+	.tui-drawer-container {
+		position: fixed;
+		left: 50%;
+		height: 100.2%;
+		top: 0;
+		transform: translate3d(-50%, -50%, 0);
+		transform-origin: center;
+		transition: all 0.3s ease-in-out;
+		z-index: 99999;
+		opacity: 0;
+		overflow-y: scroll;
+		background-color: #fff;
+		-webkit-overflow-scrolling: touch;
+		-ms-touch-action: pan-y cross-slide-y;
+		-ms-scroll-chaining: none;
+		-ms-scroll-limit: 0 50 0 50;
+	}
+	.tui-drawer-container_left {
+		left: 0;
+		top: 50%;
+		transform: translate3d(-100%, -50%, 0);
+	}
 
-.tui-drawer-container_bottom,
-.tui-drawer-container_top {
-	width: 100%;
-	height: auto !important;
-	min-height: 20rpx;
-	left: 0;
-	right: 0;
-	transform-origin: center;
-	transition: all 0.3s ease-in-out;
-}
-.tui-drawer-container_bottom {
-	bottom: 0;
-	top: auto;
-	transform: translate3d(0, 100%, 0);
-}
-.tui-drawer-container_top {
-	transform: translate3d(0, -100%, 0);
-}
-.tui-drawer-left__show,
-.tui-drawer-right__show {
-	opacity: 1;
-	transform: translate3d(0, -50%, 0);
-}
-.tui-drawer-top__show,
-.tui-drawer-bottom__show {
-	opacity: 1;
-	transform: translate3d(0, 0, 0);
-}
+	.tui-drawer-container_right {
+		right: 0;
+		top: 50%;
+		left: auto;
+		transform: translate3d(100%, -50%, 0);
+	}
+	.tui-drawer-container_show {
+		opacity: 1;
+		transform: translate3d(0, -50%, 0);
+	}
 </style>

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio