mirror of
				https://github.com/pure-admin/vue-pure-admin.git
				synced 2025-11-03 13:44:47 +08:00 
			
		
		
		
	Merge branch 'main' of github.com:pure-admin/vue-pure-admin into gitee
This commit is contained in:
		
						commit
						c0ec81b669
					
				@ -27,6 +27,7 @@ const include = [
 | 
				
			|||||||
  "vue3-danmaku",
 | 
					  "vue3-danmaku",
 | 
				
			||||||
  "v-contextmenu",
 | 
					  "v-contextmenu",
 | 
				
			||||||
  "vue-pdf-embed",
 | 
					  "vue-pdf-embed",
 | 
				
			||||||
 | 
					  "wavesurfer.js",
 | 
				
			||||||
  "china-area-data",
 | 
					  "china-area-data",
 | 
				
			||||||
  "vue-json-pretty",
 | 
					  "vue-json-pretty",
 | 
				
			||||||
  "@logicflow/core",
 | 
					  "@logicflow/core",
 | 
				
			||||||
 | 
				
			|||||||
@ -68,6 +68,7 @@ menus:
 | 
				
			|||||||
  hsguide: Guide
 | 
					  hsguide: Guide
 | 
				
			||||||
  hsAble: Able
 | 
					  hsAble: Able
 | 
				
			||||||
  hsMenuTree: Menu Tree
 | 
					  hsMenuTree: Menu Tree
 | 
				
			||||||
 | 
					  hsWavesurfer: Audio Visualization
 | 
				
			||||||
  hsOptimize: Debounce、Throttle、Copy、Longpress Directives
 | 
					  hsOptimize: Debounce、Throttle、Copy、Longpress Directives
 | 
				
			||||||
  hsWatermark: Water Mark
 | 
					  hsWatermark: Water Mark
 | 
				
			||||||
  hsPrint: Print
 | 
					  hsPrint: Print
 | 
				
			||||||
 | 
				
			|||||||
@ -68,6 +68,7 @@ menus:
 | 
				
			|||||||
  hsguide: 引导页
 | 
					  hsguide: 引导页
 | 
				
			||||||
  hsAble: 功能
 | 
					  hsAble: 功能
 | 
				
			||||||
  hsMenuTree: 菜单树结构
 | 
					  hsMenuTree: 菜单树结构
 | 
				
			||||||
 | 
					  hsWavesurfer: 音频可视化
 | 
				
			||||||
  hsOptimize: 防抖、截流、复制、长按指令
 | 
					  hsOptimize: 防抖、截流、复制、长按指令
 | 
				
			||||||
  hsWatermark: 水印
 | 
					  hsWatermark: 水印
 | 
				
			||||||
  hsPrint: 打印
 | 
					  hsPrint: 打印
 | 
				
			||||||
 | 
				
			|||||||
@ -34,7 +34,7 @@
 | 
				
			|||||||
    "@logicflow/extension": "^1.2.9",
 | 
					    "@logicflow/extension": "^1.2.9",
 | 
				
			||||||
    "@pureadmin/descriptions": "^1.1.1",
 | 
					    "@pureadmin/descriptions": "^1.1.1",
 | 
				
			||||||
    "@pureadmin/table": "^2.3.2",
 | 
					    "@pureadmin/table": "^2.3.2",
 | 
				
			||||||
    "@pureadmin/utils": "^1.9.6",
 | 
					    "@pureadmin/utils": "^1.9.7",
 | 
				
			||||||
    "@vueuse/core": "^10.2.0",
 | 
					    "@vueuse/core": "^10.2.0",
 | 
				
			||||||
    "@vueuse/motion": "^2.0.0",
 | 
					    "@vueuse/motion": "^2.0.0",
 | 
				
			||||||
    "@wangeditor/editor": "^5.1.23",
 | 
					    "@wangeditor/editor": "^5.1.23",
 | 
				
			||||||
@ -78,6 +78,7 @@
 | 
				
			|||||||
    "vue-waterfall-plugin-next": "^2.2.1",
 | 
					    "vue-waterfall-plugin-next": "^2.2.1",
 | 
				
			||||||
    "vue3-danmaku": "^1.4.0",
 | 
					    "vue3-danmaku": "^1.4.0",
 | 
				
			||||||
    "vuedraggable": "^4.1.0",
 | 
					    "vuedraggable": "^4.1.0",
 | 
				
			||||||
 | 
					    "wavesurfer.js": "^7.0.3",
 | 
				
			||||||
    "xgplayer": "^3.0.4",
 | 
					    "xgplayer": "^3.0.4",
 | 
				
			||||||
    "xlsx": "^0.18.5"
 | 
					    "xlsx": "^0.18.5"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										8552
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8552
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								public/audio/海阔天空.mp3
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								public/audio/海阔天空.mp3
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							@ -10,13 +10,21 @@ export default {
 | 
				
			|||||||
    rank: able
 | 
					    rank: able
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  children: [
 | 
					  children: [
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      path: "/able/wavesurfer",
 | 
				
			||||||
 | 
					      name: "Wavesurfer",
 | 
				
			||||||
 | 
					      component: () => import("@/views/able/wavesurfer/index.vue"),
 | 
				
			||||||
 | 
					      meta: {
 | 
				
			||||||
 | 
					        title: $t("menus.hsWavesurfer"),
 | 
				
			||||||
 | 
					        extraIcon: "IF-pure-iconfont-new svg"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      path: "/able/directives",
 | 
					      path: "/able/directives",
 | 
				
			||||||
      name: "Directives",
 | 
					      name: "Directives",
 | 
				
			||||||
      component: () => import("@/views/able/directives.vue"),
 | 
					      component: () => import("@/views/able/directives.vue"),
 | 
				
			||||||
      meta: {
 | 
					      meta: {
 | 
				
			||||||
        title: $t("menus.hsOptimize"),
 | 
					        title: $t("menus.hsOptimize")
 | 
				
			||||||
        extraIcon: "IF-pure-iconfont-new svg"
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										139
									
								
								src/views/able/wavesurfer/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								src/views/able/wavesurfer/index.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,139 @@
 | 
				
			|||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import WaveSurfer from "wavesurfer.js";
 | 
				
			||||||
 | 
					import { getTime } from "@pureadmin/utils";
 | 
				
			||||||
 | 
					import { Play, Pause, Forward, Rewind } from "./svg";
 | 
				
			||||||
 | 
					import { ref, onMounted, onBeforeUnmount } from "vue";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "tippy.js/dist/tippy.css";
 | 
				
			||||||
 | 
					import "tippy.js/animations/scale.css";
 | 
				
			||||||
 | 
					import { directive as tippy } from "vue-tippy";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					defineOptions({
 | 
				
			||||||
 | 
					  name: "Wavesurfer"
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const vTippy = tippy;
 | 
				
			||||||
 | 
					const loading = ref(true);
 | 
				
			||||||
 | 
					const wavesurfer = ref(null);
 | 
				
			||||||
 | 
					const wavesurferRef = ref();
 | 
				
			||||||
 | 
					// 音频总时长
 | 
				
			||||||
 | 
					const totalTime = ref();
 | 
				
			||||||
 | 
					// 音频当前播放位置时长
 | 
				
			||||||
 | 
					const curTime = ref();
 | 
				
			||||||
 | 
					// 音频是否正在播放
 | 
				
			||||||
 | 
					const isPlay = ref(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function init() {
 | 
				
			||||||
 | 
					  wavesurfer.value = WaveSurfer.create({
 | 
				
			||||||
 | 
					    container: wavesurferRef.value,
 | 
				
			||||||
 | 
					    height: "auto",
 | 
				
			||||||
 | 
					    waveColor: "rgb(200, 0, 200)",
 | 
				
			||||||
 | 
					    progressColor: "rgb(100, 0, 100)",
 | 
				
			||||||
 | 
					    cursorColor: "rgb(64, 158, 255)",
 | 
				
			||||||
 | 
					    cursorWidth: 4,
 | 
				
			||||||
 | 
					    // backend: "MediaElement",
 | 
				
			||||||
 | 
					    url: "/audio/海阔天空.mp3"
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // 音频被解码后触发
 | 
				
			||||||
 | 
					  wavesurfer.value.on("decode", () => (loading.value = false));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // 当音频已解码并可以播放时触发
 | 
				
			||||||
 | 
					  wavesurfer.value.on("ready", () => {
 | 
				
			||||||
 | 
					    const { duration } = wavesurfer.value;
 | 
				
			||||||
 | 
					    const { m, s } = getTime(duration);
 | 
				
			||||||
 | 
					    totalTime.value = `${m}:${s}`;
 | 
				
			||||||
 | 
					    // 光标位置取中
 | 
				
			||||||
 | 
					    wavesurfer.value.setTime(duration / 2);
 | 
				
			||||||
 | 
					    // 设置音频音量(范围0-1)
 | 
				
			||||||
 | 
					    // wavesurfer.value.setVolume(1);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // 音频位置改变时,播放期间连续触发
 | 
				
			||||||
 | 
					  wavesurfer.value.on("timeupdate", timer => {
 | 
				
			||||||
 | 
					    const { m, s } = getTime(timer);
 | 
				
			||||||
 | 
					    curTime.value = `${m}:${s}`;
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // 音频播放时触发
 | 
				
			||||||
 | 
					  wavesurfer.value.on("play", () => (isPlay.value = true));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // 音频暂停时触发
 | 
				
			||||||
 | 
					  wavesurfer.value.on("pause", () => (isPlay.value = false));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					onMounted(init);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					onBeforeUnmount(() => {
 | 
				
			||||||
 | 
					  if (wavesurfer.value) {
 | 
				
			||||||
 | 
					    wavesurfer.value.destroy();
 | 
				
			||||||
 | 
					    wavesurfer.value = null;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <el-card shadow="never">
 | 
				
			||||||
 | 
					    <template #header>
 | 
				
			||||||
 | 
					      <div class="card-header">
 | 
				
			||||||
 | 
					        <span class="font-medium">
 | 
				
			||||||
 | 
					          音频可视化,采用开源的
 | 
				
			||||||
 | 
					          <el-link
 | 
				
			||||||
 | 
					            href="https://wavesurfer-js.org/"
 | 
				
			||||||
 | 
					            target="_blank"
 | 
				
			||||||
 | 
					            style="margin: 0 4px 5px; font-size: 16px"
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            wavesurfer.js
 | 
				
			||||||
 | 
					          </el-link>
 | 
				
			||||||
 | 
					          <span class="text-[red]">
 | 
				
			||||||
 | 
					            (温馨提示:音频默认最大声音,播放时请调低电脑声音,以免影响到您)
 | 
				
			||||||
 | 
					          </span>
 | 
				
			||||||
 | 
					        </span>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </template>
 | 
				
			||||||
 | 
					    <div
 | 
				
			||||||
 | 
					      v-loading="loading"
 | 
				
			||||||
 | 
					      class="w-8/12 !m-auto !mt-[20px]"
 | 
				
			||||||
 | 
					      element-loading-background="transparent"
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
 | 
					      <div ref="wavesurferRef" />
 | 
				
			||||||
 | 
					      <div class="flex justify-between" v-show="totalTime">
 | 
				
			||||||
 | 
					        <span class="text-[#81888f]">00:00</span>
 | 
				
			||||||
 | 
					        <h1 class="text-4xl mt-2">{{ curTime }}</h1>
 | 
				
			||||||
 | 
					        <span class="text-[#81888f]">{{ totalTime }}</span>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <div class="flex mt-2 w-[180px] justify-around m-auto" v-show="totalTime">
 | 
				
			||||||
 | 
					        <Rewind
 | 
				
			||||||
 | 
					          class="cursor-pointer"
 | 
				
			||||||
 | 
					          v-tippy="{
 | 
				
			||||||
 | 
					            content: '快退(可长按)',
 | 
				
			||||||
 | 
					            placement: 'bottom',
 | 
				
			||||||
 | 
					            animation: 'scale'
 | 
				
			||||||
 | 
					          }"
 | 
				
			||||||
 | 
					          v-longpress:0:100="() => wavesurfer?.skip(-1)"
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					        <div
 | 
				
			||||||
 | 
					          class="cursor-pointer"
 | 
				
			||||||
 | 
					          v-tippy="{
 | 
				
			||||||
 | 
					            content: isPlay ? '暂停' : '播放',
 | 
				
			||||||
 | 
					            placement: 'bottom',
 | 
				
			||||||
 | 
					            animation: 'scale'
 | 
				
			||||||
 | 
					          }"
 | 
				
			||||||
 | 
					          @click="wavesurfer?.playPause()"
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          <Play v-if="isPlay" v-motion-pop />
 | 
				
			||||||
 | 
					          <Pause v-else v-motion-pop />
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <Forward
 | 
				
			||||||
 | 
					          class="cursor-pointer"
 | 
				
			||||||
 | 
					          v-tippy="{
 | 
				
			||||||
 | 
					            content: '快进(可长按)',
 | 
				
			||||||
 | 
					            placement: 'bottom',
 | 
				
			||||||
 | 
					            animation: 'scale'
 | 
				
			||||||
 | 
					          }"
 | 
				
			||||||
 | 
					          v-longpress:0:100="() => wavesurfer?.skip(1)"
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </el-card>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
							
								
								
									
										1
									
								
								src/views/able/wavesurfer/svg/forward.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/views/able/wavesurfer/svg/forward.svg
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" class="icon" viewBox="0 0 1024 1024"><path fill="#409EFF" d="M515.5 91.5C747.4 91.5 936 280.1 936 512S747.4 932.5 515.5 932.5 95 743.9 95 512 283.6 91.5 515.5 91.5m0-87C235.2 4.5 8 231.7 8 512s227.2 507.5 507.5 507.5S1023 792.3 1023 512 795.8 4.5 515.5 4.5z"/><path fill="#81888f" d="m337.7 450.8 84.1 61.2-84.1 61.2V450.8m-28.8-115c-30.1 0-58.2 23.8-58.2 58.1v236.2c0 34.3 28.1 58.1 58.2 58.1 11.5 0 23.3-3.5 33.9-11.2l162.4-118.1c31.9-23.2 31.9-70.7 0-93.8L342.8 347c-10.6-7.7-22.4-11.2-33.9-11.2z"/><path fill="#81888f" d="m529.1 450.8 84.1 61.2-84.1 61.2V450.8m-28.8-115c-30.1 0-58.2 23.8-58.2 58.1v236.2c0 34.3 28.1 58.1 58.2 58.1 11.5 0 23.3-3.5 33.9-11.2l162.4-118.1c31.9-23.2 31.9-70.7 0-93.8L534.2 347c-10.6-7.7-22.4-11.2-33.9-11.2z"/><path fill="#81888f" d="M736.8 367c-24 0-43.5 19.5-43.5 43.5v203c0 24 19.5 43.5 43.5 43.5s43.5-19.5 43.5-43.5v-203c0-24-19.5-43.5-43.5-43.5z"/></svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 956 B  | 
							
								
								
									
										15
									
								
								src/views/able/wavesurfer/svg/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/views/able/wavesurfer/svg/index.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					import Play from "./play.svg?component";
 | 
				
			||||||
 | 
					import Pause from "./pause.svg?component";
 | 
				
			||||||
 | 
					import Forward from "./forward.svg?component";
 | 
				
			||||||
 | 
					import Rewind from "./rewind.svg?component";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export {
 | 
				
			||||||
 | 
					  /** 播放 */
 | 
				
			||||||
 | 
					  Play,
 | 
				
			||||||
 | 
					  /** 暂停 */
 | 
				
			||||||
 | 
					  Pause,
 | 
				
			||||||
 | 
					  /** 快进 */
 | 
				
			||||||
 | 
					  Forward,
 | 
				
			||||||
 | 
					  /** 快退 */
 | 
				
			||||||
 | 
					  Rewind
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										1
									
								
								src/views/able/wavesurfer/svg/pause.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/views/able/wavesurfer/svg/pause.svg
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" class="icon" viewBox="0 0 1024 1024"><path fill="#f56c6c" d="M512 42.667C252.793 42.667 42.667 252.793 42.667 512S252.793 981.333 512 981.333 981.333 771.207 981.333 512 771.207 42.667 512 42.667zM708.547 543.16l-266.667 176A37.333 37.333 0 0 1 384 688V336.033a37.333 37.333 0 0 1 57.893-31.16l266.667 176a37.333 37.333 0 0 1 0 62.32z"/></svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 406 B  | 
							
								
								
									
										1
									
								
								src/views/able/wavesurfer/svg/play.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/views/able/wavesurfer/svg/play.svg
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" class="icon" viewBox="0 0 1024 1024"><path fill="#409eff" d="M512 0C229.227 0 0 229.227 0 512s229.227 512 512 512 512-229.227 512-512S794.773 0 512 0zm-33.023 704.742c0 34.191-25.028 62.18-55.617 62.18s-55.618-27.975-55.618-62.18V319.258c0-34.19 25.028-62.18 55.618-62.18s55.617 27.975 55.617 62.18zm170.328 0c0 34.191-25.027 62.18-55.617 62.18s-55.617-27.975-55.617-62.18V319.258c0-34.19 25.027-62.18 55.617-62.18s55.617 27.975 55.617 62.18z"/></svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 514 B  | 
							
								
								
									
										1
									
								
								src/views/able/wavesurfer/svg/rewind.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/views/able/wavesurfer/svg/rewind.svg
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" class="icon" viewBox="0 0 1024 1024"><path fill="#409EFF" d="M512 90.3c231.9 0 420.5 188.6 420.5 420.5S743.9 931.3 512 931.3 91.5 742.7 91.5 510.8 280.1 90.3 512 90.3m0-87C231.7 3.3 4.5 230.5 4.5 510.8s227.2 507.5 507.5 507.5 507.5-227.2 507.5-507.5S792.3 3.3 512 3.3z"/><path fill="#81888f" d="M689.8 449.7V572l-84.1-61.2 84.1-61.1m28.8-115.1c-11.5 0-23.3 3.5-33.9 11.2L522.3 463.9c-31.9 23.2-31.9 70.6 0 93.8l162.4 118.1c10.6 7.7 22.4 11.2 33.9 11.2 30.1 0 58.2-23.8 58.2-58.1V392.7c0-34.3-28.1-58.1-58.2-58.1z"/><path fill="#81888f" d="M498.4 449.7V572l-84.1-61.2 84.1-61.1m28.8-115.1c-11.5 0-23.3 3.5-33.9 11.2L330.9 463.9c-31.9 23.2-31.9 70.6 0 93.8l162.4 118.1c10.6 7.7 22.4 11.2 33.9 11.2 30.1 0 58.2-23.8 58.2-58.1V392.7c0-34.3-28.1-58.1-58.2-58.1z"/><path fill="#81888f" d="M290.7 365.8c-24 0-43.5 19.5-43.5 43.5v203c0 24 19.5 43.5 43.5 43.5s43.5-19.5 43.5-43.5v-203c0-24-19.5-43.5-43.5-43.5z"/></svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 973 B  | 
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user