回复
This commit is contained in:
parent
f855bdbb2b
commit
46304b7935
|
@ -33,7 +33,8 @@ class TopicsController extends Controller
|
|||
if (!empty($topic->slug) && $topic->slug != $request->slug) {
|
||||
return redirect($topic->link(), 301);
|
||||
}
|
||||
return view('topics.show', compact('topic'));
|
||||
$replies = $topic->replies;
|
||||
return view('topics.show', compact('topic', 'replies'));
|
||||
}
|
||||
|
||||
public function store(TopicRequest $request, Topic $topic)
|
||||
|
|
19
app/Models/Reply.php
Normal file
19
app/Models/Reply.php
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
class Reply extends Model
|
||||
{
|
||||
protected $fillable = ['content'];
|
||||
|
||||
|
||||
public function topic()
|
||||
{
|
||||
return $this->belongsTo(Topic::class);
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
|
@ -41,6 +41,12 @@ class Topic extends Model
|
|||
return $query->orderBy('created_at', 'desc');
|
||||
}
|
||||
|
||||
|
||||
public function replies()
|
||||
{
|
||||
return $this->hasMany(Reply::class);
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
|
|
|
@ -37,6 +37,11 @@ class User extends Authenticatable
|
|||
return $this->id == $model->user_id;
|
||||
}
|
||||
|
||||
public function replies()
|
||||
{
|
||||
return $this->hasMany(Reply::class, 'user_id');
|
||||
}
|
||||
|
||||
public function topics()
|
||||
{
|
||||
return $this->hasMany(Topic::class);
|
||||
|
|
21
app/Observers/ReplyObserver.php
Normal file
21
app/Observers/ReplyObserver.php
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace App\Observers;
|
||||
|
||||
use App\Models\Reply;
|
||||
|
||||
// creating, created, updating, updated, saving,
|
||||
// saved, deleting, deleted, restoring, restored
|
||||
|
||||
class ReplyObserver
|
||||
{
|
||||
public function creating(Reply $reply)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public function updating(Reply $reply)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
20
app/Policies/ReplyPolicy.php
Normal file
20
app/Policies/ReplyPolicy.php
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\Reply;
|
||||
use App\Models\User;
|
||||
|
||||
class ReplyPolicy extends Policy
|
||||
{
|
||||
public function update(User $user, Reply $reply)
|
||||
{
|
||||
// return $reply->user_id == $user->id;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function destroy(User $user, Reply $reply)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -14,6 +14,7 @@ class AuthServiceProvider extends ServiceProvider
|
|||
* @var array
|
||||
*/
|
||||
protected $policies = [
|
||||
\App\Models\Reply::class => \App\Policies\ReplyPolicy::class,
|
||||
\App\Models\Topic::class => \App\Policies\TopicPolicy::class,
|
||||
'App\Model' => 'App\Policies\ModelPolicy',
|
||||
User::class => UserPolicy::class,
|
||||
|
|
13
database/factories/ReplyFactory.php
Normal file
13
database/factories/ReplyFactory.php
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
use Faker\Generator as Faker;
|
||||
|
||||
$factory->define(App\Models\Reply::class, function (Faker $faker) {
|
||||
$time = $faker->dateTimeThisMonth();
|
||||
|
||||
return [
|
||||
'content' => $faker->sentence(),
|
||||
'created_at' => $time,
|
||||
'updated_at' => $time,
|
||||
];
|
||||
});
|
|
@ -9,7 +9,7 @@ class CreateTopicsTable extends Migration
|
|||
{
|
||||
Schema::create('topics', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->string('"title')->index();
|
||||
$table->string('title')->index();
|
||||
$table->text('body');
|
||||
$table->integer('user_id')->unsigned()->index();
|
||||
$table->integer('category_id')->unsigned()->index();
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
|
||||
class CreateRepliesTable extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::create('replies', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->integer('topic_id')->unsigned()->default(0)->index();
|
||||
$table->integer('user_id')->unsigned()->default(0)->index();
|
||||
$table->text('content');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::drop('replies');
|
||||
}
|
||||
}
|
|
@ -13,5 +13,6 @@ class DatabaseSeeder extends Seeder
|
|||
{
|
||||
$this->call(UsersTableSeeder::class);
|
||||
$this->call(TopicsTableSeeder::class);
|
||||
$this->call(ReplysTableSeeder::class);
|
||||
}
|
||||
}
|
||||
|
|
36
database/seeds/ReplysTableSeeder.php
Normal file
36
database/seeds/ReplysTableSeeder.php
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Reply;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class ReplysTableSeeder extends Seeder
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
// 所有用户 ID 数组,如:[1,2,3,4]
|
||||
$user_ids = \App\Models\User::all()->pluck('id')->toArray();
|
||||
|
||||
// 所有话题 ID 数组,如:[1,2,3,4]
|
||||
$topic_ids = \App\Models\Topic::all()->pluck('id')->toArray();
|
||||
|
||||
// 获取 Faker 实例
|
||||
$faker = app(Faker\Generator::class);
|
||||
|
||||
$replys = factory(Reply::class)
|
||||
->times(1000)
|
||||
->make()
|
||||
->each(function ($reply, $index)
|
||||
use ($user_ids, $topic_ids, $faker) {
|
||||
// 从用户 ID 数组中随机取出一个并赋值
|
||||
$reply->user_id = $faker->randomElement($user_ids);
|
||||
|
||||
// 话题 ID,同上
|
||||
$reply->topic_id = $faker->randomElement($topic_ids);
|
||||
});
|
||||
|
||||
// 将数据集合转换为数组,并插入到数据库中
|
||||
Reply::insert($replys->toArray());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -27,7 +27,6 @@ class TopicsTableSeeder extends Seeder
|
|||
// 话题分类,同上
|
||||
$topic->category_id = $faker->randomElement($category_ids);
|
||||
});
|
||||
|
||||
// 将数据集合转换为数组,并插入到数据库中
|
||||
Topic::insert($topics->toArray());
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ class UsersTableSeeder extends Seeder
|
|||
$user = \App\Models\User::find(1);
|
||||
$user->name = 'fthvgb1';
|
||||
$user->email = 'fthvgb1@163.com';
|
||||
$user->avatar = '';
|
||||
$user->password = bcrypt('123456');
|
||||
$user->save();
|
||||
|
||||
}
|
||||
|
|
29
public/css/app.css
vendored
29
public/css/app.css
vendored
|
@ -8442,16 +8442,21 @@ body {
|
|||
margin: 12px 0;
|
||||
}
|
||||
|
||||
.users-show-page .meta {
|
||||
font-size: .9em;
|
||||
color: #b3b3b3;
|
||||
}
|
||||
|
||||
.users-show-page .reply-content {
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
.users-show-page .list-group .list-group-item {
|
||||
border: none;
|
||||
margin-bottom: 0px;
|
||||
border-bottom: 1px solid #efefef;
|
||||
}
|
||||
|
||||
.users-show-page .list-group .list-group-item .meta {
|
||||
color: #b3b3b3;
|
||||
}
|
||||
|
||||
/* Topic Index Page */
|
||||
|
||||
.topics-index-page .topic-list .nav > li > a,
|
||||
|
@ -8956,3 +8961,19 @@ body {
|
|||
line-height: 38px;
|
||||
}
|
||||
|
||||
.topic-reply hr {
|
||||
margin-top: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.topic-reply a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.topic-reply .meta {
|
||||
font-size: .9em;
|
||||
color: #b3b3b3;
|
||||
}
|
||||
|
||||
/* Topic Index Page */
|
||||
|
||||
|
|
121
public/css/simditor.css
vendored
121
public/css/simditor.css
vendored
|
@ -4,6 +4,7 @@
|
|||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.simditor-icon {
|
||||
display: inline-block;
|
||||
font: normal normal normal 14px/1 'Simditor';
|
||||
|
@ -142,10 +143,12 @@
|
|||
position: relative;
|
||||
border: 1px solid #c9d8db;
|
||||
}
|
||||
|
||||
.simditor .simditor-wrapper {
|
||||
position: relative;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.simditor .simditor-wrapper > textarea {
|
||||
display: none !important;
|
||||
width: 100%;
|
||||
|
@ -160,6 +163,7 @@
|
|||
background: transparent;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.simditor .simditor-wrapper .simditor-placeholder {
|
||||
display: none;
|
||||
position: absolute;
|
||||
|
@ -172,12 +176,14 @@
|
|||
color: #999999;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.simditor .simditor-wrapper.toolbar-floating .simditor-toolbar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
box-shadow: 0 0 6px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.simditor .simditor-wrapper .simditor-image-loading {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
@ -186,6 +192,7 @@
|
|||
left: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.simditor .simditor-wrapper .simditor-image-loading .progress {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
@ -194,6 +201,7 @@
|
|||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.simditor .simditor-body {
|
||||
padding: 22px 15px 40px;
|
||||
min-height: 300px;
|
||||
|
@ -203,18 +211,23 @@
|
|||
z-index: 1;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.simditor .simditor-body a.selected {
|
||||
background: #b3d4fd;
|
||||
}
|
||||
|
||||
.simditor .simditor-body a.simditor-mention {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.simditor .simditor-body .simditor-table {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.simditor .simditor-body .simditor-table.resizing {
|
||||
cursor: col-resize;
|
||||
}
|
||||
|
||||
.simditor .simditor-body .simditor-table .simditor-resize-handle {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
|
@ -223,6 +236,7 @@
|
|||
height: 100%;
|
||||
cursor: col-resize;
|
||||
}
|
||||
|
||||
.simditor .simditor-body pre {
|
||||
/*min-height: 28px;*/
|
||||
box-sizing: border-box;
|
||||
|
@ -230,12 +244,15 @@
|
|||
word-wrap: break-word !important;
|
||||
white-space: pre-wrap !important;
|
||||
}
|
||||
|
||||
.simditor .simditor-body img {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.simditor .simditor-body img.selected {
|
||||
box-shadow: 0 0 0 4px #cccccc;
|
||||
}
|
||||
|
||||
.simditor .simditor-paste-bin {
|
||||
position: fixed;
|
||||
bottom: 10px;
|
||||
|
@ -250,21 +267,25 @@
|
|||
opacity: 0;
|
||||
-webkit-user-select: text;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar {
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
background: #ffffff;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar > ul {
|
||||
margin: 0;
|
||||
padding: 0 0 0 6px;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar > ul > li {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar > ul > li > span.separator {
|
||||
display: inline-block;
|
||||
background: #cfcfcf;
|
||||
|
@ -273,6 +294,7 @@
|
|||
margin: 11px 15px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar > ul > li > .toolbar-item {
|
||||
display: inline-block;
|
||||
width: 46px;
|
||||
|
@ -285,50 +307,63 @@
|
|||
text-align: center;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar > ul > li > .toolbar-item span {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar > ul > li > .toolbar-item span.simditor-icon {
|
||||
display: inline;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar > ul > li > .toolbar-item:hover span {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar > ul > li > .toolbar-item.active {
|
||||
background: #eeeeee;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar > ul > li > .toolbar-item.active span {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar > ul > li > .toolbar-item.disabled {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar > ul > li > .toolbar-item.disabled span {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-title span:before {
|
||||
content: "H";
|
||||
font-size: 19px;
|
||||
font-weight: bold;
|
||||
font-family: 'Times New Roman';
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-title.active-h1 span:before {
|
||||
content: 'H1';
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-title.active-h2 span:before {
|
||||
content: 'H2';
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-title.active-h3 span:before {
|
||||
content: 'H3';
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-image {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar > ul > li > .toolbar-item.toolbar-item-image > input[type=file] {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
|
@ -337,18 +372,22 @@
|
|||
font-size: 100px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar > ul > li.menu-on .toolbar-item {
|
||||
position: relative;
|
||||
z-index: 20;
|
||||
background: #ffffff;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar > ul > li.menu-on .toolbar-item span {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar > ul > li.menu-on .toolbar-menu {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu {
|
||||
display: none;
|
||||
position: absolute;
|
||||
|
@ -359,6 +398,7 @@
|
|||
text-align: left;
|
||||
box-shadow: 0 0 4px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu:before {
|
||||
content: '';
|
||||
display: block;
|
||||
|
@ -369,12 +409,14 @@
|
|||
top: -3px;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu ul {
|
||||
min-width: 160px;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 10px 1px;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item {
|
||||
display: block;
|
||||
font-size: 16px;
|
||||
|
@ -383,29 +425,36 @@
|
|||
text-decoration: none;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item:hover {
|
||||
background: #f6f6f6;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item.menu-item-h1 {
|
||||
font-size: 24px;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item.menu-item-h2 {
|
||||
font-size: 22px;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item.menu-item-h3 {
|
||||
font-size: 20px;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item.menu-item-h4 {
|
||||
font-size: 18px;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu ul > li .menu-item.menu-item-h5 {
|
||||
font-size: 16px;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu ul > li .separator {
|
||||
display: block;
|
||||
border-top: 1px solid #cccccc;
|
||||
|
@ -414,19 +463,23 @@
|
|||
font-size: 0;
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color {
|
||||
width: 96px;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list {
|
||||
height: 40px;
|
||||
margin: 10px 6px 6px 10px;
|
||||
padding: 0;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li {
|
||||
float: left;
|
||||
margin: 0 4px 4px 0;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color {
|
||||
display: block;
|
||||
width: 16px;
|
||||
|
@ -434,47 +487,60 @@
|
|||
background: #dfdfdf;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color.font-color-default {
|
||||
background: #333333;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-1 {
|
||||
background: #E33737;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-2 {
|
||||
background: #e28b41;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-3 {
|
||||
background: #c8a732;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-4 {
|
||||
background: #209361;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-5 {
|
||||
background: #418caf;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-6 {
|
||||
background: #aa8773;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-color .color-list li .font-color-7 {
|
||||
background: #999999;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-create-table {
|
||||
background: #ffffff;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-create-table table {
|
||||
border: none;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-create-table table td {
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-create-table table td:before {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
|
@ -483,19 +549,24 @@
|
|||
display: block;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-create-table table td.selected:before {
|
||||
background: #cfcfcf;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-edit-table {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-table .menu-edit-table ul li {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-image .menu-item-upload-image {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-image .menu-item-upload-image input[type=file] {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
|
@ -504,15 +575,19 @@
|
|||
font-size: 100px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-alignment {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-alignment ul {
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.simditor .simditor-toolbar .toolbar-menu.toolbar-menu-alignment .menu-item {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.simditor .simditor-popover {
|
||||
display: none;
|
||||
padding: 5px 8px 0;
|
||||
|
@ -522,31 +597,37 @@
|
|||
position: absolute;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.simditor .simditor-popover .settings-field {
|
||||
margin: 0 0 5px 0;
|
||||
font-size: 12px;
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
.simditor .simditor-popover .settings-field label {
|
||||
display: inline-block;
|
||||
margin: 0 5px 0 0;
|
||||
}
|
||||
|
||||
.simditor .simditor-popover .settings-field input[type=text] {
|
||||
display: inline-block;
|
||||
width: 200px;
|
||||
box-sizing: border-box;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.simditor .simditor-popover .settings-field input[type=text].image-size {
|
||||
width: 83px;
|
||||
}
|
||||
|
||||
.simditor .simditor-popover .settings-field .times {
|
||||
display: inline-block;
|
||||
width: 26px;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.simditor .simditor-popover.link-popover .btn-unlink, .simditor .simditor-popover.image-popover .btn-upload, .simditor .simditor-popover.image-popover .btn-restore {
|
||||
display: inline-block;
|
||||
margin: 0 0 0 5px;
|
||||
|
@ -554,18 +635,22 @@
|
|||
font-size: 14px;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.simditor .simditor-popover.link-popover .btn-unlink span, .simditor .simditor-popover.image-popover .btn-upload span, .simditor .simditor-popover.image-popover .btn-restore span {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.simditor .simditor-popover.link-popover .btn-unlink:hover span, .simditor .simditor-popover.image-popover .btn-upload:hover span, .simditor .simditor-popover.image-popover .btn-restore:hover span {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.simditor .simditor-popover.image-popover .btn-upload {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.simditor .simditor-popover.image-popover .btn-upload input[type=file] {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
|
@ -574,6 +659,7 @@
|
|||
height: 100%;
|
||||
width: 28px;
|
||||
}
|
||||
|
||||
.simditor.simditor-mobile .simditor-wrapper.toolbar-floating .simditor-toolbar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
@ -589,96 +675,123 @@
|
|||
outline: none;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.simditor .simditor-body > :first-child, .editor-style > :first-child {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
|
||||
.simditor .simditor-body a, .editor-style a {
|
||||
color: #4298BA;
|
||||
text-decoration: none;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.simditor .simditor-body a:visited, .editor-style a:visited {
|
||||
color: #4298BA;
|
||||
}
|
||||
|
||||
.simditor .simditor-body a:hover, .editor-style a:hover {
|
||||
color: #0F769F;
|
||||
}
|
||||
|
||||
.simditor .simditor-body a:active, .editor-style a:active {
|
||||
color: #9E792E;
|
||||
}
|
||||
|
||||
.simditor .simditor-body a:hover, .simditor .simditor-body a:active, .editor-style a:hover, .editor-style a:active {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.simditor .simditor-body h1, .simditor .simditor-body h2, .simditor .simditor-body h3, .simditor .simditor-body h4, .simditor .simditor-body h5, .simditor .simditor-body h6, .editor-style h1, .editor-style h2, .editor-style h3, .editor-style h4, .editor-style h5, .editor-style h6 {
|
||||
font-weight: normal;
|
||||
margin: 40px 0 20px;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.simditor .simditor-body h1, .editor-style h1 {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.simditor .simditor-body h2, .editor-style h2 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.simditor .simditor-body h3, .editor-style h3 {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.simditor .simditor-body h4, .editor-style h4 {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.simditor .simditor-body h5, .editor-style h5 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.simditor .simditor-body h6, .editor-style h6 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.simditor .simditor-body p, .simditor .simditor-body div, .editor-style p, .editor-style div {
|
||||
word-wrap: break-word;
|
||||
margin: 0 0 15px 0;
|
||||
color: #333;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.simditor .simditor-body b, .simditor .simditor-body strong, .editor-style b, .editor-style strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.simditor .simditor-body i, .simditor .simditor-body em, .editor-style i, .editor-style em {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.simditor .simditor-body u, .editor-style u {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.simditor .simditor-body strike, .simditor .simditor-body del, .editor-style strike, .editor-style del {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.simditor .simditor-body ul, .simditor .simditor-body ol, .editor-style ul, .editor-style ol {
|
||||
list-style: disc outside none;
|
||||
margin: 15px 0;
|
||||
padding: 0 0 0 40px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.simditor .simditor-body ul li, .simditor .simditor-body ol li, .editor-style ul li, .editor-style ol li {
|
||||
list-style-type: inherit;
|
||||
}
|
||||
|
||||
.simditor .simditor-body ul ul, .simditor .simditor-body ul ol, .simditor .simditor-body ol ul, .simditor .simditor-body ol ol, .editor-style ul ul, .editor-style ul ol, .editor-style ol ul, .editor-style ol ol {
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.simditor .simditor-body ul ul, .simditor .simditor-body ol ul, .editor-style ul ul, .editor-style ol ul {
|
||||
list-style: circle outside none;
|
||||
}
|
||||
|
||||
.simditor .simditor-body ul ul ul, .simditor .simditor-body ol ul ul, .editor-style ul ul ul, .editor-style ol ul ul {
|
||||
list-style: square outside none;
|
||||
}
|
||||
|
||||
.simditor .simditor-body ol, .editor-style ol {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
.simditor .simditor-body blockquote, .editor-style blockquote {
|
||||
border-left: 6px solid #ddd;
|
||||
padding: 5px 0 5px 10px;
|
||||
margin: 15px 0 15px 15px;
|
||||
}
|
||||
|
||||
.simditor .simditor-body blockquote > :first-child, .editor-style blockquote > :first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.simditor .simditor-body code, .editor-style code {
|
||||
display: inline-block;
|
||||
padding: 0 4px;
|
||||
|
@ -688,6 +801,7 @@
|
|||
font-size: 13px;
|
||||
font-family: 'monaco', 'Consolas', "Liberation Mono", Courier, monospace;
|
||||
}
|
||||
|
||||
.simditor .simditor-body pre, .editor-style pre {
|
||||
padding: 10px 5px 10px 10px;
|
||||
margin: 15px 0;
|
||||
|
@ -701,6 +815,7 @@
|
|||
word-wrap: normal;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.simditor .simditor-body pre code, .editor-style pre code {
|
||||
display: block;
|
||||
padding: 0;
|
||||
|
@ -708,6 +823,7 @@
|
|||
background: none;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.simditor .simditor-body hr, .editor-style hr {
|
||||
display: block;
|
||||
height: 0px;
|
||||
|
@ -716,6 +832,7 @@
|
|||
margin: 15px 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.simditor .simditor-body table, .editor-style table {
|
||||
width: 100%;
|
||||
table-layout: fixed;
|
||||
|
@ -723,9 +840,11 @@
|
|||
border-spacing: 0;
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.simditor .simditor-body table thead, .editor-style table thead {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
.simditor .simditor-body table td, .simditor .simditor-body table th, .editor-style table td, .editor-style table th {
|
||||
min-width: 40px;
|
||||
height: 30px;
|
||||
|
@ -735,9 +854,11 @@
|
|||
text-align: left;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.simditor .simditor-body table td.active, .simditor .simditor-body table th.active, .editor-style table td.active, .editor-style table th.active {
|
||||
background-color: #ffffee;
|
||||
}
|
||||
|
||||
.simditor .simditor-body img, .editor-style img {
|
||||
margin: 0 5px;
|
||||
vertical-align: middle;
|
||||
|
|
31
resources/assets/sass/app.scss
vendored
31
resources/assets/sass/app.scss
vendored
|
@ -94,16 +94,19 @@ body {
|
|||
.pagination {
|
||||
margin: 12px 0;
|
||||
}
|
||||
.meta {
|
||||
font-size: .9em;
|
||||
color: #b3b3b3;
|
||||
}
|
||||
.reply-content {
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
.list-group {
|
||||
.list-group-item {
|
||||
border: none;
|
||||
margin-bottom: 0px;
|
||||
border-bottom: 1px solid #efefef;
|
||||
|
||||
.meta {
|
||||
color: #b3b3b3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,4 +156,22 @@ body {
|
|||
line-height: 38px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.topic-reply {
|
||||
hr {
|
||||
margin-top: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.meta {
|
||||
font-size: .9em;
|
||||
color: #b3b3b3;
|
||||
}
|
||||
}
|
||||
|
||||
/* Topic Index Page */
|
0
resources/views/topics/_reply_box.blade.php
Normal file
0
resources/views/topics/_reply_box.blade.php
Normal file
33
resources/views/topics/_reply_list.blade.php
Normal file
33
resources/views/topics/_reply_list.blade.php
Normal file
|
@ -0,0 +1,33 @@
|
|||
<div class="reply-list">
|
||||
@foreach ($replies as $index => $reply)
|
||||
<div class=" media" name="reply{{ $reply->id }}" id="reply{{ $reply->id }}">
|
||||
<div class="avatar pull-left">
|
||||
<a href="{{ route('users.show', [$reply->user_id]) }}">
|
||||
<img class="media-object img-thumbnail" alt="{{ $reply->user->name }}"
|
||||
src="{{ $reply->user->avatar }}" style="width:48px;height:48px;"/>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="infos">
|
||||
<div class="media-heading">
|
||||
<a href="{{ route('users.show', [$reply->user_id]) }}" title="{{ $reply->user->name }}">
|
||||
{{ $reply->user->name }}
|
||||
</a>
|
||||
<span> • </span>
|
||||
<span class="meta" title="{{ $reply->created_at }}">{{ $reply->created_at->diffForHumans() }}</span>
|
||||
|
||||
{{-- 回复删除按钮 --}}
|
||||
<span class="meta pull-right">
|
||||
<a title="删除回复">
|
||||
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="reply-content">
|
||||
{!! $reply->content !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
@endforeach
|
||||
</div>
|
|
@ -63,6 +63,14 @@
|
|||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- 用户回复列表 --}}
|
||||
<div class="panel panel-default topic-reply">
|
||||
<div class="panel-body">
|
||||
@include('topics._reply_box', ['topic' => $topic])
|
||||
@include('topics._reply_list', ['replies' => $topic->replies()->with('user')->get()])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
27
resources/views/users/_replies.blade.php
Normal file
27
resources/views/users/_replies.blade.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
@if (count($replies))
|
||||
|
||||
<ul class="list-group">
|
||||
@foreach ($replies as $reply)
|
||||
<li class="list-group-item">
|
||||
<a href="{{ $reply->topic->link(['#reply' . $reply->id]) }}">
|
||||
{{ $reply->topic->title }}
|
||||
</a>
|
||||
|
||||
<div class="reply-content" style="margin: 6px 0;">
|
||||
{!! $reply->content !!}
|
||||
</div>
|
||||
|
||||
<div class="meta">
|
||||
<span class="glyphicon glyphicon-time" aria-hidden="true"></span>
|
||||
回复于 {{ $reply->created_at->diffForHumans() }}
|
||||
</div>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
|
||||
@else
|
||||
<div class="empty-block">暂无数据 ~_~</div>
|
||||
@endif
|
||||
|
||||
{{-- 分页 --}}
|
||||
{!! $replies->appends(Request::except('page'))->render() !!}
|
|
@ -39,10 +39,19 @@
|
|||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active"><a href="#">Ta 的话题</a></li>
|
||||
<li><a href="#">Ta 的回复</a></li>
|
||||
<li class="{{ active_class(if_query('tab', null)) }}">
|
||||
<a href="{{ route('users.show', $user->id) }}">Ta 的话题</a>
|
||||
</li>
|
||||
<li class="{{ active_class(if_query('tab', 'replies')) }}">
|
||||
<a href="{{ route('users.show', [$user->id, 'tab' => 'replies']) }}">Ta 的回复</a>
|
||||
</li>
|
||||
</ul>
|
||||
@include('users._topics', ['topics' => $user->topics()->recent()->paginate(5)])
|
||||
@if(if_query('tab','replies'))
|
||||
@include('users._replies', ['replies' => $user->replies()->recent()->paginate(5)])
|
||||
@else
|
||||
@include('users._topics', ['topics' => $user->topics()->recent()->paginate(5)])
|
||||
@endif
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -37,3 +37,5 @@ Route::get('topics/{topic}/{slug?}', 'TopicsController@show')->name('topics.show
|
|||
Route::resource('categories', 'CategoriesController', ['only' => ['show']]);
|
||||
Route::post('upload_image', 'TopicsController@uploadImage')->name('topics.upload_image');
|
||||
|
||||
|
||||
Route::resource('replies', 'RepliesController', ['only' => ['index', 'show', 'create', 'store', 'update', 'edit', 'destroy']]);
|
Loading…
Reference in New Issue
Block a user