Vue3实战easypan(六):回收站+设置

一、回收站

src/views/recycle/Recycle.vue

 

<template><!-- 上方两个按钮 --><div class="top"><el-button type="success" :disabled="selectFileIdList.length == 0" @click="revertBatch"><span class="iconfont icon-revert"></span>&nbsp还原</el-button><el-button type="danger" :disabled="selectFileIdList.length == 0" @click="delBatch"><span class="iconfont icon-del"></span>&nbsp批量删除</el-button></div><!-- 已删除的文件列表 --><div class="file-list"><!-- 引入Table组件 --><Table :columns="columns" :showPagination="true" :dataSource="tableData" :fetch="loadDataList":options="tableOptions" @rowSelected="rowSelected"><!-- 文件名 --><template #fileName="{ index, row }"><!-- showOp(row) 当鼠标放在当前行时,分享下载等图标出现 --><!-- cancelShowOp(row) 当鼠标离开当前行时,分享下载等图标消失 --><div class="file-item" @mouseenter="showOp(row)" @mouseleave="cancelShowOp(row)"><!-- 显示文件图标 --><template v-if="(row.fileType == 3 || row.fileType == 1) && row.status !== 0"><!-- 如果文件类型是图片或者视频,且已经成功转码,则执行 Icon中的cover --><Icon :cover="row.fileCover"></Icon></template><template v-else><!-- 如果文件夹类型是文件,则文件类型是该文件类型 --><Icon v-if="row.folderType == 0" :fileType="row.fileType"></Icon><!-- 如果文件夹类型是目录,则文件类型就是目录0 --><Icon v-if="row.folderType == 1" :fileType="0"></Icon></template><!-- 显示文件名称 --><span class="file-name" :title="row.fileName"><span>{{ row.fileName }}</span></span><!-- 当鼠标放在当前行时显示 --><span class="op"><template v-if="row.showOp && row.fileId"><span class="iconfont icon-revert" @click="revert(row)">还原</span><span class="iconfont icon-del" @click="delFile(row)">删除</span></template></span></div></template><!-- 文件大小显示 --><template #fileSize="{ index, row }"><span v-if="row.fileSize">{{ proxy.Utils.size2Str(row.fileSize) }}</span></template></Table></div>
</template><script setup>
import { ref, reactive, getCurrentInstance, nextTick } from "vue";
const { proxy } = getCurrentInstance();const api = {loadDataList: "/recycle/loadRecycleList",delFile: "/recycle/delFile",recoverFile: "/recycle/recoverFile",
};//列表
const columns = [{label: "文件名",prop: "fileName",scopedSlots: "fileName",},{label: "删除时间",prop: "recoveryTime",width: 200,},{label: "大小",prop: "fileSize",scopedSlots: "fileSize",width: 200,},
];// 数据源
const tableData = ref({});
// 表格选项
const tableOptions = {extHeight: 20,selectType: "checkbox",
};// 获得数据;
const loadDataList = async () => {let params = {// 页码pageNo: tableData.value.pageNo,// 分页大小pageSize: tableData.value.pageSize,};if (params.category !== "all") {delete params.filePid;}let result = await proxy.Request({url: api.loadDataList,params,});if (!result) {return;}tableData.value = result.data;
};// 当鼠标放在当前行时,分享下载等图标出现
// 展示操作
const showOp = (row) => {// 关闭所有的显示tableData.value.list.forEach((element) => {element.showOp = false;});// 只开启当前显示row.showOp = true;
};// 取消展示
const cancelShowOp = (row) => {row.showOp = false;
};// 行选中
// 多选 批量选中
const selectFileIdList = ref([]);
const rowSelected = (rows) => {selectFileIdList.value = [];rows.forEach((item) => {selectFileIdList.value.push(item.fileId);});
};const revertIdList = ref([]);
// 还原/恢复(单个)
const revert = (row) => {revertIdList.value = [row.fileId];revertDone();
};// 批量还原/恢复
const revertBatch = () => {if (selectFileIdList.value.length == 0) {return;}revertIdList.value = selectFileIdList.value;revertDone();
};// 还原http请求
const revertDone = async () => {proxy.Confirm(`你确定要还原吗?`, async () => {let result = await proxy.Request({url: api.recoverFile,params: {fileIds: revertIdList.value.join(","),},});if (!result) {return;}proxy.Message.success("还原成功");loadDataList();});
};const emit = defineEmits(["reload"]);
const delIdList = ref([]);
// 删除(单个)
const delFile = (row) => {delIdList.value = [row.fileId];delDone();
};// 批量删除
const delBatch = () => {if (selectFileIdList.value.length == 0) {return;}delIdList.value = selectFileIdList.value;delDone();
};// 删除http请求
const delDone = async () => {proxy.Confirm(`你确定要删除吗?`, async () => {let result = await proxy.Request({url: api.delFile,params: {fileIds: delIdList.value.join(","),},});if (!result) {return;}proxy.Message.success("删除成功");loadDataList();emit("reload");});
};
</script><style lang="scss" scoped>
@import "@/assets/file.list.scss";.file-list {margin-top: 10px;.file-item {.op {width: 120px;}}
}
</style>

二、设置(管理员)

1.用户文件

src/views/admin/Filelist.vue

<template><!-- 设置->用户文件 --><div><!-- 头部搜索框+按钮 --><div class="top"><!-- 头部按钮处 --><div class="top-op"><div class="search-panel"><el-input clearable placeholder="请输入文件名搜索" v-model="fileNameFuzzy" @keyup.enter="search"><template #suffix><i class="iconfont icon-search" @click="search"></i></template></el-input></div><!-- 刷新 --><div class="iconfont icon-refresh" @click="loadDataList"></div><!-- 删除按钮 --><el-button :style="{ 'margin-left': '10px' }" @click="delFileBatch" type="danger":disabled="selectFileIdList.length == 0"><span class="iconfont icon-del"></span>&nbsp批量删除</el-button></div><!-- 导航 --><Navigation ref="navigationRef" @navChange="navChange"></Navigation></div><!-- 文件列表 --><div class="file-list" v-if="tableData.list && tableData.list.length > 0"><Table :columns="columns" :showPagination="true" :dataSource="tableData" :fetch="loadDataList":initFetch="false" :options="tableOptions" @rowSelected="rowSelected"><!-- 文件名 --><template #fileName="{ index, row }"><!-- showOp(row) 当鼠标放在当前行时,分享下载等图标出现 --><!-- cancelShowOp(row) 当鼠标离开当前行时,分享下载等图标消失 --><div class="file-item" @mouseenter="showOp(row)" @mouseleave="cancelShowOp(row)"><!-- 显示文件图标 --><template v-if="(row.fileType == 3 || row.fileType == 1) && row.status == 2"><!-- 如果文件类型是图片或者视频,且已经成功转码,则执行 Icon中的cover --><Icon :cover="row.fileCover" :width="32"></Icon></template><template v-else><!-- 如果文件夹类型是文件,则文件类型是该文件类型 --><Icon v-if="row.folderType == 0" :fileType="row.fileType"></Icon><!-- 如果文件夹类型是目录,则文件类型就是目录0 --><Icon v-if="row.folderType == 1" :fileType="0"></Icon></template><!-- 显示文件名称 --><!-- v-if="!row.showEdit" 如果该行文件没有编辑 --><span class="file-name" v-if="!row.showEdit" :title="row.fileName"><span @click="preview(row)">{{ row.fileName }}</span><span v-if="row.status == 0" class="transfer-status">转码中</span><span v-if="row.status == 1" class="transfer-status transfer-fail">转码失败</span></span><!-- 点击新建文件夹时显示行 --><div class="edit-panel" v-if="row.showEdit"><el-input v-model.trim="row.fileNameReal" ref="editNameRef" :maxLength="190"@keyup.enter="saveNameEdit(index)"><template #suffix>{{ row.fileSuffix }}</template></el-input><!-- 对号 确定 --><span :class="['iconfont icon-right1',row.fileNameReal ? '' : 'not-allow',]" @click="saveNameEdit(index)"></span><!-- 叉号 取消 --><span class="iconfont icon-error" @click="cancelNameEdit(index)"></span></div><!-- 当鼠标放在当前行时显示 --><span class="op"><template v-if="row.showOp && row.fileId && row.status == 2"><!-- 只有当是文件夹时才可下载 --><span class="iconfont icon-download" v-if="row.folderType == 0" @click="download(row)">下载</span><span class="iconfont icon-del" @click="delFile(row)">删除</span></template></span></div></template><!-- 文件大小 --><template #fileSize="{ index, row }"><span v-if="row.fileSize">{{ proxy.Utils.size2Str(row.fileSize) }}</span></template></Table></div></div>
</template><script setup>
import { ref, reactive, getCurrentInstance, nextTick, computed } from "vue";
const { proxy } = getCurrentInstance();const api = {loadDataList: "/admin/loadFileList",delFile: "/admin/delFile",createDownloadUrl: "/admin/createDownloadUrl",download: "/api/admin/download",
};// 列表头信息
const columns = [{label: "文件名",prop: "fileName",scopedSlots: "fileName",},{label: "发布人",prop: "nickName",width: 250,},{label: "修改时间",prop: "lastUpdateTime",width: 200,},{label: "文件大小",prop: "fileSize",scopedSlots: "fileSize",width: 200,},
];// 搜索功能
const search = () => {showLoading.value = true;loadDataList();
};// 数据源
const tableData = ref({});
// 表格选项
const tableOptions = {extHeight: 50,selectType: "checkbox",
};
// 文件名
const fileNameFuzzy = ref();const showLoading = ref(true);// 当前文件夹
const currentFolder = ref({ fileId: 0 });// 获得数据;
const loadDataList = async () => {let params = {// 页码pageNo: tableData.value.pageNo,// 分页大小pageSize: tableData.value.pageSize,// 文件名(模糊)fileNameFuzzy: fileNameFuzzy.value,// 文件父idfilePid: currentFolder.value.fileId,};let result = await proxy.Request({url: api.loadDataList,showLoading: showLoading,params,});if (!result) {return;}tableData.value = result.data;
};// 当鼠标放在当前行时,分享下载等图标出现
const showOp = (row) => {// 关闭所有的显示tableData.value.list.forEach((element) => {element.showOp = false;});// 只开启当前显示row.showOp = true;
};const cancelShowOp = (row) => {row.showOp = false;
};// 行选中
// 多选 批量选中
const selectFileIdList = ref([]);
const rowSelected = (rows) => {selectFileIdList.value = [];rows.forEach((item) => {selectFileIdList.value.push(item.userId + "_" + item.fileId);});
};// 删除单个文件
const delFile = (row) => {proxy.Confirm(`你确定要删除【$row.fileName】吗?删除的文件可在 10 天内通过回收站还原`,async () => {let result = await proxy.Request({url: api.delFile,params: {fileIdAndUserIds: row.userId + "_" + row.fileId,},});if (!result) {return;}proxy.Message.success("删除成功");// 重新获取数据loadDataList();});
};// 批量删除文件
const delFileBatch = () => {if (selectFileIdList.value.length == 0) {return;}proxy.Confirm(`你确定要删除这些文件吗?删除的文件可在 10 天内通过回收站还原`,async () => {let result = await proxy.Request({url: api.delFile,params: {fileIdAndUserIds: selectFileIdList.value.join(","),},});if (!result) {return;}proxy.Message.success("删除成功");// 重新获取数据loadDataList();});
};// 预览
const previewRef = ref();
const preview = (data) => {// 如果是目录(文件夹)if (data.folderType == 1) {navigationRef.value.openFolder(data);return;}if (data.status != 2) {proxy.Message.warning("文件未完成转码,无法预览");return;}previewRef.value.showPreview(data, 1);
};// 目录
const navChange = (data) => {const { curFolder } = data;currentFolder.value = curFolder;showLoading.value = true;loadDataList();
};// 下载文件
const download = async (row) => {let result = await proxy.Request({url: api.createDownloadUrl + "/" + row.userId + "/" + row.fileId,});if (!result) {return;}window.location.href = api.download + "/" + result.data;
};
</script><style lang="scss" scoped>
@import "@/assets/file.list.scss";.search-panel {margin-left: 0px !important;
}.file-list {margin-top: 10px;.file-item {.op {width: 120px;}}
}
</style>

2.用户管理

src/views/admin/UserList.vue

<template><!-- 设置->用户管理 --><div class="top-panel"><el-form :model="searchFormData" label-width="80px" @submit.prevent><el-row><!-- 用户昵称+搜索框 --><el-col :span="4"><el-form-item label="用户昵称"><el-input clearable placeholder="支持模糊搜索" v-model.trim="searchFormData.nickNameFuzzy"@keyup.enter="loadDataList"></el-input></el-form-item></el-col><!-- 状态选择:启用禁用 --><el-col :span="4"><!-- 下拉框 --><el-form-item label="状态"><el-select clearable placeholder="请选择状态" v-model="searchFormData.status"><el-option :value="1" label="启用"></el-option><el-option :value="0" label="禁用"></el-option></el-select></el-form-item></el-col><!-- 查询按钮 --><el-col :span="4" :style="{ 'padding-left': '10px' }"><el-button type="primary" @click="loadDataList"> 查询 </el-button></el-col></el-row></el-form></div><div class="file-list"><Table :columns="columns" :showPagination="true" :dataSource="tableData" :fetch="loadDataList":options="tableOptions"><!-- 头像+昵称 --><template #avatar="{ index, row }"><div class="avatar"><Avatar :userId="row.userId" :avatar="row.qqAvatar"></Avatar></div></template><!-- 空间使用 --><template #space="{ index, row }">{{ proxy.Utils.size2Str(row.useSpace) }}/{{proxy.Utils.size2Str(row.totalSpace)}}</template><!-- 状态显示:启用禁用 --><template #status="{ index, row }"><span v-if="row.status == 1" style="color: #529b2e">启用</span><span v-if="row.status == 0" style="color: #f56c6c">禁用</span></template><!-- 操作:分配空间+启用禁用选择 --><template #op="{ index, row }"><span class="a-link" @click="updateSpace(row)">分配空间</span><el-divider direction="vertical" /><span class="a-link" @click="updateUserStatus(row)">{{ row.status == 0 ? "启用" : "禁用" }}</span></template></Table></div><!-- 点击分配空间的弹框 --><Dialog :show="dialogConfig.show" :title="dialogConfig.title" :buttons="dialogConfig.buttons" width="500px":showCancel="false" @close="dialogConfig.show = false"><el-form :model="formData" :rules="rules" ref="formDataRef" label-width="80px" @submit.prevent><el-form-item label="昵称">{{ formData.nickName }}</el-form-item><el-form-item label="空间大小" prop="changeSpace"><el-input clearable placeholder="请输入空间大小" v-model="formData.changeSpace"><template #suffix>MB</template></el-input></el-form-item></el-form></Dialog>
</template><script setup>
import { ref, reactive, getCurrentInstance, nextTick } from "vue";
import { useRouter, useRoute } from "vue-router";
const { proxy } = getCurrentInstance();
const router = useRouter();
const route = useRoute();const api = {loadDataList: "/admin/loadUserList",updateUserStatus: "/admin/updateUserStatus",updateUserSpace: "/admin/updateUserSpace",
};//列表
const columns = [{label: "头像",prop: "avatar",width: 80,scopedSlots: "avatar",},{label: "昵称",prop: "nickName",},{label: "邮箱",prop: "email",},{label: "空间使用",prop: "space",scopedSlots: "space",},{label: "加入时间",prop: "joinTime",},{label: "最后登录时间",prop: "lastLoginTime",},{label: "状态",prop: "status",scopedSlots: "status",width: 80,},{label: "操作",prop: "op",width: 150,scopedSlots: "op",},
];const searchFormData = ref({});
// 数据源
const tableData = ref({});
// 表格选项
const tableOptions = {extHeight: 20,
};// 获得数据;
const loadDataList = async () => {let params = {// 页码pageNo: tableData.value.pageNo,// 分页大小pageSize: tableData.value.pageSize,};Object.assign(params, searchFormData.value);let result = await proxy.Request({url: api.loadDataList,params,});if (!result) {return;}tableData.value = result.data;
};// 修改状态
const updateUserStatus = (row) => {proxy.Confirm(`你确定要【${row.status == 0 ? "启用" : "禁用"}】吗?`,async () => {let result = await proxy.Request({url: api.updateUserStatus,params: {userId: row.userId,status: row.status == 0 ? 1 : 0,},});if (!result) {return;}loadDataList();});
};// 分配空间:修改空间大小
const dialogConfig = ref({show: false,title: "修改空间大小",buttons: [{type: "primary",text: "确定",click: (e) => {submitForm();},},],
});
const formData = ref({});
const formDataRef = ref();
// 表单校验
const rules = {changeSpace: [{ required: true, message: "请输入空间大小" }],
};// 更新空间
const updateSpace = (data) => {dialogConfig.value.show = true;nextTick(() => {formDataRef.value.resetFields();formData.value = Object.assign({}, data);});
};// 提交表单,刷新列表
const submitForm = () => {formDataRef.value.validate(async (valid) => {if (!valid) {return;}let params = {};Object.assign(params, formData.value);let result = await proxy.Request({url: api.updateUserSpace,params: params,});if (!result) {return;}dialogConfig.value.show = false;proxy.Message.success("操作成功");loadDataList();});
};</script><style lang="scss" scoped>
.top-panel {margin-top: 10px;
}.avatar {width: 50px;height: 50px;border-radius: 25px;overflow: hidden;img {width: 100%;height: 100;}
}
</style>

3.系统设置

src/views/admin/SysSetting.vue

<template><!-- 设置->系统设置 --><div class="sys-setting-panel"><el-form :model="formData" :rules="rules" ref="formDataRef" label-width="150px" @submit.prevent><el-form-item label="注册邮件标题" prop="registerEmailTitle"><el-input clearable placeholder="邮箱验证码" v-model.trim="formData.registerEmailTitle"></el-input></el-form-item><el-form-item label="注册邮件内容" prop="registerEmailContent"><el-input clearable placeholder="请输入注册邮箱验证码邮箱内容%s占位符位验证码内容"v-model.trim="formData.registerEmailContent"></el-input></el-form-item><el-form-item label="初始空间大小" prop="userInitUseSpace"><el-input clearable placeholder="初始空间大小" v-model.trim="formData.userInitUseSpace"></el-input></el-form-item><el-form-item><el-button type="primary" @click="saveSettings">保存</el-button></el-form-item></el-form></div>
</template><script setup>
import { ref, reactive, getCurrentInstance, nextTick } from "vue";
import { useRouter, useRoute } from "vue-router";
const { proxy } = getCurrentInstance();
const router = useRouter();
const route = useRoute();const api = {getSysSettings: "/admin/getSysSettings",saveSettings: "/admin/saveSysSettings",
};const formData = ref({});
const formDataRef = ref();
const rules = {registerEmailTitle: [{ required: true, message: "请输入注册邮件验证码邮件标题" },],registerEmailContent: [{ required: true, message: "请输入注册邮件验证码邮件内容" },],userInitUseSpace: [{ required: true, message: "请输入初始化空间大小" },{ validator: proxy.Verify.number, message: "空间大小只能是数字" },],
};const getSysSettings = async () => {let result = await proxy.Request({url: api.getSysSettings,});if (!result) {return;}formData.value = result.data;
};
getSysSettings();const saveSettings = () => {formDataRef.value.validate(async (valid) => {if (!valid) {return;}let params = {};Object.assign(params, formData.value);let result = await proxy.Request({url: api.saveSettings,params: params,});if (!result) {return;}proxy.Message.success("保存成功");});
};
</script><style lang="scss" scoped>
.sys-setting-panel {margin-top: 20px;width: 600px;
}
</style>

源码:GitHub - yeguouu/easypanuu: 实现网盘的登录注册,文件的批量上传、新建、在线预览、下载、链接分享、移动以及删除还原等文件管理功能

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/331118.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[保姆式教程]使用目标检测模型YOLO V8 OBB进行旋转目标的检测:训练自己的数据集(基于卫星和无人机的农业大棚数据集)

最近需要做基于卫星和无人机的农业大棚的旋转目标检测&#xff0c;基于YOLO V8 OBB的原因是因为尝试的第二个模型就是YOLO V8&#xff0c;后面会基于YOLO V9模型做农业大棚的旋转目标检测。YOLO V9目前还不能进行旋转目标的检测&#xff0c;需要修改代码 PS:欢迎大家分享农业大…

Plotly库利用滑块创建数据可视化

使用了Plotly库来创建一个数据可视化图表&#xff0c;并使用滑块来控制显示哪些数据 import plotly.graph_objects as go from plotly.subplots import make_subplots# 示例数据 x [1, 2, 3, 4, 5] y1 [1, 2, 3, 4, 5] y2 [5, 4, 3, 2, 1] y3 [2, 3, 1, 5, 4]# 创建子图 f…

12306技术内幕

公司内部做的一次技术分享 文章目录 12306的成就12306系统特点12306系统难点解决思路产品角度技术角度余票库存的表如何设计&#xff1f; 抢票软件推荐巨人的肩膀 对于未公开的技术部分&#xff0c;只能结合已公开的信息&#xff0c;去做大胆的猜想。 本文提到的一些解决方案&…

【车载开发系列】Autosar中的VFB

【车载开发系列】Autosar中的VFB # 【车载开发系列】Autosar中的VFB 【车载开发系列】Autosar中的VFB一. 什么是VFB二. VFB的优点与缺点1&#xff09;VFB的缺点2&#xff09;VFB的好处 三. RTE与VFB之间关系四. 总线架构模式 一. 什么是VFB Virtual Functional Bus。它就是虚拟…

Python函数、类和方法

大家好&#xff0c;当涉及到编写可维护、可扩展且易于测试的代码时&#xff0c;Python提供了一些强大的工具和概念&#xff0c;其中包括函数、类和方法。这些是Python编程中的核心要素&#xff0c;可以帮助我们构建高效的测试框架和可靠的测试用例。 本文将探讨Python中的函数、…

Vue3实战笔记(43)—Vue3组合式API下封装可复用ECharts图表组件

文章目录 前言一、封装echart图标钩子二、使用步骤总结 前言 接上文&#xff0c;已经安装好了ECharts&#xff0c;开始封装组件方便使用。 一、封装echart图标钩子 首先应用我们之前学习的钩子方式&#xff0c;在hooks目录下创建一个名为 useECharts.js 的文件&#xff0c;用…

从零起航,Python编程全攻略

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、Python入门之旅 二、Python进阶之道 三、Python爬虫实战 四、Python数据分析利器 五…

linux系统——终止进程命令

linux进程&#xff0c;有所谓进程树的概念&#xff0c;在此之上&#xff0c;有父进程与子进程 pgrep进程名可以查看进程信息 同时&#xff0c;此命令也可以使用参数进行调节 关于kill有一系列命令参数 echo $?可以输出上次命令执行的情况

【Spring Boot】深度复盘在开发搜索引擎项目中重难点的整理,以及遇到的困难和总结

&#x1f493; 博客主页&#xff1a;从零开始的-CodeNinja之路 ⏩ 收录文章&#xff1a;【Spring Boot】深度复盘在开发搜索引擎项目中重难点的整理&#xff0c;以及遇到的困难和总结 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 什么是搜索引…

Ajax异步删除

在页面上定义一个按钮 <button type"button" class"btn"><a href"JavaScript:;" class"id" b_id"{{$attachment[id]}}">删除</a></button> js代码 <script>$(.id).click(function (){va…

[读论文]精读Self-Attentive Sequential Recommendation

论文链接&#xff1a;https://arxiv.org/abs/1808.09781 其他解读文章&#xff1a;https://mp.weixin.qq.com/s/cRQi3FBi9OMdO7imK2Y4Ew 摘要 顺序动态是许多现代推荐系统的一个关键特征&#xff0c;这些系统试图根据用户最近执行的操作来捕获用户活动的“上下文”。为了捕捉…

ES基础概念

本文不介绍如何使用ES&#xff08;使用ES见&#xff1a;&#xff09; 1.ES生态圈 ES&#xff1a; Logstash&#xff1a;数据处理服务程序&#xff0c;解析转换加工数据&#xff1b; Kibana&#xff1a;数据展示、集群管理&#xff0c;数据可视化、ES管理与监控、报表等&#xf…

区块链钱包如果丢失了私钥或助记词,资产还能恢复吗?

如果你丢失了区块链钱包的私钥或助记词&#xff08;通常是用于恢复钱包的短语或种子&#xff09;&#xff0c;那么你的资产在大多数情况下是无法恢复的。私钥是访问和控制你在区块链上资产的唯一凭证&#xff0c;而助记词&#xff08;如BIP39标准中的12、18、24个单词的短语&am…

【数据分析面试】53.推送消息的分布情况(SQL)

题目 我们有两个表&#xff0c;一个是 notification_deliveries 表&#xff0c;另一个是包含 created 和购买 conversion dates 的 users 表。如果用户没有购买&#xff0c;那么 conversion_date 列为 NULL。 编写一个查询&#xff0c;以获取用户转换前的推送通知总数的分布情…

无人机监测系统:天空之眼,精准掌握地球脉动

在当今信息化快速发展的时代&#xff0c;无人机技术以其独特的优势&#xff0c;正在成为资源调查、环境监测和规划支持的重要工具。无人机监测系统通过搭载多种传感器和设备&#xff0c;能够快速、高效地获取地表信息&#xff0c;为决策提供科学依据。 项目背景 随着全球环境…

SpringMVC接收请求参数的方式:

接收简单变量的请求参数 直接使用简单变量作为形参进行接收&#xff08;这里简单变量名称需要与接收的参数名称保持一致&#xff0c;否则需要加上RequestParam注解&#xff09;&#xff1a; 细节&#xff1a; 1&#xff1a;SpringMVC会针对常见类型&#xff08;八种基本类型及…

二叉排序树的创建

二叉排序树就是节点经过排序构建起的二叉树&#xff0c;其有以下性质&#xff1a; 1. 若它的左子树不为空&#xff0c;则左子树上所有节点的值均小于它的根节点的值。 2. 若它的右子树不为空&#xff0c;则右子树上所有节点的值均大于它的根节点的值。 3. 它的左、右子树也分…

python期末作业:批量爬取站长之家的网站排行榜数据并保存,数据分析可视化

爬虫作业,含python爬取数据和保存文件,数据分析使用pyecharts做数据可视化 整体上分析网站的排名,直观看各个网站的热度。 数据分析之后大致的效果: 整个项目分为两个大的部分,第一部分就是抓取网站排名数据,然后保存为Excel、csv等格式,其次就是从文件中…

下一代Docker会让部署更丝滑吗

下一代Docker会让部署更丝滑吗 如何通俗易懂的理解DockerDocker有什么缺点Docker与AI结合&#xff0c;会让部署更加丝滑吗 随着互联网技术的不断发展&#xff0c;单机系统已经无法满足日益正常的用户量以及正常处理用户请求&#xff0c;这个时候就需要进行多机部署&#xff0c;…

设计新境界:大数据赋能UI的创新美学

设计新境界&#xff1a;大数据赋能UI的创新美学 引言 随着大数据技术的蓬勃发展&#xff0c;它已成为推动UI设计创新的重要力量。大数据不仅为界面设计提供了丰富的数据资源&#xff0c;还赋予了设计师以全新的视角和工具来探索美学的新境界。本文将探讨大数据如何赋能UI设计…