Commit 4ed0db44 by Hao

Initial commit

parents
.DS_Store
node_modules
/unpackage
yarn.lock
package-lock.json
haha.json
_drop
<script>
import Vue from 'vue'
import store from './store/index.js'
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'
export default {
globalData: {
historydata: [], //用于存储搜索页面的搜索列表
token: '',
},
onLaunch: function () {
this.openidLogin()
},
onShow: function () {
this.getSystemInfo()
this.SET_IS_IphoneX(this.isIphoneX())
},
onHide: function () {},
onReady: function () {},
onUnload: function () {},
computed: {
...mapGetters(['isLogin']),
},
methods: {
...mapMutations(['SET_IS_IphoneX', 'SET_FeignWxMessageInfo']),
//登录获取
openidLogin() {
//#ifdef H5
// if (!this.isLogin) {
// uni.navigateTo({
// url: "/subPackages/login/login"
// })
// }
// #endif
// #ifndef H5
uni.login({
success: function (res) {
let queryData = {
appId: Vue.prototype.$http.appId,
code: res.code,
tenantId: Vue.prototype.$http.tenantId,
}
Vue.prototype.$http
.getSessionKeyByCode(queryData)
.then(({ success, result }) => {
if (success) {
let info = {
openid: result.openid,
}
Vue.prototype.$http
.openidLogin(info)
.then(({ success, result }) => {
if (success) {
let app = getApp()
store.state.member = result
app.globalData.token = result.token //将token存在app中的全局变量中用于其他页面是否先执行加载数据做标识
app.cbLoginCallBack &&
typeof app.cbLoginCallBack == 'function' &&
app.cbLoginCallBack()
app.getGlobalStyle()
app.getFeignWxMessageInfo()
uni.setStorageSync('member', JSON.stringify(result))
}
})
}
})
},
})
// #endif
},
getGlobalStyle() {
Vue.prototype.$http
.getGlobalStyle()
.then(({ success, message, result }) => {
if (success) {
if (result.length > 0) {
//动态获取全局颜色
store.state.globelColor.primaryColor = `--primaryColor:${result[0].globalBg2};--primaryBtnColor:${result[0].globalBg1}`
}
}
})
},
//获取模板消息
getFeignWxMessageInfo() {
Vue.prototype.$http
.getFeignWxMessageInfo()
.then(({ success, message, result }) => {
if (success) {
store.commit('SET_FeignWxMessageInfo', result)
}
})
},
testUA(str) {
return navigator.userAgent.indexOf(str) > -1
},
// 判断是iphoneX及以后的iphone手机(即iphone带全面屏的手机)
isIphoneX() {
let result = false
const res = wx.getSystemInfoSync()
const rate = res.windowHeight / res.windowWidth
let limit = res.windowHeight == res.screenHeight ? 1.8 : 1.65 // 临界判断值
if (rate > limit) {
result = true
}
return result
},
// //若没有开启定位
getSystemInfo() {
uni.getSystemInfo({
success: function (res) {
var isopendingwei = res.locationEnabled
if (isopendingwei == false) {
wx.showModal({
title: '提示',
showCancel: true,
content: '请先开启手机GPS定位,然后重新进入页面!',
success(res) {
if (res.confirm) {
uni.navigateTo({
url: '/pages/index/index?finish=true',
})
}
},
})
}
},
})
},
},
}
</script>
<style lang="scss">
/*每个页面公共css */
@import '~@/static/style/app.scss';
</style>
<style lang="less">
@import '~@/components/shop-decorater/index.less';
</style>
import ports from '../common/ports.js'
import distributionPorts from '../common/distributionPorts.js' //分销模块
import request from '../common/request.js'
import config from '@/config/index.js';
let api = {}
api['appId'] = config.appId //小程序appid
api['tenantId'] = config.tenantId //租户id
api['appCode'] = config.appCode //区分门店端或者商城端
api['imgUrl'] = config.imgUrl //图片前缀
api['baseUrl'] = config.baseUrl //api请求地址
api['shopId'] = config.shopId //商城门店Id
let arr = []
if(ports) arr.push(ports)
if(distributionPorts) arr.push(distributionPorts)
arr.forEach(item => {
Object.keys(item.get).map(key => {
api[key] = (params, Toast, loading=false) => request.globalRequest(item.get[key], 'get', params, Toast, loading)
})
Object.keys(item.post).map(key => {
api[key] = (params, Toast, loading=false) => request.globalRequest(item.post[key], 'post', params, Toast, loading)
})
Object.keys(item.deleted).map(key => {
api[key] = (params, Toast, loading=false) => request.globalRequest(item.deleted[key], 'delete', params, Toast, loading)
})
Object.keys(item.put).map(key => {
api[key] = (params, Toast, loading=false) => request.globalRequest(item.put[key], 'put', params, Toast, loading)
})
})
export default api
import api from '../api/api.js'
export default {
get: {
favoritesdelete: '/app/member/favorites/delete',
//(分销模块)(个人)
qryDmsUserClientPage: '/app/dms/dmsUser/qryDmsUserClientPage',
//查询代言人基本信息
getAppDmsUserInfo: '/app/dms/dmsUser/getAppDmsUserInfo',
//分销等级列表
getAppDmsLevelList: '/app/dms/dmsLevel/getAppDmsLevelList',
//业绩统计页面
getDmsUserPerformanceStatistics: '/app/dms/dmsUser/getDmsUserPerformanceStatistics',
//申请加入代言人
joinDmsUser: '/app/dms/dmsUser/joinDmsUser',
//用户手动升级分销等级
upgrade: '/app/dms/dmsLevel/upgrade',
//查询我邀请的代言人
getJoinDmsUserList: '/app/dms/dmsUser/getJoinDmsUserList',
//(分销模块)
//查询推广商品列表
getDmsProductList: '/app/dms/dmsProduct/getDmsProductList',
//(结算中心)
//查询当前用户的收款银行列表
memberBankList: '/app/member/memberBank/list',
//新增收款银行信息
memberBankAdd: '/app/member/memberBank/add',
//修改收款银行信息
memberBankedit: '/app/member/memberBank/edit',
//查询单个收款信息
queryById: '/app/member/memberBank/queryById',
//查询当前用户的收支明细
getDmsUserBalanceLogList: '/app/dms/settlement/getDmsUserBalanceLogList',
//提现记录列表
getAppWithdrawOrderList: '/app/dms/settlement/getAppWithdrawOrderList',
//获取腾讯云对象参数的配置参数
getUploadConfigInfo: '/sys/ext/getUploadConfigInfo',
// 小程序-分页查询当前队长所在团队的分销奖励订单
getAwardOrderList: '/app/dms/dmsTeamAward/getAwardOrderList',
//小程序-查询当前队长所在团队的分销奖励
getDmsTeamAwardList: '/app/dms/dmsTeamAward/getDmsTeamAwardList',
// 小程序-查询分销团队基本信息
getDmsTeamInfo: '/app/dms/dmsTeam/getDmsTeamInfo',
//小程序-查询团队排行榜
getAppDmsTeamRankingList: '/app/dms/dmsTeam/getAppDmsTeamRankingList',
//分销模块-团队层级管理-查询销售团队成员列表
getDmsTeamUserInfo: '/app/dms/dmsTeam/getDmsTeamUserInfo',
//团队销售额
getDmsTeamMarketInfo: '/app/dms/dmsTeam/getDmsTeamMarketInfo',
//上传
upload: '/sys/common/upload',
//(银行卡)
//查询收款支持的银行
busiBankList: '/app/dms/busiBank/list',
//收款银行信息-通过id删除
memberBankDelete: '/app/member/memberBank/delete',
//收款银行信息-编辑
memberBankEdit: '/app/member/memberBank/edit',
//收款银行信息-分页列表查询
memberBankList: '/app/member/memberBank/list',
//收款银行信息-通过id查询
memberBankQueryById: '/app/member/memberBank/queryById',
// //提现记录列表
// getAppWithdrawOrderList: '/app/dms/settlement/getAppWithdrawOrderList',
//查询当前用户的收支明细
getDmsUserBalanceLogList: '/app/dms/settlement/getDmsUserBalanceLogList',
//收藏
addCollection: '/app/member/cart/addCollection',
//小程序-查询代言人所有可推广分享的优惠券
getDmsShareEcardList: '/app/dms/dmsUser/getDmsShareEcardList',
//查询代言人推广订单明细
qryDmsUserSalesOrderPage: '/app/dms/dmsUser/qryDmsUserSalesOrderPage',
getDmsUserState: '/app/dms/dmsUser/getDmsUserState',
//用户点击代言人推广链接
clickDMSUrl: '/app/dms/dmsUser/clickDMSUrl',
// 获取省市区数据
getProvinceCityDistrict:'/app/member/address/region',
// 获取权益卡列表
getRightsCardList:'/app/card/rightsUsers/queryRightsCardList',
// 获取权益卡详情
getRightsCardDetails:'/app/card/rightsUsers/queryRightsCardById',
// 权益卡激活使用
// rightsUse:'/app/card/rightsUsers/activationCard'
// 获取计算权益后的付款金额详情
getRightsAfterSum:'/app/card/rightsAndMember/queryRightsAndMember',
},
post: {
getWxDirectList: "/app/marketing/live/getWxLiveList",
//排行榜按钮需调用开关接口,判断是否有打开
getBusiConfig: '/app/busiConfig/feign/getBusiConfig',
//判断收费身份认证
getMemberIdentityInfo: '/app/member/getMemberIdentityInfo',
//上传身份证信息
editMemberIdentityInfo: '/app/member/editMemberIdentityInfo',
//小程序-代言人申请提现
applySettlement: '/app/dms/settlement/applySettlement',
//收款银行信息-添加
},
put: {
},
deleted: {},
}
/**枚举EPlatform*/
const EPlatform = {
/**App*/
AppPlus: 'APP-PLUS',
/**App nvue*/
AppPlusNvue: 'APP-PLUS-NVUE',
/**H5*/
H5: 'H5',
/**微信小程序*/
MpWeixin: 'MP-WEIXIN',
/**支付宝小程序*/
MpAlipay: 'MP-ALIPAY',
/**百度小程序*/
MpBaidu: 'MP-BAIDU',
/**字节跳动小程序*/
MpToutiao: 'MP-TOUTIAO',
/**QQ小程序*/
MpQq: 'MP-QQ',
/**360小程序*/
Mp360: 'MP-360',
/**微信小程序/支付宝小程序/百度小程序/字节跳动小程序/QQ小程序/360小程序*/
Mp: 'MP',
/**快应用通用(包含联盟、华为)*/
QuickappWebview: 'quickapp-webview',
/**快应用联盟*/
QuickappWebviewUnion: 'quickapp-webview-union',
/**快应用华为*/
QuickappWebviewHuawei: 'quickapp-webview-huawei',
}
let platform = ''
/**平台类型*/
function ifDefPlatform() {
//#ifdef APP-PLUS
platform = EPlatform.AppPlus;
//#endif
//#ifdef APP-PLUS-NVUE
platform = EPlatform.AppPlusNvue;
//#endif
//#ifdef H5
platform = EPlatform.H5;
//#endif
//#ifdef MP-WEIXIN
platform = EPlatform.MpWeixin;
//#endif
//#ifdef MP-ALIPAY
platform = EPlatform.MpAlipay;
//#endif
//#ifdef MP-BAIDU
platform = EPlatform.MpBaidu;
//#endif
//#ifdef MP-TOUTIAO
platform = EPlatform.MpToutiao;
//#endif
//#ifdef MP-QQ
platform = EPlatform.MpQq;
//#endif
//#ifdef MP-360
platform = EPlatform.Mp360;
//#endif
//#ifdef MP
platform = EPlatform.Mp;
//#endif
//#ifdef quickapp-webview
platform = EPlatform.QuickappWebview;
//#endif
//#ifdef quickapp-webview-union
platform = EPlatform.QuickappWebviewUnion;
//#endif
//#ifdef quickapp-webview-huawei
platform = EPlatform.QuickappWebviewHuawei;
//#endif
return platform
}
/**默认导出平台类型*/
export const Platform = ifDefPlatform()
/**App*/
export const isAppPlus = Platform == EPlatform.AppPlus
/**App nvue*/
export const isAppPlusNvue = Platform == EPlatform.AppPlusNvue
/**H5*/
export const isH5 = Platform == EPlatform.H5
/**微信小程序*/
export const isMpWeixin = Platform == EPlatform.MpWeixin
/**支付宝小程序*/
export const isMpAlipay = Platform == EPlatform.MpAlipay
/**百度小程序*/
export const isMpBaidu = Platform == EPlatform.MpBaidu
/**字节跳动小程序*/
export const isMpToutiao = Platform == EPlatform.MpToutiao
/**QQ小程序*/
export const isMpQq = Platform == EPlatform.MpQq
/**360小程序*/
export const isMp360 = Platform == EPlatform.Mp360
/**微信小程序/支付宝小程序/百度小程序/字节跳动小程序/QQ小程序/360小程序*/
export const isMp = Platform == EPlatform.Mp
/**快应用通用(包含联盟、华为)*/
export const isQuickappWebview = Platform == EPlatform.QuickappWebview
/**快应用联盟*/
export const isQuickappWebviewUnion = Platform == EPlatform.QuickappWebviewUnion
/**快应用华为*/
export const isQuickappWebviewHuawei = Platform == EPlatform.QuickappWebviewHuawei
/**是否开发环境*/
export const isDevelopment = process.env.NODE_ENV == 'development'
/**是否线上环境*/
export const isProduction = process.env.NODE_ENV == 'production'
/**抖音小程序*/
export const isMpDouyinApp = uni.getSystemInfoSync().appName == 'Douyin'
/**头条小程序*/
export const isMpToutiaoApp = uni.getSystemInfoSync().appName == 'Toutiao'
\ No newline at end of file
This diff is collapsed. Click to expand it.
import api from '../api/api.js'
import Vue from 'vue'
import {
hasH5
} from '@/common/util.js'
import {
isH5,
isMp
} from '@/common/platform.js'
let self = Vue.prototype
export default {
globalRequest(url, method, data, Tosat = true, loading = true) {
let token = self.$store.state.member.token || ''
let $http = hasH5(self.$http);
let webType;
const baseUrl = api.baseUrl
if (isH5) {
webType = 'web'
} else if (isMp) {
webType = 'miniApp'
}
return new Promise((resolve, reject) => {
uni.request({
url: api.baseUrl + url,
method: method.toLocaleLowerCase(),
data: {
...data,
...{
shopId: $http.shopId,
},
},
header: {
'Content-Type': 'application/json',
'X-Access-Token': token,
tenantId: $http.tenantId,
appCode: $http.appCode,
qryShopId: $http.shopId,
mId: self.$store.getters.memberId || '',
webType
},
success(res) {
if (res.statusCode == 200) {
if (res.data.message.includes('操作失败')) {
let message = res.data.message.split('操作失败,')
res.data.message = message[message.length - 1]
}
if (res.data.code == 200) {
resolve(res.data)
} else if (res.data.message == '用户不存在!') {
//清空存储的用户信息
self.$store.dispatch('resetVuex')
} else if (res.data.code == 10011) {
uni.navigateBack({
delta: 1,
})
} else {
console.log('获取失败')
resolve(res.data)
if(Tosat) uni.showToast({
title: res.data.message,
duration: 3000,
icon: 'none',
})
}
} else {
const data = (res.data && res.data.message) || '';
if (data == 'Token失效,请重新登录') {
uni.clearStorageSync();
} else {
if(Tosat) uni.showToast({
title: res.data.message,
duration: 3000,
icon: 'none'
});
resolve(res.data || {});
}
}
},
error(res) {},
})
})
},
}
This diff is collapsed. Click to expand it.
<template>
<view class="ali">
<view class="ali_top borders">
<text class="a14">物流单号:{{ expressNo }}</text>
</view>
<view class="ali_top borders">
<text class="ali_top_icon"></text>
<text class="a14">{{ address }}</text>
</view>
<view class="ali_state">
<block v-for="(item, i) in datas" :key="i">
<view class="State_Four">
<view class="FourBox">
<text class="line" :class="[i == 0 ? 'noline' : '']"></text>
<text
class="ali_top_icon"
style="margin: 0 0"
v-if="
item.acceptStation.includes(ways.expName) ||
i == datas.length - 1
"
></text
>
<!-- =====如果不够,可以再方法和过滤器中同时添加判断-----或者如下的--[v-else-if]操作 -->
<!-- <text class="ali_top_icon" style="margin: 0 0;" v-else-if="item.remark.includes('丰巢智能快递柜') && i!= datas.length-1"></text> -->
<text
class="ali_top_icon"
:class="[item.acceptStation.includes('签收') ? 'isOk' : '']"
style="margin: 0 0"
v-else-if="
Type(item.acceptStation) == true && i != datas.length - 1
"
>{{ item.acceptStation | Type }}</text
>
<view class="ali_top_icons" style="margin: 0 0" v-else>
<text class="line" :class="[i == 0 ? 'noline' : '']"></text>
<text class="ali_top_iconss"></text>
<text class="line" :class="[i == 0 ? 'noline' : '']"></text>
</view>
<text
class="line"
:class="[i == datas.length - 1 ? 'noline' : '']"
></text>
</view>
<view class="remark">
<text class="a14" v-if="i == datas.length - 1">已发货</text>
<text class="a14" v-else>{{ item.acceptStation }}</text>
<text class="a12" style="padding-top: 10upx">{{
item.AcceptTime
}}</text>
</view>
</view>
</block>
</view>
</view>
</template>
<script>
export default {
props: ['datas', 'state', 'ways', 'expressNo', 'address'],
data() {
return {}
},
//过滤返回关键字
filters: {
Type(item) {
let Info
let Phone = /\d{11}/
if (Phone.test(item) && item.includes('正在派')) {
Info = '派'
} else if (item.includes('已收取快件')) {
Info = '揽'
} else if (item.includes('营业')) {
Info = '运'
} else if (item.includes('丰巢智能快递柜')) {
Info = '待'
} else if (item.includes('签收')) {
Info = '收'
} else {
Info = ''
}
return Info
},
},
created() {
},
methods: {
//判断哪个该展示关键字--还是默认
Type(item) {
let Info
let Phone = /\d{11}/
if (Phone.test(item) && item.includes('正在派')) {
Info = true
} else if (item.includes('已收取快件')) {
Info = true
} else if (item.includes('营业')) {
Info = true
} else if (item.includes('丰巢智能快递柜')) {
Info = true
} else if (item.includes('签收')) {
Info = true
} else {
Info = false
}
return Info
},
},
}
</script>
<style>
.isOk {
background-color: #f0ad4e !important;
}
.ali_top_iconss {
width: 12upx;
height: 12upx;
display: block;
background-color: #999;
padding-right: 2upx;
border-radius: 50%;
}
.noline {
background-color: #fff !important;
}
.State_Four {
display: flex;
align-items: flex-start;
/* border: 1upx solid red; */
}
.FourBox {
display: flex;
flex-direction: column;
align-items: center;
padding-right: 24upx;
}
.line {
width: 2upx;
display: flex;
flex-direction: column;
flex: 1;
background-color: #999;
}
/* ============= */
.remark {
display: flex;
flex-direction: column;
width: 90%;
padding: 10upx 0;
}
.borders {
border-bottom: 1upx solid #f2f2f2;
padding: 24upx 0;
}
.ali_top_icons {
width: 46upx;
height: 46upx;
display: block;
background-color: #fff;
border-radius: 50%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
align-content: center;
}
.ali_top_icon {
width: 46upx;
height: 46upx;
display: block;
background-color: #83aecf;
color: #fff;
font-size: 28upx;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
margin-right: 20upx;
}
.ali_top {
display: flex;
justify-content: flex-start;
align-items: center;
}
/* ========公共========= */
.a14 {
font-size: 28upx;
color: #000000;
}
.a12 {
font-size: 24upx;
color: #999;
}
.ali {
/* width: 100%; */
/* border: 1upx solid #F76260; */
background-color: #ffffff;
margin: 24upx;
border-radius: 18upx;
padding: 0 24upx;
display: flex;
flex: 1;
flex-direction: column;
}
</style>
<template>
<view class="box" v-if="SHOW_TOP" :style="{ top: custom ? navbarHeight + 'px' : '0px;' }" id="add-tips">
<!-- <view class='arrow' :style="'margin-right:'+arrowR+'px;'"></view> -->
<view class="body" @tap="hidden">
<!-- <image :src="logo" class="logo"></image>
<view class="tips">点击•●•添加到我的小程序,以后使用更方便</view> -->
<image :src="imgUrl('tjiaxuanfu.png')" mode="widthFix"></image>
</view>
</view>
</template>
<script>
import {
imgUrl
} from '@/common/util.js';
import {
mapState,
mapGetters,
mapMutations
} from 'vuex'
export default {
props: {
name: {
type: String,
default: '测试',
},
duration: {
type: Number,
default: 10,
},
delay: {
type: Number,
default: 1,
},
logo: {
type: String,
default: 'https://cdn.blog.makergyt.com/mini/assets/component-add_tips.png',
},
custom: {
type: Boolean,
default: true,
},
},
data() {
return {
navbarHeight: 56,
arrowR: '',
SHOW_TOP: false,
bodyR: '',
startTimer: null,
duraTimer: null,
}
},
computed: {
...mapState(['tips']),
},
watch: {
tips: {
deep: true,
handler(newVal, oldVal) {
if (!newVal) {
this.init()
}
},
},
},
created() {
this.init()
},
destroyed() {
if (this.startTimer) clearTimeout(this.startTimer)
if (this.duraTimer) clearTimeout(this.duraTimer)
},
methods: {
imgUrl,
init() {
if (this.tips) return
let rect = uni.getMenuButtonBoundingClientRect ?
uni.getMenuButtonBoundingClientRect() :
null
let {
screenWidth
} = uni.getSystemInfoSync();
(this.navbarHeight = rect.bottom + 4), //距离顶部胶囊按钮4px
(this.arrowR = screenWidth - rect.right + (rect.width * 3) / 4 - 5),
(this.bodyR = screenWidth - rect.right)
this.startTimer = setTimeout(() => {
this.SHOW_TOP = true
}, this.delay * 1000)
this.duraTimer = setTimeout(() => {
this.shrink()
//
}, (this.duration + this.delay) * 1000)
},
...mapMutations(['SET_TIPS']),
hidden: function() {
this.SET_TIPS(true)
this.shrink()
},
shrink: function() {
this.$mp.component.animate(
'#add-tips',
[{
scale: [1, 1],
},
{
scale: [0, 0],
ease: 'ease',
transformOrigin: `calc(600rpx - ${this.arrowR}px) 1%`,
},
],
500,
function() {
this.SHOW_TOP = false
}.bind(this)
)
},
},
}
</script>
<style scoped lang="less">
.box {
position: fixed;
right: 0;
display: flex;
justify-content: flex-end;
align-items: flex-end;
flex-direction: column;
width: 600rpx;
z-index: 10000;
}
// .arrow {
// width: 0;
// height: 0;
// border-width: 5px;
// border-style: solid;
// border-color: transparent transparent rgba(0, 0, 0, 0.75) transparent;
// box-shadow: 0 20rpx 20rpx -20rpx rgba(51, 51, 51, 0.1);
// }
.body {
width: 400rpx;
height: 148rpx;
image {
width: 100%;
height: 100%;
}
}
.tips {
flex: 1;
color: #ffffff;
font-size: 14px;
font-weight: 700;
}
.logo {
height: 42px;
width: 42px;
border-radius: 8px;
margin-right: 10px;
}
</style>
<template>
<view>
<popup-layer direction="top" @closeCallBack="closeDetailModal" :show-pop="show" class="coupons-detail-modal" color="#5A5B5C" :redius="true">
<template slot="content">
<view class="box">
<view class="cover" :class="[state == 0 ? 'tall' : 'short']">
<view class="ecardName">{{ coupnInfo.ecardName }}</view>
<view class="btn-group"><image :src="imgUrl('close.png')" @tap="closeDetailModal" mode="aspectFill"></image></view>
<scroll-view class="exchange-cotent" scroll-y style="height:531rpx">
<view class="conversion">
<view class="conversion_title">可用商品</view>
<view class="conversion_desc">{{ coupnInfo.productItemIdDict || '所有可用' }}</view>
</view>
<view class="conversion">
<view class="conversion_title">购买须知</view>
<jyf-parser ref="desc"></jyf-parser>
</view>
<view class="conversion">
<view class="conversion_title">售卖时间</view>
<view class="conversion_desc">{{ coupnInfo.doleStartTime }} ~ {{ coupnInfo.doleEndTime }}</view>
</view>
</scroll-view>
<view class="box_button" v-if="state == 0">
<view class="d-flex justify-content-between " style="padding:54rpx 0rpx;" :style="coupnInfo.currentTab == 1 ? 'border-top: 2rpx solid #eee;' : ''">
<view class="font-size-extra-lg text-color-primary font-weight-bold d-flex align-items-end" v-if="coupnInfo.currentTab == 1">
<view class="archMoney" v-if="coupnInfo.exchangeType == 2"></view>
{{ hasExchangeType }}
<view class="archIntegral" v-if="coupnInfo.exchangeType == 1"></view>
</view>
<view class="d-flex align-items-center" v-if="coupnInfo.currentTab == 1">
<view class="iconfont line-height-100 checkbox text-color-primary mr-16 checked icon-sel"></view>
<view class="font-size-base text-color-333 font-weight-400">{{ hasPayment }}</view>
</view>
</view>
<button type="primary" class="login-btn" @tap="sumbit" :disabled="coupnInfo.currentTab == 0 && coupnInfo.isCanBuy == 'N'">
{{
coupnInfo.currentTab !== undefined && coupnInfo.currentTab == 0
? coupnInfo.isCanBuy == 'N'
? '已经领取'
: '免费领取'
: coupnInfo.currentTab == 1
? '立即购买'
: '立即使用'
}}
</button>
</view>
</view>
</view>
</template>
</popup-layer>
</view>
</template>
<script>
import popupLayer from '@/components/popup-layer/popup-layer';
import jyfParser from '@/components/jyf-parser/jyf-parser';
import { imgUrl} from '@/common/util.js';
export default {
components: {
popupLayer,
jyfParser
},
props: {
show: {
type: Boolean,
default: false
},
coupnInfo: {
type: Object,
default: {}
},
state: {
type: Number,
default: 0
}
},
computed: {
hasExchangeType() {
return this.coupnInfo.exchangeType == 2 ? this.coupnInfo.price : this.coupnInfo.integral == 0 ? '' : this.coupnInfo.integral;
},
hasPayment() {
return this.coupnInfo.exchangeType == 2 ? '微信支付' : this.coupnInfo.integral == 0 ? '免费领取' : '积分支付';
}
},
watch: {
show: function(n, o) {
if (n) {
this.$nextTick(() => {
this.$refs['desc'].setContent(this.coupnInfo.ecardDesc || '');
});
}
}
},
data() {
return {};
},
methods: {
imgUrl,
sumbit() {
this.$emit('sumbit');
},
closeDetailModal() {
this.$emit('closeDetailModal');
}
}
};
</script>
<style scoped lang="scss">
.coupons-detail-modal {
::v-deep .interlayer {
color: #666666;
font-size: 28rpx;
}
.archMoney {
&::before {
@include archMoney();
}
}
.archIntegral {
&::after {
@include archIntegral();
}
}
.tall {
height: 916rpx;
}
.short {
height: 700rpx;
}
.cover {
padding: 48rpx 24rpx 24rpx 24rpx;
.ecardName {
text-align: center;
}
.box_button {
width: 702rpx;
margin: 0rpx auto 32rpx auto;
.box_footer {
display: flex;
justify-content: space-between;
.box_left {
}
}
button {
height: 96rpx;
line-height: 96rpx;
border-radius: 48rpx;
color: #ffffff;
background-color: var(--primaryColor);
font-size: 28rpx;
font-family: PingFangSC, PingFangSC-Regular;
font-weight: 400;
}
}
}
}
</style>
<template>
<view class="countdown">
<view class="day" v-if="d != 0"
><text class="text">{{ d }}</text
></view
>
<view class="time" style="margin-left: 9rpx">{{
h < 10 ? '0' + h : h
}}</view>
<text class="text">:</text>
<view class="time">{{ m < 10 ? '0' + m : m }}</view>
<text class="text">:</text>
<view class="time">{{ s < 10 ? '0' + s : s }}</view>
</view>
</template>
<script>
export default {
props: {
startTime: {
type: String,
},
endTime: {
type: String,
},
},
data() {
return {
timer: null,
d: 0,
h: 0,
m: 0,
s: 0,
hasShow:false
}
},
mounted() {
this.time()
},
beforeDestroy() {
clearInterval(this.timer)
this.timer = null
},
computed: {
sTime() {
return this.startTime
},
eTime() {
return this.endTime
},
},
watch: {
endTime() {
clearInterval(this.timer)
this.time()
},
},
methods: {
time() {
let leftTime = this.GetDateDiff(this.sTime, this.eTime)
this.getCountdownTime(leftTime)
},
//计算两个时间差
GetDateDiff(startTime, endTime) {
//将xxxx-xx-xx的时间格式,转换为 xxxx/xx/xx的格式
if (startTime && endTime) {
startTime = startTime.replace(/\-/g, '/')
endTime = endTime.replace(/\-/g, '/')
}
//将计算间隔类性字符转换为小写
var sTime = new Date(startTime)
var eTime = new Date(endTime)
return parseInt((eTime.getTime() - sTime.getTime()) / 1000)
},
//计算活动结束时间
getCountdownTime(leftTime) {
let time = leftTime
if (time > 0) {
this.timer = setInterval(() => {
if (time == 0) {
clearInterval(this.timer)
this.h = 0
this.m = 0
this.s = 0
this.$emit('clearCountDown')
} else {
this.d = parseInt(leftTime / 3600 / 24)
this.h = parseInt((time / 3600) % 24)
this.m = parseInt((time / 60) % 60)
this.s = parseInt(time % 60)
time--
}
this.$emit('Loading')
}, 1000)
}
},
},
}
</script>
<style lang="scss" scoped>
.countdown {
display: flex;
align-items: center;
font-size: 20rpx;
color: #fff;
.day {
font-size: 22rpx;
color: #ffffff;
display: flex;
align-items: center;
.text {
color: #ffffff;
font-size: 32rpx;
font-weight: bold;
}
}
.time {
padding: 8rpx;
background-color: var(--primaryColor);
border-radius: 4rpx;
box-sizing: border-box;
}
.text {
font-size: 36rpx;
font-weight: bolder;
margin: 0 6rpx;
color: var(--primaryColor);
}
}
</style>
<template>
<view class="box">
<image lazy-load mode="aspectFit" :src="imgUrl('empty.png')" class="drinks-img"
:style="hasMargin ? 'margin-top:100px' : ''"></image>
<view class="font-size-sm text-color-878889">暂无更多</view>
</view>
</template>
<script>
import {
imgUrl
} from '@/common/util.js';
export default {
name: 'empty-load',
data() {
return {}
},
created() {},
props: {
hasMargin: {
type: Boolean,
default: false,
},
},
methods: {
imgUrl
},
}
</script>
<style lang="less" scoped>
.box {
display: flex;
flex-direction: column;
align-items: center;
}
</style>
<template>
<view class="tikcos_logo_box">
<view class="d-flex just-content-center align-items-center">
<view class="tikcos_name">Weiit提供技术支持</view>
<!-- <view class="tikcos_name">sky企得力提供技术支持</view> -->
</view>
</view>
</template>
<script>
export default {
name: 'file-footerlogo',
data() {
return {}
},
}
</script>
<style lang="scss" scoped>
.tikcos_logo_box {
margin: 30rpx 0rpx 20rpx 0rpx;
.tikcos_img {
width: 30rpx;
height: 30rpx;
line-height: 30rpx;
border-radius: 50%;
margin-right: 10rpx;
image {
width: 100%;
height: 100%;
}
}
.tikcos_name {
height: 30rpx;
line-height: 30rpx;
font-size: $font-size-sm;
color: rgba(#9e9e9e, 0.5);
}
}
</style>
<template>
<view class="header">
<view class="licon" >
<view class="icon-fanhui iconfont" v-if="licon" @click="jump"></view>
<!-- <image :src="Licon" mode="widthFix"></image> -->
</view>
<view class="headerTitle">
<text>{{HTitle}}</text>
</view>
<view class="ricon" @click="jum">
<view class="subtitle">
<text>{{SubTitle}}</text>
</view>
<view class="subicon" v-if="Subicon">
<image :src="Subicon" mode="widthFix"></image>
</view>
</view>
<slot></slot>
</view>
</template>
<script>
export default {
props: {
licon:{
type: Boolean,
default: false,
},
Licon: {//右图标
type: String,
default: '/static/back.png'
},
HTitle: {//主标题
type: String,
default: ''
},
SubTitle: {//副标题
type: String,
default: ''
},
Subicon: {//副图标
type: String,
default: ''
},
url_l: {//左边的跳转地址
type: String,
default: null
},
url: {//右边跳转地址
type: String,
default: ''
},
otherData: {//跳转时要带的参数
type: [String, Number, Array, Object],
default: ''
}
},
methods: {
jump() {//左边返回按钮
if (this.url_l) {
uni.reLaunch({
url: this.url_l
});
} else {
uni.navigateBack({
delta:1
});
}
},
jum() {//右边的的页面跳转,有时候可能要带参数跳转,如果不需要跳转可以不传url则只传一个触发事件
if (this.url) {
if (this.otherData) {
uni.navigateTo({
url: this.url+`?otherData=${this.otherData}`
});
}else{
uni.navigateTo({
url: this.url
});
}
} else {
this.$emit('Click');
}
}
}
}
</script>
<style lang="scss">
.header {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: calc(var(--status-bar-height) + 100upx);
box-sizing: border-box;
display: flex;
align-items: center;
overflow: hidden;
justify-content: space-between;
// margin-top: var(--status-bar-height);
// padding:calc(var(--status-bar-height) + 20upx) 40upx 20upx 40upx ;
padding: var(--status-bar-height) 40upx 0;
background-color: #FFFFFF;
// border-bottom: 1upx solid #efefef;
z-index: 9;
.licon {
// margin-right: 50upx;
width: 20%;
display: flex;
align-items: center;
image {
width: 30%;
}
}
.headerTitle {
width: 60%;
text-align: center;
// padding-left:20upx ;
font-size: $font-size-base;
font-weight: bold;
line-height: calc(var(--status-bar-height) + 100upx);
}
.ricon {
display: flex;
justify-content: flex-end;
align-items: center;
text-align: right;
width: 20%;
.subtitle {
text-align: right;
}
.subicon {
width: 30%;
// height: 40upx;
// margin-left: 10upx;
// text-align: center;
display: flex;
align-items: center;
justify-content: center;
/* image{
width: 100%;
height: 100%;
} */
}
}
}
</style>
<template>
<view class="loading">
<view class="preloader" id="preloader">
<view class="loader loader-1">
<view class="loader-outter"></view>
<view class="loader-inner"></view>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'Loading',
data() {
return {}
},
}
</script>
<style lang="scss">
.loading {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
image {
width: 260rpx;
height: 260rpx;
position: relative;
}
.preloader {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #f7f8fc;
z-index: 9999999;
-webkit-transition: all 0.3s ease-in;
-o-transition: all 0.3s ease-in;
transition: all 0.3s ease-in;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
}
.preloader.hide {
opacity: 0;
display: none;
}
.loader {
position: relative;
width: 120rpx;
height: 120rpx;
border-radius: 50%;
margin: 150rpx;
display: inline-block;
vertical-align: middle;
}
.loader-1 .loader-outter {
position: absolute;
border: 8rpx solid var(--primaryColor, #b3030e);
border-left-color: transparent;
border-bottom: 0;
width: 100%;
height: 100%;
border-radius: 50%;
-webkit-animation: loader-1-outter 1s cubic-bezier(0.42, 0.61, 0.58, 0.41)
infinite;
animation: loader-1-outter 1s cubic-bezier(0.42, 0.61, 0.58, 0.41) infinite;
}
.loader-1 .loader-inner {
position: absolute;
border: 8rpx solid var(--primaryColor, #b3030e);
border-radius: 50%;
width: 80rpx;
height: 80rpx;
left: calc(50% - 40rpx);
top: calc(50% - 40rpx);
border-right: 0;
border-top-color: transparent;
-webkit-animation: loader-1-inner 1s cubic-bezier(0.42, 0.61, 0.58, 0.41)
infinite;
animation: loader-1-inner 1s cubic-bezier(0.42, 0.61, 0.58, 0.41) infinite;
}
@-webkit-keyframes loader-1-outter {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes loader-1-outter {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@-webkit-keyframes loader-1-inner {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(-360deg);
transform: rotate(-360deg);
}
}
@keyframes loader-1-inner {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(-360deg);
transform: rotate(-360deg);
}
}
}
</style>
<template>
<view class="loading">
<view class="preloader">
<view class="load">
<view class="loader"></view>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'Loading',
data() {
return {}
},
}
</script>
<style lang="scss">
.loading {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
.preloader {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #f7f8fc;
z-index: 9999999;
-webkit-transition: all 0.3s ease-in;
-o-transition: all 0.3s ease-in;
transition: all 0.3s ease-in;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
}
.load {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.loader {
display: block;
width: 120rpx;
height: 120rpx;
border-radius: 50%;
border: 8rpx solid transparent;
border-top-color: var(--primaryColor, #b3030e);
-webkit-animation: spin1 2s linear infinite;
animation: spin1 2s linear infinite;
}
.loader::before {
content: '';
position: absolute;
top: 8rpx;
left: 8rpx;
right: 8rpx;
bottom: 8rpx;
border-radius: 50%;
border: 8rpx solid transparent;
border-top-color: var(--primaryColor, #b3030e);
-webkit-animation: spin1 3s linear infinite;
animation: spin1 3s linear infinite;
}
.loader::after {
content: '';
position: absolute;
top: 24rpx;
left: 24rpx;
right: 24rpx;
bottom: 24rpx;
border-radius: 50%;
border: 8rpx solid transparent;
border-top-color: var(--primaryColor, #b3030e);
-webkit-animation: spin1 1.5s linear infinite;
animation: spin1 1.5s linear infinite;
}
@-webkit-keyframes spin1 {
0% {
-webkit-transform: rotate(0deg);
-ms-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-ms-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes spin1 {
0% {
-webkit-transform: rotate(0deg);
-ms-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-ms-transform: rotate(360deg);
transform: rotate(360deg);
}
}
}
</style>
<template>
<view class="aui-loading aui-loading-squarefour aui-loading-squarefour-style-1" v-if="SHOW">
<view class="aui-mask" v-if="mask" @touchmove.stop.prevent></view>
<view class="aui-loading-main" :style="{background: styles.background, zIndex: styles.zIndex}">
<view class="loading-img">
</view>
<view class="aui-loading-msg" v-if="msg" :style="{color: styles.color}">{{msg}}</view>
</view>
</view>
</template>
<script>
export default {
name: "aui-loading",
props: {
mask: { //是否显示遮罩,默认false
type: Boolean,
default: true
},
direction: { //横向("row")或纵向("col")控制,默认纵向
type: Number,
default: 3000
},
styles: { //样式
type: Object,
default () {
return {
color: '',
borderRadius: '',
background: '',
zIndex: ''
};
}
},
},
data() {
return {
SHOW: false, //是否显示
theme: 1,
type: 3,
msg: '加载中...'
};
},
methods: {
//显示
show() {
var _this = this;
return new Promise(function(resolve, reject) {
_this.SHOW = true;
resolve();
if (_this.direction) {
setTimeout(() => {
_this.hide()
}, _this.direction)
}
});
},
//隐藏
hide() {
var _this = this;
return new Promise(function(resolve, reject) {
_this.SHOW = false;
resolve();
});
},
}
}
</script>
<style lang="scss" scoped>
/* loading加载弹窗 */
/* loading-ring 样式设置 */
.aui-mask {
position: fixed;
z-index: 998;
height: 100%;
width: 100%;
top: 0px;
left: 0px;
}
.loading-img {
width: 200rpx;
height: 200rpx;
position: absolute;
left: 50%;
top: 42%;
z-index: 1000;
transform: translate(-50%, -50%);
image {
width: 100%;
height: 100%;
}
}
.aui-loading.aui-loading-ring {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
z-index: 999;
}
.aui-loading.aui-loading-ring .aui-loading-main {
width: 200rpx;
height: 200rpx;
min-width: 55px;
min-height: 55px;
background: rgba(0, 0, 0, .8);
border-radius: 10px;
box-shadow: 0 0 1px rgba(100, 100, 100, .5);
padding: 15px;
box-sizing: border-box;
-ms-animation: aui-fade-in .1s ease-out forwards;
-webkit-animation: aui-fade-in .1s ease-out forwards;
animation: aui-fade-in .1s ease-out forwards;
position: absolute;
top: 50%;
left: 50%;
z-index: 999;
-ms-transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
/* loading-squarefour 样式设置 */
.aui-loading.aui-loading-squarefour {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
z-index: 999;
}
.aui-loading.aui-loading-squarefour .aui-loading-main {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 996;
background: rgba(0, 0, 0, .8);
-ms-animation: aui-fade-in .2s ease-out forwards;
-webkit-animation: aui-fade-in .2s ease-out forwards;
animation: aui-fade-in .2s ease-out forwards;
}
.aui-loading.aui-loading-squarefour .aui-loading-animate view {
width: 12px;
height: 12px;
display: block;
border-radius: 2px;
background: #2cb0b2;
position: absolute;
}
.aui-loading.aui-loading-squarefour.aui-loading-squarefour-style-1 {
z-index: 999;
}
.aui-loading.aui-loading-squarefour.aui-loading-squarefour-style-1 .aui-loading-main {
width: 240rpx;
height: 240rpx;
position: relative;
min-width: 54px;
min-height: 54px;
background: rgba(0, 0, 0, .8);
border-radius: 10px;
box-shadow: 0 0 1px rgba(100, 100, 100, .3) inset;
padding: 15px;
box-sizing: border-box;
top: 50%;
left: 50%;
z-index: 999;
-ms-transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
.aui-loading.aui-loading-squarefour.aui-loading-squarefour-style-1 .aui-loading-main .aui-loading-msg {
height: 22px;
line-height: 20px;
box-sizing: border-box;
font-size: 14px;
color: #fff;
opacity: 0.9;
position: absolute;
bottom: 15px;
left: 50%;
transform: translateX(-50%);
}
</style>
<template>
<view>
<!-- 微信普通授权 -->
<popup-layer direction="top" @closeCallBack="closeCallBack" :show-pop="loginVisible" class="login-modal"
color="#5A5B5C" :redius="true">
<template slot="content">
<view class="box">
<view class="cover">
<view class="btn-group">
<image :src="imgUrl('close.png')" @tap="closeCallBack" mode="aspectFill"></image>
</view>
</view>
<view class="box_button"><button @tap="handlergetUserProfile" lang="zh_CN">
微信一键登录
</button></view>
<view class="box_foot_title">新会员登录即加入会员,享会员福利</view>
</view>
</template>
</popup-layer>
</view>
</template>
<script>
import popupLayer from '@/components/popup-layer/popup-layer'
import {
mapState,
mapGetters,
mapActions,
mapMutations
} from 'vuex'
import {
imgUrl
} from '@/common/util.js';
export default {
components: {
popupLayer,
},
props: {
//是否还有其他的弹窗
isModel: {
type: Boolean,
default: false,
// 默认是没有的,有的话就不隐藏tabber了
},
loginVisible: {
type: Boolean,
default: false,
},
getPhoneNumberVisible: {
type: Boolean,
default: false,
},
},
data() {
return {}
},
computed: {
...mapState(['PageQuery']),
},
methods: {
imgUrl,
...mapMutations(['SET_PAGEQUERY']),
...mapActions(['resetVuex', 'getUserProfile', 'getPhoneNumber', 'wxLogin']),
handlergetUserProfile() {
this.getUserProfile().then((res) => {
if (res) {
this.$emit('closeCallBack')
const pages = getCurrentPages()
const perpage = pages[pages.length - 2] //当前页面
//考虑到是导航页跳转过来的
// let currentPage = this.PageQuery;
// 先将页面标识存在对象中
// this.SET_PAGEQUERY('');
perpage.onShow()
uni.navigateBack({
delta: 1,
})
// this.SET_PAGEQUERY(currentPage);
} else {
uni.showToast({
title: '授权失败,请重新授权!',
icon: 'none',
})
}
})
},
handlergetPhoneNumber(e) {
this.getPhoneNumber(e).then((res) => {
this.mineModalVisiblegetPhoneNumber = false
})
},
closeCallBack() {
this.$emit('closeCallBack')
},
closeCallBack2() {
this.$emit('closeCallBack2')
},
},
}
</script>
<style lang="scss" scoped>
.box {
padding: 112rpx 0rpx 0rpx 0rpx;
position: relative;
text-align: center;
.box_image {
margin-bottom: 32rpx;
image {
width: 160rpx;
height: 160rpx;
}
}
.box_button {
width: 640rpx;
margin: 30rpx auto 50rpx auto;
button {
height: 80rpx;
line-height: 80rpx;
border-radius: 48rpx;
color: #ffffff;
background-color: var(--primaryColor);
font-size: 28rpx;
font-family: PingFangSC, PingFangSC-Regular;
font-weight: 400;
}
}
.box_title {
color: #582a2d;
font-size: 28rpx;
font-family: PingFangSC, PingFangSC-Regular;
font-weight: 400;
}
.box_foot_title {
font-size: 24rpx;
font-family: 'PingFangSC, PingFangSC-Regular';
font-weight: 400;
margin-bottom: 130rpx;
color: #999999;
line-height: 28rpx;
}
}
</style>
<template>
<view @touchmove.stop.prevent>
<view class="modal-box"
:style="{width:width,background:background,padding:padding,borderRadius:radius,height:height}"
:class="[(fadein || show)?'modal-normal':'modal-scale',show?'modal-show':'']">
<view v-if="custom">
<view class="el_image">
<view class="el_close" @tap="handleClickCancel" v-if="hasClose">
<view class="title" v-if="title">{{title}}</view>
<image :src="imgUrl('close.png')"></image>
</view>
<slot></slot>
<view class="el_reminder_btn d-flex justify-content-between">
<view class="el_prompt_cancel " v-if="cancalText" @tap="()=>{$emit('cancel')}"> {{cancalText }}
</view>
<view v-if="confirmText" class="el_prompt_cirfrom bg-color-primary text-color-white"
@tap="()=>{$emit('cirfrom')}">
{{confirmText}}
</view>
</view>
<slot name="footer"></slot>
</view>
</view>
<view v-else>
<view class="modal-title" v-if="title">{{title}}</view>
<view class="modal-content" :class="[title?'':'mtop']" :style="{color:color,fontSize:size+'rpx'}">
<slot></slot>
</view>
<view class="modalBtn-box" :class="[button.length!=2?'flex-column':'']">
<block v-for="(item,index) in button" :key="index">
<button class="modal-btn" :class="[
''+(item.type || 'primary')+(item.plain?'-outline':''),
button.length!=2?'btn-width':'',
button.length>2?'mbtm':'',
shape=='circle'?'circle-btn':'',
'btn-' + (item.size || 'default'),
]" :hover-class="''+(item.plain?'outline':(item.type || 'primary'))+'-hover'" :data-index="index"
@tap="handleClick">{{item.text || "确定"}}</button>
</block>
</view>
</view>
</view>
<view class="modal-mask" :class="[show?'mask-show':'']" @tap="handleClickCancel"></view>
</view>
</template>
<script>
import {
imgUrl
} from '@/common/util.js';
export default {
name: "Modal",
props: {
//是否显示
show: {
type: Boolean,
default: false
},
//自定义modal体
custom: {
type: Boolean,
default: false
},
height: {
type: String,
default: 'auto'
},
width: {
type: String,
default: "84%"
},
background: {
type: String,
default: '#fff'
},
padding: {
type: String,
default: "40rpx"
},
radius: {
type: String,
default: "24rpx"
},
//标题
title: {
type: String,
default: ""
},
//内容
content: {
type: String,
default: ""
},
//内容字体颜色
color: {
type: String,
default: "#999"
},
//内容字体大小 rpx
size: {
type: Number,
default: 28
},
//形状 circle, square
shape: {
type: String,
default: 'square'
},
cancalText: {
type: String,
default: ''
},
confirmText: {
type: String,
default: ''
},
hasClose: {
type: Boolean,
default: true
},
button: {
type: Array,
default: function() {
return [{
text: "取消",
type: "red",
plain: true //是否空心
}, {
text: "确定",
type: "red",
plain: false
}]
}
},
//点击遮罩 是否可关闭
maskClosable: {
type: Boolean,
default: true
},
//淡入效果,自定义弹框插入input输入框时传true
fadein: {
type: Boolean,
default: false
}
},
data() {
return {
};
},
methods: {
imgUrl,
handleClick(e) {
if (!this.show) return;
const dataset = e.currentTarget.dataset;
this.$emit('click', {
index: Number(dataset.index)
});
},
handleClickCancel() {
if (!this.maskClosable) return;
this.$emit('cancel');
}
}
}
</script>
<style lang="scss">
.modal-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.6);
z-index: 10005;
transition: all 0.3s ease-in-out;
visibility: hidden;
}
.modal-box {
position: fixed;
left: 50%;
top: 50%;
margin: auto;
background: #fff;
z-index: 10006;
transition: all 0.3s ease-in-out;
box-sizing: border-box;
visibility: hidden;
}
.mask-show {
visibility: visible;
}
.modal-scale {
transform: translate(-50%, -50%) scale(0);
}
.modal-normal {
transform: translate(-50%, -50%) scale(1);
}
.modal-show {
opacity: 1;
visibility: visible;
}
.modal-title {
text-align: center;
font-size: 34rpx;
color: #333;
padding-top: 20rpx;
font-weight: bold;
}
.modal-content {
color: #999;
font-size: 28rpx;
padding-top: 20rpx;
padding-bottom: 60rpx;
}
.mtop {
margin-top: 30rpx;
}
.mbtm {
margin-bottom: 30rpx;
}
.modalBtn-box {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between
}
.flex-column {
flex-direction: column;
}
.modal-btn {
width: 46%;
height: 68rpx;
line-height: 68rpx;
position: relative;
border-radius: 60rpx;
font-size: 28rpx;
overflow: visible;
margin-left: 0;
margin-right: 0;
&.btn-default {
font-size: 28rpx;
}
&.btn-lg {
font-size: 32rpx;
}
&.btn-sm {
font-size: 24rpx;
}
}
.modal-btn::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);
left: 0;
top: 0;
border-radius: 60rpx;
}
.btn-width {
width: 80% !important;
}
.primary {
background: #97AF13;
color: #fff;
}
.primary-hover {
background: #97AF13;
color: #e5e5e5;
}
.primary-outline {
color: #97AF13;
background: none;
}
.primary-outline::after {
border: 1px solid #97AF13;
}
.danger {
background: #ed3f14;
color: #fff;
}
.danger-hover {
background: #d53912;
color: #e5e5e5;
}
.danger-outline {
color: #ed3f14;
background: none;
}
.danger-outline::after {
border: 1px solid #ed3f14;
}
.red {
background: #e41f19;
color: #fff;
}
.red-hover {
background: #c51a15;
color: #e5e5e5;
}
.red-outline {
color: #e41f19;
background: none;
}
.red-outline::after {
border: 1px solid #e41f19;
}
.warning {
background: #ff7900;
color: #fff;
}
.warning-hover {
background: #e56d00;
color: #e5e5e5;
}
.warning-outline {
color: #ff7900;
background: none;
}
.warning-outline::after {
border: 1px solid #ff7900;
}
.green {
background: #19be6b;
color: #fff;
}
.green-hover {
background: #16ab60;
color: #e5e5e5;
}
.green-outline {
color: #19be6b;
background: none;
}
.green-outline::after {
border: 1px solid #19be6b;
}
.white {
background: #fff;
color: #333;
}
.white-hover {
background: #f7f7f9;
color: #666;
}
.white-outline {
color: #333;
background: none;
}
.white-outline::after {
border: 1px solid #333;
}
.gray {
background: #ededed;
color: #999;
}
.gray-hover {
background: #d5d5d5;
color: #898989;
}
.gray-outline {
color: #999;
background: none;
}
.gray-outline::after {
border: 1px solid #999;
}
.outline-hover {
opacity: 0.6;
}
.circle-btn {
border-radius: 40rpx !important;
}
.circle-btn::after {
border-radius: 80rpx !important;
}
.el_image_cancel {
width: 32rpx;
height: 32rpx;
}
.el_close {
image {
width: 32rpx;
height: 32rpx;
}
display: flex;
justify-content: flex-end;
.title {
text-align: center;
margin: 0px auto;
}
}
.el_reminder_btn {
font-size: $font-size-base;
display: flex;
.el_prompt_cancel,
.el_prompt_cirfrom {
width: 248rpx;
height: 80rpx;
line-height: 80rpx;
color: $text-color-808080;
text-align: center;
border-radius: 42rpx;
background-color: #F0F0F0;
}
.el_prompt_cirfrom {
color: $text-color-white;
background: var(--primaryColor);
}
}
</style>
<template>
<view class="navbar">
<view v-for="(item, index) in list" :key="index" class="nav-item"
:style="{'background':background,'width':`${100/list.length}%`}"
:class="{ current: tabCurrentIndex == item.tabCurrentIndex }" @click="tabClick(index,item)">
<view>{{ item.text }}</view>
<view class="tap_tabber_right" v-if="item.topdown">
<image :src="imgUrl('i.png')" v-if="item.topdown=='0'"></image>
<image :src="imgUrl('i_up.png')" v-if="item.topdown=='1'"></image>
<image :src="imgUrl('i_down.png')" v-if="item.topdown=='2'"></image>
</view>
</view>
</view>
</template>
<script>
import { imgUrl} from '@/common/util.js';
export default {
name: "file-navList",
props: {
tabCurrentIndex: {
type: [String, Number],
default: ''
},
list: {
type: Array,
default: () => []
},
background: {
type: String,
default: '#fff'
}
},
data() {
return {
};
},
methods: {
imgUrl,
tabClick(index, item) {
this.$emit('tabClick', item.tabCurrentIndex, item)
},
}
}
</script>
<style lang="scss" scoped>
.navbar {
display: flex;
height: 80rpx;
position: relative;
z-index: 10;
overflow-x: scroll;
.nav-item {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
height: 88rpx;
font-size: $font-size-base;
color: #B3B3B3;
font-weight: 400;
font-family: PingFang SC;
position: relative;
.tap_tabber_right {
width: 20rpx;
height: 33rpx;
position: absolute;
right: 18%;
top: 50%;
transform: translate(-50%, -50%);
}
.tap_tabber_right image {
width: 100%;
height: 100%;
}
&.current {
color: #000000;
font-weight: bold;
@include BottomIine(6rpx)
}
}
}
</style>
<template>
<view>
<view v-show="ifshow" @tap="ableClose" @touchmove='true' class="popup-layer">
<view class="popup-content" :class="radius?'radius':''" @tap.stop="stopEvent" :style="_location">
<view class="d-flex justify-content-between el_wareHousecart_top ">
<view class="el_wareHousecart_title font-size-36">{{title}}</view>
<image class="el_close" :src="imgUrl('close.png')" @tap="ableClose"></image>
</view>
<slot name="content" class="popup"></slot>
</view>
</view>
</view>
</template>
<script>
import {
imgUrl
} from '@/common/util.js';
export default {
name: 'popup-layer',
model: {
prop: "showPop",
event: "change"
},
props: {
radius: {
type: Boolean,
default: false,
},
title: {
type: String,
default: ''
},
propsStyle: {
type: Object,
default: () => {}
},
showPop: {
type: Boolean,
default: false,
},
direction: {
type: String,
default: 'top', // 方向 top,bottom,left,right
},
autoClose: {
type: Boolean,
default: true,
}
},
data() {
return {
ifshow: false, // 是否展示,
//#ifdef H5
translateValue: -150, // 位移距离
//#endif
//#ifndef H5
translateValue: -100, // 位移距离
//#endif
timer: null,
iftoggle: false,
};
},
computed: {
_translate() {
const transformObj = {
'top': `transform:translateY(${-this.translateValue}%)`,
'bottom': `transform:translateY(${this.translateValue}%)`,
'left': `transform:translateX(${-this.translateValue}%)`,
'right': `transform:translateX(${this.translateValue}%)`
};
return transformObj[this.direction]
},
_location() {
let positionValue = {
//#ifndef H5
'top': 'bottom:0px;width:100%;',
//#endif
//#ifdef H5
'top': 'bottom:0px;width:100%;',
//#endif
'bottom': 'top:0px;width:100%;',
'left': 'right:0px;height:100%;',
'right': 'left:0px;height:100%;',
};
positionValue = Object.assign({}, positionValue, this.propsStyle)
return positionValue[this.direction] + this._translate;
}
},
mounted() {
// if(this.showPop){
// this.show();
// }
},
watch: {
showPop(value, old) {
if (value) {
this.show();
} else {
this.close();
}
}
},
methods: {
imgUrl,
stopMove(event) {
return;
},
show(events) {
this.ifshow = true;
let _open = setTimeout(() => {
this.translateValue = 0;
_open = null;
}, 100)
let _toggle = setTimeout(() => {
this.iftoggle = true;
_toggle = null;
}, 300);
},
close() {
if (this.timer !== null || !this.iftoggle) {
return;
}
this.translateValue = -100;
//#ifdef H5
this.translateValue = -150
//#endif
this.timer = setTimeout(() => {
this.ifshow = false;
this.timer = null;
this.iftoggle = false;
this.$emit('closeCallBack', null);
this.$emit('change', false)
}, 300);
},
ableClose() {
if (this.autoClose) {
this.close();
}
},
stopEvent(event) {},
doSome() {}
}
}
</script>
<style lang="scss">
.popup-layer {
position: fixed;
z-index: 9990;
background: rgba(0, 0, 0, .3);
height: 100%;
width: 100%;
top: 0px;
left: 0px;
overflow: hidden;
}
.popup-content {
.el_wareHousecart_top {
padding: 48rpx;
background: #F5F5F5;
.el_wareHousecart_title {
color: #000000;
font-weight: 800;
}
.el_close {
width: 32rpx;
height: 32rpx;
}
}
position: fixed;
z-index: 10000;
background: #FFFFFF;
overflow: hidden;
left: 0rpx;
box-sizing: border-box;
transition: all .3s ease;
// border:1px solid red;
}
.radius {
border-radius: 32rpx 32rpx 0rpx 0rpx;
}
</style>
<template>
<file-popup-layer :showPop="AgentVisible" radius :title="title" @closeCallBack="closeCallBack">
<view class="el_Agent_popup" slot="content">
<view class="el_Agent_popup_content d-flex">
<button class="el_Agent_popup_content_item" hover-class="hover" @tap="InvitePoster(e,i)" :open-type="i==0?'share':''" v-for="e,i in list">
<image :src="e.image" mode="aspectFit"></image>
<view>{{e.name}}</view>
</button>
</view>
<view class="text-color-primary font-size-lg font-weight-bold el_Agent_popup_cancel"
@tap="closeCallBack">取消</view>
</view>
</file-popup-layer>
</template>
<script>
export default{
name: 'file-popup-share',
props:{
good:{
type:Object,
default:()=>{},
},
AgentVisible:{
type:Boolean,
default:false,
},
title:{
type:String,
default:'',
},
list:{
type:Array,
default:()=>[]
}
},
data(){
return {}
},
methods:{
closeCallBack(){
this.$emit('closeCallBack')
},
InvitePoster(e,i){
this.$emit('closeCallBack')
if(i==0){
return
}
this.$emit('InvitePoster',e,i)
}
}
}
</script>
<style lang="scss" scoped>
.el_Agent_popup {
padding: 0rpx 24rpx;
background-color: #F5F5F5;
padding-bottom: 100rpx;
}
.hover{
background-color: transparent;
}
.el_Agent_popup_content {
background-color: $bg-color-white;
border-radius: $border-radius-base;
margin-bottom: 24rpx;
height: 194rpx;
padding: 30rpx 74rpx 28rpx 74rpx;
}
.el_Agent_popup_content_item {
text-align: center;
margin-right: 80rpx;
image {
width: 80rpx;
height: 80rpx;
margin-bottom: 16rpx;
}
view {
font-size: $font-size-base;
font-family: PingFang SC;
@include fontweight(400);
color: $text-color-808080;
}
}
.el_Agent_popup_cancel {
background-color: $bg-color-white;
border-radius: $border-radius-base;
height: 88rpx;
display: flex;
align-items: center;
justify-content: center;
}
</style>
<template>
<view class="l-painter" v-if="posterPoP" :style="globalColor.primaryColor">
<view class="d-flex just-content-center painter-box">
<l-painter ref="painter" :board="base" width="618rpx" height="900rpx" pixel-ratio="2" @success="drawDone"
isCanvasToTempFilePath customStyle="border-raduis:32rpx;width:622rpx" isH5PathToBase64 isRenderImage
/>
</view>
<view class="save fixed-bottom" @tap="saveImage">保存海报</view>
<view class="modal-mask" :class="[posterPoP ? 'mask-show' : '']" @tap="handleClickCancel"></view>
</view>
</template>
<script>
// import limePainter from './lime-painter/index'
import {
mapState
} from 'vuex';
export default {
...mapState(['globalColor']),
props: {
posterPoP: {
type: Boolean,
default: false
}
},
data() {
return {
path: '',
base: {},
sence: '',
timeOut: null,
count: 0,
canvasWidth: 0,
canvasHeight: 0,
isLongPress: false,
qrcodePosition: {}
};
},
methods: {
getCanvasSize() {
const that = this;
wx.createSelectorQuery().select('l-painter72').boundingClientRect(function(rect) {
that.canvasWidth = rect.width;
that.canvasHeight = rect.height
}).exec();
},
bindEvents() {
const that = this;
const canvas = document.getElementById('l-painter72');
canvas.addEventListener('touchstart', function(e) {
if (!that.isLongPress) {
that.qrcodePosition = {
x: e.touches[0].clientX - that.canvasWidth / 2,
y: e.touches[0].clientY - that.canvasHeight / 2
}
}
});
canvas.addEventListener('touchend', function(e) {
if (!that.isLongPress) {
const distance = Math.sqrt(Math.pow(e.changedTouches[0].clientX - that.canvasWidth / 2 -
that.qrcodePosition.x, 2) + Math.pow(e.changedTouches[0].clientY - that
.canvasHeight / 2 - that.qrcodePosition.y, 2));
if (distance > 50) {
that.isLongPress = true;
setTimeout(function() {
that.isLongPress = false;
}, 1000);
} else {
that.isLongPress = false;
}
}
});
},
posterFun(good) {
console.log(good)
let slef = this;
let price = 0;
let name = '';
let Img = '';
let smarketPrice = 0;
if (slef.sence == 'groupbooking') {
price = good.grouponPrice;
name = good.grouponName;
Img = good.grouponImg;
smarketPrice = good.salePrice;
} else {
price = good.salePrice;
name = good.productName;
Img = good.productImg;
smarketPrice = good.smarketPrice;
}
let productTags = []
if (good.tagName) {
productTags = good.tagName.split(',');
if (productTags.length > 0) {
productTags = productTags.map((item, index) => {
return {
css: {
display: 'inline-block',
borderRadius: '4rpx',
marginRight: "10rpx",
fontSize: '22rpx',
color: "#90733E"
},
type: 'text',
text: `${item}`,
}
});
} else {
productTags = [];
}
}
let smarketPriceObj = smarketPrice > price ? {
type: 'text',
text: `¥${(smarketPrice || 0).toFixed(2)}`,
css: {
marginLeft: "10rpx",
fontSize: '28rpx',
color: '#9e9d9d',
textDecoration: 'line-through',
display: 'inline-block;',
verticalAlign: 'middle',
}
} : {}
return {
css: {
width: '618rpx',
height: '900rpx',
position: 'relative',
overflow: 'hidden'
},
views: [{
src: '/static/images/bgIndex.png',
css: {
left: '0rpx',
top: '0rpx',
width: '618rpx',
height: '900rpx',
position: 'absolute',
overflow: 'hidden'
},
type: 'image',
},
{
type: 'image',
src: good.sceneImg,
css: {
left: '420rpx',
top: '640rpx',
width: '168rpx',
height: '168rpx',
position: 'absolute'
}
},
{
type: 'image',
src: Img,
css: {
left: '34rpx',
top: '29rpx',
width: '550.53rpx',
height: '550rpx',
objectFit: 'contain',
objectPosition: '50% 50%',
position: 'absolute'
}
},
{
type: 'view',
css: {
left: '34rpx',
top: '620rpx',
height: '287rpx',
width: '550rpx',
fontSize: '28rpx',
position: 'absolute',
dispaly: 'flex',
alginItems: 'end'
},
views: [{
views: [{
type: 'text',
text: `¥`,
css: {
fontSize: '22rpx',
color: '#E12D2D',
display: 'inline-block',
verticalAlign: 'middle',
}
},
{
type: 'text',
text: `${price}`,
css: {
fontSize: '36rpx',
color: '#E12D2D',
fontWeight: 'bolder',
display: 'inline-block',
verticalAlign: 'middle',
}
},
// {
// type: 'text',
// text: `起`,
// css: {
// fontSize: '24rpx',
// color: '#E12D2D',
// fontWeight: 'bolder',
// display: 'inline-block',
// verticalAlign: 'middle',
// marginLeft: '5rpx'
// }
// },
smarketPriceObj
]
},
{
css: {
marginTop: '4rpx'
},
views: [{
type: 'text',
text: `${name}`,
css: {
maxLines: 2,
fontWeight: 'bolder',
overflow: 'hidden',
'display': ' -webkit-box',
'text-overflow': 'ellipsis',
'overflow': 'hidden',
'-webkit-line-clamp': 1,
'-webkit-box-orient': 'vertical',
'word-break': ' break-all',
'width': '367rpx',
fontSize: '28rpx',
color: '#000',
}
}, ]
},
{
css: {
marginTop: '4rpx'
},
views: [{
type: 'text',
text: `${good.introduction}`,
css: {
maxLines: 2,
'font-size': '24rpx',
'font-weight': '300',
'display': ' -webkit-box',
'text-overflow': 'ellipsis',
'overflow': 'hidden',
'-webkit-line-clamp': 1,
'-webkit-box-orient': 'vertical',
'word-break': ' break-all',
'width': '367rpx',
fontSize: '28rpx',
color: '#9e9d9d',
}
}, ]
}, {
css: {
display: "inline-block"
},
views: productTags,
type: "view",
}
]
},
{
type: 'text',
text: '长按图片识别',
css: {
position: 'absolute',
left: '440rpx',
top: '820rpx',
fontSize: '24rpx',
color: '#9D9D9D'
}
}
]
};
},
drawDone(event) {
this.path = event
uni.hideLoading()
},
handleClickCancel() {
this.$emit('handleClickCancel');
},
changeChecked(item) {
item.selected = !item.selected;
},
wxcreateQRCode(good, sence) {
uni.showLoading({
title: '生成中...',
icon: 'loading'
});
this.sence = sence;
let {
id
} = good;
let postData = {
isLimit: 'Y',
page: `/subPackages/productdetails/productdetails?id=${id}`,
scene: 'id=' + id,
width: 96
};
this.$http.getMiniCode(postData).then(({
result,
success
}) => {
if (success) {
this.sceneImg = result;
const poster = this.posterFun({
...good,
sceneImg: this.sceneImg
}); // 处理poster数据
this.$nextTick(() => {
this.$refs.painter.render(poster)
})
}
});
},
saveImage() {
let self = this;
this.$refs.painter.canvasToTempFilePathSync({
fileType: "jpg",
pathType: 'url',
quality: 1,
success: (res) => {
console.log(res)
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success(res) {
self.$emit('handleClickCancel');
uni.showToast({
title: '已保存到相册',
icon: 'success',
duration: 2000
});
}
});
},
});
}
}
};
</script>
<style lang="scss" scoped>
.l-painter {
position: absolute;
left: 0rpx;
top: 0rpx;
height: 100%;
width: 100%;
z-index: 1000;
position: absolute;
}
.modal-show {
opacity: 1;
visibility: visible;
}
.modal-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.6);
z-index: 100;
transition: all 0.3s ease-in-out;
opacity: 1;
visibility: visible;
}
.save {
height: 88rpx;
background: var(--primaryColor);
align-items: center;
justify-content: center;
width: 100%;
display: flex;
color: #ffffff;
font-weight: bold;
font-size: $font-size-lg;
}
.painter-box {
width: 618rpx;
height: 1016rpx;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 2000;
}
.el_scroll_view {
margin-top: 46rpx;
height: 200rpx;
.el_item_image {
width: 200rpx;
height: 200rpx;
margin-right: 20rpx;
position: relative;
}
.el_checked {
width: 44rpx;
height: 44rpx;
position: absolute;
z-index: 1;
top: 16rpx;
right: 16rpx;
}
}
// ::v-deep .painter-box{
// top: 35% !important;
// }
</style>
<template>
<!--购物车-->
<view class="p-24 just-content-center el_shop" scroll-y="true">
<view v-for="(item, index) in list" class="el_shop_item d-flex" :key="item.id">
<view class="masking" v-if="(item.isOnSale == 'N' || item.stock <= 0) && !expanded"></view>
<view class="d-flex align-items-center mr-20 el_shop_checkbox h-100 just-content-center">
<view class="iconfont line-height-100 checkbox" @tap.stop="changeChecked(item)" :class="{
'checked icon-sel': item.selected,
'icon-nor': !item.selected,
}">
</view>
</view>
<view class="d-flex w-100">
<view class="mr-20 el_shop_image d-flex" @tap.stop="itemClick(item)">
<image :src="item.productImg" mode="aspectFill"></image>
</view>
<view class="el_shop_info d-flex flex-column justify-content-between">
<view class="mb-30">
<view class="mb-12 font-size-base font-PingFang-SC">{{ item.productName }}</view>
<view class="text-color-grey font-weight-normal specContent">{{
item.specContent
}}</view>
</view>
<view class="soldOut" v-if="item.isOnSale == 'N' || item.stock <= 0">已下架</view>
<view class="d-flex justify-content-between align-items-end">
<view class="text-color-rose el_price font-size-lg">{{
item.salePrice
}}</view>
<view class="el_calculate_button d-flex justify-content-between align-items-center">
<view class="el_redue" @tap.stop="reduce(item)">-</view>
<input type="text" v-model="item.count" @focus.stop="handlerItemFocus(item)"
@change.stop="changeCount($event, item, index)"
style="text-align: center; font-size: 20rpx" />
<view class="el_add" @tap.stop="add(item)">+</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import {
throttle
} from '@/common/util'
export default {
props: {
list: {
type: Array,
default: [],
},
expanded: {
type: Boolean,
default: false,
},
},
data() {
return {}
},
methods: {
//切换
changeChecked(item) {
if (item.isOnSale == 'N' || item.stock <= 0) {
return
}
this.$emit('changeChecked', item)
},
//减
reduce(item) {
if (item.count <= 0) {
uni.showToast({
title: '数量不能为0!',
})
return
}
this.$emit('reduce', item)
},
//加
add(item) {
if (item.count >= item.stock) {
uni.showToast({
title: '数量已到达当前商品最大库存!',
icon: 'none',
})
return
}
this.$emit('add', item)
},
itemClick(item) {
this.$emit('itemClick', item)
},
handlerItemFocus(item) {
item.oldCount = item.count
},
changeCount($event, item, index) {
if (item.count <= 0) {
item.count = 0
uni.showToast({
title: '数量不能为0!',
icon: 'none',
})
return
}
if (item.count >= item.stock) {
item.count = item.stock
uni.showToast({
title: '数量已到达当前商品最大库存!',
icon: 'none',
})
return
}
let diff = item.count - item.oldCount
if (diff < 0) {
this.$emit('reduce', item, Math.abs(diff))
} else {
this.$emit('add', item, diff)
}
},
},
}
</script>
<style lang="scss" scoped>
.el_shop {
// height: calc(253rpx * 3);
.iconfont {
color: var(--primaryColor);
}
.specContent {
font-size: 28rpx;
color: gray;
}
image {
width: 100%;
height: 100%;
}
.el_shop_checkbox {
image {
width: 40rpx;
height: 40rpx;
border-radius: $border-radius-circle;
}
}
.el_shop_item {
width: 100%;
// height: 238rpx;
padding: 32rpx 24rpx;
background-color: #ffffff;
border-radius: $border-radius-base;
position: relative;
.masking {
background: rgba(255, 255, 255, 0.5);
position: absolute;
left: 0rpx;
top: 0rpx;
width: 100%;
height: 100%;
}
.el_shop_image {
image {
border-radius: $border-radius-base;
overflow: hidden;
width: 176rpx;
height: 176rpx;
}
}
.el_shop_info {
width: 100%;
}
.el_price {
font-family: DIN;
font-weight: bold;
color: var(--primaryColor);
@include unit(var(--primaryColor), $font-size-20, 300);
}
.el_calculate_button {
width: 186rpx;
height: 58rpx;
border: 2rpx solid $border-color;
opacity: 1;
border-radius: 30rpx;
padding: 14rpx 20rpx;
.el_redue {
&::after {
content: ' ';
margin-left: 20rpx;
height: 30rpx;
width: 2rpx;
border-right: 2rpx solid $border-color;
}
}
.el_add {
&::before {
content: '';
height: 30rpx;
width: 2rpx;
margin-right: 20rpx;
border-left: 2rpx solid $border-color;
}
}
}
}
.soldOut {
font-size: 28rpx;
color: gray;
padding: 5rpx 10rpx;
background: #8080801f;
width: 120rpx;
}
}
</style>
<template>
<view class="top">
<view class="top_left">
<image :src="imgUrl('search.png')" class="top_img" mode="aspectFit" @tap="handleSeach"></image>
<input placeholder="搜索商品" v-model="value" class="search" :disabled="disabled" :focus="true"
placeholder-class="search_class" confirm-type="搜索"></input>
<image v-if="!disabled && value" :src="imgUrl('closesreach.png')" class="top_img_1" mode="aspectFit"
@click.stop="handleClear"> </image>
</view>
<button class="btn1" @tap="handleSeach" >搜索</button>
</view>
</template>
<script>
import { imgUrl} from '@/common/util.js';
export default {
props: {
disabled: {
type: Boolean,
default: true
},
inputvalue: {
type: [String, Number],
default: ''
}
},
data() {
return {
value: ''
}
},
watch: {
'inputvalue': {
handler(n, o) {
this.value = n
},
deep: true,
immediate: true
}
},
methods: {
imgUrl,
handleSeach() {
if(this.disabled){
return
}
this.$emit('handleSeach', this.value)
},
//清空
handleClear() {
this.value = ''
this.$emit('handleClear', this.value)
}
}
}
</script>
<style lang="scss">
.top {
background: #fff;
display: flex;
justify-content: space-between;
width: 100%;
padding: 30rpx !important;
position: relative;
box-sizing: border-box;
z-index: 10;
}
.top_left {
position: relative;
width: 534rpx;
.search {
margin-right: 20rpx;
height: 72rpx;
padding-right: 40px;
background: rgba(248, 248, 248, 1);
border-radius: 36rpx;
border: 1rpx solid rgba(238, 238, 238, 1);
padding-left: 71rpx;
box-sizing: border-box;
font-size: $font-size-sm;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
line-height: 72rpx;
color: rgba(0, 0, 0, 0.4);
}
.top_img {
width: 24rpx;
position: absolute;
top: 22rpx;
left: 30rpx;
height: 28rpx;
}
.top_img_1 {
width: 32rpx;
height: 32rpx;
position: absolute;
right: 46rpx;
top: 20rpx;
z-index: 100;
}
}
.btn1 {
width: 136rpx;
height: 72rpx;
display: flex;
justify-content: center;
align-items: center;
background: var(--primaryColor);
border-radius: 36rpx;
font-size: $font-size-sm;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: rgba(255, 255, 255, 1);
}
</style>
<template>
<view class="scroll-wrap" :style="{ zIndex: zIndex }">
<scroll-view v-if="!isShowList" class="scroll-view_hold" scroll-x="true" scroll-with-animation="true"
:scroll-left="position">
<view v-for="(item, index) in list" :key="index"
:style="choseInd == index ? getActiveStyle : getDefaultStyle" class="scroll-view-item font-size-sm"
:data-item="item" @click="onClickScrollItem(index, $event)">{{ item.cartName }}</view>
<view v-if="isUseOpenList" style="width: 62rpx; display: inline-block"></view>
</scroll-view>
<view v-if="isUseOpenList" v-show="!isShowList" class="open-list" @click="handleShowList">
<slot name="icon-unfold">
<image :src="imgUrl('navigator-1.png')"></image>
</slot>
</view>
<view v-show="isShowList" class="list-wrap bg-fff">
<slot name="open-list-tit">
<view class="flex justify-between border-bottom-solid-ccc p-0-32 font-size-sm">
<view class="text-lineheight-lg padding-lr font-size-sm">{{
openListTit
}}</view>
<view class="flex align-center text-lineheight-lg padding-lr" @click="handleShowList">
<slot name="icon-fold">
<image :src="imgUrl('navigator-1.png')"></image>
</slot>
</view>
</view>
</slot>
<view class="flex flex-wrap padding-lr padding-bottom-sm">
<view v-for="(item, index) in list" :key="index"
:style="choseInd == index ? getActiveStyle : getDefaultStyle"
class="scroll-view-item_wrap font-size-sm" :data-item="item"
@click="onClickListItem(index, $event)">{{ item.cartName }}</view>
</view>
</view>
</view>
</template>
<script>
import { imgUrl} from '@/common/util.js';
export default {
props: {
list: {
type: Array,
required: true,
default: () => [],
},
isUseOpenList: {
type: Boolean,
default: true,
},
openListTit: {
type: String,
default: '切换',
},
itemStyleDefault: {
type: Object,
default: () => ({}),
},
itemStyleActive: {
type: Object,
default: () => ({}),
},
zIndex: {
type: [String, Number],
default: 1000,
},
defaultChoseInd: {
type: Number,
default: -1,
},
defaultChoseItem: {
type: String,
default: '',
},
},
data() {
return {
scrollViewLeftArr: new Map(), // 存储scroll信息
choseInd: 0, // 当前选中
position: 0, // 滑动位置
windowWidth: 0, // 页面高度
isShowList: false, // 是否展示为列表形式
}
},
watch: {
//监听初始话列表小标为0
list: {
handler(n, o) {
// this.choseInd = 0
this.position = 0
const query = uni.createSelectorQuery().in(this)
query.selectAll('.scroll-view-item').boundingClientRect()
if (n.length > 0) {
query.exec((res) => {
res[0].forEach((element, i) => {
const item = element.dataset.item
const {
left
} = element || {}
const obj = {
name: item,
left: left,
}
this.scrollViewLeftArr.set(i, obj)
})
})
}
},
deep: true,
immediate: true,
},
defaultChoseInd: {
handler(n, o) {
let self = this
self.choseInd = n
if (self.scrollViewLeftArr.size > 0) {
const val = self.scrollViewLeftArr.get(self.choseInd)
self.position = val.left - (self.windowWidth / 2 - 30)
}
},
deep: true,
immediate: true,
},
},
computed: {
getDefaultStyle() {
const {
itemStyleDefault
} = this
let defaultStyleObj = {
color: '#393939',
background: '#f4f4f4',
}
return this.setStyle(defaultStyleObj, itemStyleDefault)
},
getActiveStyle() {
const {
itemStyleActive
} = this
let activeStyleObj = {
color: '#3555fc',
border: '1rpx solid #3555fc;',
}
return this.setStyle(activeStyleObj, itemStyleActive)
},
},
async mounted() {
const {
defaultChoseInd,
defaultChoseItem
} = this || {}
this.choseInd = defaultChoseInd
let defaultItemInd = -1
if (defaultChoseItem) {
defaultItemInd = this.list.findIndex(
(item) => item.id === defaultChoseItem.id
)
this.choseInd = defaultItemInd !== -1 ? defaultItemInd : 0
}
const [_, {
windowWidth
}] = (await uni.getSystemInfo()) || {}
this.windowWidth = windowWidth
// 获取列表每个dom的偏移量
const query = uni.createSelectorQuery().in(this)
query.selectAll('.scroll-view-item').boundingClientRect()
query.exec((res) => {
res[0].forEach((element, i) => {
const item = element.dataset.item
const {
left
} = element || {}
const obj = {
name: item,
left: left,
}
this.scrollViewLeftArr.set(i, obj)
if (i === defaultChoseInd && !defaultChoseItem) {
this.position = left - (windowWidth / 2 - 30)
}
if (i === defaultItemInd && defaultChoseItem) {
this.position = left - (windowWidth / 2 - 30)
}
})
})
},
methods: {
imgUrl,
onClickListItem(index, event) {
this.isShowList = false
const {
item
} = event.currentTarget.dataset
const val = this.scrollViewLeftArr.get(index)
this.position = val.left - (this.windowWidth / 2 - 30)
this.choseInd = index
this.$emit('onValueChange', {
currentInd: index,
currentItem: item,
})
this.$emit('onListShow', true)
},
onClickScrollItem(index, event) {
this.choseInd = index
const {
item
} = event.currentTarget.dataset
const {
offsetLeft
} = event.target
this.position = offsetLeft - (this.windowWidth / 2 - 30)
this.$emit('onValueChange', {
currentInd: index,
currentItem: item,
})
},
handleShowList() {
this.isShowList = !this.isShowList
this.$emit('onListShow', !this.isShowList)
},
setStyle(DefaultStyleObj, CurrentStyleObj) {
Object.assign(DefaultStyleObj, CurrentStyleObj)
let style = ''
Object.keys(DefaultStyleObj).forEach((e) => {
style += `${e}: ${DefaultStyleObj[e]};`
})
return style
},
},
}
</script>
<style scoped lang="scss">
.flex {
display: flex;
}
.flex-wrap {
flex-wrap: wrap;
}
.padding-bottom-sm {
padding-bottom: 20rpx;
}
.justify-between {
justify-content: space-between;
}
.align-center {
align-items: center;
}
.text-lineheight-lg {
line-height: 80rpx;
}
image {
width: 32rpx;
height: 32rpx;
}
.border-bottom-solid-ccc {
border-bottom: 1rpx solid #ccc;
}
.size-28 {
font-size: 28rpx;
}
.scroll-view_hold {
position: relative;
width: 100%;
overflow: hidden;
white-space: nowrap;
background: #fff;
}
.scroll-view_hold ::-webkit-scrollbar {
width: 0;
height: 0;
color: transparent;
}
.scroll-view-item {
min-width: 120rpx;
padding: 0 20rpx;
display: inline-block;
text-align: center;
line-height: 60rpx;
border-radius: 32rpx;
margin: 0 20rpx 0 0rpx;
}
.scroll-wrap {
position: relative;
width: 100%;
background-color: #ffffff;
padding: 15rpx;
}
.open-list {
position: absolute;
right: 0;
top: 0;
width: 60rpx;
text-align: center;
font-weight: 600;
height: 100%;
align-items: center;
display: flex;
justify-content: center;
color: #585858;
background: rgba(255, 255, 255, 0.7);
}
.scroll-view-item_wrap {
min-width: 140rpx;
text-align: center;
font-size: 25rpx;
border-radius: 32rpx;
margin: 20rpx 0 0 15rpx;
}
.icon-unfold {
width: 30rpx;
height: 60rpx;
padding: 30rpx 0 30rpx 0;
}
.icon-fold {
width: 30rpx;
height: 60rpx;
}
</style>
<template>
<view
class="tabBar"
:class="{ 'padding-bottom': isIphoneX }"
v-if="tabBar.length > 0"
>
<view
v-for="(item, index) in tabBar"
:key="index"
class="tabbar_item"
:class="{ active: (item.navUrl == currentPage && currentPage !== 'index') || (currentPage == 'index' && currentIndex==index && clickType=='switchTab')}"
@tap="navTo(item, index)"
>
<view
class="active-count"
v-if="item.navUrl == 'shopCar' && sumCartCountLength > 0"
>{{ sumCartCountLength }}
</view>
<view class="img-box">
<image
:src="item.miniPath"
mode="aspectFit"
:class="{ translateZ: isIphone }"
></image>
</view>
<view class="text">{{ item.navName }}</view>
</view>
</view>
</template>
<script>
import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'
import {isMp} from '@/common/platform.js'
export default {
props: {
currentPage: {
type: String,
default: '',
},
clickType:{
type: String,
default: 'switchTab',
},
currentIndex:{
type: String,
default: '-1',
},
tabBar: {
type: Array,
default: () => [],
},
sumCartCount: {
type: Number,
default: 0,
},
},
data() {
return {
sumCartCountLength: 0,
}
},
watch: {
tabBar: {
handler(n, o) {
this.$nextTick(() => {
let info = this.tabBar.find((item) => item.navUrl == this.currentPage)
if (info && info.navUrl !== 'home' ) {
uni.setNavigationBarTitle({ title: info ? info.navName : '' })
}
})
},
deep: true,
},
sumCartCount: function (newVal, oldVal) {
if (newVal !== undefined) {
this.sumCartCountLength = newVal
}
},
currentPage: {
handler(n, o) {
if (n !== undefined) {
this.$nextTick(() => {
let info = this.tabBar.find(
(item) => item.navUrl == this.currentPage
)
if (info && info.navUrl !== 'home' && this.isLogin) {
uni.setNavigationBarTitle({ title: info ? info.navName : '' })
}
//如果登录了且不是购物车的页面的时候调取
if (this.isLogin && n !== 'shopCar') {
//
this.getMemberCartList()
}
})
}
},
immediate: true,
deep: true,
},
},
computed: {
...mapState(['isIphoneX', 'store']),
...mapGetters(['isLogin']),
isIphone() {
let { model, platform } = uni.getSystemInfoSync()
//
//因为模拟器不兼容transform: translateZ(0); 所以不是模拟器运行且苹果数据运行的时候才添加transform: translateZ(0);
if (/iPhone/i.test(model) && platform !== 'devtools' && isMp) {
return true
} else {
return false
}
},
},
methods: {
navTo(item, index) {
this.$emit('navTo', item, index)
},
getMemberCartList() {
let data = {
shopId: this.store.shopId,
}
this.$http.getMemberCartList(data).then(({ success, result }) => {
if (success) {
this.sumCartCountLength = result.sumCount
}
})
},
},
}
</script>
<style lang="scss" scoped>
//导航栏设置
$imgHight: 45rpx;
$isRadius: 20upx; //左上右上圆角
$isWidth: 85vw; //导航栏宽度
$isBorder: 3px solid white; //边框 不需要则设为0px
$isBg: #fff; //背景
// 选中设置
$chooseTextColor: var(--primaryColor); //选中时字体颜色
$chooseBgColor: white; //选中时背景颜色 transparent为透明
//未选中设置
$normalTextColor: #999; //未选中颜色
.tabBar {
width: 100%;
box-sizing: border-box;
min-height: 100rpx;
position: fixed;
bottom: 0;
left: 0;
right: 0;
margin: 0 auto;
z-index: 10;
background-color: $isBg;
color: $normalTextColor;
border-right: $isBorder;
display: flex;
justify-content: space-around;
box-sizing: border-box;
.tabbar_item {
padding-top: 10rpx;
flex: 1;
font-size: 22rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
&.active {
background: $chooseBgColor;
color: $chooseTextColor;
image {
position: absolute;
left: -$imgHight;
top: 0rpx;
z-index: 10;
filter: drop-shadow($imgHight 0 0 $chooseTextColor);
}
}
position: relative;
.active-count {
width: 40rpx;
transform: translate(-50%, -50%);
top: 25%;
left: 62%;
height: 40rpx;
border-radius: 50%;
background-color: var(--primaryColor);
color: #ffffff;
align-items: center;
display: flex;
justify-content: center;
position: absolute;
z-index: 1000;
}
}
.img-box {
width: $imgHight;
height: $imgHight;
overflow: hidden;
position: relative;
z-index: 10;
image {
width: $imgHight;
height: $imgHight;
vertical-align: middle;
&.translateZ {
transform: translateZ(0);
}
}
}
}
</style>
<template>
<view>
<file-modal :show="group_ctrompletion" @cancel="closeCallBack('grounpVisible')" :hasClose="false"
class="el_detail-modal font-PingFang-SC" custom background="transparent">
<view class="box">
<view class="box_2 box_1">
<view>
<view class="box_1_top_1">
<image :src="imgUrl('check1.png')" mode="aspectFit"></image><text
class="box_1_top_right">拼团成功</text>
</view>
<view class="box_1_content_1">正在努力发货,请耐心等待!</view>
<view class="box_1_content_4" :style="memberInfoList.length > 0 ? 'width:80%' : ''">
<view v-for="(item, index) in memberInfoList"
style="flex:1;display:flex;justify-content: center">
<view class="box_1_content_3_item" :key="index" :style="
index == 0
? 'background:url('+imgUrl('circle1.png')+');background-size:100% 100%;'
: 'background:url('+imgUrl('circle2.png')+');background-size:100% 100%;'
">
<image :src="item.memberImg" mode="aspectFit"></image>
</view>
</view>
<view style="flex:1;display:flex;justify-content: center" v-for="item in remainNum">
<view class="box_1_content_3_item" :style="'background: url('+imgUrl('circle3.png')+');background-size: 100% 100%'">
<image :src="imgUrl('circle3.png')" mode="aspectFit"></image>
</view>
</view>
</view>
<view class="box_2_bottom">
<text @tap="toOrderList">查看订单详情>></text>
</view>
</view>
</view>
</view>
<view class="box_1_bottom_img" @tap="closeGroup">
<image :src="imgUrl('circle3.png')" mode="aspectFit"></image>
</view>
</file-modal>
</view>
</template>
<script>
import {
imgUrl
} from '@/common/util.js';
export default {
data() {
return {
group_ctrompletion: false,
memberInfoList: [],
remainNum: 0,
}
},
methods: {
imgUrl,
closeGroup() {
this.$emit('close')
this.group_ctrompletion = false
},
toOrderList() {
this.$emit('toOrderList')
},
},
}
</script>
<style lang="less" scoped="scoped">
.box_1 {
text-align: center;
padding: 50rpx 77rpx;
box-sizing: border-box;
height: 516rpx;
background: #fff;
border-radius: 30rpx;
margin-bottom: 30rpx;
.box_2 {
height: 446rpx !important;
}
.box_2_bottom {
color: var(--primaryColor);
}
.comirm {
width: 377rpx;
height: 90rpx;
border-radius: 50rpx;
color: #fff;
border: 3rpx solid #fff;
text-align: center;
line-height: 90rpx;
margin: 0rpx auto;
margin-top: 32rpx;
}
.competition {
height: 40rpx;
font-size: 28rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: rgba(0, 0, 0, 0.4);
text-align: center;
line-height: 40rpx;
}
.pingtuan {
height: 116rpx;
display: flex;
justify-content: space-between;
margin-top: 33rpx;
margin-bottom: 54rpx;
}
.pingtuan_item {
width: 116rpx;
height: 116rpx;
}
.pingtuan_item image {
width: 100%;
height: 100%;
}
.daoji {
font-size: 36rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
display: flex;
margin: 0rpx auto;
padding: 0rpx 47rpx;
box-sizing: border-box;
}
.shop_name {
font-size: 28rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
margin-top: 5rpx;
color: rgba(0, 0, 0, 0.4);
}
.daoji text:nth-of-type(1) {
padding-bottom: 5rpx;
margin-right: 5rpx;
box-sizing: border-box;
font-size: 36rpx;
display: inline-block;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
height: 59rpx;
line-height: 59rpx;
color: rgba(0, 0, 0, 0.8);
display: block;
}
.daoji text:nth-of-type(2) {
height: 59rpx;
font-size: 42rpx;
display: block;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: rgba(0, 0, 0, 0.8);
line-height: 59rpx;
}
.suoming {
margin-top: 44rpx;
height: 40rpx;
font-size: 28rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: rgba(0, 0, 0, 0.4);
line-height: 40rpx;
}
.box_1_content_1 {
font-size: 28rpx;
margin-top: 39rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: rgba(0, 0, 0, 0.4);
}
.box_1_content_2_left {
font-size: 36rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: rgba(0, 0, 0, 0.8);
margin-top: 20rpx;
display: block;
}
.box_1_content_2 {
display: flex;
padding: 0rpx 30rpx;
box-sizing: border-box;
}
.box_1_content_2_right {
font-size: 42rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: rgba(0, 0, 0, 0.8);
margin-top: 18rpx;
margin-left: 20rpx;
display: block;
}
.box_1_content_image {
width: 100rpx;
height: 100rpx;
margin: 0rpx auto;
}
.box_1_content_image image {
width: 100%;
height: 100%;
}
.box_1_content_3 {
display: flex;
justify-content: space-between;
padding: 0rpx 56rpx;
margin-top: 32rpx;
margin-bottom: 30rpx;
}
.box_1_content_text {
font-size: 24rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: rgba(0, 0, 0, 0.6);
margin-top: 12rpx;
text-align: center;
}
.box_1_top {
display: flex;
padding: 0rpx 138rpx;
}
.box_1_top image {
display: block;
margin-right: 8rpx;
}
.box_1_top_1 {
display: flex;
justify-content: space-between;
margin: 0rpx auto;
width: 45%;
}
.box_1_top_right {
display: block;
vertical-align: middle;
}
.box_1_top_1 image {
width: 30rpx;
height: 30rpx;
margin-right: 10rpx;
margin-top: 6rpx;
}
.box_1_bottom image:nth-of-type(1),
.box_1_bottom image:nth-of-type(2) {
width: 28rpx;
height: 12rpx;
}
.box_1_bottom text {
font-size: 24rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: rgba(0, 0, 0, 0.6);
margin-right: 10rpx;
margin-left: 10rpx;
}
.box_1_content_3_item {
width: 100rpx;
height: 100rpx;
overflow: hidden;
border-radius: 50%;
padding: 10rpx;
image {
overflow: hidden;
border-radius: 50%;
}
}
.box_1_content_3_item image {
width: 100%;
height: 100%;
}
.box_1_content_4 {
display: flex;
justify-content: space-between;
margin-top: 80rpx;
margin-bottom: 80rpx;
}
.box_1_image image {
width: 120rpx;
height: 120rpx;
margin: 0rpx auto;
margin-top: 20rpx;
margin-bottom: 73rpx;
}
}
.box_1_bottom_img {
text-align: center;
image {
width: 95rpx;
height: 95rpx;
}
}
</style>
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment