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",
"style": {

View File

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

View File

@ -410,7 +410,7 @@ export default {
fail: (err) => {
// / pages.json toast,退
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 = () => {
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({
title: error.message || "获取用户信息失败",
icon: "none",
});
// uni.showToast({
// title: error.message || "",
// icon: "none",
// });
} finally {
loading.value = false;
}

View File

@ -106,7 +106,8 @@ export function useContributionRealtime(activityId, isPageActive) {
// contribution channel 也能用新 token 重新订阅,而不是复用上一个用户的 WS。
const token = uni.getStorageSync('access_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 可用,
// 必须直接调 onWsConnect 停轮询,否则 polling 会一直跑。

View File

@ -92,7 +92,8 @@ export function useMessageRealtime(activityId) {
// 解决"另一个账户没有接收到实时推送"的问题。
const token = uni.getStorageSync('access_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 可能先连上了),
// subscribe 会直接发送;否则缓存到 _topics等待 connect 事件触发 resubscribeAll

View File

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

View File

@ -486,6 +486,33 @@ export function loadTextureImage(src, canvasForCreateImage) {
/* 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') {
try {
const img = new Image()