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

完善文件上传部分

This commit is contained in:
xiaochong0302 2020-07-29 20:43:05 +08:00
parent c88284e5b7
commit fdce89a4e7
47 changed files with 619 additions and 238 deletions

View File

@ -11,7 +11,7 @@ class UploadController extends Controller
{
/**
* @Post("/cover/img", name="admin.upload.cover.img")
* @Post("/img/cover", name="admin.upload.cover_img")
*/
public function uploadCoverImageAction()
{
@ -29,7 +29,25 @@ class UploadController extends Controller
}
/**
* @Post("/content/img", name="admin.upload.content.img")
* @Post("/img/avatar", name="admin.upload.avatar_img")
*/
public function uploadAvatarImageAction()
{
$storageService = new StorageService();
$key = $storageService->uploadAvatarImage();
$url = $storageService->getCiImageUrl($key);
if ($url) {
return $this->jsonSuccess(['data' => ['src' => $url, 'title' => '']]);
} else {
return $this->jsonError(['msg' => '上传文件失败']);
}
}
/**
* @Post("/img/content", name="admin.upload.content_img")
*/
public function uploadContentImageAction()
{

View File

@ -12,15 +12,15 @@ class VodController extends Controller
{
/**
* @Post("/upload/signature", name="admin.vod.upload_signature")
* @Post("/upload/sign", name="admin.vod.upload_sign")
*/
public function uploadSignatureAction()
public function uploadSignAction()
{
$vodService = new VodService();
$signature = $vodService->getUploadSignature();
$sign = $vodService->getUploadSign();
return $this->jsonSuccess(['signature' => $signature]);
return $this->jsonSuccess(['sign' => $sign]);
}
/**

View File

@ -10,15 +10,11 @@
<div class="layui-form-item">
<label class="layui-form-label">封面</label>
<div class="layui-input-inline">
{% if course.cover %}
<img id="img-cover" class="kg-cover" src="{{ course.cover }}">
{% else %}
{{ image('id':'img-cover','class':'kg-cover','src':'admin/img/default_cover.png') }}
{% endif %}
<img id="img-cover" class="kg-cover" src="{{ course.cover }}">
<input type="hidden" name="cover" value="{{ course.cover }}">
</div>
<div class="layui-input-inline" style="padding-top:35px;">
<a href="javascript:" class="layui-btn layui-btn-sm" id="choose-cover">编辑</a>
<button id="change-cover" class="layui-btn layui-btn-sm" type="button">更换</button>
</div>
</div>

View File

@ -7,15 +7,11 @@
<div class="layui-form-item">
<label class="layui-form-label">头像</label>
<div class="layui-input-inline" style="width: 110px;">
{% if group.avatar %}
<img id="img-cover" class="kg-avatar" src="{{ group.avatar }}">
{% else %}
{{ image('id':'img-cover','class':'kg-cover','src':'admin/img/default_cover.png') }}
{% endif %}
<input type="hidden" name="cover" value="{{ group.avatar }}">
<img id="img-avatar" class="kg-avatar" src="{{ group.avatar }}">
<input type="hidden" name="avatar" value="{{ group.avatar }}">
</div>
<div class="layui-input-inline" style="padding-top:35px;">
<a href="javascript:" class="layui-btn layui-btn-sm" id="choose-cover">编辑</a>
<button id="change-avatar" class="layui-btn layui-btn-sm" type="button">更换</button>
</div>
</div>
@ -58,4 +54,4 @@
</form>
{{ partial('partials/cover_uploader') }}
{{ partial('partials/avatar_uploader') }}

View File

@ -0,0 +1,49 @@
<script>
layui.use(['jquery', 'layer', 'upload'], function () {
var $ = layui.jquery;
var layer = layui.layer;
var upload = layui.upload;
upload.render({
elem: '#change-avatar',
url: '/admin/upload/img/avatar',
accept: 'images',
acceptMime: 'image/*',
size: 512,
auto: false,
before: function () {
layer.load();
},
choose: function (obj) {
var flag = true;
obj.preview(function (index, file, result) {
console.log(file);
var img = new Image();
img.src = result;
img.onload = function () {
if (img.width < 1000 && img.height < 1000) {
obj.upload(index, file);
} else {
flag = false;
layer.msg("图片尺寸必须小于 1000 * 1000");
return false;
}
};
return flag;
});
},
done: function (res, index, upload) {
$('#img-avatar').attr('src', res.data.src);
$('input[name=avatar]').val(res.data.src);
layer.closeAll('loading');
},
error: function (index, upload) {
layer.msg('上传文件失败', {icon: 2});
}
});
});
</script>

View File

@ -1,14 +1,14 @@
<script>
layui.use(['jquery', 'upload'], function () {
layui.use(['jquery', 'layer', 'upload'], function () {
var $ = layui.jquery;
var layer = layui.layer;
var upload = layui.upload;
upload.render({
elem: '#choose-cover',
url: '/admin/upload/cover/img',
elem: '#change-cover',
url: '/admin/upload/img/cover',
accept: 'images',
acceptMime: 'image/*',
before: function () {

View File

@ -6,7 +6,7 @@
var layedit = layui.layedit;
layedit.set({
uploadImage: {url: '/admin/upload/content/img'}
uploadImage: {url: '/admin/upload/img/content'}
});
var index = layedit.build('kg-layedit');

View File

@ -11,10 +11,10 @@
var result = '';
$.ajax({
type: 'POST',
url: '/admin/vod/upload/signature',
url: '/admin/vod/upload/sign',
async: false,
success: function (res) {
result = res.signature;
result = res.sign;
}
});
return result;

View File

@ -17,15 +17,11 @@
<div class="layui-form-item">
<label class="layui-form-label">封面</label>
<div class="layui-input-inline">
{% if slide.cover %}
<img id="img-cover" class="kg-cover" src="{{ slide.cover }}">
{% else %}
{{ image('id':'img-cover','class':'kg-cover','src':'admin/img/default_cover.png') }}
{% endif %}
<img id="img-cover" class="kg-cover" src="{{ slide.cover }}">
<input type="hidden" name="cover" value="{{ slide.cover }}">
</div>
<div class="layui-input-inline" style="padding-top:35px;">
<a href="javascript:" class="layui-btn layui-btn-sm" id="choose-cover">编辑</a>
<button id="change-cover" class="layui-btn layui-btn-sm" type="button">更换</button>
</div>
</div>

View File

@ -35,10 +35,22 @@ class ImGroupController extends Controller
$this->view->setVar('pager', $pager);
}
/**
* @Get("/{id:[0-9]+}/edit", name="web.im_group.edit")
*/
public function editAction($id)
{
$service = new ImGroupService();
$group = $service->getGroup($id);
$this->view->setVar('group', $group);
}
/**
* @Post("/{id:[0-9]+}/update", name="web.im_group.update")
*/
public function updateAction()
public function updateAction($id)
{
$service = new ImGroupService();

View File

@ -9,10 +9,10 @@ use App\Services\Frontend\My\FavoriteList as MyFavoriteListService;
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\ProfileInfo as ProfileInfoService;
use App\Services\Frontend\My\ProfileUpdate as ProfileUpdateService;
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;
/**
* @RoutePrefix("/my")
@ -45,7 +45,7 @@ class MyController extends Controller
*/
public function profileAction()
{
$service = new UserInfoService();
$service = new ProfileInfoService();
$user = $service->handle();
@ -167,12 +167,15 @@ class MyController extends Controller
*/
public function groupsAction()
{
$type = $this->request->getQuery('type', 'trim', 'joined');
$service = new MyGroupListService();
$pager = $service->handle();
$pager = $service->handle($type);
$pager->items = kg_array_object($pager->items);
$this->view->setVar('type', $type);
$this->view->setVar('pager', $pager);
}
@ -181,11 +184,14 @@ class MyController extends Controller
*/
public function updateProfileAction()
{
$service = new UserUpdateService();
$service = new ProfileUpdateService();
$service->handle();
$content = ['msg' => '更新资料成功'];
$content = [
'location' => $this->request->getHTTPReferer(),
'msg' => '更新资料成功',
];
return $this->jsonSuccess($content);
}

View File

@ -0,0 +1,32 @@
<?php
namespace App\Http\Web\Controllers;
use App\Services\Storage as StorageService;
/**
* @RoutePrefix("/upload")
*/
class UploadController extends Controller
{
/**
* @Post("/img/avatar", name="web.upload.avatar_img")
*/
public function uploadAvatarImageAction()
{
$service = new StorageService();
$key = $service->uploadAvatarImage();
$url = $service->getCiImageUrl($key);
if ($url) {
return $this->jsonSuccess(['data' => ['src' => $url, 'title' => '']]);
} else {
return $this->jsonError(['msg' => '上传文件失败']);
}
}
}

View File

@ -357,13 +357,6 @@ class Im extends Service
$relation = $validator->checkFriendUser($to['id'], $user->id);
/**
* 被对方屏蔽,忽略消息
*/
if ($relation->blocked) {
return;
}
$online = Gateway::isUidOnline($to['id']);
$messageModel = new ImFriendMessageModel();
@ -386,14 +379,7 @@ class Im extends Service
$validator = new ImGroupUserValidator();
$relation = $validator->checkGroupUser($to['id'], $user->id);
/**
* 被对方屏蔽,忽略消息
*/
if ($relation->blocked) {
return;
}
$validator->checkGroupUser($to['id'], $user->id);
$messageModel = new ImGroupMessageModel();

View File

@ -31,7 +31,6 @@ Trait ImFriendTrait
$validator->checkIfSelf($user->id, $friend->id);
$validator->checkIfJoined($user->id, $friend->id);
$validator->checkIfBlocked($user->id, $friend->id);
$this->handleApplyFriendNotice($user, $friend, $group, $remark);
}

View File

@ -30,8 +30,17 @@ class ImGroup extends Service
$data = [];
$data['name'] = $validator->checkName($post['name']);
$data['about'] = $validator->checkAbout($post['about']);
if (!empty($post['name'])) {
$data['name'] = $validator->checkName($post['name']);
}
if (!empty($post['about'])) {
$data['about'] = $validator->checkAbout($post['about']);
}
if (!empty($post['avatar'])) {
$data['avatar'] = $validator->checkAvatar($post['avatar']);
}
$group->update($data);

View File

@ -31,7 +31,6 @@ Trait ImGroupTrait
$remark = $validator->checkRemark($post['remark']);
$validator->checkIfJoined($group->id, $user->id);
$validator->checkIfBlocked($group->id, $user->id);
$this->handleApplyGroupNotice($user, $group, $remark);
}

View File

@ -1,23 +1,45 @@
{% set update_group_url = url({'for':'web.im_group.update','id':group.id}) %}
{% extends 'templates/layer.volt' %}
<form class="layui-form" method="post" action="{{ update_group_url }}">
<div class="layui-form-item">
<label class="layui-form-label">名称</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="name" value="{{ group.name }}" lay-verify="required">
{% block content %}
{% set update_url = url({'for':'web.im_group.update','id':group.id}) %}
<form class="layui-form" method="post" action="{{ update_url }}">
<div class="layui-form-item">
<label class="layui-form-label">头像</label>
<div class="layui-input-inline" style="width: 110px;">
<img id="img-avatar" class="my-avatar" src="{{ group.avatar }}">
<input type="hidden" name="avatar" value="{{ group.avatar }}">
</div>
<div class="layui-input-inline" style="padding-top:35px;">
<button id="change-avatar" class="layui-btn layui-btn-sm" type="button">更换</button>
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">简介</label>
<div class="layui-input-block">
<textarea class="layui-textarea" name="about" lay-verify="required">{{ group.about }}</textarea>
<div class="layui-form-item">
<label class="layui-form-label">名称</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="name" value="{{ group.name }}" lay-verify="required">
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"></label>
<div class="layui-input-block">
<button class="layui-btn" lay-submit="true" lay-filter="go">提交</button>
<button class="layui-btn layui-btn-primary" type="reset">重置</button>
<div class="layui-form-item">
<label class="layui-form-label">简介</label>
<div class="layui-input-block">
<textarea class="layui-textarea" name="about" lay-verify="required">{{ group.about }}</textarea>
</div>
</div>
</div>
</form>
<div class="layui-form-item">
<label class="layui-form-label"></label>
<div class="layui-input-block">
<button class="layui-btn" lay-submit="true" lay-filter="go">提交</button>
<button class="layui-btn layui-btn-primary" type="reset">重置</button>
</div>
</div>
</form>
{% endblock %}
{% block include_js %}
{{ js_include('web/js/upload.avatar.js') }}
{% endblock %}

View File

@ -1,34 +0,0 @@
{% extends 'templates/layer.volt' %}
{% block content %}
<div class="im-user-list clearfix">
<div class="layui-row layui-col-space20">
{% for item in pager.items %}
<div class="layui-col-md2">
<div class="user-card">
{% if item.vip == 1 %}
<span class="vip">会员</span>
{% endif %}
<div class="avatar">
<a href="javascript:" title="{{ item.about }}"><img src="{{ item.avatar }}" alt="{{ item.name }}"></a>
</div>
<div class="name layui-elip" title="{{ item.name }}">{{ item.name }}</div>
<div class="action">
<a href="javascript:" class="layui-badge-rim apply-friend" data-id="{{ item.id }}" data-name="{{ item.name }}" data-avatar="{{ item.avatar }}">加为好友</a>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
{{ partial('partials/pager') }}
{% endblock %}
{% block include_js %}
{{ js_include('web/js/my.im.js') }}
{% endblock %}

View File

@ -10,7 +10,9 @@
<div class="my-sidebar">{{ partial('my/menu') }}</div>
<div class="my-content">
<div class="wrap">
<div class="my-nav-title">账号安全</div>
<div class="my-nav">
<span class="title">账号安全</span>
</div>
<div class="security-item-list">
<div class="security-item">
<span class="icon"><i class="layui-icon layui-icon-password"></i></span>

View File

@ -8,7 +8,9 @@
<div class="my-sidebar">{{ partial('my/menu') }}</div>
<div class="my-content">
<div class="wrap">
<div class="my-nav-title">我的咨询</div>
<div class="my-nav">
<span class="title">我的咨询</span>
</div>
{% if pager.total_pages > 0 %}
<table class="layui-table consult-table">
<colgroup>

View File

@ -8,7 +8,9 @@
<div class="my-sidebar">{{ partial('my/menu') }}</div>
<div class="my-content">
<div class="wrap">
<div class="my-nav-title">我的课程</div>
<div class="my-nav">
<span class="title">我的课程</span>
</div>
{% if pager.total_pages > 0 %}
<table class="layui-table">
<colgroup>
@ -37,7 +39,7 @@
<p>进度:{{ item.progress }}%</p>
</td>
<td align="center">
<button class="layui-btn layui-btn-sm btn-add-review" data-url="{{ review_url }}">评价</button>
<button class="layui-btn layui-btn-xs btn-add-review" data-url="{{ review_url }}">评价</button>
</td>
</tr>
{% endfor %}

View File

@ -8,7 +8,9 @@
<div class="my-sidebar">{{ partial('my/menu') }}</div>
<div class="my-content">
<div class="wrap">
<div class="my-nav-title">我的收藏</div>
<div class="my-nav">
<span class="title">我的收藏</span>
</div>
{% if pager.total_pages > 0 %}
<table class="layui-table" lay-size="lg">
<colgroup>
@ -34,7 +36,7 @@
<td><span class="layui-badge-rim">{{ item.user_count }}</span></td>
<td>{{ star_info(item.rating) }}</td>
<td align="center">
<button class="layui-btn layui-btn-sm kg-delete" data-tips="确定要取消收藏吗?" data-url="{{ favorite_url }}">取消</button>
<button class="layui-btn layui-btn-xs kg-delete" data-tips="确定要取消收藏吗?" data-url="{{ favorite_url }}">取消</button>
</td>
</tr>
{% endfor %}

View File

@ -16,7 +16,9 @@
<div class="my-sidebar">{{ partial('my/menu') }}</div>
<div class="my-content">
<div class="wrap">
<div class="my-nav-title">我的好友</div>
<div class="my-nav">
<span class="title">我的好友</span>
</div>
{% if pager.total_pages > 0 %}
<table class="layui-table" lay-size="lg">
<colgroup>
@ -45,7 +47,7 @@
<td>{{ item.location }}</td>
<td>{{ item.active_time|time_ago }}</td>
<td>
<button class="layui-btn layui-btn-sm kg-delete" data-url="{{ delete_url }}">删除</button>
<button class="layui-btn layui-btn-xs kg-delete" data-url="{{ delete_url }}">删除</button>
</td>
</tr>
{% endfor %}

View File

@ -10,48 +10,24 @@
{% endif %}
{%- endmacro %}
{% set joined_url = url({'for':'web.my.groups'},{'type':'joined'}) %}
{% set owned_url = url({'for':'web.my.groups'},{'type':'owned'}) %}
{% set joined_class = type == 'joined' ? 'layui-btn layui-btn-xs' : 'none' %}
{% set owned_class = type == 'owned' ? 'layui-btn layui-btn-xs' : 'none' %}
<div class="layout-main">
<div class="my-sidebar">{{ partial('my/menu') }}</div>
<div class="my-content">
<div class="wrap">
<div class="my-nav-title">我的群组</div>
{% if pager.total_pages > 0 %}
<table class="layui-table" lay-size="lg">
<colgroup>
<col>
<col>
<col>
<col width="15%">
</colgroup>
<thead>
<tr>
<th>名称</th>
<th>群主</th>
<th>成员</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for item in pager.items %}
{% set owner_url = url({'for':'web.user.show','id':item.owner.id}) %}
{% set manage_url = url({'for':'web.im_group.users','id':item.id}) %}
{% set delete_url = url({'for':'web.im.quit_group','id':item.id}) %}
<tr>
<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 btn-manage-group" 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 %}
</tbody>
</table>
{{ partial('partials/pager') }}
<div class="my-nav">
<span class="title">我的群组</span>
<a class="{{ joined_class }}" href="{{ joined_url }}">参加的</a>
<a class="{{ owned_class }}" href="{{ owned_url }}">管理的</a>
</div>
<div class="my-group-wrap wrap">
{% if type == 'owned' %}
{{ partial('my/groups_owned') }}
{% else %}
{{ partial('my/groups_joined') }}
{% endif %}
</div>
</div>

View File

@ -0,0 +1,33 @@
{% if pager.total_pages > 0 %}
<table class="layui-table" lay-size="lg">
<colgroup>
<col>
<col>
<col>
<col width="15%">
</colgroup>
<thead>
<tr>
<th>名称</th>
<th>群主</th>
<th>成员</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for item in pager.items %}
{% set owner_url = url({'for':'web.user.show','id':item.owner.id}) %}
{% set delete_url = url({'for':'web.im.quit_group','id':item.id}) %}
<tr>
<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>
<button class="layui-btn layui-btn-xs kg-delete" data-tips="确定要退出吗?" data-url="{{ delete_url }}">退出</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{{ partial('partials/pager') }}
{% endif %}

View File

@ -0,0 +1,35 @@
{% if pager.total_pages > 0 %}
<table class="layui-table" lay-size="lg">
<colgroup>
<col>
<col>
<col>
<col width="18%">
</colgroup>
<thead>
<tr>
<th>名称</th>
<th>群主</th>
<th>成员</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for item in pager.items %}
{% set owner_url = url({'for':'web.user.show','id':item.owner.id}) %}
{% set edit_url = url({'for':'web.im_group.edit','id':item.id}) %}
{% set users_url = url({'for':'web.im_group.users','id':item.id}) %}
<tr>
<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>
<button class="layui-btn layui-btn-xs layui-bg-blue btn-group-user" data-url="{{ users_url }}">成员</button>
<button class="layui-btn layui-btn-xs btn-edit-group" data-url="{{ edit_url }}">编辑</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{{ partial('partials/pager') }}
{% endif %}

View File

@ -9,7 +9,7 @@
<div class="my-profile-card wrap">
<div class="avatar">
<a href="javascript:"><img src="{{ auth_user.avatar }}" alt="{{ auth_user.name }}"></a>
<img class="my-avatar" src="{{ auth_user.avatar }}" alt="{{ auth_user.name }}">
</div>
<div class="name">{{ auth_user.name }} {{ vip_info(auth_user) }}</div>
</div>

View File

@ -5,12 +5,13 @@
{{ partial('partials/macro_order') }}
{% set status_types = {'all':'全部','pending':'待支付','finished':'已完成','closed':'已关闭','refunded':'已退款'} %}
{% set status = request.get('status','trim','all') %}
<div class="layout-main">
<div class="my-sidebar">{{ partial('my/menu') }}</div>
<div class="my-content">
<div class="order-filter wrap">
{% set status = request.get('status','trim','all') %}
<div class="my-nav">
<span class="title">我的订单</span>
{% for key,value in status_types %}
{% set class = (status == key) ? 'layui-btn layui-btn-xs' : 'none' %}
{% set url = (key == 'all') ? url({'for':'web.my.orders'}) : url({'for':'web.my.orders'},{'status':key}) %}
@ -31,7 +32,7 @@
<div class="column price">{{ '¥%0.2f'|format(item.amount) }}</div>
<div class="column status">{{ order_status(item.status) }}</div>
<div class="column action">
<a class="layui-btn layui-btn-sm btn-order-info" href="javascript:" data-url="{{ order_info_url }}">详情</a>
<button class="layui-btn layui-btn-xs btn-order-info" data-url="{{ order_info_url }}">详情</button>
</div>
</div>
</div>

