Commit 65b6a34b authored by fisherdaddy's avatar fisherdaddy

feature: 把OpenAI时间线和各大模型价格对比放到网站首页

parent c18258c3
...@@ -10,6 +10,8 @@ const TextToImage = lazy(() => import('./components/TextToImage')); ...@@ -10,6 +10,8 @@ const TextToImage = lazy(() => import('./components/TextToImage'));
const UrlDecode = lazy(() => import('./components/UrlDecode')); const UrlDecode = lazy(() => import('./components/UrlDecode'));
const About = lazy(() => import('./pages/About')); const About = lazy(() => import('./pages/About'));
const OpenAITimeline = lazy(() => import('./components/Timeline')); const OpenAITimeline = lazy(() => import('./components/Timeline'));
const PricingCharts = lazy(() => import('./components/PricingCharts'));
function App() { function App() {
return ( return (
...@@ -25,6 +27,7 @@ function App() { ...@@ -25,6 +27,7 @@ function App() {
<Route path="/url-decode" element={<UrlDecode />} /> <Route path="/url-decode" element={<UrlDecode />} />
<Route path="/about" element={<About />} /> <Route path="/about" element={<About />} />
<Route path="/openai-timeline" element={<OpenAITimeline />} /> <Route path="/openai-timeline" element={<OpenAITimeline />} />
<Route path="/llm-model-price" element={<PricingCharts />} />
<Route path="*" element={<NotFound />} /> <Route path="*" element={<NotFound />} />
</Routes> </Routes>
</Suspense> </Suspense>
......
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1513 975" width="1513" height="975">
<title>ae99cd49-2667-464e-b9db-b39cee0126e1-svg</title>
<style>
.s0 { fill: #ff5a00 }
</style>
<g id="#ff5a00ff">
<path id="Layer" class="s0" d="m989.5 0h67.8c95.3 5.4 196.5 23.1 272.4 85.5 60.6 49.1 86.3 133 71.4 208.6-11.4 56.4-37.4 108.4-65.4 158.1-56.8 98.4-126.6 188.2-193 280.1-11.9 15.2-21.2 33.8-20 53.6 1.1 15.7 13.1 28.4 27.2 34 27.3 11.1 57.5 8.9 86.2 7.3 90.7-9.5 178.1-37 264.6-64.6 6.6-4.1 8.8 2.6 11.3 7.4-91.9 61.3-190.8 112.4-294.8 150-57.5 19.3-118.3 37.6-179.6 30.4-32.2-3.2-64.5-22.4-74.6-54.5-12.5-41.8-7.9-88.1 10.2-127.6 27.5-61.7 70.2-114.7 110.7-168.2 67.1-88 136.4-175.5 189.1-273.3 17.4-34.7 36-76.8 18.7-115.1-16.3-35.3-51.7-56.1-85.6-71.8-60.2-26.9-124.4-43.1-187.7-61.1q-14.3 9.4-28.5 19c22 16.8 44 33.6 65.8 50.7-83.3 15-166.3 31.8-248.3 52.7-124.9 31-246.8 72.5-367.6 116.5 11.8 23.5 23.5 47.1 34.7 70.9-27.3 30.2-54.4 60.7-81.7 90.9 65.6 19.6 136.3 22.3 203.2 7.5 57.2-12.8 111-40.2 154.7-79.3-11.9-14.8-26.9-26.7-43.1-36.5 53.1 1.1 101.4 47.4 101.5 101.1q-15.6 0.1-31 0.2c-2.2-11.7-5.3-23-9.4-34.1-60.3 54.5-138.2 88.6-218.9 97.4-71.1 8.2-143.8-1.6-210.7-26.6 4.5 41.4 9 82.6 13.2 124-38 14.8-73.3 36.2-104.9 62-25.1 21.9-50 47.1-59.6 79.9-9.2 28.9 5.8 61.7 31.1 77.2 30.7 19 66.5 27.8 101.9 32.9 46.7 6.1 93.9 5.6 140.8 2.3 92.1-6.8 183.1-24.1 272.7-45.8 8.9-3.6 13.1 11.1 4 13.4-71.5 36.8-146.3 67.8-224.3 87.8-73.3 18.9-148.8 28.6-224.4 31.2-77.1-2.4-159-17.3-220.1-67.8-45.4-36.8-69.3-95.2-69.5-153.1v-3.1c1.5-61.2 22.2-120.4 52-173.4 39.2-74.8 87.5-145 144.6-207.3 98.7-108.7 222.5-192.8 355.6-253.7 137.9-62.5 285.5-107.4 437.3-115.7z"/>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<svg width="46" height="46" viewBox="0 0 46 46" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="23" cy="23" r="23" fill="white"/>
<path d="M32.73 7h-6.945L38.45 39h6.945L32.73 7ZM12.665 7 0 39h7.082l2.59-6.72h13.25l2.59 6.72h7.082L19.929 7h-7.264Zm-.702 19.337 4.334-11.246 4.334 11.246h-8.668Z" fill="#000000"></path>
</svg>
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" style="flex: 0 0 auto; line-height: 1; margin-right: 6.4px;"><title>Zhipu</title><path d="M11.991 23.503a.24.24 0 00-.244.248.24.24 0 00.244.249.24.24 0 00.245-.249.24.24 0 00-.22-.247l-.025-.001zM9.671 5.365a1.697 1.697 0 011.099 2.132l-.071.172-.016.04-.018.054c-.07.16-.104.32-.104.498-.035.71.47 1.279 1.186 1.314h.366c1.309.053 2.338 1.173 2.286 2.523-.052 1.332-1.152 2.38-2.478 2.327h-.174c-.715.018-1.274.64-1.239 1.368 0 .124.018.23.053.337.209.373.54.658.96.8.75.23 1.517-.125 1.9-.782l.018-.035c.402-.64 1.17-.96 1.92-.711.854.284 1.378 1.226 1.099 2.167a1.661 1.661 0 01-2.077 1.102 1.711 1.711 0 01-.907-.711l-.017-.035c-.2-.323-.463-.58-.851-.711l-.056-.018a1.646 1.646 0 00-1.954.746 1.66 1.66 0 01-1.065.764 1.677 1.677 0 01-1.989-1.279c-.209-.906.332-1.83 1.257-2.043a1.51 1.51 0 01.296-.035h.018c.68-.071 1.151-.622 1.116-1.333a1.307 1.307 0 00-.227-.693 2.515 2.515 0 01-.366-1.403 2.39 2.39 0 01.366-1.208c.14-.195.21-.444.227-.693.018-.71-.506-1.261-1.186-1.332l-.07-.018a1.43 1.43 0 01-.299-.07l-.05-.019a1.7 1.7 0 01-1.047-2.114 1.68 1.68 0 012.094-1.101zm-5.575 10.11c.26-.264.639-.367.994-.27.355.096.633.379.728.74.095.362-.007.748-.267 1.013-.402.41-1.053.41-1.455 0a1.062 1.062 0 010-1.482zm14.845-.294c.359-.09.738.024.992.297.254.274.344.665.237 1.025-.107.36-.396.634-.756.718-.551.128-1.1-.22-1.23-.781a1.05 1.05 0 01.757-1.26zm-.064-4.39c.314.32.49.753.49 1.206 0 .452-.176.886-.49 1.206-.315.32-.74.5-1.185.5-.444 0-.87-.18-1.184-.5a1.727 1.727 0 010-2.412 1.654 1.654 0 012.369 0zm-11.243.163c.364.484.447 1.128.218 1.691a1.665 1.665 0 01-2.188.923c-.855-.36-1.26-1.358-.907-2.228a1.68 1.68 0 011.33-1.038c.593-.08 1.183.169 1.547.652zm11.545-4.221c.368 0 .708.2.892.524.184.324.184.724 0 1.048a1.026 1.026 0 01-.892.524c-.568 0-1.03-.47-1.03-1.048 0-.579.462-1.048 1.03-1.048zm-14.358 0c.368 0 .707.2.891.524.184.324.184.724 0 1.048a1.026 1.026 0 01-.891.524c-.569 0-1.03-.47-1.03-1.048 0-.579.461-1.048 1.03-1.048zm10.031-1.475c.925 0 1.675.764 1.675 1.706s-.75 1.705-1.675 1.705-1.674-.763-1.674-1.705c0-.942.75-1.706 1.674-1.706zm-2.626-.684c.362-.082.653-.356.761-.718a1.062 1.062 0 00-.238-1.028 1.017 1.017 0 00-.996-.294c-.547.14-.881.7-.752 1.257.13.558.675.907 1.225.783zm0 16.876c.359-.087.644-.36.75-.72a1.062 1.062 0 00-.237-1.019 1.018 1.018 0 00-.985-.301 1.037 1.037 0 00-.762.717c-.108.361-.017.754.239 1.028.245.263.606.377.953.305l.043-.01zM17.19 3.5a.631.631 0 00.628-.64c0-.355-.279-.64-.628-.64a.631.631 0 00-.628.64c0 .355.28.64.628.64zm-10.38 0a.631.631 0 00.628-.64c0-.355-.28-.64-.628-.64a.631.631 0 00-.628.64c0 .355.279.64.628.64zm-5.182 7.852a.631.631 0 00-.628.64c0 .354.28.639.628.639a.63.63 0 00.627-.606l.001-.034a.62.62 0 00-.628-.64zm5.182 9.13a.631.631 0 00-.628.64c0 .355.279.64.628.64a.631.631 0 00.628-.64c0-.355-.28-.64-.628-.64zm10.38.018a.631.631 0 00-.628.64c0 .355.28.64.628.64a.631.631 0 00.628-.64c0-.355-.279-.64-.628-.64zm5.182-9.148a.631.631 0 00-.628.64c0 .354.279.639.628.639a.631.631 0 00.628-.64c0-.355-.28-.64-.628-.64zm-.384-4.992a.24.24 0 00.244-.249.24.24 0 00-.244-.249.24.24 0 00-.244.249c0 .142.122.249.244.249zM11.991.497a.24.24 0 00.245-.248A.24.24 0 0011.99 0a.24.24 0 00-.244.249c0 .133.108.236.223.247l.021.001zM2.011 6.36a.24.24 0 00.245-.249.24.24 0 00-.244-.249.24.24 0 00-.244.249.24.24 0 00.244.249zm0 11.263a.24.24 0 00-.243.248.24.24 0 00.244.249.24.24 0 00.244-.249.252.252 0 00-.244-.248zm19.995-.018a.24.24 0 00-.245.248.24.24 0 00.245.25.24.24 0 00.244-.25.252.252 0 00-.244-.248z" fill="#3859FF" fill-rule="nonzero"></path></svg>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="none"><path fill="#4285F4" d="M14.9 8.161c0-.476-.039-.954-.121-1.422h-6.64v2.695h3.802a3.24 3.24 0 01-1.407 2.127v1.75h2.269c1.332-1.22 2.097-3.02 2.097-5.15z"/><path fill="#34A853" d="M8.14 15c1.898 0 3.499-.62 4.665-1.69l-2.268-1.749c-.631.427-1.446.669-2.395.669-1.836 0-3.393-1.232-3.952-2.888H1.85v1.803A7.044 7.044 0 008.14 15z"/><path fill="#FBBC04" d="M4.187 9.342a4.17 4.17 0 010-2.68V4.859H1.849a6.97 6.97 0 000 6.286l2.338-1.803z"/><path fill="#EA4335" d="M8.14 3.77a3.837 3.837 0 012.7 1.05l2.01-1.999a6.786 6.786 0 00-4.71-1.82 7.042 7.042 0 00-6.29 3.858L4.186 6.66c.556-1.658 2.116-2.89 3.952-2.89z"/></svg>
\ No newline at end of file
<svg fill="currentColor" fill-rule="evenodd" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" style="flex: 0 0 auto; line-height: 1; margin-right: 6.4px; height:20px;"><title>MoonshotAI</title><path d="M1.052 16.916l9.539 2.552a21.007 21.007 0 00.06 2.033l5.956 1.593a11.997 11.997 0 01-5.586.865l-.18-.016-.044-.004-.084-.009-.094-.01a11.605 11.605 0 01-.157-.02l-.107-.014-.11-.016a11.962 11.962 0 01-.32-.051l-.042-.008-.075-.013-.107-.02-.07-.015-.093-.019-.075-.016-.095-.02-.097-.023-.094-.022-.068-.017-.088-.022-.09-.024-.095-.025-.082-.023-.109-.03-.062-.02-.084-.025-.093-.028-.105-.034-.058-.019-.08-.026-.09-.031-.066-.024a6.293 6.293 0 01-.044-.015l-.068-.025-.101-.037-.057-.022-.08-.03-.087-.035-.088-.035-.079-.032-.095-.04-.063-.028-.063-.027a5.655 5.655 0 01-.041-.018l-.066-.03-.103-.047-.052-.024-.096-.046-.062-.03-.084-.04-.086-.044-.093-.047-.052-.027-.103-.055-.057-.03-.058-.032a6.49 6.49 0 01-.046-.026l-.094-.053-.06-.034-.051-.03-.072-.041-.082-.05-.093-.056-.052-.032-.084-.053-.061-.039-.079-.05-.07-.047-.053-.035a7.785 7.785 0 01-.054-.036l-.044-.03-.044-.03a6.066 6.066 0 01-.04-.028l-.057-.04-.076-.054-.069-.05-.074-.054-.056-.042-.076-.057-.076-.059-.086-.067-.045-.035-.064-.052-.074-.06-.089-.073-.046-.039-.046-.039a7.516 7.516 0 01-.043-.037l-.045-.04-.061-.053-.07-.062-.068-.06-.062-.058-.067-.062-.053-.05-.088-.084a13.28 13.28 0 01-.099-.097l-.029-.028-.041-.042-.069-.07-.05-.051-.05-.053a6.457 6.457 0 01-.168-.179l-.08-.088-.062-.07-.071-.08-.042-.049-.053-.062-.058-.068-.046-.056a7.175 7.175 0 01-.027-.033l-.045-.055-.066-.082-.041-.052-.05-.064-.02-.025a11.99 11.99 0 01-1.44-2.402zm-1.02-5.794l11.353 3.037a20.468 20.468 0 00-.469 2.011l10.817 2.894a12.076 12.076 0 01-1.845 2.005L.657 15.923l-.016-.046-.035-.104a11.965 11.965 0 01-.05-.153l-.007-.023a11.896 11.896 0 01-.207-.741l-.03-.126-.018-.08-.021-.097-.018-.081-.018-.09-.017-.084-.018-.094c-.026-.141-.05-.283-.071-.426l-.017-.118-.011-.083-.013-.102a12.01 12.01 0 01-.019-.161l-.005-.047a12.12 12.12 0 01-.034-2.145zm1.593-5.15l11.948 3.196c-.368.605-.705 1.231-1.01 1.875l11.295 3.022c-.142.82-.368 1.612-.668 2.365l-11.55-3.09L.124 10.26l.015-.1.008-.049.01-.067.015-.087.018-.098c.026-.148.056-.295.088-.442l.028-.124.02-.085.024-.097c.022-.09.045-.18.07-.268l.028-.102.023-.083.03-.1.025-.082.03-.096.026-.082.031-.095a11.896 11.896 0 011.01-2.232zm4.442-4.4L17.352 4.59a20.77 20.77 0 00-1.688 1.721l7.823 2.093c.267.852.442 1.744.513 2.665L2.106 5.213l.045-.065.027-.04.04-.055.046-.065.055-.076.054-.072.064-.086.05-.065.057-.073.055-.07.06-.074.055-.069.065-.077.054-.066.066-.077.053-.06.072-.082.053-.06.067-.074.054-.058.073-.078.058-.06.063-.067.168-.17.1-.098.059-.056.076-.071a12.084 12.084 0 012.272-1.677zM12.017 0h.097l.082.001.069.001.054.002.068.002.046.001.076.003.047.002.06.003.054.002.087.005.105.007.144.011.088.007.044.004.077.008.082.008.047.005.102.012.05.006.108.014.081.01.042.006.065.01.207.032.07.012.065.011.14.026.092.018.11.022.046.01.075.016.041.01L14.7.3l.042.01.065.015.049.012.071.017.096.024.112.03.113.03.113.032.05.015.07.02.078.024.073.023.05.016.05.016.076.025.099.033.102.036.048.017.064.023.093.034.11.041.116.045.1.04.047.02.06.024.041.018.063.026.04.018.057.025.11.048.1.046.074.035.075.036.06.028.092.046.091.045.102.052.053.028.049.026.046.024.06.033.041.022.052.029.088.05.106.06.087.051.057.034.053.032.096.059.088.055.098.062.036.024.064.041.084.056.04.027.062.042.062.043.023.017c.054.037.108.075.161.114l.083.06.065.048.056.043.086.065.082.064.04.03.05.041.086.069.079.065.085.071c.712.6 1.353 1.283 1.909 2.031L7.222.994l.062-.027.065-.028.081-.034.086-.035c.113-.045.227-.09.341-.131l.096-.035.093-.033.084-.03.096-.031c.087-.03.176-.058.264-.085l.091-.027.086-.025.102-.03.085-.023.1-.026L9.04.37l.09-.023.091-.022.095-.022.09-.02.098-.021.091-.02.095-.018.092-.018.1-.018.091-.016.098-.017.092-.014.097-.015.092-.013.102-.013.091-.012.105-.012.09-.01.105-.01c.093-.01.186-.018.28-.024l.106-.008.09-.005.11-.006.093-.004.1-.004.097-.002.099-.002.197-.002z"></path></svg>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<svg fill="#000000" viewBox="-2 -2 28 28" role="img" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="14" fill="white" />
<path d="M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z"/>
</svg>
\ No newline at end of file
// PricingChart.jsx
import React, { useState } from 'react';
import '../styles/PricingChart.css';
const ChartLegend = ({ onLegendClick, highlightedBarTypes }) => (
<div className="legend">
<div
className="legend-item"
onClick={() => onLegendClick('input')}
style={{ cursor: 'pointer', opacity: highlightedBarTypes.input ? 1 : 0.5 }}
>
<div className="legend-color input-color"></div>
<span>Input price</span>
</div>
<div
className="legend-item"
onClick={() => onLegendClick('output')}
style={{ cursor: 'pointer', opacity: highlightedBarTypes.output ? 1 : 0.5 }}
>
<div className="legend-color output-color"></div>
<span>Output price</span>
</div>
</div>
);
const ChartBar = ({ price, type, maxPrice, highlighted }) => {
const getBarHeight = () => {
return (price / maxPrice) * 300;
};
return (
<div
className={`bar ${type}-bar`}
style={{
height: `${getBarHeight()}px`,
opacity: highlighted ? 1 : 0.3,
}}
>
<span className="price-label">{price}</span>
</div>
);
};
const ProviderColumn = ({ provider, maxPrice, highlightedBarTypes }) => (
<div className="chart-column">
<div className="bars-container">
<ChartBar
price={provider.inputPrice}
type="input"
maxPrice={maxPrice}
highlighted={highlightedBarTypes.input}
/>
<ChartBar
price={provider.outputPrice}
type="output"
maxPrice={maxPrice}
highlighted={highlightedBarTypes.output}
/>
</div>
<div className="provider-info">
<img
src={`/src/assets/${provider.logo}`}
alt={`${provider.name} logo`}
className="provider-logo"
/>
<span className="provider-name">{provider.name}</span>
</div>
</div>
);
const YAxis = ({ maxPrice }) => {
const numberOfTicks = 5;
const tickValues = [];
for (let i = 0; i <= numberOfTicks; i++) {
const value = ((maxPrice / numberOfTicks) * i).toFixed(2);
tickValues.push(value);
}
return (
<div className="y-axis">
{tickValues.reverse().map((value, index) => (
<div key={index} className="y-axis-label">
{value}
</div>
))}
</div>
);
};
const GridLines = () => (
<div className="grid-lines">
{[...Array(5)].map((_, index) => (
<div key={index} className="grid-line" style={{ bottom: `${(index / 4) * 100}%` }}></div>
))}
</div>
);
const PricingChart = ({ data }) => {
const [highlightedBarTypes, setHighlightedBarTypes] = useState({
input: true,
output: true,
});
const handleLegendClick = (barType) => {
setHighlightedBarTypes((prevState) => ({
...prevState,
[barType]: !prevState[barType],
}));
};
const getMaxPrice = () => {
const prices = data.providers.flatMap((provider) => [
provider.inputPrice,
provider.outputPrice,
]);
return Math.max(...prices);
};
const maxPrice = getMaxPrice();
return (
<div className="pricing-chart">
<h1 className="chart-title">{data.title}</h1>
<h2 className="chart-subtitle">{data.subtitle}</h2>
<ChartLegend onLegendClick={handleLegendClick} highlightedBarTypes={highlightedBarTypes} />
<div className="chart-area">
<YAxis maxPrice={maxPrice} />
<div className="chart-container">
<GridLines />
{data.providers.map((provider) => (
<ProviderColumn
key={provider.name}
provider={provider}
maxPrice={maxPrice}
highlightedBarTypes={highlightedBarTypes}
/>
))}
</div>
</div>
</div>
);
};
export default PricingChart;
// App.jsx 或其他父组件
import React from 'react';
import PricingChart from '../components/PricingChart';
import OpenaiPricing from '../data/openai-pricing.json';
import LLMPricing from '../data/llm-pricing.json';
import VisionPricing from '../data/vision-model-pricing.json';
const PricingCharts = () => {
const lastUpdateTime = '2024-11-06 21:30'; // 硬编码的更新时间
return (
<div className="pricing-charts-container">
<div className="update-time">数据最后更新时间: {lastUpdateTime}</div>
<PricingChart data={OpenaiPricing} />
<PricingChart data={LLMPricing} />
<PricingChart data={VisionPricing} />
</div>
);
};
export default PricingCharts;
...@@ -170,7 +170,7 @@ const events = [ ...@@ -170,7 +170,7 @@ const events = [
const Timeline = () => { const Timeline = () => {
return ( return (
<div className="container"> <div className="container">
<h1>OpenAI 产品发布时间线</h1> <div className="timeline-title">OpenAI 产品发布时间线</div>
<ul className="timeline"> <ul className="timeline">
{events.map((item, index) => ( {events.map((item, index) => (
<li className="event" key={index}> <li className="event" key={index}>
......
{
"title": "国内外各模型价格对比",
"subtitle": "Price: RMB per 1M Tokens",
"providers": [
{
"name": "Doubao-lite-32k",
"logo": "../assets/doubao.png",
"inputPrice": 0.3,
"outputPrice": 0.6
},
{
"name": "yi-lightning\n-16k",
"logo": "../assets/yi_small.jpg",
"inputPrice": 0.99,
"outputPrice": 0.99
},
{
"name": "GLM-4-Air\n-128k",
"logo": "../assets/glm_small.svg",
"inputPrice": 1,
"outputPrice": 1
},
{
"name": "gemini 1.5 Flash",
"logo": "../assets/google_small.svg",
"inputPrice": 0.53,
"outputPrice": 2.1
},
{
"name": "Doubao-pro-32k",
"logo": "../assets/doubao.png",
"inputPrice": 0.8,
"outputPrice": 2
},
{
"name": "qwen-plus\n-128k",
"logo": "../assets/ali_small.svg",
"inputPrice": 0.8,
"outputPrice": 2
},
{
"name": "ERNIE 3.5",
"logo": "../assets/wenxin_small.png",
"inputPrice": 0.8,
"outputPrice": 2
},
{
"name": "deepseek-\nchat-128k",
"logo": "../assets/deepseek_small.jpg",
"inputPrice": 1,
"outputPrice": 2
},
{
"name": "gpt-4o-mini",
"logo": "../assets/openai_small.svg",
"inputPrice": 1.05,
"outputPrice": 4.2
},
{
"name": "qwen-math-plus",
"logo": "../assets/ali_small.svg",
"inputPrice": 4,
"outputPrice": 12
},
{
"name": "claude 3.5\nHaiku",
"logo": "../assets/anthropic_small.svg",
"inputPrice": 8.75,
"outputPrice": 35
},
{
"name": "yi-large-32k",
"logo": "../assets/yi_small.jpg",
"inputPrice": 20,
"outputPrice": 20
},
{
"name": "mooonshot-v1-32k",
"logo": "../assets/moonshot_small.svg",
"inputPrice": 24,
"outputPrice": 24
},
{
"name": "qwen-max-32k",
"logo": "../assets/ali_small.svg",
"inputPrice": 20,
"outputPrice": 60
},
{
"name": "ERNIE 4.0\nTurbo",
"logo": "../assets/wenxin_small.png",
"inputPrice": 20,
"outputPrice": 60
},
{
"name": "gpt-4o",
"logo": "../assets/openai_small.svg",
"inputPrice": 17.5,
"outputPrice": 70
},
{
"name": "GLM-4-Plus-128k",
"logo": "../assets/glm_small.svg",
"inputPrice": 50,
"outputPrice": 50
},
{
"name": "o1-mini",
"logo": "../assets/openai_small.svg",
"inputPrice": 21,
"outputPrice": 84
},
{
"name": "gemini 1.5 Pro",
"logo": "../assets/google_small.svg",
"inputPrice": 87.5,
"outputPrice": 35
},
{
"name": "claude 3.5\nSonnet",
"logo": "../assets/anthropic_small.svg",
"inputPrice": 26.3,
"outputPrice": 105
},
{
"name": "o1-preview",
"logo": "../assets/openai_small.svg",
"inputPrice": 105,
"outputPrice": 420
},
{
"name": "claude 3.5\nOpus",
"logo": "../assets/anthropic_small.svg",
"inputPrice": 131,
"outputPrice": 525
}
]
}
\ No newline at end of file
{
"title": "OpenAI 各模型价格对比",
"subtitle": "Price: USD per 1M Tokens",
"providers": [
{
"name": "gpt-4o-mini",
"logo": "../assets/openai_small.svg",
"inputPrice": 0.15,
"outputPrice": 0.6
},
{
"name": "gpt-4o",
"logo": "../assets/openai_small.svg",
"inputPrice": 2.5,
"outputPrice": 10
},
{
"name": "gpt-4o-latest",
"logo": "../assets/openai_small.svg",
"inputPrice": 5,
"outputPrice": 15
},
{
"name": "gpt-4-turbo",
"logo": "../assets/openai_small.svg",
"inputPrice": 10,
"outputPrice": 30
},
{
"name": "o1-mini",
"logo": "../assets/openai_small.svg",
"inputPrice": 3,
"outputPrice": 12
},
{
"name": "o1-preview",
"logo": "../assets/openai_small.svg",
"inputPrice": 15,
"outputPrice": 60
},
{
"name": "gpt-4o-audio-preview",
"logo": "../assets/openai_small.svg",
"inputPrice": 2.5,
"outputPrice": 10
},
{
"name": "gpt-4o-realtime-preview",
"logo": "../assets/openai_small.svg",
"inputPrice": 5,
"outputPrice": 20
}
]
}
\ No newline at end of file
{
"title": "视觉各模型价格对比",
"subtitle": "Price: RMB per 1M Tokens",
"providers": [
{
"name": "gpt-4o-mini",
"logo": "../assets/openai_small.svg",
"inputPrice": 1.05,
"outputPrice": 4.2
},
{
"name": "yi-vision-16k",
"logo": "../assets/yi_small.jpg",
"inputPrice": 6,
"outputPrice": 6
},
{
"name": "GLM-4V-Plus",
"logo": "../assets/glm_small.svg",
"inputPrice": 10,
"outputPrice": 10
},
{
"name": "qwen-vl-max",
"logo": "../assets/ali_small.svg",
"inputPrice": 20,
"outputPrice": 20
},
{
"name": "gpt-4o",
"logo": "../assets/openai_small.svg",
"inputPrice": 17.5,
"outputPrice": 70
},
{
"name": "GLM-4V",
"logo": "../assets/glm_small.svg",
"inputPrice": 50,
"outputPrice": 50
}
]
}
\ No newline at end of file
...@@ -28,6 +28,15 @@ const i18n = { ...@@ -28,6 +28,15 @@ const i18n = {
copyButton: 'Copy', copyButton: 'Copy',
copiedMessage: 'Copied' copiedMessage: 'Copied'
}, },
openAITimeline: {
title: 'Summary of OpenAI Product Releases',
description: 'Overview of OpenAI Product Release Dates'
},
modelPrice: {
title: 'Global Model Price Comparison',
description: 'Overview of Price Comparison Among Models'
}
}, },
notFound: { notFound: {
title: '404 - Page Not Found', title: '404 - Page Not Found',
...@@ -77,6 +86,14 @@ const i18n = { ...@@ -77,6 +86,14 @@ const i18n = {
copyButton: '复制', copyButton: '复制',
copiedMessage: '已复制' copiedMessage: '已复制'
}, },
openAITimeline: {
title: "OpenAI 产品发布汇总",
description: 'OpenAI 产品发布时间一览',
},
modelPrice: {
title: "全球各大模型价格对比",
description: "各模型价格对比一览"
}
}, },
notFound: { notFound: {
title: '404 - 页面未找到', title: '404 - 页面未找到',
...@@ -126,6 +143,15 @@ const i18n = { ...@@ -126,6 +143,15 @@ const i18n = {
copyButton: 'コピー', copyButton: 'コピー',
copiedMessage: 'コピーしました' copiedMessage: 'コピーしました'
}, },
openAITimeline: {
title: 'OpenAI製品リリースの概要',
description: 'OpenAI製品リリース日時の一覧'
},
modelPrice: {
title: '世界の主要モデル価格比較',
description: '各モデルの価格比較一覧'
}
}, },
notFound: { notFound: {
title: '404 - ページが見つかりません', title: '404 - ページが見つかりません',
...@@ -175,6 +201,15 @@ const i18n = { ...@@ -175,6 +201,15 @@ const i18n = {
copyButton: '복사', copyButton: '복사',
copiedMessage: '복사됨' copiedMessage: '복사됨'
}, },
openAITimeline: {
title: 'OpenAI 제품 출시 요약',
description: 'OpenAI 제품 출시 날짜 개요'
},
modelPrice: {
title: '글로벌 모델 가격 비교',
description: '모델 간 가격 비교 개요'
}
}, },
notFound: { notFound: {
title: '404 - 페이지를 찾을 수 없습니다', title: '404 - 페이지를 찾을 수 없습니다',
......
...@@ -7,6 +7,8 @@ const tools = [ ...@@ -7,6 +7,8 @@ const tools = [
{ id: 'text2image', icon: 'fa-image', path: '/text2image' }, { id: 'text2image', icon: 'fa-image', path: '/text2image' },
{ id: 'jsonFormatter', icon: 'fa-code', path: '/json-formatter' }, { id: 'jsonFormatter', icon: 'fa-code', path: '/json-formatter' },
{ id: 'urlDecode', icon: 'fa-decode', path: '/url-decode' }, { id: 'urlDecode', icon: 'fa-decode', path: '/url-decode' },
{ id: 'openAITimeline', icon: 'fa-decode', path: '/openai-timeline' },
{ id: 'modelPrice', icon: 'fa-decode', path: '/llm-model-price' },
]; ];
const Home = () => { const Home = () => {
......
.pricing-chart {
padding: 2rem;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
}
.chart-title {
font-size: 1.5rem;
font-weight: 600;
margin-bottom: 0.5rem;
}
.chart-subtitle {
font-size: 1rem;
color: #666;
font-weight: normal;
margin-bottom: 1rem;
}
.legend {
display: flex;
gap: 2rem;
margin-bottom: 1rem;
}
.legend-item {
display: flex;
align-items: center;
gap: 0.5rem;
}
.legend-color {
width: 20px;
height: 20px;
border-radius: 4px;
}
.input-color {
background-color: #4285f4;
}
.output-color {
background-color: #7c4dff;
}
.chart-area {
display: flex;
}
.y-axis {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 300px;
margin-right: 10px;
}
.y-axis-label {
font-size: 0.75rem;
text-align: right;
}
.chart-container {
display: flex;
align-items: flex-end;
gap: 0.5rem; /* 减小柱状图之间的间距 */
height: 300px;
position: relative;
padding-bottom: 80px;
width: 100%; /* 确保容器占满可用宽度 */
overflow: visible; /* 移除水平滚动 */
}
.grid-lines {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 80px;
z-index: 1;
}
.grid-line {
position: absolute;
left: 0;
right: 0;
border-top: 1px solid #e0e0e0;
}
.chart-column {
position: relative;
flex: 1; /* 使柱状图列可伸缩 */
/* max-width: 60px; */ /* 移除这行 */
z-index: 2;
display: flex;
flex-direction: column;
align-items: center;
}
/* 让.bar根据可用空间调整宽度 */
.bars-container {
display: flex;
gap: 2px;
align-items: flex-end;
height: 100%;
justify-content: center;
flex-grow: 1; /* 新增 */
}
.bar {
width: 15px; /* 减小柱状图的宽度 */
position: relative;
border-radius: 4px 4px 0 0;
transition: height 0.3s ease;
}
.input-bar {
background-color: #4285f4;
}
.output-bar {
background-color: #7c4dff;
margin-left: 5px;
}
.price-label {
position: absolute;
top: -20px;
left: 50%;
transform: translateX(-50%);
font-size: 0.65rem; /* 减小价格标签的字体大小 */
white-space: nowrap;
}
.provider-info {
position: absolute;
bottom: -70px;
left: 50%;
transform: translateX(-50%);
display: flex;
flex-direction: column;
align-items: center;
}
.provider-logo {
width: 20px; /* 缩小Logo尺寸 */
height: 20px;
object-fit: contain;
}
.provider-name {
font-size: 13px;
transform: translate(-18px, 36px) rotate(-77deg);
transform-origin: top center;
/* white-space: nowrap; */
/* margin-top: 35px; */
line-height: 16px;
padding-top: -11px;
width: 80px;
text-align: right;
height: 40px;
word-break: break-all;
white-space: break-spaces;
padding-right: 18px;
}
.pricing-charts-container {
padding: 20px;
background-color: #f9f9f9;
}
.update-time {
text-align: right;
font-size: 0.9rem;
color: #555;
margin-bottom: 15px;
font-style: italic;
}
...@@ -8,10 +8,11 @@ ...@@ -8,10 +8,11 @@
background-color: #ffffff; background-color: #ffffff;
} }
h1 { .timeline-title {
text-align: center; text-align: center;
color: #d9730d; color: #d9730d;
margin-bottom: 40px; margin-bottom: 40px;
font-size: 60px;
} }
.timeline { .timeline {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment