feat: 新增会员浏览/拨打额度并优化无图展示逻辑

新增会员每日浏览完整信息和拨打电话的额度配置,调整付费查看接口描述为解锁完整信息,优化帖子无图时的兜底展示逻辑,修复图片加载路径问题,删除废弃工具脚本。
这个提交包含在:
2026-10-28 11:06:39 +08:00
父节点 bb6418f51b
当前提交 111054d984
共有 179 个文件被更改,包括 931 次插入 和 6265 次删除

查看文件

@@ -922,23 +922,7 @@ class Post extends V1
}
/**
* 详情页联系方式可见性(避免「已开通会员仍显示已受保护」)
*
* 可见规则(与 payView 计费口径一致):
* ① 会员有效期内 → 免费看
* ② 已付费解锁 fc_pay_view → 看(余额 / 微信回调写入)
* ③ 本人发布的信息 → 看
* 其它(游客 / 非会员未付费)→ 仍返回脱敏串
*
* 出参新增:unlocked(bool)、wechat(明文,未解锁为空串)。
* 注意:只加在详情接口,列表(首页/收藏等)仍保持脱敏,避免手机号被批量抓取。
*
* @param array $data buildPost() 结果
* @param array $post fc_post 行
* @return array
*/
/**
* 判断当前全站是否处于「联系方式完全免费公开」模式
* 判断当前全站是否处于「完整信息免费公开」模式
* 规则:fee.viewMode === 'free' 或 fee.payView <= 0 时均为免费公开
*
* @return bool
@@ -951,13 +935,17 @@ class Post extends V1
}
/**
* 详情页联系方式与内容访问控制(支持完全免费公开模式与商业付费/会员解锁模式自由切换)
* 详情页完整信息访问控制(免费公开 / 付费解锁 / 会员每日额度 三态自由切换)
*
* 可见规则:
* ① 全站处于「完全免费公开」模式(fee.viewMode=free 或 fee.payView<=0)→ unlocked=true,直接明文返回
* ② 本人发布的信息或已付费解锁记录(fc_pay_view)→ unlocked=true,返回真实联系方式明文
* ③ 会员享有每日免费查看额度(freeView=0 代表会员不限次数免费看),未点击解锁时不泄露真实号码
* ④ 未解锁状态下,对标题与详细正文中的手机号执行掩码遮蔽,封堵正文直接贴电话的白嫖漏洞
* 联系方式规则:任何模式下界面都不展示手机号(明文与脱敏串均不返回),仅保留拨打按钮,
* 由 POST /post/:id/dial 校验拨打额度后调起系统拨号。
*
* 完整信息(正文/农产品规格)规则:
* ① 免费公开模式(fee.viewMode=free 或 fee.payView<=0)→ 直接放行
* ② 本人发布 或 已付费解锁(fc_pay_view,永久)→ 放行
* ③ 会员:每日免费浏览额度(fc_plan.view_quota,0=不限),同一条当日只计 1 次
* ④ 额度用尽 / 非会员未解锁 → content 仅返回摘要,contentLocked=true
* 防白嫖:标题与正文中出现的手机号始终动态遮蔽。
*
* @param array $data buildPost() 结果
* @param array $post fc_post 行
@@ -965,70 +953,57 @@ class Post extends V1
*/
protected function contactAccess($data, $post)
{
$data['unlocked'] = false;
$data['wechat'] = '';
$me = $this->user();
$ext = $me ? $this->ext($me['id']) : null;
$now = time();
$userId = $me ? (int)$me['id'] : 0;
$isMember = false;
$quota = $this->memberFreeViewQuota($ext);
$freeViewUnlimited = ($quota === 0);
$used = 0;
$freeViewLeft = 0;
$payViewPrice = max(0, round((float)$this->cfg('fee.payView', 2), 2));
$isFreeView = $this->isFreeViewMode();
$isOwner = false;
$paid = false;
if ($me && $ext) {
$isMember = (int)$ext['is_member'] === 1
&& !empty($ext['member_expiretime']) && (int)$ext['member_expiretime'] > $now;
$isOwner = (int)$post['user_id'] === (int)$me['id'];
$paid = (bool)Db::name('fc_pay_view')
->where('user_id', $me['id'])
->where('post_id', $post['id'])
->find();
}
$today = date('Y-m-d');
$used = ((string)$ext['free_view_date'] === $today) ? (int)$ext['free_view_used'] : 0;
if ($isMember) {
$freeViewLeft = $freeViewUnlimited ? 999 : max(0, $quota - $used);
} else {
$freeViewLeft = 0;
$isFreeView = $this->isFreeViewMode();
$payViewPrice = max(0, round((float)$this->cfg('fee.payView', 2), 2));
$isOwner = $userId > 0 && (int)$post['user_id'] === $userId;
// ---- 已付费解锁记录(永久解锁,任何模式不占每日额度) ----
$paid = false;
if ($userId > 0) {
$paid = (bool)Db::name('fc_pay_view')
->where('user_id', $userId)
->where('post_id', (int)$post['id'])
->find();
}
// ---- 完整信息解锁判定 ----
$unlocked = false;
$viewState = null; // 会员付费模式下的浏览额度状态(含本次消耗后的最新值)
if ($isFreeView || $isOwner || $paid) {
$unlocked = true;
} elseif ($isMember) {
// 会员每日浏览额度(view_quota=0 代表不限),同一条当日只计 1 次
$viewState = $this->viewQuotaState($userId, $ext);
if ($this->hasViewedToday($userId, (int)$post['id'])) {
$unlocked = true; // 今日已浏览过该条,不重复扣额度
} elseif ($viewState['unlimited'] || $viewState['left'] > 0) {
$this->recordViewLog($userId, (int)$post['id']);
$viewState['used'] += 1;
$viewState['left'] = $viewState['unlimited'] ? 999 : max(0, $viewState['total'] - $viewState['used']);
$unlocked = true;
}
}
$data['viewMode'] = $isFreeView ? 'free' : 'paid';
$data['isMember'] = $isMember;
$data['freeViewQuota'] = $quota;
$data['freeViewUnlimited'] = $freeViewUnlimited;
$data['freeViewUsed'] = $used;
$data['freeViewLeft'] = $freeViewLeft;
$data['payViewPrice'] = $isFreeView ? 0 : $payViewPrice;
$contentLocked = !$unlocked;
// 每日电话拨打次数上限与剩余额度(详情预览页隐藏明文手机号,仅保留免责声明弹窗拨打)
$callState = $this->callQuotaState($me ? (int)$me['id'] : 0, $isMember);
$rawPhone = (string)$post['phone'];
$contactName = (string)(isset($post['contact']) ? $post['contact'] : '');
$maskedPhone = $this->maskPhone($rawPhone);
// ---- 正文与农产品规格锁定 ----
if ($contentLocked) {
$data['content'] = $this->contentPreview((string)$data['content'], 100);
unset($data['plantArea'], $data['harvestTime'], $data['outputRange']);
}
$data['hasPhone'] = $rawPhone !== '';
$data['dialDisplay'] = $this->buildDialDisplay($contactName, $rawPhone);
$data['callQuotaTotal'] = $callState['total'];
$data['callQuotaUsed'] = $callState['used'];
$data['callQuotaLeft'] = $callState['left'];
$data['canDial'] = $isOwner || $paid || $callState['unlimited'] || $callState['left'] > 0;
// 界面上始终隐藏明文手机号(仅返回脱敏号码),通过 POST /post/:id/dial 校验额度并调起系统拨号
$data['unlocked'] = ($isFreeView || $isOwner || $paid);
$data['phone'] = $maskedPhone;
$data['contact'] = $maskedPhone;
$data['contactName'] = $contactName;
$data['wechat'] = '';
// 标题与详细描述中的任何手机号执行动态安全遮蔽,防止正文直接贴电话
// 标题与正文中出现的手机号始终遮蔽,防止正文贴电话绕过限制
if (!empty($data['content'])) {
$data['content'] = $this->maskTextPhones($data['content']);
}
@@ -1036,39 +1011,138 @@ class Post extends V1
$data['title'] = $this->maskTextPhones($data['title']);
}
// ---- 拨打额度状态 ----
$callState = $this->callQuotaState($userId, $isMember);
$data['unlocked'] = $unlocked;
$data['contentLocked'] = $contentLocked;
$data['viewMode'] = $isFreeView ? 'free' : 'paid';
$data['payViewPrice'] = $isFreeView ? 0 : $payViewPrice;
$data['isMember'] = $isMember;
// 会员每日浏览额度(免费公开模式不展示、不计数)
$data['viewQuotaTotal'] = $viewState ? $viewState['total'] : 0;
$data['viewQuotaUsed'] = $viewState ? $viewState['used'] : 0;
$data['viewQuotaLeft'] = $viewState ? $viewState['left'] : 0;
$data['viewQuotaUnlimited'] = $viewState ? $viewState['unlimited'] : false;
$data['hasPhone'] = (string)$post['phone'] !== '';
// 任何模式均不返回手机号(明文与脱敏串都不给),界面只保留拨打按钮,
// 由 POST /post/:id/dial 校验拨打额度后调起系统拨号
$data['phone'] = '';
$data['contact'] = (string)(isset($post['contact']) ? $post['contact'] : '');
$data['contactName'] = (string)(isset($post['contact']) ? $post['contact'] : '');
$data['callQuotaTotal'] = $callState['total'];
$data['callQuotaUsed'] = $callState['used'];
$data['callQuotaLeft'] = $callState['left'];
$data['canDial'] = $isOwner || $paid || $callState['unlimited'] || $callState['left'] > 0;
return $data;
}
/**
* 构造免责声明拨打弹窗展示文案(如:夏178****8426)
* 计算会员今日的完整信息浏览额度状态(真源:fc_plan.view_quota;0 代表不限)
* 是否今日已浏览过某条 → hasViewedToday 单独判断
*
* @param string $contactName 联系人姓名
* @param string $phone 手机号
* @param int $userId 用户ID
* @param array $ext fc_user_ext 行
* @return array{total:int,used:int,left:int,unlimited:bool}
*/
protected function viewQuotaState($userId, $ext = null)
{
$benefit = \app\common\library\FcConfig::resolveMemberBenefit($ext);
$total = isset($benefit['viewQuota']) ? max(0, (int)$benefit['viewQuota']) : 20;
$unlimited = ($total === 0);
$today = date('Y-m-d');
$used = (int)Db::name('fc_view_log')
->where('user_id', (int)$userId)
->where('view_date', $today)
->count();
return [
'total' => $total,
'used' => $used,
'left' => $unlimited ? 999 : max(0, $total - $used),
'unlimited' => $unlimited,
];
}
/**
* 记录一条完整信息浏览日志(同一条当日幂等,重复浏览不产生新记录)
*
* @param int $userId 用户ID
* @param int $postId 信息ID
* @return bool 是否成功写入新记录
*/
protected function recordViewLog($userId, $postId)
{
$today = date('Y-m-d');
$exist = Db::name('fc_view_log')
->where('user_id', (int)$userId)
->where('post_id', (int)$postId)
->where('view_date', $today)
->find();
if ($exist) {
return false;
}
Db::name('fc_view_log')->insert([
'user_id' => (int)$userId,
'post_id' => (int)$postId,
'view_date' => $today,
'createtime' => time(),
]);
return true;
}
/**
* 判断用户今日是否已浏览过指定信息
*
* @param int $userId 用户ID
* @param int $postId 信息ID
* @return bool
*/
protected function hasViewedToday($userId, $postId)
{
return (bool)Db::name('fc_view_log')
->where('user_id', (int)$userId)
->where('post_id', (int)$postId)
->where('view_date', date('Y-m-d'))
->find();
}
/**
* 截取正文摘要(锁定态展示,保留首行主信息)
*
* @param string $content 正文
* @param int $length 摘要长度(字符)
* @return string
*/
protected function buildDialDisplay($contactName, $phone)
protected function contentPreview($content, $length = 100)
{
$masked = $this->maskPhone($phone);
$name = trim((string)$contactName);
if ($name === '') {
return $masked;
$text = trim((string)$content);
if ($text === '' || mb_strlen($text, 'UTF-8') <= $length) {
return $text;
}
$surname = mb_substr($name, 0, 1, 'UTF-8');
return $surname . $masked;
return mb_substr($text, 0, $length, 'UTF-8') . '…';
}
/**
* 计算指定用户今日的电话拨打额度状态
*
* 会员:每日拨打次数真源 = 所属 fc_plan 套餐 call_quota(0 代表不限)
* 非会员:全局配置 call.normalDailyQuota(0 代表不限)
* @param int $userId 用户ID(0表示游客)
* @param bool $isMember 是否为有效期内VIP会员
* @return array{total:int,used:int,left:int,unlimited:bool}
*/
protected function callQuotaState($userId, $isMember)
{
$normalQuota = max(0, (int)$this->cfg('call.normalDailyQuota', 5));
$vipQuota = max(0, (int)$this->cfg('call.vipDailyQuota', 30));
$total = $isMember ? $vipQuota : $normalQuota;
if ($isMember) {
$benefit = \app\common\library\FcConfig::resolveMemberBenefit();
$total = isset($benefit['callQuota']) ? max(0, (int)$benefit['callQuota']) : 30;
} else {
$total = max(0, (int)$this->cfg('call.normalDailyQuota', 5));
}
$unlimited = ($total === 0);
$used = 0;
@@ -1091,7 +1165,7 @@ class Post extends V1
/**
* P6-B 信息详情页申请拨打电话(校验每日拨打次数上限并记录拨打日志)
* POST /api/v1/post/:id/dial
* → {phoneNumber, dialDisplay, callQuotaTotal, callQuotaUsed, callQuotaLeft}
* → {phoneNumber, callQuotaTotal, callQuotaUsed, callQuotaLeft}
*
* @return void
*/
@@ -1125,8 +1199,8 @@ class Post extends V1
// 非本人且未单条付费解锁时,校验每日拨打次数上限
if (!$isOwner && !$paid && !$state['unlimited'] && $state['left'] <= 0) {
$msg = $isMember
? ('您今日的 VIP 拨打次数已达上限(' . $state['total'] . '次/日)')
: ('您今日的免费拨打次数已达上限(' . $state['total'] . '次/日),开通 VIP 会员可享每日更多拨打次数');
? ('您今日的拨打次数已达上限(' . $state['total'] . '次/日),明日再来或升级更高套餐')
: ('您今日的免费拨打次数已达上限(' . $state['total'] . '次/日),开通会员可享更多拨打次数');
$this->fail($msg, 403);
}
@@ -1145,7 +1219,6 @@ class Post extends V1
$this->ok([
'phoneNumber' => $phone,
'dialDisplay' => $this->buildDialDisplay(isset($post['contact']) ? $post['contact'] : '', $phone),
'callQuotaTotal' => $state['total'],
'callQuotaUsed' => $newUsed,
'callQuotaLeft' => $newLeft,
@@ -1153,56 +1226,11 @@ class Post extends V1
}
/**
* 会员每日免费查看条数(从用户所属 fc_plan 套餐或默认套餐读取;0 代表会员无限次免费看)
*
* @param array|null $ext fc_user_ext 行
* @return int
*/
protected function memberFreeViewQuota($ext = null)
{
$benefit = \app\common\library\FcConfig::resolveMemberBenefit($ext);
return isset($benefit['freeView']) ? max(0, (int)$benefit['freeView']) : 20;
}
/**
* 消耗一次会员免费查看额度(跨天自动重置;quota=0 代表会员不限次数无限看;需在事务内调用)
*
* @param int $userId
* @param int $quota
* @return bool 是否成功占用
*/
protected function consumeFreeView($userId, $quota)
{
$today = date('Y-m-d');
$ext = Db::name('fc_user_ext')->where('user_id', (int)$userId)->lock(true)->find();
if (!$ext) {
return false;
}
if ((string)$ext['free_view_date'] !== $today) {
Db::name('fc_user_ext')->where('user_id', (int)$userId)->update([
'free_view_date' => $today,
'free_view_used' => 1,
'updatetime' => time(),
]);
return true;
}
if ($quota > 0 && (int)$ext['free_view_used'] >= $quota) {
return false;
}
Db::name('fc_user_ext')->where('user_id', (int)$userId)->setInc('free_view_used', 1);
return true;
}
/**
* P6 付费查看联系方式
* P6 付费解锁完整信息(单条永久解锁)
* POST /api/v1/post/:id/pay-view {payType}
* → {unlocked:true,contact:{phone,wechat}}(免费公开/余额/会员免费:立即解锁)
* → {order:{orderNo,amount,payType,status:'pending'}}(微信支付:前端再调 POST /pay/prepay 调起收银台)
* 规则 BR-05;金额取 fee.payView;全站免费模式、会员额度内或已解锁免费
* → {unlocked:true}(余额:立即解锁)
* → {order:{orderNo,amount,payType,status:'pending'}}(微信支付:前端再调 POST /pay/prepay 调起收银台,回调写解锁记录)
* 适用:付费模式下非会员,或会员每日浏览额度用尽后的单条解锁;免费公开模式无需解锁
*/
public function payView()
{
@@ -1210,10 +1238,7 @@ class Post extends V1
$id = $this->routeId();
$payType = (string)$this->input('payType', '');
if ($payType === '') {
$payType = 'free';
}
if (!in_array($payType, ['wxpay', 'balance', 'free'], true)) {
if (!in_array($payType, ['wxpay', 'balance'], true)) {
$this->fail('支付方式不支持');
}
@@ -1222,128 +1247,94 @@ class Post extends V1
$this->fail('信息不存在', 404);
}
$phone = (string)$post['phone'];
$wechat = $post['wechat'] !== '' ? (string)$post['wechat'] : ('tongcheng_' . $id);
$contactName = (string)(isset($post['contact']) ? $post['contact'] : '');
$contact = [
'name' => $contactName,
'phone' => $phone,
'wechat' => $wechat,
];
$amount = max(0, round((float)$this->cfg('fee.payView', 2), 2));
$isFreeView = $this->isFreeViewMode();
$now = time();
if ($isFreeView) {
$this->ok(['unlocked' => true, 'freeMode' => true]);
}
$ext = $this->ext($user['id']);
$isMember = (int)$ext['is_member'] === 1
&& !empty($ext['member_expiretime']) && (int)$ext['member_expiretime'] > $now;
$quota = $this->memberFreeViewQuota($ext);
$freeViewUnlimited = ($quota === 0);
$isOwner = (int)$post['user_id'] === (int)$user['id'];
if ($isOwner) {
$this->ok(['unlocked' => true, 'freeMode' => true]);
}
// 已解锁直接返回(严格返回纯净扁平字段,杜绝 JSON 嵌套导致前端格式错乱)
// 已解锁直接返回
$exist = Db::name('fc_pay_view')
->where('user_id', $user['id'])
->where('post_id', $id)
->find();
if ($exist) {
$today = date('Y-m-d');
$usedToday = ((string)$ext['free_view_date'] === $today) ? (int)$ext['free_view_used'] : 0;
$this->ok([
'unlocked' => true,
'phone' => $phone,
'contact' => $contact,
'contactName' => $contactName,
'wechat' => $wechat,
'contactInfo' => $contact,
'freeViewUnlimited' => $freeViewUnlimited,
'freeViewLeft' => $isMember ? ($freeViewUnlimited ? 999 : max(0, $quota - $usedToday)) : 0,
]);
$this->ok(['unlocked' => true]);
}
$amount = max(0, round((float)$this->cfg('fee.payView', 2), 2));
$now = time();
$orderId = 0;
$pending = null;
// 后台开启支付密码时,余额支付需校验(全站免费或会员免费额度未用完时走免费,不要求密码)
if (!$isFreeView && $payType === 'balance' && !$isMember) {
// 后台开启支付密码时,余额支付需校验
if ($payType === 'balance') {
$this->verifyPayPassword($user);
}
try {
Db::transaction(function () use (&$orderId, &$pending, $isFreeView, $isMember, $quota, $payType, $amount, $user, $id, $now) {
if ($isFreeView) {
// 全站免费浏览模式(或解锁单价设为 0 元):直接免单解锁,避免走 0 元支付死锁
$amount = 0;
$payType = 'free';
} else {
// 会员每日免费查看额度(quota=0 代表会员不限次数;当天用完后按正常付费)
$usedFree = $isMember ? $this->consumeFreeView((int)$user['id'], $quota) : false;
if ($usedFree) {
$amount = 0;
$payType = 'free';
} elseif ($payType === 'free') {
// 用户希望使用会员免费特权,但额度已耗尽或非会员
throw new \RuntimeException($isMember ? '今日会员免费查看额度已用完,请选择支付方式付费查看' : '该内容需付费查看,请选择支付方式');
} elseif ($payType === 'balance') {
// 条件扣款:并发下不会扣成负数
$affected = Db::name('user')
->where('id', (int)$user['id'])
->where('money', '>=', $amount)
->setDec('money', $amount);
if (!$affected) {
throw new \RuntimeException('余额不足,请充值或使用微信支付');
}
$balance = (float)Db::name('user')->where('id', (int)$user['id'])->value('money');
// 余额支付为「即时支付」:同步落一笔已支付订单,保证「我的订单」与微信支付口径一致
$orderNo = $this->orderNo('VO');
$orderId = Db::name('fc_order')->insertGetId([
'order_no' => $orderNo,
'user_id' => $user['id'],
'type' => 'payview',
'title' => '付费查看 #' . $id,
'amount' => $amount,
'pay_type' => 'balance',
'status' => 'paid',
'paytime' => $now,
'related_id' => $id,
'createtime' => $now,
'updatetime' => $now,
]);
$this->flow('expense', '付费查看', $amount, $balance, $id, '', (int)$user['id']);
// 钱包流水(fa_user.money 减)→ 余额中心「余额明细」
$this->walletFlow($user['id'], 'expense', '付费查看', $amount, $balance, $id, '解锁信息 #' . $id);
// 余额支付同样触发分销结算(与微信回调 OrderFulfill::handle 口径一致)
$orderRow = Db::name('fc_order')->where('id', $orderId)->find();
if ($orderRow) {
DistributionService::settleOrder($orderRow);
}
} else {
// 微信支付:只落 pending 订单(不预写解锁记录),
// 支付成功后由 /pay/notify 按 type=payview + related_id 解锁(回调可独立完成)
$orderNo = $this->orderNo('VO');
Db::name('fc_order')->insert([
'order_no' => $orderNo,
'user_id' => $user['id'],
'type' => 'payview',
'title' => '付费查看 #' . $id,
'amount' => $amount,
'pay_type' => 'wxpay',
'status' => 'pending',
'paytime' => null,
'related_id' => $id,
'createtime' => $now,
'updatetime' => $now,
]);
$pending = [
'orderNo' => $orderNo,
'amount' => $amount,
'payType' => 'wxpay',
'status' => 'pending',
];
return;
Db::transaction(function () use (&$orderId, &$pending, $payType, $amount, $user, $id, $now) {
if ($payType === 'balance') {
// 条件扣款:并发下不会扣成负数
$affected = Db::name('user')
->where('id', (int)$user['id'])
->where('money', '>=', $amount)
->setDec('money', $amount);
if (!$affected) {
throw new \RuntimeException('余额不足,请充值或使用微信支付');
}
$balance = (float)Db::name('user')->where('id', (int)$user['id'])->value('money');
// 余额支付为「即时支付」:同步落一笔已支付订单,保证「我的订单」与微信支付口径一致
$orderNo = $this->orderNo('VO');
$orderId = Db::name('fc_order')->insertGetId([
'order_no' => $orderNo,
'user_id' => $user['id'],
'type' => 'payview',
'title' => '解锁信息 #' . $id,
'amount' => $amount,
'pay_type' => 'balance',
'status' => 'paid',
'paytime' => $now,
'related_id' => $id,
'createtime' => $now,
'updatetime' => $now,
]);
$this->flow('expense', '解锁信息', $amount, $balance, $id, '', (int)$user['id']);
// 钱包流水(fa_user.money 减)→ 余额中心「余额明细」
$this->walletFlow($user['id'], 'expense', '解锁信息', $amount, $balance, $id, '解锁信息 #' . $id);
// 余额支付同样触发分销结算(与微信回调 OrderFulfill::handle 口径一致)
$orderRow = Db::name('fc_order')->where('id', $orderId)->find();
if ($orderRow) {
DistributionService::settleOrder($orderRow);
}
} else {
// 微信支付:只落 pending 订单(不预写解锁记录),
// 支付成功后由 /pay/notify 按 type=payview + related_id 解锁(回调可独立完成)
$orderNo = $this->orderNo('VO');
Db::name('fc_order')->insert([
'order_no' => $orderNo,
'user_id' => $user['id'],
'type' => 'payview',
'title' => '解锁信息 #' . $id,
'amount' => $amount,
'pay_type' => 'wxpay',
'status' => 'pending',
'paytime' => null,
'related_id' => $id,
'createtime' => $now,
'updatetime' => $now,
]);
$pending = [
'orderNo' => $orderNo,
'amount' => $amount,
'payType' => 'wxpay',
'status' => 'pending',
];
return;
}
Db::name('fc_pay_view')->insert([
@@ -1375,20 +1366,8 @@ class Post extends V1
}
}
$today = date('Y-m-d');
$extNow = $this->ext($user['id']);
$usedNow = ((string)$extNow['free_view_date'] === $today) ? (int)$extNow['free_view_used'] : 0;
$this->ok([
'unlocked' => true,
'phone' => $phone,
'contact' => $contact,
'contactName' => $contactName,
'wechat' => $wechat,
'contactInfo' => $contact,
'freeViewUnlimited' => $freeViewUnlimited,
'freeViewLeft' => $isMember ? ($freeViewUnlimited ? 999 : max(0, $quota - $usedNow)) : 0,
'usedFree' => isset($usedFree) ? $usedFree : false,
'unlocked' => true,
]);
}