后台增加活动审核通知和主理人申请通知

This commit is contained in:
qinzexin 2025-07-31 18:30:46 +08:00
parent 1b443d950d
commit 0590c2c26a
54 changed files with 3507 additions and 24 deletions

View File

@ -3,6 +3,10 @@
namespace app\admin\controller\manystore;
use app\common\controller\Backend;
use think\Db;
use think\exception\DbException;
use think\exception\PDOException;
use think\exception\ValidateException;
/**
* 机构申请
@ -77,4 +81,101 @@ class ShopApply extends Backend
return $this->view->fetch();
}
/**
* 添加
*
* @return string
* @throws \think\Exception
*/
public function add()
{
if (false === $this->request->isPost()) {
return $this->view->fetch();
}
$params = $this->request->post('row/a');
if (empty($params)) {
$this->error(__('Parameter %s can not be empty', ''));
}
$params = $this->preExcludeFields($params);
if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
$params[$this->dataLimitField] = $this->auth->id;
}
$result = false;
Db::startTrans();
try {
//是否采用模型验证
if ($this->modelValidate) {
$name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
$validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
$this->model->validateFailException()->validate($validate);
}
$result = $this->model->allowField(true)->save($params);
//调用订单事件
$data = ['shop' => $this->model];
\think\Hook::listen('shop_apply_create_after', $data);
Db::commit();
} catch (ValidateException|PDOException|\Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($result === false) {
$this->error(__('No rows were inserted'));
}
$this->success();
}
/**
* 编辑
*
* @param $ids
* @return string
* @throws DbException
* @throws \think\Exception
*/
public function edit($ids = null)
{
$row = $this->model->get($ids);
if (!$row) {
$this->error(__('No Results were found'));
}
$adminIds = $this->getDataLimitAdminIds();
if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) {
$this->error(__('You have no permission'));
}
if (false === $this->request->isPost()) {
$this->view->assign('row', $row);
return $this->view->fetch();
}
$params = $this->request->post('row/a');
if (empty($params)) {
$this->error(__('Parameter %s can not be empty', ''));
}
$params = $this->preExcludeFields($params);
$result = false;
Db::startTrans();
try {
//是否采用模型验证
if ($this->modelValidate) {
$name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
$validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
$row->validateFailException()->validate($validate);
}
$result = $row->allowField(true)->save($params);
Db::commit();
} catch (ValidateException|PDOException|\Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if (false === $result) {
$this->error(__('No rows were updated'));
}
$this->success();
}
}

View File

@ -0,0 +1,113 @@
<?php
/**
* User: hnh0000
* Time: 2021/2/21 3:11 下午
* QQ: 1123416584
* Blog: blog@hnh117.com
*/
namespace app\admin\controller\notice;
use addons\notice\library\Service;
use app\admin\model\AdminLog;
use app\common\controller\Backend;
use think\Cache;
class Admin extends Backend
{
protected $noNeedRight = ['mark', 'statistical'];
public function index()
{
$user = $this->auth->getUserInfo();
$list = \app\admin\model\notice\Notice::where('to_id', $user['id'])
->where('platform', 'admin')
->where('type','msg')
->order('id', 'desc')
->paginate(20);
$config = get_addon_config('notice');
// 是否有未读的
$haveUnread = false;
// 判断是否需要自动标记为已读
$auto_read = $config['auto_read'] ?? false;
if ($auto_read) {
\app\admin\model\notice\Notice::where('id', 'in',array_column($list->items(), 'id'))
->update(['readtime' => time()]);
} else {
foreach ($list->items() as $item) {
if ($item['readtime'] === null) {
$haveUnread = true;
break;
}
}
}
$this->assign('haveUnread', $haveUnread);
$this->assign('list', $list);
$this->assign('title', '我的消息');
return $this->view->fetch();
}
// 标记为已读
public function mark()
{
$user = $this->auth->getUserInfo();
$where = [];
if (input('id')) {
$where['id'] = input('id');
}
$count = \app\admin\model\notice\Notice::where('to_id', $user['id'])
->where('platform', 'admin')
->where('type','msg')
->where($where)
->order('id', 'desc')
->whereNull('readtime')
->update(['readtime' => time()]);
$this->success('', $count);
}
// 统计
public function statistical()
{
AdminLog::setIgnoreRegex('/./');
$user = $this->auth->getUserInfo();
$statisticalTime = Cache::get('notice_admin_statistical_time_'.$user['id'], 0);
$new = \app\admin\model\notice\Notice::where('to_id', $user['id'])
->where('platform', 'admin')
->where('type','msg')
->order('id', 'desc')
->where('createtime','>', $statisticalTime)
->whereNull('readtime')
->find();
if ($new) {
Cache::set('notice_admin_statistical_time_'.$user['id'], time());
}
$noticeData = Service::getNoticeData();
$waitData = Service::getWaitData();
$data = [
'num' => \app\admin\model\notice\Notice::where('to_id', $user['id'])
->where('platform', 'admin')
->where('type','msg')
->order('id', 'desc')
->whereNull('readtime')
->count()
,
'new' => $new,
'notice_data' => $noticeData,
'wait_data' => $waitData,
];
$this->success('', '', $data);
}
}

View File

@ -0,0 +1,110 @@
<?php
namespace app\admin\controller\notice;
use app\common\controller\Backend;
use think\Cache;
/**
* 管理员绑定微信(模版消息公众号)
*
* @icon fa fa-circle-o
*/
class AdminMptemplate extends Backend
{
/**
* AdminMptemplate模型对象
* @var \app\admin\model\notice\AdminMptemplate
*/
protected $model = null;
protected $noNeedRight = ['bind'];
protected $searchFields = ['id','admin.nickname','openid'];
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\notice\AdminMptemplate;
}
public function import()
{
parent::import();
}
/**
* 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
* 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
* 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
*/
// 绑定模版消息(公众号)
public function bind()
{
$exist = \app\admin\model\notice\AdminMptemplate::where('admin_id', $this->auth->id)->find();
if ($this->request->isPost()) {
$exist->delete();
$this->success('解绑成功');
}
$this->assign('exist', $exist);
$url = '';
// 5分钟有效的绑定连接
if (!$exist){
$mark = 'notice_bmp'.uniqid();
Cache::set($mark, $this->auth->id, 60*5);
$url = addon_url('notice/index/mpauth', ['mark' => $mark], false, true);
}
$this->assignconfig('url', $url);
return $this->fetch();
}
/**
* 查看
*/
public function index()
{
//当前是否为关联查询
$this->relationSearch = true;
//设置过滤方法
$this->request->filter(['strip_tags', 'trim']);
if ($this->request->isAjax())
{
//如果发送的来源是Selectpage则转发到Selectpage
if ($this->request->request('keyField'))
{
return $this->selectpage();
}
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$total = $this->model
->with(['admin'])
->where($where)
->order($sort, $order)
->count();
$list = $this->model
->with(['admin'])
->where($where)
->order($sort, $order)
->limit($offset, $limit)
->select();
foreach ($list as $row) {
$row->getRelation('admin')->visible(['id','nickname']);
}
$list = collection($list)->toArray();
$result = array("total" => $total, "rows" => $list);
return json($result);
}
return $this->view->fetch();
}
}

View File

@ -0,0 +1,106 @@
<?php
namespace app\admin\controller\notice;
use addons\notice\library\NoticeClient;
use app\common\controller\Backend;
use think\Db;
use think\Hook;
/**
* 消息事件
*
* @icon fa fa-circle-o
*/
class Event extends Backend
{
/**
* NoticeEvent模型对象
* @var \app\admin\model\notice\NoticeEvent
*/
protected $model = null;
protected $searchFields = ['id','name','event'];
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\notice\NoticeEvent;
$this->view->assign("platformList", $this->model->getPlatformList());
$this->view->assign("typeList", $this->model->getTypeList());
$this->assignconfig("typeList", $this->model->getTypeList());
$this->view->assign("visibleSwitchList", $this->model->getVisibleSwitchList());
}
public function import()
{
parent::import();
}
/**
* 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
* 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
* 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
*/
public function test($ids)
{
$row = $this->model->get($ids);
if (!$row) {
$this->error(__('No Results were found'));
}
if ($this->request->isAjax()) {
$params = input('row/a');
$params = $this->preExcludeFields($params);
$params = array_only($params, '*');
$params['field']['receiver_admin_ids'] = input('row.receiver_admin_ids');
$params['field']['receiver_admin_group_ids'] = input('row.receiver_admin_group_ids');
$params['field'] = array_filter($params['field'], function ($v) {
return $v != '';
});
if (!$params) {
$this->error(__('Parameter %s can not be empty', ''));
}
Db::startTrans();
try{
// 函数发送
// $is = NoticeClient::instance()->trigger($row['event'], $params['field']);
// 行为发送
$noticeParams = [
'event' => $row['event'],
'params' => $params['field']
];
$is = Hook::listen('send_notice', $noticeParams, null, true);
Db::commit();
}catch (\Exception $e) {
$this->error($e->getMessage());
Db::rollback();
}
if ($is) {
$this->success('操作成功');
}
$this->error('发送失败:'.NoticeClient::instance()->getError());
}
$row->content_arr2 = array_merge(['receiver_admin_ids' => '', 'receiver_admin_group_ids' => '',], $row['content_arr']);
$this->assign('row', $row);
return $this->fetch();
}
public function edit($ids = null)
{
// copy数据
if ($this->request->isPost() && input('is_copy')) {
$params = $this->request->post("row/a");
$params = $this->preExcludeFields($params);
$this->model->save($params);
$this->success('添加成功');
}
return parent::edit($ids);
}
}

View File

@ -0,0 +1,137 @@
<?php
namespace app\admin\controller\notice;
use app\common\controller\Backend;
use think\Db;
use think\exception\PDOException;
use think\exception\ValidateException;
/**
* 消息通知
*
* @icon fa fa-circle-o
*/
class Notice extends Backend
{
/**
* Notice模型对象
* @var \app\admin\model\notice\Notice
*/
protected $model = null;
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\notice\Notice;
$this->view->assign("typeList", $this->model->getTypeList());
$this->assignconfig("typeList", $this->model->getTypeList());
$this->view->assign("platformList", $this->model->getPlatformList());
}
public function import()
{
parent::import();
}
/**
* 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
* 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
* 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
*/
/**
* 查看
*/
public function index()
{
//当前是否为关联查询
$this->relationSearch = true;
//设置过滤方法
$this->request->filter(['strip_tags', 'trim']);
if ($this->request->isAjax()) {
//如果发送的来源是Selectpage则转发到Selectpage
if ($this->request->request('keyField')) {
return $this->selectpage();
}
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$list = $this->model
->with(['noticetemplate'])
->where($where)
->order($sort, $order)
->paginate($limit);
foreach ($list as $row) {
$row->getRelation('noticetemplate')->visible(['id']);
}
$result = array("total" => $list->total(), "rows" => $list->items());
return json($result);
}
return $this->view->fetch();
}
public function add()
{
if ($this->request->isPost()) {
$params = $this->request->post("row/a");
if ($params) {
$params = $this->preExcludeFields($params);
$toIds = '';
if (input('row.platform') == 'user') {
$toIds = input('row.id1');
} else {
$toIds = input('row.id2');
}
if (empty($toIds)) {
$this->error('请选择接收人');
}
$toIds = explode(',', $toIds);
if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
$params[$this->dataLimitField] = $this->auth->id;
}
$result = false;
Db::startTrans();
try {
//是否采用模型验证
if ($this->modelValidate) {
$name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
$validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
$this->model->validateFailException(true)->validate($validate);
}
foreach ($toIds as $id) {
$params['to_id'] = $id;
$this->model::create($params, true);
}
$result = true;
Db::commit();
} catch (ValidateException $e) {
Db::rollback();
$this->error($e->getMessage());
} catch (PDOException $e) {
Db::rollback();
$this->error($e->getMessage());
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($result !== false) {
$this->success();
} else {
$this->error(__('No rows were inserted'));
}
}
$this->error(__('Parameter %s can not be empty', ''));
}
return $this->view->fetch();
}
}

View File

@ -0,0 +1,215 @@
<?php
namespace app\admin\controller\notice;
use addons\notice\library\NoticeClient;
use app\admin\model\notice\NoticeEvent;
use app\admin\model\notice\NoticeTemplate;
use app\common\controller\Backend;
use think\Db;
use think\exception\PDOException;
use think\exception\ValidateException;
/**
* 消息模版
*
* @icon fa fa-circle-o
*/
class Template extends Backend
{
/**
* NoticeTemplate模型对象
* @var \app\admin\model\notice\NoticeTemplate
*/
protected $model = null;
protected $noNeedRight = ['visible'];
public function _initialize()
{
parent::_initialize();
$this->model = new \app\admin\model\notice\NoticeTemplate;
$this->view->assign("platformList", NoticeClient::instance()->getPlatformList());
$this->view->assign("typeList", NoticeClient::instance()->getTypeList());
$this->view->assign("visibleSwitchList", $this->model->getVisibleSwitchList());
}
public function add()
{
return false;
}
public function edit($ids = null)
{
$where = $this->request->only(['notice_event_id', 'platform', 'type']);
if (count($where) != 3) {
return_error('参数错误');
}
$event = NoticeEvent::get($where['notice_event_id']);
$this->assign('event', $event);
row_check($event);
$row = $this->model->get($where);
if (!$row) {
$row = $this->model;
$row->notice_event_id = $where['notice_event_id'];
$row->platform = $where['platform'];
$row->type = $where['type'];
$row->content = '';
$row->visible_switch = 1;
$row->mptemplate_id = '';
$row->mptemplate_json = '';
$row->url_type = 1;
$row->url_title = '';
$row->url = '';
}
$adminIds = $this->getDataLimitAdminIds();
if (is_array($adminIds)) {
if (!in_array($row[$this->dataLimitField], $adminIds)) {
$this->error(__('You have no permission'));
}
}
if ($this->request->isPost()) {
$params = $this->request->post("row/a");
if (isset($params['mptemplate_id'])) {
$params['mptemplate_id'] = trim($params['mptemplate_id']);
}
if ($params) {
$params = $this->preExcludeFields($params);
$result = false;
Db::startTrans();
try {
//是否采用模型验证
if ($this->modelValidate) {
$name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
$validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
$row->validateFailException(true)->validate($validate);
}
$result = $row->allowField(true)->save($params);
Db::commit();
} catch (ValidateException $e) {
Db::rollback();
$this->error($e->getMessage());
} catch (PDOException $e) {
Db::rollback();
$this->error($e->getMessage());
} catch (\Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($result !== false) {
$this->success();
} else {
$this->error(__('No rows were updated'));
}
}
$this->error(__('Parameter %s can not be empty', ''));
}
$this->view->assign("row", $row);
$this->view->assign('urlTypeList', $row->getUrlTypeList());
return $this->view->fetch();
}
/**
* 查看
*/
public function index()
{
// 依据通知事件更新模板表
$eventList = NoticeEvent::scope('frontend')->select();
$templateList = [];
$noticeClient = new NoticeClient();
$default_params = [
// 默认平台
'platform' => array_keys($noticeClient->getPlatformData())[0],
];
$params = $this->request->only(['platform']);
$params = array_merge($default_params, $params);
// 当前平台支持的类型
$typeList = $noticeClient->getPlatformData()[$params['platform']]['type'] ?? [];
$typeList = array_combine($typeList, $typeList);
foreach ($typeList as $k=>$v) {
$typeList[$k] = $noticeClient->getTypeText($k);
}
foreach ($eventList as $item) {
$platformArr = explode(',', $item['platform']);
$typeArr = explode(',', $item['type']);
foreach ($platformArr as $v) {
if ($v != $params['platform']) {
continue;
}
$templateItem = [
'noticeevent' => $item,
'item' => []
];
foreach ($typeList as $k2 => $v2) {
// 判断是否支持
$is = in_array($k2, $typeArr);
if ($is) {
$_item = [
'notice_event_id' => $item['id'],
'platform' => $v,
'type' => $k2,
'type_text' => $v2,
'content' => null,
'visible_switch' => 0,
'id' => 0,
'send_num' => '-',
'send_fail_num' => '-',
'error' => false
];
// 判断是否有记录
$template = $noticeClient->getTemplateByPlatformAndType($item['id'],$v, $k2);
if ($template) {
$_item = array_merge($_item, $template->toArray());
}
$templateItem['item'][] = $_item;
} else {
$templateItem['item'][] = [
'error' => '不支持'
];
}
}
if ($templateItem['item']) {
$templateList[] = $templateItem;
}
}
}
$list = $templateList;
$this->assign('list', $list);
$this->assign('typeList', $typeList);
$this->assign('params', $params);
return $this->view->fetch();
}
/**
* 开关
*/
public function visible()
{
$params = $this->request->only(['notice_event_id', 'platform', 'type', 'visible_switch']);
if (count($params) != 4) {
return_error('缺少参数');
}
$where = $params;
unset($where['visible_switch']);
$row = $this->model->where($where)->find();
if (!$row) {
$this->error('请先配置');
}
$row['visible_switch'] = $params['visible_switch'];
$row->save();
$this->success('操作成功');
}
}

View File

@ -0,0 +1,12 @@
<?php
return [
'Id' => 'ID',
'Admin_id' => '管理员',
'Nickname' => '微信昵称',
'Avatar' => '微信头像',
'Createtime' => '创建时间',
'Updatetime' => '更新时间',
'Deletetime' => '删除时间',
'Admin.nickname' => '昵称'
];

View File

@ -0,0 +1,23 @@
<?php
return [
'Id' => 'ID',
'Platform' => '支持平台',
'Platform user' => '用户',
'Platform admin' => '后台',
'Type' => '支持类型',
'Type msg' => '站内通知',
'Type email' => '邮箱通知',
'Type template' => '模版消息(公众号)',
'Name' => '消息名称',
'Event' => '消息事件',
'Send_num' => '发送次数',
'Send_fail_num' => '发送失败次数',
'Content' => '参数',
'Visible_switch' => '状态',
'Visible_switch 0' => '关闭',
'Visible_switch 1' => '启用',
'Createtime' => '创建时间',
'Updatetime' => '更新时间',
'Deletetime' => '删除时间'
];

View File

@ -0,0 +1,23 @@
<?php
return [
'Id' => 'ID',
'Name' => '消息名称',
'Event' => '消息事件',
'Type' => '消息类型',
'Type msg' => '站内通知',
'Type email' => '邮箱通知',
'Type template' => '模版消息(公众号)',
'Platform' => '平台',
'Platform user' => '用户',
'Platform admin' => '后台',
'To_id' => '接收人id',
'Content' => '内容',
'Ext' => '扩展',
'Notice_template_id' => '消息模板',
'Readtime' => '是否已读',
'Createtime' => '创建时间',
'Updatetime' => '更新时间',
'Deletetime' => '删除时间',
'Noticetemplate.id' => 'ID',
];

View File

@ -0,0 +1,30 @@
<?php
return [
'Id' => 'ID',
'Notice_event_id' => '事件',
'Platform' => '平台',
'Platform user' => '用户',
'Platform admin' => '后台',
'Type' => '类型',
'Type msg' => '站内通知',
'Type email' => '邮箱通知',
'Type template' => '模版消息(公众号)',
'Content' => '消息内容',
'Visible_switch' => '状态',
'Visible_switch 0' => '关闭',
'Visible_switch 1' => '启用',
'Send_num' => '发送次数',
'Send_fail_num' => '发送失败次数',
'Ext' => '扩展数据',
'Createtime' => '创建时间',
'Updatetime' => '更新时间',
'Noticeevent.id' => 'ID',
'Noticeevent.name' => '消息名称',
'mptemplate_id' => '模板id',
'mptemplate_json' => '模版参数',
'url' => 'url',
'url_title' => 'url标题',
'url_type' => 'url类型',
];

View File

@ -0,0 +1,44 @@
<?php
namespace app\admin\model\notice;
use think\Model;
use traits\model\SoftDelete;
class AdminMptemplate extends Model
{
use SoftDelete;
// 表名
protected $name = 'notice_admin_mptemplate';
// 自动写入时间戳字段
protected $autoWriteTimestamp = 'int';
// 定义时间戳字段名
protected $createTime = 'createtime';
protected $updateTime = 'updatetime';
protected $deleteTime = 'deletetime';
// 追加属性
protected $append = [
];
public function admin()
{
return $this->belongsTo('app\admin\model\Admin', 'admin_id', 'id', [], 'LEFT')->setEagerlyType(0);
}
}

View File

@ -0,0 +1,106 @@
<?php
namespace app\admin\model\notice;
use think\Model;
use traits\model\SoftDelete;
class Notice extends Model
{
use SoftDelete;
// 表名
protected $name = 'notice';
// 自动写入时间戳字段
protected $autoWriteTimestamp = 'int';
// 定义时间戳字段名
protected $createTime = 'createtime';
protected $updateTime = 'updatetime';
protected $deleteTime = 'deletetime';
// 追加属性
protected $append = [
// 'type_text',
// 'platform_text',
// 'readtime_text'
'ext_arr',
];
public function getTypeList()
{
return ['msg' => __('Type msg'), 'email' => __('Type email'), 'mptemplate' => '模版消息(公众号)', 'miniapp' => '小程序订阅消息', 'sms' => '短信通知'];
}
public function getPlatformList()
{
return ['user' => __('Platform user'), 'admin' => __('Platform admin')];
}
public function getTypeTextAttr($value, $data)
{
$value = $value ? $value : (isset($data['type']) ? $data['type'] : '');
$list = $this->getTypeList();
return isset($list[$value]) ? $list[$value] : '';
}
public function getPlatformTextAttr($value, $data)
{
$value = $value ? $value : (isset($data['platform']) ? $data['platform'] : '');
$list = $this->getPlatformList();
return isset($list[$value]) ? $list[$value] : '';
}
public function getReadtimeTextAttr($value, $data)
{
$value = $value ? $value : (isset($data['readtime']) ? $data['readtime'] : '');
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
}
protected function setReadtimeAttr($value)
{
return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
}
public function noticetemplate()
{
return $this->belongsTo('NoticeTemplate', 'notice_template_id', 'id', [], 'LEFT')->setEagerlyType(0);
}
public function getExtArrAttr($value, $data)
{
$value = $data['ext'] ?? '';
$value = json_decode($value, true) ?? [];
if (!isset($value['url'])) {
$value['url'] = null;
}
if (!isset($value['url_type'])) {
$value['url_type'] = null;
}
if (!isset($value['url_title'])) {
$value['url_title'] = '';
}
if ($value['url']) {
if (0 === stripos($value['url'], 'http')) {
} else if (0 === stripos($value['url'], '/')) {
} else {
if (request()->module() != 'admin') {
$value['url'] = url($value['url']);
}
}
}
return $value;
}
}

View File

@ -0,0 +1,99 @@
<?php
namespace app\admin\model\notice;
use think\Model;
use think\db\Query;
use traits\model\SoftDelete;
class NoticeEvent extends Model
{
use SoftDelete;
// 表名
protected $name = 'notice_event';
// 自动写入时间戳字段
protected $autoWriteTimestamp = 'int';
// 定义时间戳字段名
protected $createTime = 'createtime';
protected $updateTime = 'updatetime';
protected $deleteTime = 'deletetime';
// 追加属性
protected $append = [
// 'platform_text',
// 'type_text',
// 'visible_switch_text'
];
public function getContentArrAttr()
{
$value = $this['content'];
$value = (array) json_decode($value);
return $value;
}
public function getPlatformList()
{
return ['user' => __('Platform user'), 'admin' => __('Platform admin')];
}
public function getTypeList()
{
return ['msg' => __('Type msg'), 'email' => __('Type email'), 'mptemplate' => '模版消息(公众号)', 'miniapp' => '小程序订阅消息', 'sms' => '短信通知'];
}
public function getVisibleSwitchList()
{
return ['0' => __('Visible_switch 0'), '1' => __('Visible_switch 1')];
}
public function getPlatformTextAttr($value, $data)
{
$value = $value ? $value : (isset($data['platform']) ? $data['platform'] : '');
$valueArr = explode(',', $value);
$list = $this->getPlatformList();
return implode(',', array_intersect_key($list, array_flip($valueArr)));
}
public function getTypeTextAttr($value, $data)
{
$value = $value ? $value : (isset($data['type']) ? $data['type'] : '');
$valueArr = explode(',', $value);
$list = $this->getTypeList();
return implode(',', array_intersect_key($list, array_flip($valueArr)));
}
public function getVisibleSwitchTextAttr($value, $data)
{
$value = $value ? $value : (isset($data['visible_switch']) ? $data['visible_switch'] : '');
$list = $this->getVisibleSwitchList();
return isset($list[$value]) ? $list[$value] : '';
}
protected function setPlatformAttr($value)
{
return is_array($value) ? implode(',', $value) : $value;
}
protected function setTypeAttr($value)
{
return is_array($value) ? implode(',', $value) : $value;
}
public function scopeFrontend(Query $query, $params = [])
{
$query->where('__TABLE__.visible_switch', 1)
->order(['__TABLE__.id'=>'desc']);
}
}

View File

@ -0,0 +1,65 @@
<?php
namespace app\admin\model\notice;
use think\Model;
class NoticeTemplate extends Model
{
// 表名
protected $name = 'notice_template';
// 自动写入时间戳字段
protected $autoWriteTimestamp = 'int';
// 定义时间戳字段名
protected $createTime = 'createtime';
protected $updateTime = 'updatetime';
protected $deleteTime = false;
// 追加属性
protected $append = [
];
public function getVisibleSwitchList()
{
return ['0' => __('Visible_switch 0'), '1' => __('Visible_switch 1')];
}
public function getVisibleSwitchTextAttr($value, $data)
{
$value = $value ? $value : (isset($data['visible_switch']) ? $data['visible_switch'] : '');
$list = $this->getVisibleSwitchList();
return isset($list[$value]) ? $list[$value] : '';
}
public function noticeevent()
{
return $this->belongsTo('NoticeEvent', 'notice_event_id', 'id', [], 'LEFT')->setEagerlyType(0);
}
public function getUrlTypeList()
{
$type = $this['type'] ?? '';
if ($type == 'msg') {
return [1 => '链接', 2=>'弹窗', 3=>'新窗口'];
}
if ($type == 'mptemplate' || $type == 'miniapp') {
return [1 => '链接'];
}
return [1 => '链接', 2=>'弹窗', 3=>'新窗口'];
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace app\admin\validate\notice;
use think\Validate;
class AdminMptemplate extends Validate
{
/**
* 验证规则
*/
protected $rule = [
];
/**
* 提示消息
*/
protected $message = [
];
/**
* 验证场景
*/
protected $scene = [
'add' => [],
'edit' => [],
];
}

View File

@ -0,0 +1,27 @@
<?php
namespace app\admin\validate\notice;
use think\Validate;
class Notice extends Validate
{
/**
* 验证规则
*/
protected $rule = [
];
/**
* 提示消息
*/
protected $message = [
];
/**
* 验证场景
*/
protected $scene = [
'add' => [],
'edit' => [],
];
}

View File

@ -0,0 +1,27 @@
<?php
namespace app\admin\validate\notice;
use think\Validate;
class NoticeEvent extends Validate
{
/**
* 验证规则
*/
protected $rule = [
];
/**
* 提示消息
*/
protected $message = [
];
/**
* 验证场景
*/
protected $scene = [
'add' => [],
'edit' => [],
];
}

View File

@ -0,0 +1,27 @@
<?php
namespace app\admin\validate\notice;
use think\Validate;
class NoticeTemplate extends Validate
{
/**
* 验证规则
*/
protected $rule = [
];
/**
* 提示消息
*/
protected $message = [
];
/**
* 验证场景
*/
protected $scene = [
'add' => [],
'edit' => [],
];
}

View File

@ -0,0 +1,108 @@
<style>
.notice-item td{
padding: 10px !important;
}
.page-header {
margin-bottom: 0px !important;
}
@media (min-width: 1200px) {
.container {
width: 100%;
}
}
.panel{
border: 0;
border-radius: 12px;
}
.panel .panel-body{
padding: 0 24px;
}
.panel .page-header{
margin: 0 -24px;
border-color: #DDDDDD;
padding: 16px 24px 12px;
line-height: 30px;
font-size: 18px;
color: #333;
font-weight: bold;
overflow: hidden;
}
.panel .page-header .btn-default{
padding: 0 8px;
background: #7A888F;
line-height: 30px;
font-size: 13px;
color: #fff;
border-radius: 3px;
}
.panel .notice-item td{
border-top: 0 !important;
border-bottom: 1px #DDDDDD solid;
padding: 16px 0 !important;
vertical-align: middle !important;
line-height: 24px !important;
font-size: 13px !important;
color: #333 !important;
}
.panel .notice-item td a{
color: inherit;
}
.panel .notice-item td a:hover{
color: #4397fd;
}
.panel .notice-item .btn{
padding: 0 10px !important;
min-width: 50px !important;
height: 24px !important;
background: #1EB18A !important;
text-align: center !important;
border-radius: 3px !important;
}
</style>
<div id="content-container" class="container">
<a href="javascript:;" class="btn btn-primary btn-refresh hidden" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a>
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-body">
<h2 class="page-header">
消息通知
{if $haveUnread}
<button class="pull-right btn btn-default mark-event" data-url="{:url('notice/admin/mark')}">全部标记为已读</button>
{/if}
</h2>
<table class="table table-hover">
<tbody>
{foreach $list as $v}
<tr class="notice-item">
<td><a data-title="{$v.ext_arr.url_title|htmlentities}" class="{$v.ext_arr.url_type == 2 ? 'btn-dialog' : ''} {$v.ext_arr.url_type == 1 ? 'btn-addtabs' : ''}" href="{$v.ext_arr.url ?? 'javascript:;'}" target="{:isset($v.ext_arr.url_type) && !empty($v.ext_arr.url) && $v.ext_arr.url_type == 3 ? 'target':'_self'}">{$v.content|htmlentities}</a></td>
<td>{$v.createtime|time_text}</td>
<td style="text-align: center">
{if $v.readtime == null}
<button class="btn btn-success mark-event" data-url="{:url('notice/admin/mark', ['id' => $v.id])}">已读</button>
{else}
已读
{/if}
</td>
</tr>
{/foreach}
</tbody>
</table>
{if $list->count() == 0}
<div class="nothing" style="text-align: center;">暂无消息</div>
{/if}
{$list->render()}
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,48 @@
<form id="add-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('admin_id')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-admin_id" min="0" data-rule="required" data-source="auth/admin" data-field="nickname" class="form-control selectpage" name="row[admin_id]" type="text" value="">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Nickname')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-nickname" class="form-control" name="row[nickname]" type="text">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Avatar')}:</label>
<div class="col-xs-12 col-sm-8">
<div class="input-group">
<input id="c-avatar" class="form-control" size="50" name="row[avatar]" type="text">
<div class="input-group-addon no-border no-padding">
<span><button type="button" id="plupload-avatar" class="btn btn-danger plupload" data-input-id="c-avatar" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp" data-multiple="false" data-preview-id="p-avatar"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
<span><button type="button" id="fachoose-avatar" class="btn btn-primary fachoose" data-input-id="c-avatar" data-mimetype="image/*" data-multiple="false"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
</div>
<span class="msg-box n-right" for="c-avatar"></span>
</div>
<ul class="row list-inline plupload-preview" id="p-avatar"></ul>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Openid')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-openid" class="form-control" name="row[openid]" type="text">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Unionid')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-unionID" class="form-control" name="row[unionid]" type="text">
</div>
</div>
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>
</form>

