-
输入 ¥{{ formatTokenPrice(product.input_token_price) }}/千Token
-
输出 ¥{{ formatTokenPrice(product.output_token_price) }}/千Token
+
+
+
+
-
- {{ getProviderInitial(product.provider) }}
- {{ product.provider || '-' }}
-
-
-
+
+
+
@@ -202,6 +230,20 @@ import { reqNavList, reqNewHomeSync, reqNewHomeFestival } from "@/api/newHome";
import { gotoYuanJingAPI } from '@/api/gotoYuanJing'
import TopBox from '@/views/homePage/components/topBox/index.vue'
+const getImageUrlPrefix = () => {
+ const origin = window.location.origin
+ if (origin.includes('localhost') || origin.includes('dev.opencomputing.cn')) {
+ return 'https://dev.opencomputing.cn/idfile?path='
+ }
+ if (origin.includes('www.opencomputing.cn')) {
+ return 'https://www.opencomputing.cn/idfile?path='
+ }
+ if (origin.includes('www.ncmatch.cn')) {
+ return 'https://www.ncmatch.cn/idfile?path='
+ }
+ return `${origin}/idfile?path=`
+}
+
export default {
name: "ProductServicePage",
components: {
@@ -219,7 +261,8 @@ export default {
tokenModelTypeList: [],
tokenProviderList: [],
tokenActiveModelType: '',
- tokenActiveProvider: ''
+ tokenActiveProvider: "",
+ IMG_URL: getImageUrlPrefix(),
};
},
computed: {
@@ -359,6 +402,61 @@ export default {
return provider ? provider.slice(0, 1) : 'M';
},
+ getModelLogoUrl(modelLogo) {
+ if (!modelLogo) return '';
+ if (/^https?:\/\//.test(modelLogo) || modelLogo.startsWith('data:') || modelLogo.startsWith('blob:')) {
+ return modelLogo;
+ }
+ return `${this.IMG_URL}${modelLogo}`;
+ },
+
+ normalizeTokenConfigList(value) {
+ if (!value) return [];
+ let parsedValue = value;
+ if (typeof value === 'string') {
+ try {
+ parsedValue = JSON.parse(value);
+ } catch (error) {
+ return [];
+ }
+ }
+ if (Array.isArray(parsedValue)) {
+ return parsedValue.map(item => ({
+ name: item.name || item.label || item.key || '',
+ value: item.value || item.text || item.content || ''
+ })).filter(item => item.name || item.value);
+ }
+ if (parsedValue && typeof parsedValue === 'object') {
+ return Object.keys(parsedValue).map(key => ({ name: key, value: parsedValue[key] }));
+ }
+ return [];
+ },
+
+ getTokenFeatureTags(model) {
+ const capabilities = this.normalizeTokenConfigList(model.capabilities);
+ const highlights = this.normalizeTokenConfigList(model.highlights);
+ const inputType = capabilities.find(item => item.name === '输入类型');
+ const outputType = capabilities.find(item => item.name === '输出类型');
+ const highlight = highlights[0];
+ return [
+ {
+ text: inputType && inputType.value ? inputType.value : (model.model_type || '模型能力'),
+ icon: 'el-icon-view',
+ type: 'green'
+ },
+ {
+ text: outputType && outputType.value ? outputType.value : (highlight && (highlight.value || highlight.name)) || '智能生成',
+ icon: 'el-icon-magic-stick',
+ type: 'purple'
+ },
+ {
+ text: model.billing_method || '按量计费',
+ icon: 'el-icon-coin',
+ type: 'blue'
+ }
+ ].filter(item => item.text);
+ },
+
// experience 为 1 才允许模型体验,0 时按钮置灰禁用。
isModelExperienceEnabled(model) {
return Number(model && model.experience) === 1;
@@ -1293,42 +1391,86 @@ export default {
}
.token-market-grid {
- display: flex;
- flex-wrap: wrap;
- gap: 14px;
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
+ gap: 12px;
+ align-items: stretch;
}
.token-market-card {
- flex: 0 0 calc((100% - 28px) / 3);
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
min-width: 0;
- padding: 14px;
+ min-height: 224px;
+ padding: 12px;
background: #ffffff;
- border: 1px solid #edf1f7;
- border-radius: 12px;
- box-shadow: 0 10px 24px rgba(31, 45, 61, 0.05);
+ border: 1px solid #dfe7f3;
+ border-radius: 10px;
+ box-shadow: 0 8px 20px rgba(31, 45, 61, 0.08);
cursor: pointer;
transition: all 0.2s ease;
&:hover {
- border-color: #d7e4f5;
+ border-color: #8bbcff;
transform: translateY(-2px);
- box-shadow: 0 16px 32px rgba(31, 45, 61, 0.08);
+ box-shadow: 0 0 0 3px rgba(30, 111, 255, 0.1), 0 18px 38px rgba(30, 111, 255, 0.18);
+
+ &:before {
+ opacity: 1;
+ }
+
+ .token-hover-actions {
+ opacity: 1;
+ transform: translateY(0);
+ }
+ }
+
+ &:before {
+ position: absolute;
+ inset: 0;
+ content: '';
+ pointer-events: none;
+ opacity: 0;
+ background: radial-gradient(420px circle at 45% 0%, rgba(51, 133, 255, 0.16), transparent 42%);
+ transition: opacity 0.35s ease;
}
}
.token-card-top {
+ position: relative;
+ z-index: 1;
display: flex;
align-items: center;
- gap: 6px;
- margin-bottom: 8px;
+ gap: 10px;
+ min-height: 38px;
+ margin-bottom: 10px;
+
+ .token-title-group {
+ flex: 1;
+ min-width: 0;
+ }
h3 {
- flex: 1;
margin: 0;
- color: #1f2d3d;
- font-size: 14px;
+ color: #111827;
+ font-size: 15px;
font-weight: 700;
- line-height: 1.35;
+ line-height: 1.25;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
+ p {
+ margin: 3px 0 0;
+ color: #6b7890;
+ font-size: 12px;
+ line-height: 1.2;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
}
}
@@ -1346,70 +1488,164 @@ export default {
transform: rotate(90deg);
}
- .token-tags {
- display: flex;
- flex-wrap: wrap;
- gap: 6px;
- padding-bottom: 10px;
+ .token-price-grid {
+ position: relative;
+ z-index: 1;
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 8px 12px;
margin-bottom: 10px;
- border-bottom: 1px dashed #d8e0ee;
+ }
+
+ .token-price-item {
+ span,
+ em {
+ display: block;
+ color: #6b7890;
+ font-style: normal;
+ }
span {
- padding: 2px 6px;
- color: #667085;
+ margin-bottom: 2px;
font-size: 11px;
- background: #f8fafc;
- border: 1px solid #edf1f7;
- border-radius: 6px;
+ }
+
+ strong {
+ display: block;
+ color: #111827;
+ font-size: 15px;
+ font-weight: 800;
+ line-height: 1.1;
+ }
+
+ em {
+ margin-top: 0;
+ font-size: 10px;
}
}
- .token-price-line {
- display: flex;
- flex-wrap: wrap;
- gap: 10px;
- margin-bottom: 8px;
- color: #1f2937;
- font-size: 12px;
- font-weight: 600;
+ .token-description {
+ position: relative;
+ z-index: 1;
+ min-height: 58px;
+ margin-bottom: 12px;
+ color: #728096;
+ font-size: 13px;
+ line-height: 1.5;
+ display: -webkit-box;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ line-clamp: 3;
+ -webkit-line-clamp: 3;
+ -webkit-box-orient: vertical;
}
- .token-meta {
+ .token-card-footer {
+ position: relative;
+ z-index: 1;
display: flex;
align-items: center;
- gap: 6px;
- margin-bottom: 10px;
- color: #667085;
- font-size: 12px;
+ justify-content: space-between;
+ gap: 8px;
+ min-width: 0;
+ margin-top: auto;
+ padding-top: 0;
+ }
+
+ .token-feature-tags {
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+ flex: 1;
+ min-width: 0;
+ gap: 5px;
}
.token-provider-avatar {
display: inline-flex;
align-items: center;
justify-content: center;
- width: 16px;
- height: 16px;
+ flex: 0 0 36px;
+ width: 34px;
+ height: 34px;
color: #ffffff;
- font-size: 10px;
- background: #1e6fff;
- border-radius: 4px;
+ font-size: 16px;
+ font-weight: 700;
+ // background: #7c3aed;
+ // border-radius: 8px;
+ overflow: hidden;
+ // box-shadow: 0 6px 16px rgba(124, 58, 237, 0.18);
+
+ img {
+ display: block;
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ }
}
- .token-actions {
+ .token-feature-tags span {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ max-width: 104px;
+ height: 20px;
+ padding: 0 7px;
+ font-size: 11px;
+ border-radius: 999px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+
+ &.green {
+ color: #047857;
+ background: #dcfce7;
+ border: 1px solid #86efac;
+ }
+
+ &.purple {
+ color: #4338ca;
+ background: #eef2ff;
+ border: 1px solid #c7d2fe;
+ }
+
+ &.blue {
+ color: #1d4ed8;
+ background: #eff6ff;
+ border: 1px solid #bfdbfe;
+ }
+ }
+
+ .token-hover-actions {
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 2;
display: flex;
gap: 6px;
+ padding: 6px;
+ opacity: 0;
+ background: rgba(255, 255, 255, 0.94);
+ border-top: 1px solid #edf1f7;
+ backdrop-filter: blur(10px);
+ transform: translateY(100%);
+ transition: all 0.25s ease;
button {
display: inline-flex;
align-items: center;
+ justify-content: center;
+ flex: 1;
gap: 4px;
height: 28px;
- padding: 0 10px;
+ padding: 0 8px;
color: #475467;
font-size: 12px;
+ font-weight: 600;
background: #ffffff;
border: 1px solid #d8e0ee;
- border-radius: 7px;
+ border-radius: 8px;
cursor: pointer;
transition: all 0.2s ease;
@@ -1417,30 +1653,32 @@ export default {
color: #1e6fff;
border-color: #9ec5ff;
background: #f4f8ff;
+ box-shadow: 0 0 0 3px rgba(30, 111, 255, 0.08);
}
}
- .experience {
- color: #4f46e5;
- border-color: #c7d2fe;
+ .primary-action {
+ color: #ffffff;
+ background: #1e6fff;
+ border-color: #1e6fff;
&:hover {
- color: #4338ca;
- border-color: #a5b4fc;
- background: #eef2ff;
+ color: #ffffff;
+ background: #155eef;
+ border-color: #155eef;
}
&.disabled,
&:disabled {
- color: #98a2b3;
+ color: #ffffff;
cursor: not-allowed;
- background: #f3f4f6;
- border-color: #e5e7eb;
+ background: #cbd5e1;
+ border-color: #cbd5e1;
&:hover {
- color: #98a2b3;
- background: #f3f4f6;
- border-color: #e5e7eb;
+ color: #ffffff;
+ background: #cbd5e1;
+ border-color: #cbd5e1;
}
}
}
@@ -1618,14 +1856,14 @@ export default {
}
}
- .product-content .main-content .token-market-card {
- flex-basis: calc((100% - 14px) / 2);
+ .product-content .main-content .token-market-grid {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
@media (max-width: 768px) {
- .product-content .main-content .token-market-card {
- flex-basis: 100%;
+ .product-content .main-content .token-market-grid {
+ grid-template-columns: 1fr;
}
}
}
diff --git a/f/web-kboss/src/views/tokenUsage/index.vue b/f/web-kboss/src/views/tokenUsage/index.vue
index e4dcfe9..4ca7265 100644
--- a/f/web-kboss/src/views/tokenUsage/index.vue
+++ b/f/web-kboss/src/views/tokenUsage/index.vue
@@ -17,6 +17,7 @@