第一次上传

This commit is contained in:
Ls
2026-03-09 16:39:03 +08:00
commit 3d9efaf15c
924 changed files with 326227 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,53 @@
<template>
<view>
<view class="" v-if="props.show">
<!-- <qf-image-cropper :src="props.url" :width="props.width" :height="props.height" :radius="20"
@crop="handleCrop"></qf-image-cropper> -->
<Tcropper :imageUrl="props.url" :width="props.width" @cancel="cancel" :height="props.height" :radius="0" @confirm='handleCrop' ></Tcropper>
</view>
</view>
</template>
<script setup lang="ts">
import { ref, watch } from 'vue';
import { onBeforeUnmount, onMounted, reactive } from 'vue';
import Tcropper from "../uni_modules/t-cropper/components/t-cropper/t-cropper.vue"
import { Service } from '@/Service/Service'
// const props = defineProps({
// show : string,
// // url : string,
// // width : number,
// // height:number,
// // upType:string,
// // retFun:Function
// });
let props = defineProps(["show","url",'width','height','upType',"retFun","imgName"]);
onMounted(() => {
});
const handleCrop = (e) => {
let arr = e.tempFilePath.split('.')
let name = arr[arr.length - 1]
Service.uploadH5(e.tempFilePath, name ,(data:any)=>{
props.retFun( {name:props.imgName,url:data})
})
}
const cancel=()=>{
console.log(11111);
uni.$emit('cancle')
}
</script>
<style>
</style>

View File