View File

@ -0,0 +1,42 @@
<form id="add-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
<div class="alert alert-success">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<p>
绑定微信仅用于接收微信公众号模版消息通知、必须关注公众号。
</p>
<p>
一个微信号可以绑定多个管理员,每个管理员只能绑定一个微信号。
</p>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
绑定账号
<a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" style="color: #ffff"><i class="fa fa-refresh"></i> </a>
</h3>
</div>
<div class="panel-body">
{if $exist}
<div style="text-align: center">
<div>
已绑定账号`{$exist.nickname|htmlentities}`
<button id="remove-event" type="button" class="btn btn-primary btn-ajax" data-url="" data-confirm="确认操作">解绑</button>
</div>
</div>
{else}
<div style="text-align: center">
<p>扫描二维码绑定账号</p>
<div style="height: 200px; width: 200px; margin: 0 auto;" id="qrcode">
</div>
</div>
{/if}
</div>
</div>
</form>

View File

@ -0,0 +1,50 @@
<form id="edit-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('admin_id')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-admin_id" min="0" data-rule="required" data-source="auth/admin" data-field="nickname" class="form-control selectpage" name="row[admin_id]" type="text" value="{$row.admin_id|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Nickname')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-nickname" class="form-control" name="row[nickname]" type="text" value="{$row.nickname|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Avatar')}:</label>
<div class="col-xs-12 col-sm-8">
<div class="input-group">
<input id="c-avatar" class="form-control" size="50" name="row[avatar]" type="text" value="{$row.avatar|htmlentities}">
<div class="input-group-addon no-border no-padding">
<span><button type="button" id="plupload-avatar" class="btn btn-danger plupload" data-input-id="c-avatar" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp" data-multiple="false" data-preview-id="p-avatar"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
<span><button type="button" id="fachoose-avatar" class="btn btn-primary fachoose" data-input-id="c-avatar" data-mimetype="image/*" data-multiple="false"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
</div>
<span class="msg-box n-right" for="c-avatar"></span>
</div>
<ul class="row list-inline plupload-preview" id="p-avatar"></ul>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Openid')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-openid" class="form-control" name="row[openid]" type="text" value="{$row.openid|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Unionid')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-unionID" class="form-control" name="row[unionID]" type="text" value="{$row.unionid|htmlentities}">
</div>
</div>
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>
</form>

View File

