| | |
| | | export default { |
| | | // BASE_URL: 'http://192.168.110.188:9100', |
| | | BASE_URL: 'https://jiashikang.cn/applet', |
| | | BASE_URL: 'http://192.168.110.188:9100', |
| | | // BASE_URL: 'https://jiashikang.cn/applet', |
| | | uploadUrl: "https://jiashikang.cn/applet/open/file/upload", |
| | | imageUrl: 'https://jiashikang.cn/images/' |
| | | }; |
| | |
| | | import goodsItem from "@/components/goodsItem.vue"; |
| | | import invitePopup from "@/components/invitePopup.vue"; |
| | | import config from '../../config/index.js' |
| | | import { getSuperiorInfo, confirmSuperior, getBannerList, getBigList, getGoodList, htmlConfig } from './service.js' |
| | | import { record, getBannerList, getBigList, getGoodList, htmlConfig } from './service.js' |
| | | |
| | | const background = reactive({ |
| | | backgroundColor: "transparent", |
| | |
| | | } |
| | | } |
| | | }) |
| | | if (uni.getStorageSync('token')) { |
| | | record().then(res => { |
| | | console.log(res) |
| | | }) |
| | | } |
| | | }) |
| | | |
| | | onLoad((query) => { |
| | |
| | | //协议配置 |
| | | export const htmlConfig = (type) => { |
| | | return request.get(`/html-config/${type}`, ) |
| | | } |
| | | //协议配置 |
| | | export const record = (type) => { |
| | | return request.post(`/appUserVisit/record`, ) |
| | | } |
| | |
| | | <view class="fs-23 lh-33 color3">订单编号:{{ item.code }}</view> |
| | | <view class="shrink0 fs-23 lh-46 px-23 br-8 border1 bgcolor3 color4" |
| | | :class="item.status == 3 && 'border2 bgcolor7 color1'"> |
| | | {{ ['待支付', '已付定金', '已支付'][item.status - 1] }} |
| | | {{ ['待支付', '已付定金', '已支付','已收货'][item.status - 1] }} |
| | | </view> |
| | | </view> |
| | | <view class="px-27 pt-27 pb-29"> |
| | |
| | | clearInterval(countdownTimers[orderNo].timer); |
| | | |
| | | // 倒计时结束时刷新列表数据 |
| | | // formData.pageNum = 1; |
| | | // isLoading.value = true; |
| | | // getList(); |
| | | formData.pageNum = 1; |
| | | isLoading.value = true; |
| | | getList(); |
| | | return; |
| | | } |
| | | |
| | |
| | | </view> |
| | | <view class="flex a-center"> |
| | | <image src="/static/image/home/view.png" class="w-23 h-19 shrink0 mr-12" /> |
| | | <view>4983</view> |
| | | <view>{{info.readCount||0}}</view> |
| | | </view> |
| | | </view> |
| | | <rich-text :nodes="content" class="mt-37"></rich-text> |
| | |
| | | const content = ref<string>(""); |
| | | const info = ref({ |
| | | |
| | | bannerName: '', createTime: '' |
| | | bannerName: '', createTime: '', readCount: 0 |
| | | }) |
| | | |
| | | onLoad((params) => { |
| | |
| | | <rich-text :nodes="content"></rich-text> |
| | | </view> |
| | | </view> |
| | | <view v-if="(detailType == 1 && detailInfo.inventory > 0) || detailType == 2"> |
| | | <view> |
| | | <view class="bottom_box"></view> |
| | | <view class="bottom_btn" @tap.stop="toBuy()"> |
| | | <view class="btn">立即购买</view> |
| | | <!-- <view v-if="detailType == 1" class="btn btn_disable">库存不足,请联系平台客服</view> --> |
| | | <view v-if="(detailType == 1 && detailInfo.inventory > 0)" class="btn btn_disable">库存不足,请联系平台客服</view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { ref, reactive } from "vue"; |
| | | import { onShareAppMessage, onLoad } from '@dcloudio/uni-app' |
| | | import banner from "@/components/banner.vue"; |
| | | import { getBigInfo, getPhysicalInfo } from './service.js' |
| | | import config from '../../config/index.js' |
| | | import { ref, reactive } from "vue"; |
| | | import { onShareAppMessage, onLoad } from '@dcloudio/uni-app' |
| | | import banner from "@/components/banner.vue"; |
| | | import { getBigInfo, getPhysicalInfo } from './service.js' |
| | | import config from '../../config/index.js' |
| | | |
| | | const list = ref([]); |
| | | const detailType = ref(1) |
| | | const content = ref<string>(""); |
| | | const detailInfo = ref({ name: '', introduction: '', totalPrice: '', inventory: 0, id: '' }) |
| | | const list = ref([]); |
| | | const detailType = ref(1) |
| | | const content = ref<string>(""); |
| | | const detailInfo = ref({ name: '', introduction: '', totalPrice: '', inventory: 0, id: '' }) |
| | | |
| | | onLoad((query) => { |
| | | wx.showShareMenu({ |
| | | menus: ['shareAppMessage', 'shareTimeline'] |
| | | }) |
| | | detailType.value = query.type |
| | | // type 1 大礼包 2 实物 |
| | | if (query.type == 1) { |
| | | getBigInfo(query.id).then(res => { |
| | | if (res.code == 200) { |
| | | list.value = res.data.detailedImage.split(',').map(item => { |
| | | return { |
| | | imageUrl: config.imageUrl + item |
| | | } |
| | | }) |
| | | if (res.data.detailedDescription) { |
| | | res.data.detailedDescription = res.data.detailedDescription.replace(/<img/gi, |
| | | '<img style="max-width:100%;height:auto;margin:0 auto;display:block"') |
| | | } |
| | | content.value = res.data.detailedDescription |
| | | detailInfo.value = res.data |
| | | } |
| | | onLoad((query) => { |
| | | wx.showShareMenu({ |
| | | menus: ['shareAppMessage', 'shareTimeline'] |
| | | }) |
| | | } else { |
| | | getPhysicalInfo(query.id).then(res => { |
| | | if (res.code == 200) { |
| | | list.value = res.data.detailedImage.split(',').map(item => { |
| | | return { |
| | | imageUrl: config.imageUrl + item |
| | | detailType.value = query.type |
| | | // type 1 大礼包 2 实物 |
| | | if (query.type == 1) { |
| | | getBigInfo(query.id).then(res => { |
| | | if (res.code == 200) { |
| | | list.value = res.data.detailedImage.split(',').map(item => { |
| | | return { |
| | | imageUrl: config.imageUrl + item |
| | | } |
| | | }) |
| | | if (res.data.detailedDescription) { |
| | | res.data.detailedDescription = res.data.detailedDescription.replace(/<img/gi, |
| | | '<img style="max-width:100%;height:auto;margin:0 auto;display:block"') |
| | | } |
| | | }) |
| | | if (res.data.detailedDescription) { |
| | | res.data.detailedDescription = res.data.detailedDescription.replace(/<img/gi, |
| | | '<img style="max-width:100%;height:auto;margin:0 auto;display:block"') |
| | | content.value = res.data.detailedDescription |
| | | detailInfo.value = res.data |
| | | } |
| | | content.value = res.data.detailedDescription |
| | | detailInfo.value = res.data |
| | | }) |
| | | } else { |
| | | getPhysicalInfo(query.id).then(res => { |
| | | if (res.code == 200) { |
| | | list.value = res.data.detailedImage.split(',').map(item => { |
| | | return { |
| | | imageUrl: config.imageUrl + item |
| | | } |
| | | }) |
| | | if (res.data.detailedDescription) { |
| | | res.data.detailedDescription = res.data.detailedDescription.replace(/<img/gi, |
| | | '<img style="max-width:100%;height:auto;margin:0 auto;display:block"') |
| | | } |
| | | content.value = res.data.detailedDescription |
| | | detailInfo.value = res.data |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | |
| | | onShareAppMessage((e) => { |
| | | if (uni.getStorageSync('userInfo')) { |
| | | let userInfo = uni.getStorageSync('userInfo') |
| | | if (userInfo.userType && userInfo.userType > 1) { |
| | | return { |
| | | title: '诚邀您一起加入嘉视达', |
| | | path: `/pages/home/home?code=${userInfo.code}&type=2` |
| | | } |
| | | } else { |
| | | return { |
| | | title: '诚邀您一起加入嘉视达', |
| | | path: '/pages/home/home' |
| | | } |
| | | } |
| | | |
| | | } else { |
| | | return { |
| | | title: '诚邀您一起加入嘉视达', |
| | | path: '/pages/home/home' |
| | | } |
| | | } |
| | | |
| | | }) |
| | | |
| | | const back = () => { |
| | | uni.navigateBack() |
| | | } |
| | | const toBuy = () => { |
| | | if (detailType.value == 1 && detailInfo.value.inventory == 0) return |
| | | uni.navigateTo({ |
| | | url: `/pagesA/placeAnOrder/placeAnOrder?id=${detailInfo.value.id}&type=${detailType.value}` |
| | | }) |
| | | } |
| | | }) |
| | | |
| | | onShareAppMessage((e) => { |
| | | if (uni.getStorageSync('userInfo')) { |
| | | let userInfo = uni.getStorageSync('userInfo') |
| | | return { |
| | | title: '诚邀您一起加入嘉视达', |
| | | path: `/pages/home/home?code=${userInfo.code}&type=2` |
| | | } |
| | | } else { |
| | | return { |
| | | title: '诚邀您一起加入嘉视达', |
| | | path: '/pages/home/home' |
| | | } |
| | | } |
| | | |
| | | }) |
| | | |
| | | const back = () => { |
| | | uni.navigateBack() |
| | | } |
| | | const toBuy = () => { |
| | | uni.navigateTo({ |
| | | url: `/pagesA/placeAnOrder/placeAnOrder?id=${detailInfo.value.id}&type=${detailType.value}` |
| | | }) |
| | | } |
| | | </script> |
| | | |
| | | <style> |
| | | page { |
| | | background-color: #f5f5f5; |
| | | } |
| | | page { |
| | | background-color: #f5f5f5; |
| | | } |
| | | </style> |
| | | <style scoped lang="scss"> |
| | | .bgcolor1 { |
| | | background-color: #fff; |
| | | } |
| | | |
| | | .color1 { |
| | | color: rgba(0, 0, 0, 0.5); |
| | | } |
| | | |
| | | .color2 { |
| | | color: #ff4d4f; |
| | | } |
| | | |
| | | .color3 { |
| | | color: rgba(0, 0, 0, 0.45); |
| | | } |
| | | |
| | | .br1 { |
| | | border-radius: 38rpx 38rpx 0rpx 0rpx; |
| | | } |
| | | |
| | | .bottom_btn { |
| | | position: fixed; |
| | | bottom: 0; |
| | | width: 100%; |
| | | background: #fff; |
| | | box-shadow: 0rpx -8rpx 15rpx 0rpx rgba(0, 0, 0, 0.06); |
| | | padding: 38rpx 39rpx; |
| | | padding-bottom: calc(env(safe-area-inset-bottom) + 38rpx); |
| | | |
| | | .btn { |
| | | background: linear-gradient(270deg, #6BEADF 0%, #1BA8EC 100%); |
| | | box-shadow: 0rpx 8rpx 19rpx 0rpx rgba(27, 168, 236, 0.3); |
| | | border-radius: 67rpx; |
| | | line-height: 96rpx; |
| | | color: #fff; |
| | | text-align: center; |
| | | font-weight: 600; |
| | | font-size: 35rpx; |
| | | .bgcolor1 { |
| | | background-color: #fff; |
| | | } |
| | | |
| | | .btn_disable { |
| | | background: rgba(8, 29, 59, 0.18); |
| | | color: #FFFFFF; |
| | | box-shadow: unset; |
| | | .color1 { |
| | | color: rgba(0, 0, 0, 0.5); |
| | | } |
| | | } |
| | | |
| | | .bottom_box { |
| | | height: calc(96rpx + 38rpx + 38rpx); |
| | | } |
| | | .color2 { |
| | | color: #ff4d4f; |
| | | } |
| | | |
| | | .color3 { |
| | | color: rgba(0, 0, 0, 0.45); |
| | | } |
| | | |
| | | .br1 { |
| | | border-radius: 38rpx 38rpx 0rpx 0rpx; |
| | | } |
| | | |
| | | .bottom_btn { |
| | | position: fixed; |
| | | bottom: 0; |
| | | width: 100%; |
| | | background: #fff; |
| | | box-shadow: 0rpx -8rpx 15rpx 0rpx rgba(0, 0, 0, 0.06); |
| | | padding: 38rpx 39rpx; |
| | | padding-bottom: calc(env(safe-area-inset-bottom) + 38rpx); |
| | | |
| | | .btn { |
| | | background: linear-gradient(270deg, #6BEADF 0%, #1BA8EC 100%); |
| | | box-shadow: 0rpx 8rpx 19rpx 0rpx rgba(27, 168, 236, 0.3); |
| | | border-radius: 67rpx; |
| | | line-height: 96rpx; |
| | | color: #fff; |
| | | text-align: center; |
| | | font-weight: 600; |
| | | font-size: 35rpx; |
| | | } |
| | | |
| | | .btn_disable { |
| | | background: rgba(8, 29, 59, 0.18); |
| | | color: #FFFFFF; |
| | | box-shadow: unset; |
| | | } |
| | | } |
| | | |
| | | .bottom_box { |
| | | height: calc(96rpx + 38rpx + 38rpx); |
| | | } |
| | | </style> |
| | |
| | | <view class="fs-27 font-bold">微信支付</view> |
| | | </view> |
| | | </view> |
| | | <view v-if="status >2 && goodsType == 1"> |
| | | <view v-if="status >2 && goodsType == 1 && orderDetail.paymentType==1"> |
| | | <view class="flex a-center j-between mt-31"> |
| | | <view class="fs-27 lh-38 color3">已付定金</view> |
| | | <view class="fs-27 font-bold">¥{{ orderDetail.deposit || 0.00 }}</view> |
| | |
| | | <view class="flex a-center j-between mt-31"> |
| | | <view class="fs-27 lh-38 color3">尾款支付时间</view> |
| | | <view class="fs-27 font-bold">{{ orderDetail.finalPaymentTime || "" }}</view> |
| | | </view> |
| | | <view class="flex a-center j-between mt-31"> |
| | | <view class="fs-27 lh-38 color3">支付方式</view> |
| | | <view class="fs-27 font-bold">微信支付</view> |
| | | </view> |
| | | </view> |
| | | <view v-else> |
| | | <view class="flex a-center j-between mt-31"> |
| | | <view class="fs-27 lh-38 color3">支付金额</view> |
| | | <view class="fs-27 font-bold">¥{{ orderDetail.paymentPrice || 0.00 }}</view> |
| | | </view> |
| | | <view class="flex a-center j-between mt-31"> |
| | | <view class="fs-27 lh-38 color3">支付时间</view> |
| | | <view class="fs-27 font-bold">{{ orderDetail.paymentTime || "" }}</view> |
| | | </view> |
| | | <view class="flex a-center j-between mt-31"> |
| | | <view class="fs-27 lh-38 color3">支付方式</view> |
| | |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { ref, reactive } from 'vue' |
| | | import { onLoad, onUnload } from '@dcloudio/uni-app' |
| | | import { getBigGiftOrderDetail, getPhysicalOrderDetail, bigGiftConfirm, physicalConfirm, bigGiftPayNow, physicalPayNow } from './service' |
| | | import { ref, reactive } from 'vue' |
| | | import { onLoad, onUnload } from '@dcloudio/uni-app' |
| | | import { getBigGiftOrderDetail, getPhysicalOrderDetail, bigGiftConfirm, physicalConfirm, bigGiftPayNow, physicalPayNow } from './service' |
| | | |
| | | const orderId = ref('') |
| | | const goodsType = ref<number | null>(null) |
| | | const status = ref<number | null>(null) |
| | | const orderDetail = ref<any>({ goodsCover: '', goodsName: '', goodsIntro: '', orderPrice: '', deposit: '', depositTime: '', finalPayment: '', finalPaymentTime: '', paymentPrice: '', paymentTime: '', deliveryTime: '' }) |
| | | const orderId = ref('') |
| | | const goodsType = ref<number | null>(null) |
| | | const status = ref<number | null>(null) |
| | | const orderDetail = ref<any>({ goodsCover: '', goodsName: '', goodsIntro: '', orderPrice: '', deposit: '', depositTime: '', finalPayment: '', finalPaymentTime: '', paymentPrice: '', paymentTime: '', deliveryTime: '' }) |
| | | |
| | | // 单个订单的倒计时数据 |
| | | const countdown = reactive({ |
| | | hours: '00', |
| | | minutes: '00', |
| | | seconds: '00', |
| | | isExpired: false, |
| | | timer: null as any |
| | | }) |
| | | // 单个订单的倒计时数据 |
| | | const countdown = reactive({ |
| | | hours: '00', |
| | | minutes: '00', |
| | | seconds: '00', |
| | | isExpired: false, |
| | | timer: null as any |
| | | }) |
| | | |
| | | // 更新倒计时 |
| | | const updateCountdown = (endTime: number) => { |
| | | const now = new Date().getTime() |
| | | const distance = endTime - now |
| | | // 更新倒计时 |
| | | const updateCountdown = (endTime : number) => { |
| | | const now = new Date().getTime() |
| | | const distance = endTime - now |
| | | |
| | | if (distance <= 0) { |
| | | countdown.hours = '00' |
| | | countdown.minutes = '00' |
| | | countdown.seconds = '00' |
| | | countdown.isExpired = true |
| | | if (distance <= 0) { |
| | | countdown.hours = '00' |
| | | countdown.minutes = '00' |
| | | countdown.seconds = '00' |
| | | countdown.isExpired = true |
| | | if (countdown.timer) { |
| | | clearInterval(countdown.timer) |
| | | countdown.timer = null |
| | | } |
| | | return |
| | | } |
| | | |
| | | const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)) |
| | | const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)) |
| | | const seconds = Math.floor((distance % (1000 * 60)) / 1000) |
| | | |
| | | countdown.hours = hours.toString().padStart(2, '0') |
| | | countdown.minutes = minutes.toString().padStart(2, '0') |
| | | countdown.seconds = seconds.toString().padStart(2, '0') |
| | | } |
| | | |
| | | // 开始倒计时(60分钟) |
| | | const startCountdown = (createTimeStr : string) => { |
| | | if (!createTimeStr) return |
| | | |
| | | const createTime = new Date(decodeURIComponent(createTimeStr)).getTime() |
| | | if (isNaN(createTime)) return |
| | | |
| | | const endTime = createTime + 60 * 60 * 1000 |
| | | |
| | | // 先清一次老的 |
| | | if (countdown.timer) { |
| | | clearInterval(countdown.timer) |
| | | countdown.timer = null |
| | | } |
| | | return |
| | | } |
| | | countdown.isExpired = false |
| | | |
| | | const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)) |
| | | const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)) |
| | | const seconds = Math.floor((distance % (1000 * 60)) / 1000) |
| | | |
| | | countdown.hours = hours.toString().padStart(2, '0') |
| | | countdown.minutes = minutes.toString().padStart(2, '0') |
| | | countdown.seconds = seconds.toString().padStart(2, '0') |
| | | } |
| | | |
| | | // 开始倒计时(60分钟) |
| | | const startCountdown = (createTimeStr: string) => { |
| | | if (!createTimeStr) return |
| | | |
| | | const createTime = new Date(decodeURIComponent(createTimeStr)).getTime() |
| | | if (isNaN(createTime)) return |
| | | |
| | | const endTime = createTime + 60 * 60 * 1000 |
| | | |
| | | // 先清一次老的 |
| | | if (countdown.timer) { |
| | | clearInterval(countdown.timer) |
| | | countdown.timer = null |
| | | } |
| | | countdown.isExpired = false |
| | | |
| | | // 立即更新一次 |
| | | updateCountdown(endTime) |
| | | |
| | | // 每秒更新 |
| | | countdown.timer = setInterval(() => { |
| | | // 立即更新一次 |
| | | updateCountdown(endTime) |
| | | }, 1000) |
| | | } |
| | | |
| | | onLoad(async (query: any) => { |
| | | orderId.value = query.id |
| | | goodsType.value = Number(query.goodsType) |
| | | await getOrderDetail(goodsType.value, orderId.value) |
| | | }) |
| | | // 每秒更新 |
| | | countdown.timer = setInterval(() => { |
| | | updateCountdown(endTime) |
| | | }, 1000) |
| | | } |
| | | |
| | | onUnload(() => { |
| | | if (countdown.timer) { |
| | | clearInterval(countdown.timer) |
| | | countdown.timer = null |
| | | } |
| | | }) |
| | | const getOrderDetail = async (type: number, id: string) => { |
| | | let res = null |
| | | if (type == 1) { |
| | | res = await getBigGiftOrderDetail(id) |
| | | } else { |
| | | res = await getPhysicalOrderDetail(id) |
| | | } |
| | | console.log('res res res', res) |
| | | if (res.code == 200) { |
| | | // 只有待支付状态才启动倒计时 |
| | | if (res.data.status === 1 && res.data.createTime) { |
| | | startCountdown(res.data.createTime) |
| | | } |
| | | status.value = res.data.status |
| | | orderDetail.value = res.data |
| | | } |
| | | } |
| | | |
| | | const toPayMoney = async () => { |
| | | // uni.navigateTo({ |
| | | // url: `/pagesA/placeAnOrder/placeAnOrder?type=${goodsType.value}&id=${orderDetail.value.goodsId}&orderId=${orderId.value}` |
| | | // }) |
| | | let res = null |
| | | if (goodsType.value == 1) { |
| | | res = await bigGiftPayNow(orderId.value) |
| | | } else { |
| | | res = await physicalPayNow(orderId.value) |
| | | } |
| | | if (res.code == 200) { |
| | | payMoney(res.data) |
| | | } |
| | | } |
| | | |
| | | const toPayBalance = () => { |
| | | uni.navigateTo({ |
| | | url: `/pagesA/placeAnOrder/placeAnOrder?id=${orderDetail.value.goodsId}&isBalance=1&type=${goodsType.value}&orderId=${orderId.value}` |
| | | }) |
| | | } |
| | | const payMoney = (payInfo: any) => { |
| | | uni.requestPayment({ |
| | | timeStamp: payInfo.paymentParams.timestamp, |
| | | nonceStr: payInfo.paymentParams.noncestr, |
| | | package: payInfo.paymentParams.package, |
| | | signType: payInfo.paymentParams.signType, |
| | | paySign: payInfo.paymentParams.sign, |
| | | success: (resp) => { |
| | | uni.redirectTo({ |
| | | url: '/pagesA/paySuccess/paySuccess' |
| | | }) |
| | | }, |
| | | fail: (err) => { |
| | | console.log('err', err) |
| | | } |
| | | }); |
| | | } |
| | | |
| | | const toConfirm = async () => { |
| | | let res = null |
| | | if (goodsType.value == 1) { |
| | | res = await bigGiftConfirm(orderId.value) |
| | | } else { |
| | | res = await physicalConfirm(orderId.value) |
| | | } |
| | | if (res.code == 200) { |
| | | uni.showToast({ |
| | | title: '确认收货成功', |
| | | icon: 'success' |
| | | }) |
| | | onLoad(async (query : any) => { |
| | | orderId.value = query.id |
| | | goodsType.value = Number(query.goodsType) |
| | | await getOrderDetail(goodsType.value, orderId.value) |
| | | }) |
| | | |
| | | onUnload(() => { |
| | | if (countdown.timer) { |
| | | clearInterval(countdown.timer) |
| | | countdown.timer = null |
| | | } |
| | | }) |
| | | const getOrderDetail = async (type : number, id : string) => { |
| | | let res = null |
| | | if (type == 1) { |
| | | res = await getBigGiftOrderDetail(id) |
| | | } else { |
| | | res = await getPhysicalOrderDetail(id) |
| | | } |
| | | console.log('res res res', res) |
| | | if (res.code == 200) { |
| | | // 只有待支付状态才启动倒计时 |
| | | if (res.data.status === 1 && res.data.createTime) { |
| | | startCountdown(res.data.createTime) |
| | | } |
| | | status.value = res.data.status |
| | | orderDetail.value = res.data |
| | | } |
| | | } |
| | | } |
| | | const back = () => { |
| | | uni.navigateBack(); |
| | | }; |
| | | |
| | | const toPayMoney = async () => { |
| | | // uni.navigateTo({ |
| | | // url: `/pagesA/placeAnOrder/placeAnOrder?type=${goodsType.value}&id=${orderDetail.value.goodsId}&orderId=${orderId.value}` |
| | | // }) |
| | | let res = null |
| | | if (goodsType.value == 1) { |
| | | res = await bigGiftPayNow(orderId.value) |
| | | } else { |
| | | res = await physicalPayNow(orderId.value) |
| | | } |
| | | if (res.code == 200) { |
| | | payMoney(res.data) |
| | | } |
| | | } |
| | | |
| | | const toPayBalance = () => { |
| | | uni.navigateTo({ |
| | | url: `/pagesA/placeAnOrder/placeAnOrder?id=${orderDetail.value.goodsId}&isBalance=1&type=${goodsType.value}&orderId=${orderId.value}` |
| | | }) |
| | | } |
| | | const payMoney = (payInfo : any) => { |
| | | uni.requestPayment({ |
| | | timeStamp: payInfo.paymentParams.timestamp, |
| | | nonceStr: payInfo.paymentParams.noncestr, |
| | | package: payInfo.paymentParams.package, |
| | | signType: payInfo.paymentParams.signType, |
| | | paySign: payInfo.paymentParams.sign, |
| | | success: (resp) => { |
| | | uni.redirectTo({ |
| | | url: '/pagesA/paySuccess/paySuccess' |
| | | }) |
| | | }, |
| | | fail: (err) => { |
| | | console.log('err', err) |
| | | } |
| | | }); |
| | | } |
| | | |
| | | const toConfirm = async () => { |
| | | let res = null |
| | | if (goodsType.value == 1) { |
| | | res = await bigGiftConfirm(orderId.value) |
| | | } else { |
| | | res = await physicalConfirm(orderId.value) |
| | | } |
| | | if (res.code == 200) { |
| | | uni.showToast({ |
| | | title: '确认收货成功', |
| | | icon: 'success' |
| | | }) |
| | | await getOrderDetail(goodsType.value, orderId.value) |
| | | } |
| | | } |
| | | const back = () => { |
| | | uni.navigateBack(); |
| | | }; |
| | | </script> |
| | | |
| | | <style> |
| | | page { |
| | | background: linear-gradient(180deg, rgba(58, 211, 247, 0.1) 0%, rgba(27, 168, 236, 0) 100%); |
| | | } |
| | | page { |
| | | background: linear-gradient(180deg, rgba(58, 211, 247, 0.1) 0%, rgba(27, 168, 236, 0) 100%); |
| | | } |
| | | </style> |
| | | <style scoped lang="scss"> |
| | | .color1 { |
| | | color: rgba(0, 0, 0, 0.45); |
| | | } |
| | | .color1 { |
| | | color: rgba(0, 0, 0, 0.45); |
| | | } |
| | | |
| | | .color2 { |
| | | color: #FF9023; |
| | | } |
| | | .color2 { |
| | | color: #FF9023; |
| | | } |
| | | |
| | | .color3 { |
| | | color: rgba(0, 0, 0, 0.65); |
| | | } |
| | | .color3 { |
| | | color: rgba(0, 0, 0, 0.65); |
| | | } |
| | | |
| | | .color4 { |
| | | color: #1BA8EC !important; |
| | | } |
| | | .color4 { |
| | | color: #1BA8EC !important; |
| | | } |
| | | |
| | | .color5 { |
| | | color: rgba(0, 0, 0, 0.5); |
| | | } |
| | | .color5 { |
| | | color: rgba(0, 0, 0, 0.5); |
| | | } |
| | | |
| | | .color6 { |
| | | color: #ff4d4f; |
| | | } |
| | | .color6 { |
| | | color: #ff4d4f; |
| | | } |
| | | |
| | | .bgcolor1 { |
| | | background-color: #fff; |
| | | } |
| | | .bgcolor1 { |
| | | background-color: #fff; |
| | | } |
| | | |
| | | .timeBox { |
| | | background: #FF9023; |
| | | border-radius: 8rpx; |
| | | color: #FFFFFF; |
| | | line-height: 27rpx; |
| | | font-size: 23rpx; |
| | | width: 38rpx; |
| | | text-align: center; |
| | | } |
| | | .timeBox { |
| | | background: #FF9023; |
| | | border-radius: 8rpx; |
| | | color: #FFFFFF; |
| | | line-height: 27rpx; |
| | | font-size: 23rpx; |
| | | width: 38rpx; |
| | | text-align: center; |
| | | } |
| | | |
| | | .bottomBtn { |
| | | position: fixed; |
| | | left: 50%; |
| | | transform: translate(-50%); |
| | | width: calc(100% - 39rpx * 2); |
| | | bottom: calc(env(safe-area-inset-bottom) + 56rpx); |
| | | font-weight: 600; |
| | | font-size: 35rpx; |
| | | color: #FFFFFF; |
| | | background: linear-gradient(270deg, #6BEADF 0%, #1BA8EC 100%); |
| | | box-shadow: 0rpx 8rpx 19rpx 0rpx rgba(27, 168, 236, 0.3); |
| | | border-radius: 67rpx; |
| | | line-height: 96rpx; |
| | | text-align: center; |
| | | } |
| | | .bottomBtn { |
| | | position: fixed; |
| | | left: 50%; |
| | | transform: translate(-50%); |
| | | width: calc(100% - 39rpx * 2); |
| | | bottom: calc(env(safe-area-inset-bottom) + 56rpx); |
| | | font-weight: 600; |
| | | font-size: 35rpx; |
| | | color: #FFFFFF; |
| | | background: linear-gradient(270deg, #6BEADF 0%, #1BA8EC 100%); |
| | | box-shadow: 0rpx 8rpx 19rpx 0rpx rgba(27, 168, 236, 0.3); |
| | | border-radius: 67rpx; |
| | | line-height: 96rpx; |
| | | text-align: center; |
| | | } |
| | | </style> |
| | |
| | | <view class="txt-center"> |
| | | <u-navbar title="支付成功" back-icon-name="arrow-leftward" :background="background" :border-bottom="false" |
| | | title-bold title-color="#000" /> |
| | | <image src="/static/image/mine/edit.png" class="w-231 h-231 mt-138" /> |
| | | <image src="/static/image/mine/success.png" class="w-231 h-231 mt-138" /> |
| | | <view class="mt-46 fs-31 lh-42 font-bold">支付成功</view> |
| | | <view class="mt-31 lh-33 fs-23 color1">{{ content }}</view> |
| | | <view @tap.stop="backHome" class="mt-65 lh-96 mx-183 br-67 white bgcolor1 fs-35">返回主页</view> |
| | |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { ref,reactive } from 'vue' |
| | | import { onLoad } from '@dcloudio/uni-app' |
| | | import { ref, reactive } from 'vue' |
| | | import { onLoad } from '@dcloudio/uni-app' |
| | | |
| | | const background = reactive({ |
| | | backgroundColor: "#fff", |
| | | }); |
| | | const content = ref('') |
| | | const background = reactive({ |
| | | backgroundColor: "#fff", |
| | | }); |
| | | const content = ref('') |
| | | |
| | | const backHome = () => { |
| | | uni.switchTab({ |
| | | url: '/pages/home/home' |
| | | }) |
| | | } |
| | | onLoad((options) => { |
| | | if (options.content) { |
| | | content.value = options.content |
| | | const backHome = () => { |
| | | uni.switchTab({ |
| | | url: '/pages/home/home' |
| | | }) |
| | | } |
| | | onLoad((options) => { |
| | | if (options.content) { |
| | | content.value = options.content |
| | | } |
| | | |
| | | }) |
| | | }) |
| | | </script> |
| | | |
| | | <style> |
| | | page { |
| | | background-color: #fff; |
| | | } |
| | | page { |
| | | background-color: #fff; |
| | | } |
| | | </style> |
| | | |
| | | <style scoped lang="scss"> |
| | | .color1 { |
| | | color: rgba(0, 0, 0, 0.65); |
| | | } |
| | | .color1 { |
| | | color: rgba(0, 0, 0, 0.65); |
| | | } |
| | | |
| | | .bgcolor1 { |
| | | background: linear-gradient(270deg, #6BEADF 0%, #1BA8EC 100%); |
| | | box-shadow: 0rpx 8rpx 19rpx 0rpx rgba(27, 168, 236, 0.3); |
| | | } |
| | | .bgcolor1 { |
| | | background: linear-gradient(270deg, #6BEADF 0%, #1BA8EC 100%); |
| | | box-shadow: 0rpx 8rpx 19rpx 0rpx rgba(27, 168, 236, 0.3); |
| | | } |
| | | </style> |
| | |
| | | <view class="bgcolor2 border3 pt-30 pb-42"> |
| | | <image @touchend="handleTouch" show-menu-by-longpress :src="imgBase64" |
| | | style="width: 550rpx;height: 550rpx;" /> |
| | | <!-- 隐藏的 canvas 用于转换 base64(2d 模式) --> |
| | | <canvas type="2d" canvas-id="tempCanvas" id="tempCanvas" |
| | | style="position: fixed; top: -9999px; width: 550px; height: 550px;"></canvas> |
| | | <view class="mt-18 fs-23 lh-33 color3">双击保存图片,分享给你好友吧</view> |
| | | <button open-type="share" class="mt-35 mx-115 lh-85 white fs-31 font-bold br-67 bgColor3 btnSty"> |
| | | 分享链接至微信好友</button> |
| | |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { ref, reactive } from "vue"; |
| | | import { ref, reactive, getCurrentInstance } from "vue"; |
| | | import { onShareAppMessage, onLoad } from '@dcloudio/uni-app' |
| | | import { saveImage } from '@/utils/utils.js' |
| | | import config from '../../config/index.js' |
| | | const userInfo = ref<any>({}); |
| | | const imgBase64 = ref('') |
| | | const background = reactive({ |
| | | backgroundColor: "transparent", |
| | | }); |
| | | const touchCount = ref(0) |
| | | const uploadedImageUrl = ref('') // 存储上传后的图片链接 |
| | | const instance = getCurrentInstance() |
| | | |
| | | onLoad(() => { |
| | | wx.showShareMenu({ |
| | | menus: ['shareAppMessage', 'shareTimeline'] |
| | | }) |
| | | userInfo.value = uni.getStorageSync('userInfo') |
| | | imgBase64.value = userInfo.value.promotionQrCode ? 'data:image/png; eyJlcnJjb2RlIjo0MTAzMCwiZXJybXNnIjoiaW52YWxpZCBwYWdlIHJpZDogNjk0ZGU3OTEtMGVjOTE1MGEtNDhjOWYyNzcifQ==' : '' |
| | | imgBase64.value = userInfo.value.promotionQrCode ? 'data:image/jpeg;base64,' + userInfo.value.promotionQrCode : '' |
| | | }) |
| | | |
| | | onShareAppMessage((e) => { |
| | |
| | | return num.toFixed(2).replace(/\d(?=(\d{3})+\.)/g, "$&,"); |
| | | }; |
| | | |
| | | // 将 base64 转换为临时文件(优先用 2d canvas 压缩生成 temp 文件,避免超限) |
| | | const base64ToTempFile = (base64Data: string): Promise<string> => { |
| | | return new Promise((resolve, reject) => { |
| | | drawBase64ToCanvas(base64Data).then(resolve).catch(reject) |
| | | }) |
| | | } |
| | | |
| | | // 使用 2d canvas 绘制 base64 图片并导出为临时文件(压缩防止超限) |
| | | const drawBase64ToCanvas = (base64Data: string): Promise<string> => { |
| | | return new Promise((resolve, reject) => { |
| | | // 目标尺寸适当缩小,减少文件体积 |
| | | const targetSize = 500 |
| | | const quality = 0.7 |
| | | const query = uni.createSelectorQuery() |
| | | // 作用域限定在当前组件,避免在自定义组件中拿不到节点 |
| | | // @ts-ignore |
| | | if (instance?.proxy) { |
| | | // @ts-ignore |
| | | query.in(instance.proxy) |
| | | } |
| | | query |
| | | .select('#tempCanvas') |
| | | .fields({ node: true, size: true }) |
| | | .exec((res) => { |
| | | if (!res || !res[0] || !res[0].node) { |
| | | reject(new Error('canvas 节点获取失败')) |
| | | return |
| | | } |
| | | const canvas = res[0].node |
| | | const ctx = canvas.getContext('2d') |
| | | const dpr = uni.getSystemInfoSync().pixelRatio || 1 |
| | | canvas.width = targetSize * dpr |
| | | canvas.height = targetSize * dpr |
| | | ctx.scale(dpr, dpr) |
| | | |
| | | const img = canvas.createImage() |
| | | img.onload = () => { |
| | | ctx.clearRect(0, 0, targetSize, targetSize) |
| | | ctx.drawImage(img, 0, 0, targetSize, targetSize) |
| | | uni.canvasToTempFilePath({ |
| | | canvas, |
| | | quality, |
| | | destWidth: targetSize, |
| | | destHeight: targetSize, |
| | | success: (res2) => resolve(res2.tempFilePath), |
| | | fail: (err) => { |
| | | console.error('canvas 导出失败:', err) |
| | | reject(err) |
| | | } |
| | | }) |
| | | } |
| | | img.onerror = (err) => { |
| | | console.error('图片加载失败:', err) |
| | | reject(err) |
| | | } |
| | | img.src = base64Data |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | // 上传 base64 图片并获取链接 |
| | | const uploadBase64Image = async (base64Data: string, showLoading = false): Promise<string> => { |
| | | return new Promise((resolve, reject) => { |
| | | try { |
| | | if (showLoading) { |
| | | uni.showLoading({ |
| | | title: '正在处理图片...' |
| | | }) |
| | | } |
| | | |
| | | // 将 base64 转换为临时文件 |
| | | base64ToTempFile(base64Data).then((tempFilePath) => { |
| | | // 上传文件 |
| | | uni.uploadFile({ |
| | | url: config.uploadUrl, |
| | | name: 'file', |
| | | filePath: tempFilePath, |
| | | header: { |
| | | 'Authorization': uni.getStorageSync('token') || '', |
| | | }, |
| | | success: (res) => { |
| | | try { |
| | | const data = JSON.parse(res.data).data |
| | | const imageUrl = config.imageUrl + data |
| | | uploadedImageUrl.value = imageUrl |
| | | if (showLoading) { |
| | | uni.hideLoading() |
| | | } |
| | | resolve(imageUrl) |
| | | } catch (err) { |
| | | console.error('解析上传结果失败:', err) |
| | | if (showLoading) { |
| | | uni.hideLoading() |
| | | uni.showToast({ |
| | | title: '处理失败,请重试', |
| | | icon: 'error' |
| | | }) |
| | | } |
| | | reject(err) |
| | | } |
| | | }, |
| | | fail: (err) => { |
| | | console.error('上传失败:', err) |
| | | if (showLoading) { |
| | | uni.hideLoading() |
| | | uni.showToast({ |
| | | title: '上传失败,请重试', |
| | | icon: 'error' |
| | | }) |
| | | } |
| | | reject(err) |
| | | }, |
| | | complete: () => { |
| | | // 清理临时文件 |
| | | uni.getFileSystemManager().unlink({ |
| | | filePath: tempFilePath, |
| | | fail: (err) => { |
| | | console.error('清理临时文件失败:', err) |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | }).catch((err) => { |
| | | console.error('处理图片失败:', err) |
| | | if (showLoading) { |
| | | uni.hideLoading() |
| | | uni.showToast({ |
| | | title: '处理失败,请重试', |
| | | icon: 'error' |
| | | }) |
| | | } |
| | | reject(err) |
| | | }) |
| | | } catch (err) { |
| | | console.error('处理图片失败:', err) |
| | | if (showLoading) { |
| | | uni.hideLoading() |
| | | uni.showToast({ |
| | | title: '处理失败,请重试', |
| | | icon: 'error' |
| | | }) |
| | | } |
| | | reject(err) |
| | | } |
| | | }) |
| | | } |
| | | |
| | | const handleTouch = () => { |
| | | touchCount.value++; |
| | | setTimeout(() => { |
| | | if (touchCount.value >= 2) { |
| | | if (imgBase64.value) { |
| | | saveImage(imgBase64.value) |
| | | if (uploadedImageUrl.value) { |
| | | // 如果已有上传后的链接,直接使用 |
| | | saveImage(uploadedImageUrl.value) |
| | | } else if (imgBase64.value) { |
| | | // 如果没有链接,直接保存 base64(内部会转成临时文件,并压缩) |
| | | saveBase64Image(imgBase64.value) |
| | | } |
| | | } |
| | | touchCount.value = 0; |
| | | }, 250); |
| | | } |
| | | |
| | | // 直接保存 base64 图片(使用 canvas 转换,避免写入临时文件) |
| | | const saveBase64Image = (base64Data: string) => { |
| | | uni.showLoading({ |
| | | title: '正在保存图片...' |
| | | }); |
| | | |
| | | uni.getSetting({ |
| | | success: (res) => { |
| | | const saveToAlbum = () => { |
| | | // 直接使用 canvas 转换 base64 为临时文件 |
| | | drawBase64ToCanvas(base64Data).then((tempFilePath) => { |
| | | uni.saveImageToPhotosAlbum({ |
| | | filePath: tempFilePath, |
| | | success: () => { |
| | | uni.hideLoading(); |
| | | uni.showToast({ |
| | | title: "保存成功!" |
| | | }); |
| | | }, |
| | | fail: (err) => { |
| | | console.error("保存失败:", err); |
| | | uni.hideLoading(); |
| | | uni.showToast({ |
| | | title: "保存失败,请重试!", |
| | | icon: 'error' |
| | | }); |
| | | } |
| | | }); |
| | | }).catch((err) => { |
| | | console.error("转换图片失败:", err); |
| | | uni.hideLoading(); |
| | | uni.showToast({ |
| | | title: "保存失败,请重试!", |
| | | icon: 'error' |
| | | }); |
| | | }); |
| | | }; |
| | | |
| | | if (!res.authSetting["scope.writePhotosAlbum"]) { |
| | | uni.authorize({ |
| | | scope: "scope.writePhotosAlbum", |
| | | success: saveToAlbum, |
| | | fail: () => { |
| | | uni.hideLoading(); |
| | | uni.showModal({ |
| | | title: "权限未授权", |
| | | content: "请前往设置中开启相册权限", |
| | | success: (res) => { |
| | | if (res.confirm) { |
| | | uni.openSetting(); |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | }); |
| | | } else { |
| | | saveToAlbum(); |
| | | } |
| | | }, |
| | | fail: () => { |
| | | uni.hideLoading(); |
| | | uni.showToast({ |
| | | title: "获取权限失败!", |
| | | icon: 'error' |
| | | }); |
| | | } |
| | | }); |
| | | } |
| | | </script> |
| | | |
| | | <style> |
| | |
| | | uni.showLoading({ |
| | | title: '正在保存图片...' |
| | | }); |
| | | |
| | | // 检查是否是 base64 格式 |
| | | const isBase64 = url && (url.startsWith('data:image') || url.startsWith('base64://')); |
| | | |
| | | // 如果是 base64,需要先转换为临时文件 |
| | | const getImagePath = (imageUrl) => { |
| | | return new Promise((resolve, reject) => { |
| | | if (isBase64) { |
| | | // base64 图片,使用 canvas 转换为临时文件 |
| | | convertBase64ToTempFile(imageUrl).then(resolve).catch(reject); |
| | | } else { |
| | | // 普通图片链接,直接获取图片信息 |
| | | uni.getImageInfo({ |
| | | src: imageUrl, |
| | | success: (res) => { |
| | | resolve(res.path); |
| | | }, |
| | | fail: reject |
| | | }); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | uni.getSetting({ |
| | | success: async (res) => { |
| | | if (!res.authSetting["scope.writePhotosAlbum"]) { |
| | | uni.authorize({ |
| | | scope: "scope.writePhotosAlbum", |
| | | success: async () => { |
| | | const res = await uni.getImageInfo({ |
| | | src: url |
| | | }); |
| | | uni.saveImageToPhotosAlbum({ |
| | | filePath: res.path, |
| | | success: () => { |
| | | uni.hideLoading(); |
| | | uni.showToast({ |
| | | title: "保存成功!" |
| | | }); |
| | | }, |
| | | fail: (err) => { |
| | | console.error("保存失败:", err); |
| | | uni.showToast({ |
| | | title: "保存失败,请重试!", |
| | | icon: 'error' |
| | | }); |
| | | } |
| | | }); |
| | | try { |
| | | const filePath = await getImagePath(url); |
| | | uni.saveImageToPhotosAlbum({ |
| | | filePath: filePath, |
| | | success: () => { |
| | | uni.hideLoading(); |
| | | uni.showToast({ |
| | | title: "保存成功!" |
| | | }); |
| | | }, |
| | | fail: (err) => { |
| | | console.error("保存失败:", err); |
| | | uni.hideLoading(); |
| | | uni.showToast({ |
| | | title: "保存失败,请重试!", |
| | | icon: 'error' |
| | | }); |
| | | } |
| | | }); |
| | | } catch (err) { |
| | | console.error("处理图片失败:", err); |
| | | uni.hideLoading(); |
| | | uni.showToast({ |
| | | title: "保存失败,请重试!", |
| | | icon: 'error' |
| | | }); |
| | | } |
| | | }, |
| | | fail: () => { |
| | | uni.hideLoading(); |
| | |
| | | } |
| | | }); |
| | | } else { |
| | | const res = await uni.getImageInfo({ |
| | | src: url |
| | | }); |
| | | uni.saveImageToPhotosAlbum({ |
| | | filePath: res.path, |
| | | success: () => { |
| | | uni.hideLoading(); |
| | | uni.showToast({ |
| | | title: "保存成功!" |
| | | }); |
| | | }, |
| | | fail: (err) => { |
| | | console.error("保存失败:", err); |
| | | uni.showToast({ |
| | | title: "保存失败,请重试!", |
| | | icon: 'error' |
| | | }); |
| | | } |
| | | }); |
| | | try { |
| | | const filePath = await getImagePath(url); |
| | | uni.saveImageToPhotosAlbum({ |
| | | filePath: filePath, |
| | | success: () => { |
| | | uni.hideLoading(); |
| | | uni.showToast({ |
| | | title: "保存成功!" |
| | | }); |
| | | }, |
| | | fail: (err) => { |
| | | console.error("保存失败:", err); |
| | | uni.hideLoading(); |
| | | uni.showToast({ |
| | | title: "保存失败,请重试!", |
| | | icon: 'error' |
| | | }); |
| | | } |
| | | }); |
| | | } catch (err) { |
| | | console.error("处理图片失败:", err); |
| | | uni.hideLoading(); |
| | | uni.showToast({ |
| | | title: "保存失败,请重试!", |
| | | icon: 'error' |
| | | }); |
| | | } |
| | | } |
| | | }, |
| | | fail: () => { |
| | |
| | | }); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // 将 base64 转换为临时文件(直接写入文件,避免 getImageInfo 失败) |
| | | const convertBase64ToTempFile = (base64Data) => { |
| | | return new Promise((resolve, reject) => { |
| | | try { |
| | | const fs = uni.getFileSystemManager(); |
| | | // 兼容不同前缀 |
| | | const match = /^data:image\/(\w+);base64,/.exec(base64Data); |
| | | const ext = match ? match[1] : 'jpg'; |
| | | const pureBase64 = base64Data.replace(/^data:image\/\w+;base64,/, '').replace(/^base64:\/\//, ''); |
| | | const filePath = `${wx.env.USER_DATA_PATH}/temp_${Date.now()}.${ext}`; |
| | | const arrayBuffer = (wx.base64ToArrayBuffer || uni.base64ToArrayBuffer)(pureBase64); |
| | | fs.writeFile({ |
| | | filePath, |
| | | data: arrayBuffer, |
| | | encoding: 'binary', |
| | | success: () => resolve(filePath), |
| | | fail: (err) => { |
| | | console.error('writeFile base64 失败:', err); |
| | | reject(err); |
| | | } |
| | | }); |
| | | } catch (err) { |
| | | reject(err); |
| | | } |
| | | }); |
| | | }; |