创建版本

This commit is contained in:
2021-02-22 12:17:00 +08:00
commit af555f49c3
2332 changed files with 369202 additions and 0 deletions
@@ -0,0 +1,202 @@
<?php namespace Gdoo\Article\Controllers;
use Arr;
use DB;
use Auth;
use Request;
use Validator;
use Gdoo\Model\Form;
use Gdoo\Model\Grid;
use Gdoo\User\Models\User;
use Gdoo\User\Models\Role;
use Gdoo\Article\Models\Article;
use Gdoo\Index\Services\AttachmentService;
use Gdoo\Index\Controllers\DefaultController;
use Gdoo\User\Models\Department;
use Gdoo\User\Services\UserService;
class ArticleController extends DefaultController
{
public $permission = [];
public function indexAction()
{
$header = Grid::header([
'code' => 'article',
'referer' => 1,
'search' => ['by' => '', 'tab' => 'all'],
]);
$cols = $header['cols'];
$cols['actions']['options'] = [[
'name' => '显示',
'action' => 'show',
'display' => $this->access['show'],
],[
'name' => '编辑',
'action' => 'edit',
'display' => $this->access['edit'],
]];
$search = $header['search_form'];
$query = $search['query'];
if (Request::method() == 'POST') {
$model = DB::table($header['table'])->setBy($header);
foreach ($header['join'] as $join) {
$model->leftJoin($join[0], $join[1], $join[2], $join[3]);
}
$model->orderBy($header['sort'], $header['order']);
foreach ($search['where'] as $where) {
if ($where['active']) {
$model->search($where);
}
}
if ($this->access['index'] < 4) {
// 这里需要包括创建者权限
$model->permission('receive_id', null, false, true, false, 'created_id');
}
// 查询是否已经阅读
$reader = function ($q) {
$q->selectRaw('1')
->from('article_reader')
->whereRaw('article_reader.article_id = article.id')
->where('article_reader.created_id', auth()->id());
};
if ($query['tab'] == 'done') {
$model->whereExists($reader);
}
if ($query['tab'] == 'unread') {
$model->whereNotExists($reader);
}
$model->select($header['select']);
$rows = $model->paginate($query['limit'])->appends($query);
$items = Grid::dataFilters($rows, $header, function($item) {
return $item;
});
return $items->toJson();
}
$header['buttons'] = [
['name' => '删除', 'icon' => 'fa-remove', 'action' => 'delete', 'display' => $this->access['delete']],
['name' => '导出', 'icon' => 'fa-share', 'action' => 'export', 'display' => 1],
];
$header['cols'] = $cols;
$header['tabs'] = Article::$tabs;
$header['bys'] = Article::$bys;
$header['js'] = Grid::js($header);
return $this->display([
'header' => $header,
]);
}
// 新建客户联系人
public function createAction()
{
$id = (int)Request::get('id');
$form = Form::make(['code' => 'article', 'id' => $id]);
return $this->display([
'form' => $form,
], 'create');
}
// 创建客户联系人
public function editAction()
{
return $this->createAction();
}
public function showAction()
{
$id = (int)Request::get('id');
$res = Article::withAt('user', ['id','username','name'])
->where('id', $id)->first();
// 发布人
$from = DB::table('user')->where('id', $res['created_id'])->first();
// 附件
$attachment = AttachmentService::show($res['attachment']);
// 已读记录
$reads = DB::table('article_reader')->where('article_id', $id)->get();
$reads = array_by($reads, 'created_id');
// 更新阅读记录
if (empty($reads[Auth::id()])) {
DB::table('article_reader')->insert([
'article_id' => $id,
]);
}
// 返回json
if (Request::wantsJson()) {
return $res->toJson();
}
$form = Form::make(['code' => 'article', 'id' => $id, 'action' => 'show']);
return $this->display([
'attachment' => $attachment,
'res' => $res,
'from' => $from,
'form' => $form,
]);
}
/**
* 阅读记录
*/
public function readerAction()
{
$id = Request::get('id', 0);
// 取得当前项目阅读情况
$reads = DB::table('article_reader')->where('article_id', $id)->get();
$reads = array_by($reads, 'created_id');
$row = DB::table('article')->where('id', $id)->first();
$scopes = UserService::getDRU($row['receive_id']);
if ($scopes->count()) {
$rows = [];
$departments = Department::orderBy('lft', 'asc')->pluck('name', 'id');
foreach ($scopes as $scope) {
$read = isset($reads[$scope['id']]) ? 1 : 0;
$rows['total'][$read]++;
$rows['data'][] = [
'read' => $read,
'department_id' => $scope['department_id'],
'department' => $departments[$scope['department_id']],
'name' => $scope['name'],
'created_at' => $reads[$scope['id']]['created_at'],
];
}
$rows['data'] = Arr::sort($rows['data'], function ($value) {
return $value['created_at'];
});
}
return $this->render([
'rows' => $rows,
]);
}
public function deleteAction()
{
if (Request::method() == 'POST') {
$ids = Request::get('id');
return Form::remove(['code' => 'article', 'ids' => $ids]);
}
}
}
@@ -0,0 +1,82 @@
<?php namespace Gdoo\Article\Controllers;
use DB;
use Auth;
use Request;
use Gdoo\Index\Controllers\DefaultController;
use Gdoo\Index\Services\InfoService;
use Gdoo\User\Models\UserWidget;
class WidgetController extends DefaultController
{
public $permission = ['index', 'info'];
/**
* 公告部件
*/
public function indexAction()
{
if (Request::isJson()) {
$model = DB::table('article')
->permission('receive_id')
->orderBy('created_at', 'desc');
// 查询是否已经阅读
$reader = function ($q) {
$q->selectRaw('1')
->from('article_reader')
->whereRaw('article_reader.article_id = article.id')
->where('article_reader.created_id', auth()->id());
};
$model->whereNotExists($reader);
$rows = $model->get(['id', 'title', 'created_at']);
$json['total'] = sizeof($rows);
$json['data'] = $rows;
return response()->json($json);
}
return $this->render();
}
/**
* 公告信息
*/
public function infoAction()
{
$config = InfoService::getInfo('article');
$count = DB::table('article')
->permission('receive_id')
->whereNotExists(function ($q) {
$q->selectRaw('1')
->from('article_reader')
->whereRaw('article_reader.article_id = article.id')
->where('article_reader.created_id', auth()->id());
})->whereRaw('('.$config['sql'].')')->count();
$count2 = DB::table('article')
->permission('receive_id')
->whereNotExists(function ($q) {
$q->selectRaw('1')
->from('article_reader')
->whereRaw('article_reader.article_id = article.id')
->where('article_reader.created_id', auth()->id());
})->whereRaw('('.$config['sql2'].')')->count();
$rate = 0;
if ($count2 > 0) {
$rate = $count / $count2 * 100;
}
$res = [
'count' => $count,
'count2' => $count2,
'rate' => $rate,
];
return $this->render([
'dates' => $config['dates'],
'info' => $config['info'],
'res' => $res,
]);
}
}
+41
View File
@@ -0,0 +1,41 @@
<?php namespace Gdoo\Article\Hooks;
use DB;
use Gdoo\Index\Services\AttachmentService;
class ArticleHook
{
public function onBeforeForm($params) {
return $params;
}
public function onAfterForm($params) {
return $params;
}
public function onBeforeStore($params)
{
return $params;
}
public function onAfterStore($params) {
return $params;
}
public function onBeforeDelete($params) {
$ids = $params['ids'];
$masters = $params['masters'];
// 新删除附件
foreach($masters as $master) {
AttachmentService::remove($master['attachment']);
}
// 删除阅读积累
DB::table('article_reader')->whereIn('article_id', $ids)->delete();
return $params;
}
public function onBeforeImport($params)
{
return $params;
}
}
+38
View File
@@ -0,0 +1,38 @@
<?php namespace Gdoo\Article\Models;
use Gdoo\Index\Models\BaseModel;
class Article extends BaseModel
{
protected $table = 'article';
public static $tabs = [
'name' => 'tab',
'items' => [
['url' => 'article/article/index', 'name' => '未读', 'value' => 'unread'],
['url' => 'article/article/index', 'name' => '已读', 'value' => 'done'],
['url' => 'article/article/index', 'name' => '全部', 'value' => 'all'],
]
];
public static $bys = [
'name' => 'by',
'items' => [
['value' => '', 'name' => '全部'],
['value' => 'divider'],
['value' => 'day', 'name' => '今日创建'],
['value' => 'week', 'name' => '本周创建'],
['value' => 'month', 'name' => '本月创建'],
]
];
public function user()
{
return $this->belongsTo('Gdoo\User\Models\User', 'created_id');
}
public function category()
{
return $this->belongsTo('Gdoo\Article\Models\ArticleCategory');
}
}
@@ -0,0 +1,8 @@
<?php namespace Gdoo\Article\Models;
use Gdoo\Index\Models\BaseModel;
class ArticleCategory extends BaseModel
{
protected $table = 'article_category';
}
@@ -0,0 +1,24 @@
<?php namespace Gdoo\Article\Services;
use DB;
class ArticleService
{
/**
* 获取未读公告
*/
public static function getBadge()
{
$rows = DB::table('article')
->permission('receive_id')
->whereNotExists(function ($q) {
$q->selectRaw('1')
->from('article_reader')
->whereRaw('article_reader.article_id = article.id')
->where('article_reader.created_id', auth()->id());
})->get();
$ret['total'] = sizeof($rows);
$ret['data'] = $rows;
return $ret;
}
}
+55
View File
@@ -0,0 +1,55 @@
<?php
return [
"name" => "公告",
"version" => "1.0",
"description" => "公告。",
"listens" => [
'article' => 'Gdoo\Article\Hooks\ArticleHook',
],
'widgets' => [
'widget_article_index' => [
'name' => '最新公告',
'type' => 1,
'url' => 'article/widget/index',
'more_url' => 'article/article/index',
],
'info_article_index' => [
'name' => '新增公告',
'type' => 2,
'url' => 'article/widget/info',
'more_url' => 'article/article/index',
],
],
'badges' => [
'article_article_index' => 'Gdoo\Article\Services\ArticleService::getBadge',
],
'menus' => [
['name' => '资讯', 'id' => 'article'],
['name' => '公告列表', 'id' => 'article_article_index', 'parent' => 'article', 'url' => 'article/article/index', 'badge' => 'article_article_index'],
],
"controllers" => [
"article" => [
"name" => "公告",
"actions" => [
"index" => [
"name" => "列表"
],
"create" => [
"name" => "新建"
],
"edit" => [
"name" => "编辑"
],
"show" => [
"name" => "查看"
],
"reader" => [
"name" => "阅读记录"
],
"delete" => [
"name" => "删除"
]
]
]
]
];
@@ -0,0 +1,16 @@
<div class="form-panel">
<div class="form-panel-header">
<div class="pull-right">
</div>
{{$form['btn']}}
</div>
<div class="form-panel-body">
<form class="form-horizontal form-controller" method="post" id="{{$form['table']}}" name="{{$form['table']}}">
{{$form['tpl']}}
</form>
</div>
</div>
<script>
var table = '{{$form["table"]}}';
</script>
@@ -0,0 +1,59 @@
{{$header["js"]}}
<div class="panel no-border" id="{{$header['master_table']}}-controller">
@include('headers')
<div class='list-jqgrid'>
<div id="{{$header['master_table']}}-grid" style="width:100%;" class="ag-theme-balham"></div>
</div>
</div>
<script>
(function ($) {
var table = '{{$header["master_table"]}}';
var config = gdoo.grids[table];
var action = config.action;
var search = config.search;
action.dialogType = 'layer';
// 自定义搜索方法
search.searchInit = function (e) {
var self = this;
}
var options = new agGridOptions();
var gridDiv = document.querySelector("#{{$header['master_table']}}-grid");
gridDiv.style.height = getPanelHeight(48);
options.remoteDataUrl = '{{url()}}';
options.remoteParams = search.advanced.query;
options.columnDefs = config.cols;
options.onRowDoubleClicked = function (params) {
if (params.node.rowPinned) {
return;
}
if (params.data == undefined) {
return;
}
if (params.data.master_id > 0) {
action.show(params.data);
}
};
new agGrid.Grid(gridDiv, options);
// 读取数据
options.remoteData({page: 1});
// 绑定自定义事件
var $gridDiv = $(gridDiv);
$gridDiv.on('click', '[data-toggle="event"]', function () {
var data = $(this).data();
if (data.master_id > 0) {
action[data.action](data);
}
});
config.grid = options;
})(jQuery);
</script>
@include('footers')
@@ -0,0 +1,23 @@
<form id="search-form" class="form-inline" name="mysearch" action="{{url()}}" method="get">
<div class="pull-right">
@if(isset($access['delete']))
<a class="btn btn-sm btn-danger" href="javascript:optionDelete('#myform','{{url('delete')}}');"><i class="icon icon-remove"></i> 删除</a>
@endif
</div>
@if(isset($access['create']))
<a href="{{url('create')}}" class="btn btn-sm btn-info"><i class="icon icon-plus"></i> 新建</a>
@endif
@include('searchForm')
</form>
<script type="text/javascript">
$(function() {
$('#search-form').searchForm({
data: {{json_encode($search['forms'])}},
init: function(e) {
var self = this;
}
});
});
</script>
@@ -0,0 +1,43 @@
<table class="table m-b-none">
<thead>
<tr>
<th align="left" colspan="4">
已读 <span class="badge bg-info">{{(int)$rows['total'][1]}}</span>
&nbsp;&nbsp;
未读 <span class="badge">{{(int)$rows['total'][0]}}</span>
</th>
</tr>
<tr>
<th align="center">
序号
</th>
<th align="left">
阅读人
</th>
<th align="center">
部门
</th>
<th align="center">
阅读时间
</th>
</tr>
</thead>
@if($rows['data'])
@foreach($rows['data'] as $row)
<tr>
<td align="center">
{{$loop->index + 1}}
</td>
<td align="left">
{{$row['name']}}
</td>
<td align="center">
{{$row['department']}}
</td>
<td align="center">
@datetime($row['created_at'])
</td>
</tr>
@endforeach
@endif
</table>
@@ -0,0 +1,38 @@
<style>
.content-body {
margin: 0;
}
</style>
<div class="form-panel">
<div class="form-panel-header">
<div class="pull-right"></div>
{{$form['btn']}}
@if(isset($access['reader']))
<button type="button" onclick="viewBox('reader', '阅读记录', '{{url('reader',['id' => $res['id']])}}')" class="btn btn-sm btn-default"><i class="icon icon-eye-open"></i> 阅读记录</button>
@endif
</div>
<div class="form-panel-body">
<div class="wrapper-sm">
<div class="panel">
<div class="panel-heading b-b b-light text-center">
<h3 class="m-xs m-l-none">
{{$res['title']}}
</h3>
<small class="text-muted">
发布人: {{get_user($res['created_id'], 'name')}}
&nbsp;
发布时间: @datetime($res['created_at'])
</small>
</div>
<div class="panel-body text-base">
{{$res['content']}}
</div>
<div class="wrapper-sm">
@include('attachment/view')
</div>
</div>
</div>
</div>
</div>
@@ -0,0 +1,32 @@
<table id="widget-article-index">
<thead>
<tr>
<th data-field="title" data-formatter="titleFormatter" data-align="left">标题</th>
<th data-field="created_at" data-width="200" data-formatter="datetimeFormatter" data-sortable="true" data-align="center">发布时间</th>
</tr>
</thead>
</table>
<script>
function datetimeFormatter(value, row) {
return format_datetime(value);
}
function titleFormatter(value, row) {
return '<a href="'+app.url('article/article/view', {id: row.id})+'">' + value + '</a>';
}
(function($) {
var $table = $('#widget-article-index');
$table.bootstrapTable({
sidePagination: 'server',
showColumns: false,
showHeader: false,
height: 200,
pagination: false,
url: '{{url("article/widget/index")}}',
});
})(jQuery);
</script>
@@ -0,0 +1,15 @@
<div class="panel panel-shadow info-skin1">
<div class="info-l hidden-xs" style="background-color:{{$info['color']}}">
<i class="fa fa-2x {{$info['icon']}}"></i>
</div>
<div class="info-c">
<div class="info-name">{{$info['name']}}</div>
<a href="javascript:;" data-toggle="addtab" data-url="{{$info['more_url']}}" data-id="{{str_replace(['/', '?', '='], ['_', '_', '_'], $info['more_url'])}}" data-name="{{$info['name']}}">
<div class="text-info info-item" data-id="{{$info['id']}}" data-more_url="{{$info['more_url']}}">{{$res['count']}}</div>
</a>
</div>
<div class="info-r">
<div>{{$dates[$info['params']['date']]}}</div>
<div class="rate @if($res['rate'] > 100) red @endif">{{$res['rate']}}%</div>
</div>
</div>