Просмотр исходного кода

减少代码量 使代码更优雅

刘冰洁 1 год назад
Родитель
Сommit
22fadc8819

+ 4 - 1
package.json

@@ -83,11 +83,14 @@
     "vue": "3.3.4",
     "vue-i18n": "^9.2.2",
     "vue-monoplasty-slide-verify": "^1.3.1",
+    "vue-pdf-embed": "^1.1.6",
     "vue-router": "^4.2.1",
     "vue-slider-vertify": "^0.0.1",
+    "vue3-pdfjs": "^0.1.6",
     "vuedraggable": "^4.1.0",
     "wangeditor": "^4.7.15",
-    "xgplayer": "^3.0.2"
+    "xgplayer": "^3.0.2",
+    "xlsx": "^0.18.5"
   },
   "devDependencies": {
     "@amap/amap-jsapi-types": "^0.0.13",

+ 109 - 0
pnpm-lock.yaml

@@ -94,12 +94,18 @@ dependencies:
   vue-monoplasty-slide-verify:
     specifier: ^1.3.1
     version: 1.3.1
+  vue-pdf-embed:
+    specifier: ^1.1.6
+    version: 1.1.6(vue@3.3.4)
   vue-router:
     specifier: ^4.2.1
     version: 4.2.1(vue@3.3.4)
   vue-slider-vertify:
     specifier: ^0.0.1
     version: 0.0.1
+  vue3-pdfjs:
+    specifier: ^0.1.6
+    version: 0.1.6
   vuedraggable:
     specifier: ^4.1.0
     version: 4.1.0(vue@3.3.4)
@@ -109,6 +115,9 @@ dependencies:
   xgplayer:
     specifier: ^3.0.2
     version: 3.0.2(core-js@3.30.1)
+  xlsx:
+    specifier: ^0.18.5
+    version: 0.18.5
 
 devDependencies:
   '@amap/amap-jsapi-types':
@@ -4627,6 +4636,11 @@ packages:
     engines: {node: '>= 10.0.0'}
     dev: false
 
+  /adler-32@1.3.1:
+    resolution: {integrity: sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==}
+    engines: {node: '>=0.8'}
+    dev: false
+
   /agent-base@6.0.2:
     resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
     engines: {node: '>= 6.0.0'}
@@ -5260,6 +5274,14 @@ packages:
     resolution: {integrity: sha512-8aUpZ7sjhlOyiNsg+pgcrTTPUXKh+rg544QYHSvQErljVEKJzvkYkCR/hUFeeVoEfTToUtY9cUKNRC7+c45YkA==}
     dev: true
 
+  /cfb@1.2.2:
+    resolution: {integrity: sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==}
+    engines: {node: '>=0.8'}
+    dependencies:
+      adler-32: 1.3.1
+      crc-32: 1.2.2
+    dev: false
+
   /chalk@1.1.3:
     resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==}
     engines: {node: '>=0.10.0'}
@@ -5399,6 +5421,11 @@ packages:
     resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==}
     engines: {node: '>=0.8'}
 
+  /codepage@1.15.0:
+    resolution: {integrity: sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==}
+    engines: {node: '>=0.8'}
+    dev: false
+
   /collection-visit@1.0.0:
     resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==}
     engines: {node: '>=0.10.0'}
@@ -5755,6 +5782,12 @@ packages:
       '@xmldom/xmldom': 0.8.7
     dev: false
 
+  /crc-32@1.2.2:
+    resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==}
+    engines: {node: '>=0.8'}
+    hasBin: true
+    dev: false
+
   /cropperjs@1.5.13:
     resolution: {integrity: sha512-by7jKAo73y5/Do0K6sxdTKHgndY0NMjG2bEdgeJxycbcmHuCiMXqw8sxy5C5Y5WTOTcDGmbT7Sr5CgKOXR06OA==}
     dev: false
@@ -6294,6 +6327,11 @@ packages:
       domelementtype: 2.3.0
     dev: true
 
+  /dommatrix@1.0.3:
+    resolution: {integrity: sha512-l32Xp/TLgWb8ReqbVJAFIvXmY7go4nTxxlWiAFyhoQw9RKEOHBZNnyGvJWqDVSPmq3Y9HlM4npqF/T6VMOXhww==}
+    deprecated: dommatrix is no longer maintained. Please use @thednp/dommatrix.
+    dev: false
+
   /domutils@1.7.0:
     resolution: {integrity: sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==}
     dependencies:
@@ -7584,6 +7622,11 @@ packages:
     engines: {node: '>=10'}
     dev: true
 
