阅读视图

发现新文章,点击刷新页面。

iQOO 15 Ultra 体验:2026 开年最强电竞手机,没有之一

2 月 4 日,iQOO 发布了 iQOO 15 系列新品,同时也是 iQOO 数字系列第一款带上「超大杯」后缀的手机——iQOO 15 Ultra,定价5699 元,首销价 5499 元,国补到手价 4999 元

新机延续了 15 系列方正干净的风格,手感丝滑的 AF 镀膜工艺磨砂质感后盖搭配大 R 角,中框边缘往内收了 1.2mm 提升衔接效果,裸机手持的感觉很舒服。

iQOO 提供了两款配色,分别是致敬《赛博朋克 2077》,以黑橙色为主的 2077 配色,以及致敬《银翼杀手 2049》,机身以有点偏冷的哑光银作为主调的 2049 配色。

后盖用上了最新的 Texture on Fiber TOF 工艺,可以将纹理、镀膜、打印等工艺集成在 PET 膜片上,实现表面双镀膜的效果,实现动态纹理的视效。

手机背后的六角形纹理会顺着不同的观看角度、不同的观影效果变化,实际上看起来会有种类似能量条充能的效果,十分有趣。

DECO 换成了更加方正的「未来舱」设计,透明面板下能看到三摄被分别固定在各自的方块上,除了实现了官方说的悬浮感,模块分明的设计加上背后条形纹理细节,提升了 DECO 的机械感。

潜望式长焦模块侧边上方的位置有一条 Monster Halo 呼吸灯,它能够根据内置风扇的设置呈现不同的光效,对应《金铲铲之战》和《王者荣耀》的专属光效。

来到机身侧边,iQOO 15 Ultra 再次加入了肩键设计。

这款超感游戏肩键采用了双独立触控控制芯片降低延迟,最高支持 600Hz 触控采样率,还有防手汗的算法来提升精度,对《和平精英》、《三角洲行动》这一类射击游戏,扳机可以移交到肩键上,移动和视角控制交给拇指触控,操作起来会更舒服。

加上,iQOO 15 Ultra 的肩键位置比较靠内,手握持时可以紧贴机身,这样拿着手机更稳定,更有操控横向掌机的感觉。

iQOO 15 Ultra 机身正面搭载了一块 6.85 英寸 3168 x 1440 的 2K 专业电竞屏。

它最高支持 144Hz 的刷新率,手动峰值亮度是1000nits,全局峰值亮度为 2600nits,局部峰值亮度更是提升到 8000nits。自身支持三光敏全域感光,提升屏幕的感光性能。还有 98.1% 首帧亮度占比,降低屏幕拖影。

护眼部分,这块屏幕支持高亮度 DC 调光,低亮度 2160Hz 高频 PWM 调光,有无偏振自然光显示、1nit 最低亮度以及护目护眼 2.0,还有莱茵的游戏、无偏振显示、无频闪认证。

配置部分,iQOO 15 Ultra 搭载了第五代高通骁龙 8 至尊版移动平台,搭配自研电竞芯片 Q3,还有 LPDDR5X Ultra Pro 和 UFS4.1 的组合,最高支持 24GB RAM+1TB ROM,顶配的话就是真正的性能超大杯了。在常规的室内环境下,安兔兔跑分为 4452860。

提升性能的同时,iQOO 这次还重点加强了散热。

iQOO 15 Ultra 内部搭载了冰穹主动散热风扇,风扇尺寸为 17 x 17 x 4mm,有 59 片扇片,单体最大出风量为 0.315CFM,有三档可选,也能够只能调节,对应不同程度的使用场景。机内还内置 8000mm² VC 均热板,进一步提升散热效能。

风扇内部加入了叶片防尘环设计,隐藏在 DECO 下侧的进风口上加入双防尘网设计,可以有效防止尘进入内部。电路板双层有防水处理,不影响机身的防水防尘性能,整机支持 IP68&IP69 的防水防尘。

