1
0
mirror of https://gitee.com/koogua/course-tencent-cloud.git synced 2025-06-27 21:10:24 +08:00

后台增加查看状态流转记录

This commit is contained in:
xiaochong0302 2020-07-27 21:00:25 +08:00
parent 7f2d3b793e
commit 29cc05a4f9
63 changed files with 588 additions and 198 deletions

View File

@ -3,6 +3,7 @@
namespace App\Builders;
use App\Repos\ImGroup as ImGroupRepo;
use App\Repos\User as UserRepo;
class ImGroupUserList extends Builder
{
@ -24,20 +25,43 @@ class ImGroupUserList extends Builder
$groupRepo = new ImGroupRepo();
$columns = ['id', 'type', 'name', 'avatar', 'about', 'user_count'];
$columns = ['id', 'type', 'name', 'avatar', 'about', 'owner_id', 'user_count'];
$groups = $groupRepo->findByIds($ids, $columns);
$users = $this->getGroupOwners($groups->toArray());
$baseUrl = kg_ci_base_url();
$result = [];
foreach ($groups->toArray() as $group) {
$group['group'] = $baseUrl . $group['avatar'];
$group['avatar'] = $baseUrl . $group['avatar'];
$group['owner'] = $users[$group['owner_id']] ?? new \stdClass();
unset($group['owner_id']);
$result[$group['id']] = $group;
}
return $result;
}
protected function getGroupOwners(array $groups)
{
$ids = kg_array_column($groups, 'owner_id');
$userRepo = new UserRepo();
$users = $userRepo->findByIds($ids, ['id', 'name']);
$result = [];
if ($users->count() > 0) {
foreach ($users->toArray() as $user) {
$result[$user['id']] = $user;
}
}
return $result;
}
}

View File

@ -62,7 +62,8 @@ class NavTreeList extends Builder
{
return NavModel::query()
->where('parent_id = :parent_id:', ['parent_id' => $navId])
->andWhere('deleted = 0')
->andWhere('published = 1')
->orderBy('priority ASC')
->execute();
}
@ -74,7 +75,8 @@ class NavTreeList extends Builder
{
return NavModel::query()
->where('position = :position:', ['position' => $position])
->andWhere('level = 1 AND deleted = 0')
->andWhere('level = 1 AND published = 1')
->orderBy('priority ASC')
->execute();
}

View File

@ -24,7 +24,7 @@ class OrderList extends Builder
$users = $this->getUsers($orders);
foreach ($orders as $key => $order) {
$orders[$key]['user'] = $users[$order['user_id']] ?? new \stdClass();
$orders[$key]['owner'] = $users[$order['owner_id']] ?? new \stdClass();
}
return $orders;
@ -130,7 +130,7 @@ class OrderList extends Builder
*/
protected function getUsers(array $orders)
{
$ids = kg_array_column($orders, 'user_id');
$ids = kg_array_column($orders, 'owner_id');
$userRepo = new UserRepo();

View File

@ -24,7 +24,7 @@ class RefundList extends Builder
$users = $this->getUsers($refunds);
foreach ($refunds as $key => $refund) {
$refunds[$key]['user'] = $users[$refund['user_id']] ?? new \stdClass();
$refunds[$key]['owner'] = $users[$refund['owner_id']] ?? new \stdClass();
}
return $refunds;
@ -49,7 +49,7 @@ class RefundList extends Builder
public function getUsers(array $refunds)
{
$ids = kg_array_column($refunds, 'user_id');
$ids = kg_array_column($refunds, 'owner_id');
$userRepo = new UserRepo();

View File

@ -24,7 +24,7 @@ class TradeList extends Builder
$users = $this->getUsers($trades);
foreach ($trades as $key => $trade) {
$trades[$key]['user'] = $users[$trade['user_id']] ?? new \stdClass();
$trades[$key]['owner'] = $users[$trade['owner_id']] ?? new \stdClass();
}
return $trades;
@ -49,7 +49,7 @@ class TradeList extends Builder
public function getUsers($trades)
{
$ids = kg_array_column($trades, 'user_id');
$ids = kg_array_column($trades, 'owner_id');
$userRepo = new UserRepo();

View File

@ -40,8 +40,8 @@ class OrderController extends Controller
$order = $orderService->getOrder($id);
$trades = $orderService->getTrades($order->id);
$refunds = $orderService->getRefunds($order->id);
$account = $orderService->getAccount($order->user_id);
$user = $orderService->getUser($order->user_id);
$account = $orderService->getAccount($order->owner_id);
$user = $orderService->getUser($order->owner_id);
$this->view->setVar('order', $order);
$this->view->setVar('trades', $trades);
@ -51,43 +51,15 @@ class OrderController extends Controller
}
/**
* @Post("/{id:[0-9]+}/close", name="admin.order.close")
* @Get("/{id:[0-9]+}/statuses", name="admin.order.statuses")
*/
public function closeAction($id)
public function statusesAction($id)
{
$orderService = new OrderService();
$orderService->closeOrder($id);
$statuses = $orderService->getStatusHistory($id);
$location = $this->request->getHTTPReferer();
$content = [
'location' => $location,
'msg' => '关闭订单成功',
];
return $this->jsonSuccess($content);
}
/**
* @Post("/refund", name="admin.order.refund")
*/
public function refundAction()
{
$tradeId = $this->request->getPost('trade_id', 'int');
$orderService = new OrderService;
$orderService->refundTrade($tradeId);
$location = $this->request->getHTTPReferer();
$content = [
'location' => $location,
'msg' => '订单退款成功',
];
return $this->jsonSuccess($content);
$this->view->setVar('statuses', $statuses);
}
}

View File

@ -40,8 +40,8 @@ class RefundController extends Controller
$refund = $refundService->getRefund($id);
$order = $refundService->getOrder($refund->order_id);
$trade = $refundService->getTrade($refund->trade_id);
$account = $refundService->getAccount($trade->user_id);
$user = $refundService->getUser($trade->user_id);
$account = $refundService->getAccount($trade->owner_id);
$user = $refundService->getUser($trade->owner_id);
$this->view->setVar('refund', $refund);
$this->view->setVar('order', $order);
@ -50,6 +50,18 @@ class RefundController extends Controller
$this->view->setVar('user', $user);
}
/**
* @Get("/{id:[0-9]+}/statuses", name="admin.refund.statuses")
*/
public function statusesAction($id)
{
$refundService = new RefundService();
$statuses = $refundService->getStatusHistory($id);
$this->view->setVar('statuses', $statuses);
}
/**
* @Post("/{id:[0-9]+}/review", name="admin.refund.review")
*/

