shopxo/app/service/GoodsCommentsService.php
2022-08-02 17:23:10 +08:00

674 lines
24 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
// +----------------------------------------------------------------------
// | ShopXO 国内领先企业级B2C免费开源电商系统
// +----------------------------------------------------------------------
// | Copyright (c) 2011~2099 http://shopxo.net All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( https://opensource.org/licenses/mit-license.php )
// +----------------------------------------------------------------------
// | Author: Devil
// +----------------------------------------------------------------------
namespace app\service;
use think\facade\Db;
use app\service\UserService;
use app\service\GoodsService;
use app\service\SystemBaseService;
/**
* 商品评论服务层
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-01T21:51:08+0800
*/
class GoodsCommentsService
{
/**
* 订单评论
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2018-10-09
* @desc description
* @param [array] $params [输入参数]
*/
public static function Comments($params = [])
{
// 请求参数
$p = [
[
'checked_type' => 'empty',
'key_name' => 'id',
'error_msg' => '订单id有误',
],
[
'checked_type' => 'empty',
'key_name' => 'business_type',
'error_msg' => '业务类型标记不能为空',
],
[
'checked_type' => 'empty',
'key_name' => 'goods_id',
'error_msg' => '商品id有误',
],
[
'checked_type' => 'empty',
'key_name' => 'rating',
'error_msg' => '评级有误',
],
[
'checked_type' => 'empty',
'key_name' => 'content',
'error_msg' => '评论内容有误',
],
[
'checked_type' => 'empty',
'key_name' => 'user',
'error_msg' => '用户信息有误',
],
];
$ret = ParamsChecked($params, $p);
if($ret !== true)
{
return DataReturn($ret, -1);
}
// 参数处理
if(!is_array($params['goods_id']))
{
$params['goods_id'] = json_decode(htmlspecialchars_decode($params['goods_id']), true);
}
if(!is_array($params['rating']))
{
$params['rating'] = json_decode(htmlspecialchars_decode($params['rating']), true);
}
if(!is_array($params['content']))
{
$params['content'] = json_decode(htmlspecialchars_decode($params['content']), true);
}
// 评分
if(min($params['rating']) <= 0)
{
return DataReturn('评级有误', -1);
}
if(min($params['rating']) <= 0 || max($params['rating']) > 5)
{
return DataReturn('评级有误', -1);
}
// 评论内容
foreach($params['content'] as $v)
{
$len = mb_strlen($v, 'utf-8');
if($len < 6 || $len > 230)
{
return DataReturn('评论内容 6~230 个字符之间', -1);
}
}
// 附件处理
if(!empty($params['images']))
{
if(!is_array($params['images']))
{
$params['images'] = json_decode(htmlspecialchars_decode($params['images']), true);
}
foreach($params['images'] as &$v)
{
if(!empty($v))
{
foreach($v as &$vs)
{
$vs = ResourcesService::AttachmentPathHandle($vs);
}
if(count($v) > 3)
{
return DataReturn('每项评论图片不能超过3张', -1);
}
}
}
}
// 获取订单信息
$order_id = intval($params['id']);
$where = ['id'=>$order_id, 'user_id'=>$params['user']['id'], 'is_delete_time'=>0, 'user_is_delete_time'=>0];
$order = Db::name('Order')->where($where)->field('id,status,user_is_comments')->find();
if(empty($order))
{
return DataReturn('资源不存在或已被删除', -1);
}
if($order['status'] != 4)
{
$status_text = MyConst('common_order_status')[$order['status']]['name'];
return DataReturn('状态不可操作['.$status_text.']', -1);
}
if($order['user_is_comments'] != 0)
{
return DataReturn('该订单你已进行过评论', -10);
}
// 处理数据
Db::startTrans();
$is_anonymous = isset($params['is_anonymous']) ? min(1, intval($params['is_anonymous'])) : 0;
foreach($params['goods_id'] as $k=>$goods_id)
{
$data = [
'user_id' => $params['user']['id'],
'order_id' => $order_id,
'goods_id' => $goods_id,
'business_type' => $params['business_type'],
'content' => isset($params['content'][$k]) ? htmlspecialchars(trim($params['content'][$k])) : '',
'images' => empty($params['images'][$k]) ? '' : json_encode($params['images'][$k]),
'rating' => isset($params['rating'][$k]) ? intval($params['rating'][$k]) : 0,
'is_anonymous' => $is_anonymous,
'add_time' => time(),
];
if(Db::name('GoodsComments')->insertGetId($data) <= 0)
{
Db::rollback();
return DataReturn('评论内容添加失败', -100);
}
}
// 订单评论状态更新
if(!Db::name('Order')->where($where)->update(['user_is_comments'=>time(), 'upd_time'=>time()]))
{
Db::rollback();
return DataReturn('订单更新失败', -101);
}
Db::commit();
return DataReturn('评论成功', 0);
}
/**
* 获取商品评论列表
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2018-09-29
* @desc description
* @param [array] $params [输入参数]
*/
public static function GoodsCommentsList($params = [])
{
$where = empty($params['where']) ? [] : $params['where'];
$field = empty($params['field']) ? '*' : $params['field'];
$order_by = empty($params['order_by']) ? 'id desc' : $params['order_by'];
$m = isset($params['m']) ? intval($params['m']) : 0;
$n = isset($params['n']) ? intval($params['n']) : 10;
// 获取数据列表
$data = Db::name('GoodsComments')->where($where)->field($field)->limit($m, $n)->order($order_by)->select()->toArray();
return DataReturn('处理成功', 0, self::GoodsCommentsListHandle($data, $params));
}
/**
* 数据处理
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2019-05-14
* @desc description
* @param [array] $data [数据]
* @param [array] $params [输入参数]
*/
public static function GoodsCommentsListHandle($data, $params = [])
{
if(!empty($data))
{
// 获取商品信息
$is_goods = (isset($params['is_goods']) && $params['is_goods'] == 1) ? 1 : 0;
$goods = [];
if($is_goods == 1)
{
$goods_params = [
'where' => [
['id', 'in', array_unique(array_column($data, 'goods_id'))],
['is_delete_time', '=', 0],
],
'field' => 'id,title,images,price,min_price',
];
$ret = GoodsService::GoodsList($goods_params);
if(!empty($ret['data']))
{
foreach($ret['data'] as $g)
{
$goods[$g['id']] = $g;
}
}
}
// 静态数据
$common_is_text_list = MyConst('common_is_text_list');
$comments_rating_list = MyConst('common_goods_comments_rating_list');
$comments_business_type_list = MyConst('common_goods_comments_business_type_list');
// 用户默认头像
$default_avatar = SystemBaseService::AttachmentHost().'/static/index/'.strtolower(MyFileConfig('common_default_theme', '', 'default', true)).'/images/default-user-avatar.jpg';
// 数据处理
foreach($data as &$v)
{
// 用户信息
if(array_key_exists('user_id', $v))
{
$user = UserService::GetUserViewInfo($v['user_id']);
if(!isset($params['is_public']) || $params['is_public'] == 1)
{
$v['user'] = [
'avatar' => empty($user['avatar']) ? $default_avatar : $user['avatar'],
'user_name_view' => (!isset($v['is_anonymous']) || $v['is_anonymous'] == 1 || empty($user['user_name_view'])) ? '匿名' : mb_substr($user['user_name_view'], 0, 1, 'utf-8').'***'.mb_substr($user['user_name_view'], -1, null, 'utf-8'),
];
} else {
$v['user'] = $user;
}
}
// 图片
if(array_key_exists('images', $v))
{
if(!empty($v['images']))
{
$images = json_decode($v['images'], true);
foreach($images as &$img)
{
$img = ResourcesService::AttachmentPathViewHandle($img);
}
$v['images'] = $images;
}
}
// 商品信息
if(array_key_exists('goods_id', $v) && $is_goods == 1)
{
$v['goods'] = isset($goods[$v['goods_id']]) ? $goods[$v['goods_id']] : [];
}
// 业务类型
if(array_key_exists('business_type', $v))
{
$v['business_type_text'] = array_key_exists($v['business_type'], $comments_business_type_list) ? $comments_business_type_list[$v['business_type']]['name'] : null;
$msg = null;
switch($v['business_type'])
{
// 订单
case 'order' :
if(!empty($v['order_id']) && !empty($v['goods_id']) && !empty($v['user_id']))
{
$msg = self::BusinessTypeOrderSpec($v['order_id'], $v['goods_id'], $v['user_id']);
}
}
$v['msg'] = empty($msg) ? null : $msg;
}
// 评分
if(array_key_exists('rating', $v))
{
$v['rating_text'] = $comments_rating_list[$v['rating']]['name'];
$v['rating_badge'] = $comments_rating_list[$v['rating']]['badge'];
}
// 是否
if(array_key_exists('is_reply', $v))
{
$v['is_reply_text'] = isset($common_is_text_list[$v['is_reply']]) ? $common_is_text_list[$v['is_reply']]['name'] : '';
}
if(array_key_exists('is_anonymous', $v))
{
$v['is_anonymous_text'] = isset($common_is_text_list[$v['is_anonymous']]) ? $common_is_text_list[$v['is_anonymous']]['name'] : '';
}
if(array_key_exists('is_show', $v))
{
$v['is_show_text'] = isset($common_is_text_list[$v['is_show']]) ? $common_is_text_list[$v['is_show']]['name'] : '';
}
// 回复时间
if(array_key_exists('reply_time', $v))
{
$v['reply_time_time'] = empty($v['reply_time']) ? null : date('Y-m-d H:i:s', $v['reply_time']);
$v['reply_time_date'] = empty($v['reply_time']) ? null : date('m-d H:i', $v['reply_time']);
}
// 评论时间
if(array_key_exists('add_time', $v))
{
$v['add_time_hour'] = date('H:i:s', $v['add_time']);
$v['add_time_time'] = date('Y-m-d H:i:s', $v['add_time']);
$v['add_time_date'] = date('m-d H:i', $v['add_time']);
}
// 更新时间
if(array_key_exists('upd_time', $v))
{
$v['upd_time_time'] = empty($v['upd_time']) ? null : date('Y-m-d H:i:s', $v['upd_time']);
$v['upd_time_date'] = empty($v['upd_time']) ? null : date('m-d H:I', $v['upd_time']);
}
}
} else {
$data = [];
}
return $data;
}
/**
* 订单规格字符串处理
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2019-05-14
* @desc description
* @param [int] $order_id [订单id]
* @param [int] $goods_id [商品id]
* @param [int] $user_id [用户id]
* @return [string] [规格字符串]
*/
private static function BusinessTypeOrderSpec($order_id, $goods_id, $user_id = 0)
{
$string = null;
$spec = Db::name('OrderDetail')->where(['order_id'=>$order_id, 'goods_id'=>$goods_id])->value('spec');
if(!empty($spec))
{
$spec = json_decode($spec, true);
if(is_array($spec) && !empty($spec))
{
foreach($spec as $k=>$v)
{
if($k > 0)
{
$string .= ' | ';
}
$string .= $v['type'].''.$v['value'];
}
}
}
return $string;
}
/**
* 商品评论总数
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2018-09-29
* @desc description
* @param [array] $where [条件]
*/
public static function GoodsCommentsTotal($where = [])
{
return (int) Db::name('GoodsComments')->where($where)->count();
}
/**
* 评论保存
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2018-07-17
* @desc description
* @param [array] $params [输入参数]
*/
public static function GoodsCommentsSave($params = [])
{
// 参数校验
$p = [
[
'checked_type' => 'empty',
'key_name' => 'id',
'error_msg' => '操作id有误',
],
[
'checked_type' => 'in',
'key_name' => 'business_type',
'checked_data' => array_keys(MyConst('common_order_aftersale_refundment_list')),
'error_msg' => '请选择业务类型',
],
[
'checked_type' => 'length',
'key_name' => 'content',
'checked_data' => '6,230',
'error_msg' => '评论内容 6~230 个字符之间',
],
[
'checked_type' => 'length',
'key_name' => 'reply',
'checked_data' => '230',
'error_msg' => '回复内容最多 230 个字符',
],
[
'checked_type' => 'in',
'key_name' => 'rating',
'checked_data' => array_keys(MyConst('common_goods_comments_rating_list')),
'error_msg' => '请选择评分',
],
];
$ret = ParamsChecked($params, $p);
if($ret !== true)
{
return DataReturn($ret, -1);
}
// 开始操作
$data = [
'content' => $params['content'],
'reply' => $params['reply'],
'business_type' => $params['business_type'],
'rating' => intval($params['rating']),
'reply_time' => empty($params['reply_time']) ? 0 : strtotime($params['reply_time']),
'is_reply' => isset($params['is_reply']) ? intval($params['is_reply']) : 0,
'is_show' => isset($params['is_show']) ? intval($params['is_show']) : 0,
'is_anonymous' => isset($params['is_anonymous']) ? intval($params['is_anonymous']) : 0,
'upd_time' => time(),
];
// 更新
if(Db::name('GoodsComments')->where(['id'=>intval($params['id'])])->update($data))
{
return DataReturn('编辑成功', 0);
}
return DataReturn('编辑失败或数据不存在', -100);
}
/**
* 删除
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2018-09-30
* @desc description
* @param [array] $params [输入参数]
*/
public static function GoodsCommentsDelete($params = [])
{
// 参数是否有误
if(empty($params['ids']))
{
return DataReturn('操作id有误', -1);
}
// 是否数组
if(!is_array($params['ids']))
{
$params['ids'] = explode(',', $params['ids']);
}
// 开始删除
if(Db::name('GoodsComments')->where(['id'=>$params['ids']])->delete())
{
return DataReturn('删除成功', 0);
}
return DataReturn('删除失败', -100);
}
/**
* 回复
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2018-12-18
* @desc description
* @param [array] $params [输入参数]
*/
public static function GoodsCommentsReply($params = [])
{
// 请求参数
$p = [
[
'checked_type' => 'empty',
'key_name' => 'id',
'error_msg' => '操作id有误',
],
[
'checked_type' => 'empty',
'key_name' => 'reply',
'error_msg' => '回复内容不能为空',
],
[
'checked_type' => 'length',
'key_name' => 'reply',
'checked_data' => '1,230',
'error_msg' => '回复内容格式 1~230 个字符',
],
];
$ret = ParamsChecked($params, $p);
if($ret !== true)
{
return DataReturn($ret, -1);
}
// 评论是否存在
$comments_id = Db::name('GoodsComments')->field('id')->find(intval($params['id']));
if(empty($comments_id))
{
return DataReturn('资源不存在或已被删除', -2);
}
// 更新问答
$data = [
'reply' => $params['reply'],
'is_reply' => 1,
'reply_time' => time(),
'upd_time' => time()
];
if(Db::name('GoodsComments')->where(['id'=>$comments_id])->update($data))
{
return DataReturn('操作成功');
}
return DataReturn('操作失败', -100);
}
/**
* 状态更新
* @author Devil
* @blog http://gong.gg/
* @version 0.0.1
* @datetime 2016-12-06T21:31:53+0800
* @param [array] $params [输入参数]
*/
public static function GoodsCommentsStatusUpdate($params = [])
{
// 请求参数
$p = [
[
'checked_type' => 'empty',
'key_name' => 'id',
'error_msg' => '操作id有误',
],
[
'checked_type' => 'in',
'key_name' => 'state',
'checked_data' => [0,1],
'error_msg' => '状态有误',
],
[
'checked_type' => 'in',
'key_name' => 'field',
'checked_data' => ['is_anonymous', 'is_show', 'is_reply'],
'error_msg' => '操作字段有误',
],
];
$ret = ParamsChecked($params, $p);
if($ret !== true)
{
return DataReturn($ret, -1);
}
// 数据更新
$data = [
$params['field'] => intval($params['state']),
'upd_time' => time(),
];
if(Db::name('GoodsComments')->where(['id'=>intval($params['id'])])->update($data))
{
return DataReturn('编辑成功');
}
return DataReturn('编辑失败或数据未改变', -100);
}
/**
* 商品动态评分
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2019-05-15
* @desc description
* @param [int] $goods_id [商品id]
*/
public static function GoodsCommentsScore($goods_id)
{
// 默认
$rating_list = [
1 => ['rating'=>1, 'name'=>'1分', 'count'=>0, 'portion'=>0],
2 => ['rating'=>2, 'name'=>'2分', 'count'=>0, 'portion'=>0],
3 => ['rating'=>3, 'name'=>'3分', 'count'=>0, 'portion'=>0],
4 => ['rating'=>4, 'name'=>'4分', 'count'=>0, 'portion'=>0],
5 => ['rating'=>5, 'name'=>'5分', 'count'=>0, 'portion'=>0],
];
$where = [
['goods_id', '=', $goods_id],
['rating', '>', 0],
];
$data = Db::name('GoodsComments')->where($where)->group('rating')->column('count(*) as count', 'rating');
if(!empty($data))
{
$sum = array_sum($data);
foreach($data as $rating=>$count)
{
if($rating > 0 && $rating <= 5)
{
$rating_list[$rating]['count'] = $count;
$rating_list[$rating]['portion'] = round(($count/$sum)*100);
}
}
}
sort($rating_list);
$avg = PriceNumberFormat(Db::name('GoodsComments')->where($where)->avg('rating'), 1);
$rate = ($avg <= 0) ? 100 : intval(($avg/5)*100);
return [
'avg' => $avg,
'rate' => $rate,
'rating' => $rating_list,
];
}
/**
* 商品最新几条评论
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2019-05-15
* @desc description
* @param [int] $goods_id [商品id]
* @param [int] $number [获取数量、默认3条]
*/
public static function GoodsFirstSeveralComments($goods_id, $number = 3)
{
$where = [
['goods_id', '=', $goods_id],
['is_show', '=', 1],
];
$field = 'id,user_id,order_id,business_type,content,reply,is_reply,rating,images,is_anonymous,reply_time,add_time';
return self::GoodsCommentsListHandle(Db::name('GoodsComments')->where($where)->field($field)->limit(0, $number)->order('id desc')->select()->toArray());
}
}
?>