Commit 4fe250d2 authored by spc's avatar spc

Merge branch 'feihesanqi_20251014' of http://gitlab.dui88.com/fh/20250528_FHQ1...

Merge branch 'feihesanqi_20251014' of http://gitlab.dui88.com/fh/20250528_FHQ1 into feihesanqi_20251014
parents 48c1feab 06e69514
......@@ -56,3 +56,6 @@ export const assistInviteJSON = (invitationCode, wxUnionId) => api.post('/c/acti
invitationCode,
wxUnionId
});
//获取邀请记录列表接口
export const getInvitationListJSON = () => api.get('/c/activity/origin_invite/invitationList');
......@@ -54,13 +54,73 @@
}
}
.signedbg_icon {
position: absolute;
width: 122rpx;
height: 122rpx;
left: 50%;
.signedbg_icon_container {
position: fixed;
top: 50%;
transform: translate(-50%, -50%);
z-index: 2;
left: 50%;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
pointer-events: none;
z-index: 10;
.signedbg_icon {
position: fixed;
width: 122rpx;
height: 122rpx;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.signedbg_icon_animating {
animation: signedIconFly 1.5s linear 1;
z-index: 5;
}
}
}
/* 金币飞向右下角动画 - 适配不同屏幕 */
@keyframes signedIconFly {
0% {
transform: translate(-50%, -50%) scale(1.3) rotate(0deg);
opacity: 1;
}
15% {
transform: translate(calc(-50% + 80rpx), calc(-50% + 100rpx)) scale(1.25) rotate(8deg);
opacity: 1;
}
30% {
transform: translate(calc(-50% + 140rpx), calc(-50% + 220rpx)) scale(1.2) rotate(14deg);
opacity: 1;
}
45% {
transform: translate(calc(-50% + 180rpx), calc(-50% + 340rpx)) scale(1.1) rotate(15deg);
opacity: 0.95;
}
60% {
transform: translate(calc(-50% + 205rpx), calc(-50% + 420rpx)) scale(0.95) rotate(20deg);
opacity: 0.85;
}
75% {
transform: translate(calc(-50% + 215rpx), calc(-50% + 480rpx)) scale(0.6) rotate(30deg);
opacity: 0.7;
}
90% {
transform: translate(calc(-50% + 220rpx), calc(-50% + 530rpx)) scale(0.25) rotate(40deg);
opacity: 0.4;
}
100% {
transform: translate(calc(-50% + 225rpx), calc(-50% + 580rpx)) scale(0) rotate(45deg);
opacity: 0;
}
}
......@@ -8,12 +8,14 @@
<image class="tips_title" :src="$baseUrl + `integral/1023/signedTitle.png`" mode="aspectFit" />
<text class="points_text">获得{{ points }}积分</text>
</view>
<image class="signedbg_icon" :src="$baseUrl + `integral/1023/jifenIcon1.png`" mode="aspectFit" />
<view class="signedbg_icon_container">
<image class="signedbg_icon" :class="{ 'signedbg_icon_animating': isAnimating }" :src="$baseUrl + `integral/1023/jifenIcon1.png`" mode="aspectFit" />
</view>
</view>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
import { defineProps, defineEmits, ref, watch } from 'vue';
// Props 定义
const props = defineProps({
......@@ -30,9 +32,22 @@ const props = defineProps({
// Emits 定义
const emit = defineEmits(['close']);
// 关闭弹窗
// 是否正在播放动画
const isAnimating = ref(false);
// 关闭弹窗 - 点击时播放动画,动画结束后关闭
const handleClose = () => {
emit('close');
// 如果正在播放动画,则不重复触发
if (isAnimating.value) return;
// 开始播放动画
isAnimating.value = true;
// 动画播放完毕后(1.5秒)关闭弹窗
setTimeout(() => {
isAnimating.value = false;
emit('close');
}, 1500);
};
</script>
......
......@@ -130,6 +130,7 @@
import { ref, watch, onMounted, computed } from "vue";
import { onLoad } from "@dcloudio/uni-app";
import { useUserStore } from "../../stores/user.js";
import { useIntegralStore } from "../../stores/integral.js";
import PickerCustom from "../PickerCustom.vue";
import MultiSelectLayer from "../MultiSelectLayer.vue";
import { uploadImage } from "../../api/common.js";
......@@ -138,6 +139,9 @@ import { updateBabyInfo, getGestationalWeeks } from "../../api/user.js";
import { usePageCfgStore } from "../../stores/pageCfg";
import md from "../../md.js";
import { jump, JumpType } from "../../utils/index.js";
import { useGlobalStore } from "../../stores/global.js";
const globalStore = useGlobalStore();
// Props 定义
const props = defineProps({
......@@ -534,6 +538,9 @@ const onSubmit = async (e) => {
icon: "success",
});
//获取任务奖品
await checkAndUpdateTaskResult();
// 触发成功事件
emit('success');
// 关闭弹窗
......@@ -546,6 +553,19 @@ const onSubmit = async (e) => {
}
};
// 检查任务结果并更新全局状态
const checkAndUpdateTaskResult = async () => {
const integralStore = useIntegralStore();
await integralStore.queryTodoResultServer();
console.log('queryTodoResult:', integralStore.queryTodoResult);
if(integralStore.queryTodoResult?.success && integralStore.queryTodoResult?.data?.length > 0) {
globalStore.isShowTaskComplete = true;
globalStore.taskCompletePoints = integralStore.queryTodoResult.data[0]?.actualCredits;
globalStore.taskCompleteTitle = integralStore.queryTodoResult.data[0]?.taskName;
}
};
const handleClose = () => {
emit('close');
};
......
{
"ok": true,
"success": true,
"msg": "获取成功",
"code": "000000",
"data": [
{
"id": 1001,
"activityId": 1,
"inviterUserId": 123456,
"inviteeUserId": 234567,
"inviteePhone": "136****2718",
"inviteeName": "张**",
"inviteeIcon": "https://example.com/icon1.png",
"createTime": "2025-09-11 23:23:23"
},
{
"id": 1002,
"activityId": 1,
"inviterUserId": 123456,
"inviteeUserId": 234568,
"inviteePhone": "138****4567",
"inviteeName": "李**",
"inviteeIcon": "https://example.com/icon2.png",
"createTime": "2025-09-10 15:30:45"
},
{
"id": 1003,
"activityId": 1,
"inviterUserId": 123456,
"inviteeUserId": 234569,
"inviteePhone": "139****7890",
"inviteeName": "王**",
"inviteeIcon": "https://example.com/icon3.png",
"createTime": "2025-09-09 09:15:20"
},
{
"id": 1004,
"activityId": 1,
"inviterUserId": 123456,
"inviteeUserId": 234570,
"inviteePhone": "135****1234",
"inviteeName": "赵**",
"inviteeIcon": "https://example.com/icon4.png",
"createTime": "2025-09-08 18:45:30"
},
{
"id": 1005,
"activityId": 1,
"inviterUserId": 123456,
"inviteeUserId": 234571,
"inviteePhone": "137****5678",
"inviteeName": "钱**",
"inviteeIcon": "https://example.com/icon5.png",
"createTime": "2025-09-07 12:20:15"
},
{
"id": 1006,
"activityId": 1,
"inviterUserId": 123456,
"inviteeUserId": 234572,
"inviteePhone": "150****9012",
"inviteeName": "孙**",
"inviteeIcon": "https://example.com/icon6.png",
"createTime": "2025-09-06 10:30:25"
},
{
"id": 1007,
"activityId": 1,
"inviterUserId": 123456,
"inviteeUserId": 234573,
"inviteePhone": "151****3456",
"inviteeName": "周**",
"inviteeIcon": "https://example.com/icon7.png",
"createTime": "2025-09-05 16:15:40"
},
{
"id": 1008,
"activityId": 1,
"inviterUserId": 123456,
"inviteeUserId": 234574,
"inviteePhone": "152****7890",
"inviteeName": "吴**",
"inviteeIcon": "https://example.com/icon8.png",
"createTime": "2025-09-04 14:50:55"
}
]
}
......@@ -10,9 +10,9 @@
<!-- 邀请奖品弹窗 -->
<InvitePrizePanel
:visible="globalStore.isShowInvitePrizePanel"
:inviteCount="1"
:prizeName="'奖品名称奖品名称'"
:prizeImage="''"
:inviteCount="globalStore.inviteCount"
:prizeName="globalStore.prizeName"
:prizeImage="globalStore.prizeImage"
@close="handleCloseInvitePrizePanel"
@record="handleInvitePrizePanelRecord"
@prize="handleInvitePrizePanelPrize"
......@@ -179,7 +179,7 @@ const checkAndUpdateTaskResult = async () => {
onMounted(async () => {
// globalStore.isShowTaskComplete = true;//?????????
//签到奖品
//任务奖品
await checkAndUpdateTaskResult();
// 调用邀请活动首页接口
......@@ -194,7 +194,7 @@ onMounted(async () => {
globalStore.isShowInvitePrizePanel = true;
globalStore.inviteCount = res.data?.invitedCount;
globalStore.prizeName = unclaimedPrize?.prizeName;
globalStore.prizeImage = res.data?.prizeImageUrl;
globalStore.prizeImage = unclaimedPrize?.prizeImageUrl;
}
console.log('邀请活动首页数据:', res);
});
......
......@@ -16,7 +16,10 @@
z-index: 10;
.note_text {
text-align: center;
left: 50%;
width: 100%;
transform: translateX(-50%);
position: absolute;
font-size: 24rpx;
......
......@@ -9,11 +9,11 @@
<view class="records_list">
<view class="record_item" v-for="(record, index) in records" :key="index">
<view class="record_left">
<text class="phone_number">{{ record.phoneNumber }}</text>
<text class="invite_time">{{ record.inviteTime }}</text>
<text class="phone_number">{{ maskPhone(record.inviteePhone) }}</text>
<text class="invite_time">{{ formatTimestamp(record.createTime) }}</text>
</view>
<view class="record_right">
<text class="status_text">邀请成功</text>
<!-- <text class="status_text">邀请成功</text> -->
</view>
</view>
</view>
......@@ -21,43 +21,63 @@
</template>
<script setup>
import { ref } from 'vue';
import { ref, onMounted } from 'vue';
import { useIntegralStore } from '@/stores/integral';
import { showLoading, hideLoading } from '@/utils';
// 邀请记录数据
const records = ref([
{
phoneNumber: '136****2718',
inviteTime: '2025.09.11 23:23:23'
},
{
phoneNumber: '138****4567',
inviteTime: '2025.09.10 15:30:45'
},
{
phoneNumber: '139****7890',
inviteTime: '2025.09.09 09:15:20'
},
{
phoneNumber: '135****1234',
inviteTime: '2025.09.08 18:45:30'
},
{
phoneNumber: '137****5678',
inviteTime: '2025.09.07 12:20:15'
},
{
phoneNumber: '139****7890',
inviteTime: '2025.09.09 09:15:20'
},
{
phoneNumber: '135****1234',
inviteTime: '2025.09.08 18:45:30'
},
{
phoneNumber: '137****5678',
inviteTime: '2025.09.07 12:20:15'
const integralStore = useIntegralStore();
const records = ref([]);
// 手机号脱敏处理:中间四位显示为 ****
const maskPhone = (phone) => {
if (!phone) return '';
const phoneStr = String(phone);
// 如果是11位手机号,将中间4位替换为****
if (phoneStr.length === 11) {
return phoneStr.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
}
// 如果已经是脱敏格式(包含*),直接返回
if (phoneStr.includes('*')) {
return phoneStr;
}
// 其他情况返回原值
return phoneStr;
};
// 将时间戳转为 "2025.09.11 23:23:23" 格式
const formatTimestamp = (timestamp) => {
if (!timestamp) return '';
const date = new Date(timestamp);
// 检查日期是否有效
if (isNaN(date.getTime())) return '';
// 获取年月日时分秒
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
// 返回格式:2025.09.11 23:23:23
return `${year}.${month}.${day} ${hours}:${minutes}:${seconds}`;
};
onMounted(async () => {
showLoading('加载中...');
try {
await integralStore.getInvitationList();
if (integralStore.invitationList?.success && integralStore.invitationList?.data) {
records.value = integralStore.invitationList.data;
}
} catch (error) {
console.error('获取邀请记录失败:', error);
} finally {
hideLoading();
}
]);
});
</script>
<style lang="less" scoped>
......
......@@ -140,6 +140,11 @@ import { updateBabyInfo, getGestationalWeeks } from "../../api/user.js";
import { usePageCfgStore } from "../../stores/pageCfg";
import md from "../../md.js";
import { jump, JumpType } from "../../utils/index.js";
import { useIntegralStore } from "../../stores/integral.js";
import { useGlobalStore } from "../../stores/global.js";
const globalStore = useGlobalStore();
const userStore = useUserStore();
const pageType = ref("add");
const babyId = ref("");
......@@ -517,6 +522,10 @@ const onSubmit = async (e) => {
title: "提交成功",
icon: "success",
});
//获取任务奖品
await checkAndUpdateTaskResult();
uni.navigateBack();
} else {
uni.showToast({
......@@ -525,6 +534,22 @@ const onSubmit = async (e) => {
});
}
};
// 检查任务结果并更新全局状态
const checkAndUpdateTaskResult = async () => {
const integralStore = useIntegralStore();
await integralStore.queryTodoResultServer();
console.log('queryTodoResult:', integralStore.queryTodoResult);
if(integralStore.queryTodoResult?.success && integralStore.queryTodoResult?.data?.length > 0) {
globalStore.isShowTaskComplete = true;
globalStore.taskCompletePoints = integralStore.queryTodoResult.data[0]?.actualCredits;
globalStore.taskCompleteTitle = integralStore.queryTodoResult.data[0]?.taskName;
}
};
const handleReturn = () => {
uni.navigateBack();
};
......
import { defineStore } from "pinia";
import { getSigninAndTaskInfoJSON, checkInJSON, getSeckillList, getPointsBenefitCouponJSON, queryTodoResultJSON, getOriginInviteHomeJSON, assistInviteJSON } from "../api/integral";
import { getSigninAndTaskInfoJSON, checkInJSON, getSeckillList, getPointsBenefitCouponJSON, queryTodoResultJSON, getOriginInviteHomeJSON, assistInviteJSON, getInvitationListJSON } from "../api/integral";
import signinAndTaskInfoMock from '../mock/getSigninAndTaskInMock.json';
import checkInMock from '../mock/checkIndata.json';
import pointsBenefitCouponMock from '../mock/pointsBenefitCoupon.json';
import queryTodoResultMock from '../mock/queryTodoResult.json';
import originInviteHomeMock from '../mock/originInviteHome.json';
import assistInviteMock from '../mock/assistInvite.json';
import invitationListMock from '../mock/invitationList.json';
export const useIntegralStore = defineStore("integral", {
state: () => {
return {
......@@ -16,6 +17,7 @@ export const useIntegralStore = defineStore("integral", {
_queryTodoResult: null, // 新增:存储查询任务结果数据
_originInviteHome: null, // 新增:存储邀请活动首页数据
_assistInviteData: null, // 新增:存储邀请助力数据
_invitationList: null, // 新增:存储邀请记录列表数据
};
},
actions: {
......@@ -111,6 +113,16 @@ export const useIntegralStore = defineStore("integral", {
return res;
}
},
async getInvitationList(isdebug = false) {
if(isdebug) {
this._invitationList = invitationListMock;
return invitationListMock;
}else{
const res = await getInvitationListJSON();
this._invitationList = res;
return res;
}
},
},
getters: {
signinAndTaskInfo : (state) => {return state._signinAndTaskInfo; },
......@@ -120,5 +132,6 @@ export const useIntegralStore = defineStore("integral", {
queryTodoResult : (state) => {return state._queryTodoResult; },
originInviteHome : (state) => {return state._originInviteHome; },
assistInviteData : (state) => {return state._assistInviteData; },
invitationList : (state) => {return state._invitationList; },
},
});
\ No newline at end of file
......@@ -656,11 +656,11 @@
align-items: center;
justify-content: center;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
position: relative;
.check_mark {
font-size: 24rpx;
color: #000000;
font-weight: bold;
width: 14rpx;
height: 10rpx;
}
}
}
......
......@@ -250,7 +250,7 @@
<!-- 已签到状态:显示白色圆圈内的对勾 -->
<view class="reward_status signed" v-if="signinStatus[day - 1]">
<view class="check_circle">
<text class="check_mark">✓</text>
<image class="check_mark" :src="$baseUrl + `integral/1023/sign_duihao1.png`" mode="aspectFit" />
</view>
</view>
<!-- 未签到状态:显示金币图标 -->
......
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