Laravel-admin 中 $form->table 图片上传时的 bug 问题

文章描述了在使用laravel-admin的JSON组件时,前端表格中的图片上传功能在编辑后提交时会丢失。作者分析了问题,发现新增时存在图片对象,但在不做改动直接编辑并提交时,图片数据丢失。

使用的是 laravel-admin 的 JSON 组件
问题代码存在与下面的 $form->table 中

protected function form()
{

$form = new Form(new Good());
……
f o r m − > t a b l e ( ′ s i z e ′ , f u n c t i o n ( form->table('size', function ( form>table(size,function(table) {
$table->text(‘sizes’, __(‘规格大小’));
$table->text(‘colors’, __(‘颜色分类’));
$table->text(‘sales’, __(‘价格’));
$table->text(‘sizecostprice’, __(‘成本价格’));
$table->text(‘sizestock’, __(‘库存’));
$table->image(‘sizeimg’, __(‘图片’));
});
……
}
前端展示界面如下:
在这里插入图片描述

加上上面代码后,前台界面显示、上传图片操作、确认提交等操作都正常;
添加完成后,再次编辑该数据,也可以正常显示;

问题在于,在编辑页面,不做任何改动直接提交后,$table->image(‘sizeimg’, __(‘图片’)); 的数据丢失了!
尝试查找原因
分别在新增和编辑时,打印 $form 数据,结果显示
新增时:
在这里插入图片描述

编辑后提交(不做任何改动,如果编辑时重新上传图片,还是可以正常存储到数据库的):
在这里插入图片描述

可以看到,新增时,sizeimg 是存在的,是一个文件对象;编辑提交后,sizeimg 丢失了

发现编辑时 sizeimg 不存在的问题后,考虑到是不是编辑时没有加载该参数 input 元素,所以又到前台编辑页面去查找,结果发现是有的,如下图:
在这里插入图片描述

可以看到,sizeimg 跟其他的 $table->text() 的字段都是同样存在的,但是不明白为什么在提交后会丢失

最后贴一下关于这个方法官方文档的使用说明:
解决方法
public function setSizeAttribute(KaTeX parse error: Expected '}', got 'EOF' at end of input: … if (isset(this->attributes[‘size’])){
o l d c o n t e n t = j s o n d e c o d e ( old_content = json_decode( oldcontent=jsondecode(this->attributes[‘size’],true);
foreach ($extra as KaTeX parse error: Expected 'EOF', got '&' at position 8: key => &̲val) {
// 如果旧数据未删除,且当前不存在图片,则将旧图片路径添加进去
if (isset( o l d c o n t e n t [ old_content[ oldcontent[key]) && !isset($val[‘img’])) {
$val[‘img’] = o l d c o n t e n t [ old_content[ oldcontent[key][‘img’] ?? ‘’;
}
}
}
t h i s − > a t t r i b u t e s [ ′ a t t r ′ ] = j s o n e n c o d e ( a r r a y v a l u e s ( this->attributes['attr'] = json_encode(array_values( this>attributes[attr]=jsonencode(arrayvalues(extra));
}

<style type="text/css"> #tNewsInfo-demo { overflow-y: scroll; } .layui-layer-content { overflow: scroll; } </style> <div class="layui-card"> <div class="layui-card-header"> <h2 class="header-title">健康资讯表</h2> <span class="layui-breadcrumb pull-right"> <a href="#!console">首页</a> <a><cite>健康资讯表</cite></a> </span> </div> <div class="layui-card-body"> <div class="layui-row"> <form class="layui-form layui-col-md12 x-so" id="complain_search"> 标题: <div class="layui-input-inline"> <input type="text" name="headline" id="headline" placeholder="请输入标题" autocomplete="off" class="layui-input"> </div> 新闻类型: <div class="layui-input-inline"> <select name="newsName" id="newsName" lay-filter="newsName"> <option value="">---请选择---</option> </select> </div> 发布状态: <div class="layui-input-inline"> <select name="postauditState" id="postauditState"> <option value="" selected>---请选择---</option> <option value="1">未提交</option> <option value="2">正在审核(冻结)</option> <option value="3">审核通过(发布)</option> <option value="4">审核未通过</option> <option value="5">审核通过(发布后冻结)</option> </select> </div> <button id="search" class="layui-btn" lay-submit lay-filter="provinceSearch"> <i class="layui-icon"></i>搜索 </button> <button id="tNewsInfo-btn-add" class="layui-btn icon-btn"><i class="layui-icon"></i>添加</button> </form> </div> <!-- 数据表格 --> <table class="layui-table" id="tNewsInfo-table" lay-filter="tNewsInfo-table"></table> </div> </div> <script type="text/javascript" charset="utf-8" src="module/neditor/neditor.config.js"></script> <script type="text/javascript" charset="utf-8" src="module/neditor/neditor.all.js"></script> <script type="text/javascript" charset="utf-8" src="module/neditor/neditor.service.js"></script> <script type="text/javascript" charset="utf-8" src="module/neditor/i18n/zh-cn/zh-cn.js"></script> <script type="text/javascript" src="module/neditor/third-party/browser-md5-file.min.js"></script> <!-- 表单弹窗 --> <script type="text/html" id="tNewsInfo-model"> <form id="tNewsInfo-form" lay-filter="tNewsInfo-form" class="layui-form model-form"> <input type="hidden" name="id" /> <div class="layui-form-item"> <label class="layui-form-label">新闻类型</label> <div class="layui-input-block"> <select name="newsType" id="newsType" lay-filter="newsType"> <option value="">-请选择新闻类型-</option> </select> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">标题</label> <div class="layui-input-block"> <input name="headline" placeholder="请输入标题" type="text" class="layui-input" maxlength="20" lay-verify="required" required /> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">发布间</label> <div class="layui-input-block"> <input name="pubdate" id="pubdate" placeholder="请输入发布间" type="text" class="layui-input" maxlength="20" lay-verify="required" required /> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">文本类型</label> <div class="layui-input-block"> <input type="radio" name="ctype" value="1" title="富文本" checked /> <input type="radio" name="ctype" value="2" title="超链接" /> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">封面图片:</label> <div class="layui-upload layui-input-block"> <input type="hidden" name="thumbnail" /> <button type="button" class="layui-btn layui-btn-primary" id="fileBtn"> <i class="layui-icon"></i>选择文件 </button> </div> <blockquote class="layui-elem-quote layui-quote-nm" style="margin-top: 10px;"> 预览图: <div class="layui-upload-list" id="demo2"></div> </blockquote> </div> <div class="layui-form-item"> <label class="layui-form-label">资讯内容</label> <div class="layui-input-block"> <textarea name="contents" id="contents"></textarea> </div> </div> <div class="layui-form-item model-form-footer"> <button class="layui-btn layui-btn-primary" ew-event="closeDialog" type="button">取消</button> <button class="layui-btn" lay-filter="tNewsInfo-form-submit" lay-submit>保存</button> </div> </form> </script> <!-- 新闻状态列 --> <script type="text/html" id="newsinfo-table-state"> <input type="checkbox" lay-filter="newsinfo-table-state" value="{{d.id}}" lay-skin="switch" lay-text="发布|冻结" {{d.postauditState==3?'checked':''}} /> </script> <script type="text/html" id="newsinfo-table-stick"> <input type="checkbox" lay-filter="newsinfo-table-stick" value="{{d.id}}" lay-skin="switch" lay-text="置顶|取消" {{d.stick==0?'checked':''}} /> </script> <!-- 表格操作列 --> <script type="text/html" id="tNewsInfo-table-bar"> <a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="edit">修改</a> <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a> </script> <script> layui.use(['form', 'table', 'util', 'config', 'admin', 'formSelects', "layedit", "laydate", "upload"], function () { var form = layui.form; var table = layui.table; var config = layui.config; var layer = layui.layer; var util = layui.util; var admin = layui.admin; var formSelects = layui.formSelects; var layedit = layui.layedit; var laydate = layui.laydate; var upload = layui.upload; // 渲染表格 var renderTable = function () { table.render({ id: "provinceReload", elem: '#tNewsInfo-table', url: config.base_server + 'api-primaryJydc/newsinfo/getList', where: { access_token: config.getToken().access_token }, page: true, cols: [[ { type: 'numbers', title: '序号' }, { field: 'typeName', sort: true, title: '新闻类型' }, { field: 'headline', sort: true, title: '标题' }, { field: 'postauditState', sort: true, templet: "#newsinfo-table-state", title: '帖子状态 ' }, { field: 'pubdate', sort: true, templet: function (d) { return util.toDateString(d.pubdate); }, title: '发布间' }, { field: 'updateTime', sort: true, templet: function (d) { return util.toDateString(d.updateTime); }, title: '更新间' }, { field: 'stick', sort: true, templet: "#newsinfo-table-stick", title: '置顶' }, { align: 'center', toolbar: '#tNewsInfo-table-bar', title: '操作', width: 250 } ]] }); }; renderTable(); // 添加按钮点击事件 $('#tNewsInfo-btn-add').click(function () { showEditModel(); }); // 初始化新闻类别查询框 var getNewsType = function () { admin.req('api-primaryJydc/newsinfo/selectAllType', {}, function (datas) { $.each(datas.data, function (index, item) { var options = '<option value = "' + item.id + '">' + item.newsType + '</option>'; $('#newsName').append(options); // 往下拉菜单里添加元素 }); }, 'GET'); form.render('select'); }; getNewsType(); // 表单提交事件 form.on('submit(tNewsInfo-form-submit)', function (data) { layer.load(2); var url = ""; data.field.publishUserid = config.getUser().id; data.field.freezeUserid = config.getUser().id; if (data.field.id == '') { url = 'api-primaryJydc/newsinfo/' + 'save'; } else { url = 'api-primaryJydc/newsinfo/' + 'update'; } admin.req(url, JSON.stringify(data.field), function (data) { layer.closeAll('loading'); if (data.resp_code == 0) { layer.msg(data.resp_msg, { icon: 1, time: 500 }); table.reload('tNewsInfo-table'); layer.closeAll('page'); } else { layer.msg(data.resp_msg, { icon: 2, time: 500 }); } }, $('#tNewsInfo-form').attr('method')); return false; }); // 工具条点击事件 table.on('tool(tNewsInfo-table)', function (obj) { var data = obj.data; if (obj.event === 'edit') { // 修改 showEditModel(data); } else if (obj.event === 'del') { // 删除 doDelete(obj); } }); // 显示编辑弹窗 var showEditModel = function (data) { layer.open({ type: 1, title: data ? '修改健康资讯表' : '添加健康资讯表', area: ['1000px', '800px'], offset: '10px', maxmin: true, id: 'tNewsInfo-demo', skin: 'tNewsInfo-demo', content: $('#tNewsInfo-model').html(), resize: true, success: function () { admin.req('api-primaryJydc/newsinfo/selectAllType', {}, function (datas) { layer.closeAll('loading'); $.each(datas.data, function (index, item) { var option = '<option value = "' + item.id + '">' + item.newsType + '</option>'; $('#newsType').append(option); // 往下拉菜单里添加元素 }); }, 'GET'); $('#tNewsInfo-form')[0].reset(); $('#tNewsInfo-form').attr('method', 'POST'); if (data) { data.pubdate = util.toDateString(data.pubdate); $("input[name=ctype][value='1']").attr("checked", data.ctype == 1 ? true : false); $("input[name=ctype][value='2']").attr("checked", data.ctype == 2 ? true : false); form.val('tNewsInfo-form', data); var picture1 = data.thumbnail; if (null != picture1) { if (picture1.indexOf("http") != 0) { picture1 = "http://www.j1dc.cn/sss-web/download?filePath=" + picture1; } $('#demo2').append('<img src="' + picture1 + '" width="50px" height="50px" class="layui-upload-img">'); } form.render(); } // 初始化日期选择器 laydate.render({ elem: '#pubdate', type: 'datetime', format: 'yyyy-MM-dd HH:mm:ss' }); UE.delEditor('contents'); UE.getEditor('contents', { initialFrameHeight: 320, imageMaxSize: 1024 * 1024 * 10 // 设置上传图片的最大大小为 10MB }); loadingUpdate(); }, resizing: function (layero) { $(".layui-layer-content").css("height", $(layero).height() - 45); $("#tNewsInfo-demo").css("overflow", "scroll"); }, min: function (layero) { $(".layui-layer-content").css("height", $(layero).height() - 45); $("#tNewsInfo-demo").css("overflow", "scroll"); }, full: function (layero) { $(".layui-layer-content").css("height", $(layero).height() - 45); $("#tNewsInfo-demo").css("overflow", "scroll"); }, restore: function (layero) { $(".layui-layer-content").css("height", $(layero).height() - 45); $("#tNewsInfo-demo").css("overflow", "scroll"); } }); }; // 删除 var doDelete = function (obj) { layer.confirm('确定要删除吗?', function (i) { layer.close(i); layer.load(2); admin.req('api-primaryJydc/newsinfo/delete/' + obj.data.id, {}, function (data) { layer.closeAll('loading'); if (data.resp_code == 0) { layer.msg(data.resp_msg, { icon: 1, time: 500 }); obj.del(); } else { layer.msg(data.resp_msg, { icon: 2, time: 500 }); } }, 'DELETE'); }); }; // 修改新闻状态 form.on('switch(newsinfo-table-state)', function (obj) { layer.load(2); admin.req('api-primaryJydc/newsinfo/updateEnabled', { id: obj.elem.value, postauditState: obj.elem.checked ? 3 : 5, freezeUserid: config.getUser().id }, function (data) { layer.closeAll('loading'); if (data.resp_code == 0) { layer.msg(data.resp_msg, { icon: 1, time: 500 }); } else { layer.msg(data.resp_msg, { icon: 2, time: 500 }); $(obj.elem).prop('checked', !obj.elem.checked); form.render('checkbox'); } }, 'GET'); }); // 文件上传 var loadingUpdate = function () { upload.render({ elem: '#fileBtn', url: config.base_server + 'api-file/files-anon', accept: 'file', auto: true, before: function (obj) { layer.load(); // 上传loading this.data = { access_token: config.getToken().access_token }; // 预读本地文件示例,不支持ie8 obj.preview(function (index, file, result) { $(".layui-upload-img").remove(); $('#demo2').append('<img src="' + result + '" width="50px" height="50px" alt="' + file.name + '" class="layui-upload-img">'); }); }, done: function (data) { layer.closeAll('loading'); $("[name=thumbnail]").val(data.datas.url); // 移除了将图片插入富文本编辑器的代码 }, error: function (data) { layer.closeAll('loading'); } }); }; // 修改新闻置顶状态 form.on('switch(newsinfo-table-stick)', function (obj) { layer.load(2); admin.req('api-primaryJydc/newsinfo/updateStick', { id: obj.elem.value, stick: obj.elem.checked ? 0 : 1, freezeUserid: config.getUser().id }, function (data) { layer.closeAll('loading'); if (data.resp_code == 0) { layer.msg(data.resp_msg, { icon: 1, time: 500 }); } else { layer.msg(data.resp_msg, { icon: 2, time: 500 }); $(obj.elem).prop('checked', !obj.elem.checked); form.render('checkbox'); } }, 'GET'); }); // 搜索框查询加载方法 form.on('submit(provinceSearch)', function (data) { var formData = data.field; console.debug(formData); var newsType = formData.newsName, headline = formData.headline, postauditState = formData.postauditState; table.reload('provinceReload', { where: { access_token: config.getToken().access_token, newsType: newsType, headline: headline, postauditState: postauditState } }); return false; }); }); </script> 修改添加按钮点击的候刷新的错误,修改富文本有候会失效的错误,保持原来页面的样子
最新发布
07-18
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值