View File

@ -2,14 +2,29 @@
{% block content %}
{% set update_profile_url = url({'for':'web.my.update_profile'}) %}
{% set update_url = url({'for':'web.my.update_profile'}) %}
{% set gender_male_checked = user.gender == 1 ? 'checked' : '' %}
{% set gender_female_checked = user.gender == 2 ? 'checked' : '' %}
{% set gender_none_checked = user.gender == 3 ? 'checked' : '' %}
<div class="layout-main">
<div class="my-sidebar">{{ partial('my/menu') }}</div>
<div class="my-content">
<div class="wrap">
<div class="my-nav-title">个人信息</div>
<form class="layui-form my-form" method="post" action="{{ update_profile_url }}">
<div class="my-nav">
<span class="title">个人信息</span>
</div>
<form class="layui-form profile-form" method="post" action="{{ update_url }}">
<div class="layui-form-item">
<label class="layui-form-label">头像</label>
<div class="layui-input-inline" style="width: 110px;">
<img id="img-avatar" class="my-avatar" src="{{ user.avatar }}">
<input type="hidden" name="avatar" value="{{ user.avatar }}">
</div>
<div class="layui-input-inline" style="padding-top:35px;">
<button id="change-avatar" class="layui-btn layui-btn-sm" type="button">更换</button>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">昵称</label>
<div class="layui-input-block">
@ -19,12 +34,9 @@
<div class="layui-form-item">
<label class="layui-form-label">性别</label>
<div class="layui-input-block">
{% set male_checked = user.gender == 1 ? 'checked' : '' %}
{% set female_checked = user.gender == 2 ? 'checked' : '' %}
{% set none_checked = user.gender == 3 ? 'checked' : '' %}
<input type="radio" name="gender" value="1" title="男" {{ male_checked }}>
<input type="radio" name="gender" value="2" title="女" {{ female_checked }}>
<input type="radio" name="gender" value="3" title="保密" {{ none_checked }}>
<input type="radio" name="gender" value="1" title="男" {{ gender_male_checked }}>
<input type="radio" name="gender" value="2" title="女" {{ gender_female_checked }}>
<input type="radio" name="gender" value="3" title="保密" {{ gender_none_checked }}>
</div>
</div>
<div class="layui-form-item" id="area-picker" style="margin-bottom: 25px;">
@ -67,6 +79,7 @@
{% block include_js %}
{{ js_include('web/js/upload.avatar.js') }}
{{ js_include('web/js/my.profile.js') }}
{% endblock %}

