feat: 重构后台服务字典与商品独立定价体系及前后端交互优化
这个提交包含在:
@@ -155,4 +155,138 @@ class Base extends Api
|
||||
{
|
||||
return date('YmdHis') . str_pad((string)mt_rand(0, 999999), 6, '0', STR_PAD_LEFT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步写入或隐藏独立晒单表 fa_showcase(仅存储脱敏后的必要公开信息)
|
||||
* @param array $order 订单行
|
||||
* @param int $isShowcase 1=公开晒单, 0=取消晒单
|
||||
* @return int 晒单表主键 ID(取消时返回 0)
|
||||
*/
|
||||
protected function syncOrderShowcase(array $order, $isShowcase = 1)
|
||||
{
|
||||
$orderId = (int)$order['id'];
|
||||
$now = time();
|
||||
if (!$isShowcase) {
|
||||
Db::name('showcase')->where('order_id', $orderId)->update([
|
||||
'status' => 'hidden',
|
||||
'updatetime' => $now,
|
||||
]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
$rev = Db::name('review')->where('order_id', $orderId)->where('status', 'normal')->find();
|
||||
$u = Db::name('user')->where('id', (int)$order['user_id'])->find();
|
||||
$cat = Db::name('service_cat')->where('id', (int)$order['cat_id'])->find();
|
||||
$service = Db::name('service')->where('id', (int)$order['service_id'])->find();
|
||||
|
||||
$isAnon = $rev ? (int)$rev['is_anonymous'] : 0;
|
||||
$userName = '匿名业主';
|
||||
$userAvatar = '';
|
||||
if (!$isAnon && $u) {
|
||||
$nick = trim((string)$u['nickname']);
|
||||
if ($nick !== '' && !preg_match('/^[0-9]/', $nick)) {
|
||||
$userName = mb_substr($nick, 0, 1) . '业主';
|
||||
} else {
|
||||
$userName = '优匠业主';
|
||||
}
|
||||
$userAvatar = !empty($u['avatar']) ? (string)$u['avatar'] : '';
|
||||
}
|
||||
|
||||
// 地区仅保留区县或城市,绝不保存具体街道/小区/门牌
|
||||
$district = trim((string)$order['district']);
|
||||
$city = trim((string)$order['city']);
|
||||
$region = $district ?: ($city ?: '同城服务');
|
||||
|
||||
// 收集晒单实拍图(评价晒图 > 完工实况图,过滤无效测试域名)
|
||||
$imgList = [];
|
||||
if ($rev && !empty($rev['images'])) {
|
||||
$dec = json_decode((string)$rev['images'], true);
|
||||
$arr = is_array($dec) ? $dec : array_filter(explode(',', (string)$rev['images']));
|
||||
foreach ($arr as $it) {
|
||||
$it = trim((string)$it);
|
||||
if ($it !== '' && substr($it, -4) !== '.svg' && strpos($it, 'example.com') === false) {
|
||||
$imgList[] = $it;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (empty($imgList)) {
|
||||
$mediaUrls = Db::name('order_media')->where('order_id', $orderId)->order('id desc')->limit(6)->column('url');
|
||||
foreach ($mediaUrls as $mu) {
|
||||
$mu = trim((string)$mu);
|
||||
if ($mu !== '' && substr($mu, -4) !== '.svg' && strpos($mu, 'example.com') === false) {
|
||||
$imgList[] = $mu;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 封面图提取
|
||||
$cover = !empty($imgList) ? $imgList[0] : '';
|
||||
if ($cover === '' && !empty($order['service_image']) && substr($order['service_image'], -4) !== '.svg') {
|
||||
$cover = (string)$order['service_image'];
|
||||
}
|
||||
if ($cover === '' && $service && !empty($service['image']) && substr($service['image'], -4) !== '.svg') {
|
||||
$cover = (string)$service['image'];
|
||||
}
|
||||
if ($cover === '') {
|
||||
$fallback = Db::name('service')
|
||||
->where('cat_id', (int)$order['cat_id'])
|
||||
->where('image', '<>', '')
|
||||
->where('image', 'not like', '%.svg%')
|
||||
->order('weigh desc, id asc')
|
||||
->value('image');
|
||||
if ($fallback) {
|
||||
$cover = (string)$fallback;
|
||||
}
|
||||
}
|
||||
|
||||
// 师傅脱敏称呼与评分
|
||||
$masterName = '优匠师傅';
|
||||
$masterScore = 5.00;
|
||||
if ((int)$order['master_id'] > 0) {
|
||||
$m = Db::name('master')->where('id', (int)$order['master_id'])->find();
|
||||
if ($m) {
|
||||
$rName = trim((string)$m['realname']);
|
||||
if ($rName !== '' && strpos($rName, '师傅') === false) {
|
||||
$masterName = mb_substr($rName, 0, 1) . '师傅';
|
||||
} elseif ($rName !== '') {
|
||||
$masterName = $rName;
|
||||
}
|
||||
$masterScore = (float)$m['score'] > 0 ? round((float)$m['score'], 2) : 5.00;
|
||||
}
|
||||
}
|
||||
|
||||
$score = $rev ? max(1, min(5, (int)$rev['score'])) : 5;
|
||||
$tags = ($rev && !empty($rev['tags'])) ? (string)$rev['tags'] : '准时,专业,值得推荐';
|
||||
$content = ($rev && !empty($rev['content'])) ? (string)$rev['content'] : '师傅准时上门,施工专业细致,安装效果很满意!';
|
||||
|
||||
$payload = [
|
||||
'order_id' => $orderId,
|
||||
'user_id' => (int)$order['user_id'],
|
||||
'user_name' => $userName,
|
||||
'user_avatar' => $userAvatar,
|
||||
'cat_id' => (int)$order['cat_id'],
|
||||
'cat_name' => $cat ? (string)$cat['name'] : '上门服务',
|
||||
'service_id' => (int)$order['service_id'],
|
||||
'service_name' => $order['service_name'] ?: ($service ? (string)$service['name'] : '上门服务'),
|
||||
'region' => $region,
|
||||
'cover_image' => $cover,
|
||||
'images' => !empty($imgList) ? json_encode(array_values($imgList), JSON_UNESCAPED_UNICODE) : '',
|
||||
'score' => $score,
|
||||
'tags' => $tags,
|
||||
'content' => mb_substr($content, 0, 500),
|
||||
'master_name' => $masterName,
|
||||
'master_score' => $masterScore,
|
||||
'status' => 'normal',
|
||||
'updatetime' => $now,
|
||||
];
|
||||
|
||||
$existing = Db::name('showcase')->where('order_id', $orderId)->find();
|
||||
if ($existing) {
|
||||
Db::name('showcase')->where('id', (int)$existing['id'])->update($payload);
|
||||
return (int)$existing['id'];
|
||||
} else {
|
||||
$payload['createtime'] = !empty($order['showcase_time']) ? (int)$order['showcase_time'] : $now;
|
||||
return (int)Db::name('showcase')->insertGetId($payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
在新工单中引用
屏蔽一个用户