feat:修改铸造相关报错

This commit is contained in:
zerosaturation 2026-07-04 00:22:05 +08:00
parent ba44041e55
commit d279976822
11 changed files with 1779 additions and 48 deletions

View File

@ -203,6 +203,15 @@
} }
} }
}, },
{
"path": "pages/castlove/create",
"style": {
"navigationStyle": "custom",
"app-plus": {
"bounce": "none"
}
}
},
{ {
"path": "pages/castlove/craft-select", "path": "pages/castlove/craft-select",
"style": { "style": {

View File

@ -112,11 +112,19 @@ isErrorProcessing: false // 防止错误重复触发
}, },
onLoad() { onLoad() {
this.initSession() this.initSession()
this.initWebSocket()
}, },
onReady() { onReady() {
console.log('[AI Chat] onReady called') console.log('[AI Chat] onReady called')
}, },
onShow() {
// WebSocket
this.initWebSocket()
},
onHide() {
//
this.clearStreamTimeout()
this.closeWebSocket()
},
onUnload() { onUnload() {
this.clearStreamTimeout() this.clearStreamTimeout()
this.closeWebSocket() this.closeWebSocket()
@ -196,11 +204,10 @@ isErrorProcessing: false // 防止错误重复触发
}) })
// - // -
socket.off('disconnect', this._disconnectHandler) const prevDisconnect = this._disconnectHandler
this._disconnectHandler = () => { this._disconnectHandler = () => {
console.log('[AI Chat] WebSocket disconnected') console.log('[AI Chat] WebSocket disconnected')
if (this.isTyping) { if (this.isTyping) {
//
if (this.currentAssistantMessage) { if (this.currentAssistantMessage) {
this.messages.push({ this.messages.push({
role: 'assistant', role: 'assistant',
@ -217,6 +224,7 @@ isErrorProcessing: false // 防止错误重复触发
this.scrollToBottom() this.scrollToBottom()
} }
} }
socket.off('disconnect', prevDisconnect)
socket.on('disconnect', this._disconnectHandler) socket.on('disconnect', this._disconnectHandler)
// //

View File

@ -410,7 +410,7 @@ export default {
fail: (err) => { fail: (err) => {
// / pages.json toast,退 // / pages.json toast,退
console.error("[castlove] navigateTo fail", card.route_path, err); console.error("[castlove] navigateTo fail", card.route_path, err);
uni.showToast({ title: "页面不存在", icon: "none" }); uni.showToast({ title: "功能待开发", icon: "none" });
}, },
}); });
}, },

View File

@ -0,0 +1,117 @@
/**
* 铸爱 create 镭射卡上传区样式独立 CSS create.vue import确保各端构建必进包
* 根类 castlove-laser-upload-root 全局唯一避免 scoped / 第二 style 块在部分端未生效
*/
.castlove-laser-upload-root {
position: relative;
width: 100%;
/* 略偏竖版小卡比例,接近设计稿「大卡 + 内虚线」观感 */
height: 520rpx;
box-sizing: border-box;
border-radius: 32rpx;
border: 1rpx solid rgba(255, 255, 255, 0.38);
background: rgba(255, 255, 255, 0.18);
backdrop-filter: blur(22rpx);
-webkit-backdrop-filter: blur(22rpx);
overflow: hidden;
box-shadow:
0 22rpx 56rpx rgba(40, 22, 80, 0.36),
inset 0 0 0 1rpx rgba(255, 255, 255, 0.22);
}
.castlove-laser-upload-root .uploaded-image {
width: 100%;
height: 100%;
border-radius: 24rpx;
box-shadow: inset 0 0 0 1rpx rgba(255, 255, 255, 0.22);
}
.castlove-laser-upload-root .upload-laser-stack {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
box-sizing: border-box;
}
/* 与设计稿一致:卡内淡色「卡面 / 人像」底图(与工艺选择同款素材) */
.castlove-laser-upload-root .upload-laser-photo-bg {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
z-index: 0;
opacity: 0.22;
pointer-events: none;
filter: saturate(1.15) contrast(0.92);
}
.castlove-laser-upload-root .upload-laser-watermark {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
z-index: 1;
opacity: 1;
pointer-events: none;
/* 叠在底图上:压暗边缘 + 轻微幻彩,避免只剩「灰蒙一块」 */
background:
linear-gradient(
118deg,
rgba(255, 170, 220, 0.12) 0%,
transparent 40%,
rgba(170, 210, 255, 0.1) 62%,
transparent 82%,
rgba(255, 210, 190, 0.08) 100%
),
radial-gradient(ellipse 55% 75% at 50% 100%, rgba(35, 22, 70, 0.45), transparent 58%),
radial-gradient(ellipse 40% 48% at 50% 32%, rgba(100, 75, 150, 0.28), transparent 55%),
linear-gradient(185deg, rgba(255, 220, 245, 0.08) 0%, rgba(55, 35, 95, 0.25) 100%);
}
.castlove-laser-upload-root .upload-laser-inset {
position: absolute;
/* 收紧留白:虚线框更贴外框,接近设计稿「整卡即相框」 */
left: 14rpx;
right: 14rpx;
top: 14rpx;
bottom: 14rpx;
z-index: 2;
box-sizing: border-box;
}
.castlove-laser-upload-root .upload-laser-dashed-inner {
width: 100%;
height: 100%;
box-sizing: border-box;
border: 2rpx dashed rgba(255, 255, 255, 0.95);
border-radius: 26rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 20rpx;
padding: 24rpx 16rpx;
background: rgba(255, 255, 255, 0.02);
}
.castlove-laser-upload-root .upload-plus--laser {
font-size: 96rpx;
line-height: 0.88;
color: #ffffff;
font-weight: 100;
text-shadow: 0 2rpx 18rpx rgba(60, 30, 100, 0.35);
}
.castlove-laser-upload-root .upload-text--laser {
font-size: 28rpx;
color: rgba(255, 255, 255, 0.96);
font-weight: 500;
letter-spacing: 1rpx;
text-shadow: 0 2rpx 12rpx rgba(40, 20, 80, 0.4);
}

File diff suppressed because it is too large Load Diff

View File

@ -106,7 +106,8 @@ const handleSelect = (idx) => {
} }
const handleBack = () => { const handleBack = () => {
uni.navigateBack({ delta: 1 }) // uni.navigateBack({ delta: 1 })
uni.redirectTo({ url: `/pages/castlove/create?name=${encodeURIComponent('镭射卡')}` })
} }
// //

