feat(round-12): 实体卡外贸生产工单/雷达多渠道归因漏斗/AI地道外联草拟/现代图片自适应协商 (87套件1007测试全绿)

这个提交包含在:
wikiboss
2026-09-21 02:06:55 +08:00
父节点 76f0dc17c0
当前提交 3cfbed9e6a
共有 8 个文件被更改,包括 897 次插入 和 0 次删除

查看文件

@@ -0,0 +1,91 @@
import { Provide } from '@midwayjs/core';
import { BaseService } from '@cool-midway/core';
export type SupportedImageFormat = 'avif' | 'webp' | 'png' | 'jpg';
export interface MediaNegotiationContext {
acceptHeader?: string;
networkType?: 'wifi' | '5g' | '4g' | '3g' | '2g' | 'unknown' | string;
targetWidth?: number;
dpr?: number;
}
export interface OptimizedMediaResult {
format: SupportedImageFormat;
width?: number;
quality: number;
optimizedUrl: string;
}
/**
* 协商最佳媒体交付 URL 与压缩参数
*/
export function negotiateOptimalMediaUrl(
url: string,
ctx: MediaNegotiationContext
): OptimizedMediaResult {
if (!url || typeof url !== 'string' || !url.trim()) {
return {
format: 'jpg',
quality: 80,
optimizedUrl: '',
};
}
const accept = (ctx.acceptHeader || '').toLowerCase();
const net = (ctx.networkType || 'wifi').toLowerCase();
const isSlowNetwork = net === '2g' || net === '3g';
// 1. 协商格式: avif > webp > 原图扩展名(png/jpg)
let format: SupportedImageFormat = 'jpg';
if (accept.includes('image/avif')) {
format = 'avif';
} else if (accept.includes('image/webp')) {
format = 'webp';
} else if (url.toLowerCase().endsWith('.png') || accept.includes('image/png')) {
format = 'png';
}
// 2. 协商质量与宽度
let quality = 85;
if (isSlowNetwork) {
quality = 65;
}
let width = ctx.targetWidth;
if (width != null && width > 0) {
const dpr = ctx.dpr && ctx.dpr > 1 ? ctx.dpr : 1;
if (isSlowNetwork) {
// 弱网降规 75%
width = Math.round(width * 0.75);
} else {
width = Math.round(width * dpr);
}
}
// 3. 构造优化 URL 参数
const separator = url.includes('?') ? '&' : '?';
const queryParts: string[] = [`format=${format}`, `q=${quality}`];
if (width != null && width > 0) {
queryParts.push(`w=${width}`);
}
const optimizedUrl = `${url}${separator}${queryParts.join('&')}`;
return {
format,
width,
quality,
optimizedUrl,
};
}
/**
* 微官网现代图片自适应协商服务
*/
@Provide()
export class PortalMediaNegotiatorService extends BaseService {
negotiate(url: string, ctx: MediaNegotiationContext): OptimizedMediaResult {
return negotiateOptimalMediaUrl(url, ctx);
}
}