在高性能配置和加入主动散热结构的作用下,iQOO 15 Ultra 应付《王者荣耀》、《和平精英》、《三角洲行动》以及《暗区突围》等主流的游戏还是很轻松的,《王者荣耀》在 144FPS + 极致画质的状态下支持档位全开,《三角洲行动》支持 144FPS + 极致画质,《暗区突围》支持原生光追加上 144FPS + 极致画质,配置上可以直接带满。

《原神》和《绝区零》可以开启全场景的光追加上 2K 原画超分+ 120 超帧顶格并发,开启 Monster 模式之后操作的确要流畅不少,只要不是刚刚进入的新图新区域,手机的表现还是很稳定的。

而且,在游戏刚刚下载完整数据包的状态下,iQOO 15 Ultra 加载到进入游戏的过程也会比不少同定位的机型快不少,由此可见游戏方面的表现是真的不错。

游戏助手的设置也很丰富,有常规的画质、帧数设置、Q3 电竞芯片的针对性设置,风扇的速度模式也可以在侧拉菜单里快速调节。

操控的部分,iQOO 15 Ultra 内置超感触控芯片,支持 480Hz 多指触控采样和最高瞬时 4000Hz 触控采样率,以及 27.1ms 的最低点击触控延迟、29.5ms 滑动触控跟手延迟。配合内置的超感陀螺仪和触控区域适配优化,用它玩《三角洲行动》确实要更准,日常「吃鸡」压枪更稳。

iQOO 15 Ultra 内置了集成 X 轴、Z 轴的战锤 MAX 双震感马达,《三角洲行动》、《崩坏:星穹铁道》有三档振感强度自定义,《原神》、《王者荣耀》、《QQ 飞车》三款游戏支持双轴振感,按压操作时的反馈会更丰富。

还有,手机支持游戏内智能录制和高光回放功能,《王者荣耀》、《和平精英》、《三角洲行动》、《暗区突围》、《无畏契约》、《穿越火线》、《使命召唤 M》支持 144FPS 直播,也有 2K 60fps 30Mbps 的手机直播模式,方便游戏内容创作者。

续航方面,iQOO 15 Ultra 搭载了一块 7400mAh 电池,日常使用的话大概 2 天左右,游戏比较多的话也能够坚持 1.5 天,算是现在比较常规的续航表现。

手机支持 100W 超快闪充,官方有线快充 0-100 时间是 65 分钟。我们用AI 小电拼进行测试,iQOO 15 Ultra 最高录得充电功率为 49W,0-100 充电耗时 77 分钟。

两者的差距主要体现在充电的后半段,不管是官方还是他家充电器都能够在 30 分钟内充满一半,40 分钟能来到 70% 以上,出门在外基本不需要绑定官方的单口快充头了。

不过,这一代 iQOO 又加入了胶囊造型设计的弯头 USB-C to C 充电线,手持打游戏的时候不用躲充电头。配合机器自身的旁路供电功能,用着还是挺舒服的。

iQOO 15 Ultra 还支持 40W 无线充电,在家配合官方充电器,出门在外配上一些磁吸配件用磁吸充电宝也很方便。

最后看看相机,旗舰定位的 iQOO 15 Ultra 给出了 5000 万三摄的标准组合:

  • 超广角:5000 万像素,1/2.76 英寸底,等效 15mm 视角,F2.05 光圈,支持电子防抖、自动对焦
  • 主摄: 5000 万像素索尼传感器,1/1.56 英寸底,等效 23mm,F1.88 光圈,自研 VCS 人眼放生技术和自研 OIS 超级防抖技术,CIPA 4.5 级,支持 8K 视频录制
  • 潜望式长焦:5000 万像素索尼传感器,1/1.953 英寸底,等效 73mm,3 倍光学变焦和 6 倍无损变焦,最高支持 100 倍数码变焦和 15 倍视频变焦,光圈 F2.65,同样支持自研 OIS 超级防抖技术,CIPA 4.5 级防抖

