Compare commits

...

14 Commits

Author SHA1 Message Date
zzc
f5841d0934 fix: create order 2026-02-11 23:59:51 +08:00
zzc
6ca148f65e feat: alipay login 2026-02-11 17:04:11 +08:00
zzc
576227154d feat: alipay navbar 2026-02-11 16:22:28 +08:00
zzc
43675643fb feat: alipay navbar 2026-02-11 16:05:46 +08:00
zzc
c86d0f7351 feat: alipay navbar 2026-02-11 15:50:55 +08:00
zzc
f4cc6ff83d feat: alipay login 2026-02-11 10:09:05 +08:00
zzc
9a69fe704c feat: alipay login 2026-02-11 09:11:56 +08:00
zzc
5257a766f6 fix: share token 2026-02-10 00:12:13 +08:00
zzc
c969c77913 fix: share token 2026-02-10 00:05:08 +08:00
zzc
88138c3300 fix: share token 2026-02-09 23:42:06 +08:00
zzc
85bbf9d8ac fix: share token 2026-02-09 22:31:01 +08:00
zzc
87a2383d0f fix: pengyouquan yulan 2026-02-09 20:30:15 +08:00
zzc
06ded41769 fix: avatar juzhong 2026-02-09 20:18:24 +08:00
zzc
247f238377 fix: make content api 2026-02-09 20:13:20 +08:00
20 changed files with 607 additions and 219 deletions

View File