View File

@ -40,8 +40,8 @@ class TradeController extends Controller
$trade = $tradeService->getTrade($id);
$refunds = $tradeService->getRefunds($trade->id);
$order = $tradeService->getOrder($trade->order_id);
$account = $tradeService->getAccount($trade->user_id);
$user = $tradeService->getUser($trade->user_id);
$account = $tradeService->getAccount($trade->owner_id);
$user = $tradeService->getUser($trade->owner_id);
$this->view->setVar('refunds', $refunds);
$this->view->setVar('trade', $trade);
@ -51,22 +51,15 @@ class TradeController extends Controller
}
/**
* @Post("/{id:[0-9]+}/close", name="admin.trade.close")
* @Get("/{id:[0-9]+}/statuses", name="admin.trade.statuses")
*/
public function closeAction($id)
public function statusesAction($id)
{
$tradeService = new TradeService();
$tradeService->closeTrade($id);
$statuses = $tradeService->getStatusHistory($id);
$location = $this->request->getHTTPReferer();
$content = [
'location' => $location,
'msg' => '关闭交易成功',
];
return $this->jsonSuccess($content);
$this->view->setVar('statuses', $statuses);
}
/**

View File

@ -64,6 +64,13 @@ class Order extends Service
return $this->findOrFail($id);
}
public function getStatusHistory($id)
{
$orderRepo = new OrderRepo();
return $orderRepo->findStatusHistory($id);
}
protected function findOrFail($id)
{
$validator = new OrderValidator();

View File

@ -32,7 +32,7 @@ abstract class PayTest extends Service
$order->subject = '测试 - 支付测试0.01元';
$order->amount = 0.01;
$order->user_id = $authUser['id'];
$order->owner_id = $authUser['id'];
$order->item_type = OrderModel::ITEM_TEST;
$order->create();
@ -50,7 +50,7 @@ abstract class PayTest extends Service
{
$trade = new TradeModel();
$trade->user_id = $order->user_id;
$trade->owner_id = $order->owner_id;
$trade->order_id = $order->id;
$trade->subject = $order->subject;
$trade->amount = $order->amount;

View File

@ -47,6 +47,13 @@ class Refund extends Service
return $this->findOrFail($id);
}
public function getStatusHistory($id)
{
$refundRepo = new RefundRepo();
return $refundRepo->findStatusHistory($id);
}
public function getTrade($tradeId)
{
$tradeRepo = new TradeRepo();

View File

@ -47,6 +47,13 @@ class Trade extends Service
return $tradeRepo->findById($id);
}
public function getStatusHistory($id)
{
$tradeRepo = new TradeRepo();
return $tradeRepo->findStatusHistory($id);
}
public function getOrder($orderId)
{
$orderRepo = new OrderRepo();
@ -87,7 +94,7 @@ class Trade extends Service
$refund->subject = $trade->subject;
$refund->amount = $trade->amount;
$refund->user_id = $trade->user_id;
$refund->owner_id = $trade->owner_id;
$refund->order_id = $trade->order_id;
$refund->trade_id = $trade->id;
$refund->apply_note = '后台人工申请退款';

View File

@ -1,3 +1,11 @@
{%- macro type_info(value) %}
{% if value == 'course' %}
<span class="layui-badge layui-bg-green">课</span>
{% elseif value == 'chat' %}
<span class="layui-badge layui-bg-blue">聊</span>
{% endif %}
{%- endmacro %}
{%- macro owner_info(owner) %}
{% if owner %}
{{ owner.name }}{{ owner.id }}
@ -42,7 +50,7 @@
{% for item in pager.items %}
<tr>
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ item.name }} {{ type_info(item.type) }}</td>
<td>{{ owner_info(item.owner) }}</td>
<td><span class="layui-badge layui-bg-gray">{{ item.user_count }}</span></td>
<td><input type="checkbox" name="published" value="1" lay-filter="published" lay-skin="switch" lay-text="是|否" data-url="{{ url({'for':'admin.group.update','id':item.id}) }}" {% if item.published == 1 %}checked{% endif %}></td>

View File

@ -40,8 +40,8 @@
<p>单号:{{ item.sn }}</p>
</td>
<td>
<p>昵称:{{ item.user.name }}</p>
<p>编号:{{ item.user.id }}</p>
<p>昵称:{{ item.owner.name }}</p>
<p>编号:{{ item.owner.id }}</p>
</td>
<td>{{ '¥%0.2f'|format(item.amount) }}</td>
<td>{{ order_status(item.status) }}</td>

View File

@ -1,3 +1,5 @@
{% set order_status_url = url({'for':'admin.order.statuses','id':order.id}) %}
<fieldset class="layui-elem-field layui-field-title">
<legend>订单信息</legend>
</fieldset>
@ -11,6 +13,7 @@
<td>订单金额</td>
<td>订单类型</td>
<td>订单状态</td>
<td>历史状态</td>
<td>创建时间</td>
</tr>
<tr>
@ -18,6 +21,24 @@
<td>{{ '¥%0.2f'|format(order.amount) }}</td>
<td>{{ item_type(order.item_type) }}</td>
<td>{{ order_status(order.status) }}</td>
<td>
<button class="layui-btn layui-btn-xs layui-bg-green order-status" data-url="{{ order_status_url }}">详情</button>
</td>
<td>{{ date('Y-m-d H:i:s',order.create_time) }}</td>
</tr>
</table>
<script>
layui.use(['jquery', 'layer'], function () {
var $ = layui.jquery;
var layer = layui.layer;
$('.order-status').on('click', function () {
layer.open({
type: 2,
title: '历史状态',
content: $(this).data('url'),
area: ['640px', '320px']
});
});
});
</script>

View File

@ -7,7 +7,7 @@
<div class="layui-form-item">
<label class="layui-form-label">用户编号</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="user_id" placeholder="用户编号精确匹配">
<input class="layui-input" type="text" name="owner_id" placeholder="用户编号精确匹配">
</div>
</div>

View File

@ -27,8 +27,8 @@
<tr>
<td>{{ item.sn }}</td>
<td>{{ '¥%0.2f'|format(item.amount) }}</td>
<td><a href="#" title="{{ item.apply_note }}">{{ substr(item.apply_note,0,15) }}</td>
<td>{{ refund_status(item) }}</td>
<td><a href="javascript:" title="{{ item.apply_note }}">{{ substr(item.apply_note,0,15) }}</td>
<td>{{ refund_status(item.status) }}</td>
<td>{{ date('Y-m-d H:i:s',item.create_time) }}</td>
<td><a class="layui-btn layui-btn-sm" href="{{ url({'for':'admin.refund.show','id':item.id}) }}">详情</a></td>
</tr>

View File

@ -0,0 +1,14 @@
{{ partial('order/macro') }}
<table class="kg-table layui-table">
<tr>
<td>状态</td>
<td>时间</td>
</tr>
{% for item in statuses %}
<tr>
<td>{{ order_status(item.status) }}</td>
<td>{{ date('Y-m-d H:i:s',item.create_time) }}</td>
</tr>
{% endfor %}
</table>

View File

@ -40,8 +40,8 @@
<p>单号:{{ item.order.sn }}</p>
</td>
<td>
<p>昵称:{{ item.user.name }}</p>
<p>编号:{{ item.user.id }}</p>
<p>昵称:{{ item.owner.name }}</p>
<p>编号:{{ item.owner.id }}</p>
</td>
<td>{{ '¥%0.2f'|format(item.amount) }}</td>
<td>{{ refund_status(item.status) }}</td>

View File

@ -13,3 +13,21 @@
<span class="layui-badge layui-bg-cyan">已失败</span>
{% endif %}
{%- endmacro %}
{%- macro refund_status_history(items) %}
{% for item in items %}
{% if item.status == 'pending' %}
<p>创建时间:{{ date('Y-m-d H:i:s',item.create_time) }}</p>
{% elseif item.status == 'canceled' %}
<p>取消时间:{{ date('Y-m-d H:i:s',item.create_time) }}</p>
{% elseif item.status == 'approved' %}
<p>过审时间:{{ date('Y-m-d H:i:s',item.create_time) }}</p>
{% elseif item.status == 'refused' %}
<p>拒绝时间:{{ date('Y-m-d H:i:s',item.create_time) }}</p>
{% elseif item.status == 'finished' %}
<p>完成时间:{{ date('Y-m-d H:i:s',item.create_time) }}</p>
{% elseif item.status == 'failed' %}
<p>失败时间:{{ date('Y-m-d H:i:s',item.create_time) }}</p>
{% endif %}
{% endfor %}
{%- endmacro %}

View File

@ -14,7 +14,7 @@
<div class="layui-form-item">
<label class="layui-form-label">用户编号</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="user_id" placeholder="用户编号精确匹配">
<input class="layui-input" type="text" name="owner_id" placeholder="用户编号精确匹配">
</div>
</div>

View File

@ -2,6 +2,8 @@
{{ partial('trade/macro') }}
{{ partial('refund/macro') }}
{% set refund_status_url = url({'for':'admin.refund.statuses','id':refund.id}) %}
<fieldset class="layui-elem-field layui-field-title">
<legend>退款信息</legend>
</fieldset>
@ -12,6 +14,7 @@
<th>退款金额</th>
<th>退款备注</th>
<th>退款状态</th>
<th>历史状态</th>
<th>创建时间</th>
</tr>
<tr>
@ -26,6 +29,9 @@
{% endif %}
</td>
<td>{{ refund_status(refund.status) }}</td>
<td>
<button class="layui-btn layui-btn-xs layui-bg-green refund-status" data-url="{{ refund_status_url }}">详情</button>
</td>
<td>{{ date('Y-m-d H:i:s',refund.create_time) }}</td>
</tr>
</table>
@ -75,3 +81,18 @@
<br>
{{ partial('order/user_info') }}
<script>
layui.use(['jquery', 'layer'], function () {
var $ = layui.jquery;
var layer = layui.layer;
$('.refund-status').on('click', function () {
layer.open({
type: 2,
title: '历史状态',
content: $(this).data('url'),
area: ['640px', '320px']
});
});
});
</script>

View File

@ -0,0 +1,14 @@
{{ partial('refund/macro') }}
<table class="kg-table layui-table">
<tr>
<td>状态</td>
<td>时间</td>
</tr>
{% for item in statuses %}
<tr>
<td>{{ refund_status(item.status) }}</td>
<td>{{ date('Y-m-d H:i:s',item.create_time) }}</td>
</tr>
{% endfor %}
</table>

View File

@ -46,7 +46,7 @@
clearInterval(interval);
}
},
error: function (xhr) {
error: function () {
$('#error-tips').removeClass('layui-hide');
$('#qrcode').addClass('layui-hide');
clearInterval(interval);

View File

@ -46,7 +46,7 @@
clearInterval(interval);
}
},
error: function (xhr) {
error: function () {
$('#error-tips').removeClass('layui-hide');
$('#qrcode').addClass('layui-hide');
clearInterval(interval);

View File

@ -42,8 +42,8 @@
<p>单号:{{ item.order.sn }}</p>
</td>
<td>
<p>昵称:{{ item.user.name }}</p>
<p>编号:{{ item.user.id }}</p>
<p>昵称:{{ item.owner.name }}</p>
<p>编号:{{ item.owner.id }}</p>
</td>
<td>{{ '¥%0.2f'|format(item.amount) }}</td>
<td>{{ channel_type(item.channel) }}</td>

View File

@ -1,3 +1,11 @@
{%- macro channel_type(value) %}
{% if value == 'alipay' %}
<span class="layui-badge layui-bg-blue">支付宝</span>
{% elseif value == 'wxpay' %}
<span class="layui-badge layui-bg-green">微信</span>
{% endif %}
{%- endmacro %}
{%- macro trade_status(value) %}
{% if value == 'pending' %}
<span class="layui-badge layui-bg-blue">待支付</span>
@ -10,10 +18,16 @@
{% endif %}
{%- endmacro %}
{%- macro channel_type(value) %}
{% if value == 'alipay' %}
<span class="layui-badge layui-bg-blue">支付宝</span>
{% elseif value == 'wxpay' %}
<span class="layui-badge layui-bg-green">微信</span>
{%- macro trade_status_history(items) %}
{% for item in items %}
{% if item.status == 'pending' %}
<p>创建时间:{{ date('Y-m-d H:i:s',item.create_time) }}</p>
{% elseif item.status == 'finished' %}
<p>完成时间:{{ date('Y-m-d H:i:s',item.create_time) }}</p>
{% elseif item.status == 'closed' %}
<p>关闭时间:{{ date('Y-m-d H:i:s',item.create_time) }}</p>
{% elseif item.status == 'refunded' %}
<p>退款时间:{{ date('Y-m-d H:i:s',item.create_time) }}</p>
{% endif %}
{% endfor %}
{%- endmacro %}

View File

@ -14,7 +14,7 @@
<div class="layui-form-item">
<label class="layui-form-label">用户编号</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="user_id" placeholder="用户编号精确匹配">
<input class="layui-input" type="text" name="owner_id" placeholder="用户编号精确匹配">
</div>
</div>

View File

@ -30,7 +30,7 @@
<tr>
<td>{{ item.sn }}</td>
<td>{{ '¥%0.2f'|format(item.amount) }}</td>
<td><a href="#" title="{{ item.apply_note }}">{{ substr(item.apply_note,0,15) }}</td>
<td><a href="javascript:" title="{{ item.apply_note }}">{{ substr(item.apply_note,0,15) }}</td>
<td>{{ refund_status(item) }}</td>
<td>{{ date('Y-m-d H:i:s',item.create_time) }}</td>
<td><a class="layui-btn layui-btn-sm" href="{{ url({'for':'admin.refund.show','id':item.id}) }}">详情</a></td>

View File

@ -0,0 +1,14 @@
{{ partial('trade/macro') }}
<table class="kg-table layui-table">
<tr>
<td>状态</td>
<td>时间</td>
</tr>
{% for item in statuses %}
<tr>
<td>{{ trade_status(item.status) }}</td>
<td>{{ date('Y-m-d H:i:s',item.create_time) }}</td>
</tr>
{% endfor %}
</table>

View File

@ -1,3 +1,5 @@
{% set trade_status_url = url({'for':'admin.trade.statuses','id':trade.id}) %}
<fieldset class="layui-elem-field layui-field-title">
<legend>交易信息</legend>
</fieldset>
@ -8,6 +10,7 @@
<th>交易金额</th>
<th>交易平台</th>
<th>交易状态</th>
<th>历史状态</th>
<th>创建时间</th>
</tr>
<tr>
@ -15,6 +18,24 @@
<td>{{ '¥%0.2f'|format(trade.amount) }}</td>
<td>{{ channel_type(trade.channel) }}</td>
<td>{{ trade_status(trade.status) }}</td>
<td>
<button class="layui-btn layui-btn-xs layui-bg-green trade-status" data-url="{{ trade_status_url }}">详情</button>
</td>
<td>{{ date('Y-m-d H:i:s',trade.create_time) }}</td>
</tr>
</table>
<script>
layui.use(['jquery', 'layer'], function () {
var $ = layui.jquery;
var layer = layui.layer;
$('.trade-status').on('click', function () {
layer.open({
type: 2,
title: '历史状态',
content: $(this).data('url'),
area: ['640px', '320px']
});
});
});
</script>

View File

@ -337,4 +337,32 @@ class ImController extends LayerController
return $this->jsonSuccess();
}
/**
* @Post("/friend/{id:[0-9]+}/quit", name="web.im.quit_friend")
*/
public function quitFriendAction($id)
{
$service = new ImService();
$service->quitFriend($id);
$content = ['msg' => '解除好友成功'];
return $this->jsonSuccess($content);
}
/**
* @Post("/group/{id:[0-9]+}/quit", name="web.im.quit_group")
*/
public function quitGroupAction($id)
{
$service = new ImService();
$service->quitGroup($id);
$content = ['msg' => '退出群组成功'];
return $this->jsonSuccess($content);
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace App\Http\Web\Controllers;
/**
* @RoutePrefix("/im/group")
*/
class ImGroupController extends Controller
{
/**
* @Get("/list", name="web.im_group.list")
*/
public function listAction()
{
}
/**
* @Get("/{id:[0-9]+}/manage", name="web.im_group.manage")
*/
public function manageAction()
{
}
/**
* @Get("/{id:[0-9]+}/users", name="web.im_group.users")
*/
public function usersAction()
{
}
/**
* @Post("/user/delete", name="web.im_group.delete_user")
*/
public function deleteUserAction()
{
}
/**
* @Post("/user/block", name="web.im_group.block_user")
*/
public function blockUserAction()
{
}
/**
* @Post("/user/unblock", name="web.im_group.unblock_user")
*/
public function unblockUserAction()
{
}
}

View File

@ -6,15 +6,13 @@ use App\Services\Frontend\My\AccountInfo as AccountInfoService;
use App\Services\Frontend\My\ConsultList as MyConsultListService;
use App\Services\Frontend\My\CourseList as MyCourseListService;
use App\Services\Frontend\My\FavoriteList as MyFavoriteListService;
use App\Services\Frontend\My\ImFriendDelete as MyFriendDeleteService;
use App\Services\Frontend\My\ImGroupDelete as MyGroupDeleteService;
use App\Services\Frontend\My\FriendList as MyFriendListService;
use App\Services\Frontend\My\GroupList as MyGroupListService;
use App\Services\Frontend\My\OrderList as MyOrderListService;
use App\Services\Frontend\My\RefundList as MyRefundListService;
use App\Services\Frontend\My\ReviewList as MyReviewListService;
use App\Services\Frontend\My\UserInfo as UserInfoService;
use App\Services\Frontend\My\UserUpdate as UserUpdateService;
use App\Services\Frontend\User\FriendList as UserFriendListService;
use App\Services\Frontend\User\GroupList as UserGroupListService;
/**
* @RoutePrefix("/my")
@ -155,9 +153,9 @@ class MyController extends Controller
*/
public function friendsAction()
{
$service = new UserFriendListService();
$service = new MyFriendListService();
$pager = $service->handle($this->authUser->id);
$pager = $service->handle();
$pager->items = kg_array_object($pager->items);
@ -169,9 +167,9 @@ class MyController extends Controller
*/
public function groupsAction()
{
$service = new UserGroupListService();
$service = new MyGroupListService();
$pager = $service->handle($this->authUser->id);
$pager = $service->handle();
$pager->items = kg_array_object($pager->items);
@ -192,32 +190,4 @@ class MyController extends Controller
return $this->jsonSuccess($content);
}
/**
* @Post("/friend/{id:[0-9]+}/delete", name="web.my.delete_friend")
*/
public function deleteFriendAction($id)
{
$service = new MyFriendDeleteService();
$service->handle($id);
$content = ['msg' => '删除好友成功'];
return $this->jsonSuccess($content);
}
/**
* @Post("/group/{id:[0-9]+}/delete", name="web.my.delete_group")
*/
public function deleteGroupAction($id)
{
$service = new MyGroupDeleteService();
$service->handle($id);
$content = ['msg' => '退出群组成功'];
return $this->jsonSuccess($content);
}
}

View File

@ -129,6 +129,19 @@ Trait ImFriendTrait
$this->handleRefuseFriendNotice($user, $sender);
}
public function quitFriend($id)
{
$user = $this->getLoginUser();
$validator = new ImFriendUserValidator();
$friend = $validator->checkFriend($id);
$friendUser = $validator->checkFriendUser($user->id, $friend->id);
$friendUser->delete();
}
protected function handleApplyFriendNotice(ImUserModel $sender, ImUserModel $receiver, ImFriendGroupModel $group, $remark)
{
$userRepo = new ImUserRepo();

View File

@ -0,0 +1,28 @@
<?php
namespace App\Http\Web\Services;
class ImGroup extends Service
{
public function getGroups()
{
}
public function getGroupUsers($id)
{
}
public function deleteUser()
{
}
public function blockUser()
{
}
public function unblockUser()
{
}
}

View File

@ -126,6 +126,25 @@ Trait ImGroupTrait
$this->handleRefuseGroupNotice($user, $sender);
}
public function quitGroup($id)
{
$loginUser = $this->getLoginUser();
$user = $this->getImUser($loginUser->id);
$validator = new ImGroupUserValidator();
$group = $validator->checkGroup($id);
$groupUser = $validator->checkGroupUser($group->id, $user->id);
$groupUser->delete();
$this->decrGroupUserCount($group);
$this->decrUserGroupCount($user);
}
protected function handleApplyGroupNotice(ImUserModel $sender, ImGroupModel $group, $remark)
{
$userRepo = new ImUserRepo();

View File

@ -38,9 +38,9 @@
<tbody>
{% for item in pager.items %}
{% set user_url = url({'for':'web.user.show','id':item.id}) %}
{% set delete_url = url({'for':'web.my.delete_friend','id':item.id}) %}
{% set delete_url = url({'for':'web.im.quit_friend','id':item.id}) %}
<tr>
<td><a href="{{ user_url }}" title="{{ item.about|e }}">{{ item.name }}</a></td>
<td><a href="{{ user_url }}" title="{{ item.about }}">{{ item.name }}</a></td>
<td>{{ gender_info(item.gender) }}</td>
<td>{{ item.location }}</td>
<td>{{ item.active_time|time_ago }}</td>

View File

@ -18,6 +18,7 @@
{% if pager.total_pages > 0 %}
<table class="layui-table" lay-size="lg">
<colgroup>
<col>
<col>
<col>
<col width="15%">
@ -25,18 +26,26 @@
<thead>
<tr>
<th>名称</th>
<th>成员数</th>
<th>群主</th>
<th>成员</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for item in pager.items %}
{% set delete_url = url({'for':'web.my.delete_group','id':item.id}) %}
{% set owner_url = url({'for':'web.user.show','id':item.owner.id}) %}
{% set manage_url = url({'for':'web.im_group.manage','id':item.id}) %}
{% set delete_url = url({'for':'web.im.quit_group','id':item.id}) %}
<tr>
<td><span title="{{ item.about|e }}">{{ item.name }}</span> {{ type_info(item.type) }}</td>
<td><span title="{{ item.about }}">{{ item.name }}</span> {{ type_info(item.type) }}</td>
<td><a href="{{ owner_url }}">{{ item.owner.name }}</a></td>
<td><span class="layui-badge-rim">{{ item.user_count }}</span></td>
<td>
{% if auth_user.id == item.owner.id %}
<button class="layui-btn layui-btn-sm layui-bg-blue" data-url="{{ manage_url }}">管理</button>
{% else %}
<button class="layui-btn layui-btn-sm kg-delete" data-tips="确定要退出吗?" data-url="{{ delete_url }}">退出</button>
{% endif %}
</td>
</tr>
{% endfor %}