@ -0,0 +1,26 @@
<div class="panel panel-default panel-intro">
{:build_heading()}
<div class="panel-body">
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade active in" id="one">
<div class="widget-body no-padding">
<div id="toolbar" class="toolbar">
<a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a>
<a href="javascript:;" class="btn btn-success btn-add {:$auth->check('notice/admin_mptemplate/add')?'':'hide'}" title="{:__('Add')}" ><i class="fa fa-plus"></i> {:__('Add')}</a>
<a href="javascript:;" class="btn btn-success btn-edit btn-disabled disabled {:$auth->check('notice/admin_mptemplate/edit')?'':'hide'}" title="{:__('Edit')}" ><i class="fa fa-pencil"></i> {:__('Edit')}</a>
<a href="javascript:;" class="btn btn-danger btn-del btn-disabled disabled {:$auth->check('notice/admin_mptemplate/del')?'':'hide'}" title="{:__('Delete')}" ><i class="fa fa-trash"></i> {:__('Delete')}</a>
<a class="btn btn-success btn-recyclebin btn-dialog {:$auth->check('notice/admin_mptemplate/recyclebin')?'':'hide'}" href="notice/admin_mptemplate/recyclebin" title="{:__('Recycle bin')}"><i class="fa fa-recycle"></i> {:__('Recycle bin')}</a>
</div>
<table id="table" class="table table-striped table-bordered table-hover table-nowrap"
data-operate-edit="{:$auth->check('notice/admin_mptemplate/edit')}"
data-operate-del="{:$auth->check('notice/admin_mptemplate/del')}"
width="100%">
</table>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,25 @@
<div class="panel panel-default panel-intro">
{:build_heading()}
<div class="panel-body">
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade active in" id="one">
<div class="widget-body no-padding">
<div id="toolbar" class="toolbar">
{:build_toolbar('refresh')}
<a class="btn btn-info btn-multi btn-disabled disabled {:$auth->check('notice/admin_mptemplate/restore')?'':'hide'}" href="javascript:;" data-url="notice/admin_mptemplate/restore" data-action="restore"><i class="fa fa-rotate-left"></i> {:__('Restore')}</a>
<a class="btn btn-danger btn-multi btn-disabled disabled {:$auth->check('notice/admin_mptemplate/destroy')?'':'hide'}" href="javascript:;" data-url="notice/admin_mptemplate/destroy" data-action="destroy"><i class="fa fa-times"></i> {:__('Destroy')}</a>
<a class="btn btn-success btn-restoreall {:$auth->check('notice/admin_mptemplate/restore')?'':'hide'}" href="javascript:;" data-url="notice/admin_mptemplate/restore" title="{:__('Restore all')}"><i class="fa fa-rotate-left"></i> {:__('Restore all')}</a>
<a class="btn btn-danger btn-destroyall {:$auth->check('notice/admin_mptemplate/destroy')?'':'hide'}" href="javascript:;" data-url="notice/admin_mptemplate/destroy" title="{:__('Destroy all')}"><i class="fa fa-times"></i> {:__('Destroy all')}</a>
</div>
<table id="table" class="table table-striped table-bordered table-hover"
data-operate-restore="{:$auth->check('notice/admin_mptemplate/restore')}"
data-operate-destroy="{:$auth->check('notice/admin_mptemplate/destroy')}"
width="100%">
</table>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,88 @@
<form id="add-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Platform')}:</label>
<div class="col-xs-12 col-sm-8">
<select id="c-platform" data-rule="required" class="form-control selectpicker" multiple="" name="row[platform][]">
{foreach name="platformList" item="vo"}
<option value="{$key|htmlentities}" {in name="key" value="user"}selected{/in}>{$vo|htmlentities}</option>
{/foreach}
</select>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Type')}:</label>
<div class="col-xs-12 col-sm-8">
<select id="c-type" data-rule="required" class="form-control selectpicker" multiple="" name="row[type][]">
{foreach name="typeList" item="vo"}
<option value="{$key|htmlentities}" {in name="key" value=""}selected{/in}>{$vo|htmlentities}</option>
{/foreach}
</select>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Name')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-name" data-rule="required" class="form-control" name="row[name]" type="text">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Event')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-event" data-rule="required" class="form-control" name="row[event]" type="text">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Send_num')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-send_num" data-rule="required" class="form-control" name="row[send_num]" type="number" value="0">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Send_fail_num')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-send_fail_num" data-rule="required" class="form-control" name="row[send_fail_num]" type="number" value="0">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Content')}:</label>
<div class="col-xs-12 col-sm-8">
<dl class="fieldlist" data-name="row[content]">
<dd>
<ins>字段名</ins>
<ins>注释</ins>
</dd>
<dd>
<a href="javascript:;" class="btn btn-sm btn-success btn-append"><i class="fa fa-plus"></i> 追加</a>
</dd>
<textarea name="row[content]" class="form-control hide" cols="30" rows="5"></textarea>
</dl>
<div class="help-block">
温馨提示没有user_id字段情况下没有用户昵称等字段、前台用户无法收到消息。
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Visible_switch')}:</label>
<div class="col-xs-12 col-sm-8">
<select id="c-visible_switch" data-rule="required" class="form-control selectpicker" name="row[visible_switch]">
{foreach name="visibleSwitchList" item="vo"}
<option value="{$key|htmlentities}" {in name="key" value="1"}selected{/in}>{$vo|htmlentities}</option>
{/foreach}
</select>
</div>
</div>
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>
</form>

View File

