🚧 adjust page route
This commit is contained in:
41
components.d.ts
vendored
41
components.d.ts
vendored
@@ -16,13 +16,13 @@ declare module 'vue' {
|
||||
ACard: typeof import('ant-design-vue/es')['Card']
|
||||
ACascader: typeof import('ant-design-vue/es')['Cascader']
|
||||
AccountSetting: typeof import('./src/views/User/AccountSetting/AccountSetting.vue')['default']
|
||||
AccountSettingBackup: typeof import('./src/views/User/AccountSetting/components/AccountSettingBackup/AccountSettingBackup.vue')['default']
|
||||
AccountSettingHome: typeof import('./src/views/User/AccountSetting/components/AccountSettingHome/AccountSettingHome.vue')['default']
|
||||
AccountSettingInfo: typeof import('./src/views/User/AccountSetting/components/AccountSettingInfo/AccountSettingInfo.vue')['default']
|
||||
AccountSettingLog: typeof import('./src/views/User/AccountSetting/components/AccountSettingLog/AccountSettingLog.vue')['default']
|
||||
AccountSettingSidebar: typeof import('./src/views/User/AccountSetting/components/AccountSettingSidebar/AccountSettingSidebar.vue')['default']
|
||||
AccountSettingStorage: typeof import('./src/views/User/AccountSetting/components/AccountSettingStorage/AccountSettingStorage.vue')['default']
|
||||
AccountSettingTask: typeof import('./src/views/User/AccountSetting/components/AccountSettingTask/AccountSettingTask.vue')['default']
|
||||
AccountSettingBackup: typeof import('./src/views/User/AccountSetting/Pages/AccountSettingBackup/AccountSettingBackup.vue')['default']
|
||||
AccountSettingHome: typeof import('./src/views/User/AccountSetting/Pages/AccountSettingHome/AccountSettingHome.vue')['default']
|
||||
AccountSettingInfo: typeof import('./src/views/User/AccountSetting/Pages/AccountSettingInfo/AccountSettingInfo.vue')['default']
|
||||
AccountSettingLog: typeof import('./src/views/User/AccountSetting/Pages/AccountSettingLog/AccountSettingLog.vue')['default']
|
||||
AccountSettingSidebar: typeof import('./src/views/User/AccountSetting/Pages/AccountSettingSidebar/AccountSettingSidebar.vue')['default']
|
||||
AccountSettingStorage: typeof import('./src/views/User/AccountSetting/Pages/AccountSettingStorage/AccountSettingStorage.vue')['default']
|
||||
AccountSettingTask: typeof import('./src/views/User/AccountSetting/Pages/AccountSettingTask/AccountSettingTask.vue')['default']
|
||||
ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
|
||||
ACheckboxGroup: typeof import('ant-design-vue/es')['CheckboxGroup']
|
||||
ACol: typeof import('ant-design-vue/es')['Col']
|
||||
@@ -68,6 +68,7 @@ declare module 'vue' {
|
||||
ASelect: typeof import('ant-design-vue/es')['Select']
|
||||
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
|
||||
ASkeleton: typeof import('ant-design-vue/es')['Skeleton']
|
||||
ASlider: typeof import('ant-design-vue/es')['Slider']
|
||||
ASpace: typeof import('ant-design-vue/es')['Space']
|
||||
ASpin: typeof import('ant-design-vue/es')['Spin']
|
||||
AStatistic: typeof import('ant-design-vue/es')['Statistic']
|
||||
@@ -108,13 +109,13 @@ declare module 'vue' {
|
||||
CommonPhoneUpload: typeof import('./src/views/Phone/CommonPhoneUpload/CommonPhoneUpload.vue')['default']
|
||||
CompareImage: typeof import('./src/views/Upscale/CompareImage.vue')['default']
|
||||
Dashboard: typeof import('./src/views/Admin/System/Pages/Dashboard.vue')['default']
|
||||
DeleteConfirmModal: typeof import('./src/views/User/AccountSetting/components/AccountSettingTask/components/DeleteConfirmModal.vue')['default']
|
||||
DeleteConfirmModal: typeof import('./src/views/User/AccountSetting/Pages/AccountSettingTask/components/DeleteConfirmModal.vue')['default']
|
||||
DeleteOutlined: typeof import('@ant-design/icons-vue')['DeleteOutlined']
|
||||
DownloadOutlined: typeof import('@ant-design/icons-vue')['DownloadOutlined']
|
||||
DownOutlined: typeof import('@ant-design/icons-vue')['DownOutlined']
|
||||
DynamicTitle: typeof import('./src/components/DynamicTitle/DynamicTitle.vue')['default']
|
||||
EditOutlined: typeof import('@ant-design/icons-vue')['EditOutlined']
|
||||
EmailModal: typeof import('./src/views/User/AccountSetting/components/AccountSettingHome/EmailModal.vue')['default']
|
||||
EmailModal: typeof import('./src/views/User/AccountSetting/Pages/AccountSettingHome/EmailModal.vue')['default']
|
||||
ExclamationCircleOutlined: typeof import('@ant-design/icons-vue')['ExclamationCircleOutlined']
|
||||
EyeInvisibleOutlined: typeof import('@ant-design/icons-vue')['EyeInvisibleOutlined']
|
||||
EyeOutlined: typeof import('@ant-design/icons-vue')['EyeOutlined']
|
||||
@@ -127,6 +128,7 @@ declare module 'vue' {
|
||||
HeatmapPro: typeof import('./src/components/HeatmapPro/HeatmapPro.vue')['default']
|
||||
ImageBed: typeof import('./src/views/ImageBed/index.vue')['default']
|
||||
ImageEnhancer: typeof import('./src/components/ImageEnhancer/ImageEnhancer.vue')['default']
|
||||
ImageEnhancerModal: typeof import('./src/components/ImageEnhancer/ImageEnhancerModal.vue')['default']
|
||||
ImageShare: typeof import('./src/views/Share/ImageShare/ImageShare.vue')['default']
|
||||
ImageToolbar: typeof import('./src/components/ImageToolbar/ImageToolbar.vue')['default']
|
||||
ImageUpload: typeof import('./src/components/ImageUpload/ImageUpload.vue')['default']
|
||||
@@ -154,7 +156,7 @@ declare module 'vue' {
|
||||
PageError404: typeof import('./src/views/Admin/Error/PageError404.vue')['default']
|
||||
PageError500: typeof import('./src/views/Admin/Error/PageError500.vue')['default']
|
||||
ParameterSetting: typeof import('./src/views/Upscale/ParameterSetting.vue')['default']
|
||||
PasswordModal: typeof import('./src/views/User/AccountSetting/components/AccountSettingHome/PasswordModal.vue')['default']
|
||||
PasswordModal: typeof import('./src/views/User/AccountSetting/Pages/AccountSettingHome/PasswordModal.vue')['default']
|
||||
PeopleAlbumDetail: typeof import('./src/views/Album/PeopleAlbum/PeopleAlbumDetail.vue')['default']
|
||||
PeopleAlbumIndex: typeof import('./src/views/Album/PeopleAlbum/PeopleAlbumIndex.vue')['default']
|
||||
PeopleAlbumList: typeof import('./src/views/Album/PeopleAlbum/PeopleAlbumList.vue')['default']
|
||||
@@ -164,7 +166,7 @@ declare module 'vue' {
|
||||
PhoalbumDetail: typeof import('./src/views/Album/Phoalbum/PhoalbumDetail.vue')['default']
|
||||
PhoalbumIndex: typeof import('./src/views/Album/Phoalbum/PhoalbumIndex.vue')['default']
|
||||
PhoalbumList: typeof import('./src/views/Album/Phoalbum/PhoalbumList.vue')['default']
|
||||
PhoneModal: typeof import('./src/views/User/AccountSetting/components/AccountSettingHome/PhoneModal.vue')['default']
|
||||
PhoneModal: typeof import('./src/views/User/AccountSetting/Pages/AccountSettingHome/PhoneModal.vue')['default']
|
||||
PhotoStack: typeof import('./src/components/PhotoStack/PhotoStack.vue')['default']
|
||||
PlusOutlined: typeof import('@ant-design/icons-vue')['PlusOutlined']
|
||||
PlusSquareOutlined: typeof import('@ant-design/icons-vue')['PlusSquareOutlined']
|
||||
@@ -199,29 +201,30 @@ declare module 'vue' {
|
||||
ShareViewList: typeof import('./src/views/Share/ShareViewList/index.vue')['default']
|
||||
Spin: typeof import('./src/components/MyUI/Spin/Spin.vue')['default']
|
||||
StarButton: typeof import('./src/components/StarButton/StarButton.vue')['default']
|
||||
StorageCard: typeof import('./src/views/User/AccountSetting/components/AccountSettingStorage/StorageCard.vue')['default']
|
||||
StorageCard: typeof import('./src/views/User/AccountSetting/Pages/AccountSettingStorage/StorageCard.vue')['default']
|
||||
StorageManagement: typeof import('./src/views/Admin/System/Pages/StorageManagement.vue')['default']
|
||||
SystemHeader: typeof import('./src/views/Admin/System/Components/SystemHeader.vue')['default']
|
||||
SystemLogs: typeof import('./src/views/Admin/System/Pages/SystemLogs.vue')['default']
|
||||
SystemSidebar: typeof import('./src/views/Admin/System/Components/SystemSidebar.vue')['default']
|
||||
TabletOutlined: typeof import('@ant-design/icons-vue')['TabletOutlined']
|
||||
TaskCard: typeof import('./src/views/User/AccountSetting/components/AccountSettingTask/components/TaskCard.vue')['default']
|
||||
TaskForm: typeof import('./src/views/User/AccountSetting/components/AccountSettingTask/components/TaskForm.vue')['default']
|
||||
TaskCard: typeof import('./src/views/User/AccountSetting/Pages/AccountSettingTask/components/TaskCard.vue')['default']
|
||||
TaskForm: typeof import('./src/views/User/AccountSetting/Pages/AccountSettingTask/components/TaskForm.vue')['default']
|
||||
TaskSchedule: typeof import('./src/components/TaskSchedule/TaskSchedule.vue')['default']
|
||||
TaskTypeSelector: typeof import('./src/views/User/AccountSetting/components/AccountSettingTask/components/TaskTypeSelector.vue')['default']
|
||||
TaskTypeSelector: typeof import('./src/views/User/AccountSetting/Pages/AccountSettingTask/components/TaskTypeSelector.vue')['default']
|
||||
TestPage: typeof import('./src/views/Test/TestPage.vue')['default']
|
||||
ThingAlbumDetail: typeof import('./src/views/Album/ThingAlbum/ThingAlbumDetail.vue')['default']
|
||||
ThingAlbumIndex: typeof import('./src/views/Album/ThingAlbum/ThingAlbumIndex.vue')['default']
|
||||
ThingAlbumList: typeof import('./src/views/Album/ThingAlbum/ThingAlbumList.vue')['default']
|
||||
ThirdPartyLoginModal: typeof import('./src/views/User/AccountSetting/components/AccountSettingHome/ThirdPartyLoginModal.vue')['default']
|
||||
ThirdPartyLoginModal: typeof import('./src/views/User/AccountSetting/Pages/AccountSettingHome/ThirdPartyLoginModal.vue')['default']
|
||||
Tooltip: typeof import('./src/components/MyUI/Tooltip/Tooltip.vue')['default']
|
||||
UploadImage: typeof import('./src/views/Upscale/UploadImage.vue')['default']
|
||||
UploadSetting: typeof import('./src/components/ImageUpload/UploadSetting.vue')['default']
|
||||
Upscale: typeof import('./src/views/Upscale/index.vue')['default']
|
||||
UpscalePhoneUpload: typeof import('./src/views/Phone/UpscalePhoneUpload/UpscalePhoneUpload.vue')['default']
|
||||
UserAnalysis: typeof import('./src/views/Admin/System/Pages/UserAnalysis.vue')['default']
|
||||
UserCenterDynamic: typeof import('./src/views/User/PersonalCenter/components/UserCenterDynamic/UserCenterDynamic.vue')['default']
|
||||
UserCenterHome: typeof import('./src/views/User/PersonalCenter/components/UserCenterHome/UserCenterHome.vue')['default']
|
||||
UserCenterSetting: typeof import('./src/views/User/PersonalCenter/components/UserCenterSetting/UserCenterSetting.vue')['default']
|
||||
UserCenterDynamic: typeof import('./src/views/User/PersonalCenter/Pages/UserCenterDynamic/UserCenterDynamic.vue')['default']
|
||||
UserCenterHome: typeof import('./src/views/User/PersonalCenter/Pages/UserCenterHome/UserCenterHome.vue')['default']
|
||||
UserCenterSetting: typeof import('./src/views/User/PersonalCenter/Pages/UserCenterSetting/UserCenterSetting.vue')['default']
|
||||
UserInfoCard: typeof import('./src/components/CommentReply/src/UserInfoCard/UserInfoCard.vue')['default']
|
||||
UserList: typeof import('./src/views/Admin/System/Pages/UserList.vue')['default']
|
||||
UserOutlined: typeof import('@ant-design/icons-vue')['UserOutlined']
|
||||
|
@@ -34,7 +34,7 @@
|
||||
"@types/file-saver": "^2.0.7",
|
||||
"@types/json-stringify-safe": "^5.0.3",
|
||||
"@types/leaflet": "^1.9.17",
|
||||
"@types/node": "^22.13.14",
|
||||
"@types/node": "^22.13.17",
|
||||
"@types/nprogress": "^0.2.3",
|
||||
"@vladmandic/face-api": "^1.7.15",
|
||||
"@vuepic/vue-datepicker": "^11.0.2",
|
||||
@@ -89,11 +89,11 @@
|
||||
"@vitejs/plugin-vue": "^5.2.3",
|
||||
"eslint-plugin-vue": "^10.0.0",
|
||||
"globals": "^16.0.0",
|
||||
"sass": "^1.86.0",
|
||||
"sass": "^1.86.1",
|
||||
"typescript": "^5.8.2",
|
||||
"typescript-eslint": "^8.28.0",
|
||||
"typescript-eslint": "^8.29.0",
|
||||
"unplugin-vue-components": "^28.4.1",
|
||||
"vite": "^6.2.3",
|
||||
"vite": "^6.2.4",
|
||||
"vite-plugin-bundle-obfuscator": "1.4.2",
|
||||
"vite-plugin-chunk-split": "^0.5.0",
|
||||
"vue-tsc": "2.2.8"
|
||||
|
852
src/components/ImageEnhancer/ImageEnhancerModal.vue
Normal file
852
src/components/ImageEnhancer/ImageEnhancerModal.vue
Normal file
@@ -0,0 +1,852 @@
|
||||
<template>
|
||||
<div class="enhancer-modal-container">
|
||||
<AFlex class="enhancer-modal-content" :vertical="false" align="center" justify="space-between">
|
||||
<!-- 左侧控制面板 -->
|
||||
<div class="enhancer-modal-left">
|
||||
<ACard class="enhancer-modal-left-container" :bordered="false">
|
||||
<!-- 上传区域 -->
|
||||
<div class="enhancer-modal-upload">
|
||||
<Spin :spinning="enhancer.uploading" indicator="magic-ring">
|
||||
<AUploadDragger
|
||||
name="image"
|
||||
accept="image/*"
|
||||
:multiple="false"
|
||||
:directory="false"
|
||||
:maxCount="1"
|
||||
:beforeUpload="enhancer.beforeUpload"
|
||||
:custom-request="enhancer.customUploadRequest"
|
||||
:disabled="enhancer.uploading || enhancer.isProcessing"
|
||||
:showUploadList="false">
|
||||
<div class="enhancer-modal-upload-content">
|
||||
<ABadge :offset="[-10, 10]">
|
||||
<template #count>
|
||||
<AAvatar :size="22" :src="successIcon" v-if="enhancer.imageData"/>
|
||||
<AAvatar :size="22" :src="warnIcon" v-if="!enhancer.imageData"/>
|
||||
</template>
|
||||
<AAvatar shape="square" :size="60" :src="fileIcon"/>
|
||||
</ABadge>
|
||||
<span class="enhancer-modal-upload-text">
|
||||
点击或拖拽上传图片
|
||||
</span>
|
||||
</div>
|
||||
</AUploadDragger>
|
||||
</Spin>
|
||||
</div>
|
||||
|
||||
<!-- 功能选择区 -->
|
||||
<ADivider orientation="center" :plain="true">
|
||||
<span class="enhancer-modal-divider-title">增强功能</span>
|
||||
</ADivider>
|
||||
|
||||
<div class="enhancer-modal-function-selector">
|
||||
<ARadioGroup v-model:value="enhancer.selectedFunction" button-style="solid" size="small"
|
||||
style="width: 100%">
|
||||
<ARadioButton value="upscale">图像升级</ARadioButton>
|
||||
<ARadioButton value="deblur">去模糊</ARadioButton>
|
||||
<ARadioButton value="denoise">去噪</ARadioButton>
|
||||
<ARadioButton value="lowlight">弱光增强</ARadioButton>
|
||||
</ARadioGroup>
|
||||
</div>
|
||||
|
||||
<!-- 参数设置区 -->
|
||||
<ADivider orientation="center" :plain="true">
|
||||
<span class="enhancer-modal-divider-title">参数设置</span>
|
||||
</ADivider>
|
||||
|
||||
<!-- 图像升级参数 -->
|
||||
<div v-if="enhancer.selectedFunction === 'upscale'" class="enhancer-modal-params">
|
||||
<div class="enhancer-modal-params-item">
|
||||
<div class="enhancer-modal-params-item-content">
|
||||
<span class="enhancer-modal-params-title">模型:</span>
|
||||
<ASelect style="width: 100%" size="middle"
|
||||
v-model:value="enhancer.upscaleParams.model"
|
||||
:options="enhancer.upscaleModels">
|
||||
</ASelect>
|
||||
</div>
|
||||
<div class="enhancer-modal-params-item-content">
|
||||
<span class="enhancer-modal-params-title">比例:</span>
|
||||
<ASelect style="width: 100%" size="middle"
|
||||
v-model:value="enhancer.upscaleParams.scale"
|
||||
:options="enhancer.upscaleScales">
|
||||
</ASelect>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 去模糊参数 -->
|
||||
<div v-if="enhancer.selectedFunction === 'deblur'" class="enhancer-modal-params">
|
||||
<div class="enhancer-modal-params-item">
|
||||
<div class="enhancer-modal-params-item-content">
|
||||
<span class="enhancer-modal-params-title">强度:</span>
|
||||
<ASlider v-model:value="enhancer.deblurParams.strength" :min="0" :max="100" :step="1"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 去噪参数 -->
|
||||
<div v-if="enhancer.selectedFunction === 'denoise'" class="enhancer-modal-params">
|
||||
<div class="enhancer-modal-params-item">
|
||||
<div class="enhancer-modal-params-item-content">
|
||||
<span class="enhancer-modal-params-title">强度:</span>
|
||||
<ASlider v-model:value="enhancer.denoiseParams.strength" :min="0" :max="100" :step="1"/>
|
||||
</div>
|
||||
<div class="enhancer-modal-params-item-content">
|
||||
<span class="enhancer-modal-params-title">保留细节:</span>
|
||||
<ASlider v-model:value="enhancer.denoiseParams.preserveDetail" :min="0" :max="100" :step="1"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 弱光增强参数 -->
|
||||
<div v-if="enhancer.selectedFunction === 'lowlight'" class="enhancer-modal-params">
|
||||
<div class="enhancer-modal-params-item">
|
||||
<div class="enhancer-modal-params-item-content">
|
||||
<span class="enhancer-modal-params-title">亮度:</span>
|
||||
<ASlider v-model:value="enhancer.lowlightParams.brightness" :min="0" :max="100" :step="1"/>
|
||||
</div>
|
||||
<div class="enhancer-modal-params-item-content">
|
||||
<span class="enhancer-modal-params-title">对比度:</span>
|
||||
<ASlider v-model:value="enhancer.lowlightParams.contrast" :min="0" :max="100" :step="1"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 处理按钮 -->
|
||||
<ADivider></ADivider>
|
||||
<AButton style="width: 100%;" size="middle" shape="default" type="primary" :loading="enhancer.isProcessing"
|
||||
:disabled="!enhancer.imageData"
|
||||
@click="startEnhance">
|
||||
<template #icon>
|
||||
<AAvatar shape="square" :size="20" :src="runIcon"/>
|
||||
</template>
|
||||
<span class="enhancer-modal-params-btn">开始处理</span>
|
||||
</AButton>
|
||||
</ACard>
|
||||
</div>
|
||||
|
||||
<!-- 右侧图像预览区 -->
|
||||
<div class="enhancer-modal-right">
|
||||
<div
|
||||
ref="canvasContainer"
|
||||
class="canvas-container"
|
||||
@mousedown="startDragging"
|
||||
@mouseup="stopDragging"
|
||||
@mouseleave="stopDragging"
|
||||
@mousemove="dragImage"
|
||||
@wheel="resizeImage"
|
||||
@touchstart="touchStart"
|
||||
@touchmove="touchMove"
|
||||
@touchend="touchEnd"
|
||||
>
|
||||
<!-- 进度条 -->
|
||||
<div class="canvas-progressbar">
|
||||
<span class="canvas-progressbar-text">
|
||||
{{ enhancer.msg }}
|
||||
</span>
|
||||
<AProgress
|
||||
v-if="enhancer.isProcessing"
|
||||
:stroke-color="{
|
||||
'0%': '#108ee9',
|
||||
'100%': '#87d068',}"
|
||||
:percent="enhancer.progressBar"
|
||||
:showInfo="false"
|
||||
status="active"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 图片 -->
|
||||
<canvas ref="canvas"></canvas>
|
||||
|
||||
<!-- 拖动条 -->
|
||||
<div
|
||||
class="dragLine"
|
||||
v-if="enhancer.isDone"
|
||||
ref="dragLine">
|
||||
<div class="dragBall"
|
||||
@mousedown.stop="startDraggingLine"
|
||||
@mousemove.stop="dragLineFn"
|
||||
@mouseup.stop="stopDraggingLine"
|
||||
>
|
||||
<svg width="24" viewBox="0 0 27 20">
|
||||
<path fill="#ff3484" d="M9.6 0L0 9.6l9.6 9.6z"></path>
|
||||
<path fill="#5fb3e5" d="M17 19.2l9.5-9.6L16.9 0z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 菜单 -->
|
||||
<div class="floating-menu" @mousedown.stop v-if="enhancer.isDone && enhancer.processedImg">
|
||||
<AFlex :vertical="false" align="center" justify="space-between" :gap="8">
|
||||
<ATooltip placement="top" title="下载图片">
|
||||
<AButton type="text" size="small" @click="downloadImage" class="menu-btn">
|
||||
<template #icon>
|
||||
<AAvatar :src="downloadIcon" class="menu-icon" :size="20"/>
|
||||
</template>
|
||||
</AButton>
|
||||
</ATooltip>
|
||||
<ATooltip placement="top" title="保存图片">
|
||||
<AButton type="text" size="small" class="menu-btn" @click="saveImage">
|
||||
<template #icon>
|
||||
<AAvatar :src="saveIcon" :size="20" class="menu-icon"/>
|
||||
</template>
|
||||
</AButton>
|
||||
</ATooltip>
|
||||
<ATooltip placement="top" title="删除图片">
|
||||
<AButton type="text" size="small" danger class="menu-btn" @click="deleteImage">
|
||||
<template #icon>
|
||||
<AAvatar :src="deleteIcon" :size="20" class="menu-icon"/>
|
||||
</template>
|
||||
</AButton>
|
||||
</ATooltip>
|
||||
</AFlex>
|
||||
</div>
|
||||
|
||||
<!-- 图片信息 -->
|
||||
<div class="image-info">
|
||||
<ATag color="cyan" :bordered="false" v-if="enhancer.imageData">原图: {{ originalImageSize }}</ATag>
|
||||
<ATag color="purple" :bordered="false" v-if="enhancer.processedImg">处理后: {{ processedImageSize }}</ATag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</AFlex>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed, onMounted, onUnmounted, defineEmits } from 'vue';
|
||||
import { message } from "ant-design-vue";
|
||||
import Spin from "@/components/MyUI/Spin/Spin.vue";
|
||||
import Upscaler from 'upscaler';
|
||||
|
||||
// 图标导入
|
||||
import fileIcon from "@/assets/svgs/file.svg";
|
||||
import successIcon from '@/assets/svgs/success.svg';
|
||||
import warnIcon from '@/assets/svgs/warn.svg';
|
||||
import runIcon from '@/assets/svgs/run.svg';
|
||||
import downloadIcon from '@/assets/svgs/download.svg';
|
||||
import saveIcon from '@/assets/svgs/save.svg';
|
||||
import deleteIcon from '@/assets/svgs/deleted.svg';
|
||||
|
||||
// 定义事件
|
||||
const emit = defineEmits(['save-image', 'close']);
|
||||
|
||||
// DOM引用
|
||||
const canvasContainer = ref<HTMLDivElement | null>(null);
|
||||
const canvas = ref<HTMLCanvasElement | null>(null);
|
||||
const dragLine = ref<HTMLDivElement | null>(null);
|
||||
|
||||
// 图像处理实例
|
||||
let upscaler: any = null;
|
||||
|
||||
// 状态管理
|
||||
const enhancer = reactive({
|
||||
// 基本状态
|
||||
uploading: false,
|
||||
isProcessing: false,
|
||||
isDone: false,
|
||||
msg: "",
|
||||
progressBar: 0,
|
||||
|
||||
// 图像数据
|
||||
imageData: "",
|
||||
fileData: "",
|
||||
processedImg: "",
|
||||
input: null as any,
|
||||
|
||||
// 拖拽状态
|
||||
dragging: false,
|
||||
linePosition: 0,
|
||||
draggingLine: false,
|
||||
|
||||
// 功能选择
|
||||
selectedFunction: "upscale",
|
||||
|
||||
// 图像升级参数
|
||||
upscaleParams: {
|
||||
model: "x4",
|
||||
scale: 4
|
||||
},
|
||||
upscaleModels: [
|
||||
{label: "通用模型 x2", value: "x2"},
|
||||
{label: "通用模型 x4", value: "x4"},
|
||||
{label: "照片增强", value: "photo"},
|
||||
{label: "动漫风格", value: "anime"}
|
||||
],
|
||||
upscaleScales: [
|
||||
{label: "2x", value: 2},
|
||||
{label: "4x", value: 4}
|
||||
],
|
||||
|
||||
// 去模糊参数
|
||||
deblurParams: {
|
||||
strength: 50,
|
||||
radius: 5
|
||||
},
|
||||
|
||||
// 去噪参数
|
||||
denoiseParams: {
|
||||
strength: 50,
|
||||
preserveDetail: 70
|
||||
},
|
||||
|
||||
// 弱光增强参数
|
||||
lowlightParams: {
|
||||
brightness: 60,
|
||||
contrast: 50
|
||||
},
|
||||
|
||||
// 图片上传前的校验
|
||||
async beforeUpload(file: File) {
|
||||
enhancer.uploading = true;
|
||||
const urlData = URL.createObjectURL(file);
|
||||
const image = new Image();
|
||||
image.src = urlData;
|
||||
|
||||
// 等待图片加载完成
|
||||
await new Promise(resolve => {
|
||||
image.onload = resolve;
|
||||
});
|
||||
|
||||
await clear();
|
||||
enhancer.fileData = urlData;
|
||||
enhancer.uploading = false;
|
||||
return true;
|
||||
},
|
||||
|
||||
// 自定义上传图片请求
|
||||
async customUploadRequest(_file: any) {
|
||||
enhancer.imageData = enhancer.fileData;
|
||||
await loadImage();
|
||||
}
|
||||
});
|
||||
|
||||
// 图片尺寸信息
|
||||
const originalImageSize = computed(() => {
|
||||
if (!enhancer.imageData) return "";
|
||||
const img = new Image();
|
||||
img.src = enhancer.imageData;
|
||||
return `${img.width}x${img.height}`;
|
||||
});
|
||||
|
||||
const processedImageSize = computed(() => {
|
||||
if (!enhancer.processedImg) return "";
|
||||
const img = new Image();
|
||||
img.src = enhancer.processedImg;
|
||||
return `${img.width}x${img.height}`;
|
||||
});
|
||||
|
||||
// 清空数据
|
||||
async function clear() {
|
||||
enhancer.imageData = "";
|
||||
enhancer.processedImg = "";
|
||||
enhancer.isDone = false;
|
||||
enhancer.msg = "";
|
||||
enhancer.progressBar = 0;
|
||||
enhancer.isProcessing = false;
|
||||
enhancer.dragging = false;
|
||||
enhancer.linePosition = 0;
|
||||
enhancer.draggingLine = false;
|
||||
enhancer.input = null;
|
||||
}
|
||||
|
||||
// 加载图片
|
||||
async function loadImage() {
|
||||
if (!canvas.value || !enhancer.imageData) return;
|
||||
|
||||
const ctx = canvas.value.getContext('2d');
|
||||
if (!ctx) return;
|
||||
|
||||
const img = new Image();
|
||||
img.src = enhancer.imageData;
|
||||
|
||||
await new Promise(resolve => {
|
||||
img.onload = resolve;
|
||||
});
|
||||
|
||||
canvas.value.width = img.width;
|
||||
canvas.value.height = img.height;
|
||||
ctx.drawImage(img, 0, 0);
|
||||
|
||||
// 初始化拖动线位置
|
||||
enhancer.linePosition = img.width / 2;
|
||||
|
||||
// 初始化Upscaler
|
||||
if (!upscaler) {
|
||||
upscaler = new Upscaler();
|
||||
}
|
||||
}
|
||||
|
||||
// 开始图像增强处理
|
||||
async function startEnhance() {
|
||||
if (!enhancer.imageData || !canvas.value) {
|
||||
message.warning("请先上传图片");
|
||||
return;
|
||||
}
|
||||
|
||||
enhancer.isProcessing = true;
|
||||
enhancer.msg = "正在处理图片...";
|
||||
const start = Date.now();
|
||||
|
||||
try {
|
||||
const img = new Image();
|
||||
img.src = enhancer.imageData;
|
||||
|
||||
await new Promise(resolve => {
|
||||
img.onload = resolve;
|
||||
});
|
||||
|
||||
let processedImage;
|
||||
|
||||
// 根据选择的功能进行不同的处理
|
||||
switch (enhancer.selectedFunction) {
|
||||
case 'upscale':
|
||||
enhancer.msg = "正在进行图像升级...";
|
||||
processedImage = await upscaler.upscale(img, {
|
||||
model: enhancer.upscaleParams.model,
|
||||
scale: enhancer.upscaleParams.scale,
|
||||
progress: (progress: number) => {
|
||||
enhancer.progressBar = Math.round(progress * 100);
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
||||
case 'deblur':
|
||||
enhancer.msg = "正在进行去模糊处理...";
|
||||
// 使用upscaler的去模糊功能
|
||||
processedImage = await simulateImageProcessing(img, 'deblur');
|
||||
break;
|
||||
|
||||
case 'denoise':
|
||||
enhancer.msg = "正在进行去噪处理...";
|
||||
processedImage = await simulateImageProcessing(img, 'denoise');
|
||||
break;
|
||||
|
||||
case 'lowlight':
|
||||
enhancer.msg = "正在进行弱光增强...";
|
||||
processedImage = await simulateImageProcessing(img, 'lowlight');
|
||||
break;
|
||||
}
|
||||
|
||||
if (processedImage) {
|
||||
enhancer.processedImg = processedImage.src || processedImage;
|
||||
enhancer.isDone = true;
|
||||
enhancer.msg = `处理完成! 用时: ${((Date.now() - start) / 1000).toFixed(2)}秒`;
|
||||
|
||||
// 更新画布显示处理后的图片
|
||||
updateCanvasWithProcessedImage();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("图像处理失败", error);
|
||||
message.error("图像处理失败,请重试");
|
||||
enhancer.msg = "处理失败";
|
||||
} finally {
|
||||
enhancer.isProcessing = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 模拟图像处理(在实际实现中应替换为真实的处理逻辑)
|
||||
async function simulateImageProcessing(img: HTMLImageElement, _type: string) {
|
||||
// 模拟进度
|
||||
let progress = 0;
|
||||
const interval = setInterval(() => {
|
||||
progress += Math.random() * 5;
|
||||
enhancer.progressBar = Math.min(Math.round(progress), 99);
|
||||
if (progress >= 100) {
|
||||
clearInterval(interval);
|
||||
}
|
||||
}, 200);
|
||||
|
||||
// 这里应该是实际的图像处理逻辑
|
||||
// 目前使用upscaler的基本功能模拟其他处理效果
|
||||
try {
|
||||
const result = await upscaler.upscale(img, {
|
||||
model: 'x2',
|
||||
scale: 1.5,
|
||||
progress: (p: number) => {
|
||||
enhancer.progressBar = Math.round(p * 100);
|
||||
}
|
||||
});
|
||||
clearInterval(interval);
|
||||
return result;
|
||||
} catch (error) {
|
||||
clearInterval(interval);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 更新画布显示处理后的图片
|
||||
function updateCanvasWithProcessedImage() {
|
||||
if (!canvas.value || !enhancer.processedImg) return;
|
||||
|
||||
const ctx = canvas.value.getContext('2d');
|
||||
if (!ctx) return;
|
||||
|
||||
const img = new Image();
|
||||
img.src = enhancer.processedImg;
|
||||
|
||||
img.onload = () => {
|
||||
canvas.value!.width = img.width;
|
||||
canvas.value!.height = img.height;
|
||||
ctx.drawImage(img, 0, 0);
|
||||
|
||||
// 重置拖动线位置
|
||||
enhancer.linePosition = img.width / 2;
|
||||
|
||||
// 绘制对比效果
|
||||
drawComparisonView();
|
||||
};
|
||||
}
|
||||
|
||||
// 绘制对比视图
|
||||
function drawComparisonView() {
|
||||
if (!canvas.value || !enhancer.imageData || !enhancer.processedImg || !enhancer.isDone) return;
|
||||
|
||||
const ctx = canvas.value.getContext('2d');
|
||||
if (!ctx) return;
|
||||
|
||||
const originalImg = new Image();
|
||||
originalImg.src = enhancer.imageData;
|
||||
|
||||
const processedImg = new Image();
|
||||
processedImg.src = enhancer.processedImg;
|
||||
|
||||
originalImg.onload = () => {
|
||||
processedImg.onload = () => {
|
||||
// 清除画布
|
||||
ctx.clearRect(0, 0, canvas.value!.width, canvas.value!.height);
|
||||
|
||||
// 绘制处理后的图片
|
||||
ctx.drawImage(processedImg, 0, 0, canvas.value!.width, canvas.value!.height);
|
||||
|
||||
// 绘制原图(左侧部分)
|
||||
ctx.drawImage(
|
||||
originalImg,
|
||||
0, 0, originalImg.width, originalImg.height,
|
||||
0, 0, enhancer.linePosition, canvas.value!.height
|
||||
);
|
||||
|
||||
// 绘制分割线
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(enhancer.linePosition, 0);
|
||||
ctx.lineTo(enhancer.linePosition, canvas.value!.height);
|
||||
ctx.strokeStyle = '#ffffff';
|
||||
ctx.lineWidth = 2;
|
||||
ctx.stroke();
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// 拖动相关函数
|
||||
function startDragging(_e: MouseEvent) {
|
||||
enhancer.dragging = true;
|
||||
}
|
||||
|
||||
function stopDragging() {
|
||||
enhancer.dragging = false;
|
||||
}
|
||||
|
||||
function dragImage(e: MouseEvent) {
|
||||
if (!enhancer.dragging || !canvasContainer.value) return;
|
||||
|
||||
if (enhancer.isDone) {
|
||||
// 更新拖动线位置
|
||||
const rect = canvasContainer.value.getBoundingClientRect();
|
||||
const x = e.clientX - rect.left;
|
||||
enhancer.linePosition = Math.max(0, Math.min(canvas.value?.width || 0, x));
|
||||
drawComparisonView();
|
||||
}
|
||||
}
|
||||
|
||||
function startDraggingLine(e: MouseEvent) {
|
||||
e.preventDefault();
|
||||
enhancer.draggingLine = true;
|
||||
}
|
||||
|
||||
function stopDraggingLine() {
|
||||
enhancer.draggingLine = false;
|
||||
}
|
||||
|
||||
function dragLineFn(e: MouseEvent) {
|
||||
if (!enhancer.draggingLine || !canvas.value || !canvasContainer.value) return;
|
||||
|
||||
const rect = canvasContainer.value.getBoundingClientRect();
|
||||
const x = e.clientX - rect.left;
|
||||
|
||||
// 限制拖动范围在画布内
|
||||
enhancer.linePosition = Math.max(0, Math.min(canvas.value.width, x));
|
||||
|
||||
// 重新绘制对比视图
|
||||
drawComparisonView();
|
||||
}
|
||||
|
||||
// 缩放相关函数
|
||||
function resizeImage(e: WheelEvent) {
|
||||
e.preventDefault();
|
||||
// 实现简单的缩放功能
|
||||
if (!canvas.value || !enhancer.isDone) return;
|
||||
|
||||
// 这里可以实现缩放逻辑
|
||||
}
|
||||
|
||||
// 触摸事件处理
|
||||
function touchStart(e: TouchEvent) {
|
||||
if (e.touches.length === 1) {
|
||||
enhancer.dragging = true;
|
||||
}
|
||||
}
|
||||
|
||||
function touchMove(e: TouchEvent) {
|
||||
if (!enhancer.dragging || !canvasContainer.value || e.touches.length !== 1) return;
|
||||
|
||||
const touch = e.touches[0];
|
||||
const rect = canvasContainer.value.getBoundingClientRect();
|
||||
const x = touch.clientX - rect.left;
|
||||
|
||||
if (enhancer.isDone) {
|
||||
// 更新拖动线位置
|
||||
enhancer.linePosition = Math.max(0, Math.min(canvas.value?.width || 0, x));
|
||||
drawComparisonView();
|
||||
}
|
||||
}
|
||||
|
||||
function touchEnd() {
|
||||
enhancer.dragging = false;
|
||||
}
|
||||
|
||||
// 下载图片
|
||||
function downloadImage() {
|
||||
if (!enhancer.processedImg) return;
|
||||
|
||||
const link = document.createElement('a');
|
||||
link.href = enhancer.processedImg;
|
||||
link.download = `enhanced_image_${Date.now()}.png`;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
|
||||
message.success('图片下载成功');
|
||||
}
|
||||
|
||||
// 保存图片
|
||||
function saveImage() {
|
||||
if (!enhancer.processedImg) return;
|
||||
emit('save-image', enhancer.processedImg);
|
||||
message.success('图片已保存');
|
||||
}
|
||||
|
||||
// 删除图片
|
||||
function deleteImage() {
|
||||
clear();
|
||||
message.success('图片已删除');
|
||||
}
|
||||
|
||||
// 组件挂载和卸载
|
||||
onMounted(() => {
|
||||
// 初始化Upscaler
|
||||
upscaler = new Upscaler();
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
// 清理资源
|
||||
if (enhancer.processedImg) {
|
||||
URL.revokeObjectURL(enhancer.processedImg);
|
||||
}
|
||||
if (enhancer.imageData) {
|
||||
URL.revokeObjectURL(enhancer.imageData);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.enhancer-modal-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 10px;
|
||||
|
||||
.enhancer-modal-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 15px;
|
||||
|
||||
.enhancer-modal-left {
|
||||
width: 35%;
|
||||
height: 100%;
|
||||
|
||||
.enhancer-modal-left-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
border-radius: 8px;
|
||||
background-color: rgba(255, 255, 255, 0.8);
|
||||
backdrop-filter: blur(10px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
|
||||
padding: 15px;
|
||||
|
||||
.enhancer-modal-divider-title {
|
||||
font-size: 13px;
|
||||
color: rgba(80, 80, 90, 0.9);
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.enhancer-modal-right {
|
||||
width: 65%;
|
||||
height: 100%;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
background-color: rgba(245, 245, 245, 0.5);
|
||||
backdrop-filter: blur(5px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.enhancer-modal-upload {
|
||||
width: 100%;
|
||||
margin-bottom: 15px;
|
||||
|
||||
.enhancer-modal-upload-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px 0;
|
||||
gap: 10px;
|
||||
|
||||
.enhancer-modal-upload-text {
|
||||
font-size: 14px;
|
||||
color: rgba(80, 80, 90, 0.8);
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.enhancer-modal-function-selector {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.enhancer-modal-params {
|
||||
margin-bottom: 15px;
|
||||
|
||||
.enhancer-modal-params-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
|
||||
.enhancer-modal-params-item-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
|
||||
.enhancer-modal-params-title {
|
||||
font-size: 13px;
|
||||
color: rgba(80, 80, 90, 0.9);
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.enhancer-modal-params-btn {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.canvas-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(0, 0, 0, 0.02);
|
||||
border-radius: 8px;
|
||||
|
||||
canvas {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.canvas-progressbar {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
right: 10px;
|
||||
z-index: 10;
|
||||
background-color: rgba(255, 255, 255, 0.7);
|
||||
padding: 8px;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
|
||||
.canvas-progressbar-text {
|
||||
font-size: 13px;
|
||||
color: rgba(80, 80, 90, 0.9);
|
||||
margin-bottom: 5px;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.dragLine {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 2px;
|
||||
background-color: #ffffff;
|
||||
z-index: 5;
|
||||
|
||||
.dragBall {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
cursor: ew-resize;
|
||||
background-color: rgba(255, 255, 255, 0.9);
|
||||
border-radius: 50%;
|
||||
padding: 2px;
|
||||
box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
.floating-menu {
|
||||
position: absolute;
|
||||
bottom: 15px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background-color: rgba(255, 255, 255, 0.8);
|
||||
backdrop-filter: blur(5px);
|
||||
border-radius: 8px;
|
||||
padding: 5px 10px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||
z-index: 10;
|
||||
|
||||
.menu-btn {
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
.menu-icon {
|
||||
opacity: 0.8;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.image-info {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
z-index: 10;
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,3 +0,0 @@
|
||||
import ImageEnhancer from './ImageEnhancer.vue';
|
||||
|
||||
export default ImageEnhancer;
|
11
src/router/modules/test.ts
Normal file
11
src/router/modules/test.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
export default [
|
||||
{
|
||||
path: '/test',
|
||||
name: 'testPage',
|
||||
component: () => import('@/views/Test/TestPage.vue'),
|
||||
meta: {
|
||||
requiresAuth: false,
|
||||
title: 'testPage',
|
||||
}
|
||||
},
|
||||
];
|
@@ -1,13 +1,13 @@
|
||||
import UserCenterHome from "@/views/User/PersonalCenter/components/UserCenterHome/UserCenterHome.vue";
|
||||
import UserCenterDynamic from "@/views/User/PersonalCenter/components/UserCenterDynamic/UserCenterDynamic.vue";
|
||||
import UserCenterSetting from "@/views/User/PersonalCenter/components/UserCenterSetting/UserCenterSetting.vue";
|
||||
import UserCenterHome from "@/views/User/PersonalCenter/Pages/UserCenterHome/UserCenterHome.vue";
|
||||
import UserCenterDynamic from "@/views/User/PersonalCenter/Pages/UserCenterDynamic/UserCenterDynamic.vue";
|
||||
import UserCenterSetting from "@/views/User/PersonalCenter/Pages/UserCenterSetting/UserCenterSetting.vue";
|
||||
|
||||
import AccountSettingHome from "@/views/User/AccountSetting/components/AccountSettingHome/AccountSettingHome.vue";
|
||||
import AccountSettingInfo from "@/views/User/AccountSetting/components/AccountSettingInfo/AccountSettingInfo.vue";
|
||||
import AccountSettingHome from "@/views/User/AccountSetting/Pages/AccountSettingHome/AccountSettingHome.vue";
|
||||
import AccountSettingInfo from "@/views/User/AccountSetting/Pages/AccountSettingInfo/AccountSettingInfo.vue";
|
||||
import AccountSettingStorage
|
||||
from "@/views/User/AccountSetting/components/AccountSettingStorage/AccountSettingStorage.vue";
|
||||
from "@/views/User/AccountSetting/Pages/AccountSettingStorage/AccountSettingStorage.vue";
|
||||
import AccountSettingBackup
|
||||
from "@/views/User/AccountSetting/components/AccountSettingBackup/AccountSettingBackup.vue";
|
||||
from '@/views/User/AccountSetting/Pages/AccountSettingBackup/AccountSettingBackup.vue';
|
||||
|
||||
export default [
|
||||
{
|
||||
@@ -99,7 +99,7 @@ export default [
|
||||
{
|
||||
path: '/main/user/setting/task',
|
||||
name: 'AccountSettingTask',
|
||||
component: () => import('@/views/User/AccountSetting/components/AccountSettingTask/AccountSettingTask.vue'),
|
||||
component: () => import('@/views/User/AccountSetting/Pages/AccountSettingTask/AccountSettingTask.vue'),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: '定时任务'
|
||||
@@ -108,7 +108,7 @@ export default [
|
||||
{
|
||||
path: '/main/user/setting/log',
|
||||
name: 'AccountSettingLog',
|
||||
component: () => import('@/views/User/AccountSetting/components/AccountSettingLog/AccountSettingLog.vue'),
|
||||
component: () => import('@/views/User/AccountSetting/Pages/AccountSettingLog/AccountSettingLog.vue'),
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: '执行记录'
|
||||
|
@@ -11,7 +11,7 @@ import phone_upload from "@/router/modules/phone_upload.ts";
|
||||
import user from "@/router/modules/user.ts";
|
||||
import system from "@/router/modules/system.ts";
|
||||
import preview from "@/router/modules/preview.ts";
|
||||
|
||||
import test from "@/router/modules/test.ts";
|
||||
const routes: Array<RouteRecordRaw> = [
|
||||
...login,
|
||||
...notFound,
|
||||
@@ -21,6 +21,7 @@ const routes: Array<RouteRecordRaw> = [
|
||||
...user,
|
||||
...system,
|
||||
...preview,
|
||||
...test,
|
||||
{
|
||||
path: '/:pathMatch(.*)',
|
||||
redirect: '/404',
|
||||
|
12
src/views/Test/TestPage.vue
Normal file
12
src/views/Test/TestPage.vue
Normal file
@@ -0,0 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import ImageEnhancerModal from "@/components/ImageEnhancer/ImageEnhancerModal.vue";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ImageEnhancerModal/>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
@@ -14,7 +14,7 @@
|
||||
<script setup lang="ts">
|
||||
import Header from "@/layout/default/Header/Header.vue";
|
||||
import AccountSettingSidebar
|
||||
from "@/views/User/AccountSetting/components/AccountSettingSidebar/AccountSettingSidebar.vue";
|
||||
from "@/views/User/AccountSetting/Pages/AccountSettingSidebar/AccountSettingSidebar.vue";
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.account-setting {
|
||||
|
@@ -79,7 +79,7 @@
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
|
||||
import StorageCard from "@/views/User/AccountSetting/components/AccountSettingStorage/StorageCard.vue";
|
||||
import StorageCard from "@/views/User/AccountSetting/Pages/AccountSettingStorage/StorageCard.vue";
|
||||
import {addStorageConfigApi, listUserStorageConfigApi} from "@/api/storage";
|
||||
import {message} from "ant-design-vue";
|
||||
|
Reference in New Issue
Block a user