mirror of
				https://github.com/XiaoDaiGua-Ray/ray-template.git
				synced 2025-10-31 16:32:34 +08:00 
			
		
		
		
	feat: v4.1.9补充qrcode组件
This commit is contained in:
		
							parent
							
								
									ccc4d6c710
								
							
						
					
					
						commit
						689813f1a0
					
				| @ -5,9 +5,11 @@ | ||||
| ### Feats | ||||
| 
 | ||||
| - 新增 RayQRCode 组件(二维码) | ||||
|   - 基于 awesome-qr 封装,继承其所有特性。并且拓展了 状态、下载、自动更新等属性 | ||||
|   - 基于 awesome-qr 封装,继承其所有特性。并且拓展 状态、下载、自动更新等属性 | ||||
|   - 自动卸载于释放内存,仅需要关注 text 内容填充 | ||||
| - 移除 qrcode.vue 依赖 | ||||
| - 更新 vue-hooks-plus 版本至 v1.8.2 | ||||
| - 移除 office 功能集成 | ||||
| 
 | ||||
| ### Fixes | ||||
| 
 | ||||
|  | ||||
| @ -1,21 +0,0 @@ | ||||
| ## 常见问题 | ||||
| 
 | ||||
| ### 路由 | ||||
| 
 | ||||
| #### 缓存失效 | ||||
| 
 | ||||
| > 如果出现缓存配置不生效的情况可以按照如下方法进行排查 | ||||
| 
 | ||||