View File

@ -821,10 +821,10 @@ const fetchUserInfo = async (forceRefresh = false) => {
} }
} }
uni.showToast({ // uni.showToast({
title: error.message || "获取用户信息失败", // title: error.message || "",
icon: "none", // icon: "none",
}); // });
} finally { } finally {
loading.value = false; loading.value = false;
} }

View File

@ -106,7 +106,8 @@ export function useContributionRealtime(activityId, isPageActive) {
// contribution channel 也能用新 token 重新订阅,而不是复用上一个用户的 WS。 // contribution channel 也能用新 token 重新订阅,而不是复用上一个用户的 WS。
const token = uni.getStorageSync('access_token') const token = uni.getStorageSync('access_token')
if (token) { if (token) {
socket.connect(token).catch(err => console.warn('[useContributionRealtime] connect error:', err)) // 连接统一由页面 onShow 管理
// socket.connect(token).catch(err => console.warn('[useContributionRealtime] connect error:', err))
} }
// 同步分支:如果 WS 已连接(单例复用导致 'connect' 事件不会再次触发)且 pubsub 可用, // 同步分支:如果 WS 已连接(单例复用导致 'connect' 事件不会再次触发)且 pubsub 可用,
// 必须直接调 onWsConnect 停轮询,否则 polling 会一直跑。 // 必须直接调 onWsConnect 停轮询,否则 polling 会一直跑。

View File

@ -92,7 +92,8 @@ export function useMessageRealtime(activityId) {
// 解决"另一个账户没有接收到实时推送"的问题。 // 解决"另一个账户没有接收到实时推送"的问题。
const token = uni.getStorageSync('access_token') const token = uni.getStorageSync('access_token')
if (token) { if (token) {
socket.connect(token).catch(err => console.warn('[useMessageRealtime] connect error:', err)) // 连接统一由页面 onShow 管理
// socket.connect(token).catch(err => console.warn('[useMessageRealtime] connect error:', err))
} }
// 同步分支:如果 WS 已连接(单例复用,另一个 composable 可能先连上了), // 同步分支:如果 WS 已连接(单例复用,另一个 composable 可能先连上了),
// subscribe 会直接发送;否则缓存到 _topics等待 connect 事件触发 resubscribeAll // subscribe 会直接发送;否则缓存到 _topics等待 connect 事件触发 resubscribeAll

View File

@ -208,7 +208,7 @@ import TopRanking from "./components/TopRanking.vue";
import MessageBoard from "./components/MessageBoard.vue"; import MessageBoard from "./components/MessageBoard.vue";
import MessageInput from "./components/MessageInput.vue"; import MessageInput from "./components/MessageInput.vue";
import { getEarningsSummaryApi } from "@/utils/api.js"; import { getEarningsSummaryApi } from "@/utils/api.js";
import { closeActivitySocket } from "@/utils/socket/ActivitySocket.js"; import { getActivitySocket, closeActivitySocket } from "@/utils/socket/ActivitySocket.js";
import { useMessageRealtime } from "./composables/useMessageRealtime.js"; import { useMessageRealtime } from "./composables/useMessageRealtime.js";
import { useContributionRealtime } from "./composables/useContributionRealtime.js"; import { useContributionRealtime } from "./composables/useContributionRealtime.js";
@ -551,7 +551,6 @@ async function preloadCriticalAssets() {
return new Promise((resolve) => { return new Promise((resolve) => {
const startTime = Date.now(); const startTime = Date.now();
let isResolved = false; let isResolved = false;
const img = new Image();
// //
const timeoutId = setTimeout(() => { const timeoutId = setTimeout(() => {
@ -562,7 +561,10 @@ async function preloadCriticalAssets() {
} }
}, 3000); }, 3000);
img.onload = () => { // uni-app 使 uni.getImageInfo new Image() App/iOS/Android
uni.getImageInfo({
src,
success: () => {
if (!isResolved) { if (!isResolved) {
isResolved = true; isResolved = true;
clearTimeout(timeoutId); clearTimeout(timeoutId);
@ -570,9 +572,8 @@ async function preloadCriticalAssets() {
performanceMonitor.recordImageLoad(true, loadTime); performanceMonitor.recordImageLoad(true, loadTime);
resolve(); resolve();
} }
}; },
fail: () => {
img.onerror = () => {
if (!isResolved) { if (!isResolved) {
isResolved = true; isResolved = true;
clearTimeout(timeoutId); clearTimeout(timeoutId);
@ -580,9 +581,8 @@ async function preloadCriticalAssets() {
performanceMonitor.recordImageLoad(false, loadTime); performanceMonitor.recordImageLoad(false, loadTime);
resolve(); // 使 resolve(); // 使
} }
}; },
});
img.src = src;
}); });
}); });
@ -609,19 +609,18 @@ function preloadNonCriticalAssets() {
nonCriticalImages.forEach((src) => { nonCriticalImages.forEach((src) => {
if (src) { if (src) {
const startTime = Date.now(); const startTime = Date.now();
const img = new Image(); // uni-app 使 uni.getImageInfo new Image() App/iOS/Android
uni.getImageInfo({
img.onload = () => { src,
success: () => {
const loadTime = Date.now() - startTime; const loadTime = Date.now() - startTime;
performanceMonitor.recordImageLoad(true, loadTime); performanceMonitor.recordImageLoad(true, loadTime);
}; },
fail: () => {
img.onerror = () => {
const loadTime = Date.now() - startTime; const loadTime = Date.now() - startTime;
performanceMonitor.recordImageLoad(false, loadTime); performanceMonitor.recordImageLoad(false, loadTime);
}; },
});
img.src = src;
} }
}); });
}, 1000); // 1 }, 1000); // 1
@ -652,8 +651,13 @@ onLoad(async (options) => {
onShow(() => { onShow(() => {
isPageActive.value = true; isPageActive.value = true;
// Activity socket
const token = uni.getStorageSync("access_token");
if (token) {
getActivitySocket().connect(token);
}
if (!isLoading.value && !errorMessage.value && progressManager) { if (!isLoading.value && !errorMessage.value && progressManager) {
// 使 resumePolling startPolling
progressManager.resumePolling(); progressManager.resumePolling();
} }
@ -661,6 +665,9 @@ onShow(() => {
}); });
onHide(() => { onHide(() => {
// Activity socket
closeActivitySocket();
isPageActive.value = false; isPageActive.value = false;
// 使 pausePolling // 使 pausePolling

View File

@ -486,6 +486,33 @@ export function loadTextureImage(src, canvasForCreateImage) {
/* fall through */ /* fall through */
} }
} }
// uni-app 环境使用 uni.getImageInfo 代替 new Image(),兼容 App/iOS/Android
if (typeof uni !== 'undefined' && typeof uni.getImageInfo === 'function') {
try {
uni.getImageInfo({
src,
success: (res) => {
const localPath = res.path || src
const offC = typeof uni.createOffscreenCanvas === 'function'
? uni.createOffscreenCanvas({ type: '2d', width: 1, height: 1 })
: null
if (offC && typeof offC.createImage === 'function') {
const img = offC.createImage()
img.onload = () => resolve(img)
img.onerror = () => reject(new Error('createImage load'))
img.src = localPath
} else {
reject(new Error('createOffscreenCanvas failed'))
}
},
fail: (err) => reject(new Error('getImageInfo: ' + JSON.stringify(err)))
})
return
} catch (e) {
reject(e)
return
}
}
if (typeof Image !== 'undefined') { if (typeof Image !== 'undefined') {
try { try {
const img = new Image() const img = new Image()