+  /frac@1.1.2:
+    resolution: {integrity: sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==}
+    engines: {node: '>=0.8'}
+    dev: false
+
   /fragment-cache@0.2.1:
     resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==}
     engines: {node: '>=0.10.0'}
@@ -10349,6 +10392,18 @@ packages:
       through: 2.3.8
     dev: false
 
+  /pdfjs-dist@2.16.105:
+    resolution: {integrity: sha512-J4dn41spsAwUxCpEoVf6GVoz908IAA3mYiLmNxg8J9kfRXc2jxpbUepcP0ocp0alVNLFthTAM8DZ1RaHh8sU0A==}
+    peerDependencies:
+      worker-loader: ^3.0.8
+    peerDependenciesMeta:
+      worker-loader:
+        optional: true
+    dependencies:
+      dommatrix: 1.0.3
+      web-streams-polyfill: 3.2.1
+    dev: false
+
   /perfect-debounce@1.0.0:
     resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==}
     dev: true
@@ -11564,6 +11619,13 @@ packages:
       through: 2.3.8
     dev: true
 
+  /ssf@0.11.2:
+    resolution: {integrity: sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==}
+    engines: {node: '>=0.8'}
+    dependencies:
+      frac: 1.1.2
+    dev: false
+
   /ssr-window@3.0.0:
     resolution: {integrity: sha512-q+8UfWDg9Itrg0yWK7oe5p/XRCJpJF9OBtXfOPgSJl+u3Xd5KI328RUEvUqSMVM9CiQUEf1QdBzJMkYGErj9QA==}
     dev: false
@@ -12842,6 +12904,14 @@ packages:
       vue: 2.7.14
     dev: false
 
+  /vue-pdf-embed@1.1.6(vue@3.3.4):
+    resolution: {integrity: sha512-CRQIw8OxiD6H1n8KT2zVWbp/00fA3PgSV/JYJ0Ut+FdC1jHrRDHNBj3BvaRVwZFZg3EJ8LLjyEDYxWWUMOjrDw==}
+    peerDependencies:
+      vue: ^2.x || ^3.x
+    dependencies:
+      vue: 3.3.4
+    dev: false
+
   /vue-router@4.2.1(vue@3.3.4):
     resolution: {integrity: sha512-nW28EeifEp8Abc5AfmAShy5ZKGsGzjcnZ3L1yc2DYUo+MqbBClrRP9yda3dIekM4I50/KnEwo1wkBLf7kHH5Cw==}
     peerDependencies:
@@ -12877,6 +12947,16 @@ packages:
       typescript: 5.0.4
     dev: true
 
+  /vue3-pdfjs@0.1.6:
+    resolution: {integrity: sha512-7UaWbsp8wNqB0y/rRlyo5yRb0S+XOkkSpmdUuS267Dhi07Pt4RFEetQ8inrpf/aTFJwGnW0Uc/UE4p376s+Zmw==}
+    engines: {node: '>=10.0.0'}
+    dependencies:
+      pdfjs-dist: 2.16.105
+      vue: 3.3.4
+    transitivePeerDependencies:
+      - worker-loader
+    dev: false
+
   /vue@2.7.14:
     resolution: {integrity: sha512-b2qkFyOM0kwqWFuQmgd4o+uHGU7T+2z3T+WQp8UBjADfEv2n4FEMffzBmCKNP0IGzOEEfYjvtcC62xaSKeQDrQ==}
     dependencies:
@@ -12934,6 +13014,11 @@ packages:
       tslib: 2.5.0
     dev: false
 
+  /web-streams-polyfill@3.2.1:
+    resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==}
+    engines: {node: '>= 8'}
+    dev: false
+
   /webidl-conversions@4.0.2:
     resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==}
     dev: true
@@ -13017,6 +13102,11 @@ packages:
       semver: 5.7.1
     dev: false
 
+  /wmf@1.0.2:
+    resolution: {integrity: sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==}
+    engines: {node: '>=0.8'}
+    dev: false
+
   /wolfy87-eventemitter@5.2.9:
     resolution: {integrity: sha512-P+6vtWyuDw+MB01X7UeF8TaHBvbCovf4HPEMF/SV7BdDc1SMTiBy13SRD71lQh4ExFTG1d/WNzDGDCyOKSMblw==}
     dev: false
@@ -13025,6 +13115,11 @@ packages:
     resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==}
     engines: {node: '>=0.10.0'}
 
+  /word@0.3.0:
+    resolution: {integrity: sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==}
+    engines: {node: '>=0.8'}
+    dev: false
+
   /wordwrap@1.0.0:
     resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==}
     dev: true