View File

@ -24,8 +24,8 @@
</div>
</div>
<div id="alipay-qr-box" class="layui-hide"></div>
<div id="wxpay-qr-box" class="layui-hide"></div>
<div id="alipay-qrcode" class="layui-hide"></div>
<div id="wxpay-qrcode" class="layui-hide"></div>
<div class="layui-hide">
<input type="hidden" name="trade_create_url" value="{{ url({'for':'web.trade.create'}) }}">

View File

@ -3,20 +3,16 @@
<div class="top-nav">
<ul class="layui-nav">
{% for nav in site_navs.top %}
{% if nav.children %}
<li class="layui-nav-item">
<a href="javascript:">{{ nav.name }}</a>
<a href="{{ nav.url }}" target="{{ nav.target }}">{{ nav.name }}</a>
{% if nav.children %}
<dl class="layui-nav-child">
{% for child in nav.children %}
<dd><a href="{{ child.url }}" target="{{ child.target }}">{{ child.name }}</a></dd>
{% endfor %}
</dl>
</li>
{% else %}
<li class="layui-nav-item">
<a href="{{ nav.url }}">{{ nav.name }}</a>
</li>
{% endif %}
</li>
{% endfor %}
</ul>
</div>

View File

@ -133,6 +133,10 @@ class ImGroup extends Model
if ($this->deleted == 1) {
$this->published = 0;
}
if (Text::startsWith($this->avatar, 'http')) {
$this->avatar = self::getAvatarPath($this->avatar);
}
}
public function afterFetch()