@@ -2,7 +2,7 @@ import { request } from "@/utils/request.js";
export const createOrder = async (data) => { export const createOrder = async (data) => {
return request({ return request({
url: "/api/pay/wechat/order/create", url: "/api/pay/order/v2/create",
method: "POST", method: "POST",
data, data,
}); });

View File

@@ -36,6 +36,10 @@
</view> </view>
<view class="form-section"> <view class="form-section">
<view v-if="isSinglePage" class="single-page-tip">
<uni-icons type="info" size="16" color="#ff4d4f"></uni-icons>
<text class="tip-text">当前处于预览模式请前往小程序登录</text>
</view>
<view class="input-group"> <view class="input-group">
<text class="label">昵称</text> <text class="label">昵称</text>
<input <input
@@ -51,7 +55,7 @@
<view class="action-section"> <view class="action-section">
<button class="confirm-btn custom-button" @tap="confirmLogin"> <button class="confirm-btn custom-button" @tap="confirmLogin">
一键登录 {{ isSinglePage ? "前往小程序登录" : "一键登录" }}
</button> </button>
<!-- <view class="agreement-row" @tap="toggleAgreement"> <!-- <view class="agreement-row" @tap="toggleAgreement">
@@ -84,12 +88,12 @@
</template> </template>
<script setup> <script setup>
import { ref } from "vue"; import { ref, computed } from "vue";
import { useUserStore } from "@/stores/user"; import { useUserStore } from "@/stores/user";
import { getPlatformProvider } from "@/utils/system"; import { getPlatformProvider, isSinglePageMode } from "@/utils/system";
import { uploadImage } from "@/utils/common"; import { uploadImage } from "@/utils/common";
import { apiLogin } from "@/api/auth.js"; import { apiLogin } from "@/api/auth.js";
import { wxLogin } from "@/utils/login.js"; import { wxLogin, alipayLogin } from "@/utils/login.js";
import PrivacyPopup from "@/components/PrivacyPopup/PrivacyPopup.vue"; import PrivacyPopup from "@/components/PrivacyPopup/PrivacyPopup.vue";
const popupRef = ref(null); const popupRef = ref(null);
@@ -99,8 +103,18 @@ const nickname = ref("");
const userStore = useUserStore(); const userStore = useUserStore();
const props = defineProps({
shareToken: {
type: String,
default: "",
},
});
const emit = defineEmits(["logind"]); const emit = defineEmits(["logind"]);
// 是否处于单页模式(朋友圈打开)
const isSinglePage = computed(() => isSinglePageMode());
const festivalNames = [ const festivalNames = [
"春意", "春意",
"福星", "福星",
@@ -146,6 +160,11 @@ const getFestivalName = () => {
}; };
const open = async () => { const open = async () => {
// #ifdef MP-ALIPAY
handleAlipayLogin();
return;
// #endif
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
const isAgreed = await privacyRef.value.check(); const isAgreed = await privacyRef.value.check();
if (isAgreed) { if (isAgreed) {
@@ -153,11 +172,50 @@ const open = async () => {
} }
// #endif // #endif
// #ifndef MP-WEIXIN // #ifndef MP-WEIXIN || MP-ALIPAY
popupRef.value.open(); popupRef.value.open();
// #endif // #endif
}; };
const handleAlipayLogin = async () => {
try {
uni.showLoading({ title: "登录中...", mask: true });
const code = await alipayLogin();
const imageUrl = avatarUrl.value ? await uploadImage(avatarUrl.value) : "";
const loginRes = await apiLogin({
code,
nickname: nickname.value || getFestivalName(),
avatarUrl: imageUrl,
platform: "alipay",
shareToken: props.shareToken,
});
// 保存用户信息到store
userStore.setUserInfo({
nickName: loginRes?.user?.nickname || nickname.value || getFestivalName(),
avatarUrl: loginRes?.user?.avatar || imageUrl,
id: loginRes?.user?.id,
isVip: loginRes?.isVip || false,
vipExpireAt: loginRes?.vipExpireAt || null,
});
userStore.setToken(loginRes.token);
uni.hideLoading();
uni.showToast({ title: "登录成功", icon: "success" });
emit("logind");
popupRef.value.close();
// 重置临时变量
avatarUrl.value = "";
nickname.value = "";
} catch (err) {
uni.hideLoading();
uni.showToast({ title: "登录失败", icon: "none" });
console.error(err);
}
};
const onPrivacyAgree = () => { const onPrivacyAgree = () => {
popupRef.value.open(); popupRef.value.open();
}; };
@@ -175,9 +233,22 @@ const confirmLogin = async () => {
// uni.showToast({ title: "请先同意用户协议和隐私政策", icon: "none" }); // uni.showToast({ title: "请先同意用户协议和隐私政策", icon: "none" });
// return; // return;
// } // }
if (isSinglePage.value) {
uni.showModal({
title: "提示",
content: "请点击屏幕下方的“前往小程序”按钮,进入完整版体验登录功能",
showCancel: false,
confirmText: "我知道了",
});
return;
}
try { try {
const platform = getPlatformProvider(); const platform = getPlatformProvider();
if (platform === "mp-weixin") { if (platform === "mp-weixin") {
uni.showLoading({ title: "登录中...", mask: true });
const code = await wxLogin(); const code = await wxLogin();
const imageUrl = avatarUrl.value const imageUrl = avatarUrl.value
? await uploadImage(avatarUrl.value) ? await uploadImage(avatarUrl.value)
@@ -188,6 +259,7 @@ const confirmLogin = async () => {
nickname: nickname.value || getFestivalName(), nickname: nickname.value || getFestivalName(),
avatarUrl: imageUrl, avatarUrl: imageUrl,
platform: "wx", platform: "wx",
shareToken: props.shareToken,
}); });
// 保存用户信息到store // 保存用户信息到store
userStore.setUserInfo({ userStore.setUserInfo({
@@ -199,7 +271,7 @@ const confirmLogin = async () => {
}); });
userStore.setToken(loginRes.token); userStore.setToken(loginRes.token);
uni.hideLoading();
uni.showToast({ title: "登录成功", icon: "success" }); uni.showToast({ title: "登录成功", icon: "success" });
emit("logind"); emit("logind");
popupRef.value.close(); popupRef.value.close();
@@ -207,6 +279,8 @@ const confirmLogin = async () => {
// 重置临时变量 // 重置临时变量
avatarUrl.value = ""; avatarUrl.value = "";
nickname.value = ""; nickname.value = "";
} else if (platform === "mp-alipay") {
await handleAlipayLogin();
} }
} catch (err) { } catch (err) {
uni.showToast({ title: "登录失败", icon: "none" }); uni.showToast({ title: "登录失败", icon: "none" });
@@ -318,6 +392,23 @@ defineExpose({ open, close });
.form-section { .form-section {
margin-bottom: 80rpx; margin-bottom: 80rpx;
.single-page-tip {
display: flex;
align-items: center;
justify-content: center;
background: #fff1f0;
border: 1rpx solid #ffccc7;
border-radius: 12rpx;
padding: 16rpx;
margin-bottom: 30rpx;
.tip-text {
font-size: 24rpx;
color: #ff4d4f;
margin-left: 8rpx;
}
}
.input-group { .input-group {
display: flex; display: flex;
align-items: center; align-items: center;

View File

@@ -15,16 +15,14 @@
height: navBarHeight + 'px', height: navBarHeight + 'px',
paddingTop: statusBarHeight + 'px', paddingTop: statusBarHeight + 'px',
backgroundColor: transparent ? 'transparent' : background, backgroundColor: transparent ? 'transparent' : background,
color: color color: color,
boxSizing: 'border-box',
}" }"
> >
<view class="nav-content"> <view class="nav-content">
<view <view v-if="back" class="back" @tap="goBack" :style="{ color: color }"
v-if="back" ></view
class="back" >
@tap="goBack"
:style="{ color: color }"
></view>
<text class="nav-title" :style="{ color: color }">{{ title }}</text> <text class="nav-title" :style="{ color: color }">{{ title }}</text>
</view> </view>
</view> </view>
@@ -33,7 +31,7 @@
<script setup> <script setup>
import { ref, onMounted } from "vue"; import { ref, onMounted } from "vue";
import { getBavBarHeight, getStatusBarHeight } from "@/utils/system"; import { getTitleBarHeight } from "@/utils/system";
const props = defineProps({ const props = defineProps({
title: { title: {
@@ -70,8 +68,9 @@ const navBarHeight = ref(64);
const statusBarHeight = ref(20); const statusBarHeight = ref(20);
onMounted(() => { onMounted(() => {
navBarHeight.value = getBavBarHeight(); const systemInfo = uni.getSystemInfoSync();
statusBarHeight.value = getStatusBarHeight(); statusBarHeight.value = systemInfo.statusBarHeight || 20;
navBarHeight.value = statusBarHeight.value + getTitleBarHeight();
}); });
const goBack = () => { const goBack = () => {
@@ -89,7 +88,7 @@ const goBack = () => {
width: 100%; width: 100%;
box-sizing: border-box; box-sizing: border-box;
z-index: 999; z-index: 999;
&.fixed { &.fixed {
position: fixed; position: fixed;
top: 0; top: 0;
@@ -121,4 +120,4 @@ const goBack = () => {
text-align: center; text-align: center;
margin-right: 50rpx; /* Balance back button */ margin-right: 50rpx; /* Balance back button */
} }
</style> </style>

View File

@@ -35,8 +35,8 @@ const privacyContractName = ref("《用户隐私保护指引》");
const emit = defineEmits(["agree"]); const emit = defineEmits(["agree"]);
let resolveCheck = null; let resolveCheck = null;
// #ifdef MP-WEIXIN
const check = () => { const check = () => {
// #ifdef MP-WEIXIN
return new Promise((resolve) => { return new Promise((resolve) => {
if (uni.getPrivacySetting) { if (uni.getPrivacySetting) {
uni.getPrivacySetting({ uni.getPrivacySetting({
@@ -59,8 +59,11 @@ const check = () => {
resolve(true); resolve(true);
} }
}); });
// #endif
// #ifdef MP-ALIPAY
return Promise.resolve(true);
// #endif
}; };
// #endif
// Only for WeChat Mini Program // Only for WeChat Mini Program
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN

View File

@@ -157,7 +157,11 @@
"navigationBarTextStyle": "black", "navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app", "navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8", "navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8" "backgroundColor": "#F8F8F8",
"mp-alipay": {
"transparentTitle": "always",
"titlePenetrate": "YES"
}
}, },
"tabBar": { "tabBar": {
"color": "#999999", "color": "#999999",

View File

@@ -128,7 +128,7 @@ import { ref, onMounted } from "vue";
import { onLoad, onShareAppMessage, onShareTimeline } from "@dcloudio/uni-app"; import { onLoad, onShareAppMessage, onShareTimeline } from "@dcloudio/uni-app";
import { getPageDetail } from "@/api/system.js"; import { getPageDetail } from "@/api/system.js";
import { getAvatarRecommendList } from "@/api/avatar.js"; import { getAvatarRecommendList } from "@/api/avatar.js";
import { saveViewRequest } from "@/utils/common.js"; import { getShareToken, saveViewRequest } from "@/utils/common.js";
import NavBar from "@/components/NavBar/NavBar.vue"; import NavBar from "@/components/NavBar/NavBar.vue";
const defaultAvatar = const defaultAvatar =
@@ -145,20 +145,22 @@ onLoad((options) => {
fetchFrames(); fetchFrames();
}); });
onShareAppMessage(() => { onShareAppMessage(async () => {
const token = await getShareToken("avatar_detail", detailData.value?.id);
return { return {
title: "快来看看我刚领到的新年专属头像 🎊", title: "快来看看我刚领到的新年专属头像 🎊",
path: `/pages/avatar/detail?shareToken=${shareToken.value}`, path: `/pages/avatar/detail?shareToken=${token}`,
imageUrl: imageUrl:
detailData.value?.imageUrl || detailData.value?.imageUrl ||
"https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png", "https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png",
}; };
}); });
onShareTimeline(() => { onShareTimeline(async () => {
const token = await getShareToken("avatar_timeline", detailData.value?.id);
return { return {
title: "快来看看我刚领到的新年专属头像 🎊", title: "快来看看我刚领到的新年专属头像 🎊",
query: `shareToken=${shareToken.value}`, query: `shareToken=${token}`,
imageUrl: imageUrl:
detailData.value?.imageUrl || detailData.value?.imageUrl ||
"https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png", "https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png",
@@ -169,7 +171,7 @@ const fetchDetail = async () => {
try { try {
// uni.showLoading({ title: "加载中..." }); // uni.showLoading({ title: "加载中..." });
const res = await getPageDetail(shareToken.value); const res = await getPageDetail(shareToken.value);
saveViewRequest(shareToken.value, "avatar_download", res.id); saveViewRequest(shareToken.value, "avatar_detail", res.id);
if (res) { if (res) {
detailData.value = res; detailData.value = res;
} }

View File

@@ -71,15 +71,11 @@
<view v-if="activeTool === 'avatar'" class="section"> <view v-if="activeTool === 'avatar'" class="section">
<view class="section-title">选择头像</view> <view class="section-title">选择头像</view>
<view class="grid"> <view class="grid">
<view class="grid-item upload-card"> <view class="grid-item upload-card" @tap="onChooseAlbum">
<button <view class="wechat-avatar-btn">
class="wechat-avatar-btn"
open-type="chooseAvatar"
@chooseavatar="onChooseAvatar"
>
<view class="upload-icon"></view> <view class="upload-icon"></view>
<text class="upload-text">微信头像</text> <text class="upload-text">上传头像</text>
</button> </view>
</view> </view>
<view <view
v-for="item in systemAvatars" v-for="item in systemAvatars"
@@ -144,7 +140,11 @@
/> />
<!-- Login Popup --> <!-- Login Popup -->
<LoginPopup ref="loginPopupRef" @logind="handleLogind" /> <LoginPopup
ref="loginPopupRef"
@logind="handleLogind"
:share-token="shareToken"
/>
<!-- More Avatar Popup --> <!-- More Avatar Popup -->
<uni-popup ref="morePopup" type="bottom" background-color="#fff"> <uni-popup ref="morePopup" type="bottom" background-color="#fff">
@@ -199,8 +199,10 @@ import {
getShareToken, getShareToken,
generateObjectId, generateObjectId,
uploadImage, uploadImage,
saveViewRequest,
} from "@/utils/common.js"; } from "@/utils/common.js";
import NavBar from "@/components/NavBar/NavBar.vue"; import NavBar from "@/components/NavBar/NavBar.vue";
import LoginPopup from "@/components/LoginPopup/LoginPopup.vue";
const userStore = useUserStore(); const userStore = useUserStore();
const loginPopupRef = ref(null); const loginPopupRef = ref(null);
@@ -210,6 +212,7 @@ const isLoggedIn = computed(() => !!userStore.userInfo.nickName);
const systemAvatars = ref([]); const systemAvatars = ref([]);
const frames = ref([]); const frames = ref([]);
const decors = ref([]); const decors = ref([]);
const shareToken = ref("");
// Panel and steps logic // Panel and steps logic
const activeTool = ref("avatar"); const activeTool = ref("avatar");
@@ -351,6 +354,11 @@ onLoad((options) => {
currentAvatar.value = recommendItem; currentAvatar.value = recommendItem;
} }
} }
if (options.shareToken) {
shareToken.value = options.shareToken;
saveViewRequest("avatar_download", options.shareToken);
}
}); });
onReachBottom(() => { onReachBottom(() => {
@@ -462,16 +470,46 @@ const handleLogind = async () => {
// Logic after successful login if needed // Logic after successful login if needed
}; };
const onChooseAvatar = async (e) => { const onChooseAlbum = () => {
const avatarUrl = e.detail.avatarUrl; uni.chooseImage({
if (!avatarUrl) return; count: 1,
sizeType: ["original", "compressed"],
sourceType: ["album"],
success: (res) => {
const path = res.tempFilePaths[0];
// #ifdef MP-ALIPAY
// 支付宝小程序不支持 cropImage直接使用原图
onAvatarSelect(path);
// #endif
// #ifndef MP-ALIPAY
// 调用系统裁剪,强制 1:1
uni.cropImage({
src: path,
aspectRatio: "1:1",
success: (cropRes) => {
onAvatarSelect(cropRes.tempFilePath);
},
fail: (err) => {
console.warn("Crop failed or cancelled", err);
onAvatarSelect(path);
},
});
// #endif
},
});
};
const onAvatarSelect = async (url) => {
if (!url) return;
uni.showLoading({ title: "上传中...", mask: true }); uni.showLoading({ title: "上传中...", mask: true });
try { try {
const imageUrl = await uploadImage(avatarUrl); const imageUrl = await uploadImage(url);
currentAvatar.value = { currentAvatar.value = {
id: "wechat_" + Date.now(), id: "custom_" + Date.now(),
imageUrl: imageUrl, imageUrl: imageUrl,
}; };
uni.hideLoading(); uni.hideLoading();
@@ -694,13 +732,16 @@ onShareAppMessage(async () => {
return { return {
title: "我做了一个新头像,真的太好看了", title: "我做了一个新头像,真的太好看了",
path: `/pages/avatar/detail?shareToken=${shareToken}`, path: `/pages/avatar/detail?shareToken=${shareToken}`,
imageUrl, // 使用默认封面或 popularCards 的封面 imageUrl:
imageUrl + "?imageMogr2/thumbnail/!500x400r/gravity/Center/crop/500x400",
}; };
}); });
onShareTimeline(() => { onShareTimeline(async () => {
const shareToken = await getShareToken("avatar_timeline");
return { return {
title: "快来定制你的新年专属头像 🎊", title: "快来定制你的新年专属头像 🎊",
query: `shareToken=${shareToken}`,
imageUrl: imageUrl:
"https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png", "https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png",
}; };

View File

@@ -117,7 +117,7 @@
import { ref } from "vue"; import { ref } from "vue";
import { onLoad, onShareAppMessage, onShareTimeline } from "@dcloudio/uni-app"; import { onLoad, onShareAppMessage, onShareTimeline } from "@dcloudio/uni-app";
import { getPageDetail } from "@/api/system.js"; import { getPageDetail } from "@/api/system.js";
import { saveViewRequest } from "@/utils/common.js"; import { getShareToken, saveViewRequest } from "@/utils/common.js";
import NavBar from "@/components/NavBar/NavBar.vue"; import NavBar from "@/components/NavBar/NavBar.vue";
const cardId = ref(""); const cardId = ref("");
@@ -132,20 +132,22 @@ onLoad(async (options) => {
} }
}); });
onShareAppMessage(() => { onShareAppMessage(async () => {
const token = await getShareToken("card_detail", cardDetail.value?.id);
return { return {
title: "送你一张精美的新春祝福卡片 🎊", title: "送你一张精美的新春祝福卡片 🎊",
path: `/pages/detail/index?shareToken=${cardDetail.value?.shareToken || ""}`, path: `/pages/detail/index?shareToken=${token || ""}`,
imageUrl: imageUrl:
cardDetail.value?.imageUrl || cardDetail.value?.imageUrl ||
"https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png", "https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png",
}; };
}); });
onShareTimeline(() => { onShareTimeline(async () => {
const token = await getShareToken("card_timeline", cardDetail.value?.id);
return { return {
title: "送你一张精美的新春祝福卡片 🎊", title: "送你一张精美的新春祝福卡片 🎊",
query: `shareToken=${cardDetail.value?.shareToken || ""}`, query: `shareToken=${token}`,
imageUrl: imageUrl:
cardDetail.value?.imageUrl || cardDetail.value?.imageUrl ||
"https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png", "https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png",

View File

@@ -109,7 +109,11 @@
style="width: 300px; height: 500px; position: fixed; left: 9999px" style="width: 300px; height: 500px; position: fixed; left: 9999px"
></canvas> --> ></canvas> -->
<LoginPopup ref="loginPopupRef" @logind="handleLogind" /> <LoginPopup
ref="loginPopupRef"
@logind="handleLogind"
:share-token="shareToken"
/>
</view> </view>
</template> </template>
@@ -130,6 +134,7 @@ import {
getShareToken, getShareToken,
saveRemoteImageToLocal, saveRemoteImageToLocal,
saveRecordRequest, saveRecordRequest,
saveViewRequest,
} from "@/utils/common.js"; } from "@/utils/common.js";
import NavBar from "@/components/NavBar/NavBar.vue"; import NavBar from "@/components/NavBar/NavBar.vue";
@@ -142,6 +147,7 @@ const remainingCount = ref(0);
const allowShareCount = ref(0); const allowShareCount = ref(0);
const useShareCount = ref(0); const useShareCount = ref(0);
const canUse = ref(true); const canUse = ref(true);
const shareToken = ref("");
// 音效控制 // 音效控制
const audioContext = uni.createInnerAudioContext(); const audioContext = uni.createInnerAudioContext();
@@ -155,7 +161,12 @@ audioContext.onEnded(() => {
} }
}); });
onLoad(() => {}); onLoad((options) => {
if (options.shareToken) {
shareToken.value = options.shareToken;
saveViewRequest(options.shareToken, "fortune_draw");
}
});
onShow(() => { onShow(() => {
checkDrawStatus(); checkDrawStatus();
@@ -176,15 +187,20 @@ onShareAppMessage(async () => {
}; };
}); });
onShareTimeline(() => { onShareTimeline(async () => {
const shareToken = await getShareToken("fortune_timeline");
return { return {
title: "新春到,抽灵签!快来测测你的新年运势 🏮", title: "新春到,抽灵签!快来测测你的新年运势 🏮",
query: `shareToken=${shareToken}`,
imageUrl: imageUrl:
"https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png", "https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png",
}; };
}); });
const handleLogind = async () => { const handleLogind = async () => {
if (shareToken.value) {
console.log(11111111, shareToken.value);
}
checkDrawStatus(); checkDrawStatus();
}; };

View File

@@ -31,7 +31,9 @@
class="notice-swiper-item" class="notice-swiper-item"
@tap="onNoticeTap(tip)" @tap="onNoticeTap(tip)"
> >
<text v-if="tip.tag" class="notice-tag">{{ getTagText(tip.tag) }}</text> <text v-if="tip.tag" class="notice-tag">{{
getTagText(tip.tag)
}}</text>
<text class="notice-text">{{ tip.text }}</text> <text class="notice-text">{{ tip.text }}</text>
</swiper-item> </swiper-item>
</swiper> </swiper>
@@ -209,15 +211,16 @@ onShareAppMessage(async () => {
}; };
}); });
onShareTimeline(() => { onShareTimeline(async () => {
const shareToken = await getShareToken("index_timeline");
return { return {
title: "新年好运已送达 🎊|祝福卡·头像·壁纸", title: "新年好运已送达 🎊|祝福卡·头像·壁纸",
query: `shareToken=${shareToken}`,
imageUrl: imageUrl:
"https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png", "https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png",
}; };
}); });
const getIndexTips = async () => { const getIndexTips = async () => {
const res = await getTipsList(); const res = await getTipsList();
noticeList.value = res || []; noticeList.value = res || [];

View File

@@ -154,7 +154,7 @@
@tap="selectTitle(title)" @tap="selectTitle(title)"
> >
<image <image
:src="title.imageUrl" :src="getTitleThumbUrl(title.imageUrl)"
class="title-cover" class="title-cover"
mode="aspectFit" mode="aspectFit"
/> />
@@ -427,7 +427,11 @@
style="width: 540px; height: 960px" style="width: 540px; height: 960px"
/> />
<LoginPopup ref="loginPopupRef" @logind="handleLogind" /> <LoginPopup
ref="loginPopupRef"
@logind="handleLogind"
:share-token="shareToken"
/>
</view> </view>
</template> </template>
@@ -653,8 +657,8 @@ const fontSize = ref(38);
const fontWeight = ref("normal"); // 默认加粗 const fontWeight = ref("normal"); // 默认加粗
const textColors = [ const textColors = [
'#F8DA84', "#F8DA84",
'#B4802C', "#B4802C",
"#000000", "#000000",
"#ffffff", "#ffffff",
"#ff3b30", "#ff3b30",
@@ -734,11 +738,15 @@ const bubbleOffsetY = ref(0);
const bubbleMaxWidth = ref(400); // 默认宽度 const bubbleMaxWidth = ref(400); // 默认宽度
const userOffsetX = ref(0); const userOffsetX = ref(0);
const userOffsetY = ref(0); const userOffsetY = ref(0);
const shareToken = ref("");
onLoad((options) => { onLoad((options) => {
getTemplateList(); getTemplateList();
getTemplateContentList(); getTemplateContentList();
getTemplateTitleList(); getTemplateTitleList();
if (options.shareToken) {
shareToken.value = options.shareToken;
}
}); });
const syncUserInfo = () => { const syncUserInfo = () => {
@@ -925,6 +933,10 @@ const getThumbUrl = (url) => {
return `${url}?imageView2/1/w/340/h/600/q/80`; return `${url}?imageView2/1/w/340/h/600/q/80`;
}; };
const getTitleThumbUrl = (url) => {
return `${url}?imageView2/2/w/200/h/200/q/80`;
};
const getTemplateContentList = async (isLoadMore = false) => { const getTemplateContentList = async (isLoadMore = false) => {
if (loadingBlessings.value || (!hasMoreBlessings.value && isLoadMore)) return; if (loadingBlessings.value || (!hasMoreBlessings.value && isLoadMore)) return;
@@ -982,17 +994,18 @@ const onPanelScrollToLower = () => {
}; };
onShareAppMessage(async (options) => { onShareAppMessage(async (options) => {
if (!isLoggedIn.value) {
const shareToken = await getShareToken("card_generate_not_login", "");
return {
title: "快来制作新春祝福卡片🎉",
path: "/pages/make/index?shareToken=" + shareToken,
imageUrl:
"https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png",
};
}
getShareReward({ scene: "card_generate" }); getShareReward({ scene: "card_generate" });
if (options.from === "button") { if (options.from === "button") {
if (!isLoggedIn.value) {
const shareToken = await getShareToken("card_generate_not_login", "");
return {
title: "新春祝福",
path: "/pages/index/index?shareToken=" + shareToken,
imageUrl:
"https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png",
};
}
// 1. 确保有 cardId (如果内容有变动,最好是新建) // 1. 确保有 cardId (如果内容有变动,最好是新建)
const id = createCard(); const id = createCard();
@@ -1007,17 +1020,19 @@ onShareAppMessage(async (options) => {
} else { } else {
const shareToken = await getShareToken("card_generate_index", ""); const shareToken = await getShareToken("card_generate_index", "");
return { return {
title: "新春祝福", title: "快来制作新春祝福卡片🎉",
path: `/pages/index/index?shareToken=${shareToken}`, path: `/pages/make/index?shareToken=${shareToken}`,
imageUrl: imageUrl:
"https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png", "https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png",
}; };
} }
}); });
onShareTimeline(() => { onShareTimeline(async () => {
const shareToken = await getShareToken("card_timeline");
return { return {
title: "送你一张精美的新春祝福卡片 🎊", title: "送你一张精美的新春祝福卡片 🎊",
query: `shareToken=${shareToken}`,
imageUrl: imageUrl:
"https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png", "https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png",
}; };
@@ -1165,6 +1180,12 @@ const saveByCanvas = async (save = true) => {
canvas.width = baseW * dpr; canvas.width = baseW * dpr;
canvas.height = baseH * dpr; canvas.height = baseH * dpr;
// ⚠️ 关键修复:重置变换矩阵,防止多次调用导致 scale 累积
// 支付宝小程序在设置 width/height 后可能未完全重置 Context 状态
ctx.setTransform(1, 0, 0, 1, 0, 0);
// 清空画布(使用物理像素尺寸)
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 缩放上下文,使得后续绘制指令依然可以使用逻辑坐标 (baseW, baseH) // 缩放上下文,使得后续绘制指令依然可以使用逻辑坐标 (baseW, baseH)
ctx.scale(dpr, dpr); ctx.scale(dpr, dpr);
@@ -1186,6 +1207,11 @@ const saveByCanvas = async (save = true) => {
const r2p = (rpx) => (rpx * baseW) / 506; const r2p = (rpx) => (rpx * baseW) / 506;
try { try {
// #ifdef MP-ALIPAY
// 支付宝环境:显式等待 Canvas 节点就绪,避免过早绘制
await new Promise((resolve) => setTimeout(resolve, 300));
// #endif
// 1⃣ 画背景 // 1⃣ 画背景
// ⭐ 先加载背景图 // ⭐ 先加载背景图
const [bgImg, avatarImg, titleImg] = await Promise.all([ const [bgImg, avatarImg, titleImg] = await Promise.all([
@@ -1251,6 +1277,11 @@ const saveByCanvas = async (save = true) => {
}); });
// 6⃣ 输出 // 6⃣ 输出
// #ifdef MP-ALIPAY
// 支付宝环境:等待绘制指令执行完毕,确保渲染完成
await new Promise((resolve) => setTimeout(resolve, 300));
// #endif
uni.canvasToTempFilePath({ uni.canvasToTempFilePath({
canvas: canvas, // Canvas 2D 必须传 canvas 实例 canvas: canvas, // Canvas 2D 必须传 canvas 实例
width: canvas.width, width: canvas.width,

View File

@@ -99,7 +99,6 @@ import {
onPullDownRefresh, onPullDownRefresh,
onReachBottom, onReachBottom,
onShareAppMessage, onShareAppMessage,
onShareTimeline,
} from "@dcloudio/uni-app"; } from "@dcloudio/uni-app";
import { getMyCard } from "@/api/mine.js"; import { getMyCard } from "@/api/mine.js";
import NavBar from "@/components/NavBar/NavBar.vue"; import NavBar from "@/components/NavBar/NavBar.vue";
@@ -148,14 +147,6 @@ onShareAppMessage(async (options) => {
} }
}); });
onShareTimeline(() => {
return {
title: "送你一张精美的新春祝福卡片 🎊",
imageUrl:
"https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png",
};
});
const fetchList = async (reset = false) => { const fetchList = async (reset = false) => {
if (loading.value) return; if (loading.value) return;
if (reset) { if (reset) {

View File

@@ -136,7 +136,8 @@
<script setup> <script setup>
import { ref, computed, onMounted } from "vue"; import { ref, computed, onMounted } from "vue";
import { useUserStore } from "@/stores/user"; import { useUserStore } from "@/stores/user";
import { onShareAppMessage, onShareTimeline } from "@dcloudio/uni-app"; import { onShareAppMessage } from "@dcloudio/uni-app";
import { getShareToken } from "@/utils/common";
import LoginPopup from "@/components/LoginPopup/LoginPopup.vue"; import LoginPopup from "@/components/LoginPopup/LoginPopup.vue";
const userStore = useUserStore(); const userStore = useUserStore();
@@ -158,7 +159,7 @@ const userInfo = computed(() => ({
const isLoggedIn = computed(() => !!userStore.userInfo.nickName); const isLoggedIn = computed(() => !!userStore.userInfo.nickName);
const isIos = computed(() => uni.getSystemInfoSync().osName === "ios"); const isIos = false;
onMounted(() => { onMounted(() => {
const sysInfo = uni.getSystemInfoSync(); const sysInfo = uni.getSystemInfoSync();
@@ -167,18 +168,11 @@ onMounted(() => {
navBarHeight.value = 44; navBarHeight.value = 44;
}); });
onShareAppMessage(() => { onShareAppMessage(async () => {
return { const shareToken = await getShareToken("mine");
title: "新年好运已送达 🎊|祝福卡·头像·壁纸",
path: "/pages/index/index",
imageUrl:
"https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png",
};
});
onShareTimeline(() => {
return { return {
title: "新年好运已送达 🎊|祝福卡·头像·壁纸", title: "新年好运已送达 🎊|祝福卡·头像·壁纸",
path: "/pages/index/index?shareToken=" + shareToken,
imageUrl: imageUrl:
"https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png", "https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png",
}; };

View File

@@ -111,6 +111,7 @@ import { storeToRefs } from "pinia";
import { useUserStore } from "@/stores/user"; import { useUserStore } from "@/stores/user";
import { createOrder, getVipPlan } from "@/api/pay.js"; import { createOrder, getVipPlan } from "@/api/pay.js";
import NavBar from "@/components/NavBar/NavBar.vue"; import NavBar from "@/components/NavBar/NavBar.vue";
import { getPlatformProvider } from "@/utils/system";
const userStore = useUserStore(); const userStore = useUserStore();
const { userInfo } = storeToRefs(userStore); const { userInfo } = storeToRefs(userStore);
@@ -179,8 +180,11 @@ const handlePurchase = async () => {
}); });
if (orderRes?.payParams) { if (orderRes?.payParams) {
const platform = getPlatformProvider();
const provider = platform === "mp-alipay" ? "alipay" : "wxpay";
uni.requestPayment({ uni.requestPayment({
provider: "wxpay", provider: provider,
...orderRes.payParams, ...orderRes.payParams,
success(res) { success(res) {
uni.showToast({ title: "支付成功", icon: "success" }); uni.showToast({ title: "支付成功", icon: "success" });
@@ -189,7 +193,9 @@ const handlePurchase = async () => {
}, },
fail(err) { fail(err) {
console.log("payment fail", err); console.log("payment fail", err);
if (err.errMsg.indexOf("cancel") > -1) { // 支付宝取消支付的错误码是 6001
// 微信取消支付的错误信息包含 cancel
if (err.errMsg.indexOf("cancel") > -1 || err.resultCode === "6001") {
uni.showToast({ title: "支付已取消", icon: "none" }); uni.showToast({ title: "支付已取消", icon: "none" });
} else { } else {
uni.showToast({ title: "支付失败", icon: "none" }); uni.showToast({ title: "支付失败", icon: "none" });

View File

@@ -11,7 +11,11 @@
<text class="main">新春祝福</text> <text class="main">新春祝福</text>
</view> </view>
<text class="hero-sub">新年快乐万事如意</text> <text class="hero-sub">新年快乐万事如意</text>
<image class="hero-decor" src="https://file.lihailezzc.com/resource/58c8d19e5f2d9c958a7b8b9f44b8c3e3.png" mode="aspectFill" /> <image
class="hero-decor"
src="https://file.lihailezzc.com/resource/58c8d19e5f2d9c958a7b8b9f44b8c3e3.png"
mode="aspectFill"
/>
</view> </view>
<!-- 功能入口宫格 --> <!-- 功能入口宫格 -->
@@ -39,7 +43,12 @@
</view> </view>
<scroll-view scroll-x class="cards-scroll" show-scrollbar="false"> <scroll-view scroll-x class="cards-scroll" show-scrollbar="false">
<view class="cards-wrap"> <view class="cards-wrap">
<view v-for="(card, i) in popularCards" :key="i" class="use-card" @tap="previewCard(card)"> <view
v-for="(card, i) in popularCards"
:key="i"
class="use-card"
@tap="previewCard(card)"
>
<image :src="card.cover" class="use-cover" mode="aspectFill" /> <image :src="card.cover" class="use-cover" mode="aspectFill" />
<view class="use-info"> <view class="use-info">
<text class="use-title">{{ card.title }}</text> <text class="use-title">{{ card.title }}</text>
@@ -68,7 +77,12 @@
</view> </view>
<view class="feed-content"> <view class="feed-content">
<text class="feed-text">{{ post.text }}</text> <text class="feed-text">{{ post.text }}</text>
<image v-if="post.image" :src="post.image" class="feed-image" mode="aspectFill" /> <image
v-if="post.image"
:src="post.image"
class="feed-image"
mode="aspectFill"
/>
</view> </view>
<view class="feed-actions"> <view class="feed-actions">
<view class="action" @tap="like(i)"> <view class="action" @tap="like(i)">
@@ -98,78 +112,123 @@
</template> </template>
<script setup> <script setup>
import { ref } from 'vue' import { ref } from "vue";
import { onPullDownRefresh, onShareAppMessage, onShareTimeline } from '@dcloudio/uni-app' import {
import { getBavBarHeight } from '@/utils/system' onPullDownRefresh,
onShareAppMessage,
onShareTimeline,
} from "@dcloudio/uni-app";
import { getBavBarHeight } from "@/utils/system";
import { getShareToken } from "@/utils/common";
const features = ref([ const features = ref([
{ title: '新春祝福卡片', subtitle: '龙年贺卡', icon: 'https://file.lihailezzc.com/resource/6b6cb83abf3a9c9b78a4744238b5b851.png', type: 'card' }, {
{ title: '视频拜年', subtitle: 'AI合成短视频', icon: 'https://file.lihailezzc.com/resource/1a7b4b9d2b9b4bcb88f14c9f1ef4413a.png', type: 'video' }, title: "新春祝福卡片",
{ title: '新春头像装饰', subtitle: '锦上添花', icon: 'https://file.lihailezzc.com/resource/5e7d2b8d1c34c22f9c4f4f4cb4cba70d.png', type: 'avatar_decor' }, subtitle: "龙年贺卡",
{ title: '马年主题头像框', subtitle: '2026限定', icon: 'https://file.lihailezzc.com/resource/9f80ab295b7e0a7a5f62c3b0f2d7a11c.png', type: 'avatar_frame' }, icon: "https://file.lihailezzc.com/resource/6b6cb83abf3a9c9b78a4744238b5b851.png",
]) type: "card",
},
{
title: "视频拜年",
subtitle: "AI合成短视频",
icon: "https://file.lihailezzc.com/resource/1a7b4b9d2b9b4bcb88f14c9f1ef4413a.png",
type: "video",
},
{
title: "新春头像装饰",
subtitle: "锦上添花",
icon: "https://file.lihailezzc.com/resource/5e7d2b8d1c34c22f9c4f4f4cb4cba70d.png",
type: "avatar_decor",
},
{
title: "马年主题头像框",
subtitle: "2026限定",
icon: "https://file.lihailezzc.com/resource/9f80ab295b7e0a7a5f62c3b0f2d7a11c.png",
type: "avatar_frame",
},
]);
const popularCards = ref([ const popularCards = ref([
{ title: '极简祝福金框', sub: '极简风格', cover: 'https://file.lihailezzc.com/resource/7a5b2f2f5d6c42b5b21b8b1c9b28a3a1.jpg' }, {
{ title: '红包封面', sub: '新春限定', cover: 'https://file.lihailezzc.com/resource/9b3d2a1a4c7b4a4a9e3b94c4a2b9c3e2.jpg' }, title: "极简祝福金框",
{ title: '新春大拜年卡', sub: '全家福', cover: 'https://file.lihailezzc.com/resource/3a2b1c9d7e6f5a4b3c2d1e0f9a8b7c6d.jpg' } sub: "极简风格",
]) cover:
"https://file.lihailezzc.com/resource/7a5b2f2f5d6c42b5b21b8b1c9b28a3a1.jpg",
},
{
title: "红包封面",
sub: "新春限定",
cover:
"https://file.lihailezzc.com/resource/9b3d2a1a4c7b4a4a9e3b94c4a2b9c3e2.jpg",
},
{
title: "新春大拜年卡",
sub: "全家福",
cover:
"https://file.lihailezzc.com/resource/3a2b1c9d7e6f5a4b3c2d1e0f9a8b7c6d.jpg",
},
]);
const feeds = ref([ const feeds = ref([
{ {
name: '陈小明', name: "陈小明",
time: '刚刚', time: "刚刚",
avatar: 'https://file.lihailezzc.com/resource/1463f294244c11cf274a5eaae115872a.jpeg', avatar:
text: '祝大家新的一年万事如意,阖家幸福!龙年行大运,喜气满满~✨', "https://file.lihailezzc.com/resource/1463f294244c11cf274a5eaae115872a.jpeg",
image: 'https://file.lihailezzc.com/resource/02b7d1f8a9c34f2b8a2a7d4e9b1a5c8d.jpg', text: "祝大家新的一年万事如意,阖家幸福!龙年行大运,喜气满满~✨",
image:
"https://file.lihailezzc.com/resource/02b7d1f8a9c34f2b8a2a7d4e9b1a5c8d.jpg",
likes: 12, likes: 12,
comments: 3 comments: 3,
}, },
{ {
name: '李华', name: "李华",
time: '5分钟前', time: "5分钟前",
avatar: 'https://file.lihailezzc.com/resource/1463f294244c11cf274a5eaae115872a.jpeg', avatar:
text: '新年快乐祝朋友们身体健康、工作顺利2026马到成功', "https://file.lihailezzc.com/resource/1463f294244c11cf274a5eaae115872a.jpeg",
image: '', text: "新年快乐祝朋友们身体健康、工作顺利2026马到成功",
image: "",
likes: 8, likes: 8,
comments: 2 comments: 2,
}, },
{ {
name: '王伟', name: "王伟",
time: '10分钟前', time: "10分钟前",
avatar: 'https://file.lihailezzc.com/resource/1463f294244c11cf274a5eaae115872a.jpeg', avatar:
text: '给你们拜年啦!', "https://file.lihailezzc.com/resource/1463f294244c11cf274a5eaae115872a.jpeg",
image: 'https://file.lihailezzc.com/resource/1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f.jpg', text: "给你们拜年啦!",
image:
"https://file.lihailezzc.com/resource/1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f.jpg",
likes: 6, likes: 6,
comments: 1 comments: 1,
} },
]) ]);
const onFeatureTap = (item) => { const onFeatureTap = (item) => {
uni.showToast({ title: `进入:${item.title}`, icon: 'none' }) uni.showToast({ title: `进入:${item.title}`, icon: "none" });
// 可跳转到对应功能页面 // 可跳转到对应功能页面
// uni.navigateTo({ url: `/pages/${item.type}/index` }) // uni.navigateTo({ url: `/pages/${item.type}/index` })
} };
const previewCard = (card) => { const previewCard = (card) => {
uni.previewImage({ urls: [card.cover] }) uni.previewImage({ urls: [card.cover] });
} };
const onMore = (type) => { const onMore = (type) => {
uni.showToast({ title: '即将开放~', icon: 'none' }) uni.showToast({ title: "即将开放~", icon: "none" });
} };
const like = (index) => { const like = (index) => {
feeds.value[index].likes += 1 feeds.value[index].likes += 1;
} };
const comment = (index) => { const comment = (index) => {
uni.showToast({ title: '评论功能开发中~', icon: 'none' }) uni.showToast({ title: "评论功能开发中~", icon: "none" });
} };
const share = () => { const share = () => {
uni.showShareMenu && uni.showShareMenu() uni.showShareMenu && uni.showShareMenu();
} };
onShareAppMessage(() => { onShareAppMessage(() => {
return { return {
@@ -180,24 +239,26 @@ onShareAppMessage(() => {
}; };
}); });
onShareTimeline(() => { onShareTimeline(async () => {
const shareToken = await getShareToken("spring_timeline");
return { return {
title: "2026 丙午马年,送你一份新春祝福 🎊", title: "2026 丙午马年,送你一份新春祝福 🎊",
query: `shareToken=${shareToken}`,
imageUrl: imageUrl:
"https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png", "https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png",
}; };
}); });
const createGreeting = () => { const createGreeting = () => {
uni.showToast({ title: '去发布祝福~', icon: 'none' }) uni.showToast({ title: "去发布祝福~", icon: "none" });
} };
onPullDownRefresh(() => { onPullDownRefresh(() => {
setTimeout(() => { setTimeout(() => {
uni.stopPullDownRefresh() uni.stopPullDownRefresh();
uni.showToast({ title: '已为你更新内容', icon: 'success' }) uni.showToast({ title: "已为你更新内容", icon: "success" });
}, 600) }, 600);
}) });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@@ -220,11 +281,13 @@ onPullDownRefresh(() => {
.hero-badge { .hero-badge {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
background: rgba(255,255,255,0.2); background: rgba(255, 255, 255, 0.2);
border-radius: 999rpx; border-radius: 999rpx;
padding: 8rpx 16rpx; padding: 8rpx 16rpx;
font-size: 22rpx; font-size: 22rpx;
.badge-dot { margin-right: 8rpx; } .badge-dot {
margin-right: 8rpx;
}
} }
.hero-title { .hero-title {
margin-top: 24rpx; margin-top: 24rpx;
@@ -270,7 +333,7 @@ onPullDownRefresh(() => {
padding: 20rpx; padding: 20rpx;
border-radius: 18rpx; border-radius: 18rpx;
background: #f9f5f0; background: #f9f5f0;
box-shadow: 0 6rpx 16rpx rgba(0,0,0,0.04); box-shadow: 0 6rpx 16rpx rgba(0, 0, 0, 0.04);
} }
.feature-icon { .feature-icon {
width: 80rpx; width: 80rpx;
@@ -283,10 +346,14 @@ onPullDownRefresh(() => {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
.feature-title { .feature-title {
font-size: 28rpx; color: #222; font-weight: 600; font-size: 28rpx;
color: #222;
font-weight: 600;
} }
.feature-sub { .feature-sub {
font-size: 22rpx; color: #888; margin-top: 8rpx; font-size: 22rpx;
color: #888;
margin-top: 8rpx;
} }
} }
} }
@@ -300,10 +367,22 @@ onPullDownRefresh(() => {
align-items: center; align-items: center;
padding: 0 24rpx; padding: 0 24rpx;
.section-bar { .section-bar {
width: 10rpx; height: 30rpx; border-radius: 6rpx; background: #ff3b30; margin-right: 12rpx; width: 10rpx;
height: 30rpx;
border-radius: 6rpx;
background: #ff3b30;
margin-right: 12rpx;
}
.section-title {
font-size: 28rpx;
color: #222;
flex: 1;
font-weight: 600;
}
.section-more {
font-size: 24rpx;
color: #999;
} }
.section-title { font-size: 28rpx; color: #222; flex: 1; font-weight: 600; }
.section-more { font-size: 24rpx; color: #999; }
} }
} }
@@ -312,38 +391,84 @@ onPullDownRefresh(() => {
margin-top: 16rpx; margin-top: 16rpx;
padding-left: 24rpx; padding-left: 24rpx;
} }
.cards-wrap { display: flex; } .cards-wrap {
display: flex;
}
.use-card { .use-card {
width: 260rpx; width: 260rpx;
flex-shrink: 0; flex-shrink: 0;
margin-right: 18rpx; margin-right: 18rpx;
border-radius: 18rpx; border-radius: 18rpx;
background: #fff; background: #fff;
box-shadow: 0 8rpx 20rpx rgba(0,0,0,0.06); box-shadow: 0 8rpx 20rpx rgba(0, 0, 0, 0.06);
overflow: hidden; overflow: hidden;
.use-cover { width: 100%; height: 200rpx; } .use-cover {
.use-info { padding: 16rpx; } width: 100%;
.use-title { font-size: 26rpx; color: #333; font-weight: 600; } height: 200rpx;
.use-sub { font-size: 22rpx; color: #999; margin-top: 6rpx; } }
.use-info {
padding: 16rpx;
}
.use-title {
font-size: 26rpx;
color: #333;
font-weight: 600;
}
.use-sub {
font-size: 22rpx;
color: #999;
margin-top: 6rpx;
}
} }
/* 已移除:.cards-scroll、feed-list、feed-item、feed-header、feed-avatar、feed-user、feed-name、feed-time、feed-content、feed-text、feed-image、feed-actions、.see-more */ /* 已移除:.cards-scroll、feed-list、feed-item、feed-header、feed-avatar、feed-user、feed-name、feed-time、feed-content、feed-text、feed-image、feed-actions、.see-more */
.feed-list { padding: 0 24rpx; } .feed-list {
padding: 0 24rpx;
}
.feed-item { .feed-item {
padding: 22rpx 0; padding: 22rpx 0;
border-bottom: 1rpx solid #f0f0f0; border-bottom: 1rpx solid #f0f0f0;
} }
.feed-header { display: flex; align-items: center; } .feed-header {
.feed-avatar { display: flex;
width: 64rpx; height: 64rpx; border-radius: 50%; margin-right: 16rpx; align-items: center;
}
.feed-avatar {
width: 64rpx;
height: 64rpx;
border-radius: 50%;
margin-right: 16rpx;
}
.feed-user {
display: flex;
flex-direction: column;
}
.feed-name {
font-size: 26rpx;
color: #333;
font-weight: 600;
}
.feed-time {
font-size: 22rpx;
color: #999;
margin-top: 6rpx;
}
.feed-content {
margin-top: 12rpx;
}
.feed-text {
font-size: 26rpx;
color: #333;
line-height: 1.6;
}
.feed-image {
width: 100%;
height: 280rpx;
border-radius: 12rpx;
margin-top: 12rpx;
background: #f6f6f6;
} }
.feed-user { display: flex; flex-direction: column; }
.feed-name { font-size: 26rpx; color: #333; font-weight: 600; }
.feed-time { font-size: 22rpx; color: #999; margin-top: 6rpx; }
.feed-content { margin-top: 12rpx; }
.feed-text { font-size: 26rpx; color: #333; line-height: 1.6; }
.feed-image { width: 100%; height: 280rpx; border-radius: 12rpx; margin-top: 12rpx; background: #f6f6f6; }
.feed-actions { .feed-actions {
margin-top: 12rpx; margin-top: 12rpx;
display: flex; display: flex;
@@ -352,26 +477,38 @@ onPullDownRefresh(() => {
align-items: center; align-items: center;
margin-right: 24rpx; margin-right: 24rpx;
color: #666; color: #666;
.icon { margin-right: 8rpx; } .icon {
margin-right: 8rpx;
}
} }
} }
.see-more { .see-more {
margin: 24rpx; padding: 18rpx 0; text-align: center; margin: 24rpx;
color: #999; font-size: 24rpx; padding: 18rpx 0;
text-align: center;
color: #999;
font-size: 24rpx;
} }
/* 发布悬浮按钮 */ /* 发布悬浮按钮 */
.fab { .fab {
position: fixed; position: fixed;
left: 50%; transform: translateX(-50%); left: 50%;
transform: translateX(-50%);
bottom: 60rpx; bottom: 60rpx;
width: 100rpx; height: 100rpx; width: 100rpx;
height: 100rpx;
border-radius: 50%; border-radius: 50%;
background: #ff3b30; background: #ff3b30;
color: #fff; color: #fff;
display: flex; align-items: center; justify-content: center; display: flex;
box-shadow: 0 12rpx 24rpx rgba(255,59,48,0.4); align-items: center;
.fab-plus { font-size: 48rpx; line-height: 1; } justify-content: center;
box-shadow: 0 12rpx 24rpx rgba(255, 59, 48, 0.4);
.fab-plus {
font-size: 48rpx;
line-height: 1;
}
} }
</style> </style>

View File

@@ -67,7 +67,7 @@
@tap="onRecommendClick(item)" @tap="onRecommendClick(item)"
> >
<image <image
:src="item.imageUrl" :src="getThumbUrl(item.imageUrl)"
mode="aspectFill" mode="aspectFill"
class="scroll-img" class="scroll-img"
/> />
@@ -129,7 +129,7 @@ import { onLoad, onShareAppMessage, onShareTimeline } from "@dcloudio/uni-app";
import { getBavBarHeight } from "@/utils/system"; import { getBavBarHeight } from "@/utils/system";
import { getPageDetail } from "@/api/system"; import { getPageDetail } from "@/api/system";
import { getWallpaperRecommendList } from "@/api/wallpaper"; import { getWallpaperRecommendList } from "@/api/wallpaper";
import { saveViewRequest } from "@/utils/common.js"; import { getShareToken, saveViewRequest } from "@/utils/common.js";
const navHeight = getBavBarHeight(); const navHeight = getBavBarHeight();
const statusBarHeight = uni.getSystemInfoSync().statusBarHeight; const statusBarHeight = uni.getSystemInfoSync().statusBarHeight;
@@ -148,30 +148,36 @@ onLoad(async (options) => {
fetchRecommend(); fetchRecommend();
}); });
onShareAppMessage(() => { onShareAppMessage(async () => {
const token = await getShareToken("wallpaper_detail", detailData.value?.id);
return { return {
title: "快来看看我刚领到的新年精美壁纸 🖼", title: "快来看看我刚领到的新年精美壁纸 🖼",
path: `/pages/wallpaper/detail?shareToken=${shareToken.value}`, path: `/pages/wallpaper/detail?shareToken=${token || ""}`,
imageUrl: imageUrl:
detailData.value?.imageUrl || detailData.value?.imageUrl ||
"https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png", "https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png",
}; };
}); });
onShareTimeline(() => { onShareTimeline(async () => {
const token = await getShareToken("wallpaper_timeline", detailData.value?.id);
return { return {
title: "快来看看我刚领到的新年精美壁纸 🖼", title: "快来看看我刚领到的新年精美壁纸 🖼",
query: `shareToken=${shareToken.value}`, query: `shareToken=${token}`,
imageUrl: imageUrl:
detailData.value?.imageUrl || detailData.value?.imageUrl ||
"https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png", "https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png",
}; };
}); });
const getThumbUrl = (url) => {
return `${url}?imageView2/1/w/340/h/600/q/80`;
};
const fetchDetail = async () => { const fetchDetail = async () => {
try { try {
const res = await getPageDetail(shareToken.value); const res = await getPageDetail(shareToken.value);
saveViewRequest(shareToken.value, "wallpaper_download", res.id); saveViewRequest(shareToken.value, "wallpaper_detail", res.id);
if (res) { if (res) {
detailData.value = res; detailData.value = res;
} }

View File

@@ -74,21 +74,26 @@
</view> </view>
</scroll-view> </scroll-view>
<LoginPopup ref="loginPopupRef" @logind="handleLogind" /> <LoginPopup
ref="loginPopupRef"
@logind="handleLogind"
:share-token="shareToken"
/>
</view> </view>
</template> </template>
<script setup> <script setup>
import { ref, onMounted, computed } from "vue"; import { ref, computed } from "vue";
import { getWallpaperList, getWallpaperCategoryList } from "@/api/wallpaper.js"; import { getWallpaperList, getWallpaperCategoryList } from "@/api/wallpaper.js";
import { import {
saveRemoteImageToLocal, saveRemoteImageToLocal,
saveRecordRequest, saveRecordRequest,
getShareToken, getShareToken,
} from "@/utils/common.js"; } from "@/utils/common.js";
import { onShareAppMessage, onShareTimeline } from "@dcloudio/uni-app"; import { onShareAppMessage, onShareTimeline, onLoad } from "@dcloudio/uni-app";
import { getShareReward, abilityCheck } from "@/api/system.js"; import { getShareReward, abilityCheck } from "@/api/system.js";
import { useUserStore } from "@/stores/user"; import { useUserStore } from "@/stores/user";
import { saveViewRequest } from "@/utils/common.js";
import NavBar from "@/components/NavBar/NavBar.vue"; import NavBar from "@/components/NavBar/NavBar.vue";
const userStore = useUserStore(); const userStore = useUserStore();
@@ -102,9 +107,10 @@ const page = ref(1);
const loading = ref(false); const loading = ref(false);
const hasMore = ref(true); const hasMore = ref(true);
const isRefreshing = ref(false); const isRefreshing = ref(false);
const shareToken = ref("");
onShareAppMessage(async (options) => { onShareAppMessage(async (options) => {
if(!isLoggedIn.value) { if (!isLoggedIn.value) {
const shareToken = await getShareToken("wallpaper_download_index", ""); const shareToken = await getShareToken("wallpaper_download_index", "");
return { return {
title: "新春祝福", title: "新春祝福",
@@ -134,16 +140,22 @@ onShareAppMessage(async (options) => {
} }
}); });
onShareTimeline(() => { onShareTimeline(async () => {
const shareToken = await getShareToken("wallpaper_timeline");
return { return {
title: "精选新年壁纸,让手机也过年 🖼", title: "精选新年壁纸,让手机也过年 🖼",
query: `shareToken=${shareToken}`,
imageUrl: imageUrl:
"https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png", "https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png",
}; };
}); });
onMounted(async () => { onLoad((options) => {
await fetchCategories(); fetchCategories();
if (options.shareToken) {
shareToken.value = options.shareToken;
saveViewRequest(options.shareToken, "wallpaper_download");
}
}); });
const getThumbUrl = (url) => { const getThumbUrl = (url) => {

View File

@@ -1,30 +1,53 @@
export const wxLogin = () => { export const wxLogin = () => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
wx.login({ wx.login({
success: res => { success: (res) => {
if (res.code) { if (res.code) {
resolve(res.code) resolve(res.code);
} else { } else {
reject('登录失败code为空') reject("登录失败code为空");
} }
}, },
fail: err => { fail: (err) => {
reject(err) reject(err);
} },
}) });
}) });
} };
export const alipayLogin = () => {
return new Promise((resolve, reject) => {
// #ifdef MP-ALIPAY
my.getAuthCode({
scopes: "auth_user",
success: (res) => {
if (res.authCode) {
resolve(res.authCode);
} else {
reject("登录失败authCode为空");
}
},
fail: (err) => {
reject(err);
},
});
// #endif
// #ifndef MP-ALIPAY
reject("当前非支付宝环境");
// #endif
});
};
export const wxGetUserProfile = () => { export const wxGetUserProfile = () => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
wx.getUserProfile({ wx.getUserProfile({
desc: '用于完善用户信息', desc: "用于完善用户信息",
success: res => { success: (res) => {
resolve(res) resolve(res);
}, },
fail: err => { fail: (err) => {
reject(err) reject(err);
} },
}) });
}) });
} };

View File

@@ -1,8 +1,10 @@
const BASE_URL = "https://api.ai-meng.com"; // const BASE_URL = "https://api.ai-meng.com";
// const BASE_URL = 'http://127.0.0.1:3999' // const BASE_URL = 'http://127.0.0.1:3999'
// const BASE_URL = "http://192.168.1.3:3999"; const BASE_URL = "http://192.168.1.3:3999";
// const BASE_URL = "http://192.168.31.253:3999"; // const BASE_URL = "http://192.168.31.253:3999";
import { useUserStore } from "@/stores/user"; import { useUserStore } from "@/stores/user";
import { getPlatform } from "./system.js";
const platform = getPlatform();
// 环境区分 // 环境区分
// const BASE_URL = // const BASE_URL =
@@ -33,6 +35,7 @@ function hideLoading() {
function getHeaders() { function getHeaders() {
const headers = { const headers = {
"x-app-id": "69665538a49b8ae3be50fe5d", "x-app-id": "69665538a49b8ae3be50fe5d",
"x-platform": platform,
}; };
const userStore = useUserStore(); const userStore = useUserStore();
if (userStore.token) { if (userStore.token) {

View File

@@ -2,12 +2,21 @@ const SYSTEM = uni.getSystemInfoSync();
export const getStatusBarHeight = () => SYSTEM.statusBarHeight || 15; export const getStatusBarHeight = () => SYSTEM.statusBarHeight || 15;
export const getTitleBarHeight = () => { export const getTitleBarHeight = () => {
// #ifdef MP-ALIPAY
return 44;
// #endif
if (uni.getMenuButtonBoundingClientRect) { if (uni.getMenuButtonBoundingClientRect) {
const { top, height } = uni.getMenuButtonBoundingClientRect(); try {
return height + (top - getStatusBarHeight()) * 2; const rect = uni.getMenuButtonBoundingClientRect();
} else { if (rect && rect.top && rect.height) {
return 40; return rect.height + (rect.top - getStatusBarHeight()) * 2;
}
} catch (e) {
console.error(e);
}
} }
return 44;
}; };
export const getBavBarHeight = () => getStatusBarHeight() + getTitleBarHeight(); export const getBavBarHeight = () => getStatusBarHeight() + getTitleBarHeight();
@@ -46,6 +55,10 @@ export function getPlatformProvider() {
// return typeof tt !== 'undefined' ? 'toutiao' : 'weixin'; // return typeof tt !== 'undefined' ? 'toutiao' : 'weixin';
} }
export function getPlatform() {
return getPlatformProvider().replace("mp-", "");
}
export function getDeviceInfo() { export function getDeviceInfo() {
const info = uni.getSystemInfoSync(); const info = uni.getSystemInfoSync();
return { return {
@@ -62,3 +75,14 @@ export function getDeviceInfo() {
appId: "69665538a49b8ae3be50fe5d", appId: "69665538a49b8ae3be50fe5d",
}; };
} }
/**
* 判断是否处于朋友圈单页模式
*/
export function isSinglePageMode() {
// #ifdef MP-WEIXIN
const launchOptions = uni.getLaunchOptionsSync();
return launchOptions.scene === 1154;
// #endif
return false;
}