|
@@ -2,12 +2,19 @@
|
|
|
/**
|
|
/**
|
|
|
* 用途:商城顾客售后申请业务类
|
|
* 用途:商城顾客售后申请业务类
|
|
|
* 谁用:app-mall RefundController、app-hd RefundController 审核入口
|
|
* 谁用:app-mall RefundController、app-hd RefundController 审核入口
|
|
|
- * 解决:申请记录的增删改查、归属校验、列表查询
|
|
|
|
|
|
|
+ * 解决:申请记录的增删改查、归属校验;顾客端列表按设计稿补齐店铺/商品/状态文案
|
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
namespace bizHd\refund\classes;
|
|
namespace bizHd\refund\classes;
|
|
|
|
|
|
|
|
use bizHd\base\classes\BaseClass;
|
|
use bizHd\base\classes\BaseClass;
|
|
|
|
|
+use bizHd\custom\classes\HdClass;
|
|
|
|
|
+use bizHd\order\classes\OrderClass;
|
|
|
|
|
+use bizHd\order\classes\OrderGoodsClass;
|
|
|
|
|
+use bizHd\order\classes\OrderItemClass;
|
|
|
|
|
+use bizHd\shop\classes\ShopClass;
|
|
|
|
|
+use biz\shop\classes\ShopClass as SharedShopClass;
|
|
|
|
|
+use common\components\imgUtil;
|
|
|
use common\components\util;
|
|
use common\components\util;
|
|
|
|
|
|
|
|
class MallRefundApplyClass extends BaseClass
|
|
class MallRefundApplyClass extends BaseClass
|
|
@@ -46,20 +53,30 @@ class MallRefundApplyClass extends BaseClass
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 校验申请归属顾客(商城端)
|
|
|
|
|
|
|
+ * 校验申请归属当前登录商城用户
|
|
|
|
|
+ * 列表/详情不带当前店 hdId 时 customId 可能为 0,需同时认 userId
|
|
|
* @param object|null $apply
|
|
* @param object|null $apply
|
|
|
- * @param int $customId
|
|
|
|
|
|
|
+ * @param int $customId 当前请求店铺的客户 id,可能为 0
|
|
|
|
|
+ * @param int $userId 商城登录用户 id
|
|
|
* @return bool
|
|
* @return bool
|
|
|
*/
|
|
*/
|
|
|
- public static function validByCustom($apply, $customId)
|
|
|
|
|
|
|
+ public static function validByCustom($apply, $customId, $userId = 0)
|
|
|
{
|
|
{
|
|
|
if (empty($apply)) {
|
|
if (empty($apply)) {
|
|
|
util::fail('没有找到售后申请');
|
|
util::fail('没有找到售后申请');
|
|
|
}
|
|
}
|
|
|
- if ((int)($apply->customId ?? 0) !== (int)$customId) {
|
|
|
|
|
- util::fail('不是你的售后申请');
|
|
|
|
|
|
|
+ $userId = (int)$userId;
|
|
|
|
|
+ $customId = (int)$customId;
|
|
|
|
|
+ $applyUserId = (int)($apply->userId ?? 0);
|
|
|
|
|
+ $applyCustomId = (int)($apply->customId ?? 0);
|
|
|
|
|
+ if ($userId > 0 && $applyUserId === $userId) {
|
|
|
|
|
+ return true;
|
|
|
}
|
|
}
|
|
|
- return true;
|
|
|
|
|
|
|
+ if ($customId > 0 && $applyCustomId === $customId) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ util::fail('不是你的售后申请');
|
|
|
|
|
+ return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -107,17 +124,54 @@ class MallRefundApplyClass extends BaseClass
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 顾客端申请列表
|
|
|
|
|
- * @param array $where
|
|
|
|
|
|
|
+ * 顾客端售后列表(mallApp 退款售后页,跨店)
|
|
|
|
|
+ * 按商城 userId 过滤,避免请求里只有缓存店铺 customId 时漏单或 customId=0
|
|
|
|
|
+ * @param int $userId 当前登录商城用户
|
|
|
|
|
+ * @param string $tab all|pending|0|refunded|1|closed|2|3
|
|
|
|
|
+ * @return array 分页 list + pendingCount(处理中角标)
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function getCustomApplyList($userId, $tab = 'all')
|
|
|
|
|
+ {
|
|
|
|
|
+ $userId = (int)$userId;
|
|
|
|
|
+ $where = ['userId' => $userId];
|
|
|
|
|
+ $tab = (string)$tab;
|
|
|
|
|
+ if ($tab === 'pending' || $tab === '0') {
|
|
|
|
|
+ $where['status'] = self::STATUS_PENDING;
|
|
|
|
|
+ } elseif ($tab === 'refunded' || $tab === '1') {
|
|
|
|
|
+ $where['status'] = self::STATUS_PASS;
|
|
|
|
|
+ } elseif ($tab === 'closed') {
|
|
|
|
|
+ // 已关闭:驳回 + 顾客撤销,对应设计稿「已关闭」Tab
|
|
|
|
|
+ $where['status'] = ['in', [self::STATUS_REJECT, self::STATUS_CANCEL]];
|
|
|
|
|
+ } elseif ($tab !== '' && $tab !== 'all' && is_numeric($tab)) {
|
|
|
|
|
+ $where['status'] = (int)$tab;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $data = self::getList('*', $where, 'addTime DESC');
|
|
|
|
|
+ $data['pendingCount'] = (int)self::getCount([
|
|
|
|
|
+ 'userId' => $userId,
|
|
|
|
|
+ 'status' => self::STATUS_PENDING,
|
|
|
|
|
+ ]);
|
|
|
|
|
+ if (!empty($data['list'])) {
|
|
|
|
|
+ $data['list'] = self::formatCustomList($data['list']);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $data['list'] = [];
|
|
|
|
|
+ }
|
|
|
|
|
+ return $data;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 顾客端售后详情:单条申请补齐与列表相同的展示字段
|
|
|
|
|
+ * @param array $row xhMallRefundApply 行
|
|
|
* @return array
|
|
* @return array
|
|
|
*/
|
|
*/
|
|
|
- public static function getCustomApplyList($where)
|
|
|
|
|
|
|
+ public static function formatCustomDetail($row)
|
|
|
{
|
|
{
|
|
|
- return self::getList('*', $where, 'addTime DESC');
|
|
|
|
|
|
|
+ $list = self::formatCustomList([$row]);
|
|
|
|
|
+ return $list[0] ?? $row;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 状态文案
|
|
|
|
|
|
|
+ * 状态短文案(审核语义)
|
|
|
* @param int $status
|
|
* @param int $status
|
|
|
* @return string
|
|
* @return string
|
|
|
*/
|
|
*/
|
|
@@ -131,4 +185,332 @@ class MallRefundApplyClass extends BaseClass
|
|
|
];
|
|
];
|
|
|
return $map[(int)$status] ?? '';
|
|
return $map[(int)$status] ?? '';
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 列表卡片主状态文案,对齐设计稿「退款中·待商家处理 / 退款成功」
|
|
|
|
|
+ * @param int $status
|
|
|
|
|
+ * @param int $refundType 1退货退款 2仅退款
|
|
|
|
|
+ * @return string
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function displayStatusTitle($status, $refundType)
|
|
|
|
|
+ {
|
|
|
|
|
+ $status = (int)$status;
|
|
|
|
|
+ if ($status === self::STATUS_PENDING) {
|
|
|
|
|
+ return (int)$refundType === self::REFUND_TYPE_MONEY_GOOD
|
|
|
|
|
+ ? '退货中·待商家处理'
|
|
|
|
|
+ : '退款中·待商家处理';
|
|
|
|
|
+ }
|
|
|
|
|
+ if ($status === self::STATUS_PASS) {
|
|
|
|
|
+ return '退款成功';
|
|
|
|
|
+ }
|
|
|
|
|
+ if ($status === self::STATUS_REJECT) {
|
|
|
|
|
+ return '已驳回';
|
|
|
|
|
+ }
|
|
|
|
|
+ if ($status === self::STATUS_CANCEL) {
|
|
|
|
|
+ return '已取消';
|
|
|
|
|
+ }
|
|
|
|
|
+ return self::statusText($status);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 卡片底部提示:处理中给审核时效,通过后带审核时间
|
|
|
|
|
+ * @param array $row
|
|
|
|
|
+ * @return string
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function displayStatusTip($row)
|
|
|
|
|
+ {
|
|
|
|
|
+ $status = (int)($row['status'] ?? 0);
|
|
|
|
|
+ if ($status === self::STATUS_PENDING) {
|
|
|
|
|
+ return '商家审核中·预计 24 小时内处理';
|
|
|
|
|
+ }
|
|
|
|
|
+ if ($status === self::STATUS_PASS) {
|
|
|
|
|
+ $time = trim((string)($row['auditTime'] ?? ''));
|
|
|
|
|
+ if ($time !== '' && $time !== '0000-00-00 00:00:00') {
|
|
|
|
|
+ return '退款已到账·原路退回 ' . $time;
|
|
|
|
|
+ }
|
|
|
|
|
+ return '退款已到账·原路退回';
|
|
|
|
|
+ }
|
|
|
|
|
+ if ($status === self::STATUS_REJECT) {
|
|
|
|
|
+ $reason = trim((string)($row['rejectReason'] ?? ''));
|
|
|
|
|
+ return $reason !== '' ? ('商家已驳回·' . $reason) : '商家已驳回';
|
|
|
|
|
+ }
|
|
|
|
|
+ if ($status === self::STATUS_CANCEL) {
|
|
|
|
|
+ return '申请已取消';
|
|
|
|
|
+ }
|
|
|
|
|
+ return '';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 退款类型标签:1退货退款 2仅退款
|
|
|
|
|
+ * @param int $refundType
|
|
|
|
|
+ * @return string
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function refundTypeText($refundType)
|
|
|
|
|
+ {
|
|
|
|
|
+ return (int)$refundType === self::REFUND_TYPE_MONEY_GOOD ? '退货退款' : '仅退款';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 批量补齐店铺名、商品封面/规格,避免列表 N+1
|
|
|
|
|
+ * @param array $list
|
|
|
|
|
+ * @return array
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function formatCustomList($list)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (empty($list) || !is_array($list)) {
|
|
|
|
|
+ return [];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $shopIds = [];
|
|
|
|
|
+ $hdIds = [];
|
|
|
|
|
+ $orderSns = [];
|
|
|
|
|
+ foreach ($list as $row) {
|
|
|
|
|
+ $shopId = (int)($row['shopId'] ?? 0);
|
|
|
|
|
+ if ($shopId > 0) {
|
|
|
|
|
+ $shopIds[$shopId] = $shopId;
|
|
|
|
|
+ }
|
|
|
|
|
+ $hdId = (int)($row['hdId'] ?? 0);
|
|
|
|
|
+ if ($hdId > 0) {
|
|
|
|
|
+ $hdIds[$hdId] = $hdId;
|
|
|
|
|
+ }
|
|
|
|
|
+ $sn = trim((string)($row['orderSn'] ?? ''));
|
|
|
|
|
+ if ($sn !== '') {
|
|
|
|
|
+ $orderSns[$sn] = $sn;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 花店名称按申请 shopId 查 xhShop,首店展示商家名、分店拼 merchantName-shopName
|
|
|
|
|
+ $shopMap = [];
|
|
|
|
|
+ if (!empty($shopIds)) {
|
|
|
|
|
+ $shopMap = ShopClass::getByIds(array_values($shopIds), null, 'id', 'id,shopName,merchantName,avatar') ?: [];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 联系客服要的是该店 xhHd.customId,申请表 customId 可能为 0
|
|
|
|
|
+ $hdCustomMap = [];
|
|
|
|
|
+ if (!empty($hdIds)) {
|
|
|
|
|
+ $hdRows = HdClass::getByIds(array_values($hdIds), null, 'id', 'id,customId') ?: [];
|
|
|
|
|
+ foreach ($hdRows as $id => $hd) {
|
|
|
|
|
+ $hdCustomMap[(int)$id] = (int)($hd['customId'] ?? 0);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $orderCustomMap = [];
|
|
|
|
|
+
|
|
|
|
|
+ $goodsBySn = [];
|
|
|
|
|
+ $itemBySn = [];
|
|
|
|
|
+ $firstGoodsBySn = [];
|
|
|
|
|
+ if (!empty($orderSns)) {
|
|
|
|
|
+ $snList = array_values($orderSns);
|
|
|
|
|
+ $orderRows = OrderClass::getAllByCondition(['orderSn' => ['in', $snList]], null, 'orderSn,customId') ?: [];
|
|
|
|
|
+ foreach ($orderRows as $order) {
|
|
|
|
|
+ $sn = $order['orderSn'] ?? '';
|
|
|
|
|
+ $cid = (int)($order['customId'] ?? 0);
|
|
|
|
|
+ if ($sn !== '' && $cid > 0) {
|
|
|
|
|
+ $orderCustomMap[$sn] = $cid;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ $goodsRows = OrderGoodsClass::getAllByCondition(['orderSn' => ['in', $snList]]) ?: [];
|
|
|
|
|
+ foreach ($goodsRows as $goods) {
|
|
|
|
|
+ $sn = $goods['orderSn'] ?? '';
|
|
|
|
|
+ $gid = (int)($goods['goodsId'] ?? 0);
|
|
|
|
|
+ if ($sn === '') {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ $goodsBySn[$sn][$gid] = $goods;
|
|
|
|
|
+ if (!isset($firstGoodsBySn[$sn])) {
|
|
|
|
|
+ $firstGoodsBySn[$sn] = $goods;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ $itemRows = OrderItemClass::getAllByCondition(['orderSn' => ['in', $snList]]) ?: [];
|
|
|
|
|
+ foreach ($itemRows as $item) {
|
|
|
|
|
+ $sn = $item['orderSn'] ?? '';
|
|
|
|
|
+ $itemId = (int)($item['itemId'] ?? 0);
|
|
|
|
|
+ if ($sn === '' || $itemId <= 0) {
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ $itemBySn[$sn][$itemId] = $item;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $formatted = [];
|
|
|
|
|
+ foreach ($list as $row) {
|
|
|
|
|
+ $formatted[] = self::formatCustomRow($row, $shopMap, $goodsBySn, $itemBySn, $firstGoodsBySn, $hdCustomMap, $orderCustomMap);
|
|
|
|
|
+ }
|
|
|
|
|
+ return $formatted;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 单条申请转列表/详情展示结构
|
|
|
|
|
+ * @param array $row
|
|
|
|
|
+ * @param array $shopMap shopId => xhShop 行
|
|
|
|
|
+ * @param array $goodsBySn orderSn => [goodsId => 行]
|
|
|
|
|
+ * @param array $itemBySn orderSn => [itemId => 行]
|
|
|
|
|
+ * @param array $firstGoodsBySn 仅退款无勾选商品时用原单首件兜底
|
|
|
|
|
+ * @param array $hdCustomMap hdId => xhHd.customId
|
|
|
|
|
+ * @param array $orderCustomMap orderSn => 订单 customId
|
|
|
|
|
+ * @return array
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function formatCustomRow($row, $shopMap = [], $goodsBySn = [], $itemBySn = [], $firstGoodsBySn = [], $hdCustomMap = [], $orderCustomMap = [])
|
|
|
|
|
+ {
|
|
|
|
|
+ $status = (int)($row['status'] ?? 0);
|
|
|
|
|
+ $refundType = (int)($row['refundType'] ?? self::REFUND_TYPE_MONEY);
|
|
|
|
|
+ $shopId = (int)($row['shopId'] ?? 0);
|
|
|
|
|
+ $orderSn = trim((string)($row['orderSn'] ?? ''));
|
|
|
|
|
+ $shop = $shopMap[$shopId] ?? [];
|
|
|
|
|
+ $row['customId'] = self::resolveChatCustomId($row, $hdCustomMap, $orderCustomMap);
|
|
|
|
|
+
|
|
|
|
|
+ $productList = [];
|
|
|
|
|
+ if (!empty($row['product'])) {
|
|
|
|
|
+ $decoded = is_array($row['product']) ? $row['product'] : json_decode($row['product'], true);
|
|
|
|
|
+ if (is_array($decoded)) {
|
|
|
|
|
+ $productList = $decoded;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $goodsList = [];
|
|
|
|
|
+ foreach ($productList as $product) {
|
|
|
|
|
+ $property = (int)($product['property'] ?? 0);
|
|
|
|
|
+ $productId = (int)($product['productId'] ?? 0);
|
|
|
|
|
+ $line = [];
|
|
|
|
|
+ if ($property === 1) {
|
|
|
|
|
+ $line = $itemBySn[$orderSn][$productId] ?? [];
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $line = $goodsBySn[$orderSn][$productId] ?? [];
|
|
|
|
|
+ }
|
|
|
|
|
+ $goodsList[] = self::buildGoodsView($product, $line);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 仅退款可能没勾选商品,用原订单首件商品撑起卡片,避免空白
|
|
|
|
|
+ if (empty($goodsList) && isset($firstGoodsBySn[$orderSn])) {
|
|
|
|
|
+ $goodsList[] = self::buildGoodsView([], $firstGoodsBySn[$orderSn]);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $row['productList'] = $productList;
|
|
|
|
|
+ $row['goodsList'] = $goodsList;
|
|
|
|
|
+ $row['goods'] = $goodsList[0] ?? self::emptyGoodsView();
|
|
|
|
|
+ $displayName = SharedShopClass::formatDisplayShopName($shop);
|
|
|
|
|
+ $row['hdName'] = $displayName !== '' ? $displayName : '花店';
|
|
|
|
|
+ $row['hdAvatar'] = self::coverUrl($shop['avatar'] ?? '');
|
|
|
|
|
+ $row['statusText'] = self::statusText($status);
|
|
|
|
|
+ $row['statusTitle'] = self::displayStatusTitle($status, $refundType);
|
|
|
|
|
+ $row['statusTip'] = self::displayStatusTip($row);
|
|
|
|
|
+ $row['statusTone'] = self::statusTone($status);
|
|
|
|
|
+ $row['refundTypeText'] = self::refundTypeText($refundType);
|
|
|
|
|
+ $row['reasonText'] = self::reasonText($row);
|
|
|
|
|
+ $row['canModify'] = $status === self::STATUS_PENDING ? 1 : 0;
|
|
|
|
|
+ $row['refundPrice'] = round((float)($row['refundPrice'] ?? 0), 2);
|
|
|
|
|
+ return $row;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 联系客服用的 customId:申请表可能为 0,依次用申请本身、xhHd、原订单补齐
|
|
|
|
|
+ * @param array $row
|
|
|
|
|
+ * @param array $hdCustomMap
|
|
|
|
|
+ * @param array $orderCustomMap
|
|
|
|
|
+ * @return int
|
|
|
|
|
+ */
|
|
|
|
|
+ protected static function resolveChatCustomId($row, $hdCustomMap, $orderCustomMap)
|
|
|
|
|
+ {
|
|
|
|
|
+ $applyCustomId = (int)($row['customId'] ?? 0);
|
|
|
|
|
+ if ($applyCustomId > 0) {
|
|
|
|
|
+ return $applyCustomId;
|
|
|
|
|
+ }
|
|
|
|
|
+ $hdId = (int)($row['hdId'] ?? 0);
|
|
|
|
|
+ if ($hdId > 0 && !empty($hdCustomMap[$hdId])) {
|
|
|
|
|
+ return (int)$hdCustomMap[$hdId];
|
|
|
|
|
+ }
|
|
|
|
|
+ $orderSn = trim((string)($row['orderSn'] ?? ''));
|
|
|
|
|
+ if ($orderSn !== '' && !empty($orderCustomMap[$orderSn])) {
|
|
|
|
|
+ return (int)$orderCustomMap[$orderSn];
|
|
|
|
|
+ }
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 处理中橙色、成功绿色、关闭灰色,供前端绑 class
|
|
|
|
|
+ * @param int $status
|
|
|
|
|
+ * @return string pending|success|closed
|
|
|
|
|
+ */
|
|
|
|
|
+ protected static function statusTone($status)
|
|
|
|
|
+ {
|
|
|
|
|
+ $status = (int)$status;
|
|
|
|
|
+ if ($status === self::STATUS_PENDING) {
|
|
|
|
|
+ return 'pending';
|
|
|
|
|
+ }
|
|
|
|
|
+ if ($status === self::STATUS_PASS) {
|
|
|
|
|
+ return 'success';
|
|
|
|
|
+ }
|
|
|
|
|
+ return 'closed';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 售后原因:优先顾客备注,没有则给兜底文案(申请表无 refundOptionName)
|
|
|
|
|
+ * @param array $row
|
|
|
|
|
+ * @return string
|
|
|
|
|
+ */
|
|
|
|
|
+ protected static function reasonText($row)
|
|
|
|
|
+ {
|
|
|
|
|
+ $remark = trim((string)($row['remark'] ?? ''));
|
|
|
|
|
+ if ($remark !== '') {
|
|
|
|
|
+ return $remark;
|
|
|
|
|
+ }
|
|
|
|
|
+ return '顾客申请售后';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 把申请商品快照与订单行封面/规格拼成卡片商品
|
|
|
|
|
+ * @param array $product
|
|
|
|
|
+ * @param array $line
|
|
|
|
|
+ * @return array
|
|
|
|
|
+ */
|
|
|
|
|
+ protected static function buildGoodsView($product, $line)
|
|
|
|
|
+ {
|
|
|
|
|
+ $name = $product['name'] ?? ($line['name'] ?? '商品');
|
|
|
|
|
+ $cover = $product['cover'] ?? ($line['cover'] ?? '');
|
|
|
|
|
+ $spec = $product['styleName'] ?? ($product['unitName'] ?? '');
|
|
|
|
|
+ if ($spec === '') {
|
|
|
|
|
+ $spec = $line['styleName'] ?? ($line['unitName'] ?? '');
|
|
|
|
|
+ }
|
|
|
|
|
+ $price = $product['unitPrice'] ?? ($line['unitPrice'] ?? 0);
|
|
|
|
|
+ $num = $product['num'] ?? ($line['num'] ?? 1);
|
|
|
|
|
+ return [
|
|
|
|
|
+ 'name' => $name,
|
|
|
|
|
+ 'cover' => self::coverUrl($cover),
|
|
|
|
|
+ 'spec' => $spec,
|
|
|
|
|
+ 'price' => round((float)$price, 2),
|
|
|
|
|
+ 'num' => $num,
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 无商品时的占位,避免前端取 goods 空指针
|
|
|
|
|
+ * @return array
|
|
|
|
|
+ */
|
|
|
|
|
+ protected static function emptyGoodsView()
|
|
|
|
|
+ {
|
|
|
|
|
+ return [
|
|
|
|
|
+ 'name' => '售后商品',
|
|
|
|
|
+ 'cover' => self::coverUrl(''),
|
|
|
|
|
+ 'spec' => '',
|
|
|
|
|
+ 'price' => 0,
|
|
|
|
|
+ 'num' => 1,
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 相对路径转可访问封面;已是 http(s) 则原样返回
|
|
|
|
|
+ * @param string $short
|
|
|
|
|
+ * @return string
|
|
|
|
|
+ */
|
|
|
|
|
+ protected static function coverUrl($short)
|
|
|
|
|
+ {
|
|
|
|
|
+ $short = trim((string)$short);
|
|
|
|
|
+ if ($short === '') {
|
|
|
|
|
+ return imgUtil::groupImg('retail/default-img.png');
|
|
|
|
|
+ }
|
|
|
|
|
+ if (strpos($short, 'http://') === 0 || strpos($short, 'https://') === 0) {
|
|
|
|
|
+ return $short;
|
|
|
|
|
+ }
|
|
|
|
|
+ return imgUtil::groupImg($short) . '?x-oss-process=image/resize,m_fill,h_200,w_200';
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|