| - 查看 APP_KEEP_ALIVE setupKeepAlive 属性是否配置为 true | ||||
| - 查看每个组件的 `name` 是否唯一,[`KeepAlive`](https://cn.vuejs.org/guide/built-ins/keep-alive.html) 组件重度依赖组件 `name` 作为唯一标识。详情可以查看官方文档 | ||||
| - 查看该页面的路由配置是否正确,比如:`path` 是否按照模板约定方式进行配置 | ||||
| 
 | ||||
| #### 自动导入失败 | ||||
| 
 | ||||
| > 模板采用自动导入路由模块方式。如果发现路由导入有误、或者导入报错,请查看文件命名是否有误。 | ||||
| 
 | ||||
| ### 国际化 | ||||
| 
 | ||||
| #### 国际化切换错误、警告 | ||||
| 
 | ||||
| > 模板二次封装 [`useI18n`](https://github.com/XiaoDaiGua-Ray/ray-template/blob/main/src/locales/useI18n.ts) 方法,首选该方法作为国际化语言切换方法。 | ||||
| @ -41,7 +41,7 @@ | ||||
|     "sass": "^1.54.3", | ||||
|     "screenfull": "^6.0.2", | ||||
|     "vue": "^3.3.4", | ||||
|     "vue-hooks-plus": "1.8.1", | ||||
|     "vue-hooks-plus": "1.8.2", | ||||
|     "vue-i18n": "^9.2.2", | ||||
|     "vue-router": "^4.2.4", | ||||
|     "vuedraggable": "^4.1.0", | ||||
|  | ||||
| @ -21,6 +21,35 @@ import { call } from '@/utils/vue/index' | ||||
| 
 | ||||
| import type { QRCodeRenderResponse } from './type' | ||||
| 
 | ||||
| const readGIFAsArrayBuffer = ( | ||||
|   url: string, | ||||
| ): Promise<string | ArrayBuffer | null> => { | ||||
|   return new Promise((resolve, reject) => { | ||||
|     const xhr = new XMLHttpRequest() | ||||
| 
 | ||||
|     xhr.responseType = 'blob' | ||||
| 
 | ||||
|     xhr.onload = () => { | ||||
|       const reader = new FileReader() | ||||
| 
 | ||||
|       reader.onloadend = () => { | ||||
|         resolve(reader.result) | ||||
|       } | ||||
|       reader.onerror = (e) => { | ||||
|         reject(e) | ||||
|       } | ||||
|       reader.onabort = (e) => { | ||||
|         reject(e) | ||||
|       } | ||||
| 
 | ||||
|       reader.readAsArrayBuffer(xhr.response) | ||||
|     } | ||||
| 
 | ||||
|     xhr.open('GET', url) | ||||
|     xhr.send() | ||||
|   }) | ||||
| } | ||||
| 
 | ||||
| const RayQRcode = defineComponent({ | ||||
|   name: 'RayQRcode', | ||||
|   props, | ||||
| @ -31,10 +60,28 @@ const RayQRcode = defineComponent({ | ||||
|     const spinOverrides = { | ||||
|       opacitySpinning: '0.1', | ||||
|     } | ||||
|     let gifBuffer: string | ArrayBuffer | null | ||||
| 
 | ||||
|     const getGIFImageByURL = async () => { | ||||
|       const { gifBackgroundURL } = props | ||||
| 
 | ||||
|       if (!gifBackgroundURL) { | ||||
|         return | ||||
|       } | ||||
| 
 | ||||
|       try { | ||||
|         gifBuffer = await readGIFAsArrayBuffer(gifBackgroundURL) | ||||
|       } catch (e) { | ||||
|         console.error(e) | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     const renderQRCode = () => { | ||||
|       const { gifBackgroundURL, gifBackground, ...ops } = props | ||||
| 
 | ||||
|       new AwesomeQR({ | ||||
|         ...props, | ||||
|         ...ops, | ||||
|         gifBackground: (gifBuffer as ArrayBuffer) ?? undefined, | ||||
|       }) | ||||
|         .draw() | ||||
|         .then((res) => { | ||||
| @ -85,7 +132,8 @@ const RayQRcode = defineComponent({ | ||||
|       downloadQRCode, | ||||
|     }) | ||||
| 
 | ||||
|     onMounted(() => { | ||||
|     onMounted(async () => { | ||||
|       await getGIFImageByURL() | ||||
|       renderQRCode() | ||||
|     }) | ||||
| 
 | ||||
|  | ||||
| @ -190,6 +190,15 @@ const props = { | ||||
|     type: String, | ||||
|     default: 'rgba(0, 0, 0, 0)', | ||||
|   }, | ||||
|   gifBackgroundURL: { | ||||
|     /** | ||||
|      * | ||||
|      * GIF background image to be used in the QR code | ||||
|      * | ||||
|      * @default undefined | ||||
|      */ | ||||
|     type: String, | ||||
|   }, | ||||
|   gifBackground: { | ||||
|     /** | ||||
|      * | ||||
| @ -249,6 +258,17 @@ const props = { | ||||
|     type: Number, | ||||
|     default: 8, | ||||
|   }, | ||||
|   dotScale: { | ||||
|     /** | ||||
|      * | ||||
|      * Ratio of the real size to the full size of the blocks. | ||||
|      * This can be helpful when you want to make more parts of the background visible. | ||||
|      * | ||||
|      * @default 1 | ||||
|      */ | ||||
|     type: Number, | ||||
|     default: 1, | ||||
|   }, | ||||
|   onSuccess: { | ||||
|     /** | ||||
|      * | ||||
|  | ||||
| @ -388,7 +388,7 @@ const MenuTag = defineComponent({ | ||||
|         if (tags?.length) { | ||||
|           const [menuTag] = tags | ||||
| 
 | ||||
|           nextTick(() => { | ||||
|           nextTick().then(() => { | ||||
|             menuTag.scrollIntoView?.() | ||||
|           }) | ||||
|         } | ||||
|  | ||||
| @ -1,27 +0,0 @@ | ||||
| /** | ||||
|  * | ||||
|  * @author Ray <https://github.com/XiaoDaiGua-Ray>
 | ||||
|  * | ||||
|  * @date 2023-03-22 | ||||
|  * | ||||
|  * @workspace ray-template | ||||
|  * | ||||
|  * @remark 今天也是元气满满撸代码的一天 | ||||
|  */ | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * onlyoffice | ||||
|  * | ||||
|  * 该功能暂未实现, 后续应该会补上 | ||||
|  * 由于该方法需要后端进行相关配合, 因为目前还在考虑是否接上私有 onlyoffice 服务器, 所以该功能暂未实现 | ||||
|  * 望多多理解, 理解万岁 | ||||
|  */ | ||||
| 
 | ||||
| import { getAppEnvironment } from '@use-utils/hook' | ||||
| import request from '@/axios/instance' | ||||
| 
 | ||||
| export const getOfficeDocumentApi = async (uuid: string) => { | ||||
|   const { VITE_APP_OFFICE_PROXY_URL } = getAppEnvironment() | ||||
|   const { get } = request | ||||
| } | ||||
| @ -1,43 +0,0 @@ | ||||
| import { t } from '@/locales/useI18n' | ||||
| import { LAYOUT } from '@/router/constant/index' | ||||
| 
 | ||||
| import type { AppRouteRecordRaw } from '@/router/type' | ||||
| 
 | ||||
| const office: AppRouteRecordRaw = { | ||||
|   path: '/office', | ||||
|   name: 'ROffice', | ||||
|   component: () => import('@/views/demo/office/index'), | ||||
|   meta: { | ||||
|     i18nKey: t('menu.Office'), | ||||
|     icon: 'office', | ||||
|     hidden: true, | ||||
|   }, | ||||
|   children: [ | ||||
|     { | ||||
|       path: 'document', | ||||
|       name: 'Document', | ||||
|       component: () => import('@/views/demo/office/views/document/index'), | ||||
|       meta: { | ||||
|         i18nKey: 'Office_Document', | ||||
|       }, | ||||
|     }, | ||||
|     { | ||||
|       path: 'presentation', | ||||
|       name: 'Presentation', | ||||
|       component: () => import('@/views/demo/office/views/presentation/index'), | ||||
|       meta: { | ||||
|         i18nKey: 'Office_Presentation', | ||||
|       }, | ||||
|     }, | ||||
|     { | ||||
|       path: 'spreadsheet', | ||||
|       name: 'Spreadsheet', | ||||
|       component: () => import('@/views/demo/office/views/spreadsheet/index'), | ||||
|       meta: { | ||||
|         i18nKey: 'Office_Spreadsheet', | ||||
|       }, | ||||
|     }, | ||||
|   ], | ||||
| } | ||||
| 
 | ||||
| export default office | ||||
| @ -1,21 +0,0 @@ | ||||
| /** | ||||
|  * | ||||
|  * @author Ray <https://github.com/XiaoDaiGua-Ray>
 | ||||
|  * | ||||
|  * @date 2023-03-22 | ||||
|  * | ||||
|  * @workspace ray-template | ||||
|  * | ||||
|  * @remark 今天也是元气满满撸代码的一天 | ||||
|  */ | ||||
| 
 | ||||
| import { RouterView } from 'vue-router' | ||||
| 
 | ||||
| const Office = defineComponent({ | ||||
|   name: 'ROffice', | ||||
|   render() { | ||||
|     return <RouterView /> | ||||
|   }, | ||||
| }) | ||||
| 
 | ||||
| export default Office | ||||
| @ -1,47 +0,0 @@ | ||||
| /** | ||||
|  * | ||||
|  * @author Ray <https://github.com/XiaoDaiGua-Ray>
 | ||||
|  * | ||||
|  * @date 2023-03-22 | ||||
|  * | ||||
|  * @workspace ray-template | ||||
|  * | ||||
|  * @remark 今天也是元气满满撸代码的一天 | ||||
|  */ | ||||
| 
 | ||||
| import { uuid } from '@/utils/hook' | ||||
| 
 | ||||
| import type { PropType } from 'vue' | ||||
| 
 | ||||
| const Document = defineComponent({ | ||||
|   name: 'RDocument', | ||||
|   setup() { | ||||
|     const editorUUID = uuid(16) | ||||
|     const state = reactive({}) | ||||
|     const config = { | ||||
|       document: { | ||||
|         fileType: 'docx', | ||||
|         key: editorUUID, | ||||
|         title: 'Example Document Title.docx', | ||||
|         url: 'https://example.com/url-to-example-document.docx', | ||||
|       }, | ||||
|       documentType: 'word', | ||||
|       authorization: 'a2122252', | ||||
|       token: 'a2122252', | ||||
|       Authorization: 'a2122252', | ||||
|       editorConfig: { | ||||
|         lang: 'zh-cn', | ||||
|       }, | ||||
|     } | ||||
| 
 | ||||
|     return { | ||||
|       ...toRefs(state), | ||||
|       editorUUID, | ||||
|     } | ||||
|   }, | ||||
|   render() { | ||||
|     return <div> </div> | ||||
|   }, | ||||
| }) | ||||
| 
 | ||||
| export default Document | ||||
| @ -1,24 +0,0 @@ | ||||
| /** | ||||
|  * | ||||
|  * @author Ray <https://github.com/XiaoDaiGua-Ray>
 | ||||
|  * | ||||
|  * @date 2023-03-22 | ||||
|  * | ||||
|  * @workspace ray-template | ||||
|  * | ||||
|  * @remark 今天也是元气满满撸代码的一天 | ||||
|  */ | ||||
| 
 | ||||
| import type { PropType } from 'vue' | ||||
| 
 | ||||
| const Presentation = defineComponent({ | ||||
|   name: 'RPresentation', | ||||
|   setup() { | ||||
|     return {} | ||||
|   }, | ||||
|   render() { | ||||
|     return <div></div> | ||||
|   }, | ||||
| }) | ||||
| 
 | ||||
| export default Presentation | ||||
| @ -1,24 +0,0 @@ | ||||
| /** | ||||
|  * | ||||
|  * @author Ray <https://github.com/XiaoDaiGua-Ray>
 | ||||
|  * | ||||
|  * @date 2023-03-22 | ||||
|  * | ||||
|  * @workspace ray-template | ||||
|  * | ||||
|  * @remark 今天也是元气满满撸代码的一天 | ||||
|  */ | ||||
| 
 | ||||
| import type { PropType } from 'vue' | ||||
| 
 | ||||
| const Spreadsheet = defineComponent({ | ||||
|   name: 'RSpreadsheet', | ||||
|   setup() { | ||||
|     return {} | ||||
|   }, | ||||
|   render() { | ||||
|     return <div></div> | ||||
|   }, | ||||
| }) | ||||
| 
 | ||||
| export default Spreadsheet | ||||
| @ -43,6 +43,12 @@ const RQRCode = defineComponent({ | ||||
|           <NSpace> | ||||
|             <RayQRcode text="ray template yes" /> | ||||
|             <RayQRcode text="ray template yes" logoImage={LOGO} /> | ||||
|             <RayQRcode | ||||
|               text="ray template yes" | ||||
|               gifBackgroundURL="https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif?imageView2/1/w/80/h/80" | ||||
|               dotScale={0.5} | ||||
|               colorDark="#64d9d6" | ||||
|             /> | ||||
|           </NSpace> | ||||
|         </NCard> | ||||
|         <NCard title="状态二维码"> | ||||
|  | ||||
| @ -115,6 +115,7 @@ export default defineConfig(async ({ mode }) => { | ||||
|         fix: true, | ||||
|         exclude: ['dist/**', '**/node_modules/**', 'vite-env.d.ts', '*.md'], | ||||
|         include: ['src/**/*.{vue,js,jsx,ts,tsx}'], | ||||
|         cache: true, | ||||
|       }), | ||||
|       vitePluginImp({ | ||||
|         libList: [ | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user