oss.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /**
  2. * oss resize 参数
  3. * 详情见 https://help.aliyun.com/document_detail/44688.html?spm=a2c4g.11186623.6.751.7434663c1Ne07e
  4. * ,/
  5. * oss watermark 参数
  6. * 详情见 https://help.aliyun.com/document_detail/44957.html
  7. *
  8. * resize 参数被提到最外层(兼容 + 使用最频繁)
  9. * 其他(如 watermark)使用对象
  10. */
  11. import encBase64Url from 'crypto-js/enc-base64url'
  12. import encUtf8 from 'crypto-js/enc-utf8'
  13. export type IOSSResize =
  14. | {
  15. m: 'lfit' | 'mfit' | 'fixed' | 'fixed' | 'fill' | 'pad'
  16. w?: number
  17. h?: number
  18. l?: number
  19. s?: number
  20. color?: string
  21. limit?: 0 | 1
  22. }
  23. | {
  24. p?: number
  25. }
  26. export type IOSSOptions = {
  27. watermark?: IOSSWatermark | IOSSWatermark[]
  28. quality?: IOSSQuality
  29. } & {
  30. [key: string]: object
  31. }
  32. export type IOSSWatermark = {
  33. t?: number
  34. g?: 'nw' | 'north' | 'ne' | 'west' | 'center' | 'east' | 'sw' | 'south' | 'se'
  35. x?: number
  36. y?: number
  37. voffset?: number
  38. // 图片
  39. image?: string
  40. P?: number
  41. // 文字
  42. text?: string
  43. type?: string
  44. size?: number
  45. shadow?: number
  46. rotate?: number
  47. fill?: 0 | 1
  48. color?: string
  49. // 混合
  50. order?: 0 | 1
  51. align?: 0 | 1 | 2
  52. interval?: number
  53. } & (
  54. | {
  55. image: string
  56. // text?: string
  57. }
  58. | {
  59. // image?: string
  60. text: string
  61. }
  62. )
  63. export type IOSSQuality = {
  64. q?: number
  65. Q?: number
  66. }
  67. function createParams(key: string, options: Record<string, any>) {
  68. const list = [key]
  69. Object.keys(options).forEach((key) => {
  70. const value = options[key]
  71. if (value !== undefined && value !== null) {
  72. list.push(`${key}_${value}`)
  73. }
  74. })
  75. return list.join(',')
  76. }
  77. export function ossResize(
  78. url?: string,
  79. resize: IOSSResize = {},
  80. options: IOSSOptions = {}
  81. ) {
  82. if (!url) return ''
  83. try {
  84. const target = new URL(url)
  85. const parmas = target.searchParams
  86. const { watermark, quality, ...otherOptions } = options
  87. const list = ['image']
  88. // 尺寸调整
  89. if ('m' in resize || 'p' in resize) {
  90. list.push(createParams('resize', resize))
  91. }
  92. // 水印
  93. if (watermark) {
  94. ;(Array.isArray(watermark) ? watermark : [watermark]).forEach(
  95. (watermark) => {
  96. list.push(createParams('watermark', watermark))
  97. }
  98. )
  99. }
  100. // 图片质量
  101. list.push(
  102. createParams(
  103. 'quality',
  104. quality ?? {
  105. Q: 80,
  106. }
  107. )
  108. )
  109. // 其他
  110. Object.keys(otherOptions).forEach((key) => {
  111. list.push(createParams(key, otherOptions[key]))
  112. })
  113. parmas.set('x-oss-process', list.join('/'))
  114. return target.toString()
  115. } catch (error) {
  116. console.error(error)
  117. return url
  118. }
  119. }
  120. export function createWaterMarkText(text: string) {
  121. return encBase64Url.stringify(encUtf8.parse(text))
  122. }
  123. export function splitText(text: string) {
  124. if (!text) return ''
  125. const reg = /^[\u0000-\u00ff]$/
  126. const len = text.length
  127. let result = ''
  128. let count = 0
  129. for (let i = 0; i < len; i += 1) {
  130. const char = text.charAt(i)
  131. count += reg.test(char) ? 1 : 2
  132. if (count === 32 && i === len - 1) {
  133. result += char
  134. break
  135. } else if (count > 29) {
  136. result += '...'
  137. break
  138. } else {
  139. result += char
  140. }
  141. }
  142. return result
  143. }