View File

@ -5,12 +5,13 @@
{{ partial('partials/macro_refund') }}
{% set status_types = {'all':'全部','pending':'待处理','canceled':'已取消','approved':'退款中','finished':'已完成'} %}
{% set status = request.get('status','trim','all') %}
<div class="layout-main">
<div class="my-sidebar">{{ partial('my/menu') }}</div>
<div class="my-content">
<div class="order-filter wrap">
{% set status = request.get('status','trim','all') %}
<div class="my-nav">
<span class="title">我的退款</span>
{% for key,value in status_types %}
{% set class = (status == key) ? 'layui-btn layui-btn-xs' : 'none' %}
{% set url = (key == 'all') ? url({'for':'web.my.refunds'}) : url({'for':'web.my.refunds'},{'status':key}) %}
@ -31,7 +32,7 @@
<div class="column price">{{ '¥%0.2f'|format(item.amount) }}</div>
<div class="column status">{{ refund_status(item.status) }}</div>
<div class="column action">
<a class="layui-btn layui-btn-sm btn-refund-info" href="javascript:" data-url="{{ refund_info_url }}">详情</a>
<button class="layui-btn layui-btn-xs btn-refund-info" data-url="{{ refund_info_url }}">详情</button>
</div>
</div>
</div>

View File

