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" /}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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" /}
+
+
+
+
+
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.