相机内支持 NICE 3.0 光学重构引擎和 Magic 2.0 画质还原引擎,提升长焦画质。「原生光影」 算法更新,提升了拍摄的自然度,去除 AI 后感。

iQOO 还更新了「撕拉片」风格滤镜和新的 AI 视效「AI 风光大师」,在增加机身拍摄的风格和玩法。

最后看看定价,iQOO 15 Ultra 有四个储存版本,全线 16GB 运存起步:

  • 16GB+256GB 5699 元,首销价 5499 元,国补到手价 4999 元
  • 16GB+512GB 5999 元,国补后到手价 5499 元
  • 16GB+1TB 6999 元
  • 24GB+1TB 7699 元
「买吧,不贵。」

#欢迎关注爱范儿官方微信公众号:爱范儿(微信号:ifanr),更多精彩内容第一时间为您奉上。

爱范儿 | 原文链接 · 查看评论 · 新浪微博


*ST节能:控股子公司重大合同终止且涉及诉讼

36氪获悉,*ST节能公告,股票连续2个交易日内收盘价格跌幅偏离值累计达12.65%,属于股票交易异常波动的情况。公司于2026年1月31日披露了《关于控股子公司重大合同进展公告》。江苏省冶金设计院有限公司收到中清先进电池制造(石河子)有限公司送达的《关于终止中清项目总承包合同的函》。经江苏院审慎决定,计划终止新疆项目后续一切工作。公司于2026年1月31日披露了《关于控股子公司涉及诉讼的公告》,截至本公告披露日,该诉讼法院已受理,尚未开庭审理。

锐新科技:筹划发行股份及支付现金芜湖德恒控制权,明起停牌

36氪获悉,锐新科技公告,公司正在筹划以发行股份及支付现金方式购买芜湖德恒汽车装备有限公司控制权并募集配套资金事项,预计构成重大资产重组。因有关事项尚存不确定性,公司股票自2026年2月5日起开始停牌。公司预计在不超过10个交易日的时间内披露本次交易方案。芜湖德恒汽车装备有限公司主营业务包括汽车零部件及配件制造、模具制造、非标专用设备制造、搬运设备制造、工业机器人制造等。

盛新锂能:子公司拟12.6亿元收购惠绒矿业13.93%股权

36氪获悉,盛新锂能公告,公司全资子公司四川盛屯锂业有限公司拟以现金人民币125,970.00万元收购厦门创益盛屯新能源产业投资合伙企业(有限合伙)持有的雅江县惠绒矿业有限责任公司13.93%股权,本次交易完成后,公司将100%控股惠绒矿业。本次交易对方厦门创益为公司的关联方,本次股权收购事项构成关联交易,尚需获得股东会的批准,不构成重大资产重组。

【AI 编程实战】第 10 篇:让应用更健壮 - 错误处理与边界情况

功能做完了,但用户体验还差一步——当网络出错、接口超时、数据异常时,应用会不会崩溃?用户能不能看到友好的提示?这篇文章以心动恋聊小程序为例,展示如何和 AI 对话,构建健壮、友好、可维护的错误处理体系。

系列专栏【AI 编程实战】专栏目录

本篇主题:让应用更健壮 - 错误处理与边界情况

实战项目:心动恋聊 - AI 恋爱聊天助手

一、开篇:错误处理的重要性

1.1 没有错误处理的代码

// ❌ 危险:没有任何错误处理
const handleGenerate = async () => {
  const response = await chatService.generateReply({ text: inputText.value });
  replies.value = response.data.replies;
};

可能出现的问题

  • 网络断开 → 应用白屏
  • 接口超时 → 无任何反馈
  • 返回数据为空 → Cannot read property 'replies' of undefined
  • 用户点击多次 → 重复请求