@ -0,0 +1,87 @@
<form id="edit-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Platform')}:</label>
<div class="col-xs-12 col-sm-8">
<select id="c-platform" data-rule="required" class="form-control selectpicker" multiple="" name="row[platform][]">
{foreach name="platformList" item="vo"}
<option value="{$key|htmlentities}" {in name="key" value="$row.platform"}selected{/in}>{$vo|htmlentities}</option>
{/foreach}
</select>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Type')}:</label>
<div class="col-xs-12 col-sm-8">
<select id="c-type" data-rule="required" class="form-control selectpicker" multiple="" name="row[type][]">
{foreach name="typeList" item="vo"}
<option value="{$key|htmlentities}" {in name="key" value="$row.type"}selected{/in}>{$vo|htmlentities}</option>
{/foreach}
</select>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Name')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-name" data-rule="required" class="form-control" name="row[name]" type="text" value="{$row.name|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Event')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-event" data-rule="required" class="form-control" name="row[event]" type="text" value="{$row.event|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Send_num')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-send_num" data-rule="required" class="form-control" name="row[send_num]" type="number" value="{$row.send_num|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Send_fail_num')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-send_fail_num" data-rule="required" class="form-control" name="row[send_fail_num]" type="number" value="{$row.send_fail_num|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Content')}:</label>
<div class="col-xs-12 col-sm-8">
<div class="form-group">
<dl class="fieldlist" data-name="row[content]">
<dd>
<ins>字段名</ins>
<ins>注释</ins>
</dd>
<dd>
<a href="javascript:;" class="btn btn-sm btn-success btn-append"><i class="fa fa-plus"></i> 追加</a>
</dd>
<textarea name="row[content]" class="form-control hide" cols="30" rows="5">{$row->content}</textarea>
</dl>
</div>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Visible_switch')}:</label>
<div class="col-xs-12 col-sm-8">
<select id="c-visible_switch" data-rule="required" class="form-control selectpicker" name="row[visible_switch]">
{foreach name="visibleSwitchList" item="vo"}
<option value="{$key|htmlentities}" {in name="key" value="$row.visible_switch"}selected{/in}>{$vo|htmlentities}</option>
{/foreach}
</select>
</div>
</div>
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>
</form>

View File

@ -0,0 +1,35 @@
<div class="panel panel-default panel-intro">
{:build_heading()}
<div class="panel-body">
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade active in" id="one">
<div class="widget-body no-padding">
<div id="toolbar" class="toolbar">
<a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a>
<a href="javascript:;" class="btn btn-success btn-add {:$auth->check('notice/event/add')?'':'hide'}" title="{:__('Add')}" ><i class="fa fa-plus"></i> {:__('Add')}</a>
<a href="javascript:;" class="btn btn-success btn-edit btn-disabled disabled {:$auth->check('notice/event/edit')?'':'hide'}" title="{:__('Edit')}" ><i class="fa fa-pencil"></i> {:__('Edit')}</a>
<a href="javascript:;" class="btn btn-danger btn-del btn-disabled disabled {:$auth->check('notice/event/del')?'':'hide'}" title="{:__('Delete')}" ><i class="fa fa-trash"></i> {:__('Delete')}</a>
<div class="dropdown btn-group {:$auth->check('notice/event/multi')?'':'hide'}">
<a class="btn btn-primary btn-more dropdown-toggle btn-disabled disabled" data-toggle="dropdown"><i class="fa fa-cog"></i> {:__('More')}</a>
<ul class="dropdown-menu text-left" role="menu">
<li><a class="btn btn-link btn-multi btn-disabled disabled" href="javascript:;" data-params="visible_switch=1"><i class="fa fa-eye"></i> {:__('Set to normal')}</a></li>
<li><a class="btn btn-link btn-multi btn-disabled disabled" href="javascript:;" data-params="visible_switch=0"><i class="fa fa-eye-slash"></i> {:__('Set to hidden')}</a></li>
</ul>
</div>
<a class="btn btn-success btn-recyclebin btn-dialog {:$auth->check('notice/event/recyclebin')?'':'hide'}" href="notice/event/recyclebin" title="{:__('Recycle bin')}"><i class="fa fa-recycle"></i> {:__('Recycle bin')}</a>
</div>
<table id="table" class="table table-striped table-bordered table-hover table-nowrap"
data-operate-edit="{:$auth->check('notice/event/edit')}"
data-operate-del="{:$auth->check('notice/event/del')}"
data-operate-test="{:$auth->check('notice/event/test')}"
width="100%">
</table>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,25 @@
<div class="panel panel-default panel-intro">
{:build_heading()}
<div class="panel-body">
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade active in" id="one">
<div class="widget-body no-padding">
<div id="toolbar" class="toolbar">
{:build_toolbar('refresh')}
<a class="btn btn-info btn-multi btn-disabled disabled {:$auth->check('notice/event/restore')?'':'hide'}" href="javascript:;" data-url="notice/event/restore" data-action="restore"><i class="fa fa-rotate-left"></i> {:__('Restore')}</a>
<a class="btn btn-danger btn-multi btn-disabled disabled {:$auth->check('notice/event/destroy')?'':'hide'}" href="javascript:;" data-url="notice/event/destroy" data-action="destroy"><i class="fa fa-times"></i> {:__('Destroy')}</a>
<a class="btn btn-success btn-restoreall {:$auth->check('notice/event/restore')?'':'hide'}" href="javascript:;" data-url="notice/event/restore" title="{:__('Restore all')}"><i class="fa fa-rotate-left"></i> {:__('Restore all')}</a>
<a class="btn btn-danger btn-destroyall {:$auth->check('notice/event/destroy')?'':'hide'}" href="javascript:;" data-url="notice/event/destroy" title="{:__('Destroy all')}"><i class="fa fa-times"></i> {:__('Destroy all')}</a>
</div>
<table id="table" class="table table-striped table-bordered table-hover"
data-operate-restore="{:$auth->check('notice/event/restore')}"
data-operate-destroy="{:$auth->check('notice/event/destroy')}"
width="100%">
</table>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,61 @@
<form id="edit-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
<div class="alert">
<h4>{$row.name|htmlentities}</h4>
</div>
<table class="table table-hover">
<thead>
<tr>
<th>字段名</th>
<th>备注</th>
<th></th>
</tr>
</thead>
<tbody>
{foreach $row->content_arr as $k=>$v}
<tr>
<td>{$k|htmlentities}</td>
<td>{$v|htmlentities}</td>
<td class="form-inline"><input type="text" name="row[field][{$k|htmlentities}]" class="form-control"></td>
</tr>
{/foreach}
<tr>
<td>receiver_admin_ids</td>
<td>(选填)接受消息管理员ids</td>
<td class="form-inline"><input type="text" name="row[receiver_admin_ids]" class="form-control selectpage" data-source="auth/admin" data-field="nickname"></td>
</tr>
<tr>
<td>receiver_admin_group_ids</td>
<td>(选填)接受消息管理员组别ids</td>
<td class="form-inline"><input type="text" name="row[receiver_admin_group_ids]" class="form-control selectpage" data-source="auth/group" data-field="name"></td>
</tr>
</tbody>
</table>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">调用代码</h3>
</div>
<div class="panel-body">
<pre>
// 发送通知-{$row.name|htmlentities}
$noticeParams = [
'event' => '{$row.event|htmlentities}',
'params' => {:var_export($row->content_arr2, true)}
];
\Think\Hook::listen('send_notice', $noticeParams);
</pre>
</div>
</div>
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>
</form>

View File

@ -0,0 +1,85 @@
<form id="add-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
<input id="row[type]" class="form-control" name="row[type]" type="hidden" value="msg">
<!-- <div class="form-group">-->
<!-- <label class="control-label col-xs-12 col-sm-2">{:__('Type')}:</label>-->
<!-- <div class="col-xs-12 col-sm-8">-->
<!-- -->
<!-- <select id="c-type" data-rule="required" class="form-control selectpicker" name="row[type]">-->
<!-- {foreach name="typeList" item="vo"}-->
<!-- <option value="{$key|htmlentities}" {in name="key" value=""}selected{/in}>{$vo|htmlentities}</option>-->
<!-- {/foreach}-->
<!-- </select>-->
<!-- </div>-->
<!-- </div>-->
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Name')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-name" class="form-control" name="row[name]" type="text">
</div>
</div>
<!-- <div class="form-group">-->
<!-- <label class="control-label col-xs-12 col-sm-2">{:__('Event')}:</label>-->
<!-- <div class="col-xs-12 col-sm-8">-->
<!-- <input id="c-event" class="form-control" name="row[event]" type="text">-->
<!-- </div>-->
<!-- </div>-->
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Platform')}:</label>
<div class="col-xs-12 col-sm-8">
<select id="c-platform" class="form-control selectpicker" name="row[platform]">
{foreach name="platformList" item="vo"}
<option value="{$key|htmlentities}" {in name="key" value="user"}selected{/in}>{$vo|htmlentities}</option>
{/foreach}
</select>
</div>
</div>
<div class="form-group hidden" data-favisible="platform=user">
<label class="control-label col-xs-12 col-sm-2">用户:</label>
<div class="col-xs-12 col-sm-8">
<input data-source="user/user" data-field="nickname" data-rule="required" class="form-control selectpage" data-multiple="true" name="row[id1]" type="text" value="">
</div>
</div>
<div class="form-group hidden" data-favisible="platform=admin">
<label class="control-label col-xs-12 col-sm-2">管理员:</label>
<div class="col-xs-12 col-sm-8">
<input data-multiple="true" data-source="auth/admin" data-field="nickname" data-rule="required" class="form-control selectpage" name="row[id2]" type="text" value="">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Content')}:</label>
<div class="col-xs-12 col-sm-8">
<textarea id="c-content" data-rule="required" class="form-control editor" rows="5" name="row[content]" cols="50"></textarea>
</div>
</div>
<!-- <div class="form-group">-->
<!-- <label class="control-label col-xs-12 col-sm-2">{:__('Ext')}:</label>-->
<!-- <div class="col-xs-12 col-sm-8">-->
<!-- <textarea id="c-ext" class="form-control " rows="5" name="row[ext]" cols="50"></textarea>-->
<!-- </div>-->
<!-- </div>-->
<!-- <div class="form-group">-->
<!-- <label class="control-label col-xs-12 col-sm-2">{:__('Notice_template_id')}:</label>-->
<!-- <div class="col-xs-12 col-sm-8">-->
<!-- <input id="c-notice_template_id" data-rule="required" data-name="id" data-source="notice/template/index" class="form-control" name="row[notice_template_id]" type="text" value="">-->
<!-- </div>-->
<!-- </div>-->
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">阅读时间:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-readtime" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-use-current="true" name="row[readtime]" type="text" value="">
</div>
</div>
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>
</form>

View File

@ -0,0 +1,76 @@
<form id="edit-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Type')}:</label>
<div class="col-xs-12 col-sm-8">
<select id="c-type" data-rule="required" class="form-control selectpicker" name="row[type]">
{foreach name="typeList" item="vo"}
<option value="{$key|htmlentities}" {in name="key" value="$row.type"}selected{/in}>{$vo|htmlentities}</option>
{/foreach}
</select>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Name')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-name" class="form-control" name="row[name]" type="text" value="{$row.name|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Event')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-event" class="form-control" name="row[event]" type="text" value="{$row.event|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Platform')}:</label>
<div class="col-xs-12 col-sm-8">
<select id="c-platform" class="form-control selectpicker" name="row[platform]">
{foreach name="platformList" item="vo"}
<option value="{$key|htmlentities}" {in name="key" value="$row.platform"}selected{/in}>{$vo|htmlentities}</option>
{/foreach}
</select>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('To_id')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-to_id" data-rule="required" data-source="to/index" class="form-control" name="row[to_id]" type="text" value="{$row.to_id|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Content')}:</label>
<div class="col-xs-12 col-sm-8">
<textarea id="c-content" data-rule="required" class="form-control editor" rows="5" name="row[content]" cols="50">{$row.content|htmlentities}</textarea>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Ext')}:</label>
<div class="col-xs-12 col-sm-8">
<textarea id="c-ext" class="form-control " rows="5" name="row[ext]" cols="50">{$row.ext|htmlentities}</textarea>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Notice_template_id')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-notice_template_id" data-rule="required" data-source="notice/template/index" class="form-control" name="row[notice_template_id]" type="text" value="{$row.notice_template_id|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Readtime')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-readtime" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-use-current="true" name="row[readtime]" type="text" value="{:$row.readtime?datetime($row.readtime):''}">
</div>
</div>
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>
</form>

View File

@ -0,0 +1,26 @@
<div class="panel panel-default panel-intro">
{:build_heading()}
<div class="panel-body">
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade active in" id="one">
<div class="widget-body no-padding">
<div id="toolbar" class="toolbar">
<a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a>
<a href="javascript:;" class="btn btn-success btn-add {:$auth->check('notice/notice/add')?'':'hide'}" title="{:__('Add')}" ><i class="fa fa-plus"></i> {:__('Add')}</a>
<!-- <a href="javascript:;" class="btn btn-success btn-edit btn-disabled disabled {:$auth->check('notice/notice/edit')?'':'hide'}" title="{:__('Edit')}" ><i class="fa fa-pencil"></i> {:__('Edit')}</a>-->
<a href="javascript:;" class="btn btn-danger btn-del btn-disabled disabled {:$auth->check('notice/notice/del')?'':'hide'}" title="{:__('Delete')}" ><i class="fa fa-trash"></i> {:__('Delete')}</a>
<a class="btn btn-success btn-recyclebin btn-dialog {:$auth->check('notice/notice/recyclebin')?'':'hide'}" href="notice/notice/recyclebin" title="{:__('Recycle bin')}"><i class="fa fa-recycle"></i> {:__('Recycle bin')}</a>
</div>
<table id="table" class="table table-striped table-bordered table-hover table-nowrap"
data-operate-edit="0"
data-operate-del="{:$auth->check('notice/notice/del')}"
width="100%">
</table>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,25 @@
<div class="panel panel-default panel-intro">
{:build_heading()}
<div class="panel-body">
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade active in" id="one">
<div class="widget-body no-padding">
<div id="toolbar" class="toolbar">
{:build_toolbar('refresh')}
<a class="btn btn-info btn-multi btn-disabled disabled {:$auth->check('notice/notice/restore')?'':'hide'}" href="javascript:;" data-url="notice/notice/restore" data-action="restore"><i class="fa fa-rotate-left"></i> {:__('Restore')}</a>
<a class="btn btn-danger btn-multi btn-disabled disabled {:$auth->check('notice/notice/destroy')?'':'hide'}" href="javascript:;" data-url="notice/notice/destroy" data-action="destroy"><i class="fa fa-times"></i> {:__('Destroy')}</a>
<a class="btn btn-success btn-restoreall {:$auth->check('notice/notice/restore')?'':'hide'}" href="javascript:;" data-url="notice/notice/restore" title="{:__('Restore all')}"><i class="fa fa-rotate-left"></i> {:__('Restore all')}</a>
<a class="btn btn-danger btn-destroyall {:$auth->check('notice/notice/destroy')?'':'hide'}" href="javascript:;" data-url="notice/notice/destroy" title="{:__('Destroy all')}"><i class="fa fa-times"></i> {:__('Destroy all')}</a>
</div>
<table id="table" class="table table-striped table-bordered table-hover"
data-operate-restore="{:$auth->check('notice/notice/restore')}"
data-operate-destroy="{:$auth->check('notice/notice/destroy')}"
width="100%">
</table>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,76 @@
<form id="add-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Notice_event_id')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-notice_event_id" data-rule="required" data-source="notice/event/index" class="form-control selectpage" name="row[notice_event_id]" type="text" value="">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Platform')}:</label>
<div class="col-xs-12 col-sm-8">
<select id="c-platform" data-rule="required" class="form-control selectpicker" name="row[platform]">
{foreach name="platformList" item="vo"}
<option value="{$key|htmlentities}" {in name="key" value="user"}selected{/in}>{$vo|htmlentities}</option>
{/foreach}
</select>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Type')}:</label>
<div class="col-xs-12 col-sm-8">
<select id="c-type" data-rule="required" class="form-control selectpicker" name="row[type]">
{foreach name="typeList" item="vo"}
<option value="{$key|htmlentities}" {in name="key" value=""}selected{/in}>{$vo|htmlentities}</option>
{/foreach}
</select>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Content')}:</label>
<div class="col-xs-12 col-sm-8">
<textarea id="c-content" class="form-control editor" rows="5" name="row[content]" cols="50"></textarea>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Visible_switch')}:</label>
<div class="col-xs-12 col-sm-8">
<select id="c-visible_switch" data-rule="required" class="form-control selectpicker" name="row[visible_switch]">
{foreach name="visibleSwitchList" item="vo"}
<option value="{$key|htmlentities}" {in name="key" value="1"}selected{/in}>{$vo|htmlentities}</option>
{/foreach}
</select>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Send_num')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-send_num" data-rule="required" class="form-control" name="row[send_num]" type="number" value="0">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Send_fail_num')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-send_fail_num" data-rule="required" class="form-control" name="row[send_fail_num]" type="number" value="0">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('Ext')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-ext" class="form-control" name="row[ext]" type="text">
</div>
</div>
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>
</form>

View File

