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 ...@@ -56,3 +56,6 @@ export const assistInviteJSON = (invitationCode, wxUnionId) => api.post('/c/acti
invitationCode, invitationCode,
wxUnionId wxUnionId
}); });
//获取邀请记录列表接口
export const getInvitationListJSON = () => api.get('/c/activity/origin_invite/invitationList');
...@@ -54,13 +54,73 @@ ...@@ -54,13 +54,73 @@
} }
} }
.signedbg_icon { .signedbg_icon_container {
position: absolute; position: fixed;
width: 122rpx;
height: 122rpx;
left: 50%;
top: 50%; top: 50%;
transform: translate(-50%, -50%); left: 50%;
z-index: 2; 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 @@ ...@@ -8,12 +8,14 @@
<image class="tips_title" :src="$baseUrl + `integral/1023/signedTitle.png`" mode="aspectFit" /> <image class="tips_title" :src="$baseUrl + `integral/1023/signedTitle.png`" mode="aspectFit" />
<text class="points_text">获得{{ points }}积分</text> <text class="points_text">获得{{ points }}积分</text>
</view> </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> </view>
</template> </template>
<script setup> <script setup>
import { defineProps, defineEmits } from 'vue'; import { defineProps, defineEmits, ref, watch } from 'vue';
// Props 定义 // Props 定义
const props = defineProps({ const props = defineProps({
...@@ -30,9 +32,22 @@ const props = defineProps({ ...@@ -30,9 +32,22 @@ const props = defineProps({
// Emits 定义 // Emits 定义
const emit = defineEmits(['close']); const emit = defineEmits(['close']);
// 关闭弹窗 // 是否正在播放动画
const isAnimating = ref(false);
// 关闭弹窗 - 点击时播放动画,动画结束后关闭
const handleClose = () => { const handleClose = () => {
emit('close'); // 如果正在播放动画,则不重复触发
if (isAnimating.value) return;
// 开始播放动画
isAnimating.value = true;
// 动画播放完毕后(1.5秒)关闭弹窗
setTimeout(() => {
isAnimating.value = false;
emit('close');
}, 1500);
}; };
</script> </script>
......
...@@ -130,6 +130,7 @@ ...@@ -130,6 +130,7 @@
import { ref, watch, onMounted, computed } from "vue"; import { ref, watch, onMounted, computed } from "vue";
import { onLoad } from "@dcloudio/uni-app"; import { onLoad } from "@dcloudio/uni-app";
import { useUserStore } from "../../stores/user.js"; import { useUserStore } from "../../stores/user.js";
import { useIntegralStore } from "../../stores/integral.js";
import PickerCustom from "../PickerCustom.vue"; import PickerCustom from "../PickerCustom.vue";
import MultiSelectLayer from "../MultiSelectLayer.vue"; import MultiSelectLayer from "../MultiSelectLayer.vue";
import { uploadImage } from "../../api/common.js"; import { uploadImage } from "../../api/common.js";
...@@ -138,6 +139,9 @@ import { updateBabyInfo, getGestationalWeeks } from "../../api/user.js"; ...@@ -138,6 +139,9 @@ import { updateBabyInfo, getGestationalWeeks } from "../../api/user.js";
import { usePageCfgStore } from "../../stores/pageCfg"; import { usePageCfgStore } from "../../stores/pageCfg";
import md from "../../md.js"; import md from "../../md.js";
import { jump, JumpType } from "../../utils/index.js"; import { jump, JumpType } from "../../utils/index.js";
import { useGlobalStore } from "../../stores/global.js";
const globalStore = useGlobalStore();
// Props 定义 // Props 定义
const props = defineProps({ const props = defineProps({
...@@ -534,6 +538,9 @@ const onSubmit = async (e) => { ...@@ -534,6 +538,9 @@ const onSubmit = async (e) => {
icon: "success", icon: "success",
}); });
//获取任务奖品
await checkAndUpdateTaskResult();
// 触发成功事件 // 触发成功事件
emit('success'); emit('success');
// 关闭弹窗 // 关闭弹窗
...@@ -546,6 +553,19 @@ const onSubmit = async (e) => { ...@@ -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 = () => { const handleClose = () => {
emit('close'); 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 @@ ...@@ -10,9 +10,9 @@
<!-- 邀请奖品弹窗 --> <!-- 邀请奖品弹窗 -->
<InvitePrizePanel <InvitePrizePanel
:visible="globalStore.isShowInvitePrizePanel" :visible="globalStore.isShowInvitePrizePanel"
:inviteCount="1" :inviteCount="globalStore.inviteCount"
:prizeName="'奖品名称奖品名称'" :prizeName="globalStore.prizeName"
:prizeImage="''" :prizeImage="globalStore.prizeImage"
@close="handleCloseInvitePrizePanel" @close="handleCloseInvitePrizePanel"
@record="handleInvitePrizePanelRecord" @record="handleInvitePrizePanelRecord"
@prize="handleInvitePrizePanelPrize" @prize="handleInvitePrizePanelPrize"
...@@ -179,7 +179,7 @@ const checkAndUpdateTaskResult = async () => { ...@@ -179,7 +179,7 @@ const checkAndUpdateTaskResult = async () => {
onMounted(async () => { onMounted(async () => {
// globalStore.isShowTaskComplete = true;//????????? // globalStore.isShowTaskComplete = true;//?????????
//签到奖品 //任务奖品
await checkAndUpdateTaskResult(); await checkAndUpdateTaskResult();
// 调用邀请活动首页接口 // 调用邀请活动首页接口
...@@ -194,7 +194,7 @@ onMounted(async () => { ...@@ -194,7 +194,7 @@ onMounted(async () => {
globalStore.isShowInvitePrizePanel = true; globalStore.isShowInvitePrizePanel = true;
globalStore.inviteCount = res.data?.invitedCount; globalStore.inviteCount = res.data?.invitedCount;
globalStore.prizeName = unclaimedPrize?.prizeName; globalStore.prizeName = unclaimedPrize?.prizeName;
globalStore.prizeImage = res.data?.prizeImageUrl; globalStore.prizeImage = unclaimedPrize?.prizeImageUrl;
} }
console.log('邀请活动首页数据:', res); console.log('邀请活动首页数据:', res);
}); });
......
...@@ -16,7 +16,10 @@ ...@@ -16,7 +16,10 @@
z-index: 10; z-index: 10;
.note_text { .note_text {
text-align: center;
left: 50%; left: 50%;
width: 100%;
transform: translateX(-50%); transform: translateX(-50%);
position: absolute; position: absolute;
font-size: 24rpx; font-size: 24rpx;
......
...@@ -9,11 +9,11 @@ ...@@ -9,11 +9,11 @@
<view class="records_list"> <view class="records_list">
<view class="record_item" v-for="(record, index) in records" :key="index"> <view class="record_item" v-for="(record, index) in records" :key="index">
<view class="record_left"> <view class="record_left">
<text class="phone_number">{{ record.phoneNumber }}</text> <text class="phone_number">{{ maskPhone(record.inviteePhone) }}</text>
<text class="invite_time">{{ record.inviteTime }}</text> <text class="invite_time">{{ formatTimestamp(record.createTime) }}</text>
</view> </view>
<view class="record_right"> <view class="record_right">
<text class="status_text">邀请成功</text> <!-- <text class="status_text">邀请成功</text> -->
</view> </view>
</view> </view>
</view> </view>
...@@ -21,43 +21,63 @@ ...@@ -21,43 +21,63 @@
</template> </template>
<script setup> <script setup>
import { ref } from 'vue'; import { ref, onMounted } from 'vue';
import { useIntegralStore } from '@/stores/integral';
import { showLoading, hideLoading } from '@/utils';
// 邀请记录数据 const integralStore = useIntegralStore();
const records = ref([ const records = ref([]);
{
phoneNumber: '136****2718', // 手机号脱敏处理:中间四位显示为 ****
inviteTime: '2025.09.11 23:23:23' const maskPhone = (phone) => {
}, if (!phone) return '';
{ const phoneStr = String(phone);
phoneNumber: '138****4567', // 如果是11位手机号,将中间4位替换为****
inviteTime: '2025.09.10 15:30:45' if (phoneStr.length === 11) {
}, return phoneStr.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
{ }
phoneNumber: '139****7890', // 如果已经是脱敏格式(包含*),直接返回
inviteTime: '2025.09.09 09:15:20' if (phoneStr.includes('*')) {
}, return phoneStr;
{ }
phoneNumber: '135****1234', // 其他情况返回原值
inviteTime: '2025.09.08 18:45:30' return phoneStr;
}, };
{
phoneNumber: '137****5678', // 将时间戳转为 "2025.09.11 23:23:23" 格式
inviteTime: '2025.09.07 12:20:15' const formatTimestamp = (timestamp) => {
}, if (!timestamp) return '';
{
phoneNumber: '139****7890', const date = new Date(timestamp);
inviteTime: '2025.09.09 09:15:20'
}, // 检查日期是否有效
{ if (isNaN(date.getTime())) return '';
phoneNumber: '135****1234',
inviteTime: '2025.09.08 18:45:30' // 获取年月日时分秒
}, const year = date.getFullYear();
{ const month = String(date.getMonth() + 1).padStart(2, '0');
phoneNumber: '137****5678', const day = String(date.getDate()).padStart(2, '0');
inviteTime: '2025.09.07 12:20:15' 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> </script>
<style lang="less" scoped> <style lang="less" scoped>
......
...@@ -140,6 +140,11 @@ import { updateBabyInfo, getGestationalWeeks } from "../../api/user.js"; ...@@ -140,6 +140,11 @@ import { updateBabyInfo, getGestationalWeeks } from "../../api/user.js";
import { usePageCfgStore } from "../../stores/pageCfg"; import { usePageCfgStore } from "../../stores/pageCfg";
import md from "../../md.js"; import md from "../../md.js";
import { jump, JumpType } from "../../utils/index.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 userStore = useUserStore();
const pageType = ref("add"); const pageType = ref("add");
const babyId = ref(""); const babyId = ref("");
...@@ -517,6 +522,10 @@ const onSubmit = async (e) => { ...@@ -517,6 +522,10 @@ const onSubmit = async (e) => {
title: "提交成功", title: "提交成功",
icon: "success", icon: "success",
}); });
//获取任务奖品
await checkAndUpdateTaskResult();
uni.navigateBack(); uni.navigateBack();
} else { } else {
uni.showToast({ uni.showToast({
...@@ -525,6 +534,22 @@ const onSubmit = async (e) => { ...@@ -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 = () => { const handleReturn = () => {
uni.navigateBack(); uni.navigateBack();
}; };
......
import { defineStore } from "pinia"; 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 signinAndTaskInfoMock from '../mock/getSigninAndTaskInMock.json';
import checkInMock from '../mock/checkIndata.json'; import checkInMock from '../mock/checkIndata.json';
import pointsBenefitCouponMock from '../mock/pointsBenefitCoupon.json'; import pointsBenefitCouponMock from '../mock/pointsBenefitCoupon.json';
import queryTodoResultMock from '../mock/queryTodoResult.json'; import queryTodoResultMock from '../mock/queryTodoResult.json';
import originInviteHomeMock from '../mock/originInviteHome.json'; import originInviteHomeMock from '../mock/originInviteHome.json';
import assistInviteMock from '../mock/assistInvite.json'; import assistInviteMock from '../mock/assistInvite.json';
import invitationListMock from '../mock/invitationList.json';
export const useIntegralStore = defineStore("integral", { export const useIntegralStore = defineStore("integral", {
state: () => { state: () => {
return { return {
...@@ -16,6 +17,7 @@ export const useIntegralStore = defineStore("integral", { ...@@ -16,6 +17,7 @@ export const useIntegralStore = defineStore("integral", {
_queryTodoResult: null, // 新增:存储查询任务结果数据 _queryTodoResult: null, // 新增:存储查询任务结果数据
_originInviteHome: null, // 新增:存储邀请活动首页数据 _originInviteHome: null, // 新增:存储邀请活动首页数据
_assistInviteData: null, // 新增:存储邀请助力数据 _assistInviteData: null, // 新增:存储邀请助力数据
_invitationList: null, // 新增:存储邀请记录列表数据
}; };
}, },
actions: { actions: {
...@@ -111,6 +113,16 @@ export const useIntegralStore = defineStore("integral", { ...@@ -111,6 +113,16 @@ export const useIntegralStore = defineStore("integral", {
return res; return res;
} }
}, },
async getInvitationList(isdebug = false) {
if(isdebug) {
this._invitationList = invitationListMock;
return invitationListMock;
}else{
const res = await getInvitationListJSON();
this._invitationList = res;
return res;
}
},
}, },
getters: { getters: {
signinAndTaskInfo : (state) => {return state._signinAndTaskInfo; }, signinAndTaskInfo : (state) => {return state._signinAndTaskInfo; },
...@@ -120,5 +132,6 @@ export const useIntegralStore = defineStore("integral", { ...@@ -120,5 +132,6 @@ export const useIntegralStore = defineStore("integral", {
queryTodoResult : (state) => {return state._queryTodoResult; }, queryTodoResult : (state) => {return state._queryTodoResult; },
originInviteHome : (state) => {return state._originInviteHome; }, originInviteHome : (state) => {return state._originInviteHome; },
assistInviteData : (state) => {return state._assistInviteData; }, assistInviteData : (state) => {return state._assistInviteData; },
invitationList : (state) => {return state._invitationList; },
}, },
}); });
\ No newline at end of file
...@@ -656,11 +656,11 @@ ...@@ -656,11 +656,11 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1); box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
position: relative;
.check_mark { .check_mark {
font-size: 24rpx; width: 14rpx;
color: #000000; height: 10rpx;
font-weight: bold;
} }
} }
} }
......
...@@ -250,7 +250,7 @@ ...@@ -250,7 +250,7 @@
<!-- 已签到状态:显示白色圆圈内的对勾 --> <!-- 已签到状态:显示白色圆圈内的对勾 -->
<view class="reward_status signed" v-if="signinStatus[day - 1]"> <view class="reward_status signed" v-if="signinStatus[day - 1]">
<view class="check_circle"> <view class="check_circle">
<text class="check_mark">✓</text> <image class="check_mark" :src="$baseUrl + `integral/1023/sign_duihao1.png`" mode="aspectFit" />
</view> </view>
</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