Commit de6bdec6 authored by spc's avatar spc

Merge branch feihesanqi_20251014 into dev

parents 958a9aac c9642209
No preview for this file type
import requestModule from './request.js';
const {
api
} = requestModule;
/**
* 保存地址
* @param {Object} data - 请求参数
* @param {string} [data.id] - 地址ID (可选,编辑时必传)
* @param {boolean} [data.current=true] - 是否是默认地址 (可选,默认true)
* @param {string} data.name - 联系人 (必须)
* @param {string} data.mobile - 联系电话 (必须)
* @param {string} data.email - 邮箱 (必须)
* @param {string} [data.province] - 省 (可选)
* @param {integer} [data.provinceCode] - 省代码 (可选)
* @param {string} [data.city] - 市 (可选)
* @param {integer} [data.cityCode] - 市代码 (可选)
* @param {string} [data.area] - 区/县 (可选)
* @param {integer} [data.areaCode] - 区/县代码 (可选)
* @param {string} [data.town] - 街道地址 (可选)
* @param {integer} [data.townCode] - 街道代码 (可选)
* @param {string} data.detail - 详细地址 (必须)
* @param {string} [data.postalCode] - 邮政编码 (可选)
* @param {string} [data.floorNo] - 门牌号 (可选)
* @returns {Promise} API响应
* @description 保存或更新地址信息
* @response {Object} 响应数据
* @response {boolean} response.ok - 请求是否成功
* @response {boolean} response.success - 操作是否成功
* @response {string} response.msg - 响应消息
* @response {string} response.code - 响应代码
* @response {Object} response.data - 响应数据
*/
export const saveAddress = (data) => api.post('/c/user/address/save', data);
/**
* 获取地址列表
* @returns {Promise} API响应
* @description 返回地址列表,每个地址对象包含以下字段:
* - id: 地址ID (string)
* - current: 是否是默认地址 (boolean)
* - name: 联系人 (string)
* - mobile: 联系电话 (string)
* - email: 邮箱 (string)
* - province: 省 (string)
* - provinceCode: 省代码 (integer)
* - city: 市 (string)
* - cityCode: 市代码 (integer)
* - area: 区/县 (string)
* - areaCode: 区/县代码 (integer)
* - town: 乡镇 (string)
* - townCode: 乡镇代码 (integer)
* - detail: 详细地址 (string)
* - postalCode: 邮政编码 (string)
* - floorNo: 门牌号 (string)
*/
export const getAddressList = () => api.get('/c/user/address');
/**
* 更新地址
* @param {Object} data - 请求参数
* @param {string} [data.id] - 地址ID (可选,编辑时必传)
* @param {boolean} [data.current=true] - 是否是默认地址 (可选,默认true)
* @param {string} data.name - 联系人 (必须)
* @param {string} data.mobile - 联系电话 (必须)
* @param {string} data.email - 邮箱 (必须)
* @param {string} [data.province] - 省 (可选)
* @param {integer} [data.provinceCode] - 省代码 (可选)
* @param {string} [data.city] - 市 (可选)
* @param {integer} [data.cityCode] - 市代码 (可选)
* @param {string} [data.area] - 区/县 (可选)
* @param {integer} [data.areaCode] - 区/县代码 (可选)
* @param {string} [data.town] - 街道地址 (可选)
* @param {integer} [data.townCode] - 街道代码 (可选)
* @param {string} data.detail - 详细地址 (必须)
* @param {string} [data.postalCode] - 邮政编码 (可选)
* @param {string} [data.floorNo] - 门牌号 (可选)
* @returns {Promise} API响应
* @description 更新地址信息
* @response {Object} 响应数据
* @response {boolean} response.ok - 请求是否成功
* @response {boolean} response.success - 操作是否成功
* @response {string} response.msg - 响应消息
* @response {string} response.code - 响应代码
* @response {Object} response.data - 响应数据
*/
export const updateAddress = (data) => api.post('/c/user/address/update', data);
/**
* 删除地址
* @param {Object} data - 请求参数
* @param {string} data.id - 地址ID (必须)
* @returns {Promise} API响应
* @description 删除指定ID的地址
* @response {Object} 响应数据
* @response {boolean} response.ok - 请求是否成功
* @response {boolean} response.success - 操作是否成功
* @response {string} response.msg - 响应消息
* @response {string} response.code - 响应代码
* @response {boolean} response.data - 响应数据
*/
export const deleteAddress = (data) => api.post('/c/user/address/del', data);
/**
* 设置默认地址
* @param {*} data
* @returns
*/
export const setDefaultAddress = (data) => api.post('/c/user/address/current', data);
/**
* 获取地址详情
* @param {Object} data - 请求参数
* @param {string} data.id - 地址ID (必须)
* @returns {Promise} API响应
* @description 根据地址ID获取地址详细信息
* @response {Object} 响应数据
* @response {boolean} response.ok - 请求是否成功
* @response {boolean} response.success - 操作是否成功
* @response {string} response.msg - 响应消息
* @response {string} response.code - 响应代码
* @response {Object} response.data - 地址详情数据
* @response {string} response.data.id - 地址ID
* @response {boolean} response.data.current - 是否是默认地址
* @response {string} response.data.name - 联系人
* @response {string} response.data.mobile - 联系电话
* @response {string} response.data.email - 邮箱
* @response {string} response.data.province - 省
* @response {integer} response.data.provinceCode - 省代码
* @response {string} response.data.city - 市
* @response {integer} response.data.cityCode - 市代码
* @response {string} response.data.area - 区/县
* @response {integer} response.data.areaCode - 区/县代码
* @response {string} response.data.town - 乡镇
* @response {integer} response.data.townCode - 乡镇代码
* @response {string} response.data.detail - 详细地址
* @response {string} response.data.postalCode - 邮政编码
* @response {string} response.data.floorNo - 门牌号
*/
export const getAddressDetail = (data) => api.get('/c/user/address/detail', data);
/**
* 获取省市区数据
* @param {Object} params - 请求参数
* @param {number} [params.id=0] - 上级地区ID,初始传0获取省份列表,后续使用上级接口返回的id查询下级
* @returns {Promise} API响应
* @description 根据上级地区ID获取下级地区列表
* @response {Object} 响应数据
* @response {boolean} response.ok - 请求是否成功
* @response {boolean} response.success - 操作是否成功
* @response {string} response.msg - 响应消息
* @response {string} response.code - 响应代码
* @response {Array} response.data - 地区列表
* @response {number} response.data[].id - 地区ID(用于查询下级)
* @response {number} response.data[].code - 地区代码
* @response {string} response.data[].name - 地区名称
*/
export const getRegionList = (params = {}) => api.get('/c/regions/query', params);
/**
* 获取订单物流信息
* @param {Object} data - 请求参数
* @param {string} data.order_no - 订单号 (必须)
* @returns {Promise} API响应
* @description 根据订单号查询订单物流信息
* @response {Object} 响应数据
* @response {boolean} response.ok - 请求是否成功
* @response {boolean} response.success - 操作是否成功
* @response {string} response.msg - 响应消息
* @response {string} response.code - 响应代码
* @response {Object} response.data - 物流信息数据
* @response {string} response.data.order_no - 订单号
* @response {string} response.data.express_company - 快递公司名称
* @response {string} response.data.express_no - 快递公司单号
* @response {Array} response.data.traces - 物流轨迹列表
* @response {string} response.data.traces[].time - 物流事件时间
* @response {string} response.data.traces[].context - 物流事件描述
*/
export const getOrderLogistics = (data) => api.get('/c/order/express/route', data);
import requestModule from './request.js';
const {
api
} = requestModule;
/**
* 获取商品详情
* @param {gid} data
* @returns
*/
export const fetchGoodsDetail = (data) => api.get('/c/goods/detail', data);
/**
* 获取秒杀商品详情
* @param {Object} data - 请求参数
* @param {string} data.gid - 商品ID (必须)
* @param {string} data.activityId - 活动ID (必须)
* @param {string} data.sessionKey - 会话密钥 (必须)
* @returns {Promise} API响应
* @description 获取秒杀商品详情信息
*/
export const fetchSeckillDetail = (data) => api.get('/c/seckill/detail', data);
/**
* 计算商品价格优惠
* @param {Object} data - 请求参数
* @param {number} data.gid - 商品ID (必须)
* @param {number} [data.skuld] - 商品规格ID (可选)
* @param {number} [data.buy_num=1] - 下单数量 (可选,默认1)
* @param {string} [data.phone] - 充值号码 (可选)
* @param {string} [data.amount] - 充值面额 (可选)
* @param {number} [data.couponId] - 优惠券ID (可选)
* @param {string} [data.remark] - 下单备注 (可选)
* @param {number} [data.addressId] - 地址ID (可选)
* @param {number} [data.storeId] - 门店ID (可选)
* @param {string} [data.projectId] - 活动ID (可选)
* @returns {Promise} API响应
* @description 计算商品价格和优惠信息,在下单前调用
*/
export const fetchGoodsPrice = (data) => api.post('/c/goods/price', data);
/**
* 下单
* @param {Object} data - 请求参数
* @param {number} data.gid - 商品ID (必须)
* @param {number} [data.skuld] - 商品规格ID (可选)
* @param {number} [data.buy_num=1] - 下单数量 (可选,默认1)
* @param {string} [data.phone] - 充值号码 (可选)
* @param {string} [data.amount] - 充值面额 (可选)
* @param {number} [data.couponId] - 优惠券ID (可选)
* @param {string} [data.remark] - 下单备注 (可选)
* @param {number} [data.addressId] - 地址ID (可选)
* @param {number} [data.storeId] - 门店ID (可选)
* @param {string} [data.projectId] - 活动ID (可选)
* @returns {Promise} API响应
* @description 创建订单,在价格计算后调用
*/
export const fetchTradeCredits = (data) => api.post('/c/trade/credits', data);
/**
* 秒杀下单
* @param {Object} data - 请求参数
* @param {string} data.id - 商品ID (必须)
* @param {string} [data.phone] - 充值号码 (可选)
* @param {string} [data.buyNum=1] - 下单数量 (可选,默认1)
* @param {string} [data.storeId] - 门店ID (可选)
* @param {string} [data.amount] - 充值面额 (可选)
* @param {string} [data.channel] - 渠道 (可选)
* @param {string} [data.addressId] - 地址ID (可选)
* @param {string} data.appGoodsId - 应用商品ID (必须)
* @param {string} data.sessionKey - 会话密钥 (必须)
* @returns {Promise} API响应
* @description 秒杀下单,不需要调用价格计算接口
*/
export const fetchSeckillTakeOrder = (data) => api.post('/c/seckill/takeOrder', data);
/**
* 订单物流信息
* @param {Object} data - 请求参数
* @param {string} data.order_no - 订单ID (必须)
* @returns {Promise} API响应
* @description 获取订单物流信息
*/
export const fetchOrderExpressRoute = (data) => api.get('/c/order/express/route', data);
/**
* 取消订单
* @param {Object} data - 请求参数
* @param {string} data.order_no - 订单ID (必须)
* @returns {Promise} API响应
* @description 取消订单
*/
export const fetchOrderCancel = (data) => api.get('/c/order/cancel', data);
......@@ -9,4 +9,9 @@ const {
*/
export const fetchHomeInfo = () => api.get('/c/user/index');
export const fetchHomeJSON = () => api.get('/c/front/content',{type:'home_V1'});
\ No newline at end of file
export const fetchCanEatIndex = () => api.get('/c/eat/index');
export const fetchCanEatJoin = (data) => api.post('/c/eat/join', data);
export const fetchHomeJSON = () => api.get('/c/front/content',{type:'home_V1'});
......@@ -29,4 +29,33 @@ export const fetchBatchReceiveJSON = () => api.post('/c/equity/birthdayGift/batc
export const fetchActivityStateJSON = () => api.get('/c/third/activity/state');
//获取配置项和商品列表
export const getResourceList = () => api.get('c/resource/list');
\ No newline at end of file
export const getResourceList = () => api.get('/c/resource/list');
//获取签到和任务信息接口
export const getSigninAndTaskInfoJSON = () => api.get('/c/activity/todo/list');
//签到接口
export const checkInJSON = (activityId) => api.post('/c/activity/todo/checkIn', {activityId});
//获取秒杀列表
export const getSeckillList = () => api.get('/c/seckill/list');
//完成任务接口
export const taskCompleteJSON = (activityId) => api.post('/c/activity/todo/complete', { activityId });
//获取异业券接口
export const getPointsBenefitCouponJSON = () => api.get('/c/resource/pointsBenefit/coupon');
//查询任务结果接口
export const queryTodoResultJSON = (activityId) => api.get('/c/activity/todo/queryTodoResult');
//获取邀请活动首页信息接口
export const getOriginInviteHomeJSON = () => api.get('/c/activity/origin_invite/home');
//邀请助力接口
export const assistInviteJSON = (invitationCode, wxUnionId) => api.post('/c/activity/origin_invite/assist', {
invitationCode,
wxUnionId
});
//获取邀请记录列表接口
export const getInvitationListJSON = () => api.get('/c/activity/origin_invite/invitationList');
......@@ -17,8 +17,8 @@ const {
// 通常可以吧 baseUrl 单独放在一个 js 文件了
// const baseUrl = "http://172.16.230.108:7777/pmall";
// const baseUrl = "https://momclub-uat.feihe.com/pmall";//测试环境
// const baseUrl = "https://momclub-test.feihe.com/pmall";//测试环境2
const baseUrl = "https://momclub.feihe.com/pmall";//生产环境
const baseUrl = "https://momclub-test.feihe.com/pmall";
// let baseUrl = "https://momclub.feihe.com/pmall";//生产环境
// const baseUrl = "https://docs.dui88.com/mock/1956/api";//mock
// const baseUrl = "https://feihe.m.duibatest.com.cn/pmall"
......
......@@ -49,4 +49,28 @@ export const updateBabyInfo = (data) => api.post('/c/user/saveBaby', data);
export const fetchUserJSON = () => api.get('/c/front/content', { type: 'my_V1' });
/** 查询用户是否参与生育补贴和鹤礼2.0*/
export const checkParticipation = (data) => api.get('/c/fertility/index', data);
\ No newline at end of file
export const checkParticipation = (data) => api.get('/c/fertility/index', data);
export const doTerminate = () => api.post('/c/user/terminate');
/**
* 获取积分兑换记录列表(分页)
* @param {Object} params - 请求参数
* @param {number} [params.nextId] - 下一页ID,不传则为第一页
* @returns {Promise} 返回兑换记录列表
*/
export const getExchangeList = (params = {}) => api.get('/c/user/exchange/list', { params });
/**
*
* @param {orderNo} data
* @returns
*/
export const getOrderDetail = (data) => api.get('/c/order/detail', data);
\ No newline at end of file
assets/reservation-images/briefcase.png

566 Bytes | W: | H:

assets/reservation-images/briefcase.png

337 Bytes | W: | H:

assets/reservation-images/briefcase.png
assets/reservation-images/briefcase.png
assets/reservation-images/briefcase.png
assets/reservation-images/briefcase.png
  • 2-up
  • Swipe
  • Onion skin
assets/reservation-images/briefcase_new.png

517 Bytes | W: | H:

assets/reservation-images/briefcase_new.png

480 Bytes | W: | H:

assets/reservation-images/briefcase_new.png
assets/reservation-images/briefcase_new.png
assets/reservation-images/briefcase_new.png
assets/reservation-images/briefcase_new.png
  • 2-up
  • Swipe
  • Onion skin
assets/reservation-images/calendar-gray.png

657 Bytes | W: | H:

assets/reservation-images/calendar-gray.png

344 Bytes | W: | H:

assets/reservation-images/calendar-gray.png
assets/reservation-images/calendar-gray.png
assets/reservation-images/calendar-gray.png
assets/reservation-images/calendar-gray.png
  • 2-up
  • Swipe
  • Onion skin
assets/reservation-images/calendar.png

556 Bytes | W: | H:

assets/reservation-images/calendar.png

348 Bytes | W: | H:

assets/reservation-images/calendar.png
assets/reservation-images/calendar.png
assets/reservation-images/calendar.png
assets/reservation-images/calendar.png
  • 2-up
  • Swipe
  • Onion skin
assets/reservation-images/calendar_new.png

831 Bytes | W: | H:

assets/reservation-images/calendar_new.png

719 Bytes | W: | H:

assets/reservation-images/calendar_new.png
assets/reservation-images/calendar_new.png
assets/reservation-images/calendar_new.png
assets/reservation-images/calendar_new.png
  • 2-up
  • Swipe
  • Onion skin
assets/reservation-images/close.png

5.11 KB | W: | H:

assets/reservation-images/close.png

1.41 KB | W: | H:

assets/reservation-images/close.png
assets/reservation-images/close.png
assets/reservation-images/close.png
assets/reservation-images/close.png
  • 2-up
  • Swipe
  • Onion skin
assets/reservation-images/icon-list.png

1.45 KB | W: | H:

assets/reservation-images/icon-list.png

587 Bytes | W: | H:

assets/reservation-images/icon-list.png
assets/reservation-images/icon-list.png
assets/reservation-images/icon-list.png
assets/reservation-images/icon-list.png
  • 2-up
  • Swipe
  • Onion skin
assets/reservation-images/s-1.png

210 KB | W: | H:

assets/reservation-images/s-1.png

70.8 KB | W: | H:

assets/reservation-images/s-1.png
assets/reservation-images/s-1.png
assets/reservation-images/s-1.png
assets/reservation-images/s-1.png
  • 2-up
  • Swipe
  • Onion skin
assets/reservation-images/s-2.png

343 KB | W: | H:

assets/reservation-images/s-2.png

95.7 KB | W: | H:

assets/reservation-images/s-2.png
assets/reservation-images/s-2.png
assets/reservation-images/s-2.png
assets/reservation-images/s-2.png
  • 2-up
  • Swipe
  • Onion skin
assets/reservation-images/sign.png

163 KB | W: | H:

assets/reservation-images/sign.png

58.7 KB | W: | H:

assets/reservation-images/sign.png
assets/reservation-images/sign.png
assets/reservation-images/sign.png
assets/reservation-images/sign.png
  • 2-up
  • Swipe
  • Onion skin
assets/reservation-images/success.png

98.7 KB | W: | H:

assets/reservation-images/success.png

33.3 KB | W: | H:

assets/reservation-images/success.png
assets/reservation-images/success.png
assets/reservation-images/success.png
assets/reservation-images/success.png
  • 2-up
  • Swipe
  • Onion skin
assets/reservation-images/twitter.png

1.18 KB | W: | H:

assets/reservation-images/twitter.png

704 Bytes | W: | H:

assets/reservation-images/twitter.png
assets/reservation-images/twitter.png
assets/reservation-images/twitter.png
assets/reservation-images/twitter.png
  • 2-up
  • Swipe
  • Onion skin
<template>
<uni-popup ref="answerPopup" type="bottom" :maskClick="false" :safe-area="true" :backgroundColor="'rgba(0, 0, 0, 0.5)'">
<view class="answer-popup-container">
<view class="answer-popup">
<!-- 关闭按钮 -->
<view class="close-btn" @tap="handleClose">
<image :src="`${$baseUrl}homepage/Q3Res/canEatCloseBtn.png`" mode="aspectFit"></image>
</view>
<!-- 结果标题和图标 -->
<view class="result-header">
<text class="result-title">{{ isCorrect ? '你太棒了,回答正确!' : '快来补课吧,回答错误哦!' }}</text>
<view class="result-icon">
<image v-if="isCorrect" :src="`${$baseUrl}homepage/Q3Res/eat_goodIcon.png`" mode="aspectFit"></image>
<image v-else :src="`${$baseUrl}homepage/Q3Res/eat_cryIcon.png`" mode="aspectFit"></image>
</view>
</view>
<!-- 奖励信息 -->
<view v-if="rewardInfo && isCorrect" class="reward-info">
已获得{{ rewardInfo }}
</view>
<!-- 错误状态下也保留相同高度的空间 -->
<view v-else class="empty-reward-space"></view>
<!-- 选项分布 -->
<view class="option-distribution">
<view class="option-bar" v-for="(option, index) in displayOptionDistribution" :key="index">
<text class="option-text">{{ option.label }}: {{ option.percentage }}</text>
</view>
</view>
<!-- 题目和答案 -->
<view class="question-answer-section">
<text class="question-text">{{ question }}</text>
<text class="answer-text">答案:{{ correctAnswer }}</text>
</view>
<!-- 解析内容 -->
<view class="analysis-section">
<text class="analysis-title">解析</text>
<text class="analysis-content">{{ analysis }}</text>
</view>
</view>
</view>
</uni-popup>
</template>
<script>
export default {
name: 'CanEatAnswerPopup',
props: {
visible: {
type: Boolean,
default: false
},
isCorrect: {
type: Boolean,
default: false
},
rewardInfo: {
type: String,
default: ''
},
question: {
type: String,
default: ''
},
correctAnswer: {
type: String,
default: ''
},
analysis: {
type: String,
default: ''
},
allResult: {
type: String,
default: '25|25|25|25'
},
fallResult: {
type: String,
default: ''
},
optionDistribution: {
type: Array,
default: () => [
{ label: '能吃', percentage: '25%', color: '#B27C1E' },
{ label: '少吃', percentage: '25%', color: '#B27C1E' },
{ label: '慎吃', percentage: '25%', color: '#B27C1E' },
{ label: '禁吃', percentage: '25%', color: '#B27C1E' }
]
}
},
computed: {
// 根据fallResult或allResult字符串生成显示用的选项分布数据
displayOptionDistribution() {
const labels = ['能吃', '少吃', '慎吃', '禁吃'];
// 确保所有数据都被正确记录
console.log('AllResult数据:', this.allResult, '类型:', typeof this.allResult);
console.log('FallResult数据:', this.fallResult, '类型:', typeof this.fallResult);
// 首先检查fallResult
if (this.fallResult && this.fallResult !== null && this.fallResult.trim() !== '' && this.fallResult.includes('|')) {
try {
const percentages = this.fallResult.split('|');
console.log('使用fallResult生成分布:', percentages);
return percentages.map((percent, index) => ({
label: labels[index] || '',
percentage: `${percent}%`
}));
} catch (error) {
console.error('处理fallResult时出错:', error);
}
}
// 然后检查allResult,使用更宽松的判断条件
if (this.allResult && this.allResult !== null && typeof this.allResult === 'string') {
// 即使不包含|符号,也尝试处理
let percentages;
if (this.allResult.includes('|')) {
percentages = this.allResult.split('|');
} else {
// 尝试作为单个百分比处理
percentages = [this.allResult, '0', '0', '0'];
}
console.log('使用allResult生成分布:', percentages);
return percentages.map((percent, index) => ({
label: labels[index] || '',
percentage: `${percent}%`
}));
}
// 最后使用默认的optionDistribution
console.log('使用默认optionDistribution');
return this.optionDistribution;
}
},
watch: {
visible: {
handler(newVal) {
if (newVal) {
this.openPopup();
} else {
this.closePopup();
}
},
immediate: true
}
},
methods: {
openPopup() {
// 禁止背景页面滚动(小程序原生方式)
wx.setPageStyle({
style: {
overflow: 'hidden'
}
});
this.$refs.answerPopup.open();
},
closePopup() {
// 恢复背景页面滚动(小程序原生方式)
wx.setPageStyle({
style: {
overflow: 'auto'
}
});
if (this.$refs.answerPopup) {
this.$refs.answerPopup.close();
}
},
handleClose() {
this.$emit('close');
}
}
}
</script>
<style scoped>
.answer-popup-container {
width: 750rpx;
height: 986rpx;
position: relative;
margin: 0 auto;
overflow: visible;
}
.answer-popup {
/* width: 100%;
height: 100%; */
background: #FFF9EB;
border-radius: 24rpx 24rpx 0 0;
padding: 30rpx 40rpx 60rpx 40rpx;
position: relative;
/* box-sizing: border-box; */
overflow: visible;
display: flex;
flex-direction: column;
}
.close-btn {
position: absolute;
top: 20rpx;
right: 20rpx;
width: 60rpx;
height: 60rpx;
z-index: 10;
display: flex;
align-items: center;
justify-content: center;
}
.close-btn image {
width: 100%;
height: 100%;
}
.result-header {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
height: 60rpx;
}
.result-title {
font-size: 36rpx;
font-weight: bold;
color: #B27C1E;
margin-right: 20rpx;
flex: 1;
line-height: 1.4;
}
.result-icon {
width: 164rpx;
height: 164rpx;
display: flex;
align-items: center;
justify-content: center;
position: relative;
top: 0rpx;
left: -140rpx;
}
.result-icon image {
width: 100%;
height: 100%;
object-fit: contain;
}
.reward-info {
text-align: left;
font-size: 28rpx;
color: #666;
margin-bottom: 30rpx;
}
.option-distribution {
display: flex;
gap: 3rpx;
margin-bottom: 30rpx;
align-items: center;
width: 100%;
}
.option-bar {
flex: 1;
padding: 10rpx 15rpx;
color: #fff;
border-radius: 20rpx;
display: flex;
justify-content: center;
align-items: center;
font-size: 24rpx;
text-align: center;
position: relative;
overflow: hidden;
box-sizing: border-box;
}
/* 从左到右4种颜色 - 反转顺序 */
.option-bar:nth-child(1) {
border-radius: 50rpx 20rpx 50rpx 50rpx;
background: #D3A458;
}
.option-bar:nth-child(2) {
border-radius: 20rpx 10rpx 20rpx 10rpx;
background: #B27C1E;
}
.option-bar:nth-child(3) {
border-radius: 20rpx 10rpx 20rpx 10rpx;
background: #8D5C05;
}
.option-bar:nth-child(4) {
border-radius: 20rpx 50rpx 50rpx 20rpx;
background: #644104;
}
/* 第一个选项只有右斜切 */
.option-bar:first-child {
clip-path: polygon(0 0, 100% 0, 90% 100%, 0% 100%);
}
/* 中间的选项左右都有斜切 */
.option-bar:not(:first-child):not(:last-child) {
clip-path: polygon(10% 0, 100% 0, 90% 100%, 0% 100%);
margin-left: -12rpx;
}
/* 最后一个选项只有左斜切 */
.option-bar:last-child {
clip-path: polygon(10% 0, 100% 0, 100% 100%, 0% 100%);
margin-left: -12rpx;
}
.question-answer-section {
background: #FFFFFF;
/* height: 164rpx; */
padding: 40rpx;
border-radius: 20rpx;
margin-bottom: 30rpx;
overflow-y: auto;
}
.question-text {
font-size: 28rpx;
color: #333;
display: block;
font-weight: bolder;
margin-bottom: 15rpx;
line-height: 1.6;
}
.answer-text {
font-size: 28rpx;
color: #D3A358;
display: block;
/* font-weight: bold; */
}
.analysis-section {
background: #FFFFFF;
height: 446rpx;
padding: 40rpx;
border-radius: 36rpx;
margin-bottom: 40rpx;
overflow-y: auto;
}
.analysis-title {
font-size: 30rpx;
font-weight: bolder;
color: #000;
display: block;
margin-bottom: 15rpx;
}
.analysis-content {
font-size: 28rpx;
color: #999999;
line-height: 1.8;
white-space: pre-wrap;
}
/* .confirm-btn {
width: 100%;
height: 90rpx;
line-height: 90rpx;
text-align: center;
background: #D3A358;
color: #fff;
border-radius: 45rpx;
font-size: 32rpx;
font-weight: bold;
margin-top: 20rpx;
margin-bottom: 20rpx;
} */
.empty-reward-space {
height: 40rpx;
margin-bottom: 30rpx;
}
</style>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -41,7 +41,7 @@ const tabList = ref([
selectedIconPath: $baseUrl + "tabBar/icon_tab_brand_selected.png",
},
{
text: "积分服务",
text: "积分权益",
iconPath: $baseUrl + "tabBar/icon_tab_gift_normal.png",
selectedIconPath: $baseUrl + "tabBar/icon_tab_gift_selected.png",
},
......
.invite_gift_container {
width: 100%;
margin-bottom: 30rpx;
.invite_gift_title {
font-size: 30rpx;
font-weight: bold;
color: #000000;
margin-bottom: 20rpx;
display: block;
&.item-4 {
color: #FFF0DF;
}
}
.invite_card {
position: relative;
width: 100%;
height: 254rpx;
background: rgba(255, 255, 255, 0.2);
border-radius: 30rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
padding: 30rpx;
box-sizing: border-box;
overflow: hidden;
&.item-4 {
background: rgba(255, 255, 255, 0.1);
}
.card_content {
position: relative;
height: 100%;
display: flex;
flex-direction: column;
// justify-content: space-between;
.card_title {
font-size: 36rpx;
font-weight: bold;
color: #1c1c1c;
&.item-4 {
color: #FFF0DF;
}
}
.card_description {
font-size: 24rpx;
color: #999999;
margin-top: 10rpx;
&.item-4 {
color: #FFF0DF;
}
}
.invite_button {
width: 172rpx;
height: 62rpx;
background: linear-gradient(to right, #916633 0%, #AB7A44 100%);
border-radius: 30rpx;
display: flex;
margin-top: 30rpx;
margin-left: 0rpx;
align-items: center;
justify-content: center;
box-shadow: 0 2rpx 8rpx rgba(160, 123, 77, 0.3);
transition: transform 0.2s ease;
.invite_button_text {
font-size: 28rpx;
// font-weight: bold;
color: #FFFFFF;
}
&:active {
transform: scale(0.95);
}
&.item-1 {
background: linear-gradient(to right, #5089C1 0%, #6FA2D5 100%);
}
&.item-2 {
background: linear-gradient(to right, #7253A5 0%, #9879CC 100%);
}
&.item-3 {
background: linear-gradient(to right, #CDA36B 0%, #E0B97D 100%);
}
&.item-4 {
background: linear-gradient(to right, #000000 0%, #2C1500 100%);
}
}
}
.record_button {
position: absolute;
width: 146rpx;
height: 52rpx;
top: 16rpx;
right: 20rpx;
background: rgba(255, 255, 255, 0.8);
border-radius: 30rpx;
display: flex;
align-items: center;
justify-content: center;
transition: transform 0.2s ease;
.record_text {
font-size: 24rpx;
color: #999999;
margin-right: 8rpx;
&.item-4 {
color: #D7D7D7;
}
}
.record_arrow {
width: 11rpx;
height: 18rpx;
}
&.item-4 {
background: rgba(255, 255, 255, 0.36);
}
&:active {
transform: scale(0.95);
}
}
.star_character {
position: absolute;
right: 44rpx;
bottom: -20rpx;
width: 216rpx;
height: 211rpx;
.star_img {
width: 100%;
height: 100%;
}
}
}
}
<template>
<view class="invite_gift_container" :class="`item-${itemIndex}`">
<!-- 主标题 -->
<text class="invite_gift_title" :class="`item-${itemIndex}`">邀请得好礼</text>
<!-- 邀请卡片 -->
<view class="invite_card" :class="`item-${itemIndex}`">
<!-- 卡片内容区域 -->
<view class="card_content">
<!-- 卡片标题 -->
<text class="card_title" :class="`item-${itemIndex}`">邀请好友注册得好礼</text>
<!-- 描述文字 -->
<text class="card_description" :class="`item-${itemIndex}`">成功邀请一位好友注册即可获得XXX</text>
<!-- 去邀请按钮 -->
<button class="invite_button" :class="`item-${itemIndex}`" @tap="handleInviteClick" open-type="share">
<text class="invite_button_text">去邀请</text>
</button>
</view>
<!-- 3D星星角色 -->
<view class="star_character">
<image
class="star_img"
:src="$baseUrl + 'integral/1023/invate_star_character1023.png'"
mode="aspectFit"
/>
</view>
<!-- 邀请记录按钮 -->
<view class="record_button" :class="`item-${itemIndex}`" @click="handleRecordClick">
<text class="record_text" :class="`item-${itemIndex}`">邀请记录</text>
<image class="record_arrow" :class="`item-${itemIndex}`" :src="$baseUrl + 'integral/1023/yaoqingjiluIcon.png'" mode="aspectFit" />
</view>
<!-- 3D星星角色 -->
<!-- <view class="star_character">
<image
class="star_img"
:src="$baseUrl + 'integral/1023/star_character.png'"
mode="aspectFit"
/>
</view> -->
</view>
</view>
</template>
<script setup>
import { defineProps, defineEmits, onMounted } from 'vue';
// Props 定义
const props = defineProps({
itemIndex: {
type: Number,
default: 0
}
});
// Emits 定义
const emit = defineEmits(['invite', 'record']);
// 在 onMounted 中打印 itemIndex
onMounted(() => {
console.log('InviteGift itemIndex:', props.itemIndex);
});
// 去邀请按钮点击事件
const handleInviteClick = () => {
console.log('去邀请按钮点击');
emit('invite');
};
// 邀请记录按钮点击事件
const handleRecordClick = () => {
console.log('邀请记录按钮点击');
emit('record');
};
</script>
<!-- <script>
// 微信小程序分享配置 - 使用 Options API
export default {
// 分享配置
onShareAppMessage() {
return {
title: '积分分享',
path: '/pages/invate/sharepage',
imageUrl: 'https://course.feihe.com/momclub-picture/integral/1023/invate_star_character1023.png'
};
}
}
</script> -->
<style lang="less" scoped>
@import '@/components/integralArea/InviteGift.less';
</style>
.invite_prize_panel_overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.6);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
.invite_prize_panel_container {
position: relative;
width: 600rpx;
background: linear-gradient(to bottom, #FFE9C5, #FFFFFF);
border-radius: 30rpx;
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.3);
padding: 50rpx 40rpx 40rpx 40rpx;
box-sizing: border-box;
.panel_content {
display: flex;
flex-direction: column;
align-items: center;
.panel_title {
font-size: 36rpx;
font-weight: bold;
color: #D3A458;
text-align: center;
margin-bottom: 40rpx;
line-height: 1.4;
}
.prize_image_area {
width: 200rpx;
height: 200rpx;
background: #FFFFFF;
border-radius: 20rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.1);
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 30rpx;
.prize_image {
width: 180rpx;
height: 180rpx;
border-radius: 16rpx;
}
}
.prize_name {
font-size: 28rpx;
color: #333333;
text-align: center;
margin-bottom: 40rpx;
line-height: 1.4;
}
.button_area {
width: 100%;
display: flex;
justify-content: space-between;
gap: 20rpx;
.record_button {
flex: 1;
height: 78rpx;
width: 220rpx;
background: transparent;
border: 2rpx solid #D3A458;
border-radius: 60rpx;
display: flex;
align-items: center;
justify-content: center;
transition: transform 0.2s ease;
.record_button_text {
font-size: 32rpx;
color: #D3A458;
font-weight: 500;
}
&:active {
transform: scale(0.95);
}
}
.prize_button {
flex: 1;
height: 78rpx;
width: 220rpx;
background: #D3A458;
border-radius: 60rpx;
display: flex;
align-items: center;
justify-content: center;
transition: transform 0.2s ease;
.prize_button_text {
font-size: 32rpx;
color: #FFFFFF;
// font-weight: 500;
}
&:active {
transform: scale(0.95);
}
}
}
}
.close_button {
position: absolute;
bottom: -80rpx;
left: 50%;
transform: translateX(-50%);
width: 60rpx;
height: 60rpx;
background: rgba(255, 255, 255, 0.4);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.2);
transition: transform 0.2s ease;
.close_icon {
font-size: 36rpx;
color: #ffffff;
font-weight: bold;
line-height: 1;
}
&:active {
transform: translateX(-50%) scale(0.95);
}
}
}
}
<template>
<view class="invite_prize_panel_overlay" v-if="visible" @click="handleClose">
<view class="invite_prize_panel_container" @click.stop>
<!-- 弹窗内容 -->
<view class="panel_content">
<!-- 主标题 -->
<text class="panel_title">恭喜您成功邀请{{ inviteCount }}位好友注册</text>
<!-- 奖品图片区域 -->
<view class="prize_image_area">
<image
class="prize_image"
:src="prizeImage || $baseUrl + 'integral/1023/invate_star_character1023.png'"
mode="aspectFit"
/>
</view>
<!-- 奖品名称 -->
<text class="prize_name">{{ prizeName || '奖品名称奖品名称' }}</text>
<!-- 按钮区域 -->
<view class="button_area">
<!-- 查看邀请记录按钮 -->
<view class="record_button" @click="handleRecordClick">
<text class="record_button_text">查看邀请记录</text>
</view>
<!-- 查看奖品按钮 -->
<view class="prize_button" @click="handlePrizeClick">
<text class="prize_button_text">查看奖品</text>
</view>
</view>
</view>
<!-- 关闭按钮 -->
<view class="close_button" @click="handleClose">
<text class="close_icon">×</text>
</view>
</view>
</view>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
import { jump } from '../../utils';
// Props 定义
const props = defineProps({
visible: {
type: Boolean,
default: false
},
inviteCount: {
type: Number,
default: 1
},
prizeName: {
type: String,
default: '奖品名称奖品名称'
},
prizeImage: {
type: String,
default: ''
}
});
// Emits 定义
const emit = defineEmits(['close', 'record', 'prize']);
// 关闭弹窗
const handleClose = () => {
emit('close');
};
// 查看邀请记录按钮点击事件
const handleRecordClick = () => {
jump({
type: 1,
url: '/pages/invate/invaterecords'
});
console.log('查看邀请记录按钮点击');
emit('record');
};
// 查看奖品按钮点击事件
const handlePrizeClick = () => {
console.log('查看奖品按钮点击');
emit('prize');
};
</script>
<style lang="less" scoped>
@import '@/components/integralArea/InvitePrizePanel.less';
</style>
.sharenpopnologin_overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
.sharenpopnologin_container {
width: 546rpx;
height: 536rpx;
background: linear-gradient(to top, #ffffff 0%, #ffffff 50%, #FFE9C5 100%); // 金色渐变,上面渐变更慢
border-radius: 30rpx;
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.2);
position: relative;
padding: 92rpx 30rpx 0rpx 30rpx;
.popup_content {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
.popup_title {
font-size: 36rpx;
font-weight: bold;
color: #D3A458;
margin-bottom: 60rpx;
line-height: 1.4;
}
.star_character {
margin-bottom: 60rpx;
.star_img {
width: 200rpx;
height: 200rpx;
}
}
.view_button {
width: 400rpx;
height: 80rpx;
background: #D3A458; // 金色渐变
border-radius: 40rpx;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4rpx 16rpx rgba(212, 164, 104, 0.3);
.view_button_text {
font-size: 32rpx;
font-weight: bold;
color: #ffffff;
}
}
}
.close_button {
position: absolute;
bottom: -120rpx;
left: 50%;
transform: translateX(-50%);
width: 60rpx;
height: 60rpx;
background: rgba(255, 255, 255, 0.3);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.2);
z-index: 2;
.close_icon {
font-size: 36rpx;
color: #fff;
font-weight: bold;
line-height: 1;
}
}
}
}
<template>
<view class="sharenpopnologin_overlay" v-if="visible">
<view class="sharenpopnologin_container" @click.stop>
<!-- 弹窗内容 -->
<view class="popup_content">
<!-- 标题文字 -->
<text class="popup_title">快去查看你的权益吧</text>
<!-- 3D星星角色 -->
<view class="star_character">
<image
class="star_img"
:src="$baseUrl + 'integral/1023/invate_star_character1023.png'"
mode="aspectFit"
/>
</view>
<!-- 立即查看按钮 -->
<view class="view_button" @click="handleViewBenefits">
<text class="view_button_text">立即查看</text>
</view>
</view>
<!-- 关闭按钮 -->
<view class="close_button" @click="handleClose">
<text class="close_icon">×</text>
</view>
</view>
</view>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
import { jump, JumpType } from '../../utils';
// Props 定义
const props = defineProps({
visible: {
type: Boolean,
default: false
}
});
// Emits 定义
const emit = defineEmits(['close', 'viewBenefits']);
// 关闭弹窗
const handleClose = () => {
emit('close');
// gotoIntegral();
};
// 查看权益按钮点击
const handleViewBenefits = () => {
emit('viewBenefits');
emit('close');
gotoIntegral();
};
const gotoIntegral = () => {
jump({
url: '/pages/index/index?pageType=integral',
type: JumpType.INNER
});
};
</script>
<style lang="less" scoped>
@import '@/components/integralArea/sharenpopnologin.less';
</style>
.sharepoplogin_overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
.sharepoplogin_container {
// box-sizing: border-box;
width: 546rpx;
height: 536rpx;
background: linear-gradient(to top, #ffffff 0%, #ffffff 50%, #FFE9C5 100%); // 金色渐变,上面渐变更慢
border-radius: 30rpx;
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.2);
position: relative;
padding: 72rpx 30rpx 0rpx 30rpx;
.popup_content {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
.popup_title {
font-size: 36rpx;
font-weight: bold;
color: #D3A458;
margin-bottom: 16rpx;
line-height: 1.4;
}
.popup_subtitle {
font-size: 28rpx;
color: #54390D;
margin-bottom: 40rpx;
line-height: 1.4;
}
.star_character {
margin-bottom: 40rpx;
.star_img {
width: 200rpx;
height: 200rpx;
}
}
.benefits_button {
width: 400rpx;
height: 80rpx;
background: #D3A458;
border-radius: 40rpx;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4rpx 16rpx rgba(212, 164, 104, 0.3);
.benefits_button_text {
font-size: 32rpx;
font-weight: bold;
color: #ffffff;
}
}
}
.close_button {
position: absolute;
bottom: -120rpx;
left: 50%;
transform: translateX(-50%);
width: 60rpx;
height: 60rpx;
background: rgba(255, 255, 255, 0.3);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.2);
z-index: 2;
.close_icon {
font-size: 36rpx;
color: #fff;
font-weight: bold;
line-height: 1;
}
}
}
}
<template>
<view class="sharepoplogin_overlay" v-if="visible">
<view class="sharepoplogin_container" @click.stop>
<!-- 弹窗内容 -->
<view class="popup_content">
<!-- 标题文字 -->
<text class="popup_title">你已注册过飞鹤星妈会会员</text>
<text class="popup_subtitle">直接领取你的权益吧</text>
<!-- 3D星星角色 -->
<view class="star_character">
<image
class="star_img"
:src="$baseUrl + 'integral/1023/invate_star_character1023.png'"
mode="aspectFit"
/>
</view>
<!-- 查看权益按钮 -->
<view class="benefits_button" @click="handleViewBenefits">
<text class="benefits_button_text">查看我的权益</text>
</view>
</view>
<!-- 关闭按钮 -->
<view class="close_button" @click="handleClose">
<text class="close_icon">×</text>
</view>
</view>
</view>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
import { jump, JumpType } from '../../utils';
// Props 定义
const props = defineProps({
visible: {
type: Boolean,
default: false
}
});
// Emits 定义
const emit = defineEmits(['close', 'viewBenefits']);
// 关闭弹窗
const handleClose = () => {
emit('close');
// gotoIntegral();
};
// 查看权益按钮点击
const handleViewBenefits = () => {
emit('viewBenefits');
emit('close');
gotoIntegral();
};
const gotoIntegral = () => {
jump({
url: '/pages/index/index?pageType=integral',
type: JumpType.INNER
});
};
</script>
<style lang="less" scoped>
@import '@/components/integralArea/sharepoplogin.less';
</style>
......@@ -36,22 +36,30 @@
}
.rule_list {
width: 100%;
margin-left: 108rpx;
margin-left: 56rpx;
margin-right: 56rpx;
height: 190rpx;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
.rule_date {
font-size: 26rpx;
color: #54390D;
.rule_rich_text {
width: 100%;
display: block;
}
.rule_text {
font-size: 26rpx;
color: #54390D;
// line-height: 1.5;
display: block;
// margin-bottom: 20rpx;
// :deep(.rule_date) {
// font-size: 26rpx;
// color: #54390D;
// // line-height: 1.5;
// // margin-bottom: 12rpx;
// display: block;
// }
:deep(.rule_text) {
font-size: 24rpx;
color: #54390D;
// line-height: 1.8;
display: block;
// margin-bottom: 8rpx;
}
}
}
}
......
......@@ -6,11 +6,7 @@
<text class="rule_title">任务规则</text>
<view class="rule_list">
<text class="rule_date">2025年4月1日签到规则升级</text>
<text class="rule_text">1. 当月连签2天后,单日签到奖励升至2分</text>
<text class="rule_text">2. 当周满签7天,额外再奖励5分</text>
<text class="rule_text">3. 断签也有机会补,邀请小伙伴帮你助力</text>
<text class="rule_text">4. 每月1号连签次数清零</text>
<rich-text class="rule_rich_text" :nodes="ruleContent"></rich-text>
</view>
</view>
......@@ -23,7 +19,8 @@
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
import { defineProps, defineEmits, ref } from 'vue';
import { useIntegralStore } from '../../stores/integral';
// Props 定义
const props = defineProps({
......@@ -35,6 +32,11 @@ const props = defineProps({
// Emits 定义
const emit = defineEmits(['close']);
const integralStore = useIntegralStore();
const ruleText = ref(integralStore.signinAndTaskInfo?.checkInTodo?.checkInExtra?.rule);
// 富文本内容字符串
const ruleContent = ref(ruleText.value ? ruleText.value : '<div class="rule_text">2025年4月1日签到规则升级</div><div class="rule_text">1. 当月连签2天后,单日签到奖励升至2分</div><div class="rule_text">2. 当周满签7天,额外再奖励5分</div><div class="rule_text">3. 断签也有机会补,邀请小伙伴帮你助力</div><div class="rule_text">4. 每月1号连签次数清零</div>');
// 关闭弹窗
const handleClose = () => {
......
......@@ -54,12 +54,73 @@
}
}
.signedbg_icon {
position: absolute;
bottom: 140rpx;
right: -70rpx;
width: 750rpx;
height: 880rpx;
z-index: 2;
.signedbg_icon_container {
position: fixed;
top: 50%;
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/signedBgIcon.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>
......
.task_complete_overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
.background_container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
}
.task_complete_container {
position: relative;
width: 750rpx;
height: 500rpx;
// background: #ffffff;
border-radius: 30rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
// box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.3);
z-index: 2;
// padding: 40rpx;
.task_title {
font-size: 64rpx;
font-weight: bold;
color: #ffffff;
margin-bottom: 20rpx;
text-align: center;
}
.points_text {
font-size: 32rpx;
color: #ffffff;
margin-bottom: 40rpx;
text-align: center;
}
.coin_icon {
width: 119rpx;
height: 116rpx;
margin-bottom: 40rpx;
}
.accept_button {
width: 300rpx;
height: 80rpx;
background: #D3A458;
border-radius: 40rpx;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 30rpx;
.accept_text {
font-size: 32rpx;
color: #ffffff;
font-weight: bold;
}
}
}
.close_button {
position: absolute;
top: calc(1150rpx);
left: 50%;
transform: translateX(-50%);
width: 56rpx;
height: 56rpx;
background: rgba(255, 255, 255, 0.5);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.2);
z-index: 2;
.close_icon {
font-size: 36rpx;
color: #333333;
font-weight: bold;
line-height: 1;
}
}
}
<template>
<view class="task_complete_overlay" v-if="visible" @click="handleClose">
<!-- 背景容器,右下角镂空透明圆角矩形 -->
<view class="background_container"></view>
<view class="task_complete_container">
<!-- 任务完成标题 -->
<text class="task_title">完成{{ taskTitle }}任务</text>
<!-- 获得积分文字 -->
<text class="points_text">获得{{ points }}积分</text>
<!-- 金币图标 -->
<image class="coin_icon" :src="$baseUrl + `integral/1023/jifenIcon1.png`" mode="aspectFit" />
<!-- 开心收下按钮 -->
<view class="accept_button" @click="handleAccept">
<text class="accept_text">开心收下</text>
</view>
</view>
<!-- 关闭按钮 -->
<view class="close_button" @click="handleClose">
<text class="close_icon">×</text>
</view>
</view>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
// Props 定义
const props = defineProps({
visible: {
type: Boolean,
default: false
},
points: {
type: Number,
default: 100
},
taskTitle: {
type: String,
default: 'xxx'
}
});
// Emits 定义
const emit = defineEmits(['close', 'accept']);
// 关闭弹窗
const handleClose = () => {
emit('close');
};
// 开心收下按钮点击
const handleAccept = () => {
emit('accept');
emit('close');
};
</script>
<style lang="less" scoped>
@import '@/components/qiandao/TaskComplete.less';
</style>
.gongzhonghao_pop_overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: flex-end;
justify-content: center;
z-index: 9999;
.gongzhonghao_pop_container {
width: 100%;
height: 812rpx;
background: #ffffff;
border-radius: 24rpx 24rpx 0 0;
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.1);
overflow: hidden;
animation: slideUp 0.3s ease-out;
.pop_header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx 30rpx 0rpx 30rpx;
// border-bottom: 1rpx solid #f0f0f0;
.pop_title {
font-size: 36rpx;
font-weight: bold;
color: #1D1E25;
}
.close_button {
width: 70rpx;
height: 70rpx;
display: flex;
align-items: center;
justify-content: center;
.close_icon {
font-size: 50rpx;
color: #999999;
font-weight: bold;
line-height: 1;
}
}
}
.pop_content {
padding: 30rpx 40rpx 60rpx 40rpx;
display: flex;
flex-direction: column;
align-items: center;
.description_text {
font-size: 28rpx;
color: #6F6D67; ;
text-align: center;
line-height: 1.5;
margin-bottom: 60rpx;
// padding: 0 20rpx;
}
.qr_code_container {
width: 340rpx;
height: 340rpx;
border-radius: 16rpx;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 60rpx;
// padding: 30rpx;
.qr_code_img {
width: 100%;
height: 100%;
}
}
.download_button {
width: 286rpx;
height: 89rpx;
// align-items: center;
// justify-content: center;
// flex-direction: row;
.download_icon {
width: 100%;
height: 100%;
}
// .download_text {
// font-size: 28rpx;
// color: #666666;
// }
}
}
}
}
@keyframes slideUp {
from {
transform: translateY(100%);
}
to {
transform: translateY(0);
}
}
<template>
<view class="gongzhonghao_pop_overlay" v-if="visible">
<view class="gongzhonghao_pop_container">
<!-- 弹窗头部 -->
<view class="pop_header">
<text class="pop_title">{{ props.title }}</text>
<view class="close_button" @click="handleClose">
<text class="close_icon">×</text>
</view>
</view>
<!-- 弹窗内容 -->
<view class="pop_content">
<text class="description_text">{{ props.description }}</text>
<!-- 二维码区域 -->
<view class="qr_code_container">
<image
class="qr_code_img"
:src="props.qrCodeUrl"
mode="aspectFit"
:show-menu-by-longpress="true"
/>
</view>
<!-- 下载二维码按钮 -->
<view class="download_button" @click="handleDownload">
<image class="download_icon" src="https://course.feihe.com/momclub-picture/homepage/btn_download.png" mode="aspectFit" />
<!-- <text class="download_text">下载二维码</text> -->
</view>
</view>
</view>
</view>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
// Props 定义
const props = defineProps({
visible: {
type: Boolean,
default: false
},
title: {
type: String,
default: '公众号'
},
description: {
type: String,
default: '长按关注星妈会公众号,了解更多专业育儿资讯'
},
qrCodeUrl: {
type: String,
default: 'https://course.feihe.com/momclub-picture/homepage/qrcode_gzh.png'
}
});
// Emits 定义
const emit = defineEmits(['close', 'download']);
// 关闭弹窗
const handleClose = () => {
emit('close');
};
// 下载二维码
const handleDownload = () => {
emit('download', props.title);
};
</script>
<style lang="less" scoped>
@import '@/components/renwu/GongzhonghaoPop.less';
</style>
......@@ -30,29 +30,52 @@
z-index: 2;
.tips_title {
font-size: 50rpx;
font-weight: bold;
font-size: 64rpx;
font-weight: 400rpx;
color: #ffffff;
margin-bottom: 20rpx;
text-align: center;
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 560rpx;
}
.points_text {
font-size: 32rpx;
color: #ffffff;
margin-bottom: 80rpx;
margin-bottom: 60rpx;
text-align: center;
}
.task_complete_icon_container {
position: relative;
width: 300rpx;
height: 300rpx;
margin-bottom: 60rpx;
display: flex;
align-items: center;
justify-content: center;
}
.task_complete_icon {
width: 122rpx;
height: 122rpx;
margin-bottom: 90rpx;
position: absolute;
width: 238rpx;
height: 232rpx;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.task_complete_icon_animating {
animation: taskCompleteIconFly 1.5s linear 1;
z-index: 5;
}
.accept_button {
width: 300rpx;
height: 80rpx;
width: 324rpx;
height: 78rpx;
background: #D3A458;
border-radius: 40rpx;
display: flex;
......@@ -63,7 +86,7 @@
.accept_button_text {
font-size: 32rpx;
color: #ffffff;
font-weight: 500;
font-weight: 400;
}
}
......@@ -74,15 +97,58 @@
display: flex;
align-items: center;
justify-content: center;
background: rgba(0, 0, 0, 0.5);
background: rgba(255, 255, 255, 0.5);
.close_icon {
margin-top: -7rpx;
margin-left: 2rpx;
font-size: 40rpx;
color: #ffffff;
font-weight: bold;
// font-weight: bold;
}
}
}
}
/* 缓动动画关键帧 - 优化版本,更流畅 */
@keyframes taskCompleteIconFly {
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(20deg);
opacity: 0.95;
}
60% {
transform: translate(calc(-50% + 205rpx), calc(-50% + 420rpx)) scale(0.95) rotate(28deg);
opacity: 0.85;
}
75% {
transform: translate(calc(-50% + 215rpx), calc(-50% + 480rpx)) scale(0.6) rotate(36deg);
opacity: 0.7;
}
90% {
transform: translate(calc(-50% + 220rpx), calc(-50% + 530rpx)) scale(0.25) rotate(42deg);
opacity: 0.4;
}
100% {
transform: translate(calc(-50% + 225rpx), calc(-50% + 580rpx)) scale(0) rotate(45deg);
opacity: 0;
}
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -79,8 +79,9 @@
margin-right: 20rpx;
.icon_img {
width: 50rpx;
height: 50rpx;
width: 100%;
height: 100%;
border-radius: 50%;
}
}
......@@ -118,13 +119,16 @@
font-weight: 500;
}
&:active {
// 只有非已完成状态的按钮才有点击效果
&:not(.completed):active {
transform: scale(0.95);
}
&.completed {
background: #F6DEB7;
// border: 1rpx solid #d4a468;
// 已完成状态不添加点击效果
transition: none;
.task_button_text {
color: #ffffff;
......
This diff is collapsed.
......@@ -80,5 +80,6 @@
"uniStatistics" : {
"enable" : false
},
"vueVersion" : "3"
"vueVersion" : "3",
"requiredPrivateInfos" : [ "chooseAddress" ]
}
This diff is collapsed.
This diff is collapsed.
{"code":"000000","data":{"checkInTodo":{"checkInExtra":{"joinRecord":[{"coefficient":null,"credits":"5","index":"1","joined":false,"today":false},{"coefficient":null,"credits":"5","index":"2","joined":true,"today":true},{"coefficient":null,"credits":"6","index":"3","joined":false,"today":false},{"coefficient":null,"credits":"6","index":"4","joined":false,"today":false},{"coefficient":null,"credits":"6","index":"5","joined":false,"today":false},{"coefficient":null,"credits":"6","index":"6","joined":false,"today":false},{"coefficient":null,"credits":"6","index":"7","joined":false,"today":false}],"rule":null,"taskCode":null,"taskId":"1115","type":"CheckIn"},"id":1115,"name":"每日签到-修改"},"taskTodo":[{"id":1195,"name":"小哇演示","taskTodoExtra":{"credits":"20","desc":"小哇演示","extra":"{\"type\":\"GOODS\",\"value\":\"607028533731099656\",\"label\":\"飞鹤星飞帆1段婴儿配方奶粉一段700g(0-6月龄)JXH自营积分+现金1\",\"url\":\"#/goods/607028533731099656\",\"skuId\":\"607028533731099657\"}","icon":"https://firmus-member-test-1253290912.cos.ap-beijing.myqcloud.com/xmh-mini-program/manager/image/2025/10/28/xmh-mini-program_1761636548928_c8b83a5e3c4a40b5b8971f3acbd83362.png","limit":null,"sort":"1","status":"1","title":"小哇演示","type":"BROWSE_PAGE"}},{"id":1120,"name":"关注公众号","taskTodoExtra":{"credits":"10","desc":"关注公众号","extra":null,"icon":"https://firmus-member-test-1253290912.cos.ap-beijing.myqcloud.com/xmh-mini-program/manager/image/2025/10/19/xmh-mini-program_1760883654444_2791e90272af46f29fa07bf4ae90dd53.png","limit":null,"sort":"4","status":"1","title":"关注公众号","type":"FollowWx"}},{"id":1207,"name":"浏览test","taskTodoExtra":{"credits":"10","desc":"浏览test","extra":"{\"type\":\"SELF_GOODS\",\"value\":82,\"label\":\"飞鹤星飞帆1段婴儿配方奶粉xiaowa \",\"url\":\"#/goods/82\"}","icon":"https://firmus-member-test-1253290912.cos.ap-beijing.myqcloud.com/xmh-mini-program/manager/image/2025/10/28/xmh-mini-program_1761652747376_75e68bd480a34eea9ec5b693a8de65f5.png","limit":null,"sort":"10","status":"1","title":"浏览test","type":"BROWSE_PAGE"}},{"id":1127,"name":"消费任务消费任务消费任务","taskTodoExtra":{"credits":"100","desc":"消费任务副标题","extra":"[{\"itemFeaturesPayType\":\"7\",\"itemId\":\"825847777614046618\",\"pictUrl\":\"https://fh01-dev-bucket.oss-cn-beijing.aliyuncs.com/xxyx-fn_bp_bs/item-img/c9a1a676-48ce-7e9a-e7d7d0f70faa009b.jpg\",\"price\":\"100\",\"skuFeatures\":\"1\",\"skuId\":\"825847777614046619\",\"skuProperties\":\"435315499745502188:700462790409131774;435315875667965138:183166545774596244;\",\"skuStatus\":1,\"status\":1,\"storeName\":\"xgren联营店铺001分店\",\"title\":\"任相阁-黑人牙刷30支联营\"}]","icon":"https://firmus-member-test-1253290912.cos.ap-beijing.myqcloud.com/xmh-mini-program/manager/image/2025/10/21/xmh-mini-program_1761027269827_446aa82498834c3abb6b98126599308d.jpg","limit":null,"sort":"23","status":"3","title":"消费任务消费任务消费任务","type":"EXCHANGE_GOODS"}}]},"message":"success","ok":true,"success":true}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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