@@ -13241,6 +13336,20 @@ packages:
       xgplayer-subtitles: 1.1.1(core-js@3.30.1)
     dev: false
 
+  /xlsx@0.18.5:
+    resolution: {integrity: sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==}
+    engines: {node: '>=0.8'}
+    hasBin: true
+    dependencies:
+      adler-32: 1.3.1
+      cfb: 1.2.2
+      codepage: 1.15.0
+      crc-32: 1.2.2
+      ssf: 0.11.2
+      wmf: 1.0.2
+      word: 0.3.0
+    dev: false
+
   /xml-name-validator@4.0.0:
     resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==}
     engines: {node: '>=12'}

+ 12 - 17
src/App.vue

@@ -1,17 +1,12 @@
 <template>
-  <n-config-provider
-    :theme="theme.naiveTheme"
-    :theme-overrides="theme.naiveThemeOverrides"
-    :locale="zhCN"
-    :date-locale="dateZhCN"
-    class="h-full"
-  >
-    <naive-provider>
-      <fs-ui-context>
-        <router-view />
-      </fs-ui-context>
-    </naive-provider>
-  </n-config-provider>
+	<n-config-provider :theme="theme.naiveTheme" :theme-overrides="theme.naiveThemeOverrides" :locale="zhCN"
+		:date-locale="dateZhCN" class="h-full">
+		<naive-provider>
+			<fs-ui-context>
+				<router-view />
+			</fs-ui-context>
+		</naive-provider>
+	</n-config-provider>
 </template>
 
 <script setup lang="ts">
@@ -30,10 +25,10 @@ subscribeStore();
 useGlobalEvents();
 
 watch(
-  () => locale.value,
-  () => {
-    document.title = route.meta.i18nTitle ? t(route.meta.i18nTitle) : route.meta.title;
-  }
+	() => locale.value,
+	() => {
+		document.title = route.meta.i18nTitle ? t(route.meta.i18nTitle) : route.meta.title;
+	}
 );
 </script>
 

+ 121 - 0
src/components/View/pdfPreview.vue

@@ -0,0 +1,121 @@
+<template>
+	<div class="pdf-preview">
+		<div class="pdf-wrap">
+			<vue-pdf-embed :source="state.source" :style="scale" class="vue-pdf-embed" :page="state.pageNum" />
+		</div>
+		<div class="page-tool">
+			<div class="page-tool-item" @click="lastPage">上一页</div>
+			<div class="page-tool-item" @click="nextPage">下一页</div>
+			<div class="page-tool-item">{{ state.pageNum }}/{{ state.numPages }}</div>
+			<div class="page-tool-item" @click="pageZoomOut">放大</div>
+			<div class="page-tool-item" @click="pageZoomIn">缩小</div>
+		</div>
+	</div>
+</template>
+<script setup lang="ts">
+import VuePdfEmbed from "vue-pdf-embed";
+import { createLoadingTask } from "vue3-pdfjs";
+import { reactive, onMounted, computed } from "vue";
+
+const props = defineProps({
+	pdfUrl: {
+		type: String,
+		required: true
+	}
+})
+const state = reactive({
+	source: props.pdfUrl,
+	pageNum: 1,
+	scale: 1, // 缩放比例
+	numPages: 0, // 总页数
+});
+
+const scale = computed(() => `transform:scale(${state.scale})`)
+function lastPage() {
+	if (state.pageNum > 1) {
+		state.pageNum -= 1;
+	}
+}
+function nextPage() {
+	if (state.pageNum < state.numPages) {
+		state.pageNum += 1;
+	}
+}
+function pageZoomOut() {
+	if (state.scale < 2) {
+		state.scale += 0.1;
+	}
+}
+function pageZoomIn() {
+	if (state.scale > 1) {
+		state.scale -= 0.1;
+	}
+}
+
+onMounted(() => {
+	const loadingTask = createLoadingTask(state.source);
+	loadingTask.promise.then((pdf: { numPages: number }) => {
+		state.numPages = pdf.numPages;
+	});
+});
+
+</script>
+<style lang="css" scoped>
+.pdf-preview {
+	position: relative;
+	height: 100vh;
+	padding: 20px 0;
+	box-sizing: border-box;
+	background: rgb(66, 66, 66);
+}
+
+.vue-pdf-embed {
+	text-align: center;
+	width: 515px;
+	border: 1px solid #e5e5e5;
+	margin: 0 auto;
+	box-sizing: border-box;
+}
+
+.pdf-preview {
+	position: relative;
+	height: 100vh;
+	padding: 20px 0;
+	box-sizing: border-box;
+	background-color: e9e9e9;
+}
+
+.pdf-wrap {
+	overflow-y: auto;
+}
+
+.vue-pdf-embed {
+	text-align: center;
+	width: 515px;
+	border: 1px solid #e5e5e5;
+	margin: 0 auto;
+	box-sizing: border-box;
+}
+
+.page-tool {
+	position: absolute;
+	bottom: 35px;
+	padding-left: 15px;
+	padding-right: 15px;
+	display: flex;
+	align-items: center;
+	background: rgb(66, 66, 66);
+	color: white;
+	border-radius: 19px;
+	z-index: 100;
+	cursor: pointer;
+	margin-left: 50%;
+	transform: translateX(-50%);
+}
+
+.page-tool-item {
+	padding: 8px 15px;
+	padding-left: 10px;
+	cursor: pointer;
+}
+</style>