@ -0,0 +1,158 @@
<form id="edit-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">({$row.id??'0'}){:__('Visible_switch')}:</label>
<div class="col-xs-12 col-sm-8">
<select id="c-visible_switch" data-rule="required" class="form-control selectpicker" name="row[visible_switch]">
{foreach name="visibleSwitchList" item="vo"}
<option value="{$key|htmlentities}" {in name="key" value="$row.visible_switch"}selected{/in}>{$vo|htmlentities}</option>
{/foreach}
</select>
</div>
</div>
<!-- 公众号模版消息-->
{if $row.type == 'mptemplate' || $row.type == 'miniapp' || $row.type == 'sms'}
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('mptemplate_id')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-mptemplate_id" data-rule="required" class="form-control" name="row[mptemplate_id]" type="text" value="{$row.mptemplate_id|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('mptemplate_json')}:</label>
<div class="col-xs-12 col-sm-8">
<p class="help-block">字段格式 {{字段名}}, 例如: {{user_nickname}}、必须严格按照模版消息参数来,否则会发送失败</p>
<dl class="fieldlist" data-name="row[mptemplate_json]">
<dd>
<ins>模版参数</ins>
<ins>字段</ins>
</dd>
<dd>
<a href="javascript:;" class="btn btn-sm btn-success btn-append"><i class="fa fa-plus"></i> 追加</a>
</dd>
<textarea name="row[mptemplate_json]" class="form-control hide" cols="30" rows="5">{$row.mptemplate_json|htmlentities}</textarea>
</dl>
</div>
</div>
{else}
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('content')}:</label>
<div class="col-xs-12 col-sm-8">
<p class="help-block">字段格式 {{字段名}}, 例如: {{user_nickname}}</p>
<textarea class="form-control" rows="3" name="row[content]">{$row.content|htmlentities}</textarea>
</div>
</div>
{/if}
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('url_type')}:</label>
<div class="col-xs-12 col-sm-8">
<select id="c-url_type" data-rule="required" class="form-control selectpicker" name="row[url_type]">
{foreach name="urlTypeList" item="vo"}
<option value="{$key|htmlentities}" {in name="key" value="$row.url_type"}selected{/in}>{$vo|htmlentities}</option>
{/foreach}
</select>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">{:__('url')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-url" data-rule="" class="form-control" name="row[url]" type="text" value="{$row.url|htmlentities}">
<div class="help-block">
温馨提示链接非http开头非/开头,会自动调用 url 补全url和url标题支持使用字段
</div>
</div>
</div>
<div class="form-group" data-favisible="url_type=2||url_type=1">
<label class="control-label col-xs-12 col-sm-2">{:__('url_title')}:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-url_title" data-rule="" class="form-control" name="row[url_title]" type="text" value="{$row.url_title|htmlentities}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">支持字段</label>
<div class="col-xs-12 col-sm-8">
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>字段</th>
<th>注释</th>
</tr>
</thead>
<tbody>
{foreach $event->content_arr as $k => $v}
<tr>
<td>{$k|htmlentities}</td>
<td>{$v|htmlentities}</td>
</tr>
{/foreach}
</tbody>
</table>
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">默认字段</label>
<div class="col-xs-12 col-sm-8">
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>字段</th>
<th>注释</th>
</tr>
</thead>
<tbody>
{if array_key_exists("user_id",$event->content_arr)}
<tr>
<td>user_nickname</td>
<td>用户昵称</td>
</tr>
<tr>
<td>user_email</td>
<td>邮箱</td>
</tr>
<tr>
<td>user_mobile</td>
<td>手机号</td>
</tr>
{/if}
<tr>
<td>createtime</td>
<td>发送时间(年-月-日 时:分:秒)</td>
</tr>
<tr>
<td>createdate</td>
<td>发送日期(年-月-日)</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="form-group layer-footer">
<label class="control-label col-xs-12 col-sm-2"></label>
<div class="col-xs-12 col-sm-8">
<button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
<button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
</div>
</div>
</form>

View File

@ -0,0 +1,66 @@
<div class="panel panel-default panel-intro">
<div class="panel-heading">
{:build_heading(null,FALSE)}
<ul class="nav nav-tabs" data-field="platform">
{foreach name="platformList" item="vo"}
<li class="{:$params.platform === (string)$key ? 'active' : ''}"><a href="#t-{$key|htmlentities}" data-value="{$key|htmlentities}" data-toggle="tab">{$vo|htmlentities}</a></li>
{/foreach}
</ul>
</div>
<form role="form">
<div class="panel-body">
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade active in" id="one">
<div class="widget-body no-padding">
<div id="toolbar" class="toolbar">
</div>
<table class="table table-striped table-bordered table-hover table-nowrap">
<thead>
<tr>
<th>消息名称</th>
{foreach $typeList as $v}
<th>{$v|htmlentities}</th>
{/foreach}
</tr>
</thead>
<tbody>
{foreach $list as $k=>$item}
<tr>
<td>{$item.noticeevent.name|htmlentities}</td>
{foreach $item.item as $k2=>$v2}
<td>
{if $v2.error}
<div style="line-height: 30px;">
<!-- {$v2.error|htmlentities}-->
未开启 <i class="fa fa-info-circle" data-toggle="tooltip" title="" data-original-title="请在消息事件里面开启"></i>
</div>
{else}
<div class="parent" data-notice_event_id="{$item.noticeevent.id|htmlentities}" data-platform="{$v2.platform|htmlentities}" data-type="{$v2.type|htmlentities}">
<div style="display: flex; align-items: center">
<div class="btn-group" style="line-height: 30px; background: rgba(27,180,146,0.3);">
<button type="button" class="btn btn-success btn-dialog" data-url="notice/template/edit?notice_event_id={$item.noticeevent.id|htmlentities}&platform={$v2.platform|htmlentities}&type={$v2.type|htmlentities}" data-title="{$item.noticeevent.name|htmlentities}配置">配置</button>
<span style="padding-right: 10px; padding-left: 10px; color: rgb(27,180,146)">发送次数:{$v2.send_num|htmlentities}</span>
</div>
<div style="margin-left: 15px;">
<input id="c-switch-{$k|htmlentities}-{$k2|htmlentities}" name="switch-{$k|htmlentities}-{$k2|htmlentities}" class="form-control switch-input" type="hidden" value="{$v2.visible_switch|htmlentities}">
<a href="javascript:;" data-toggle="switcher" class="btn-switcher "
data-input-id="c-switch-{$k|htmlentities}-{$k2|htmlentities}" data-yes="1" data-no="0"><i
class="fa fa-toggle-on text-success {$v2.visible_switch==0?'fa-flip-horizontal text-gray':''} fa-2x"></i></a>
</div>
</div>
</div>
{/if}
</td>
{/foreach}
</tr>
{/foreach}
</tbody>
</table>
</div>
</div>
</div>
</div>
</form>
</div>

View File

@ -76,6 +76,9 @@ $manystoreHooks = [
'shop_update_after' => [ // 机构数据变更
'app\\common\\listener\\manystore\\ShopHook'
],
'shop_apply_create_after' => [ // 主理人申请提交
'app\\common\\listener\\manystore\\ShopHook'
],
];

View File

@ -223,4 +223,57 @@ class ShopHook
}
// 主理人申请提交
public function shopApplyCreateAfter(&$params)
{
["shop"=>$shop] = $params;
$user = User::where("id" ,$shop["user_id"])->find();
//记录订单日志
$desc = "您申请的认证{$shop['name']}已提交审核审核时间为1-3日内,请耐心等待审核结果";
$title = "入驻申请提交";
$mini_type = "shop_apply";
$to_type="user";
$to_id = $shop["user_id"];
$status ="system";
$platform="user";
$oper_id=0;
$oper_type="system";
$params=[
"event"=>"shop_apply_create_after",
"shop_id"=>$shop["id"],
"name"=>$shop["name"],
];
$param = [
"name" => $shop['name'],
"realname" => $shop["realname"],
"mobile" => $shop["mobile"],
"address" => $shop["address"],
];
//发给用户
(new MessageConfig)
->setTemplate($params["event"])
->setTemplateData($param)
->setToUid($to_id)
->setMessageStatus($status)
->setMessageMiniType($mini_type)
->setMessageParams($params)
->sendMessage();
}
}

View File

@ -159,6 +159,10 @@ class ShopApply extends BaseModel
// $res = false;
try{
$res = self::create($params);
//调用订单事件
$data = ['shop' => $res];
\think\Hook::listen('shop_apply_create_after', $data);
if($trans){
self::commitTrans();

View File

@ -0,0 +1,44 @@
<?php
namespace app\common\model\notice;
use think\Model;
use traits\model\SoftDelete;
class AdminMptemplate extends Model
{
use SoftDelete;
// 表名
protected $name = 'notice_admin_mptemplate';
// 自动写入时间戳字段
protected $autoWriteTimestamp = 'int';
// 定义时间戳字段名
protected $createTime = 'createtime';
protected $updateTime = 'updatetime';
protected $deleteTime = 'deletetime';
// 追加属性
protected $append = [
];
public function admin()
{
return $this->belongsTo('app\admin\model\Admin', 'admin_id', 'id', [], 'LEFT')->setEagerlyType(0);
}
}

View File

@ -0,0 +1,106 @@
<?php
namespace app\common\model\notice;
use think\Model;
use traits\model\SoftDelete;
class Notice extends Model
{
use SoftDelete;
// 表名
protected $name = 'notice';
// 自动写入时间戳字段
protected $autoWriteTimestamp = 'int';
// 定义时间戳字段名
protected $createTime = 'createtime';
protected $updateTime = 'updatetime';
protected $deleteTime = 'deletetime';
// 追加属性
protected $append = [
// 'type_text',
// 'platform_text',
// 'readtime_text'
'ext_arr',
];
public function getTypeList()
{
return ['msg' => __('Type msg'), 'email' => __('Type email'), 'mptemplate' => '模版消息(公众号)', 'miniapp' => '小程序订阅消息', 'sms' => '短信通知'];
}
public function getPlatformList()
{
return ['user' => __('Platform user'), 'admin' => __('Platform admin')];
}
public function getTypeTextAttr($value, $data)
{
$value = $value ? $value : (isset($data['type']) ? $data['type'] : '');
$list = $this->getTypeList();
return isset($list[$value]) ? $list[$value] : '';
}
public function getPlatformTextAttr($value, $data)
{
$value = $value ? $value : (isset($data['platform']) ? $data['platform'] : '');
$list = $this->getPlatformList();
return isset($list[$value]) ? $list[$value] : '';
}
public function getReadtimeTextAttr($value, $data)
{
$value = $value ? $value : (isset($data['readtime']) ? $data['readtime'] : '');
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
}
protected function setReadtimeAttr($value)
{
return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
}
public function noticetemplate()
{
return $this->belongsTo('NoticeTemplate', 'notice_template_id', 'id', [], 'LEFT')->setEagerlyType(0);
}
public function getExtArrAttr($value, $data)
{
$value = $data['ext'] ?? '';
$value = json_decode($value, true) ?? [];
if (!isset($value['url'])) {
$value['url'] = null;
}
if (!isset($value['url_type'])) {
$value['url_type'] = null;
}
if (!isset($value['url_title'])) {
$value['url_title'] = '';
}
if ($value['url']) {
if (0 === stripos($value['url'], 'http')) {
} else if (0 === stripos($value['url'], '/')) {
} else {
if (request()->module() != 'admin') {
$value['url'] = url($value['url']);
}
}
}
return $value;
}
}

View File

@ -0,0 +1,99 @@
<?php
namespace app\common\model\notice;
use think\Model;
use think\db\Query;
use traits\model\SoftDelete;
class NoticeEvent extends Model
{
use SoftDelete;
// 表名
protected $name = 'notice_event';
// 自动写入时间戳字段
protected $autoWriteTimestamp = 'int';
// 定义时间戳字段名
protected $createTime = 'createtime';
protected $updateTime = 'updatetime';
protected $deleteTime = 'deletetime';
// 追加属性
protected $append = [
// 'platform_text',
// 'type_text',
// 'visible_switch_text'
];
public function getContentArrAttr()
{
$value = $this['content'];
$value = (array) json_decode($value);
return $value;
}
public function getPlatformList()
{
return ['user' => __('Platform user'), 'admin' => __('Platform admin')];
}
public function getTypeList()
{
return ['msg' => __('Type msg'), 'email' => __('Type email'), 'mptemplate' => '模版消息(公众号)', 'miniapp' => '小程序订阅消息', 'sms' => '短信通知'];
}
public function getVisibleSwitchList()
{
return ['0' => __('Visible_switch 0'), '1' => __('Visible_switch 1')];
}
public function getPlatformTextAttr($value, $data)
{
$value = $value ? $value : (isset($data['platform']) ? $data['platform'] : '');
$valueArr = explode(',', $value);
$list = $this->getPlatformList();
return implode(',', array_intersect_key($list, array_flip($valueArr)));
}
public function getTypeTextAttr($value, $data)
{
$value = $value ? $value : (isset($data['type']) ? $data['type'] : '');
$valueArr = explode(',', $value);
$list = $this->getTypeList();
return implode(',', array_intersect_key($list, array_flip($valueArr)));
}
public function getVisibleSwitchTextAttr($value, $data)
{
$value = $value ? $value : (isset($data['visible_switch']) ? $data['visible_switch'] : '');
$list = $this->getVisibleSwitchList();
return isset($list[$value]) ? $list[$value] : '';
}
protected function setPlatformAttr($value)
{
return is_array($value) ? implode(',', $value) : $value;
}
protected function setTypeAttr($value)
{
return is_array($value) ? implode(',', $value) : $value;
}
public function scopeFrontend(Query $query, $params = [])
{
$query->where('__TABLE__.visible_switch', 1)
->order(['__TABLE__.id'=>'desc']);
}
}

View File

@ -0,0 +1,65 @@
<?php
namespace app\common\model\notice;
use think\Model;
class NoticeTemplate extends Model
{
// 表名
protected $name = 'notice_template';
// 自动写入时间戳字段
protected $autoWriteTimestamp = 'int';
// 定义时间戳字段名
protected $createTime = 'createtime';
protected $updateTime = 'updatetime';
protected $deleteTime = false;
// 追加属性
protected $append = [
];
public function getVisibleSwitchList()
{
return ['0' => __('Visible_switch 0'), '1' => __('Visible_switch 1')];
}
public function getVisibleSwitchTextAttr($value, $data)
{
$value = $value ? $value : (isset($data['visible_switch']) ? $data['visible_switch'] : '');
$list = $this->getVisibleSwitchList();
return isset($list[$value]) ? $list[$value] : '';
}
public function noticeevent()
{
return $this->belongsTo('NoticeEvent', 'notice_event_id', 'id', [], 'LEFT')->setEagerlyType(0);
}
public function getUrlTypeList()
{
$type = $this['type'] ?? '';
if ($type == 'msg') {
return [1 => '链接', 2=>'弹窗', 3=>'新窗口'];
}
if ($type == 'mptemplate' || $type == 'miniapp') {
return [1 => '链接'];
}
return [1 => '链接', 2=>'弹窗', 3=>'新窗口'];
}
}

View File

@ -3,6 +3,7 @@
namespace app\common\model\school;
use app\common\model\notice\NoticeEvent;
use bw\Common;
use think\Cache;
use think\Model;
@ -276,10 +277,30 @@ class MessageConfig extends Model
return true;
}
}
public function sendBackendMessage($to_uid=0){
if($to_uid)$this->setToUid($to_uid);
$template = $this->messageTemplate;
if(!$template) return true;
$event = $template["event"];
$notice_event = NoticeEvent::where("event",$event)->where("visible_switch",1)->find();
if($notice_event){
//执行后台通知
// 发送通知-主理人申请通知
$noticeParams = [
'event' => $event,
'params' => array_merge( array (
'receiver_admin_ids' => '',
'receiver_admin_group_ids' => '',
), $this->templateData)];
\Think\Hook::listen('send_notice', $noticeParams);
}
}
public function sendMessage($to_uid=0){
$this->sendSelfmail($to_uid);
$this->sendMobileMessage($to_uid);
$this->sendWechatWap($to_uid);
$this->sendBackendMessage($to_uid);
return $this;
}

