You've already forked guangan
1
This commit is contained in:
41
plugs/think-plugs-ticket/composer.json
Normal file
41
plugs/think-plugs-ticket/composer.json
Normal file
@ -0,0 +1,41 @@
|
||||
{
|
||||
"type": "think-admin-plugin",
|
||||
"name": "jerryyan/think-plugs-ticket",
|
||||
"license": "WTFPL",
|
||||
"homepage": "https://thinkadmin.top",
|
||||
"description": "Ticket Plugin for ThinkAdmin",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jerry Yan",
|
||||
"email": "jerryyan0912@qq.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">7.1"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"plugin\\ticket\\": "src"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"config": {
|
||||
"type": "module",
|
||||
"name": "工单管理",
|
||||
"document": "https://thinkadmin.top/plugin/think-plugs-wechat.html",
|
||||
"description": "工单管理"
|
||||
},
|
||||
"think": {
|
||||
"services": [
|
||||
"plugin\\ticket\\Service"
|
||||
]
|
||||
}
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"config": {
|
||||
"sort-packages": true,
|
||||
"allow-plugins": {
|
||||
"zoujingli/think-install": true
|
||||
}
|
||||
}
|
||||
}
|
30
plugs/think-plugs-ticket/src/Service.php
Normal file
30
plugs/think-plugs-ticket/src/Service.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace plugin\ticket;
|
||||
|
||||
use think\admin\Plugin;
|
||||
|
||||
class Service extends Plugin
|
||||
{
|
||||
protected $appName = '工单管理';
|
||||
protected $appCode = 'ticket';
|
||||
protected $package = 'jerryyan/think-plugs-ticket';
|
||||
|
||||
public static function register(): void
|
||||
{
|
||||
}
|
||||
|
||||
public static function menu(): array
|
||||
{
|
||||
$code = app(static::class)->appCode;
|
||||
return [
|
||||
[
|
||||
'name' => '工单管理',
|
||||
'subs' => [
|
||||
['name' => '工单列表', 'icon' => 'layui-icon layui-icon-template-1', 'node' => "{$code}/ticket/index"],
|
||||
['name' => '工单分类', 'icon' => 'layui-icon layui-icon-template-1', 'node' => "{$code}/type/index"],
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
130
plugs/think-plugs-ticket/src/controller/Ticket.php
Normal file
130
plugs/think-plugs-ticket/src/controller/Ticket.php
Normal file
@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
namespace plugin\ticket\controller;
|
||||
|
||||
use plugin\ticket\model\TicketReply;
|
||||
use plugin\ticket\model\TicketTicket;
|
||||
use plugin\ticket\model\TicketType;
|
||||
use think\admin\Controller;
|
||||
use think\admin\helper\QueryHelper;
|
||||
|
||||
/**
|
||||
* 工单管理
|
||||
*/
|
||||
class Ticket extends Controller
|
||||
{
|
||||
/**
|
||||
* 工单列表
|
||||
* @auth true
|
||||
* @menu true
|
||||
* @return void
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->title = '工单中心';
|
||||
$this->type_list = TicketType::getList();
|
||||
$this->user_id = $this->request->session('user')['id'];
|
||||
TicketTicket::mQuery()->layTable(function () {
|
||||
|
||||
}, function (QueryHelper $query) {
|
||||
$query->like(['title|content|contact_name|ticket_address|contact_phone#keyword'])
|
||||
->dateBetween(['create_at', 'last_activity_at'])
|
||||
->equal(['status', 'type_id']);
|
||||
$query->with(['user'])->append(['imgs_arr', 'status_text', 'type_name', 'last_reply']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加工单
|
||||
* @auth true
|
||||
* @menu true
|
||||
* @return void
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$this->title = '添加工单';
|
||||
$this->types = TicketType::mk()->scope('active')->select();
|
||||
TicketTicket::mForm('form');
|
||||
}
|
||||
|
||||
public function _form_filter(&$data)
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$data['uid'] = 0;
|
||||
}
|
||||
$data['status'] = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看工单
|
||||
* @auth true
|
||||
* @menu true
|
||||
* @return void
|
||||
*/
|
||||
public function detail()
|
||||
{
|
||||
$this->title = '工单详情';
|
||||
['id' => $id] = $this->_vali(['id.require' => '请指定工单ID!']);
|
||||
$this->vo = TicketTicket::mk()->with(['user', 'type', 'reply'])->append(['imgs_arr', 'status_text', 'type_name', 'last_reply'])->find($id);
|
||||
$this->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑工单
|
||||
* @auth true
|
||||
* @menu true
|
||||
* @return void
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
$this->title = '编辑工单';
|
||||
$this->types = TicketType::mk()->scope('active')->select();
|
||||
TicketTicket::mForm('form');
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除工单
|
||||
* @auth true
|
||||
* @menu true
|
||||
* @return void
|
||||
*/
|
||||
public function remove()
|
||||
{
|
||||
TicketTicket::mDelete();
|
||||
}
|
||||
|
||||
public function reply()
|
||||
{
|
||||
$this->title = '回复工单';
|
||||
[
|
||||
'ticket_id'=>$ticket_id,
|
||||
'id'=>$id
|
||||
] = $this->_vali([
|
||||
'ticket_id.require'=>'请指定工单ID!',
|
||||
'id.require'=>'请指定回复ID!'
|
||||
]);
|
||||
$this->vo = TicketTicket::mk()->with(['user', 'type'])->append(['imgs_arr', 'status_text', 'type_name'])->find($ticket_id);
|
||||
TicketReply::mForm('reply');
|
||||
}
|
||||
|
||||
public function _reply_form_filter(&$data)
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$this->_applyFormToken();
|
||||
$data['type'] = 1;
|
||||
$adminInfo = $this->request->session('user');
|
||||
$data['user_id'] = $adminInfo['id'];
|
||||
$data['username'] = $adminInfo['nickname'];
|
||||
$data['contact'] = $adminInfo['contact_phone'];
|
||||
}
|
||||
}
|
||||
}
|
90
plugs/think-plugs-ticket/src/controller/Type.php
Normal file
90
plugs/think-plugs-ticket/src/controller/Type.php
Normal file
@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace plugin\ticket\controller;
|
||||
|
||||
use plugin\ticket\model\TicketTicket;
|
||||
use plugin\ticket\model\TicketType;
|
||||
use think\admin\Controller;
|
||||
use think\admin\helper\QueryHelper;
|
||||
|
||||
/**
|
||||
* 工单类型管理
|
||||
*/
|
||||
class Type extends Controller
|
||||
{
|
||||
/**
|
||||
* 工单类型列表
|
||||
* @return void
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$this->title = '工单类型';
|
||||
TicketType::mQuery()->layTable(function () {
|
||||
|
||||
}, function (QueryHelper $query) {
|
||||
$query->withCount(['tickets']);
|
||||
$query->like(['name'])->equal(['status']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加工单类型
|
||||
* @return void
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
TicketType::mForm('form');
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑工单类型
|
||||
* @return void
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
TicketType::mForm('form');
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改工单类型状态
|
||||
* @return void
|
||||
*/
|
||||
public function status()
|
||||
{
|
||||
TicketType::mSave($this->_vali([
|
||||
'id.require' => '类型ID不能为空',
|
||||
'status.in:0,1' => '状态值范围异常!',
|
||||
'status.require' => '状态值不能为空!',
|
||||
]), 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改工单类型排序
|
||||
* @return void
|
||||
*/
|
||||
public function sort()
|
||||
{
|
||||
TicketType::mSave($this->_vali([
|
||||
'id.require' => '文章ID不能为空',
|
||||
'sort.require' => '排序值不能为空!',
|
||||
'sort.number' => '排序必须为数字!',
|
||||
'sort.between:0,9999' => '排序值必须为0~9999之间!',
|
||||
]), 'id');
|
||||
}
|
||||
/**
|
||||
* 删除工单类型
|
||||
* @return void
|
||||
*/
|
||||
public function remove()
|
||||
{
|
||||
['id' => $id] = $this->_vali(['id.require' => '请指定工单类型ID!']);
|
||||
$count = TicketTicket::mk()->scope('avail')->where('type_id', '=', $id)->count();
|
||||
if ($count > 0) {
|
||||
$this->error('工单类型删除失败,请先删除该类型下的工单!');
|
||||
}
|
||||
TicketType::mDelete();
|
||||
}
|
||||
}
|
31
plugs/think-plugs-ticket/src/model/TicketReply.php
Normal file
31
plugs/think-plugs-ticket/src/model/TicketReply.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace plugin\ticket\model;
|
||||
|
||||
use think\admin\Model;
|
||||
use think\admin\model\SystemUser;
|
||||
|
||||
class TicketReply extends Model
|
||||
{
|
||||
protected $append = ['type_name'];
|
||||
public function ticket()
|
||||
{
|
||||
return $this->belongsTo(TicketTicket::class, 'ticket_id');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(SystemUser::class, 'user_id');
|
||||
}
|
||||
|
||||
public function getTypeNameAttr($value, $data)
|
||||
{
|
||||
switch ($data['type']) {
|
||||
case 0: return '流转';
|
||||
case 1: return '回复';
|
||||
case 9: return '退回';
|
||||
default: return '其他';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
68
plugs/think-plugs-ticket/src/model/TicketTicket.php
Normal file
68
plugs/think-plugs-ticket/src/model/TicketTicket.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace plugin\ticket\model;
|
||||
|
||||
use plugin\account\model\PluginAccountBind;
|
||||
use think\admin\Model;
|
||||
|
||||
class TicketTicket extends Model
|
||||
{
|
||||
protected $append = ['status_text', 'type_name'];
|
||||
public function type()
|
||||
{
|
||||
return $this->belongsTo(TicketType::class, 'type_id');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(PluginAccountBind::class, 'uid');
|
||||
}
|
||||
|
||||
public function reply()
|
||||
{
|
||||
return $this->hasMany(TicketReply::class, 'ticket_id')->order("create_at", 'asc');
|
||||
}
|
||||
|
||||
public function getImgsArrAttr($value, $data)
|
||||
{
|
||||
return str2arr($data['imgs'] ?: '', '|');
|
||||
}
|
||||
|
||||
public function getLastReplyAttr($value, $data)
|
||||
{
|
||||
return $this->reply()->order('create_at', 'desc')->find();
|
||||
}
|
||||
|
||||
public function getTypeNameAttr($value, $data)
|
||||
{
|
||||
$type = $this->type()->find();
|
||||
if (!empty($type)) {
|
||||
return $type['name'];
|
||||
} else {
|
||||
return '未知';
|
||||
}
|
||||
}
|
||||
|
||||
public function getStatusTextAttr($value, $data)
|
||||
{
|
||||
if (!empty($this->getStatusList()[$data['status']])) {
|
||||
return $this->getStatusList()[$data['status']];
|
||||
} else {
|
||||
return '未知';
|
||||
}
|
||||
}
|
||||
|
||||
private function getStatusList()
|
||||
{
|
||||
return [
|
||||
-1 => '已关闭',
|
||||
0 => '待处理',
|
||||
1 => '已作处理',
|
||||
];
|
||||
}
|
||||
|
||||
public function scopeAvail($query)
|
||||
{
|
||||
return $query->where('status', '>=', '0');
|
||||
}
|
||||
}
|
23
plugs/think-plugs-ticket/src/model/TicketType.php
Normal file
23
plugs/think-plugs-ticket/src/model/TicketType.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace plugin\ticket\model;
|
||||
|
||||
use think\admin\Model;
|
||||
|
||||
class TicketType extends Model
|
||||
{
|
||||
public static function getList()
|
||||
{
|
||||
return self::mk()->scope('active')->order('sort', 'asc')->field('name, id')->select();
|
||||
}
|
||||
public function tickets()
|
||||
{
|
||||
return $this->hasMany(TicketTicket::class, 'type_id');
|
||||
}
|
||||
|
||||
public function scopeActive($query)
|
||||
{
|
||||
return $query->where('status', '=', '1');
|
||||
}
|
||||
|
||||
}
|
11
plugs/think-plugs-ticket/src/view/main.html
Normal file
11
plugs/think-plugs-ticket/src/view/main.html
Normal file
@ -0,0 +1,11 @@
|
||||
<div class="layui-card layui-bg-gray">
|
||||
{block name='style'}{/block}
|
||||
{notempty name='title'}
|
||||
<div class="layui-card-header notselect">
|
||||
<span class="layui-icon layui-icon-next font-s10 color-desc margin-right-5"></span>{$title|default=''}
|
||||
<div class="pull-right">{block name='button'}{/block}</div>
|
||||
</div>
|
||||
{/notempty}
|
||||
<div class="layui-card-body">{block name='content'}{/block}</div>
|
||||
{block name='script'}{/block}
|
||||
</div>
|
23
plugs/think-plugs-ticket/src/view/table.html
Normal file
23
plugs/think-plugs-ticket/src/view/table.html
Normal file
@ -0,0 +1,23 @@
|
||||
<div class="layui-card">
|
||||
{block name='style'}{/block}
|
||||
{block name='header'}
|
||||
{notempty name='title'}
|
||||
<div class="layui-card-header">
|
||||
<span class="layui-icon font-s10 color-desc ta-mr-5"></span>{$title|lang}
|
||||
<div class="pull-right">{block name='button'}{/block}</div>
|
||||
</div>
|
||||
{/notempty}
|
||||
{/block}
|
||||
<div class="layui-card-line"></div>
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-card-table">
|
||||
{notempty name='showErrorMessage'}
|
||||
<div class="think-box-notify" type="error">
|
||||
<b>系统提示:</b><span>{$showErrorMessage|raw}</span>
|
||||
</div>
|
||||
{/notempty}
|
||||
{block name='content'}{/block}
|
||||
</div>
|
||||
</div>
|
||||
{block name='script'}{/block}
|
||||
</div>
|
65
plugs/think-plugs-ticket/src/view/ticket/detail.html
Normal file
65
plugs/think-plugs-ticket/src/view/ticket/detail.html
Normal file
@ -0,0 +1,65 @@
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">工单内容</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-row">
|
||||
工单编号:{$vo.id|default=""}
|
||||
</div>
|
||||
<div class="layui-row">
|
||||
工单标题:{$vo.title|default=""}
|
||||
</div>
|
||||
<div class="layui-row">
|
||||
反馈人信息:{$vo.contact_name|default="未填写名称"},
|
||||
联系方式:{$vo.contact_phone|default="未填写联系方式"},
|
||||
联系地址:{$vo.contact_address|default="未填写地址"}
|
||||
</div>
|
||||
<div class="layui-row">
|
||||
工单类型:{$vo.type_name|default=""}
|
||||
</div>
|
||||
<div class="layui-row">
|
||||
工单地址:{$vo.ticket_address|default=""}
|
||||
</div>
|
||||
<div class="layui-row">
|
||||
工单内容:{$vo.content|default=""}
|
||||
</div>
|
||||
<div class="layui-row">
|
||||
工单图片:
|
||||
<div>
|
||||
{foreach $vo.imgs_arr as $img}
|
||||
<img data-tips-image src="{$img}" alt="image" style="height: 100px;">
|
||||
<span> </span>
|
||||
{/foreach}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">工单流转详情</div>
|
||||
<div class="layui-card-body">
|
||||
<table id="replyTable" class="layui-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th lay-data='{field: "username", width: "120px"}'>工单处理人</th>
|
||||
<th lay-data='{field: "type_name", width: "120px"}'>处理类型</th>
|
||||
<th lay-data='{field: "create_at", width: "180px"}'>工单处理时间</th>
|
||||
<th lay-data='{field: "content", minWidth: "200px"}'>处理内容</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{notempty name='vo.reply'}
|
||||
{foreach $vo.reply as $reply}
|
||||
<tr>
|
||||
<td>{$reply.username|default=""}</td>
|
||||
<td>{$reply.type_name|default=""}</td>
|
||||
<td>{$reply.create_at|default=""}</td>
|
||||
<td>{$reply.content|default=""}</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
{else}
|
||||
<tr>
|
||||
<td colspan="999" class="text-center">暂无工单流转记录</td>
|
||||
</tr>
|
||||
{/notempty}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
44
plugs/think-plugs-ticket/src/view/ticket/form.html
Normal file
44
plugs/think-plugs-ticket/src/view/ticket/form.html
Normal file
@ -0,0 +1,44 @@
|
||||
<form class="layui-form layui-card" action="{:sysuri()}" data-auto="true" method="post" autocomplete="off" data-table-id="ticketTable">
|
||||
<h1 style="color: red; text-align: center; padding: 20px; border: 1px solid red; margin-bottom: 20px">
|
||||
原则上不允许私自创建或修改工单!!!
|
||||
</h1>
|
||||
<div class="layui-row">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">工单标题</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="title" value='{$vo.title|default=""}' required placeholder="请输入工单标题" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">工单分类</label>
|
||||
<div class="layui-input-block">
|
||||
<select class="layui-select" name="type_id" required>
|
||||
{foreach $types as $type}
|
||||
<option value='{$type.id}'>{$type.name}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">工单内容</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea data-textarea class="layui-textarea" name='content' required>{$vo.content|default=""}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">工单图片</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="hidden" value='{$vo.imgs|default=""}' name="imgs">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{notempty name='id'}<input class="layui-input layui-hide" type='hidden' value='{$id}' name='id'>{/notempty}
|
||||
<div class="layui-form-item text-center">
|
||||
<button class="layui-btn layui-btn-normal" type='submit'>保存数据</button>
|
||||
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消编辑吗?" data-close>取消编辑</button>
|
||||
</div>
|
||||
</form>
|
||||
<script>
|
||||
$('[name="imgs"]').uploadMultipleImage()
|
||||
</script>
|
85
plugs/think-plugs-ticket/src/view/ticket/index.html
Normal file
85
plugs/think-plugs-ticket/src/view/ticket/index.html
Normal file
@ -0,0 +1,85 @@
|
||||
{extend name="table"}
|
||||
|
||||
{block name="button"}
|
||||
<!--{if auth("add")}-->
|
||||
<button type="button" class="layui-btn layui-btn-sm layui-btn-disabled" data-modal='{:url("add")}' data-title="添加工单">添加工单</button>
|
||||
<!--{/if}-->
|
||||
{/block}
|
||||
|
||||
{block name="content"}
|
||||
<div class="layui-tab">
|
||||
<div class="layui-row">
|
||||
<div class="layui-col">
|
||||
<div class="article_list think-bg-white">
|
||||
{include file='ticket/index_search'}
|
||||
<table class="layui-hide" data-url="{$request->url()}" data-target-search="form.form-search" id="ticketTable" lay-filter="ticketTable"></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/html" id="toolbar">
|
||||
<!--{if auth("detail")}-->
|
||||
<a data-modal="{:url('detail')}?id={{ d.id }}" data-height="90%" data-width="60%" class="layui-btn layui-btn-xs layui-btn-normal" title="详情">详情</a>
|
||||
<!--{/if}-->
|
||||
<!--{if auth("move")}-->
|
||||
<a data-modal="{:url('move')}?ticket_id={{ d.id }}" data-height="80%" data-width="80%" class="layui-btn layui-btn-xs" title="流转">流转</a>
|
||||
<!--{/if}-->
|
||||
<!--{if auth("reply")}-->
|
||||
{{# if (d.last_reply && d.last_reply.user_id == {$user_id} && d.last_reply.status == 0) { }}
|
||||
<a data-modal="{:url('reply')}?id={{ d.last_reply.id }}&ticket_id={{ d.id }}" data-height="80%" data-width="80%" class="layui-btn layui-btn-xs" title="回复">回复</a>
|
||||
{{# }; }}
|
||||
<!--{/if}-->
|
||||
<!--{if auth("edit")}-->
|
||||
<a data-modal="{:url('edit')}?id={{ d.id }}" data-height="80%" data-width="80%" class="layui-btn layui-btn-xs layui-btn-danger" title="修改工单">修改</a>
|
||||
<!--{/if}-->
|
||||
<!--{if auth("remove")}-->
|
||||
<a data-confirm="原则上不允许主动删除用户工单,是否继续删除?" data-action="{:url('remove')}" data-value="id#{{ d.id }}" class="layui-btn layui-btn-xs layui-btn-danger" title="删除">删除</a>
|
||||
<!--{/if}-->
|
||||
</script>
|
||||
{/block}
|
||||
|
||||
{block name='style'}
|
||||
<style>
|
||||
</style>
|
||||
{/block}
|
||||
|
||||
{block name='script'}
|
||||
<script>
|
||||
$(function () {
|
||||
$('#ticketTable').layTable({
|
||||
height: 'full-250',
|
||||
toolbar: true,
|
||||
sort: {field: 'create_at', type: 'desc'},
|
||||
title: '工单列表',
|
||||
cols: [[
|
||||
{field: 'create_at', title: '工单创建时间', width: 160, sort: true},
|
||||
{field:'title', title:'标题', width:160},
|
||||
{field:'type_name', title:'工单类型', width:120},
|
||||
{field:'content', title:'工单内容', minWidth:100},
|
||||
{field:'ticket_address', title:'工单地址', width:100},
|
||||
{field: 'imgs', title: '工单图片', width: 100, templet:function(item){
|
||||
if (item.imgs) {
|
||||
return item.imgs.split("|").map((img) => {
|
||||
return laytpl('<a target="_blank" data-tips-hover data-tips-image="{{d}}"><i class="layui-icon layui-icon-picture"></i></a>').render(img)
|
||||
}).concat(' ')
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}},
|
||||
{field:'status', title:'状态', width:80, templet:function(item){
|
||||
if(item.status == 0){
|
||||
return '<span style="color:red;">正在处理</span>';
|
||||
}else if(item.status == 1){
|
||||
return '<span style="color:green;">已处理</span>';
|
||||
}else{
|
||||
return '<span style="color:gray;">已关闭</span>';
|
||||
}
|
||||
}},
|
||||
|
||||
{fixed: 'right', title:'操作', toolbar: '#toolbar', width:200}
|
||||
]],
|
||||
page: true
|
||||
})
|
||||
})
|
||||
</script>
|
||||
{/block}
|
50
plugs/think-plugs-ticket/src/view/ticket/index_search.html
Normal file
50
plugs/think-plugs-ticket/src/view/ticket/index_search.html
Normal file
@ -0,0 +1,50 @@
|
||||
<fieldset>
|
||||
<legend>条件搜索</legend>
|
||||
<form class="layui-form layui-form-pane form-search" action="{:request()->url()}" onsubmit="return false" method="get" autocomplete="off">
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">关键字</label>
|
||||
<div class="layui-input-inline">
|
||||
<input name="keyword" value="{:input('get.keyword')}" placeholder="标题、内容、地址、当事人、电话" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">工单类型</label>
|
||||
<div class="layui-input-inline">
|
||||
<select class="layui-select" name="type_id">
|
||||
<option value=''>-- 全部 --</option>
|
||||
{foreach $type_list as $type}
|
||||
<option value='{$type.id}'>{$type.name}</option>
|
||||
{/foreach}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">工单状态</label>
|
||||
<div class="layui-input-inline">
|
||||
<select class="layui-select" name="status">
|
||||
<option value=''>-- 全部 --</option>
|
||||
<option value='0'>正在处理</option>
|
||||
<option value='1'>已处理</option>
|
||||
<option value='-1'>已取消</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">创建时间</label>
|
||||
<div class="layui-input-inline">
|
||||
<input data-date-range name="create_at" value="{:input('get.create_at')}" placeholder="请选择创建时间" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">最后操作时间</label>
|
||||
<div class="layui-input-inline">
|
||||
<input data-date-range name="last_activity_at" value="{:input('get.last_activity_at')}" placeholder="请选择最后操作时间" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<button class="layui-btn layui-btn-primary" lay-submit lay-filter="searchData"><i class="layui-icon"></i> 搜 索</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</fieldset>
|
43
plugs/think-plugs-ticket/src/view/ticket/reply.html
Normal file
43
plugs/think-plugs-ticket/src/view/ticket/reply.html
Normal file
@ -0,0 +1,43 @@
|
||||
<form class="layui-form layui-card margin-top-10 padding-10" action="{:sysuri()}" data-auto="true" method="post" autocomplete="off" data-table-id="ticketTable">
|
||||
<input class="layui-input layui-hide" type='hidden' value="{:input('get.id')}" name='id'>
|
||||
<input class="layui-input layui-hide" type='hidden' value="{:input('get.ticket_id')}" name='ticket_id'>
|
||||
<input class="layui-input layui-hide" type='hidden' value='{:systoken("reply")}' name='_token_'>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">回复内容</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea data-textarea class="layui-textarea" name='content' required></textarea>
|
||||
<div class="layui-word-aux">此回复对外可见,请认真回复。</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">回复图片</label>
|
||||
<div class="layui-input-block">
|
||||
<input class="layui-hide" name='imgs'>
|
||||
<div class="layui-word-aux">此图片对外可见,请认真回复。</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">内部回复内容</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea data-textarea class="layui-textarea" name='inner_content'></textarea>
|
||||
<div class="layui-word-aux">此回复仅系统内部可见。</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">内部回复图片</label>
|
||||
<div class="layui-input-block">
|
||||
<input class="layui-hide" name='inner_imgs'>
|
||||
<div class="layui-word-aux">此图片仅系统内部可见。</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item text-center">
|
||||
<button class="layui-btn layui-btn-normal" type='submit'>保存数据</button>
|
||||
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消编辑吗?" data-close>取消编辑</button>
|
||||
</div>
|
||||
</form>
|
||||
<script>
|
||||
$('[name="imgs"]').uploadMultipleImage()
|
||||
$('[name="inner_imgs"]').uploadMultipleImage()
|
||||
</script>
|
||||
{include file="ticket/detail"}
|
63
plugs/think-plugs-ticket/src/view/type/form.html
Normal file
63
plugs/think-plugs-ticket/src/view/type/form.html
Normal file
@ -0,0 +1,63 @@
|
||||
<form class="layui-form layui-card" action="{:request()->url()}" data-auto="true" method="post" autocomplete="off" data-table-id="typeTable">
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-row layui-col-space15">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">分类名称</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="name" value='{$vo.name|default=""}' required placeholder="请输入分类名称" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hr-line-dashed"></div>
|
||||
{notempty name='vo.id'}<input type='hidden' value='{$vo.id}' name='id'>{/notempty}
|
||||
<div class="layui-form-item text-center">
|
||||
<button class="layui-btn layui-btn-normal" type='submit'>保存数据</button>
|
||||
<button class="layui-btn layui-btn-danger" type='button' data-confirm="确定要取消编辑吗?" data-close>取消编辑</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<style>
|
||||
.layui-tab-item{ min-height: 400px;}
|
||||
.input-group-addon {
|
||||
top: 0;
|
||||
right: 0;
|
||||
color: #eee;
|
||||
width: 25px;
|
||||
padding: 7px;
|
||||
position: absolute;
|
||||
margin-top: -1px;
|
||||
text-align: center;
|
||||
background: #393D49;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
layui.form.render();
|
||||
layui.use(['layer', 'jquery', 'form','element'], function () {
|
||||
var layer = layui.layer,
|
||||
$ = layui.jquery,
|
||||
form = layui.form,
|
||||
element = layui.element;
|
||||
|
||||
//监听是否为跳转链接的选择变化
|
||||
form.on("radio(islink_filter)", function (data) {
|
||||
if(parseInt(data.value)){
|
||||
$('#category_link_url').show();
|
||||
}else{
|
||||
$('#category_link_url').hide();
|
||||
}
|
||||
});
|
||||
//监听指定开关
|
||||
form.on('switch(urlpath_filter)', function(data){
|
||||
if(this.checked){
|
||||
$(this).parent('.layui-input-block').prev().removeClass('label-required-next');
|
||||
$('input[name="url_path"]').next('span').hide();
|
||||
$('input[name="url_path"]').removeAttr('required').attr('disabled',true);
|
||||
}else{
|
||||
$(this).parent('.layui-input-block').prev().addClass('label-required-next');
|
||||
$('input[name="url_path"]').next('span').show();
|
||||
$('input[name="url_path"]').removeAttr('disabled').attr('required',true);
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
83
plugs/think-plugs-ticket/src/view/type/index.html
Normal file
83
plugs/think-plugs-ticket/src/view/type/index.html
Normal file
@ -0,0 +1,83 @@
|
||||
{extend name="table"}
|
||||
|
||||
{block name="button"}
|
||||
<!--{if auth("add")}-->
|
||||
<button data-modal='{:url("add")}' data-title="添加栏目" class='layui-btn layui-btn-sm layui-btn-primary'>添加类型</button>
|
||||
<!--{/if}-->
|
||||
{/block}
|
||||
|
||||
{block name="content"}
|
||||
<div class="layui-tab layui-tab-card think-bg-white">
|
||||
<div class="layui-tab-content think-box-shadow">
|
||||
{include file='type/index_search'}
|
||||
<table class="layui-table margin-top-10" data-url="{$request->url()}" data-target-search="form.form-search" lay-skin="line" id="typeTable"></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/html" id="toolbar">
|
||||
|
||||
<!--{if auth("edit")}-->
|
||||
<a data-modal="{:url('edit')}?id={{ d.id }}" class="layui-btn layui-btn-xs layui-btn-normal" title="修改">修改</a>
|
||||
<!--{/if}-->
|
||||
|
||||
<!--{if auth("status")}-->
|
||||
{{# if(d.status == 0){ }}
|
||||
<a class="layui-btn layui-btn-xs layui-btn-normal" data-title="显示分类" data-modal='{:url("status")}?id={{ d.id }}&status=1'>显 示</a>
|
||||
{{# } else { }}
|
||||
<a class="layui-btn layui-btn-xs layui-btn-primary" data-title="隐藏分类" data-modal='{:url("status")}?id={{ d.id }}&status=0'>隐 藏</a>
|
||||
{{# } }}
|
||||
<!--{/if}-->
|
||||
|
||||
<!--{if auth("remove")}-->
|
||||
<a data-confirm="确定要永久删除此分类吗?" data-action="{:url('remove')}" data-value="id#{{ d.id }}" data-csrf="{:systoken('remove')}" class="layui-btn layui-btn-xs layui-btn-danger" title="删除">删除</a>
|
||||
<!--{/if}-->
|
||||
</script>
|
||||
{/block}
|
||||
|
||||
{block name='style'}
|
||||
<style>
|
||||
</style>
|
||||
{/block}
|
||||
|
||||
{block name='script'}
|
||||
<script>
|
||||
$(function () {
|
||||
$('#typeTable').layTable({
|
||||
height: 'full-240',
|
||||
toolbar: true,
|
||||
sort: {field: 'sort', type: 'asc'},
|
||||
cols: [[
|
||||
{type: 'numbers'},
|
||||
{field: 'sort', title: '排序', width: 80, sort: true, edit: 'text'},
|
||||
{field: 'name', title: '工单类型名称', minWidth: 165},
|
||||
{field: 'status', title: '状态', width: 60,templet:function(item){
|
||||
if(item.status == 0){
|
||||
return '<span style="color:red;">隐藏</span>';
|
||||
}else if(item.status == 1){
|
||||
return '<span style="color:green;">显示</span>';
|
||||
}
|
||||
}},
|
||||
{field: 'tickets_count', title: '该类型工单数', width: 120},
|
||||
{field: 'create_at', title: '创建时间', width: 150},
|
||||
{align: 'center', toolbar: '#toolbar', title: '操作', width: 240}
|
||||
]]
|
||||
})
|
||||
layui.use(['table'], function(){
|
||||
var table = layui.table,
|
||||
layer = layui.layer;
|
||||
table.on('edit(typeTable)', function(obj) {
|
||||
if (obj.field == 'sort') {
|
||||
if (obj.value == '') {
|
||||
obj.value = obj.oldValue
|
||||
return false;
|
||||
} else {
|
||||
$.form.load("{:url('sort')}", {sort: obj.value, id: obj.data.id}, 'post', function (ret) {
|
||||
$('#typeTable').trigger('reload');
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
})
|
||||
</script>
|
||||
{/block}
|
16
plugs/think-plugs-ticket/src/view/type/index_search.html
Normal file
16
plugs/think-plugs-ticket/src/view/type/index_search.html
Normal file
@ -0,0 +1,16 @@
|
||||
<fieldset>
|
||||
<legend>条件搜索</legend>
|
||||
<form class="layui-form layui-form-pane form-search" action="{:request()->url()}" onsubmit="return false" method="get" autocomplete="off">
|
||||
<div class="layui-form-item layui-inline">
|
||||
<label class="layui-form-label">分类名称</label>
|
||||
<div class="layui-input-inline">
|
||||
<input name="name" value="{:input('get.name')}" placeholder="请输入分类名称" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-inline">
|
||||
<button class="layui-btn layui-btn-primary" lay-submit lay-filter="searchData"><i class="layui-icon"></i> 搜 索</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</fieldset>
|
Reference in New Issue
Block a user