1.2 完善的错误处理

// ✅ 健壮:完整的错误处理
const handleGenerate = async () => {
  if (loading.value) return;  // 防重复点击

  loading.value = true;
  try {
    const response = await chatService.generateReply({ text: inputText.value });

    if (response.code !== 200) {
      throw new Error(response.msg || '生成失败');
    }

    replies.value = response.data?.replies ?? [];  // 空值保护
  } catch (error) {
    const errMsg = error?.message || '网络错误,请稍后再试';
    toast.error(errMsg);
    console.error('生成回复失败:', error);
  } finally {
    loading.value = false;
  }
};

1.3 本文要解决的问题

问题 解决方案
网络错误 统一错误提示 + 重试机制
接口错误码 分类处理(401/403/500)
空值异常 可选链 + 空值合并
重复点击 loading 状态锁定
用户取消 区分取消和真正的错误

二、统一错误提示:Toast 封装

2.1 我的需求

我:项目里很多地方要显示提示,有成功、失败、警告等类型。
    每次都写 uni.showToast 太繁琐,能不能封装一下?

2.2 AI 设计方案

AI:封装一个 toast 工具,提供链式调用:

📐 接口设计:

toast.success('操作成功')
toast.error('操作失败')
toast.warning('请注意')
toast.info('提示信息')

📐 配置选项:

interface ToastOptions {
  duration?: number;      // 显示时长,默认 2000ms
  position?: 'top' | 'middle' | 'bottom';  // 位置
  mask?: boolean;         // 是否显示遮罩防止穿透
}

2.3 AI 生成代码

// src/utils/toast.ts
type ToastType = 'success' | 'error' | 'warning' | 'info';

interface ToastOptions {
  type?: ToastType;
  duration?: number;
  position?: 'top' | 'middle' | 'bottom';
  message: string;
  mask?: boolean;
}

export function showToast(message: string): void;
export function showToast(options: ToastOptions): void;
export function showToast(options: ToastOptions | string): void {
  const defaultOptions: ToastOptions = {
    type: 'info',
    duration: 2000,
    position: 'middle',
    message: '',
    mask: false,
  };

  const mergedOptions = typeof options === 'string'
    ? { ...defaultOptions, message: options }
    : { ...defaultOptions, ...options };

  // 映射 position 到 UniApp 支持的格式
  const positionMap = {
    top: 'top',
    middle: 'center',
    bottom: 'bottom',
  };

  uni.showToast({
    title: mergedOptions.message,
    duration: mergedOptions.duration,
    position: positionMap[mergedOptions.position ?? 'middle'],
    icon: 'none',
    mask: mergedOptions.mask,
  });
}

// 便捷方法
type SimpleToastOptions = Omit<ToastOptions, 'type' | 'message'>;

export const toast = {
  success: (message: string, options?: SimpleToastOptions) =>
    showToast({ ...options, type: 'success', message }),
  error: (message: string, options?: SimpleToastOptions) =>
    showToast({ ...options, type: 'error', message }),
  warning: (message: string, options?: SimpleToastOptions) =>
    showToast({ ...options, type: 'warning', message }),
  info: (message: string, options?: SimpleToastOptions) =>
    showToast({ ...options, type: 'info', message }),
};

2.4 使用示例

import { toast } from '@/utils/toast';

// 简单用法
toast.success('保存成功');
toast.error('网络错误,请稍后再试');

// 带配置
toast.info('正在处理...', { duration: 3000, mask: true });

三、接口错误分类处理

3.1 我的需求

我:后端返回不同的错误码:
    - 401:未登录或 token 过期
    - 403:没有权限(如 VIP 功能)
    - 500:服务器错误

    不同错误码要有不同的处理逻辑。

3.2 AI 设计错误分类

AI:在 HTTP 层统一处理常见错误码,业务层处理特殊错误:

📐 错误分类:

【HTTP 层处理】(在 http.ts 中)
- 401 → 清除登录态,跳转登录
- 网络错误 → 显示"网络错误"提示

【业务层处理】(在页面中)
- 403 → 引导开通 VIP
- 业务错误 → 显示具体错误信息

3.3 HTTP 层错误处理

// src/http/http.ts
export function http<T>(options: CustomRequestOptions) {
  return new Promise<IResData<T>>((resolve, reject) => {
    uni.request({
      ...options,
      success(res) {
        // 2xx 状态码视为成功
        if (res.statusCode >= 200 && res.statusCode < 300) {
          resolve(res.data as IResData<T>);
        }
        // 401 未授权
        else if (res.statusCode === 401) {
          // 清除登录态
          uni.removeStorageSync('token');
          // 可以触发全局事件或跳转登录
          reject(res);
        }
        // 其他错误
        else {
          if (!options.hideErrorToast) {
            const data = res.data as IResData<T>;
            uni.showToast({
              icon: 'none',
              title: data.msg || '请求错误',
            });
          }
          reject(res);
        }
      },
      // 网络错误
      fail(err) {
        uni.showToast({
          icon: 'none',
          title: '网络错误,换个网络试试',
        });
        reject(err);
      },
    });
  });
}

3.4 业务层错误处理

// 页面中处理 403 等业务错误
const handleGenerate = async () => {
  loading.value = true;

  try {
    const response = await chatService.generateReply(params);

    if (response.code !== 200) {
      throw new Error(response.msg || '生成失败');
    }

    replies.value = response.data?.replies ?? [];
  } catch (error: any) {
    console.error('生成回复失败:', error);

    // 提取错误信息
    const errMsg = error?.data?.message
      || error?.msg
      || error?.message
      || '生成失败,请稍后再试';

    // 根据状态码分类处理
    const statusCode = error?.statusCode || error?.data?.code || error?.code;

    if (statusCode === 403) {
      // 权限不足,引导开通 VIP
      const message = errMsg || '免费次数已用完,请开通VIP';
      promptOpenVip(message);
    } else {
      // 其他错误,显示提示
      toast.error(errMsg);
    }
  } finally {
    loading.value = false;
  }
};

四、空值保护:防御性编程

4.1 常见的空值错误

// ❌ 危险:可能报错
const username = response.data.user.username;
// 如果 response.data 是 undefined,就会报错

const firstReply = replies[0].text;
// 如果 replies 是空数组,就会报错

4.2 AI 教我防御性编程

AI:用可选链(?.)和空值合并(??)来保护:

📐 防御性编程规则:

1. 访问对象属性 → 用 ?.
2. 提供默认值 → 用 ??
3. 数组访问 → 先检查长度或用 ?.[0]

4.3 实践示例

// ✅ 安全:可选链 + 空值合并
const username = response?.data?.user?.username ?? '未知用户';

// ✅ 安全:数组保护
const replies = response.data?.replies ?? [];
const firstReply = replies.length > 0 ? replies[0].text : '';

// ✅ 安全:解构时提供默认值
const { data = {} } = response ?? {};
const { replies = [], analysis = '' } = data;

// ✅ 安全:函数参数默认值
const updateUserInfo = (info: Partial<UserInfo> = {}) => {
  // info 一定是对象,不会是 undefined
};

4.4 实际代码中的应用

// 生成回复的完整错误处理
const handleGenerate = async () => {
  // ... 请求逻辑

  const data = response.data ?? {};

  // 安全提取分析结果
  analysisResult.value = data.analysis || '';

  // 安全提取回复列表,并添加 id
  const repliesFromApi = Array.isArray(data.replies)
    ? data.replies.slice(0, MEMORY_REPLY_COUNT)
    : [];

  replies.value = repliesFromApi.map((r, idx) => ({
    ...r,
    id: r.id ?? idx,  // 如果没有 id,用索引代替
  }));

  // 安全更新配额信息
  userStore.updateFreeQuota({
    free_reply_total: data.freeReplyTotal,
    free_reply_used: data.freeReplyUsed,
    free_reply_remaining: data.remainingTimes,
    vip_status: data.isVip ? 'vip' : 'none',
    vip_expire_time: data.vipExpireTime ?? null,
  });
};