View File

@ -66,12 +66,20 @@ class Join extends BaseModel
}
if(config("site.activity_idcard_need")){
$rule = [
'user_id'=>'require',
'name'=>'require',
'idnum'=>'require',
];
}else{
$rule = [
'user_id'=>'require',
'name'=>'require',
// 'idnum'=>'require',
];
}
$rule = [
'user_id'=>'require',
'name'=>'require',
'idnum'=>'require',
];
$rule_msg = [
"user_id.require"=>'用户必填',
@ -130,11 +138,19 @@ class Join extends BaseModel
$rule = [
'user_id'=>'require',
'name'=>'require',
'idnum'=>'require',
];
if(config("site.activity_idcard_need")){
$rule = [
'user_id'=>'require',
'name'=>'require',
'idnum'=>'require',
];
}else{
$rule = [
'user_id'=>'require',
'name'=>'require',
// 'idnum'=>'require',
];
}
$rule_msg = [
"user_id.require"=>'用户必填',

View File

@ -692,27 +692,31 @@ class Order extends BaseModel
throw new \Exception("报名人信息需要跟报名人数一致!");
}
//$param["people"] = [{name:"小明",idnum:"410303199501220515"}]
$people_idnums = [];
foreach ($peoples as $people){
$people_idnums[] = $people["idnum"];
}
//当前活动已经报名的身份证无法重复报名
$as = (new OrderCode)->getWithAlisaName();
$orderCode = OrderCode::with("activityorder")
->where("{$as}.activity_id",$activity_id)
->where("activityorder.status","in",[ "0","2","3",'4',"7","9"])
->where("{$as}.idnum","in",$people_idnums)
->find();
if($orderCode){
if(config("site.activity_idcard_need")){
//$param["people"] = [{name:"小明",idnum:"410303199501220515"}]
$people_idnums = [];
foreach ($peoples as $people){
$people_idnums[] = $people["idnum"];
}
$as = (new OrderCode)->getWithAlisaName();
$orderCode = OrderCode::with("activityorder")
->where("{$as}.activity_id",$activity_id)
->where("activityorder.status","in",[ "0","2","3",'4',"7","9"])
->where("{$as}.idnum","in",$people_idnums)
->find();
if($orderCode){
// throw new \Exception("{$orderCode['name']}已经报过名了!请勿重复报名!");
throw new \Exception("该身份证号已报名!请勿重复报名!");
throw new \Exception("该身份证号已报名!请勿重复报名!");
}
}
}
@ -956,7 +960,7 @@ class Order extends BaseModel
];
if($people && isset($people[$i])){
$params["name"] = $people[$i]["name"];
$params["idnum"] = $people[$i]["idnum"];
$params["idnum"] = $people[$i]["idnum"] ?? "";
}

View File

@ -0,0 +1,51 @@
<?php
namespace app\index\controller\notice;
use app\common\controller\Frontend;
/**
* 消息通知
* Class Notice
*/
class Index extends Frontend
{
protected $layout = 'default';
protected $noNeedRight = ['*'];
public function index()
{
$user = $this->auth->getUser();
$list = \app\admin\model\notice\Notice::where('to_id', $user['id'])
->where('platform', 'user')
->where('type','msg')
->order('id', 'desc')
->paginate(20);
$config = get_addon_config('notice');
// 是否有未读的
$haveUnread = false;
// 判断是否需要自动标记为已读
$auto_read = $config['auto_read'] ?? false;
if ($auto_read) {
\app\admin\model\notice\Notice::where('id', 'in',array_column($list->items(), 'id'))
->update(['readtime' => time()]);
} else {
foreach ($list->items() as $item) {
if ($item['readtime'] === null) {
$haveUnread = true;
break;
}
}
}
$this->assign('haveUnread', $haveUnread);
$this->assign('list', $list);
$this->assign('title', '我的消息');
return $this->fetch();
}
}

View File

@ -0,0 +1,110 @@
<style>
.notice-item td{
padding: 10px !important;
}
.page-header {
margin-bottom: 0px !important;
}
#container .panel{
border: 0;
border-radius: 12px;
}
#container .panel .panel-body{
padding: 0 24px;
}
#container .panel .page-header{
margin: 0 -24px;
border-color: #DDDDDD;
padding: 16px 24px 12px;
line-height: 30px;
font-size: 18px;
color: #333;
font-weight: bold;
overflow: hidden;
}
#container .panel .page-header .btn-default{
padding: 0 8px;
background: #7A888F;
line-height: 30px;
font-size: 13px;
color: #fff;
border-radius: 3px;
}
#container .panel .notice-item td{
border-top: 0 !important;
border-bottom: 1px #DDDDDD solid;
padding: 16px 0 !important;
vertical-align: middle !important;
line-height: 24px !important;
font-size: 13px !important;
color: #333 !important;
}
#container .panel .notice-item td a{
color: inherit;
}
#container .panel .notice-item td a:hover{
color: #4397fd;
}
#container .panel .notice-item .btn{
padding: 0 10px !important;
min-width: 50px !important;
height: 24px !important;
background: #1EB18A !important;
text-align: center !important;
border-radius: 3px !important;
}
</style>
<div id="container" class="container">
<div class="row">
<div class="col-md-3">
{include file="common/sidenav" /}
</div>
<div class="col-md-9">
<div class="panel panel-default">
<div class="panel-body">
<h2 class="page-header">
消息通知
{if $haveUnread}
<button class="pull-right btn btn-default mark-event" data-url="{:addon_url('notice/api/mark')}">全部标记为已读</button>
{/if}
</h2>
<table class="table table-hover">
<!-- <thead>-->
<!-- <tr>-->
<!-- <th>消息内容</th>-->
<!-- <th>创建时间</th>-->
<!-- <th>状态</th>-->
<!-- </tr>-->
<!-- </thead>-->
<tbody>
{foreach $list as $v}
<tr class="notice-item">
<td><a data-title="{$v.ext_arr.url_title|htmlentities}" class="{$v.ext_arr.url_type == 2 ? 'btn-dialog' : ''}" href="{$v.ext_arr.url ?? 'javascript:;'}" target="{:isset($v.ext_arr.url_type) && !empty($v.ext_arr.url) && $v.ext_arr.url_type == 3 ? 'target':'_self'}">{$v.content|htmlentities}</a></td>
<td>{$v.createtime|time_text}</td>
<td style="text-align: center">
{if $v.readtime == null}
<button class="btn btn-success mark-event" data-url="{:addon_url('notice/api/mark', ['id' => $v.id])}">已读</button>
{else}
已读
{/if}
</td>
</tr>
{/foreach}
</tbody>
</table>
{if $list->count() == 0}
<div class="nothing"></div>
{/if}
{$list->render()}
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,32 @@
define(['jquery', 'bootstrap', 'frontend', 'form', 'template'], function ($, undefined, Frontend, Form, Template) {
var Controller = {
index: function () {
// 标记为已读
$(document).on('click', '.mark-event', function () {
Fast.api.ajax($(this).data('url'), function () {
location.reload();
});
});
$(document).on('click','.btn-refresh', function () {
Layer.load();
location.reload();
});
// 重新获取左侧消息数量
Fast.api.ajax({
url: 'notice/admin/statistical',
loading: false,
method: 'post',
}, function (data, res) {
Backend.api.sidebar({
'notice/admin': data.num,
});
return false;
}, function () {
return false;
});
}
};
return Controller;
});

View File

