ModelPricingHeader.jsx 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. Copyright (C) 2025 QuantumNous
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with this program. If not, see <https://www.gnu.org/licenses/>.
  13. For commercial licensing, please contact support@quantumnous.com
  14. */
  15. import React from 'react';
  16. import { Card } from '@douyinfe/semi-ui';
  17. import { IconVerify, IconLayers, IconInfoCircle } from '@douyinfe/semi-icons';
  18. import { AlertCircle } from 'lucide-react';
  19. const ModelPricingHeader = ({
  20. userState,
  21. groupRatio,
  22. selectedGroup,
  23. models,
  24. t
  25. }) => {
  26. return (
  27. <Card
  28. className="!rounded-2xl !border-0 !shadow-md overflow-hidden mb-6"
  29. style={{
  30. background: 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 25%, #a855f7 50%, #c084fc 75%, #d8b4fe 100%)',
  31. position: 'relative'
  32. }}
  33. bodyStyle={{ padding: 0 }}
  34. >
  35. <div className="relative p-6 sm:p-8" style={{ color: 'white' }}>
  36. <div className="flex flex-col lg:flex-row lg:items-start lg:justify-between gap-4 lg:gap-6">
  37. <div className="flex items-start">
  38. <div className="w-10 h-10 sm:w-12 sm:h-12 rounded-xl bg-white/10 flex items-center justify-center mr-3 sm:mr-4">
  39. <IconLayers size="extra-large" className="text-white" />
  40. </div>
  41. <div className="flex-1 min-w-0">
  42. <div className="text-base sm:text-lg font-semibold mb-1 sm:mb-2">
  43. {t('模型定价')}
  44. </div>
  45. <div className="text-sm text-white/80">
  46. {userState.user ? (
  47. <div className="flex items-center">
  48. <IconVerify className="mr-1.5 flex-shrink-0" size="small" />
  49. <span className="truncate">
  50. {t('当前分组')}: {userState.user.group},{t('倍率')}: {groupRatio[userState.user.group]}
  51. </span>
  52. </div>
  53. ) : (
  54. <div className="flex items-center">
  55. <AlertCircle size={14} className="mr-1.5 flex-shrink-0" />
  56. <span className="truncate">
  57. {t('未登录,使用默认分组倍率:')}{groupRatio['default']}
  58. </span>
  59. </div>
  60. )}
  61. </div>
  62. </div>
  63. </div>
  64. <div className="grid grid-cols-3 gap-2 sm:gap-3 mt-2 lg:mt-0">
  65. <div
  66. className="text-center px-2 py-2 sm:px-3 sm:py-2.5 bg-white/10 rounded-lg backdrop-blur-sm hover:bg-white/20 transition-colors duration-200"
  67. style={{ backdropFilter: 'blur(10px)' }}
  68. >
  69. <div className="text-xs text-white/70 mb-0.5">{t('分组倍率')}</div>
  70. <div className="text-sm sm:text-base font-semibold">{groupRatio[selectedGroup] || '1.0'}x</div>
  71. </div>
  72. <div
  73. className="text-center px-2 py-2 sm:px-3 sm:py-2.5 bg-white/10 rounded-lg backdrop-blur-sm hover:bg-white/20 transition-colors duration-200"
  74. style={{ backdropFilter: 'blur(10px)' }}
  75. >
  76. <div className="text-xs text-white/70 mb-0.5">{t('可用模型')}</div>
  77. <div className="text-sm sm:text-base font-semibold">
  78. {models.filter(m => m.enable_groups.includes(selectedGroup)).length}
  79. </div>
  80. </div>
  81. <div
  82. className="text-center px-2 py-2 sm:px-3 sm:py-2.5 bg-white/10 rounded-lg backdrop-blur-sm hover:bg-white/20 transition-colors duration-200"
  83. style={{ backdropFilter: 'blur(10px)' }}
  84. >
  85. <div className="text-xs text-white/70 mb-0.5">{t('计费类型')}</div>
  86. <div className="text-sm sm:text-base font-semibold">2</div>
  87. </div>
  88. </div>
  89. </div>
  90. {/* 计费说明 */}
  91. <div className="mt-4 sm:mt-5">
  92. <div className="flex items-start">
  93. <div
  94. className="w-full flex items-start space-x-2 px-3 py-2 sm:px-4 sm:py-2.5 rounded-lg text-xs sm:text-sm"
  95. style={{
  96. backgroundColor: 'rgba(255, 255, 255, 0.2)',
  97. color: 'white',
  98. backdropFilter: 'blur(10px)'
  99. }}
  100. >
  101. <IconInfoCircle className="flex-shrink-0 mt-0.5" size="small" />
  102. <span>
  103. {t('按量计费费用 = 分组倍率 × 模型倍率 × (提示token数 + 补全token数 × 补全倍率)/ 500000 (单位:美元)')}
  104. </span>
  105. </div>
  106. </div>
  107. </div>
  108. <div className="absolute top-0 left-0 w-full h-2 bg-gradient-to-r from-yellow-400 via-orange-400 to-red-400" style={{ opacity: 0.6 }}></div>
  109. </div>
  110. </Card>
  111. );
  112. };
  113. export default ModelPricingHeader;