+ 5 - 0
src/views/dashboard/analysis/index.vue

@@ -2,12 +2,17 @@
   <n-space :vertical="true" :size="16">
     <top-chart />
     <data-card />
+		<div>
+			<PDFView :pdfUrl="jsPdf" />
+		</div>
     <bottom-part />
   </n-space>
 </template>
 
 <script lang="ts" setup>
 import { BottomPart, DataCard, TopChart } from './components';
+import PDFView from "../../.././components/View/pdfPreview.vue"
+import jsPdf from "../../../java.pdf"
 </script>
 
 <style scoped></style>

+ 9 - 22
src/views/management/sort/index.vue

@@ -49,12 +49,15 @@
 				</n-space>
 				<n-data-table :columns="columns" :data="tableData" :loading="loading" :row-key="rowKey"
 					@update:checked-row-keys="handleCheck" />
-				<n-pagination  class="flex-justify-end"  v-model:page="pagination.page"  v-model:page-size="pagination.pageSize" :item-count="pagination.itemCount"    show-size-picker :page-sizes="[10, 20, 30, 40]" @change="onChange" @page-size-change="onUpdatePageSize"/>
+				<n-pagination  class="flex-justify-end"  v-model:page="pagination.page"  v-model:page-size="pagination.pageSize" :item-count="pagination.itemCount"    show-size-picker :page-sizes="[10, 20, 30, 40]" :on-update:page="(page: number)=>{pagination.page = page; searchCondition()}"  :on-update:page-size="(pageSize: number)=>{pagination.pageSize = pageSize; searchCondition()}" />
 				<table-action-add v-model:visible="visible" :type="modalType" @searchCondition="searchCondition"
 					:pagination="pagination" :edit-data="(editData as SelectByCondition_1Params)" />
 			</n-card>
 		</n-scrollbar>
 	</div>
+		<!-- <div>
+			<PDFView :pdfUrl="tableData" />
+		</div> -->
 </template>
 
 <script setup lang="tsx" >
@@ -70,7 +73,7 @@ import { userStatusLabels } from '@/constants';
 import { deleteById } from '~/src/service/api/sort';
 import { selectByCondition_1 } from '~/src/service/api/sort';
 import type { SelectByCondition_1Params } from '~/src/service/api/sort';
-
+// import PDFView from "../../.././components/View/pdfPreview.vue"
 type RowData = {
 	key: number
 	id: number
@@ -99,28 +102,9 @@ const pagination: PaginationProps = ref({
 	page: 1,
 	pageSize: 10,
 	showSizePicker: true,
-	itemCount: 14,
+	itemCount: 1,
 }).value;
 
-function onChange(page: number)  {
-		// 处理页码变化
-		pagination.page = page;
-		selectByCondition_1(pagination.page as number, pagination.pageSize as number, conditionParams).then((res)=>{
-			tableData.value = res.data as [];
-			pagination.itemCount = Number(res.total);
-		})
-}
-
-function onUpdatePageSize(pageSize: number)  {
-		// 处理每页显示数量变化
-		pagination.pageSize = pageSize;
-		pagination.page = 1;
-		selectByCondition_1(pagination.page as number, pagination.pageSize as number, conditionParams).then((res)=>{
-		tableData.value = res.data as [];
-    pagination.itemCount = Number(res.total);
-	})
-}
-
 async function searchCondition() {
 	startLoading();
 	const res = await selectByCondition_1(pagination.page as number, pagination.pageSize as number, conditionParams);
@@ -265,6 +249,9 @@ const columns: Ref<DataTableColumns<UserManagement.User>> = ref([
 							trigger: () => <NButton size={'small'}>删除</NButton>
 						}}
 					</NPopconfirm>
+					<NButton size={'small'} onClick={() => handleEditTable(row.id)} >
+						查看
+					</NButton>
 				</NSpace>
 			);
 		}