@ -0,0 +1,137 @@
define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
var Controller = {
index: function () {
// 初始化表格参数配置
Table.api.init({
extend: {
index_url: 'notice/admin_mptemplate/index' + location.search,
add_url: 'notice/admin_mptemplate/add',
edit_url: 'notice/admin_mptemplate/edit',
del_url: 'notice/admin_mptemplate/del',
multi_url: 'notice/admin_mptemplate/multi',
import_url: 'notice/admin_mptemplate/import',
table: 'notice_admin_mptemplate',
}
});
var table = $("#table");
// 初始化表格
table.bootstrapTable({
url: $.fn.bootstrapTable.defaults.extend.index_url,
pk: 'id',
sortName: 'id',
columns: [
[
{checkbox: true},
{field: 'id', title: __('Id')},
// {field: 'admin_id', title: __('Admin_id')},
{field: 'admin.nickname', title: '管理员', operate: 'LIKE', formatter: Table.api.formatter.dialog, url: 'auth/admin/index?id={row.admin_id}&_t={ids}'},
{field: 'nickname', title: __('Nickname')},
{field: 'avatar', title: __('Avatar'), events: Table.api.events.image, formatter: Table.api.formatter.image},
{field: 'openid', title: __('Openid')},
{field: 'unionid', title: __('Unionid')},
{field: 'createtime', title: __('Createtime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
// {field: 'updatetime', title: __('Updatetime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
]
]
});
// 为表格绑定事件
Table.api.bindevent(table);
},
recyclebin: function () {
// 初始化表格参数配置
Table.api.init({
extend: {
'dragsort_url': ''
}
});
var table = $("#table");
// 初始化表格
table.bootstrapTable({
url: 'notice/admin_mptemplate/recyclebin' + location.search,
pk: 'id',
sortName: 'id',
columns: [
[
{checkbox: true},
{field: 'id', title: __('Id')},
{
field: 'deletetime',
title: __('Deletetime'),
operate: 'RANGE',
addclass: 'datetimerange',
formatter: Table.api.formatter.datetime
},
{
field: 'operate',
width: '130px',
title: __('Operate'),
table: table,
events: Table.api.events.operate,
buttons: [
{
name: 'Restore',
text: __('Restore'),
classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
icon: 'fa fa-rotate-left',
url: 'notice/admin_mptemplate/restore',
refresh: true
},
{
name: 'Destroy',
text: __('Destroy'),
classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
icon: 'fa fa-times',
url: 'notice/admin_mptemplate/destroy',
refresh: true
}
],
formatter: Table.api.formatter.operate
}
]
]
});
// 为表格绑定事件
Table.api.bindevent(table);
},
add: function () {
Controller.api.bindevent();
},
edit: function () {
Controller.api.bindevent();
},
bind: function () {
$(document).on('click', '.btn-refresh', function () {
location.reload();
});
$('#remove-event').data('success', function () {
location.reload();
});
require(['qrcode'], function () {
var qrcode = new QRCode("qrcode", {
text: Config.url,
width: 200,
height: 200,
colorDark : "#000000",
colorLight : "#ffffff",
correctLevel : QRCode.CorrectLevel.H
});
});
},
api: {
bindevent: function () {
Form.api.bindevent($("form[role=form]"));
}
}
};
return Controller;
});

View File

@ -0,0 +1,139 @@
define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
var Controller = {
index: function () {
// 初始化表格参数配置
Table.api.init({
extend: {
index_url: 'notice/event/index' + location.search,
add_url: 'notice/event/add',
edit_url: 'notice/event/edit',
del_url: 'notice/event/del',
multi_url: 'notice/event/multi',
import_url: 'notice/event/import',
table: 'notice_event',
}
});
var table = $("#table");
// 初始化表格
table.bootstrapTable({
url: $.fn.bootstrapTable.defaults.extend.index_url,
pk: 'id',
sortName: 'id',
fixedColumns: true,
fixedRightNumber: 1,
columns: [
[
{checkbox: true},
{field: 'id', title: __('Id')},
{field: 'platform', title: __('Platform'), searchList: {"user":__('Platform user'),"admin":__('Platform admin')}, operate:'FIND_IN_SET', formatter: Table.api.formatter.label},
{field: 'type', title: __('Type'), searchList: Config.typeList, operate:'FIND_IN_SET', formatter: Table.api.formatter.label},
{field: 'name', title: __('Name'), operate: 'LIKE'},
{field: 'event', title: __('Event'), operate: 'LIKE'},
{field: 'send_num', title: __('Send_num')},
{field: 'send_fail_num', title: __('Send_fail_num')},
{field: 'visible_switch', title: __('Visible_switch'), searchList: {"0":__('Visible_switch 0'),"1":__('Visible_switch 1')}, table: table, formatter: Table.api.formatter.toggle},
{field: 'createtime', title: __('Createtime'), operate:'RANGE', addclass:'datetimerange', autocomplete:false, formatter: Table.api.formatter.datetime},
{field: 'updatetime', title: __('Updatetime'), operate:'RANGE', addclass:'datetimerange', autocomplete:false, formatter: Table.api.formatter.datetime, visible: false},
{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate,
buttons: [
{
name: 'test',
text: '测试',
url: 'notice/event/test',
classname: 'btn btn-xs btn-dialog btn-primary',
},
{
name: 'copy',
text: '复制',
url: 'notice/event/edit?is_copy=1',
classname: 'btn btn-xs btn-dialog btn-primary',
}
]
}
]
]
});
// 为表格绑定事件
Table.api.bindevent(table);
},
recyclebin: function () {
// 初始化表格参数配置
Table.api.init({
extend: {
'dragsort_url': ''
}
});
var table = $("#table");
// 初始化表格
table.bootstrapTable({
url: 'notice/event/recyclebin' + location.search,
pk: 'id',
sortName: 'id',
columns: [
[
{checkbox: true},
{field: 'id', title: __('Id')},
{field: 'name', title: __('Name'), align: 'left'},
{
field: 'deletetime',
title: __('Deletetime'),
operate: 'RANGE',
addclass: 'datetimerange',
formatter: Table.api.formatter.datetime
},
{
field: 'operate',
width: '130px',
title: __('Operate'),
table: table,
events: Table.api.events.operate,
buttons: [
{
name: 'Restore',
text: __('Restore'),
classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
icon: 'fa fa-rotate-left',
url: 'notice/event/restore',
refresh: true
},
{
name: 'Destroy',
text: __('Destroy'),
classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
icon: 'fa fa-times',
url: 'notice/event/destroy',
refresh: true
}
],
formatter: Table.api.formatter.operate
}
]
]
});
// 为表格绑定事件
Table.api.bindevent(table);
},
add: function () {
Controller.api.bindevent();
},
edit: function () {
Controller.api.bindevent();
},
test: function () {
Form.api.bindevent($("form[role=form]"));
},
api: {
bindevent: function () {
Form.api.bindevent($("form[role=form]"));
}
}
};
return Controller;
});

View File

@ -0,0 +1,119 @@
define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
var Controller = {
index: function () {
// 初始化表格参数配置
Table.api.init({
extend: {
index_url: 'notice/notice/index' + location.search,
add_url: 'notice/notice/add',
edit_url: 'notice/notice/edit',
del_url: 'notice/notice/del',
multi_url: 'notice/notice/multi',
import_url: 'notice/notice/import',
table: 'notice',
}
});
var table = $("#table");
// 初始化表格
table.bootstrapTable({
url: $.fn.bootstrapTable.defaults.extend.index_url,
pk: 'id',
sortName: 'id',
columns: [
[
{checkbox: true},
{field: 'id', title: __('Id')},
{field: 'name', title: __('Name'), operate: 'LIKE'},
{field: 'event', title: __('Event'), operate: 'LIKE', visible: false},
{field: 'platform', title: __('Platform'), searchList: {"user":__('Platform user'),"admin":__('Platform admin')}, formatter: Table.api.formatter.normal},
{field: 'type', title: __('Type'), searchList: Config.typeList, formatter: Table.api.formatter.normal},
{field: 'to_id', title: __('To_id')},
{field: 'notice_template_id', title: __('Notice_template_id')},
{field: 'readtime', title: __('Readtime'), operate:'RANGE', addclass:'datetimerange', autocomplete:false, formatter: Table.api.formatter.datetime},
{field: 'createtime', title: __('Createtime'), operate:'RANGE', addclass:'datetimerange', autocomplete:false, formatter: Table.api.formatter.datetime},
{field: 'updatetime', title: __('Updatetime'), operate:'RANGE', addclass:'datetimerange', autocomplete:false, formatter: Table.api.formatter.datetime, visible: false},
{field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
]
]
});
// 为表格绑定事件
Table.api.bindevent(table);
},
recyclebin: function () {
// 初始化表格参数配置
Table.api.init({
extend: {
'dragsort_url': ''
}
});
var table = $("#table");
// 初始化表格
table.bootstrapTable({
url: 'notice/notice/recyclebin' + location.search,
pk: 'id',
sortName: 'id',
columns: [
[
{checkbox: true},
{field: 'id', title: __('Id')},
{field: 'name', title: __('Name'), align: 'left'},
{
field: 'deletetime',
title: __('Deletetime'),
operate: 'RANGE',
addclass: 'datetimerange',
formatter: Table.api.formatter.datetime
},
{
field: 'operate',
width: '130px',
title: __('Operate'),
table: table,
events: Table.api.events.operate,
buttons: [
{
name: 'Restore',
text: __('Restore'),
classname: 'btn btn-xs btn-info btn-ajax btn-restoreit',
icon: 'fa fa-rotate-left',
url: 'notice/notice/restore',
refresh: true
},
{
name: 'Destroy',
text: __('Destroy'),
classname: 'btn btn-xs btn-danger btn-ajax btn-destroyit',
icon: 'fa fa-times',
url: 'notice/notice/destroy',
refresh: true
}
],
formatter: Table.api.formatter.operate
}
]
]
});
// 为表格绑定事件
Table.api.bindevent(table);
},
add: function () {
Controller.api.bindevent();
},
edit: function () {
Controller.api.bindevent();
},
api: {
bindevent: function () {
Form.api.bindevent($("form[role=form]"));
}
}
};
return Controller;
});

View File

@ -0,0 +1,45 @@
define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
var Controller = {
index: function () {
Controller.api.bindevent();
$(document).on('change', '.switch-input', function () {
// ajax请求
var params = {
'notice_event_id': $(this).parents('.parent').data('notice_event_id'),
'platform': $(this).parents('.parent').data('platform'),
'type': $(this).parents('.parent').data('type'),
'visible_switch': $(this).val()
};
Fast.api.ajax({
url: 'notice/template/visible',
data: params,
loading: false
});
});
// tab自定义
$('.panel-heading [data-field] a[data-toggle="tab"]').unbind('shown.bs.tab');
$('.panel-heading [data-field] a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
var platform = $(this).data('value');
var url = 'notice/template?platform='+platform;
url = Fast.api.fixurl(url);
Layer.load();
location.href = url;
});
},
add: function () {
Controller.api.bindevent();
},
edit: function () {
Controller.api.bindevent();
},
api: {
bindevent: function () {
Form.api.bindevent($("form[role=form]"));
}
}
};
return Controller;
});

View File

@ -0,0 +1,36 @@
define(['jquery', 'bootstrap', 'frontend', 'form', 'template'], function ($, undefined, Frontend, Form, Template) {
var Controller = {
index: function () {
// 标记为已读
$(document).on('click', '.mark-event', function () {
Fast.api.ajax($(this).data('url'), function () {
location.reload();
});
});
//点击包含.btn-dialog的元素时弹出dialog
$(document).on('click', '.btn-dialog,.dialogit', function (e) {
if(e.returnValue){
e.returnValue = false
}else{
e.preventDefault()
}
var that = this;
var options = $.extend({}, $(that).data() || {});
var url = $(that).data("url") || $(that).attr('href');
var title = $(that).attr("title") || $(that).data("title") || $(that).data('original-title');
if (typeof options.confirm !== 'undefined') {
Layer.confirm(options.confirm, function (index) {
Frontend.api.open(url, title, options);
Layer.close(index);
});
} else {
window[$(that).data("window") || 'self'].Frontend.api.open(url, title, options);
}
return false;
});
}
};
return Controller;
});