五、用户取消 vs 真正的错误

5.1 问题场景

我:用户选择图片时点了"取消",会触发 fail 回调,
    显示"图片选择失败"的错误提示。
    但这不是真正的错误,不应该提示。

5.2 AI 分析区分方法

AI:通过错误信息来区分用户取消和真正的错误:

📊 错误信息分析:

【用户取消】
- chooseMedia:fail cancel
- chooseImage:fail cancel
- chooseImage:fail(code: 0)

【真正的错误】
- chooseImage:fail no permission
- chooseMedia:fail system error
- 其他错误信息

5.3 实现代码

const addImages = () => {
  const { run } = useUpload('', {}, {
    count: remainingCount,
    selectOnly: true,
    onSelect: (images) => {
      // 正常处理选中的图片
      images.forEach((img) => uploadChosenImage(img));
    },
    onError: (err) => {
      // 判断是否为用户主动取消
      const errMsg = typeof err === 'object' && err !== null && 'errMsg' in err
        ? (err as any).errMsg
        : '';
      const errCode = typeof err === 'object' && err !== null && 'code' in err
        ? (err as any).code
        : -1;

      const isUserCancel =
        errMsg === 'chooseMedia:fail cancel' ||
        errMsg === 'chooseImage:fail cancel' ||
        (errMsg === 'chooseImage:fail' && errCode === 0);

      if (!isUserCancel) {
        // 只有真正的错误才提示
        console.error('图片选择失败:', err);
        toast.error('图片选择失败');
      }
      // 用户取消时静默处理,不显示任何提示
    },
  });

  run();
};

六、Promise 封装:统一回调风格

6.1 我的需求

我:uni.login 等 API 用的是回调风格,写起来很繁琐。
    能不能封装成 Promise 风格?

6.2 AI 封装示例

// src/utils/wechat.ts
/**
 * 获取微信登录凭证
 * 将回调风格封装成 Promise
 */
export const requestWechatLoginCode = () =>
  new Promise<string>((resolve, reject) => {
    uni.login({
      provider: 'weixin',
      onlyAuthorize: true,
      success: (res) => {
        if (res?.code) {
          resolve(res.code);
        } else {
          reject(new Error('未获取到有效的登录凭证'));
        }
      },
      fail: (err) => {
        reject(err);
      },
    });
  });

// 使用时
try {
  const code = await requestWechatLoginCode();
  await userStore.wechatLogin(code);
} catch (error) {
  toast.error('登录失败');
}

6.3 剪贴板封装

// src/utils/clipboard.ts
import { isApp } from '@/utils/platform';

declare const plus: any;

/**
 * 跨平台复制文本到剪贴板
 */
export function copyText(text: string): Promise<void> {
  // App 端使用 plus API
  if (isApp && typeof plus !== 'undefined' && plus?.navigator) {
    return new Promise((resolve, reject) => {
      try {
        plus.navigator.setClipboard(text);
        resolve();
      } catch (error) {
        reject(error);
      }
    });
  }

  // 小程序/H5 使用 uni API
  return new Promise((resolve, reject) => {
    uni.setClipboardData({
      data: text,
      success: () => resolve(),
      fail: (err) => reject(err),
    });
  });
}

// 使用时
const handleCopy = async (text: string) => {
  try {
    await copyText(text);
    toast.success('已复制');
  } catch (error) {
    console.error('复制失败:', error);
    toast.error('复制失败,请稍后再试');
  }
};

七、Loading 状态管理

7.1 防止重复点击

