当前位置: 首页 > news >正文

thinkphp8+layui多图上传,带删除\排序功能

环境:thinkphp8.1\php8.3\layui2.10; layui的版本必须是2.8.8版本以上;

layui.define(['jquery', 'upload', 'layer'], function (exports) {const $ = layui.jquery;const upload = layui.upload;const layer = layui.layer;const multiUpload = {/*** 初始化上传组件* @param {Object} options*/init: function (options) {const opts = $.extend({elemSelect: '#uploadBtn',elemPreview: '#upload-preview',elemStart: '#startUpload',elemHidden: '#imagePaths',uploadUrl: '/api/index/upload'}, options);let fileMap = new Map();let imgIndex = 0;// 选择图片 + 本地预览upload.render({elem: opts.elemSelect,auto: false,multiple: true,choose: function (obj) {const previewContainer = $(opts.elemPreview);obj.preview(function (index, file, result) {imgIndex++;const id = 'img-' + imgIndex;fileMap.set(id, file);const card = $(`<div class="img-card" id="${id}"><img src="${result}" alt="${file.name}"><button type="button" class="delete-btn" title="删除图片">&times;</button></div>`);card.find('.delete-btn').on('click', function () {fileMap.delete(id);card.remove();updateImageList();});previewContainer.append(card);});}});// 拖拽排序$(opts.elemPreview).sortable({items: '.img-card',cursor: 'move',opacity: 0.7,tolerance: 'pointer',update: function () {updateImageList();}});// 更新隐藏字段function updateImageList() {const ids = $(opts.elemPreview + ' .img-card').map(function () {return this.id;}).get();$(opts.elemHidden).val(ids.join('|'));}// 更新URL(仅相对路径)function updateImageListUrls() {const urls = [];$(opts.elemPreview + ' .img-card').each(function () {let url = $(this).attr('data-url');if (url) {url = url.replace(/^https?:\/\/[^/]+\/storage\//, '');urls.push(url);}});$(opts.elemHidden).val(urls.join('|'));console.log('当前图片相对路径顺序:', urls.join('|'));}// 点击上传$(opts.elemStart).on('click', function () {const orderedIds = $(opts.elemPreview + ' .img-card').map(function () {return this.id;}).get();if (orderedIds.length === 0) {layer.msg('请先选择图片', { icon: 0 });return;}const formData = new FormData();for (const id of orderedIds) {const file = fileMap.get(id);if (file) formData.append('file[]', file);}layer.msg('上传中...', { icon: 16, shade: 0.3, time: 0 });$.ajax({url: opts.uploadUrl,type: 'POST',data: formData,processData: false,contentType: false,dataType: 'json'}).done(function (res) {layer.closeAll('loading');if (res.code === 0) {const baseUrl = window.location.origin + '/storage/';const urls = res.data.urls.map(p => baseUrl + p);$(opts.elemPreview + ' .img-card').each(function (i) {const img = $(this).find('img');if (urls[i]) img.attr('src', urls[i]);$(this).attr('data-url', urls[i]);});updateImageListUrls();layer.msg('上传成功,共 ' + urls.length + ' 张', { icon: 1 });} else {layer.msg('上传失败:' + res.msg, { icon: 2 });}}).fail(function (xhr, status, error) {layer.closeAll('loading');console.error('AJAX 错误:', status, error);layer.msg('上传接口异常', { icon: 2 });}).always(function () {console.log('上传请求结束');});});// 暴露可用方法return {reload: updateImageListUrls,clear: function () {$(opts.elemPreview).empty();$(opts.elemHidden).val('');fileMap.clear();}};}};// 输出模块exports('multiUpload', multiUpload);
});

定义多图上传模块,放到 layui\modules\multiUpload.js;

<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>多图上传,预览,删除,排序(顺序同步)</title><link href="__ADMIN__/layui/css/layui.css" rel="stylesheet"><link href="__INDEX__/jquery-ui/themes/base/jquery-ui.css" rel="stylesheet"><script src="__INDEX__/jquery/jquery.js"></script><script src="__INDEX__/jquery-ui/jquery-ui.min.js"></script><script src="__ADMIN__/layui/layui.js"></script><link href="__INDEX__/upload/upload.css" rel="stylesheet">
</head>
<body>
<div class="layui-container"><div class="layui-upload"><div class="layui-btn-container"><button type="button" class="layui-btn layui-btn-normal" id="uploadBtn"><i class="layui-icon layui-icon-upload"></i> 选择多图</button><button type="button" class="layui-btn layui-btn-danger" id="startUpload"><i class="layui-icon layui-icon-release"></i> 开始上传</button></div><blockquote class="layui-elem-quote layui-quote-nm">预览图(可拖拽排序):<div id="upload-preview" class="layui-upload-list"></div></blockquote><input type="hidden" id="imagePaths" name="images" value=""></div>
</div><script>layui.config({base: '__ADMIN__/'  // 模块目录路径}).use(['index', 'multiUpload'], function () {const multiUpload = layui.multiUpload;// 初始化multiUpload.init({elemSelect: '#uploadBtn',elemPreview: '#upload-preview',elemStart: '#startUpload',elemHidden: '#imagePaths',uploadUrl: '/api/index/upload'});});
</script>
</body>
</html>

排序:这里我用到jquery-ui组件的排序功能,版本:1.14;jQuery3.7;

/*** 多图上传接口* 路径:/api/index/upload*/public function upload(): Json{// 获取前端统一上传字段 file[]$files = Request::file('file');if (empty($files)) {return json(['code' => 1, 'msg' => '未选择文件']);}$paths = [];try {foreach ($files as $file) {// 存入 storage/topic/YYYYMMDD/$savePath = Filesystem::putFile("", $file);// 统一路径格式为 /$paths[] = str_replace('\\', '/', $savePath);}} catch (\Throwable $e) {return json(['code' => 2,'msg'  => '上传失败:' . $e->getMessage(),]);}// 生成可访问 URL$urls = array_map(fn($p) => $p, $paths);return json(['code' => 0,'msg'  => '上传成功','data' => ['paths' => implode('|', $paths),'urls'  => $urls,'count' => count($paths),],]);}

这是后端的代码,欢迎大家指正!

http://www.dtcms.com/a/486708.html

相关文章:

  • LeetCode 合并K个升序链表
  • FFmpeg 基本API avformat_alloc_context 函数内部调用流程分析
  • ubuntu系统中ffmpeg+x264简易编译安装指南
  • FLAC to MP3 批量转换 Python
  • 开源鸿蒙6.1和8.1版本被确定为LTS建议版本,最新路标正式发布!-转自开源鸿蒙OpenHarmony社区
  • linux sdl图形编程之helloworld.
  • 开发一个网站系统报价电子商务网站建设试卷及答案
  • 瑞芯微算法环境搭建(2)------编译opencv
  • 计算机视觉(opencv)——人脸网格关键点检测
  • 自己做网站投入编程培训机构需要哪些证件
  • AXI总线的基础知识
  • 【泛微OA】泛微OA平台实现计算具体的天数
  • 「深度学习笔记1」深度学习全面解析:从基本概念到未来趋势
  • puppeteer 生成pdf,含动态目录,目录带页码
  • 深度学习的卷积神经网络中医舌诊断病系统-ResNet50与VGG16方法的比较研究
  • 如何查看网站空间wordpress图片多选
  • Android的Activity与intent知识点
  • 一、前置基础(MVC学习前提)_核心特性_【C# MVC 前置】委托与事件:从 “小区通知” 看懂 MVC 过滤器的底层逻辑
  • 网站建设年度汇报详情页设计理念怎么写
  • Spring Boot项目中Maven引入依赖常见报错问题解决
  • Android 13 启动的时候会显示一下logo,很不友好
  • seo网站快速排名外包关键词seo排名优化如何
  • Linux防火墙:核心机制与安全实践全解析
  • SX1261IMLTRT射频收发器Semtech赋能远距离物联网连接的低功耗射频芯片IC
  • Flutter---坐标网格图标
  • 邢台做网站多少钱洪泽网站建设
  • 整体设计 逻辑系统程序 之30 定稿V1 之1 含 4 套程序架构、三式模型与时空约束体系
  • 基于单片机的智能洗衣机的设计与实现(论文+源码)
  • 【ComfyUI】SDXL Revision 文本提示实现参考图像概念迁移生成
  • Zabbix 模板、监控项、图形指南