global-text-processor.js 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. import axios from 'axios'
  2. import Vue from 'vue'
  3. import { delayPerform } from 'js-perform-lock'
  4. const WindowsTranslateApi = 'https://jiasm.zfire.top/translate'
  5. // const WindowsTranslateApi = 'http://127.0.0.1:7001'
  6. // 数据过滤校验
  7. function isNumberRegex(str) {
  8. const regexPatterns = [
  9. /^\d+$/, // 纯数字
  10. /^\d*\.\d+$/, // 浮点数
  11. /^([01]\d|2[0-3]):([0-5]\d)$/, // 时间 (HH:MM)
  12. /^([01]\d|2[0-3]):([0-5]\d):([0-5]\d)$/, // 时间 (HH:MM:SS)
  13. /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/, // 完整时间戳
  14. /^[A-Za-z]+$/, // 纯字母
  15. /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]+$/, // 字母和数字
  16. /^(?=.*[A-Za-z])(?=.*[\p{P}\p{S}])[\p{L}\p{P}\p{S}]+$/u, // 字母和标点符号
  17. /^(?=.*\d)(?=.*[\p{P}\p{S}])[\d\p{P}\p{S}]+$/u, // 数字和标点符号
  18. /^[\p{P}\s\dA-Za-z]+$/u // 字母、数字和标点符号
  19. ]
  20. return regexPatterns.some(pattern => pattern.test(str)) || !!window.Vue_Translation_Of_Text_Old_Data[str]
  21. }
  22. // 文本转译请求
  23. function pushNewText(data) {
  24. return new Promise(function (r, j) {
  25. axios
  26. .post(WindowsTranslateApi + '/api/v1/common/translationOfText', data)
  27. .then(response => {
  28. if (response.data.code === 0) {
  29. var obj = {}
  30. var obj2 = {}
  31. response.data.data.map(val => {
  32. obj[val[0]] = val[1]
  33. obj2[val[1]] = true
  34. })
  35. window.Vue_Translation_Of_Text_Old_Data = { ...(window.Vue_Translation_Of_Text_Old_Data || {}), ...obj2 }
  36. window.Vue_Translation_Of_Text_Data = { ...(window.Vue_Translation_Of_Text_Data || {}), ...obj }
  37. r({ ...obj })
  38. }
  39. })
  40. .catch(j)
  41. })
  42. }
  43. var deferredReplacement = (function () {
  44. var allKeywords = []
  45. var keywords = []
  46. var zhixingfun = []
  47. var index = 0
  48. var index2 = 0
  49. const dInit = new delayPerform(250).refactor(function () {
  50. let len = index
  51. let len2 = index2
  52. let keywords_ = keywords.splice(0, len)
  53. let zhixingfun_ = zhixingfun.splice(0, len2)
  54. index -= len
  55. index2 -= len2
  56. if (keywords_.length > 0) {
  57. pushNewText({
  58. keywords: keywords_,
  59. targetLanguage: window?.Vue_Translation_Of_Text_Type
  60. }).then(data => {
  61. for (var i = 0; i < len2; i++) {
  62. zhixingfun_?.[i]?.()
  63. }
  64. })
  65. } else if (zhixingfun_.length > 0) {
  66. setTimeout(function () {
  67. for (var i = 0; i < len2; i++) {
  68. zhixingfun_?.[i]?.()
  69. }
  70. }, 250)
  71. }
  72. })
  73. return function (text, cb) {
  74. dInit()
  75. if (!allKeywords.includes(text)) {
  76. index++
  77. allKeywords.push(text)
  78. keywords.push(text)
  79. }
  80. index2++
  81. zhixingfun.push(cb)
  82. }
  83. })()
  84. export const GlobalTextProcessor = {
  85. install(Vue) {
  86. Vue.mixin({
  87. updated() {
  88. this.$nextTick(() => {
  89. this.processTextNodes(this.$el)
  90. this.autoSelect('uni-tabbar-bottom')
  91. })
  92. },
  93. methods: {
  94. // 通过class修改
  95. autoSelect(name) {
  96. document.querySelectorAll(`.${name}`).forEach(element => {
  97. this.processAbsolutely(element)
  98. })
  99. },
  100. // 通过标签名修改
  101. autoHtmlSelect(name) {
  102. document.getElementsByTagName(name).forEach(element => {
  103. this.processAbsolutely(element)
  104. })
  105. },
  106. processTextNodes(el) {
  107. // 遍历子节点并处理文本内容
  108. if (el.nodeType === Node.ELEMENT_NODE) {
  109. // 跳过 table-body中的td 元素
  110. if (el.nodeName.toLowerCase() === 'td') {
  111. return
  112. }
  113. Array.from(el.childNodes).forEach(child => {
  114. if (child.nodeType === Node.TEXT_NODE) {
  115. let text = child.textContent
  116. let _child = child
  117. if (text && !isNumberRegex(text.trim())) {
  118. try {
  119. if (window?.Vue_Translation_Of_Text_Data?.[text.trim()]) {
  120. child.textContent = window?.Vue_Translation_Of_Text_Data?.[text.trim()]
  121. } else if (text.trim()) {
  122. deferredReplacement(text.trim(), function () {
  123. if (window.Vue_Translation_Of_Text_Data[text.trim()]) {
  124. _child.textContent = window.Vue_Translation_Of_Text_Data[text.trim()]
  125. }
  126. })
  127. }
  128. } catch (error) {}
  129. }
  130. } else if (child.nodeName === 'INPUT' || child.nodeName === 'TEXTAREA' || child.nodeName === 'SELECT') {
  131. // 修改输入框和下拉框的 placeholder 内容
  132. let placeholder = child.getAttribute('placeholder')
  133. let _child = child
  134. if (placeholder && !isNumberRegex(placeholder.trim())) {
  135. try {
  136. if (window?.Vue_Translation_Of_Text_Data?.[placeholder.trim() + '']) {
  137. child.setAttribute('placeholder', window?.Vue_Translation_Of_Text_Data?.[placeholder.trim() + ''])
  138. } else if (placeholder.trim() + '') {
  139. deferredReplacement(placeholder.trim() + '', function () {
  140. if (window?.Vue_Translation_Of_Text_Data?.[placeholder.trim() + '']) {
  141. _child.setAttribute(
  142. 'placeholder',
  143. window?.Vue_Translation_Of_Text_Data?.[placeholder.trim() + '']
  144. )
  145. }
  146. })
  147. }
  148. } catch (error) {}
  149. }
  150. } else if (child?.classList?.contains?.('el-select')) {
  151. // 处理 class 为 el-select 的组件
  152. this.processSelect(child)
  153. } else {
  154. // 递归处理子节点
  155. this.processTextNodes(child)
  156. }
  157. })
  158. }
  159. },
  160. processSelect(el) {
  161. // 遍历子节点并处理文本内容
  162. if (el.nodeType === Node.ELEMENT_NODE) {
  163. Array.from(el.childNodes).forEach(child => {
  164. if (child.nodeName === 'INPUT') {
  165. // 修改输入框和下拉框的 placeholder 内容
  166. let value = child.value
  167. let _child = child
  168. if (value && !isNumberRegex(value.trim())) {
  169. try {
  170. if (window?.Vue_Translation_Of_Text_Data?.[value.trim() + '']) {
  171. child.value = window?.Vue_Translation_Of_Text_Data?.[value.trim() + '']
  172. } else if (value.trim() + '') {
  173. deferredReplacement(value.trim() + '', function () {
  174. if (window?.Vue_Translation_Of_Text_Data?.[value.trim() + '']) {
  175. _child.value = window?.Vue_Translation_Of_Text_Data?.[value.trim() + '']
  176. }
  177. })
  178. }
  179. } catch (error) {}
  180. }
  181. } else {
  182. // 递归处理子节点
  183. this.processSelect(child)
  184. }
  185. })
  186. }
  187. },
  188. processAbsolutely(el) {
  189. // 遍历子节点并处理文本内容
  190. if (el.nodeType === Node.ELEMENT_NODE) {
  191. Array.from(el.childNodes).forEach(child => {
  192. if (child.nodeType === Node.TEXT_NODE) {
  193. let text = child.textContent
  194. let _child = child
  195. if (text && !isNumberRegex(text.trim())) {
  196. try {
  197. if (window?.Vue_Translation_Of_Text_Data?.[text.trim()]) {
  198. child.textContent = window?.Vue_Translation_Of_Text_Data?.[text.trim()]
  199. } else if (text.trim()) {
  200. deferredReplacement(text.trim(), function () {
  201. if (window.Vue_Translation_Of_Text_Data[text.trim()]) {
  202. _child.textContent = window.Vue_Translation_Of_Text_Data[text.trim()]
  203. }
  204. })
  205. }
  206. } catch (error) {}
  207. }
  208. } else {
  209. // 递归处理子节点
  210. this.processAbsolutely(child)
  211. }
  212. })
  213. }
  214. }
  215. }
  216. })
  217. }
  218. }
  219. export function translaBeforeRegistration(cb) {
  220. window.Vue_Translation_Of_Text_Type = window.localStorage.getItem('Vue_Translation_Of_Text_Type')
  221. if (window?.Vue_Translation_Of_Text_Type && ['en', 'ar', 'ru', 'ja'].includes(window?.Vue_Translation_Of_Text_Type)) {
  222. Vue.use(GlobalTextProcessor) // 注册插件
  223. axios
  224. .post(WindowsTranslateApi + '/api/v1/common/readTranslationOfText', {
  225. targetLanguage: window?.Vue_Translation_Of_Text_Type
  226. })
  227. .then(({ data }) => {
  228. var obj = {}
  229. var obj2 = {}
  230. data?.data?.map(item => {
  231. obj[item.source] = item.target
  232. obj2[item.target] = true
  233. })
  234. window.Vue_Translation_Of_Text_Old_Data = { ...(window.Vue_Translation_Of_Text_Old_Data || {}), ...obj2 }
  235. window.Vue_Translation_Of_Text_Data = { ...(window.Vue_Translation_Of_Text_Data || {}), ...obj }
  236. cb?.()
  237. })
  238. .catch(error => {
  239. cb?.()
  240. })
  241. } else {
  242. cb?.()
  243. }
  244. }