mirror of
https://github.com/langgenius/dify.git
synced 2026-03-08 08:57:37 +08:00
Signed-off-by: majiayu000 <1835304752@qq.com> Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: NeatGuyCoding <15627489+NeatGuyCoding@users.noreply.github.com> Signed-off-by: -LAN- <laipz8200@outlook.com> Signed-off-by: yihong0618 <zouzou0208@gmail.com> Co-authored-by: QuantumGhost <obelisk.reg+git@gmail.com> Co-authored-by: 盐粒 Yanli <yanli@dify.ai> Co-authored-by: wangxiaolei <fatelei@gmail.com> Co-authored-by: Stephen Zhou <38493346+hyoban@users.noreply.github.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Cursx <33718736+Cursx@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: lif <1835304752@qq.com> Co-authored-by: 非法操作 <hjlarry@163.com> Co-authored-by: Asuka Minato <i@asukaminato.eu.org> Co-authored-by: fenglin <790872612@qq.com> Co-authored-by: qiaofenglin <qiaofenglin@baidu.com> Co-authored-by: -LAN- <laipz8200@outlook.com> Co-authored-by: TomoOkuyama <49631611+TomoOkuyama@users.noreply.github.com> Co-authored-by: Tomo Okuyama <tomo.okuyama@intersystems.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: zyssyz123 <916125788@qq.com> Co-authored-by: hj24 <mambahj24@gmail.com> Co-authored-by: Coding On Star <447357187@qq.com> Co-authored-by: CodingOnStar <hanxujiang@dify.ai> Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com> Co-authored-by: Xiangxuan Qu <fghpdf@outlook.com> Co-authored-by: fghpdf <fghpdf@users.noreply.github.com> Co-authored-by: coopercoder <whitetiger0127@163.com> Co-authored-by: zhaiguangpeng <zhaiguangpeng@didiglobal.com> Co-authored-by: Junyan Qin (Chin) <rockchinq@gmail.com> Co-authored-by: E.G <146701565+GlobalStar117@users.noreply.github.com> Co-authored-by: GlobalStar117 <GlobalStar117@users.noreply.github.com> Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com> Co-authored-by: CodingOnStar <hanxujiang@dify.com> Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com> Co-authored-by: heyszt <270985384@qq.com> Co-authored-by: NeatGuyCoding <15627489+NeatGuyCoding@users.noreply.github.com> Co-authored-by: Yeuoly <45712896+Yeuoly@users.noreply.github.com> Co-authored-by: zxhlyh <jasonapring2015@outlook.com> Co-authored-by: moonpanda <chuanzegao@163.com> Co-authored-by: warlocgao <warlocgao@tencent.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: KVOJJJin <jzongcode@gmail.com> Co-authored-by: eux <euxx@users.noreply.github.com> Co-authored-by: bangjiehan <bangjiehan@gmail.com> Co-authored-by: FFXN <31929997+FFXN@users.noreply.github.com> Co-authored-by: Jyong <76649700+JohnJyong@users.noreply.github.com> Co-authored-by: Nie Ronghua <nieronghua@sf-express.com> Co-authored-by: JQSevenMiao <141806521+JQSevenMiao@users.noreply.github.com> Co-authored-by: jiasiqi <jiasiqi3@tal.com> Co-authored-by: Seokrin Taron Sung <sungsjade@gmail.com> Co-authored-by: CrabSAMA <40541269+CrabSAMA@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: yihong <zouzou0208@gmail.com> Co-authored-by: Joel <iamjoel007@gmail.com> Co-authored-by: Wu Tianwei <30284043+WTW0313@users.noreply.github.com> Co-authored-by: yessenia <yessenia.contact@gmail.com> Co-authored-by: Jax <anobaka@qq.com> Co-authored-by: niveshdandyan <155956228+niveshdandyan@users.noreply.github.com> Co-authored-by: OSS Contributor <oss-contributor@example.com> Co-authored-by: niveshdandyan <niveshdandyan@users.noreply.github.com> Co-authored-by: Sean Kenneth Doherty <Smaster7772@gmail.com>
151 lines
4.2 KiB
TypeScript
151 lines
4.2 KiB
TypeScript
import type { Dayjs } from 'dayjs'
|
|
import type { Locale } from '@/i18n-config'
|
|
import { localeMap } from '@/i18n-config/language'
|
|
import 'dayjs/locale/de'
|
|
import 'dayjs/locale/es'
|
|
import 'dayjs/locale/fa'
|
|
import 'dayjs/locale/fr'
|
|
import 'dayjs/locale/hi'
|
|
import 'dayjs/locale/id'
|
|
import 'dayjs/locale/it'
|
|
import 'dayjs/locale/ja'
|
|
import 'dayjs/locale/ko'
|
|
import 'dayjs/locale/pl'
|
|
import 'dayjs/locale/pt-br'
|
|
import 'dayjs/locale/ro'
|
|
import 'dayjs/locale/ru'
|
|
import 'dayjs/locale/sl'
|
|
import 'dayjs/locale/th'
|
|
import 'dayjs/locale/tr'
|
|
import 'dayjs/locale/uk'
|
|
import 'dayjs/locale/vi'
|
|
import 'dayjs/locale/zh-cn'
|
|
import 'dayjs/locale/zh-tw'
|
|
|
|
/**
|
|
* Formats a number with comma separators.
|
|
* @example formatNumber(1234567) will return '1,234,567'
|
|
* @example formatNumber(1234567.89) will return '1,234,567.89'
|
|
* @example formatNumber(0.0000008) will return '0.0000008'
|
|
*/
|
|
export const formatNumber = (num: number | string) => {
|
|
if (!num)
|
|
return num
|
|
const n = typeof num === 'string' ? Number(num) : num
|
|
|
|
let numStr: string
|
|
|
|
// Force fixed decimal for small numbers to avoid scientific notation
|
|
if (Math.abs(n) < 0.001 && n !== 0) {
|
|
const str = n.toString()
|
|
const match = str.match(/e-(\d+)$/)
|
|
let precision: number
|
|
if (match) {
|
|
// Scientific notation: precision is exponent + decimal digits in mantissa
|
|
const exponent = Number.parseInt(match[1], 10)
|
|
const mantissa = str.split('e')[0]
|
|
const mantissaDecimalPart = mantissa.split('.')[1]
|
|
precision = exponent + (mantissaDecimalPart?.length || 0)
|
|
}
|
|
else {
|
|
// Decimal notation: count decimal places
|
|
const decimalPart = str.split('.')[1]
|
|
precision = decimalPart?.length || 0
|
|
}
|
|
numStr = n.toFixed(precision)
|
|
}
|
|
else {
|
|
numStr = n.toString()
|
|
}
|
|
|
|
const parts = numStr.split('.')
|
|
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',')
|
|
return parts.join('.')
|
|
}
|
|
|
|
/**
|
|
* Format file size into standard string format.
|
|
* @param fileSize file size (Byte)
|
|
* @example formatFileSize(1024) will return '1.00 KB'
|
|
* @example formatFileSize(1024 * 1024) will return '1.00 MB'
|
|
*/
|
|
export const formatFileSize = (fileSize: number) => {
|
|
if (!fileSize)
|
|
return fileSize
|
|
const units = ['', 'K', 'M', 'G', 'T', 'P']
|
|
let index = 0
|
|
while (fileSize >= 1024 && index < units.length) {
|
|
fileSize = fileSize / 1024
|
|
index++
|
|
}
|
|
if (index === 0)
|
|
return `${fileSize.toFixed(2)} bytes`
|
|
return `${fileSize.toFixed(2)} ${units[index]}B`
|
|
}
|
|
|
|
/**
|
|
* Format time into standard string format.
|
|
* @example formatTime(60) will return '1.00 min'
|
|
* @example formatTime(60 * 60) will return '1.00 h'
|
|
*/
|
|
export const formatTime = (seconds: number) => {
|
|
if (!seconds)
|
|
return seconds
|
|
const units = ['sec', 'min', 'h']
|
|
let index = 0
|
|
while (seconds >= 60 && index < units.length) {
|
|
seconds = seconds / 60
|
|
index++
|
|
}
|
|
return `${seconds.toFixed(2)} ${units[index]}`
|
|
}
|
|
|
|
/**
|
|
* Formats a number into a readable string using "k", "M", or "B" suffix.
|
|
* @example
|
|
* 950 => "950"
|
|
* 1200 => "1.2k"
|
|
* 1500000 => "1.5M"
|
|
* 2000000000 => "2B"
|
|
*
|
|
* @param {number} num - The number to format
|
|
* @returns {string} - The formatted number string
|
|
*/
|
|
export const formatNumberAbbreviated = (num: number) => {
|
|
// If less than 1000, return as-is
|
|
if (num < 1000)
|
|
return num.toString()
|
|
|
|
// Define thresholds and suffixes
|
|
const units = [
|
|
{ value: 1e9, symbol: 'B' },
|
|
{ value: 1e6, symbol: 'M' },
|
|
{ value: 1e3, symbol: 'k' },
|
|
]
|
|
|
|
for (let i = 0; i < units.length; i++) {
|
|
if (num >= units[i].value) {
|
|
const value = num / units[i].value
|
|
let rounded = Math.round(value * 10) / 10
|
|
let unitIndex = i
|
|
|
|
// If rounded value >= 1000, promote to next unit
|
|
if (rounded >= 1000 && i > 0) {
|
|
rounded = rounded / 1000
|
|
unitIndex = i - 1
|
|
}
|
|
|
|
const formatted = rounded.toFixed(1)
|
|
return formatted.endsWith('.0')
|
|
? `${Number.parseInt(formatted)}${units[unitIndex].symbol}`
|
|
: `${formatted}${units[unitIndex].symbol}`
|
|
}
|
|
}
|
|
// Fallback: if no threshold matched, return the number string
|
|
return num.toString()
|
|
}
|
|
|
|
export const formatToLocalTime = (time: Dayjs, local: Locale, format: string) => {
|
|
return time.locale(localeMap[local] ?? 'en').format(format)
|
|
}
|