@@ -0,0 +1,466 @@
<template>
<view class="member-code-page">
<!-- 沉浸式状态栏 -->
<view class="status-bar"></view>
<!-- 顶部导航 -->
<view class="nav-bar">
<image class="back-icon" src="/static/icons/back.svg" @click="Service.GoPageBack()" mode="aspectFit" />
<text class="nav-title">会员码</text>
<view class="nav-placeholder"></view>
</view>
<!-- 主要内容区域 -->
<view class="content">
<!-- 会员卡片 -->
<view class="member-card">
<!-- 用户信息 -->
<view class="user-section">
<image class="user-avatar" :src="Service.GetMateUrlByImg(userData.headImg)" mode="aspectFill" />
<view class="user-info">
<text class="user-name">{{ userData.nick }}</text>
<!-- ID和会员等级标签在一排 -->
<view class="tags-row">
<view class="user-id-tag" @click="copyMemberId">
<text class="ri-vip-crown-2-fill id-icon"></text>
<text class="id-text">ID: {{ userData.userNo }}</text>
<text class="ri-file-copy-line id-copy"></text>
</view>
<!-- <view class="user-member-tag">
<text class="ri-vip-crown-fill member-icon"></text>
<text class="member-text">黄金会员</text>
</view> -->
</view>
</view>
</view>
<!-- 分割线 -->
<view class="divider"></view>
<!-- 条形码区域 -->
<view class="barcode-section">
<u-barcode value="1234567890" :displayValue='false' :width="300"
:height="100" />
<text class="barcode-number">{{ user.memberCode }}</text>
</view>
<!-- 二维码区域 -->
<view class="qrcode-section">
<view class="qrcode-wrapper" @click="previewQrcode">
<view class="qrcode-placeholder">
<text class="ri-qr-code-line qrcode-icon"></text>
</view>
</view>
<text class="code-tip">向商家出示会员码,扫码享受积分优惠</text>
</view>
<!-- 刷新提示 -->
<view class="refresh-section">
<text class="ri-time-line refresh-icon"></text>
<text class="refresh-text">{{ refreshCountdown }}秒后自动刷新</text>
<view class="refresh-btn" @click="refreshCode">
<text class="ri-refresh-line btn-icon"></text>
<text class="btn-text">刷新</text>
</view>
</view>
</view>
<!-- 温馨提示 -->
<view class="tips-section">
<view class="tips-title">
<text class="ri-lightbulb-line tips-icon"></text>
<text class="title-text">温馨提示</text>
</view>
<view class="tips-list">
<text class="tips-item">• 会员码每分钟自动更新,确保使用安全</text>
<text class="tips-item">• 结账时请向商家出示此码</text>
<text class="tips-item">• 消费可获得积分,积分可抵扣现金</text>
</view>
</view>
</view>
</view>
</template>
<script lang="ts" setup>
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { vpUserService, Service } from '@/Service/vp/vpUserService'
import { onLoad } from '@dcloudio/uni-app'
// 用户数据
const user = ref({
nickname: '美食达人',
avatar: 'https://picsum.photos/200/200?random=100',
points: 2580,
memberLevel: 'gold',
memberId: '8888888',
memberCode: 'VIP8888888888888'
})
let userData = ref<any>({})
// 刷新倒计时(秒)
const refreshCountdown = ref(60)
let refreshTimer = null
let countdownTimer = null
// 会员等级文本
const memberLevelText = computed(() => {
const levelMap = {
'gold': '黄金会员',
'platinum': '铂金会员',
'diamond': '钻石会员'
}
return levelMap[user.value.memberLevel] || '普通会员'
})
onLoad(() => {
fetchUserInfo()
})
// 获取用户信息
const fetchUserInfo = () => {
vpUserService.GetUserInfo().then(res => {
if (res.code == 0) {
userData.value = res.data.userInfo
console.log(userData.value);
}
})
}
// 刷新会员码
const refreshCode = () => {
// 生成新的会员码
const newCode = 'VIP' + Date.now().toString().slice(-12)
user.value.memberCode = newCode
// 重置倒计时
refreshCountdown.value = 60
uni.showToast({
title: '会员码已刷新',
icon: 'success',
duration: 1500
})
}
// 预览条形码
const previewBarcode = () => {
uni.showToast({
title: '条形码预览功能开发中',
icon: 'none'
})
}
// 预览二维码
const previewQrcode = () => {
uni.showToast({
title: '二维码预览功能开发中',
icon: 'none'
})
}
// 复制会员ID
const copyMemberId = () => {
uni.setClipboardData({
data: user.value.memberId,
success: () => {
uni.showToast({
title: '会员ID已复制',
icon: 'success',
duration: 2000
})
}
})
}
// 开始自动刷新
const startAutoRefresh = () => {
// 清除之前的定时器
if (refreshTimer) {
clearInterval(refreshTimer)
}
if (countdownTimer) {
clearInterval(countdownTimer)
}
// 倒计时定时器(每秒更新)
countdownTimer = setInterval(() => {
refreshCountdown.value--
if (refreshCountdown.value <= 0) {
refreshCountdown.value = 60
// 自动刷新会员码
const newCode = 'VIP' + Date.now().toString().slice(-12)
user.value.memberCode = newCode
}
}, 1000)
}
// 清理定时器
onUnmounted(() => {
if (refreshTimer) {
clearInterval(refreshTimer)
}
if (countdownTimer) {
clearInterval(countdownTimer)
}
})
</script>
<style lang="scss" scoped>
/* 引入全局标签样式 */
@import '@/styles/member-tags.scss';
/* 现代化会员码页面 */
.member-code-page {
min-height: 100vh;
background: linear-gradient(180deg, #FFF4E6 0%, #F5F5F5 100%);
display: flex;
flex-direction: column;
}
/* 状态栏 */
.status-bar {
background: linear-gradient(135deg, #FF6B00, #FF9500);
height: var(--status-bar-height);
width: 100%;
}
/* 导航栏 */
.nav-bar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 20rpx 24rpx;
background: linear-gradient(135deg, #FF6B00, #FF9500);
}
.back-icon {
width: 48rpx;
height: 48rpx;
padding: 8rpx;
}
.nav-title {
font-size: 36rpx;
font-weight: 600;
color: #FFFFFF;
}
.nav-placeholder {
width: 40rpx;
}
/* 内容区域 */
.content {
flex: 1;
padding: 32rpx 24rpx;
display: flex;
flex-direction: column;
align-items: center;
}
/* 会员卡片 */
.member-card {
width: 100%;
background: #FFFFFF;
border-radius: 24rpx;
padding: 32rpx;
box-shadow: 0 4rpx 20rpx rgba(255, 107, 0, 0.12);
margin-bottom: 24rpx;
}
/* 用户信息区域 */
.user-section {
display: flex;
align-items: center;
margin-bottom: 32rpx;
}
.user-avatar {
width: 96rpx;
height: 96rpx;
border-radius: 48rpx;
margin-right: 20rpx;
border: 3rpx solid #FF6B00;
}
.user-info {
flex: 1;
display: flex;
flex-direction: column;
gap: 8rpx;
}
.user-name {
font-size: 32rpx;
font-weight: 600;
color: #222222;
margin-bottom: 10rpx;
}
/* 分割线 */
.divider {
height: 1rpx;
background: linear-gradient(90deg, transparent, #E0E0E0, transparent);
margin-bottom: 32rpx;
}
/* 条形码区域 */
.barcode-section {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 32rpx;
}
.barcode-wrapper {
width: 480rpx;
background: #F8F8F8;
border-radius: 12rpx;
padding: 20rpx 32rpx;
margin-bottom: 16rpx;
}
.barcode-placeholder {
display: flex;
align-items: center;
justify-content: center;
}
.barcode-lines {
font-size: 40rpx;
color: #000000;
letter-spacing: 2rpx;
font-weight: 900;
line-height: 1;
}
.barcode-number {
font-size: 32rpx;
font-weight: 600;
color: #222222;
letter-spacing: 4rpx;
}
/* 二维码区域 */
.qrcode-section {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 32rpx;
}
.qrcode-wrapper {
width: 360rpx;
height: 360rpx;
background: #F8F8F8;
border-radius: 16rpx;
padding: 24rpx;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20rpx;
}
.qrcode-placeholder {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background: #000000;
border-radius: 8rpx;
}
.qrcode-icon {
font-size: 200rpx;
color: #FFFFFF;
}
.code-tip {
font-size: 22rpx;
color: #999999;
text-align: center;
}
/* 刷新区域 */
.refresh-section {
display: flex;
align-items: center;
justify-content: center;
gap: 8rpx;
}
.refresh-icon {
font-size: 24rpx;
color: #FF6B00;
}
.refresh-text {
font-size: 24rpx;
color: #666666;
text-align: center;
}
.refresh-btn {
display: flex;
align-items: center;
gap: 4rpx;
background: linear-gradient(135deg, #FF6B00, #FF9500);
padding: 10rpx 20rpx;
border-radius: 24rpx;
}
.btn-icon {
font-size: 20rpx;
color: #FFFFFF;
}
.btn-text {
font-size: 24rpx;
color: #FFFFFF;
font-weight: 500;
}
/* 温馨提示 */
.tips-section {
width: 100%;
background: #FFFFFF;
border-radius: 16rpx;
padding: 24rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
}
.tips-title {
display: flex;
align-items: center;
gap: 8rpx;
margin-bottom: 16rpx;
}
.tips-icon {
font-size: 28rpx;
color: #FFA500;
}
.title-text {
font-size: 28rpx;
font-weight: 600;
color: #222222;
}
.tips-list {
display: flex;
flex-direction: column;
gap: 12rpx;
}
.tips-item {
font-size: 24rpx;
color: #666666;
line-height: 1.6;
}
</style>

View File

@@ -0,0 +1 @@
@import './styles/index.scss';