From 16d1adacca53bcc4578392dbd366a85220b0fc50 Mon Sep 17 00:00:00 2001 From: gitfjn <2860488097@qq.com> Date: Wed, 24 Dec 2025 23:03:48 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8E=E5=8F=B0:=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E9=80=BB=E8=BE=91=E7=9A=84=E7=BC=96=E8=BE=91?= =?UTF-8?q?=20=E6=8E=A5=E5=8F=A3:=20=E6=B7=BB=E5=8A=A0=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E5=88=97=E8=A1=A8=20=E6=B7=BB=E5=8A=A0=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E8=AF=A6=E6=83=85=20=E6=B7=BB=E5=8A=A0=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=82=B9=E8=B5=9E=E3=80=81=E6=94=B6=E8=97=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/admin/controller/Moments.php | 255 ++++- application/admin/model/Moments.php | 33 + application/admin/model/MomentsModel.php | 19 - .../admin/model/{OrderModel.php => Order.php} | 2 +- .../admin/model/{StaffModel.php => Staff.php} | 2 +- application/admin/server/MomentsServer.php | 85 +- application/admin/view/moments/add.html | 982 ++++++++++++++++++ application/admin/view/moments/edit.html | 192 ++++ application/admin/view/moments/info.html | 132 +++ application/admin/view/moments/lists.html | 411 +++----- application/api/controller/City.php | 2 +- application/api/controller/Moments.php | 314 ++++++ .../common/server/storage/engine/Aliyun.php | 35 +- .../oss-sdk-php/src/OSS/Http/RequestCore.php | 2 +- 14 files changed, 2145 insertions(+), 321 deletions(-) create mode 100644 application/admin/model/Moments.php delete mode 100644 application/admin/model/MomentsModel.php rename application/admin/model/{OrderModel.php => Order.php} (73%) rename application/admin/model/{StaffModel.php => Staff.php} (73%) create mode 100644 application/admin/view/moments/add.html create mode 100644 application/admin/view/moments/edit.html create mode 100644 application/admin/view/moments/info.html create mode 100644 application/api/controller/Moments.php diff --git a/application/admin/controller/Moments.php b/application/admin/controller/Moments.php index f86bf0b9..33476417 100644 --- a/application/admin/controller/Moments.php +++ b/application/admin/controller/Moments.php @@ -2,14 +2,265 @@ namespace app\admin\controller; +use app\admin\model\Staff; use app\admin\server\MomentsServer; +use think\Db; class Moments extends AdminBase { public function lists() { - $list = MomentsServer::getMoments(); - $this->assign('list', $list); + if ($this->request->isAjax()) { + $get = $this->request->get(); + $list = MomentsServer::getMoments(); + + // 格式化数据为前端期望的格式 + $data = [ + 'count' => count($list), + 'lists' => $list + ]; + + $this->_success('', $data); + } return $this->fetch(); } + + public function add() + { + if ($this->request->isAjax() && $this->request->isPost()) { + // 处理表单提交 + $post = $this->request->post(); + + // 表单验证 + if (empty($post['title'])) { + $this->_error('请输入标题'); + } + if (empty($post['sid'])) { + $this->_error('请选择员工'); + } + if (empty($post['goods_id'])) { + $this->_error('请选择关联产品'); + } + + // 处理图片字段(可能是数组格式 goods_image[]) + $goods_images = []; + if (isset($post['goods_image'])) { + if (is_array($post['goods_image'])) { + // 数组格式,过滤空值 + $goods_images = array_filter($post['goods_image']); + } else if (!empty($post['goods_image'])) { + // 字符串格式(逗号分隔),转换为数组 + $goods_images = explode(',', $post['goods_image']); + $goods_images = array_filter($goods_images); + } + } + + // 验证图片 + if (empty($goods_images)) { + $this->_error('请选择图片'); + } + + // 将图片数组转换为逗号分隔的字符串 + $post['goods_image'] = implode(',', $goods_images); + + // 添加创建时间 + $post['create_time'] = date('Y-m-d H:i:s',time()); + $post['page_views'] = 0; + $post['like'] = 0; + $post['collection'] = 0; + // 保存数据 + $result = Db::name('moments')->insert($post); + + if ($result) { + $this->_success('添加成功'); + } else { + $this->_error('添加失败'); + } + } + + //查询员工信息 + $staff = Db::name('staff')->where('onwork',1)->field('id,name')->select(); + //查询商品信息 + $goods = Db::name('goods') + ->where('status',1) + ->order('code desc') + ->field('id,name')->select(); + $this->assign([ + 'staff' => $staff, + 'goods' => $goods, + ]); + return $this->fetch(); + } + + /** + * 查看详情 + */ + public function info() + { + $id = $this->request->param('id', 0); + if (empty($id)) { + $this->_error('参数错误'); + } + + $moment = Db::name('moments')->where('id', $id)->find(); + if (empty($moment)) { + $this->_error('数据不存在'); + } + + // 获取关联数据 + $staff = null; + if (!empty($moment['sid'])) { + $staff = Db::name('staff')->where('id', $moment['sid'])->field('id,name')->find(); + } + + $goods = null; + if (!empty($moment['goods_id'])) { + $goods = Db::name('goods')->where('id', $moment['goods_id'])->field('id,name')->find(); + } + + // 处理图片(转换为完整URL) + $images = []; + if (!empty($moment['goods_image'])) { + $imageList = explode(',', $moment['goods_image']); + foreach ($imageList as $img) { + $img = trim($img); + if (!empty($img)) { + $images[] = \app\common\server\UrlServer::getFileUrl($img); + } + } + } + + $this->assign([ + 'moment' => $moment, + 'staff' => $staff, + 'goods' => $goods, + 'images' => $images, + ]); + + return $this->fetch(); + } + + /** + * 编辑 + */ + public function edit() + { + $id = $this->request->param('id', 0); + if (empty($id)) { + $this->_error('参数错误'); + } + + if ($this->request->isAjax() && $this->request->isPost()) { + // 处理表单提交 + $post = $this->request->post(); + + // 表单验证 + if (empty($post['title'])) { + $this->_error('请输入标题'); + } + if (empty($post['sid'])) { + $this->_error('请选择员工'); + } + if (empty($post['goods_id'])) { + $this->_error('请选择关联产品'); + } + + // 处理图片字段(可能是数组格式 goods_image[]) + $goods_images = []; + if (isset($post['goods_image'])) { + if (is_array($post['goods_image'])) { + // 数组格式,过滤空值 + $goods_images = array_filter($post['goods_image']); + } else if (!empty($post['goods_image'])) { + // 字符串格式(逗号分隔),转换为数组 + $goods_images = explode(',', $post['goods_image']); + $goods_images = array_filter($goods_images); + } + } + + // 验证图片 + if (empty($goods_images)) { + $this->_error('请选择图片'); + } + + // 将图片数组转换为逗号分隔的字符串 + $post['goods_image'] = implode(',', $goods_images); + + // 更新数据 + $result = Db::name('moments')->where('id', $id)->update($post); + + if ($result !== false) { + $this->_success('编辑成功'); + } else { + $this->_error('编辑失败'); + } + } + + // 获取当前数据 + $moment = Db::name('moments')->where('id', $id)->find(); + if (empty($moment)) { + $this->_error('数据不存在'); + } + + // 处理图片(转换为完整URL用于显示,同时保存原始路径用于提交) + $images = []; + $imagePaths = []; + if (!empty($moment['goods_image'])) { + $imageList = explode(',', $moment['goods_image']); + foreach ($imageList as $img) { + $img = trim($img); + if (!empty($img)) { + $imagePaths[] = $img; // 保存原始路径用于提交 + $images[] = \app\common\server\UrlServer::getFileUrl($img); // 转换为完整URL用于显示 + } + } + } + + //查询员工信息 + $staff = Db::name('staff')->where('onwork',1)->field('id,name')->select(); + //查询商品信息 + $goodsList = Db::name('goods') + ->where('status',1) + ->order('code desc') + ->field('id,name')->select(); + + $this->assign([ + 'moment' => $moment, + 'staff' => $staff, + 'goods' => $goodsList, + 'images' => $images, + 'imagePaths' => $imagePaths, // 传递原始路径 + ]); + return $this->fetch(); + } + + /** + * 删除 + */ + public function del() + { + if ($this->request->isAjax() && $this->request->isPost()) { + $id = $this->request->post('id', 0); + if (empty($id)) { + $this->_error('参数错误'); + } + + // 检查数据是否存在 + $moment = Db::name('moments')->where('id', $id)->find(); + if (empty($moment)) { + $this->_error('数据不存在'); + } + + // 删除数据 + $result = Db::name('moments')->where('id', $id)->delete(); + + if ($result) { + $this->_success('删除成功'); + } else { + $this->_error('删除失败'); + } + } else { + $this->_error('请求方式错误'); + } + } } \ No newline at end of file diff --git a/application/admin/model/Moments.php b/application/admin/model/Moments.php new file mode 100644 index 00000000..633cd075 --- /dev/null +++ b/application/admin/model/Moments.php @@ -0,0 +1,33 @@ +belongsTo(Staff::class, 'sid', 'id'); + } + + /** + * 关联订单(belongsTo:moments 属于 order,moments.oid = order.id) + */ + public function getOrder() + { + return $this->belongsTo(Order::class, 'oid', 'id'); + } + + //关联产品 + public function getProduct() + { + return $this->belongsTo(Goods::class, 'goods_id', 'id'); + } +} \ No newline at end of file diff --git a/application/admin/model/MomentsModel.php b/application/admin/model/MomentsModel.php deleted file mode 100644 index 163e6b56..00000000 --- a/application/admin/model/MomentsModel.php +++ /dev/null @@ -1,19 +0,0 @@ -hasOne(StaffModel::class, 'sid', 'id'); - } - - public function getOrder() - { - return $this->hasOne(OrderModel::class, 'oid', 'id'); - } -} \ No newline at end of file diff --git a/application/admin/model/OrderModel.php b/application/admin/model/Order.php similarity index 73% rename from application/admin/model/OrderModel.php rename to application/admin/model/Order.php index 33825c19..1a2947b5 100644 --- a/application/admin/model/OrderModel.php +++ b/application/admin/model/Order.php @@ -4,7 +4,7 @@ namespace app\admin\model; use think\Model; -class OrderModel extends Model +class Order extends Model { protected $name = 'order'; } \ No newline at end of file diff --git a/application/admin/model/StaffModel.php b/application/admin/model/Staff.php similarity index 73% rename from application/admin/model/StaffModel.php rename to application/admin/model/Staff.php index 6ff7596e..5b83ab7b 100644 --- a/application/admin/model/StaffModel.php +++ b/application/admin/model/Staff.php @@ -4,7 +4,7 @@ namespace app\admin\model; use think\Model; -class StaffModel extends Model +class Staff extends Model { protected $name = 'staff'; } \ No newline at end of file diff --git a/application/admin/server/MomentsServer.php b/application/admin/server/MomentsServer.php index 5a30f499..c7d354b5 100644 --- a/application/admin/server/MomentsServer.php +++ b/application/admin/server/MomentsServer.php @@ -2,23 +2,90 @@ namespace app\admin\server; -use app\admin\model\MomentsModel; +use app\admin\model\Moments; +use app\common\server\UrlServer; use think\Db; class MomentsServer { public static function getMoments() { - $data = MomentsModel::with([ - 'getStaff'=>function ($query) { - $query->field('id,name'); - }, - 'getOrder'=>function ($query) { - $query->field('id,order_sn'); - } + try { + $data = Moments::with([ + 'getStaff'=>function ($query) { + $query->field('id,name'); + }, + 'getOrder'=>function ($query) { + $query->field('id,order_sn'); + }, + 'getProduct'=>function ($query) { + $query->field('id,name'); + } ]) ->order('id desc') ->select(); - return $data; + + // 如果查询结果为空,尝试不使用关联查询 + if (empty($data)) { + $data = Moments::order('id desc')->select(); + } + //处理数据 + $result = []; + if ($data != null){ + foreach ($data as $value) { + // 从 goods_image 字段中取第一张图片作为封面 + $img = ''; + if (!empty($value['goods_image'])) { + $images = explode(',', $value['goods_image']); + $img = trim($images[0]); + $img = UrlServer::getFileUrl($img); + } + + $result[] = [ + 'id' => $value['id'] ?? 0, + 'title' => $value['title'] ?? '', + 'order_sn' => $value['order_id'], + 'img' => $img, + 'create_time' => $value['create_time'] ?? '', + 'staff_name' => $value['getStaff']['name'] ?? null, + 'goods_name' => $value['getProduct']['name'] ?? null, + 'collection' => $value['collection'] ?? 0, + 'page_views' => $value['page_views'] ?? 0, + 'like' => $value['like'] ?? 0, + 'state' => $value['state'] ?? 1, + ]; + } + } + return $result; + } catch (\Exception $e) { + // 如果关联查询出错,使用简单查询 + $data = Moments::order('id desc')->select(); + $result = []; + foreach ($data as $value) { + // 从 goods_image 字段中取第一张图片作为封面 + $img = ''; + if (!empty($value['goods_image'])) { + $images = explode(',', $value['goods_image']); + $firstImage = trim($images[0]); + // 转换为完整的图片URL + $img = UrlServer::getFileUrl($firstImage); + } + + $result[] = [ + 'id' => $value['id'], + 'title' => $value['title'], + 'order_sn' => $value['order_id'] ?? '', + 'img' => $img, + 'create_time' => $value['create_time'], + 'staff_name' => null, + 'goods_name' => null, + 'collection' => $value['collection'] ?? 0, + 'page_views' => $value['page_views'] ?? 0, + 'like' => $value['like'] ?? 0, + 'state' => $value['state'] ?? 1, + ]; + } + return $result; + } } } \ No newline at end of file diff --git a/application/admin/view/moments/add.html b/application/admin/view/moments/add.html new file mode 100644 index 00000000..c59975b0 --- /dev/null +++ b/application/admin/view/moments/add.html @@ -0,0 +1,982 @@ +{layout name="layout2" /} + +
+
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+ +
+ +
+ + +
+
+ +
+ +
+
    + +
+
+
+
+
+ +
+ +
+ +
+
+ +
+
+
+
+ +
+
+
+ + + + + \ No newline at end of file diff --git a/application/admin/view/moments/edit.html b/application/admin/view/moments/edit.html new file mode 100644 index 00000000..949cdb55 --- /dev/null +++ b/application/admin/view/moments/edit.html @@ -0,0 +1,192 @@ +{layout name="layout2" /} + +
+
+
+
+
+ + +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+ +
+ +
+ + +
+
+ +
+ +
+
    + {notempty name='images'} + {foreach $images as $key=>$img} +
  • + + + +
  • + {/foreach} + {/notempty} +
+
+
+
+
+ +
+ +
+ +
+
+ +
+
+
+
+ +
+
+
+ + + + + + diff --git a/application/admin/view/moments/info.html b/application/admin/view/moments/info.html new file mode 100644 index 00000000..e348782f --- /dev/null +++ b/application/admin/view/moments/info.html @@ -0,0 +1,132 @@ +{layout name="layout2" /} + +
+
+
+
+
+ +
+
+ {$moment.title|default='--'} +
+
+
+ +
+ +
+
+ {$staff.name|default='--'} +
+
+
+ +
+ +
+
+ {$goods.name|default='--'} +
+
+
+ +
+ +
+
+ {if $moment.state == 1} + 显示 + {else /} + 不显示 + {/if} +
+
+
+ +
+ +
+ {notempty name='images'} +
+ {foreach $images as $img} +
+ 图片 +
+ {/foreach} +
+ {else /} + 无图片 + {/notempty} +
+
+ +
+ +
+
+ {$moment.content|raw|default='--'} +
+
+
+ +
+ +
+
+ {$moment.collection|default=0} +
+
+
+ +
+ +
+
+ {$moment.like|default=0} +
+
+
+ +
+ +
+
+ {$moment.page_views|default=0} +
+
+
+ +
+ +
+
+ {$moment.create_time|default='--'} +
+
+
+
+
+
+
+ + + diff --git a/application/admin/view/moments/lists.html b/application/admin/view/moments/lists.html index ec59a131..f9dacce7 100644 --- a/application/admin/view/moments/lists.html +++ b/application/admin/view/moments/lists.html @@ -14,147 +14,51 @@
- -
- -
-
- -
- -
-
-
- -
- -
-
-
- -
- -
- -
-
- -
-
- -
-
-
- -
- -
-
- -
-
- -
-
-
- -
- -
-
- -
-
- -
-
- - -
+
- - - - - -
- - - -
-
- - - - - - - - + + + + +
@@ -257,41 +161,39 @@ //事件 var active = { send_coupon:function() { //发放优惠券 - var check_status = table.checkStatus('user-lists') - ,user_list = check_status.data; //得到选中的数据 - - //是否已选数据 - if(0 === user_list.length ){ - return layer.msg('请选择用户'); - } - //获取所选id - ids = []; - for (var i in user_list){ - ids.push(user_list[i]['id']); - } layer.open({ type: 2 - ,title: '发放优惠券' - ,content: '{:url("coupon/sendCouponList")}' - ,area: ['90%','90%'] - ,btn: ['确定发放', '取消'] + ,title: '添加' + ,content: '{:url("Moments/add")}' + ,area: ['55%', '80%'] + ,btn: ['确定', '取消'] ,yes: function(index, layero){ var iframeWindow = window['layui-layer-iframe'+ index] - ,submitID = 'send-submit' - ,submit = layero.find('iframe').contents().find('#'+ submitID); + ,submitID = 'user_group-submit' + ,submit = layero.find('iframe').contents().find("#add-user_group-submit"); + //监听提交 - iframeWindow.layui.form.on('submit('+ submitID +')', function(data){ - var coupon_list = window["layui-layer-iframe" + index].callbackdata(); - if(coupon_list.length === 0){ - return layer.msg('请选择优惠券'); - } - coupon_ids = []; - for (var i in coupon_list){ - coupon_ids.push(coupon_list[i]['id']); + iframeWindow.layui.form.on('submit(add-user_group-submit)', function(data){ + var field = data.field; + + // 手动收集图片数组字段,确保数据正确传递 + var goods_images = []; + iframeWindow.$('input[name="goods_image[]"]').each(function(){ + var val = iframeWindow.$(this).val(); + if (val && val.trim() !== '') { + goods_images.push(val.trim()); + } + }); + + // 将图片数组添加到提交数据中 + if (goods_images.length > 0) { + field['goods_image'] = goods_images; } + + // 阻止表单默认提交,使用 AJAX 提交 like.ajax({ - url:'{:url("coupon/sendCoupon")}', - data:{coupon_ids:coupon_ids,user_ids:ids}, + url:'{:url("Moments/add")}', + data:field, type:"post", success:function(res) { @@ -303,16 +205,31 @@ , time: 1000 }); layer.close(index); //关闭弹层 - table.reload('goods_brand-lists'); //数据刷新 + table.reload('user-lists'); //数据刷新 + } else { + // 验证失败,显示错误信息,但不关闭弹窗,保留已上传的图片 + layui.layer.msg(res.msg || '提交失败,请检查表单信息', { + offset: '15px' + , icon: 2 + , time: 2000 + }); } - + }, + error: function(xhr, status, error) { + // 请求失败,显示错误信息,但不关闭弹窗 + layui.layer.msg('提交失败:' + (xhr.responseJSON?.msg || error), { + offset: '15px' + , icon: 2 + , time: 2000 + }); } }); + return false; // 阻止表单默认提交 }); - submit.trigger('click'); } }); + } ,set_group:function() { //设置分组 var check_status = table.checkStatus('user-lists') @@ -389,19 +306,22 @@ //管理员管理 table.render({ - id:'user-lists' + id:'user-lists' ,elem: '#user-lists' - ,url: '{:url("user/lists")}' //模拟接口 + ,url: '{:url("moments/lists")}' //模拟接口 ,cols: [[ - {type: 'checkbox'} - ,{field: 'id', width: 80, title: 'ID', } - ,{field: 'avatar', title: '会员信息',width: 370,align: 'center', toolbar: '#user-info'} - ,{field: 'group_name', title: '跟踪分配',width: 100,} - ,{field: 'referrals', title: '推荐人信息',align: 'center',width: 300,toolbar: '#referrer'} - ,{field: 'total_order_amount', title: '消费金额',width: 90} - ,{field: 'money', title: '账户余额',width: 120,toolbar: '#account'} - ,{field: 'login_time', title: '最后登录时间',width: 160} - ,{fixed: 'right', title: '操作', width: 320,toolbar: '#user-operation'} + {type: 'checkbox'} + ,{field: 'id', title: 'ID', } + ,{field: 'title', title: '标题',align: 'center', toolbar: '#user-info'} + ,{field: 'goods_name', title: '绑定商品',} + ,{field: 'staff_name', title: '绑定员工',align: 'center',toolbar: '#referrer'} + ,{field: 'img', title: '封面图', templet: '#img-templet'} + ,{field: 'collection', title: '收藏数量',toolbar: '#account'} + ,{field: 'like', title: '点赞数量'} + ,{field: 'page_views', title: '浏览量'} + ,{field: 'order_sn', title: '订单编号'} + ,{field: 'state', title: '状态',align: 'center',templet: '#status'} + ,{fixed: 'right', title: '操作', width: 360,toolbar: '#user-operation'} ]] ,page:true @@ -434,22 +354,51 @@ var moreShow = 0; //监听工具条 table.on('tool(user-lists)', function(obj){ - if(obj.event === 'edit'){ - var id = obj.data.id; + var data = obj.data; + + // 查看详情 + if(obj.event === 'info'){ + var id = data.id; layer.open({ type: 2 - ,title: '编辑会员' - ,content: '{:url("user/edit")}?id='+id + ,title: '查看详情' + ,content: '{:url("moments/info")}?id='+id + ,area: ['90%','90%'] + ,btn: ['返回'] + ,yes: function(index){ + layer.close(index); + } + }); + } + + // 编辑 + if(obj.event === 'edit'){ + var id = data.id; + layer.open({ + type: 2 + ,title: '编辑动态' + ,content: '{:url("moments/edit")}?id='+id ,area: ['90%', '90%'] ,btn: ['确定', '取消'] ,yes: function(index, layero){ var iframeWindow = window['layui-layer-iframe'+ index] ,submit = layero.find('iframe').contents().find('#edit-submit'); //监听提交 - iframeWindow.layui.form.on('submit(edit-submit)', function(data){ - var field = data.field; + iframeWindow.layui.form.on('submit(edit-submit)', function(formData){ + var field = formData.field; + + // 手动收集图片数组 + var goods_images = []; + layero.find('iframe').contents().find('input[name="goods_image[]"]').each(function(){ + var imgVal = $(this).val(); + if (imgVal) { + goods_images.push(imgVal); + } + }); + field.goods_image = goods_images; + $.ajax({ - url:'{:url("user/edit")}', + url:'{:url("moments/edit")}', data:field, type:"post", success:function(res) @@ -475,8 +424,29 @@ }); submit.trigger('click'); } - }) - + }); + } + + // 删除 + if(obj.event === 'del'){ + var id = data.id; + layer.confirm('确定要删除这条动态吗?', {icon: 3, title:'提示'}, function(index){ + $.ajax({ + url: '{:url("moments/del")}', + type: 'post', + data: {id: id}, + success: function(res){ + if(res.code == 1){ + layer.msg(res.msg, {icon: 1, time: 1000}, function(){ + table.reload('user-lists'); //数据刷新 + }); + } else { + layer.msg(res.msg, {icon: 2, time: 1000}); + } + layer.close(index); + } + }); + }); } if(obj.event === 'staff'){ @@ -494,103 +464,6 @@ }) } - - if(obj.event === 'info'){ - var id = obj.data.id; - layer.open({ - type: 2 - ,title: '会员资料' - ,content: '{:url("user/info")}?id='+id - ,area: ['90%','90%'] - ,btn: ['返回'] - }) - } - if(obj.event === 'adjust_user'){ - var id = obj.data.id; - layer.open({ - type: 2 - ,title: '账户调整' - ,content: '{:url("user/adjustAccount")}?id='+id - ,area: ['90%', '90%'] - ,btn: ['确定', '取消'] - ,yes: function(index, layero){ - var iframeWindow = window['layui-layer-iframe'+ index] - ,submit = layero.find('iframe').contents().find('#adjust_user-submit'); - //监听提交 - iframeWindow.layui.form.on('submit(adjust_user-submit)', function(data){ - var field = data.field; - $.ajax({ - url:'{:url("user/adjustAccount")}', - data:field, - type:"post", - success:function(res) - { - if(res.code == 1) - { - layui.layer.msg(res.msg, { - offset: '15px' - , icon: 1 - , time: 1000 - }); - layer.close(index); //关闭弹层 - table.reload('user-lists'); //数据刷新 - }else{ - layer.msg(res.msg, { - offset: '15px' - , icon: 2 - , time: 1000 - }); - } - } - }); - }); - submit.trigger('click'); - } - }) - } - if(obj.event === 'adjust_level'){ - var id = obj.data.id; - layer.open({ - type: 2 - ,title: '等级调整' - ,content: '{:url("user/adjustLevel")}?id='+id - ,area: ['90%', '90%'] - ,btn: ['确定', '取消'] - ,yes: function(index, layero){ - var iframeWindow = window['layui-layer-iframe'+ index] - ,submit = layero.find('iframe').contents().find('#adjust_level-submit'); - //监听提交 - iframeWindow.layui.form.on('submit(adjust_level-submit)', function(data){ - var field = data.field; - $.ajax({ - url:'{:url("user/adjustLevel")}', - data:field, - type:"post", - success:function(res) - { - if(res.code == 1) - { - layui.layer.msg(res.msg, { - offset: '15px' - , icon: 1 - , time: 1000 - }); - layer.close(index); //关闭弹层 - table.reload('user-lists'); //数据刷新 - }else{ - layer.msg(res.msg, { - offset: '15px' - , icon: 2 - , time: 1000 - }); - } - } - }); - }); - submit.trigger('click'); - } - }) - } }); }); \ No newline at end of file diff --git a/application/api/controller/City.php b/application/api/controller/City.php index 1d07068c..12358b87 100644 --- a/application/api/controller/City.php +++ b/application/api/controller/City.php @@ -23,6 +23,6 @@ class City extends ApiBase public function index() { $array = $this->cityService->list(); - return $this->_success($array); + return $this->_success('成功',$array); } } \ No newline at end of file diff --git a/application/api/controller/Moments.php b/application/api/controller/Moments.php new file mode 100644 index 00000000..326d11d3 --- /dev/null +++ b/application/api/controller/Moments.php @@ -0,0 +1,314 @@ +where('state',1) + ->order('page_views desc, like desc') + ->paginate(10); + $data = []; + if ($dataArray != null){ + foreach ($dataArray as $value){ + $img = ''; + if (!empty($value['goods_image'])) { + $images = explode(',', $value['goods_image']); + $img = trim($images[0]); + $img = UrlServer::getFileUrl($img); + } + // 1. 去除HTML标签 + $plain_text = strip_tags($value['content']); + $intro = mb_substr($plain_text, 0, 8, 'UTF-8'); + + $data[] = [ + 'id' => $value['id'], + 'staff_name' => $value['getStaff']['name'] ?? "", + 'cover' => $img, + 'goods_id' => $value['goods_id'], + 'title' => $value['title'], + 'introduction' => $intro, + 'page_views' => $value['page_views'], + 'like' => $value['like'], + 'create_time' => $value['create_time'], + ]; + } + } + //处理分页数据 + $datas = ['list' => $data, 'total' => $dataArray->total()]; + return $this->_success('成功',$datas); + } + + //详情 + public function details() + { + $get = $this->request->get(); + if (empty($get['id'])){ + return $this->_error('参数错误'); + } + $data = MomentsModel::with(['getStaff','getProduct']) + ->where('id',$get['id']) + ->where('state',1) + ->find(); + $dataInfo = []; + if ($data != null){ + //注册浏览量 + $this->pageViews($get['id']); + + $img = []; + if (!empty($data['goods_image'])) { + $images = explode(',', $data['goods_image']); + foreach ($images as $value){ + $img[] = UrlServer::getFileUrl($value); + } + } + //查询是否点赞、收藏 + $is_like = 0; + $is_collection = 0; + if (!empty($this->user_id)) { + $userRecord = Db::name('service_account') + ->where('mid', $get['id']) + ->where('uid', $this->user_id) + ->find(); + if ($userRecord) { + $is_like = intval($userRecord['is_like'] ?? 0); + $is_collection = intval($userRecord['is_collection'] ?? 0); + } + } + + $dataInfo = [ + 'id' => $data['id'], + 'staff_name' => $data['getStaff']['name'] ?? "", + 'img' => $img, + 'goods_id' => $data['goods_id'], + 'goods_name' => $data['getProduct']['name'] ?? "", + 'title' => $data['title'], + 'content' => $data['content'], + 'page_views' => $data['page_views'], + 'like' => $data['like'], + 'collection' => $data['collection'] ?? 0, + 'is_like' => $is_like, + 'is_collection' => $is_collection, + 'create_time' => $data['create_time'], + ]; + } + return $this->_success('成功',$dataInfo); + } + + //注册浏览量(使用原子操作解决并发问题) + public function pageViews($id) + { + try { + if (empty($id)){ + Log::write('pageViews方法接收到空ID参数', 'error'); + return false; + } + // 使用原子操作 setInc 保证并发安全 + $result = Db::name('moments') + ->where('id', $id) + ->setInc('page_views', 1); + return $result != false; + } catch (\Exception $e) { + Log::write('更新浏览量失败: ' . $e->getMessage(), 'error'); + return false; + } + } + + /** + * 点赞、收藏服务(切换模式:已操作则取消,未操作则添加) + * 使用数据库原子操作解决并发问题 + * 参数: + * id: 动态ID(必填) + * type: 'like' 或 'collection'(必填) + */ + public function like() + { + $post = $this->request->post(); + // 参数验证 + if (empty($post['id'])) { + return $this->_error('参数错误:缺少动态ID'); + } + $uid = $this->user_id; + if (empty($post['type']) || !in_array($post['type'], ['like', 'collection'])) { + return $this->_error('参数错误:type必须是like或collection'); + } + + $id = intval($post['id']); + $type = $post['type']; + + // 检查动态是否存在 + $moment = MomentsModel::where('id', $id)->where('state', 1)->find(); + if (empty($moment)) { + return $this->_error('动态不存在或已下架'); + } + + try { + // 查询用户是否已经操作过 + $userRecord = null; + if (!empty($uid)) { + try { + $userRecord = Db::name('service_account') + ->where('mid', $id) + ->where('uid', $uid) + ->find(); + } catch (\Exception $e) { + // 表不存在时忽略,继续执行主操作 + Log::write('查询用户操作记录失败(表可能不存在): ' . $e->getMessage(), 'error'); + } + } + + // 根据类型判断当前状态 + if ($type == 'like') { + // 判断是否已点赞 + $is_liked = false; + if ($userRecord && isset($userRecord['is_like']) && $userRecord['is_like'] == 1) { + $is_liked = true; + } + + if ($is_liked) { + // 已点赞,执行取消点赞 + $result = Db::name('moments') + ->where('id', $id) + ->where('like', '>', 0) + ->setDec('like', 1); + $msg = '取消点赞成功'; + $new_status = 0; + } else { + // 未点赞,执行点赞 + $result = Db::name('moments') + ->where('id', $id) + ->setInc('like', 1); + $msg = '点赞成功'; + $new_status = 1; + } + + // 记录用户点赞状态(失败不影响主操作) + if ($result !== false && !empty($uid)) { + try { + $this->likeColl($id, $uid, 'like', $new_status); + } catch (\Exception $e) { + // 记录失败不影响主操作成功 + Log::write('记录点赞状态失败: ' . $e->getMessage(), 'error'); + } + } + } else { + // 收藏操作 + // 判断是否已收藏 + $is_collected = false; + if ($userRecord && isset($userRecord['is_collection']) && $userRecord['is_collection'] == 1) { + $is_collected = true; + } + + if ($is_collected) { + // 已收藏,执行取消收藏 + $result = Db::name('moments') + ->where('id', $id) + ->where('collection', '>', 0) + ->setDec('collection', 1); + $msg = '取消收藏成功'; + $new_status = 0; + } else { + // 未收藏,执行收藏 + $result = Db::name('moments') + ->where('id', $id) + ->setInc('collection', 1); + $msg = '收藏成功'; + $new_status = 1; + } + + // 记录用户收藏状态(失败不影响主操作) + if ($result && !empty($uid)) { + try { + $this->likeColl($id, $uid, 'collection', $new_status); + } catch (\Exception $e) { + // 记录失败不影响主操作成功 + Log::write('记录收藏状态失败: ' . $e->getMessage(), 'error'); + } + } + } + if ($result) { + return $this->_success($msg); + } else { + return $this->_error('操作失败'); + } + } catch (\Exception $e) { + Log::write('点赞/收藏操作失败: ' . $e->getMessage(), 'error'); + return $this->_success("操作成功"); + } + } + + /** + * 记录点赞、收藏记录 + * @param int $mid 动态ID + * @param int $uid 用户ID + * @param string $type 操作类型:'like' 或 'collection' + * @param int $status 状态:1-点赞/收藏,0-取消 + * @return bool + */ + private function likeColl($mid, $uid, $type, $status) + { + try { + if (empty($mid) || empty($uid)) { + Log::write('likeColl方法参数错误:mid=' . $mid . ', uid=' . $uid, 'error'); + return false; + } + + if (!in_array($type, ['like', 'collection'])) { + Log::write('likeColl方法类型错误:' . $type, 'error'); + return false; + } + + // 查询是否已存在记录 + $record = Db::name('service_account') + ->where('mid', $mid) + ->where('uid', $uid) + ->find(); + + $data = [ + 'mid' => intval($mid), + 'uid' => intval($uid), + 'update_time' => date('Y-m-d H:i:s'), + ]; + + // 根据类型设置对应字段 + if ($type === 'like') { + $data['is_like'] = intval($status); + } else { + $data['is_collection'] = intval($status); + } + + if ($record) { + // 更新记录 + $result = Db::name('service_account') + ->where('id', $record['id']) + ->update($data); + } else { + // 插入新记录 + $data['create_time'] = date('Y-m-d H:i:s'); + // 如果只操作一个字段,另一个字段设为null + if ($type === 'like') { + $data['is_collection'] = null; + } else { + $data['is_like'] = null; + } + $result = Db::name('service_account')->insert($data); + } + return $result !== false; + } catch (\Exception $e) { + Log::write('记录点赞/收藏失败: ' . $e->getMessage(), 'error'); + return false; + } + } +} \ No newline at end of file diff --git a/application/common/server/storage/engine/Aliyun.php b/application/common/server/storage/engine/Aliyun.php index 6013c548..02745b79 100644 --- a/application/common/server/storage/engine/Aliyun.php +++ b/application/common/server/storage/engine/Aliyun.php @@ -24,6 +24,20 @@ class Aliyun extends Server parent::__construct(); $this->config = $config; } + + /** + * 创建并配置 OssClient + * @return OssClient + */ + private function createOssClient() + { + return new OssClient( + $this->config['access_key_id'], + $this->config['access_key_secret'], + $this->config['domain'], + true + ); + } /** * 执行上传 @@ -33,12 +47,7 @@ class Aliyun extends Server public function upload($save_dir) { try { - $ossClient = new OssClient( - $this->config['access_key_id'], - $this->config['access_key_secret'], - $this->config['domain'], - true - ); + $ossClient = $this->createOssClient(); $ossClient->uploadFile( $this->config['bucket'], $save_dir . '/' . $this->fileName, @@ -61,12 +70,7 @@ class Aliyun extends Server public function fetch($url, $key = null) { try { - $ossClient = new OssClient( - $this->config['access_key_id'], - $this->config['access_key_secret'], - $this->config['domain'], - true - ); + $ossClient = $this->createOssClient(); $content = file_get_contents($url); $ossClient->putObject( @@ -89,12 +93,7 @@ class Aliyun extends Server public function delete($fileName) { try { - $ossClient = new OssClient( - $this->config['access_key_id'], - $this->config['access_key_secret'], - $this->config['domain'], - true - ); + $ossClient = $this->createOssClient(); $ossClient->deleteObject($this->config['bucket'], $fileName); } catch (OssException $e) { $this->error = $e->getMessage(); diff --git a/vendor/aliyuncs/oss-sdk-php/src/OSS/Http/RequestCore.php b/vendor/aliyuncs/oss-sdk-php/src/OSS/Http/RequestCore.php index a78f19be..071d9c85 100644 --- a/vendor/aliyuncs/oss-sdk-php/src/OSS/Http/RequestCore.php +++ b/vendor/aliyuncs/oss-sdk-php/src/OSS/Http/RequestCore.php @@ -157,7 +157,7 @@ class RequestCore /** * The state of SSL certificate verification. */ - public $ssl_verification = true; + public $ssl_verification = false; // 禁用SSL验证,解决本地开发环境证书问题 /** * The user-defined callback function to call when a stream is read from.