@ -8,7 +8,9 @@
<div class="my-sidebar">{{ partial('my/menu') }}</div>
<div class="my-content">
<div class="wrap">
<div class="my-nav-title">我的评价</div>
<div class="my-nav">
<span class="title">我的评价</span>
</div>
{% if pager.total_pages > 0 %}
<table class="layui-table review-table">
<colgroup>

View File

@ -0,0 +1,101 @@
<?php
namespace App\Library\Utils;
class FileInfo
{
static function isVideo($mine)
{
$case1 = self::isSecure($mine);
$case2 = strpos($mine, 'video') !== false;
return $case1 && $case2;
}
static function isAudio($mine)
{
$case1 = self::isSecure($mine);
$case2 = strpos($mine, 'audio') !== false;
return $case1 && $case2;
}
static function isImage($mine)
{
$case1 = self::isSecure($mine);
$case2 = strpos($mine, 'image') !== false;
return $case1 && $case2;
}
static function isSecure($mine)
{
return in_array($mine, self::mineTypes());
}
static function mineTypes()
{
return [
'aac' => 'audio/aac',
'ogg' => 'audio/ogg',
'wav' => 'audio/wav',
'mp3' => 'audio/mpeg',
'weba' => 'audio/webm',
'm4a' => 'audio/x-m4a',
'wma' => 'audio/x-ms-wma',
'mp4' => 'video/mp4',
'3gp' => 'video/3gpp',
'mpeg' => 'video/mpeg',
'webm' => 'video/webm',
'flv' => 'video/x-flv',
'avi' => 'video/x-msvideo',
'mkv' => 'video/x-matroska',
'wmv' => 'video/x-ms-wmv',
'gif' => 'image/gif',
'jpeg' => 'image/jpeg',
'jpg' => 'image/jpeg',
'png' => 'image/png',
'webp' => 'image/webp',
'bmp' => 'image/bmp',
'tif' => 'image/tiff',
'tiff' => 'image/tiff',
'svg' => 'image/svg+xml',
'psd' => 'image/vnd.adobe.photoshop',
'rar' => 'application/vnd.rar',
'tar' => 'application/x-tar',
'7z' => 'application/x-7z-compressed',
'bz' => 'application/x-bzip',
'bz2' => 'application/x-bzip2',
'gz' => 'application/gzip',
'zip' => 'application/zip',
'txt' => 'text/plain',
'csv' => 'text/csv',
'json' => 'application/json',
'xml' => 'application/xml',
'pdf' => 'application/pdf',
'doc' => 'application/msword',
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'ppt' => 'application/vnd.ms-powerpoint',
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'xls' => 'application/vnd.ms-excel',
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'swf' => 'application/x-shockwave-flash',
'vsd' => 'application/vnd.visio',
'rtf' => 'application/rtf',
'ttf' => 'font/ttf',
'woff' => 'font/woff',
'woff2' => 'font/woff2',
];
}
}