const loading = ref(false);

const handleSubmit = async () => {
  // 防止重复点击
  if (loading.value) return;

  loading.value = true;
  try {
    await doSubmit();
  } finally {
    loading.value = false;
  }
};

7.2 按钮状态联动

<template>
  <XButton
    :text="loading ? '处理中...' : '提交'"
    :loading="loading"
    :disabled="loading || !canSubmit"
    @click="handleSubmit"
  />
</template>

7.3 多个 Loading 状态

// 页面有多个独立的加载状态
const isGenerating = ref(false);      // 生成回复
const isUploadingImages = ref(false); // 上传图片
const isSaving = ref(false);          // 保存数据

// 计算总体加载状态
const isLoading = computed(() =>
  isGenerating.value || isUploadingImages.value || isSaving.value
);

// 细粒度控制按钮状态
<XButton
  :disabled="isGenerating || isUploadingImages"
  @click="handleGenerate"
/>

八、错误处理最佳实践

8.1 错误处理清单

层级 处理内容 示例
HTTP 层 网络错误、401 http.ts 统一处理
业务层 403、业务错误码 页面 catch 块处理
UI 层 用户提示、状态恢复 toast + loading

8.2 代码模板

// 标准的异步操作模板
const handleAsyncAction = async () => {
  // 1. 防重复
  if (loading.value) return;

  // 2. 前置校验
  if (!canSubmit.value) {
    toast.warning('请填写完整信息');
    return;
  }

  loading.value = true;

  try {
    // 3. 执行操作
    const response = await doAction();

    // 4. 校验响应
    if (response.code !== 200) {
      throw new Error(response.msg || '操作失败');
    }

    // 5. 处理成功
    const data = response.data ?? {};
    processData(data);
    toast.success('操作成功');

  } catch (error: any) {
    // 6. 分类处理错误
    console.error('操作失败:', error);

    const statusCode = error?.statusCode || error?.code;
    const errMsg = error?.msg || error?.message || '操作失败';

    if (statusCode === 403) {
      handleNoPermission();
    } else {
      toast.error(errMsg);
    }

  } finally {
    // 7. 恢复状态
    loading.value = false;
  }
};

8.3 总结

技术 用途 示例
try-catch-finally 捕获和恢复 异步操作的标准模式
可选链 ?. 安全访问属性 response?.data?.user
空值合并 ?? 提供默认值 value ?? defaultValue
Promise 封装 统一回调风格 requestWechatLoginCode()
错误分类 差异化处理 401/403/500 不同处理
Loading 状态 防重复 + 用户反馈 if (loading) return

错误处理不是"事后补救",而是设计阶段就要考虑的架构问题

好的错误处理让用户感受到应用的专业和可靠。

如果这篇文章对你有帮助,请点赞、收藏、转发!

MiniCPM-o 4.5开源

36氪获悉,面壁智能开源了新一代全模态旗舰模型MiniCPM-o 4.5。据了解,MiniCPM-o 4.5具有边看、边听、主动说的全模态能力。目前,MiniCPM-o 4.5已在GitHub、Hugging Face等平台开源,结合面壁自研的开源流式全模态模型高效端侧推理框架llama.cpp-omni,让模型部署更加简单、稳定、高效。

docker-compose k8s部署项目使用服务名称,后端服务发布后出现接口502问题

这里使用一个例子docker-compose.yml

// docker-compose.yml
# 确保所有服务在同一网络
version: '3.8'
services:
  app:
    networks:
      - mynetwork
    depends_on:
      - mysql
      - redis
  
  mysql:
    networks:
      - mynetwork
  
  redis:
    networks:
      - mynetwork
  imotor-ltq:
    image: phm-ltq:1.0.0
    container_name: imotor-ltq
    restart: always
    networks:
      - app_net
    deploy:
      resources:
        limits:
          cpus: '3.00'
          memory: 5G
        reservations:
          cpus: '3.00'
          memory: 2G
    ports:
      - "7953:8080"