View File

@ -65,7 +65,7 @@ class Order extends Model
*
* @var int
*/
public $user_id;
public $owner_id;
/**
* 条目编号

View File

@ -29,7 +29,7 @@ class Refund extends Model
*
* @var string
*/
public $user_id;
public $owner_id;
/**
* 订单编号

View File

@ -33,7 +33,7 @@ class Trade extends Model
*
* @var int
*/
public $user_id;
public $owner_id;
/**
* 订单编号

View File

@ -30,8 +30,8 @@ class Order extends Repository
$builder->andWhere('sn = :sn:', ['sn' => $where['sn']]);
}
if (!empty($where['user_id'])) {
$builder->andWhere('user_id = :user_id:', ['user_id' => $where['user_id']]);
if (!empty($where['owner_id'])) {
$builder->andWhere('owner_id = :owner_id:', ['owner_id' => $where['owner_id']]);
}
if (!empty($where['item_id'])) {
@ -105,7 +105,7 @@ class Order extends Repository
$status = OrderModel::STATUS_FINISHED;
return OrderModel::findFirst([
'conditions' => 'user_id = ?1 AND item_id = ?2 AND item_type = ?3 AND status = ?4',
'conditions' => 'owner_id = ?1 AND item_id = ?2 AND item_type = ?3 AND status = ?4',
'bind' => [1 => $userId, 2 => $itemId, 3 => $itemType, 4 => $status],
'order' => 'id DESC',
]);
@ -122,7 +122,7 @@ class Order extends Repository
$status = OrderModel::STATUS_PENDING;
return OrderModel::findFirst([
'conditions' => 'user_id = ?1 AND item_id = ?2 AND item_type = ?3 AND status= ?4',
'conditions' => 'owner_id = ?1 AND item_id = ?2 AND item_type = ?3 AND status= ?4',
'bind' => [1 => $userId, 2 => $itemId, 3 => $itemType, 4 => $status],
'order' => 'id DESC',
]);

View File

@ -21,8 +21,8 @@ class Refund extends Repository
$builder->where('1 = 1');
if (!empty($where['user_id'])) {
$builder->andWhere('user_id = :user_id:', ['user_id' => $where['user_id']]);
if (!empty($where['owner_id'])) {
$builder->andWhere('owner_id = :owner_id:', ['owner_id' => $where['owner_id']]);
}
if (!empty($where['order_id'])) {

View File

@ -5,6 +5,7 @@ namespace App\Repos;
use App\Library\Paginator\Adapter\QueryBuilder as PagerQueryBuilder;
use App\Models\Refund as RefundModel;
use App\Models\Trade as TradeModel;
use App\Models\TradeStatus as TradeStatusModel;
use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
@ -28,8 +29,8 @@ class Trade extends Repository
$builder->andWhere('sn = :sn:', ['sn' => $where['sn']]);
}
if (!empty($where['user_id'])) {
$builder->andWhere('user_id = :user_id:', ['user_id' => $where['user_id']]);
if (!empty($where['owner_id'])) {
$builder->andWhere('owner_id = :owner_id:', ['owner_id' => $where['owner_id']]);
}
if (!empty($where['order_id'])) {
@ -116,6 +117,17 @@ class Trade extends Repository
->execute();
}
/**
* @param int $tradeId
* @return ResultsetInterface|Resultset|TradeStatusModel[]
*/
public function findStatusHistory($tradeId)
{
return TradeStatusModel::query()
->where('trade_id = :trade_id:', ['trade_id' => $tradeId])
->execute();
}
/**
* @param int $tradeId
* @return RefundModel|Model|bool

View File

@ -1,6 +1,6 @@
<?php
namespace App\Services\Frontend\My;
namespace App\Services\Frontend\Im;
use App\Services\Frontend\Service as FrontendService;
use App\Validators\ImFriendUser as ImFriendUserValidator;

View File

@ -1,9 +1,9 @@
<?php
namespace App\Services\Frontend\My;
namespace App\Services\Frontend\Im;
use App\Models\ImGroup as ImGroupModel;
use App\Repos\ImGroup as ImGroupRepo;
use App\Models\ImUser as ImUserModel;
use App\Services\Frontend\Service as FrontendService;
use App\Validators\ImGroupUser as ImGroupUserValidator;
@ -22,18 +22,23 @@ class ImGroupDelete extends FrontendService
$groupUser->delete();
$this->updateGroupUserCount($group);
$this->decrGroupUserCount($group);
}
protected function updateGroupUserCount(ImGroupModel $group)
protected function decrGroupUserCount(ImGroupModel $group)
{
$repo = new ImGroupRepo();
$userCount = $repo->countUsers($group->id);
$group->user_count = $userCount;
if ($group->user_count > 0) {
$group->user_count -= 1;
$group->update();
}
}
protected function decrUserGroupCount(ImUserModel $user)
{
if ($user->group_count > 0) {
$user->group_count -= 1;
$user->update();
}
}
}

View File

@ -0,0 +1,52 @@
<?php
namespace App\Services\Frontend\Im;
use App\Models\ImGroup as ImGroupModel;
use App\Models\ImUser as ImUserModel;
use App\Services\Frontend\Service as FrontendService;
use App\Validators\ImGroupUser as ImGroupUserValidator;
class ImGroupUserDelete extends FrontendService
{
public function handle()
{
$post = $this->request->getPost();
$loginUser = $this->getLoginUser();
$validator = new ImGroupUserValidator();
$group = $validator->checkGroup($post['group_id']);
$user = $validator->checkUser($post['user_id']);
$validator->checkOwner($group->owner_id, $loginUser->id);
$groupUser = $validator->checkGroupUser($group->id, $user->id);
$groupUser->delete();
$this->decrGroupUserCount($group);
$this->decrUserGroupCount($user);
}
protected function decrGroupUserCount(ImGroupModel $group)
{
if ($group->user_count > 0) {
$group->user_count -= 1;
$group->update();
}
}
protected function decrUserGroupCount(ImUserModel $user)
{
if ($user->group_count > 0) {
$user->group_count -= 1;
$user->update();
}
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace App\Services\Frontend\My;
use App\Services\Frontend\Service as FrontendService;
use App\Services\Frontend\User\FriendList as UserFriendListService;
class FriendList extends FrontendService
{
public function handle()
{
$user = $this->getLoginUser();
$service = new UserFriendListService();
return $service->handle($user->id);
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace App\Services\Frontend\My;
use App\Services\Frontend\Service as FrontendService;
use App\Services\Frontend\User\GroupList as UserGroupListService;
class GroupList extends FrontendService
{
public function handle()
{
$user = $this->getLoginUser();
$service = new UserGroupListService();
return $service->handle($user->id);
}
}

View File

@ -20,7 +20,7 @@ class OrderCancel extends FrontendService
$validator = new OrderValidator();
$validator->checkOwner($user->id, $order->user_id);
$validator->checkOwner($user->id, $order->owner_id);
$validator->checkIfAllowCancel($order);

View File

@ -87,7 +87,7 @@ class OrderCreate extends FrontendService
$order = new OrderModel();
$order->user_id = $user->id;
$order->owner_id = $user->id;
$order->item_id = $course->id;
$order->item_type = OrderModel::ITEM_COURSE;
$order->item_info = $itemInfo;
@ -122,7 +122,7 @@ class OrderCreate extends FrontendService
$order = new OrderModel();
$order->user_id = $user->id;
$order->owner_id = $user->id;
$order->item_id = $package->id;
$order->item_type = OrderModel::ITEM_PACKAGE;
$order->item_info = $itemInfo;
@ -151,7 +151,7 @@ class OrderCreate extends FrontendService
$order = new OrderModel();
$order->user_id = $user->id;
$order->owner_id = $user->id;
$order->item_id = $vip->id;
$order->item_type = OrderModel::ITEM_VIP;
$order->item_info = $itemInfo;
@ -176,7 +176,7 @@ class OrderCreate extends FrontendService
$order = new OrderModel();
$order->user_id = $user->id;
$order->owner_id = $user->id;
$order->item_id = "{$course->id}-{$reward->id}";
$order->item_type = OrderModel::ITEM_REWARD;
$order->item_info = $itemInfo;

View File

@ -22,7 +22,7 @@ class RefundCancel extends FrontendService
$validator = new RefundValidator();
$validator->checkOwner($user->id, $refund->user_id);
$validator->checkOwner($user->id, $refund->owner_id);
$refund->status = RefundModel::STATUS_CANCELED;

View File

@ -31,7 +31,7 @@ class RefundCreate extends FrontendService
$validator = new OrderValidator();
$validator->checkOwner($user->id, $order->user_id);
$validator->checkOwner($user->id, $order->owner_id);
$validator->checkIfAllowRefund($order);
@ -54,7 +54,7 @@ class RefundCreate extends FrontendService
$refund->apply_note = $applyNote;
$refund->order_id = $order->id;
$refund->trade_id = $trade->id;
$refund->user_id = $user->id;
$refund->owner_id = $user->id;
$refund->status = RefundModel::STATUS_APPROVED;
$refund->review_note = '退款周期内无条件审批';

View File

@ -1,18 +0,0 @@
<?php
namespace App\Services\Frontend\Trade;
use App\Services\Frontend\OrderTrait;
use App\Services\Frontend\Service as FrontendService;
class TradeCancel extends FrontendService
{
use OrderTrait;
public function handle($sn)
{
}
}

View File

@ -30,7 +30,7 @@ class TradeCreate extends FrontendService
$trade->amount = $order->amount;
$trade->channel = $channel;
$trade->order_id = $order->id;
$trade->user_id = $user->id;
$trade->owner_id = $user->id;
$trade->create();

View File

@ -17,7 +17,7 @@ class ImGroupUser extends Validator
public function checkUser($id)
{
$validator = new User();
$validator = new ImUser();
return $validator->checkUser($id);
}

View File

@ -179,3 +179,12 @@ img.kg-qrcode {
padding-top: 0;
border-top: none;
}
.kg-status-history {
line-height: 30px;
}
.kg-status-history .time {
margin-left: 10px;
color: #666;
}

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<cross-domain-policy>
<allow-access-from domain="*"/>
</cross-domain-policy>

View File

@ -9,24 +9,23 @@ layui.use(['jquery', 'layer'], function () {
var statusUrl = $('input[name=trade_status_url]').val();
var forwardUrl = $('input[name=forward_url]').val();
var orderSn = $('input[name=order_sn]').val();
var $qrBox = $('#' + channel + '-qr-box');
var $qrBlock = $('#' + channel + '-qrcode');
var $snInput = $('input[name=' + channel + '_trade_sn]');
var qrTitle = channel === 'alipay' ? '支付宝扫码支付' : '微信扫码支付';
var qrHtml = $qrBox.html();
var qrHtml = $qrBlock.html();
if (qrHtml.length === 0) {
var postData = {order_sn: orderSn, channel: channel};
$.post(createUrl, postData, function (res) {
qrHtml = '<div class="qrcode"><img src="' + res.qrcode_url + '" alt="支付二维码"></div>';
showQrLayer(qrTitle, qrHtml);
$qrBox.html(qrHtml);
$qrBlock.html(qrHtml);
$snInput.html(res.sn);
var interval = setInterval(function () {
var queryData = {sn: res.sn};
$.get(statusUrl, queryData, function (res) {
if (res.status === 'finished') {
clearInterval(interval);
var html = '<div class="success-tips">支付成功</div>';
$('#pay-layer').html(html);
$('#pay-layer').html('<div class="success-tips">支付成功</div>');
setTimeout(function () {
window.location.href = forwardUrl;
}, 5000);