View File

@ -40,13 +40,6 @@ class ImFriendUser extends Model
*/
public $msg_count;
/**
* 屏蔽标识
*
* @var int
*/
public $blocked;
/**
* 创建时间
*

View File

@ -33,13 +33,6 @@ class ImGroupUser extends Model
*/
public $priority;
/**
* 屏蔽标识
*
* @var int
*/
public $blocked;
/**
* 创建时间
*

View File

@ -84,14 +84,14 @@ class Order extends Model
/**
* 条目信息
*
* @var string
* @var string|array
*/
public $item_info;
/**
* 优惠信息
*
* @var string
* @var string|array
*/
public $coupon_info;

View File

@ -84,6 +84,7 @@ class ImUser extends Repository
{
return ImFriendUserModel::query()
->where('user_id = :user_id:', ['user_id' => $userId])
->orderBy('update_time DESC')
->execute();
}
@ -110,7 +111,7 @@ class ImUser extends Repository
->addFrom(ImGroupModel::class, 'g')
->join(ImGroupUserModel::class, 'g.id = gu.group_id', 'gu')
->where('gu.user_id = :user_id:', ['user_id' => $userId])
->andWhere('g.deleted = 0')
->andWhere('g.published = 0')
->getQuery()->execute();
}

View File

@ -2,13 +2,29 @@
namespace App\Services\Frontend\My;
use App\Builders\ImGroupList as ImGroupListBuilder;
use App\Library\Paginator\Query as PagerQuery;
use App\Repos\ImGroup as ImGroupRepo;
use App\Services\Frontend\Service as FrontendService;
use App\Services\Frontend\User\GroupList as UserGroupListService;
class GroupList extends FrontendService
{
public function handle()
public function handle($type)
{
$result = [];
if ($type == 'joined') {
$result = $this->handleJoinedGroups();
} elseif ($type == 'owned') {
$result = $this->handleOwnedGroups();
}
return $result;
}
public function handleJoinedGroups()
{
$user = $this->getLoginUser();
@ -17,4 +33,58 @@ class GroupList extends FrontendService
return $service->handle($user->id);
}
public function handleOwnedGroups()
{
$user = $this->getLoginUser();
$pagerQuery = new PagerQuery();
$params = $pagerQuery->getParams();
$params['owner_id'] = $user->id;
$params['published'] = 1;
$sort = $pagerQuery->getSort();
$page = $pagerQuery->getPage();
$limit = $pagerQuery->getLimit();
$repo = new ImGroupRepo();
$pager = $repo->paginate($params, $sort, $page, $limit);
if ($pager->total_items == 0) {
return $pager;
}
$builder = new ImGroupListBuilder();
$groups = $pager->items->toArray();
$users = $builder->getUsers($groups);
$baseUrl = kg_ci_base_url();
$items = [];
foreach ($groups as $group) {
$group['avatar'] = $baseUrl . $group['avatar'];
$group['owner'] = $users[$group['owner_id']] ?? new \stdClass();
$items[] = [
'id' => $group['id'],
'type' => $group['type'],
'name' => $group['name'],
'avatar' => $group['avatar'],
'about' => $group['about'],
'user_count' => $group['user_count'],
'owner' => $group['owner'],
];
}
$pager->items = $items;
return $pager;
}
}

