diff --git a/pageQuota/vipUser/1.vue b/pageQuota/vipUser/1.vue new file mode 100644 index 0000000..5e7f340 --- /dev/null +++ b/pageQuota/vipUser/1.vue @@ -0,0 +1,813 @@ +<template> + <view class="" v-if="!STORE_INFO.id"> + <up-modal :show="showModa" title="登录门店" @confirm="confirmStore" confirmColor='#20B128'> + <view class="slot-content"> + <up-form labelPosition="left" label-width="100rpx"> + <up-form-item label="手机号" borderBottom> + <up-input v-model="storePhone" placeholder="请输入门店手机号"></up-input> + </up-form-item> + <!-- <up-form-item label="角色" borderBottom> + <uni-data-select v-model="Role" :localdata="range" :clear='false'></uni-data-select> + </up-form-item> --> + </up-form> + </view> + </up-modal> + </view> + + <view v-else> + <view class="tabs"> + <text @click="currentTab = 1" :class="{ actText: currentTab == 1 }">开通{{ Role == 1 ? '行业会员' : '商户' }} + </text> + <text @click="currentTab = 2, getCount(), getLists()" :class="{ actText: currentTab == 2 }"> 已开通列表</text> + <view class="lines" :class="{ actLine: currentTab == 2 }" /> + </view> + <!-- tabs1 --> + <block v-if='currentTab == 1'> + <view class="card card1"> + <view class="card1-tit"> + {{ Role == 1 ? '行业会员' : '商户' }}开通报备 + <up-input v-model='formData.auth_code'> </up-input> + </view> + <up-form labelPosition="left" :model="formData" :borderBottom='false'> + <up-form-item label=""> + <up-input v-model="formData.real_name" border="none" prefixIcon="account" placeholder="请输入真实姓名" + :customStyle="{ background: '#F3F3F3', padding: '20rpx', 'border-radius': '30rpx' }" + :placeholderStyle="{ color: '#444444' }" + :prefixIconStyle="{ 'margin-right': '40rpx' }"></up-input> + </up-form-item> + <up-form-item label=""> + <up-input v-model="formData.mobile" border="none" prefixIcon="phone" placeholder="请输入电话号码" + :customStyle="{ background: '#F3F3F3', padding: '20rpx', 'border-radius': '30rpx' }" + :placeholderStyle="{ color: '#444444' }" + :prefixIconStyle="{ 'margin-right': '40rpx' }"></up-input> + </up-form-item> + <up-form-item label=""> + <view @click="showPop = true" style="width: 100%;"> + <up-input style="pointer-events: none" v-model="formData.address" border="none" + prefixIcon="map" readonly placeholder="点击选择地址" :customStyle="{ + background: '#F3F3F3', padding: '20rpx', + 'border-radius': '30rpx' + }" :placeholderStyle="{ color: '#444444' }" :prefixIconStyle="{ 'margin-right': '40rpx' }" + suffixIcon='arrow-down'></up-input> + </view> + </up-form-item> + <up-form-item label="" v-if='Role == 1'> + <view @click="showPop1 = true" style="width: 100%;"> + <up-input style="pointer-events: none" v-model="formData.label_name" border="none" + prefixIcon="man-add" readonly placeholder="点击选择用户身份" :customStyle="{ + background: '#F3F3F3', padding: '20rpx', + 'border-radius': '30rpx' + }" :placeholderStyle="{ color: '#444444' }" :prefixIconStyle="{ 'margin-right': '40rpx' }" + suffixIcon='arrow-down'></up-input> + </view> + </up-form-item> + <!-- <up-form-item label="" v-if='Role == 1'> + <view style="width: 100%;"> + <up-input v-model="formData.price" border="none" prefixIcon="rmb-circle" placeholder="请输入金额" + :customStyle="{ + background: '#F3F3F3', padding: '20rpx', + 'border-radius': '30rpx' + }" :placeholderStyle="{ color: '#444444' }" :prefixIconStyle="{ 'margin-right': '40rpx' }"></up-input> + </view> + </up-form-item> --> + <up-form-item label=""> + <view style="width: 100%;display: flex;align-items: center;justify-content: space-between;"> + <view class=""> + <up-input v-model="formData.code" border="none" prefixIcon="tags" placeholder="请输入验证码" + :customStyle="{ + background: '#F3F3F3', padding: '20rpx', + 'border-radius': '30rpx' + }" :placeholderStyle="{ color: '#444444' }" :prefixIconStyle="{ 'margin-right': '40rpx' }"></up-input> + </view> + <text class='btn-text' style="color: grey;" v-if='cutDown'>重新获取({{ cutDown }})</text> + <text @click="getCode" class='btn-text' v-else> {{ flag ? '获取验证码' : '重新获取' }} </text> + </view> + </up-form-item> + </up-form> + <view class="store-info"> + 报备人:{{ STORE_INFO.name }} + </view> + + <view class="store-info" v-if="Role==1"> + <view class="" style="width: 300rpx;margin: 0 auto;border-bottom: 1px solid #F3F3F3;"> + <up-input inputAlign='center' placeholder="请输入金额" @focus="formData.price=''" color='#FF6B00' + :placeholderStyle="{fontSize:'28rpx'}" fontSize='20px' border="none" + v-model="formData.price" @blur='tofixedPrice'></up-input> + </view> + <view style="color: red;margin-top: 20rpx;font-size: 24rpx;" + v-if="formData.label_limit&&formData.price<formData.label_limit"> + {{formData.label_name}}角色最低金额不能低于{{formData.label_limit}}元 + </view> + + </view> + <button @click="test">anniu</button> + </view> + <view class="submit-btn" @click="submit"> + <view + style='width: 710rpx;height: 100rpx;text-align: center;line-height: 100rpx;text-align: center;color: white;background-color: #33B83A;border-radius: 50rpx;font-size:40rpx ;'> + {{ Role == 1 ? '完成并收款' : '完成' }} + </view> + </view> + </block> + + <!-- tabs2 --> + <block v-else> + <view class="vip-card"> + <text>当前已开通:</text> + <up-count-to :startVal="0" :endVal="count"></up-count-to> + <text>位{{ Role == 1 ? '行业会员' : '商户' }}</text> + </view> + + <view class="table"> + <uni-table stripe emptyText="暂无更多数据" width="100%"> + <!-- 表头行 --> + <uni-tr> + <uni-th width="20" align="center">序号</uni-th> + <uni-th width="50" align="center" v-if='Role == 1'>行业会员</uni-th> + <uni-th width="50" align="center" v-if='Role == 1'>经营资金</uni-th> + <uni-th width="50" align="center" v-if='Role == 4'>开通时间</uni-th> + <uni-th width="50" align="center" v-if='Role == 4'>商户</uni-th> + <uni-th width="50" align="center" v-if='Role == 1'>角色</uni-th> + <uni-th width="50" align="center">状态</uni-th> + </uni-tr> + <!-- 表格数据行 --> + <uni-tr v-for="(item, index) in lists" :key="item.order_id"> + <uni-td align="center">{{index+1}}</uni-td> + <uni-td style="font-size: 20rpx;" align="center" v-if='Role == 1'>{{ item.real_name }}</uni-td> + <uni-td style="font-size: 20rpx;" align="center" v-if='Role == 1'>{{ item.price }}</uni-td> + <uni-td style="font-size: 20rpx;" align="center" + v-if='Role == 4'>{{ item.create_time }}</uni-td> + <uni-td style="font-size: 20rpx;" align="center" v-if='Role == 4'>{{ item.nickname }}</uni-td> + <uni-td style="font-size: 20rpx;" align="center" v-if='Role == 1'>{{ item.label_name }}</uni-td> + <uni-td style="font-size: 20rpx;" align="center"> + <view v-if="item.paid == 1 || Role == 4">已开通</view> + <view v-else style="color:#33B83A ;"> + <view @click="upadtaStatus(item)"> + 未开通,查询 + </view> + <view @click="rePay(item)"> + 重新支付 + </view> + </view> + </uni-td> + </uni-tr> + </uni-table> + </view> + </block> + </view> + <view style="height: 50rpx;" /> + + <!-- 地址选择器 --> + <up-popup :show="showPop" @close="showPop = false" @open="showPop = true" :round="10"> + <view style="padding: 20rpx;"> + <up-tabs :list="tabsList" @change='addressTbasChange' :current='currentAddressIndex' lineColor='#20B128' + :activeStyle="{ color: '#20B128' }"></up-tabs> + <up-line style="margin-top:20rpx "></up-line> + <view class="address-content" v-if='currentAddressIndex == 0'> + <view class="address-li" :class='{ act: item.city_code == formData.city }' + v-for="item in addressList.city" :key="item.city_code" @click="addressLiClick(0, item)"> + <text>{{ item.city_name }}</text> + <up-icon name="arrow-right" :color="item.city_code == formData.city ? '#20B128' : '#777777'" /> + </view> + </view> + <view class="address-content" v-else-if='currentAddressIndex == 1'> + <view class="address-li" v-for="item in addressList.area" @click="addressLiClick(1, item)" + :key="item.area_code" :class='{ act: item.area_code == formData.area }'> + <text>{{ item.area_name }}</text> + <up-icon name="arrow-right" :color="item.area_code == formData.area ? '#20B128' : '#777777'" /> + </view> + </view> + <view class="address-content" v-else-if='currentAddressIndex == 2'> + <view class="address-li" v-for="item in addressList.street" @click="addressLiClick(2, item)" + :key="item.street_code" :class='{ act: item.street_code == formData.street }'> + <text>{{ item.street_name }}</text> + <up-icon name="arrow-right" :color="item.street_code == formData.street ? '#20B128' : '#777777'" /> + </view> + </view> + <view class="address-content" v-else-if='currentAddressIndex == 3'> + <view class="address-li" v-for="item in addressList.village" @click="addressLiClick(3, item)" + :key="item.village_code" :class='{ act: item.village_code == formData.village }'> + <text>{{ item.village_name }}</text> + <up-icon name="arrow-right" + :color="item.village_code == formData.village ? '#20B128' : '#777777'" /> + </view> + </view> + <view class="address-content" v-else-if='currentAddressIndex == 4'> + <view class="address-li" :class='{ act: item.id == formData.brigade }' + v-for="item in addressList.brigade" :key="item.id" @click="addressLiClick(4, item)"> + <text>{{ item.brigade_name }}</text> + <up-icon name="arrow-right" :color="item.id == formData.brigade ? '#20B128' : '#777777'" /> + </view> + </view> + </view> + </up-popup> + <up-picker :show="showPop1" :columns="columns" @confirm='conformRole' @cancel='showPop1 = false' + @close="showPop1 = false" @open="showPop1 = true" keyName='label_name' confirmColor='#33B83A'></up-picker> +</template> +<script setup> + import { + reactive, + ref + } from 'vue'; + import useUserStore from "@/store/user"; + import { + provinceListApi, + cityListApi, + areaListApi, + streetListApi, + villageListApi, + brigadeListApi + } from "@/api/address.js" + import { + vipRechargeApi, + rechargeCountApi, + reVipRechargeApi, + rechargeListsApi, + updataOrderApi, + getStoreByPhone, + getUserLabel, + getUserShip, + getCreateLists, + getReportingSms + } from "@/api/user.js" + import Push from "@/utils/push.js" + import { + onPullDownRefresh, + onLoad, + onReachBottom + } from "@dcloudio/uni-app" + import { + config + } from "@/config/app.js" + + const showPop1 = ref(false) + const Role = ref(1) + const range = ref({}) + const columns = ref([]) + const showModa = ref(true) + const storePhone = ref('') + const confirmStore = () => { + getStoreByPhone({ + phone: storePhone.value + }).then(res => { + for (let key in res.data) { + STORE_INFO[key] = res.data[key] + } + setPhoneOneDay() + }).catch(err => { + uni.$u.toast('未查到店铺信息,请检查手机号码') + }) + } + // 用户选择的门店信息 + let STORE_INFO = reactive({ + id: "" + }) + + + // 门店手机号保留一天 + const setPhoneOneDay = () => { + if (uni.getStorageSync('VIP_PHONE')) return; + const currentDate = new Date(); + const nextDay = new Date(currentDate); + nextDay.setDate(currentDate.getDate() + 1); + uni.setStorageSync('VIP_PHONE', JSON.stringify({ + time: nextDay, + phone: storePhone.value + })); + } + const getPhoneOneDay = () => { + if (uni.getStorageSync('VIP_PHONE')) { + let data = JSON.parse(uni.getStorageSync('VIP_PHONE')) + if (new Date() > data.time) { + uni.removeStorageSync('VIP_PHONE'); + } else { + storePhone.value = data.phone + } + } + } + // 手机保留一天结束 + + // 验证码 + const cutDown = ref(0) + const flag = ref(true) + const code = ref('') + const checkPhone = (phone) => { + const regex = /^1[3-9]\d{9}$/; + return regex.test(formData.mobile) ? true : false + } + + const getCode = async () => { + if (!checkPhone(formData.mobile)) return uni.$u.toast('请输入正确的手机号') + await getReportingSms({ + account: formData.mobile + }) + flag.value = false + cutDown.value = 60 + let timer = setInterval(() => { + cutDown.value-- + if (cutDown.value <= 0) { + cutDown.value = 0; + clearInterval(timer); + } + }, 1000) + } + // 验证码结束 + + + const currentTab = ref(1) + const formData = reactive({ + // store_id: STORE_INFO.id, + // mobile: "", + // province: 510000, + // city: '', + // area: "", + // street: "", + // village: "", + // real_name: "", + // auth_code: "", + // address: "", + // label_name: "", + // label_id: "", + // label_limit: "", + // user_ship: '', + // code: '', + // brigade: "", + // price: "", + store_id: STORE_INFO.id, + mobile: "19130550023", + province: 510000, + city: '510500', + area: "510503", + street: "510503102", + village: "510503102201", + real_name: "赵明军", + auth_code: "131197337173621549", + address: "", + label_name: "", + label_id: "4", + user_ship: '1', + code: '' + }) + + const tofixedPrice = () => { + formData.price = (+formData.price).toFixed(2) + } + + const resetFormData = () => { + for (let key in formData) { + formData[key] = '' + } + tabsList.forEach(item => { + item.name = '请选择' + }) + formData.province = 510000 + cutDown.value = 0 + currentAddressIndex.value = 0 + } + + const conformRole = (e) => { + formData.label_name = e.value[0].label_name + formData.label_id = e.value[0].label_id + formData.price = (+e.value[0].limit).toFixed(2) + formData.label_limit = e.value[0].limit + showPop1.value = false + } + + + // 地址选择 + const showPop = ref(false) + const currentAddressIndex = ref(0) + const currentAddressList = () => { + if (!formData.city) return [0, 'city']; + else if (formData.area) return [1, 'area']; + else if (formData.street) return [2, 'street']; + else if (formData.village) return [3, 'village']; + else if (formData.brigade) return [4, 'brigade']; + } + const addressTbasChange = (e) => { + currentAddressIndex.value = e.index + } + const addressList = reactive({ + city: [], + area: [], + street: [], + village: [], + brigade: [] + }) + const addressLiClick = async (i, item) => { + if (i == 0) { + formData.city = item.city_code + tabsList[0].name = item.city_name + let res = await areaListApi({ + city_code: formData.city + }) + addressList.area = res.data + } + if (i == 1) { + formData.area = item.area_code + tabsList[1].name = item.area_name + let res = await streetListApi({ + area_code: formData.area + }) + addressList.street = res.data + } + + if (i == 2) { + formData.street = item.street_code + tabsList[2].name = item.street_name + let res = await villageListApi({ + street_code: formData.street + }) + addressList.village = res.data + } + if (i == 3) { + formData.village = item.village_code + tabsList[3].name = item.village_name + let res = await brigadeListApi({ + village_code: formData.village + }) + addressList.brigade = res.data + } + if (i == 4) { + formData.brigade = item.id + tabsList[4].name = item.brigade_name + + formData.address = tabsList[0].name + tabsList[1].name + tabsList[2].name + tabsList[3].name + + tabsList[4].name + return showPop.value = false + } + formData.address = tabsList[0].name + tabsList[1].name + tabsList[2].name + tabsList[3].name + tabsList[4] + .name + return currentAddressIndex.value++ + } + const getCityList = async () => { + let res = await cityListApi({ + province_code: formData.province + }) + addressList.city = res.data + } + const tabsList = reactive( + [{ + name: "请选择" + }, + { + name: '请选择', + disabled: false + }, + { + name: '请选择', + disabled: false + }, + { + name: '请选择', + disabled: false + }, + { + name: '请选择', + disabled: false + }, + ]); + + + + let timerInvol = null + // 开起一个scoket监听用户知否支付成功 + const userInfo = useUserStore().userInfo; + const connection = new Push({ + url: config.WSS_URL, // websocket地址 + app_key: '2ce3ce22329517213caa7dad261f5695', + }); + const user_channel = connection.subscribe(`wechat_mmp_${userInfo.id}`); + user_channel.on('message', function(data) { + console.log(111111, timerInvol) + clearTimeout(timerInvol); + test() + console.log(222222, timerInvol) + // setImmediate() + paySuccessToTabs2() + }); + // 结束 + const test = () => { + console.log(33333, timerInvol) + clearTimeout(timerInvol) + console.log(44444, timerInvol) + } + + // 提交 + const submit = async () => { + if (!formData.real_name) return uni.$u.toast('请填写真实姓名'); + if (!formData.mobile) return uni.$u.toast('请填写电话号码'); + if (!formData.code) return uni.$u.toast('请输入短信验证码'); + // if (!formData.address) return uni.$u.toast('请选择地址'); + // if (!formData.label_id) return uni.$u.toast('请选择用户身份'); + if (formData.price < formData.label_limit) return uni.$u.toast( + `${formData.label_name}角色最低金额不能低于${formData.label_limit}元`); + formData.store_id = STORE_INFO.id + if (Role.value == 1) { + formData.recharge_type = 'INDUSTRYMEMBERS' + formData.user_ship = 1 + vipRechargeApi(formData).then(res => { + timerInvol = setTimeout(() => { + uni.hideLoading(); + uni.$u.toast('支付超时'); + console.log("支付超时") + }, 20000) + + }) + return + uni.scanCode({ + success: function(res) { + if (String(res.result.length) != 18) return uni.$u.toast('二维码未扫描完整'); + uni.showLoading({ + title: '支付中...' + }); + formData.auth_code = res.result + formData.recharge_type = 'INDUSTRYMEMBERS' + formData.user_ship = 1 + vipRechargeApi(formData).then(res => { + timerInvol = setTimeout(() => { + uni.hideLoading(); + uni.$u.toast('支付超时'); + console.log("支付超时") + }, 10000) + }) + + } + }); + } + } + + const rePay = (item) => { + uni.scanCode({ + success: function(res) { + if (String(res.result.length) != 18) return uni.$u.toast('二维码未扫描完整'); + uni.showLoading({ + title: '等待用户支付' + }); + reVipRechargeApi({ + id: item.id, + auth_code: res.result + }).then(res => { + timerInvol = setTimeout(() => { + uni.hideLoading(); + uni.$u.toast('支付超时'); + console.log("支付超时") + }, 30000) + }) + } + }); + } + + // 支付成功后清除formData并且切换tabs2 + const paySuccessToTabs2 = () => { + uni.hideLoading() + uni.showToast({ + title: '支付成功', + duration: 2000, + success() { + currentTab.value = 2 + resetFormData() + setTimeout(() => { + getLists() + getCount() + }, 500); // 延迟1秒执行 + } + }); + } + + // 邀请用户数 + let where = { + page_no: 1, + page_size: 25, + loadingOver: false + + } + const count = ref(0) + const getCount = async () => { + if (Role.value == 4) return; + let res = await rechargeCountApi({ + store_id: STORE_INFO.id + }) + count.value = res.data.count + } + + // 邀请列表 + const lists = ref([]) + const getLists = async () => { + where.loadingOver = false + where.page_no = 1 + where.page_size = 25 + let res = await rechargeListsApi({ + store_id: STORE_INFO.id, + recharge_type: "INDUSTRYMEMBERS", + page_no: 1, + page_size: 25 + }) + lists.value = res.data.lists + + } + + getCount() + getLists() + + const upadtaStatus = (item) => { + updataOrderApi({ + order_no: item.order_id, + recharge: 1 + }).then(res => { + getCount() + getLists() + + }) + } + + onLoad(() => { + getUserShip().then(res => { + range.value = res.data.lists.map(item => { + return { + value: item.id, + text: item.title + } + }) + }) + getUserLabel().then(res => { + columns.value = [res.data.lists] + }) + getPhoneOneDay() + getCityList() + }) + + onPullDownRefresh(() => { + getCount() + getLists() + setTimeout(() => { + uni.stopPullDownRefresh() + }, 1000) + }) + + + onReachBottom(async () => { + if (where.loadingOver) return; + where.page_no++; + if (Role.value == 1) { + let res = await rechargeListsApi({ + store_id: STORE_INFO.id, + recharge_type: "INDUSTRYMEMBERS", + ...where + }) + if (res.data.lists.length <= 0) { + return where.loadingOver = true + } + lists.value.push(...res.data.lists) + } else { + let res = await getCreateLists({ + store_id: STORE_INFO.id, + ...where + }) + if (res.data.lists.length <= 0) { + return where.loadingOver = true + } + lists.value.push(...res.data.lists) + } + }) +</script> + +<style lang='scss'> + .tabs { + background-color: #fff; + width: 100vw; + box-sizing: border-box; + padding: 30rpx 0; + justify-content: space-around; + position: relative; + display: flex; + font-size: 32rpx; + color: #444444; + + .actText { + color: #20B128; + } + + + .lines { + position: absolute; + width: 70rpx; + height: 7rpx; + border-radius: 8rpx; + background-color: #33B83A; + bottom: 15rpx; + transition: 300ms; + left: calc(25vw - 35rpx); + } + + .actLine { + left: calc(75vw - 35rpx); + } + } + + .card { + width: 710rpx; + margin: 20rpx auto; + background-color: #fff; + box-sizing: border-box; + border-radius: 10rpx; + } + + .card1 { + padding: 52rpx 30rpx; + + .card1-tit { + font-size: 32rpx; + color: #444444; + text-align: center; + margin-bottom: 90rpx; + } + + .store-info { + font-size: 28rpx; + color: #20B128; + text-align: center; + margin-top: 30rpx; + } + } + + .submit-btn { + /* height: 200rpx; */ + position: fixed; + bottom: 50rpx; + width: 710rpx; + left: 50%; + transform: translateX(-50%); + + } + + + .vip-card { + width: 690rpx; + height: 270rpx; + background-image: url('https://lihai001.oss-cn-chengdu.aliyuncs.com/attach/4a92b202406162207212332.png'); + background-size: 100% 100%; + margin: 20rpx auto; + display: flex; + align-items: center; + font-size: 30rpx; + box-sizing: border-box; + padding: 0 30rpx; + color: #444444; + justify-content: space-around; + + .num { + font-size: 72rpx; + color: #7B5232; + + } + } + + .table { + width: 710rpx; + box-sizing: border-box; + font-size: 30rpx; + margin: 0 auto; + } + + + .address-content { + padding: 20rpx; + height: 50vh; + overflow-y: auto; + + .address-li { + display: flex; + justify-content: space-between; + align-items: center; + font-size: 32rpx; + color: #777777; + margin: 30rpx 0; + } + + .act { + color: #20B128; + } + } + + .uni-table-th { + padding: 10rpx 0 !important; + } + + .uni-table-td { + padding: 10rpx 0 !important; + } + + .slot-content { + /* padding-bottom: 50rpx; */ + } + + .code-btn { + display: flex; + align-items: center; + } + + .btn-text { + color: #20B128; + } +</style> \ No newline at end of file diff --git a/pageQuota/vipUser/index.vue b/pageQuota/vipUser/index.vue index ef01bb8..1b4edaf 100644 --- a/pageQuota/vipUser/index.vue +++ b/pageQuota/vipUser/index.vue @@ -1,801 +1,40 @@ <template> - <view class="" v-if="!STORE_INFO.id"> - <up-modal :show="showModa" title="登录门店" @confirm="confirmStore" confirmColor='#20B128'> - <view class="slot-content"> - <up-form labelPosition="left" label-width="100rpx"> - <up-form-item label="手机号" borderBottom> - <up-input v-model="storePhone" placeholder="请输入门店手机号"></up-input> - </up-form-item> - <!-- <up-form-item label="角色" borderBottom> - <uni-data-select v-model="Role" :localdata="range" :clear='false'></uni-data-select> - </up-form-item> --> - </up-form> - </view> - </up-modal> - </view> - <view v-else> - <view class="tabs"> - <text @click="currentTab = 1" :class="{ actText: currentTab == 1 }">开通{{ Role == 1 ? '行业会员' : '商户' }} - </text> - <text @click="currentTab = 2, getCount(), getLists()" :class="{ actText: currentTab == 2 }"> 已开通列表</text> - <view class="lines" :class="{ actLine: currentTab == 2 }" /> - </view> - <!-- tabs1 --> - <block v-if='currentTab == 1'> - <view class="card card1"> - <view class="card1-tit"> - {{ Role == 1 ? '行业会员' : '商户' }}开通报备 - <!-- <up-input v-model='formData.auth_code'> </up-input> --> - </view> - <up-form labelPosition="left" :model="formData" :borderBottom='false'> - <up-form-item label=""> - <up-input v-model="formData.real_name" border="none" prefixIcon="account" placeholder="请输入真实姓名" - :customStyle="{ background: '#F3F3F3', padding: '20rpx', 'border-radius': '30rpx' }" - :placeholderStyle="{ color: '#444444' }" - :prefixIconStyle="{ 'margin-right': '40rpx' }"></up-input> - </up-form-item> - <up-form-item label=""> - <up-input v-model="formData.mobile" border="none" prefixIcon="phone" placeholder="请输入电话号码" - :customStyle="{ background: '#F3F3F3', padding: '20rpx', 'border-radius': '30rpx' }" - :placeholderStyle="{ color: '#444444' }" - :prefixIconStyle="{ 'margin-right': '40rpx' }"></up-input> - </up-form-item> - <up-form-item label=""> - <view @click="showPop = true" style="width: 100%;"> - <up-input style="pointer-events: none" v-model="formData.address" border="none" - prefixIcon="map" readonly placeholder="点击选择地址" :customStyle="{ - background: '#F3F3F3', padding: '20rpx', - 'border-radius': '30rpx' - }" :placeholderStyle="{ color: '#444444' }" :prefixIconStyle="{ 'margin-right': '40rpx' }" - suffixIcon='arrow-down'></up-input> - </view> - </up-form-item> - <up-form-item label="" v-if='Role == 1'> - <view @click="showPop1 = true" style="width: 100%;"> - <up-input style="pointer-events: none" v-model="formData.label_name" border="none" - prefixIcon="man-add" readonly placeholder="点击选择用户身份" :customStyle="{ - background: '#F3F3F3', padding: '20rpx', - 'border-radius': '30rpx' - }" :placeholderStyle="{ color: '#444444' }" :prefixIconStyle="{ 'margin-right': '40rpx' }" - suffixIcon='arrow-down'></up-input> - </view> - </up-form-item> - <!-- <up-form-item label="" v-if='Role == 1'> - <view style="width: 100%;"> - <up-input v-model="formData.price" border="none" prefixIcon="rmb-circle" placeholder="请输入金额" - :customStyle="{ - background: '#F3F3F3', padding: '20rpx', - 'border-radius': '30rpx' - }" :placeholderStyle="{ color: '#444444' }" :prefixIconStyle="{ 'margin-right': '40rpx' }"></up-input> - </view> - </up-form-item> --> - <up-form-item label=""> - <view style="width: 100%;display: flex;align-items: center;justify-content: space-between;"> - <view class=""> - <up-input v-model="formData.code" border="none" prefixIcon="tags" placeholder="请输入验证码" - :customStyle="{ - background: '#F3F3F3', padding: '20rpx', - 'border-radius': '30rpx' - }" :placeholderStyle="{ color: '#444444' }" :prefixIconStyle="{ 'margin-right': '40rpx' }"></up-input> - </view> - <text class='btn-text' style="color: grey;" v-if='cutDown'>重新获取({{ cutDown }})</text> - <text @click="getCode" class='btn-text' v-else> {{ flag ? '获取验证码' : '重新获取' }} </text> - </view> - </up-form-item> - </up-form> - <view class="store-info"> - 报备人:{{ STORE_INFO.name }} - </view> + <button @click="test">anniu</button> - <view class="store-info" v-if="Role==1"> - <view class="" style="width: 300rpx;margin: 0 auto;border-bottom: 1px solid #F3F3F3;"> - <up-input inputAlign='center' placeholder="请输入金额" @focus="formData.price=''" color='#FF6B00' - :placeholderStyle="{fontSize:'28rpx'}" fontSize='20px' border="none" - v-model="formData.price" @blur='tofixedPrice'></up-input> - </view> - <view style="color: red;margin-top: 20rpx;font-size: 24rpx;" - v-if="formData.label_limit&&formData.price<formData.label_limit"> - {{formData.label_name}}角色最低金额不能低于{{formData.label_limit}}元 - </view> - - </view> - - </view> - <view class="submit-btn" @click="submit"> - <view - style='width: 710rpx;height: 100rpx;text-align: center;line-height: 100rpx;text-align: center;color: white;background-color: #33B83A;border-radius: 50rpx;font-size:40rpx ;'> - {{ Role == 1 ? '完成并收款' : '完成' }} - </view> - - </view> - </block> - - <!-- tabs2 --> - <block v-else> - <view class="vip-card"> - <text>当前已开通:</text> - <up-count-to :startVal="0" :endVal="count"></up-count-to> - <text>位{{ Role == 1 ? '行业会员' : '商户' }}</text> - </view> - - <view class="table"> - <uni-table stripe emptyText="暂无更多数据" width="100%"> - <!-- 表头行 --> - <uni-tr> - <uni-th width="20" align="center">序号</uni-th> - <uni-th width="50" align="center" v-if='Role == 1'>行业会员</uni-th> - <uni-th width="50" align="center" v-if='Role == 1'>经营资金</uni-th> - <uni-th width="50" align="center" v-if='Role == 4'>开通时间</uni-th> - <uni-th width="50" align="center" v-if='Role == 4'>商户</uni-th> - <uni-th width="50" align="center" v-if='Role == 1'>角色</uni-th> - <uni-th width="50" align="center">状态</uni-th> - </uni-tr> - <!-- 表格数据行 --> - <uni-tr v-for="(item, index) in lists" :key="item.order_id"> - <uni-td align="center">{{index+1}}</uni-td> - <uni-td style="font-size: 20rpx;" align="center" v-if='Role == 1'>{{ item.real_name }}</uni-td> - <uni-td style="font-size: 20rpx;" align="center" v-if='Role == 1'>{{ item.price }}</uni-td> - <uni-td style="font-size: 20rpx;" align="center" - v-if='Role == 4'>{{ item.create_time }}</uni-td> - <uni-td style="font-size: 20rpx;" align="center" v-if='Role == 4'>{{ item.nickname }}</uni-td> - <uni-td style="font-size: 20rpx;" align="center" v-if='Role == 1'>{{ item.label_name }}</uni-td> - <uni-td style="font-size: 20rpx;" align="center"> - <view v-if="item.paid == 1 || Role == 4">已开通</view> - <view v-else style="color:#33B83A ;"> - <view @click="upadtaStatus(item)"> - 未开通,查询 - </view> - <view @click="rePay(item)"> - 重新支付 - </view> - </view> - </uni-td> - </uni-tr> - </uni-table> - </view> - </block> - </view> - <view style="height: 50rpx;" /> - - <!-- 地址选择器 --> - <up-popup :show="showPop" @close="showPop = false" @open="showPop = true" :round="10"> - <view style="padding: 20rpx;"> - <up-tabs :list="tabsList" @change='addressTbasChange' :current='currentAddressIndex' lineColor='#20B128' - :activeStyle="{ color: '#20B128' }"></up-tabs> - <up-line style="margin-top:20rpx "></up-line> - <view class="address-content" v-if='currentAddressIndex == 0'> - <view class="address-li" :class='{ act: item.city_code == formData.city }' - v-for="item in addressList.city" :key="item.city_code" @click="addressLiClick(0, item)"> - <text>{{ item.city_name }}</text> - <up-icon name="arrow-right" :color="item.city_code == formData.city ? '#20B128' : '#777777'" /> - </view> - </view> - <view class="address-content" v-else-if='currentAddressIndex == 1'> - <view class="address-li" v-for="item in addressList.area" @click="addressLiClick(1, item)" - :key="item.area_code" :class='{ act: item.area_code == formData.area }'> - <text>{{ item.area_name }}</text> - <up-icon name="arrow-right" :color="item.area_code == formData.area ? '#20B128' : '#777777'" /> - </view> - </view> - <view class="address-content" v-else-if='currentAddressIndex == 2'> - <view class="address-li" v-for="item in addressList.street" @click="addressLiClick(2, item)" - :key="item.street_code" :class='{ act: item.street_code == formData.street }'> - <text>{{ item.street_name }}</text> - <up-icon name="arrow-right" :color="item.street_code == formData.street ? '#20B128' : '#777777'" /> - </view> - </view> - <view class="address-content" v-else-if='currentAddressIndex == 3'> - <view class="address-li" v-for="item in addressList.village" @click="addressLiClick(3, item)" - :key="item.village_code" :class='{ act: item.village_code == formData.village }'> - <text>{{ item.village_name }}</text> - <up-icon name="arrow-right" - :color="item.village_code == formData.village ? '#20B128' : '#777777'" /> - </view> - </view> - <view class="address-content" v-else-if='currentAddressIndex == 4'> - <view class="address-li" :class='{ act: item.id == formData.brigade }' - v-for="item in addressList.brigade" :key="item.id" @click="addressLiClick(4, item)"> - <text>{{ item.brigade_name }}</text> - <up-icon name="arrow-right" :color="item.id == formData.brigade ? '#20B128' : '#777777'" /> - </view> - </view> - </view> - </up-popup> - <up-picker :show="showPop1" :columns="columns" @confirm='conformRole' @cancel='showPop1 = false' - @close="showPop1 = false" @open="showPop1 = true" keyName='label_name' confirmColor='#33B83A'></up-picker> </template> + <script setup> - import { - reactive, - ref - } from 'vue'; - import useUserStore from "@/store/user"; - import { - provinceListApi, - cityListApi, - areaListApi, - streetListApi, - villageListApi, - brigadeListApi - } from "@/api/address.js" - import { - vipRechargeApi, - rechargeCountApi, - reVipRechargeApi, - rechargeListsApi, - updataOrderApi, - getStoreByPhone, - getUserLabel, - getUserShip, - getCreateLists, - getReportingSms - } from "@/api/user.js" import Push from "@/utils/push.js" import { - onPullDownRefresh, - onLoad, - onReachBottom - } from "@dcloudio/uni-app" + ref, + reactive + } from "vue" import { config } from "@/config/app.js" - - const showPop1 = ref(false) - const Role = ref(1) - const range = ref({}) - const columns = ref([]) - const showModa = ref(true) - const storePhone = ref('') - const confirmStore = () => { - getStoreByPhone({ - phone: storePhone.value - }).then(res => { - for (let key in res.data) { - STORE_INFO[key] = res.data[key] - } - setPhoneOneDay() - }).catch(err => { - uni.$u.toast('未查到店铺信息,请检查手机号码') - }) - } - // 用户选择的门店信息 - let STORE_INFO = reactive({ - id: "" - }) - - - // 门店手机号保留一天 - const setPhoneOneDay = () => { - if (uni.getStorageSync('VIP_PHONE')) return; - const currentDate = new Date(); - const nextDay = new Date(currentDate); - nextDay.setDate(currentDate.getDate() + 1); - uni.setStorageSync('VIP_PHONE', JSON.stringify({ - time: nextDay, - phone: storePhone.value - })); - } - const getPhoneOneDay = () => { - if (uni.getStorageSync('VIP_PHONE')) { - let data = JSON.parse(uni.getStorageSync('VIP_PHONE')) - if (new Date() > data.time) { - uni.removeStorageSync('VIP_PHONE'); - } else { - storePhone.value = data.phone - } - } - } - // 手机保留一天结束 - - // 验证码 - const cutDown = ref(0) - const flag = ref(true) - const code = ref('') - const checkPhone = (phone) => { - const regex = /^1[3-9]\d{9}$/; - return regex.test(formData.mobile) ? true : false - } - - const getCode = async () => { - if (!checkPhone(formData.mobile)) return uni.$u.toast('请输入正确的手机号') - await getReportingSms({ - account: formData.mobile - }) - flag.value = false - cutDown.value = 60 - let timer = setInterval(() => { - cutDown.value-- - if (cutDown.value <= 0) { - cutDown.value = 0; - clearInterval(timer); - } - }, 1000) - } - // 验证码结束 - - - const currentTab = ref(1) - const formData = reactive({ - store_id: STORE_INFO.id, - mobile: "", - province: 510000, - city: '', - area: "", - street: "", - village: "", - real_name: "", - auth_code: "", - address: "", - label_name: "", - label_id: "", - label_limit: "", - user_ship: '', - code: '', - brigade: "", - price: "", - // store_id: STORE_INFO.id, - // mobile: "19130550023", - // province: 510000, - // city: '510500', - // area: "510503", - // street: "510503102", - // village: "510503102201", - // real_name: "赵明军", - // auth_code: "131197337173621549", - // address: "", - // label_name: "", - // label_id: "4", - // user_ship: '1', - // code: '' - }) - - const tofixedPrice = () => { - formData.price = (+formData.price).toFixed(2) - } - - const resetFormData = () => { - for (let key in formData) { - formData[key] = '' - } - tabsList.forEach(item => { - item.name = '请选择' - }) - formData.province = 510000 - cutDown.value = 0 - currentAddressIndex.value = 0 - } - - const conformRole = (e) => { - formData.label_name = e.value[0].label_name - formData.label_id = e.value[0].label_id - formData.price = (+e.value[0].limit).toFixed(2) - formData.label_limit = e.value[0].limit - showPop1.value = false - } - - - // 地址选择 - const showPop = ref(false) - const currentAddressIndex = ref(0) - const currentAddressList = () => { - if (!formData.city) return [0, 'city']; - else if (formData.area) return [1, 'area']; - else if (formData.street) return [2, 'street']; - else if (formData.village) return [3, 'village']; - else if (formData.brigade) return [4, 'brigade']; - } - const addressTbasChange = (e) => { - currentAddressIndex.value = e.index - } - const addressList = reactive({ - city: [], - area: [], - street: [], - village: [], - brigade: [] - }) - const addressLiClick = async (i, item) => { - if (i == 0) { - formData.city = item.city_code - tabsList[0].name = item.city_name - let res = await areaListApi({ - city_code: formData.city - }) - addressList.area = res.data - } - if (i == 1) { - formData.area = item.area_code - tabsList[1].name = item.area_name - let res = await streetListApi({ - area_code: formData.area - }) - addressList.street = res.data - } - - if (i == 2) { - formData.street = item.street_code - tabsList[2].name = item.street_name - let res = await villageListApi({ - street_code: formData.street - }) - addressList.village = res.data - } - if (i == 3) { - formData.village = item.village_code - tabsList[3].name = item.village_name - let res = await brigadeListApi({ - village_code: formData.village - }) - addressList.brigade = res.data - } - if (i == 4) { - formData.brigade = item.id - tabsList[4].name = item.brigade_name - - formData.address = tabsList[0].name + tabsList[1].name + tabsList[2].name + tabsList[3].name + - tabsList[4].name - return showPop.value = false - } - formData.address = tabsList[0].name + tabsList[1].name + tabsList[2].name + tabsList[3].name + tabsList[4] - .name - return currentAddressIndex.value++ - } - const getCityList = async () => { - let res = await cityListApi({ - province_code: formData.province - }) - addressList.city = res.data - } - const tabsList = reactive( - [{ - name: "请选择" - }, - { - name: '请选择', - disabled: false - }, - { - name: '请选择', - disabled: false - }, - { - name: '请选择', - disabled: false - }, - { - name: '请选择', - disabled: false - }, - ]); - - - let timerInvol = null // 开起一个scoket监听用户知否支付成功 - const userInfo = useUserStore().userInfo; const connection = new Push({ url: config.WSS_URL, // websocket地址 app_key: '2ce3ce22329517213caa7dad261f5695', }); - const user_channel = connection.subscribe(`wechat_mmp_${userInfo.id}`); + const user_channel = connection.subscribe(`wechat_mmp_9`); user_channel.on('message', function(data) { - try { - clearTimeout(timerInvol); - paySuccessToTabs2() - } catch (error) {} + console.log(111111, timerInvol) + clearTimeout(timerInvol); + console.log(222222, timerInvol) + // setImmediate() }); // 结束 - - // 提交 - const submit = async () => { - if (!formData.real_name) return uni.$u.toast('请填写真实姓名'); - if (!formData.mobile) return uni.$u.toast('请填写电话号码'); - if (!formData.code) return uni.$u.toast('请输入短信验证码'); - if (!formData.address) return uni.$u.toast('请选择地址'); - if (!formData.label_id) return uni.$u.toast('请选择用户身份'); - if (formData.price < formData.label_limit) return uni.$u.toast( - `${formData.label_name}角色最低金额不能低于${formData.label_limit}元`); - formData.store_id = STORE_INFO.id - if (Role.value == 1) { - // formData.recharge_type = 'INDUSTRYMEMBERS' - // formData.user_ship = 1 - // vipRechargeApi(formData).then(res => {}) - // return - uni.scanCode({ - success: function(res) { - if (String(res.result.length) != 18) return uni.$u.toast('二维码未扫描完整'); - uni.showLoading({ - title: '支付中...' - }); - formData.auth_code = res.result - formData.recharge_type = 'INDUSTRYMEMBERS' - formData.user_ship = 1 - vipRechargeApi(formData).then(res => { - timerInvol = setTimeout(() => { - uni.hideLoading(); - if (currentTab.value == 2) return; - uni.$u.toast('支付超时'); - }, 30000) - }) - - } - }); - } - } - - const rePay = (item) => { - uni.scanCode({ - success: function(res) { - if (String(res.result.length) != 18) return uni.$u.toast('二维码未扫描完整'); - uni.showLoading({ - title: '等待用户支付' - }); - reVipRechargeApi({ - id: item.id, - auth_code: res.result - }).then(res => { - timerInvol = setTimeout(() => { - uni.hideLoading(); - if (currentTab.value == 2) return; - uni.$u.toast('支付超时'); - }, 30000) - }) - } - }); - } - - // 支付成功后清除formData并且切换tabs2 - const paySuccessToTabs2 = () => { - uni.hideLoading() - uni.showToast({ - title: '支付成功', - duration: 2000, - success() { - currentTab.value = 2 - resetFormData() - setTimeout(() => { - getLists() - getCount() - }, 500); // 延迟1秒执行 - } - }); - } - - // 邀请用户数 - let where = { - page_no: 1, - page_size: 25, - loadingOver: false + const test = () => { + timerInvol = setTimeout(() => { + console.log("支付超时") + }, 5000) } - const count = ref(0) - const getCount = async () => { - if (Role.value == 4) return; - let res = await rechargeCountApi({ - store_id: STORE_INFO.id - }) - count.value = res.data.count - } - - // 邀请列表 - const lists = ref([]) - const getLists = async () => { - where.loadingOver = false - where.page_no = 1 - where.page_size = 25 - let res = await rechargeListsApi({ - store_id: STORE_INFO.id, - recharge_type: "INDUSTRYMEMBERS", - page_no: 1, - page_size: 25 - }) - lists.value = res.data.lists - - } - - getCount() - getLists() - - const upadtaStatus = (item) => { - updataOrderApi({ - order_no: item.order_id, - recharge: 1 - }).then(res => { - getCount() - getLists() - - }) - } - - onLoad(() => { - getUserShip().then(res => { - range.value = res.data.lists.map(item => { - return { - value: item.id, - text: item.title - } - }) - }) - getUserLabel().then(res => { - columns.value = [res.data.lists] - }) - getPhoneOneDay() - getCityList() - }) - - onPullDownRefresh(() => { - getCount() - getLists() - setTimeout(() => { - uni.stopPullDownRefresh() - }, 1000) - }) - - - onReachBottom(async () => { - if (where.loadingOver) return; - where.page_no++; - if (Role.value == 1) { - let res = await rechargeListsApi({ - store_id: STORE_INFO.id, - recharge_type: "INDUSTRYMEMBERS", - ...where - }) - if (res.data.lists.length <= 0) { - return where.loadingOver = true - } - lists.value.push(...res.data.lists) - } else { - let res = await getCreateLists({ - store_id: STORE_INFO.id, - ...where - }) - if (res.data.lists.length <= 0) { - return where.loadingOver = true - } - lists.value.push(...res.data.lists) - } - }) </script> -<style lang='scss'> - .tabs { - background-color: #fff; - width: 100vw; - box-sizing: border-box; - padding: 30rpx 0; - justify-content: space-around; - position: relative; - display: flex; - font-size: 32rpx; - color: #444444; - - .actText { - color: #20B128; - } - - - .lines { - position: absolute; - width: 70rpx; - height: 7rpx; - border-radius: 8rpx; - background-color: #33B83A; - bottom: 15rpx; - transition: 300ms; - left: calc(25vw - 35rpx); - } - - .actLine { - left: calc(75vw - 35rpx); - } - } - - .card { - width: 710rpx; - margin: 20rpx auto; - background-color: #fff; - box-sizing: border-box; - border-radius: 10rpx; - } - - .card1 { - padding: 52rpx 30rpx; - - .card1-tit { - font-size: 32rpx; - color: #444444; - text-align: center; - margin-bottom: 90rpx; - } - - .store-info { - font-size: 28rpx; - color: #20B128; - text-align: center; - margin-top: 30rpx; - } - } - - .submit-btn { - /* height: 200rpx; */ - position: fixed; - bottom: 50rpx; - width: 710rpx; - left: 50%; - transform: translateX(-50%); - - } - - - .vip-card { - width: 690rpx; - height: 270rpx; - background-image: url('https://lihai001.oss-cn-chengdu.aliyuncs.com/attach/4a92b202406162207212332.png'); - background-size: 100% 100%; - margin: 20rpx auto; - display: flex; - align-items: center; - font-size: 30rpx; - box-sizing: border-box; - padding: 0 30rpx; - color: #444444; - justify-content: space-around; - - .num { - font-size: 72rpx; - color: #7B5232; - - } - } - - .table { - width: 710rpx; - box-sizing: border-box; - font-size: 30rpx; - margin: 0 auto; - } - - - .address-content { - padding: 20rpx; - height: 50vh; - overflow-y: auto; - - .address-li { - display: flex; - justify-content: space-between; - align-items: center; - font-size: 32rpx; - color: #777777; - margin: 30rpx 0; - } - - .act { - color: #20B128; - } - } - - .uni-table-th { - padding: 10rpx 0 !important; - } - - .uni-table-td { - padding: 10rpx 0 !important; - } - - .slot-content { - /* padding-bottom: 50rpx; */ - } - - .code-btn { - display: flex; - align-items: center; - } - - .btn-text { - color: #20B128; - } +<style> </style> \ No newline at end of file diff --git a/pages/login/login.vue b/pages/login/login.vue index 5a83bc1..f420957 100644 --- a/pages/login/login.vue +++ b/pages/login/login.vue @@ -118,6 +118,7 @@ // } } + // 微信公众号绑定 const officialCode = () => { console.log("jinfas")