spectral-ltq-web:
    image: spectral-ltq-web:1.0.0
    container_name: spectral-ltq-web
    restart: always
    networks:
      - app_net
    deploy:
      resources:
        limits:
          cpus: '1.00'
          memory: 1G
        reservations:
          cpus: '1.00'
          memory: 1G
    ports:
      - "7777:8080"
    depends_on:
      imotor-algo:
        condition: service_healthy
networks:
  mynetwork:
    driver: bridge

前端nginx 镜像容器配置:

    location /api/ {                # 使用变量强制每次解析                proxy_pass http://imotor-ltq:7953/;                proxy_set_header Host $proxy_host;                proxy_set_header X-Real-IP $remote_addr;                proxy_set_header remote_addr $remote_addr;                proxy_http_version 1.1;                proxy_connect_timeout 4s;                proxy_read_timeout 600s;                proxy_send_timeout 12s;            }

当后端开发新功能发版后偶现

发现服务不能使用了,每次出现这个问题时 都需要重启前端项目,

后面开始排查:查看docker 网络

docker network ls
docker network inspect <network_name>

多次重启后发现IP地址会发生变化,基本可以确定是使用服务名DNS解析时存在缓存
使用的是之前的服务IP地址,所以找不到

进一步确定问题:使用 docker-compose exec 前端应用 ping imotor-ltq
服务

解决方法:

server { 
         listen       8080;# 访问端口 
         server_name  localhost;
         resolver 127.0.0.11 valid=10s;  # Docker 内置 DNS
         location /api/ {
          set $algo_host imotor-algo;
          rewrite ^/api/(.*)$ /$1 break; //使用rewrite重置为后端需要的地址
          proxy_pass http://$algo_host:8080;
       }
    }

// 添加 resolver 127.0.0.11 valid=10s; # Docker 内置 DNS
使用变量

 set $algo_host imotor-algo;

rewrite ^/api/(.*)/ /1 break;

proxy_pass http://$algo_host:8080;

之前想省略  rewrite ^/api/(.*)/ /1 break;直接在后面加/

set $algo_host imotor-algo;
proxy_pass http://$algo_host:8080/;

发现找不到服务地址,不知道什么原因

大洋电机:拟出资1000万元认购慕智合创基金份额

36氪获悉,大洋电机公告,公司于2026年2月3日与上海慕华金誉股权投资管理合伙企业(有限合伙)及其他有限合伙人签署了《共青城慕智合创创业投资合伙企业(有限合伙)合伙协议》。共青城慕智合创创业投资合伙企业(有限合伙)目标认缴规模为人民币2.9亿元,其中首次关闭规模为人民币7,250万元,公司作为有限合伙人使用自有资金出资1,000万元人民币认购合伙企业的基金份额。公司本次投资不存在对合伙企业实施控制或共同控制的情形,亦不存在对合伙企业产生重大影响的情形。

山金国际:已回购183.49万股,使用资金总额3409.25万元

36氪获悉,山金国际公告,截至2026年1月31日,公司累计通过股票回购专用证券账户以集中竞价交易方式回购股份数量为1,834,929股,占公司总股本的0.07%,其中,最高成交价为19.45元/股,最低成交价17.85元/股,成交总金额为34,092,534.43元(不含交易费用)。本次回购股份的资金来源为公司自有资金及回购专项贷款,回购价格未超过确定的价格上限29.70元/股(含)。公司回购进展情况符合既定的回购方案和相关法律法规的要求。

腾讯混元AI Infra核心技术开源

36氪获悉,腾讯混元AI Infra团队正式推出开源生产级高性能LLM推理核心算子库HPC-Ops。腾讯混元称,在真实场景下,基于HPC-Ops,混元模型推理QPM提升30%,DeepSeek模型QPM提升17%。
❌