View File

@ -5,7 +5,7 @@ namespace App\Services\Frontend\My;
use App\Models\User as UserModel;
use App\Services\Frontend\Service as FrontendService;
class UserInfo extends FrontendService
class ProfileInfo extends FrontendService
{
public function handle()

View File

@ -6,7 +6,7 @@ use App\Caches\User as UserCache;
use App\Services\Frontend\Service as FrontendService;
use App\Validators\User as UserValidator;
class UserUpdate extends FrontendService
class ProfileUpdate extends FrontendService
{
public function handle()
@ -38,6 +38,10 @@ class UserUpdate extends FrontendService
$data['about'] = $validator->checkAbout($post['about']);
}
if (!empty($post['avatar'])) {
$data['avatar'] = $validator->checkAvatar($post['avatar']);
}
$user->update($data);
$this->rebuildUserCache($user->id);

View File

@ -84,7 +84,7 @@ class Vod extends Service
*
* @return string
*/
public function getUploadSignature()
public function getUploadSign()
{
$secret = $this->getSectionSettings('secret');

View File

@ -79,15 +79,4 @@ class ImFriendUser extends Validator
}
}
public function checkIfBlocked($userId, $friendId)
{
$repo = new ImFriendUserRepo();
$record = $repo->findFriendUser($friendId, $userId);
if ($record && $record->blocked == 1) {
throw new BadRequestException('im_friend_user.blocked');
}
}
}

View File

@ -59,15 +59,4 @@ class ImGroupUser extends Validator
}
}
public function checkIfBlocked($groupId, $userId)
{
$repo = new ImGroupUserRepo();
$record = $repo->findGroupUser($groupId, $userId);
if ($record && $record->blocked == 1) {
throw new BadRequestException('im_group_user.blocked');
}
}
}

View File

@ -125,6 +125,17 @@ class User extends Validator
return join('/', $area);
}
public function checkAvatar($avatar)
{
$value = $this->filter->sanitize($avatar, ['trim', 'string']);
if (!CommonValidator::url($value)) {
throw new BadRequestException('user.invalid_avatar');
}
return $value;
}
public function checkEduRole($value)
{
$list = UserModel::eduRoleTypes();

View File

@ -62,6 +62,7 @@ $error['user.sign_too_long'] = '签名过长超过50个字符';
$error['user.about_too_long'] = '简介过长超过255个字符';
$error['user.invalid_gender'] = '无效的性别类型';
$error['user.invalid_area'] = '无效的省市地区';
$error['user.invalid_avatar'] = '无效的头像';
$error['user.invalid_edu_role'] = '无效的教学角色';
$error['user.invalid_admin_role'] = '无效的后台角色';
$error['user.invalid_vip_status'] = '无效的会员状态';
@ -337,13 +338,11 @@ $error['im_group.invalid_publish_status'] = '无效的发布状态';
$error['im_group_user.not_found'] = '群组关系不存在';
$error['im_group_user.remark_too_long'] = '验证信息太长超过30字符';
$error['im_group_user.has_joined'] = '已经加入过群组';
$error['im_group_user.blocked'] = '对方拒绝接收消息';
$error['im_friend_user.not_found'] = '好友关系不存在';
$error['im_friend_user.remark_too_long'] = '验证信息太长超过30字符';
$error['im_friend_user.self_apply'] = '不能添加自己为好友';
$error['im_friend_user.has_joined'] = '已经是好友啦';
$error['im_friend_user.blocked'] = '对方拒绝接收消息';
$error['im_message.not_found'] = '消息不存在';
$error['im_message.invalid_type'] = '无效的消息类型';

View File

@ -1337,6 +1337,12 @@ body {
width: 900px;
}
.my-avatar {
width: 96px;
height: 96px;
border-radius: 100px;
}
.my-profile-card {
text-align: center;
}
@ -1345,12 +1351,6 @@ body {
margin-bottom: 10px;
}
.my-profile-card .avatar img {
width: 90px;
height: 90px;
border-radius: 100px;
}
.my-profile-card .name {
margin-bottom: 10px;
}
@ -1360,17 +1360,30 @@ body {
padding-left: 30px;
}
.my-nav-title {
font-size: 16px;
padding-bottom: 15px;
margin-bottom: 30px;
.my-nav {
line-height: 30px;
padding-bottom: 10px;
margin-bottom: 20px;
border-bottom: 1px solid #e6e6e6;
}
.my-form {
.my-nav .title {
margin-right: 20px;
font-size: 16px;
}
.my-nav a {
margin-right: 20px;
}
.profile-form {
width: 95%;
}
.wrap .layui-table {
margin-top: 0;
}
.layui-table p {
line-height: 1.8em;
}
@ -1428,11 +1441,11 @@ body {
}
.order-filter {
padding: 15px;
padding: 15px 20px;
}
.order-filter a {
margin-right: 30px;
margin-right: 20px;
}
.order-table {
@ -1460,7 +1473,7 @@ body {
}
.order-card {
padding: 15px;
padding: 15px 20px;
margin-bottom: 20px;
background-color: white;
color: #666;
@ -1479,7 +1492,7 @@ body {
.order-card .column {
float: left;
line-height: 40px;
line-height: 30px;
}
.order-card .subject {

View File

@ -94,13 +94,29 @@ layui.use(['jquery', 'layer', 'helper'], function () {
});
/**
* 群组管理
* 修改群组
*/
$('.btn-manage-group').on('click', function () {
$('.btn-edit-group').on('click', function () {
var url = $(this).data('url');
layer.open({
type: 2,
title: '群组管理',
title: '修改群组',
content: [url, 'no'],
area: ['640px', '400px'],
cancel: function () {
parent.location.reload();
}
});
});
/**
* 群组成员管理
*/
$('.btn-group-user').on('click', function () {
var url = $(this).data('url');
layer.open({
type: 2,
title: '成员管理',
maxmin: true,
resize: false,
content: [url, 'no'],

View File

@ -0,0 +1,45 @@
layui.use(['jquery', 'layer', 'upload'], function () {
var $ = layui.jquery;
var layer = layui.layer;
var upload = layui.upload;
upload.render({
elem: '#change-avatar',
url: '/upload/img/avatar',
accept: 'images',
acceptMime: 'image/*',
size: 512,
auto: false,
before: function () {
layer.load();
},
choose: function (obj) {
var flag = true;
obj.preview(function (index, file, result) {
console.log(file);
var img = new Image();
img.src = result;
img.onload = function () {
if (img.width < 1000 && img.height < 1000) {
obj.upload(index, file);
} else {
flag = false;
layer.msg("图片尺寸必须小于 1000 * 1000");
return false;
}
};
return flag;
});
},
done: function (res, index, upload) {
$('#img-avatar').attr('src', res.data.src);
$('input[name=avatar]').val(res.data.src);
layer.closeAll('loading');
},
error: function (index, upload) {
layer.msg('上传文件失败', {icon: 2});
}
});
});