mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-13 12:02:51 +00:00
feat: 实现非对称加密关键接口
This commit is contained in:
parent
ef7ed58a22
commit
7e98a78333
1
.gitignore
vendored
1
.gitignore
vendored
@ -6,6 +6,7 @@
|
||||
/public/.user.ini
|
||||
/storage/*.key
|
||||
/config/LICENSE
|
||||
/config/PGP_*
|
||||
/vendor
|
||||
/build
|
||||
/tmp
|
||||
|
||||
@ -2,6 +2,12 @@
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [0.25.48]
|
||||
|
||||
### Performance
|
||||
|
||||
- 自动清空文件回收站
|
||||
|
||||
## [0.25.42]
|
||||
|
||||
### Performance
|
||||
|
||||
@ -9889,12 +9889,12 @@
|
||||
* Clones a request and overrides some of its parameters.
|
||||
*
|
||||
* @return static
|
||||
* @param array $query The GET parameters
|
||||
* @param array $request The POST parameters
|
||||
* @param array $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
|
||||
* @param array $cookies The COOKIE parameters
|
||||
* @param array $files The FILES parameters
|
||||
* @param array $server The SERVER parameters
|
||||
* @param array|null $query The GET parameters
|
||||
* @param array|null $request The POST parameters
|
||||
* @param array|null $attributes The request attributes (parameters parsed from the PATH_INFO, ...)
|
||||
* @param array|null $cookies The COOKIE parameters
|
||||
* @param array|null $files The FILES parameters
|
||||
* @param array|null $server The SERVER parameters
|
||||
* @return static
|
||||
* @static
|
||||
*/
|
||||
|
||||
@ -534,7 +534,7 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/msg/one 10. 获取单条消息
|
||||
* @api {get} api/dialog/msg/one 11. 获取单条消息
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
@ -563,7 +563,7 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/msg/read 11. 已读聊天消息
|
||||
* @api {get} api/dialog/msg/read 12. 已读聊天消息
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
@ -614,7 +614,7 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/msg/unread 12. 获取未读消息数据
|
||||
* @api {get} api/dialog/msg/unread 13. 获取未读消息数据
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
@ -655,7 +655,7 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {post} api/dialog/msg/sendtext 13. 发送消息
|
||||
* @api {post} api/dialog/msg/sendtext 14. 发送消息
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
@ -676,7 +676,6 @@ class DialogController extends AbstractController
|
||||
*/
|
||||
public function msg__sendtext()
|
||||
{
|
||||
Base::checkClientVersion('0.19.0');
|
||||
$user = User::auth();
|
||||
//
|
||||
if (!$user->bot) {
|
||||
@ -691,11 +690,11 @@ class DialogController extends AbstractController
|
||||
}
|
||||
}
|
||||
//
|
||||
$dialog_id = Base::getPostInt('dialog_id');
|
||||
$update_id = Base::getPostInt('update_id');
|
||||
$reply_id = Base::getPostInt('reply_id');
|
||||
$text = trim(Base::getPostValue('text'));
|
||||
$silence = trim(Base::getPostValue('silence')) === 'yes';
|
||||
$dialog_id = intval(Request::input('dialog_id'));
|
||||
$update_id = intval(Request::input('update_id'));
|
||||
$reply_id = intval(Request::input('reply_id'));
|
||||
$text = trim(Request::input('text'));
|
||||
$silence = trim(Request::input('silence')) === 'yes';
|
||||
//
|
||||
WebSocketDialog::checkDialog($dialog_id);
|
||||
//
|
||||
@ -745,7 +744,7 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {post} api/dialog/msg/sendrecord 14. 发送语音
|
||||
* @api {post} api/dialog/msg/sendrecord 15. 发送语音
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
@ -765,15 +764,15 @@ class DialogController extends AbstractController
|
||||
{
|
||||
$user = User::auth();
|
||||
//
|
||||
$dialog_id = Base::getPostInt('dialog_id');
|
||||
$reply_id = Base::getPostInt('reply_id');
|
||||
$dialog_id = intval(Request::input('dialog_id'));
|
||||
$reply_id = intval(Request::input('reply_id'));
|
||||
//
|
||||
WebSocketDialog::checkDialog($dialog_id);
|
||||
//
|
||||
$action = $reply_id > 0 ? "reply-$reply_id" : "";
|
||||
$path = "uploads/chat/" . date("Ym") . "/" . $dialog_id . "/";
|
||||
$base64 = Base::getPostValue('base64');
|
||||
$duration = Base::getPostInt('duration');
|
||||
$base64 = Request::input('base64');
|
||||
$duration = intval(Request::input('duration'));
|
||||
if ($duration < 600) {
|
||||
return Base::retError('说话时间太短');
|
||||
}
|
||||
@ -792,7 +791,7 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {post} api/dialog/msg/sendfile 15. 文件上传
|
||||
* @api {post} api/dialog/msg/sendfile 16. 文件上传
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
@ -814,16 +813,16 @@ class DialogController extends AbstractController
|
||||
{
|
||||
$user = User::auth();
|
||||
//
|
||||
$dialog_id = Base::getPostInt('dialog_id');
|
||||
$reply_id = Base::getPostInt('reply_id');
|
||||
$image_attachment = Base::getPostInt('image_attachment');
|
||||
$dialog_id = intval(Request::input('dialog_id'));
|
||||
$reply_id = intval(Request::input('reply_id'));
|
||||
$image_attachment = intval(Request::input('image_attachment'));
|
||||
//
|
||||
$dialog = WebSocketDialog::checkDialog($dialog_id);
|
||||
//
|
||||
$action = $reply_id > 0 ? "reply-$reply_id" : "";
|
||||
$path = "uploads/chat/" . date("Ym") . "/" . $dialog_id . "/";
|
||||
$image64 = Base::getPostValue('image64');
|
||||
$fileName = Base::getPostValue('filename');
|
||||
$image64 = Request::input('image64');
|
||||
$fileName = Request::input('filename');
|
||||
if ($image64) {
|
||||
$data = Base::image64save([
|
||||
"image64" => $image64,
|
||||
@ -876,7 +875,7 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/msg/sendfileid 16. 通过文件ID发送文件
|
||||
* @api {get} api/dialog/msg/sendfileid 17. 通过文件ID发送文件
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
@ -946,7 +945,7 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {post} api/dialog/msg/sendanon 16. 发送匿名消息
|
||||
* @api {post} api/dialog/msg/sendanon 18. 发送匿名消息
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
@ -964,8 +963,8 @@ class DialogController extends AbstractController
|
||||
{
|
||||
User::auth();
|
||||
//
|
||||
$userid = Base::getPostInt('userid');
|
||||
$text = trim(Base::getPostValue('text'));
|
||||
$userid = intval(Request::input('userid'));
|
||||
$text = trim(Request::input('text'));
|
||||
//
|
||||
$anonMessage = Base::settingFind('system', 'anon_message', 'open');
|
||||
if ($anonMessage != 'open') {
|
||||
@ -999,7 +998,7 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/msg/readlist 17. 获取消息阅读情况
|
||||
* @api {get} api/dialog/msg/readlist 19. 获取消息阅读情况
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
@ -1028,7 +1027,7 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/msg/detail 18. 消息详情
|
||||
* @api {get} api/dialog/msg/detail 20. 消息详情
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
@ -1076,7 +1075,7 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/msg/download 19. 文件下载
|
||||
* @api {get} api/dialog/msg/download 21. 文件下载
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
@ -1119,7 +1118,7 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/msg/withdraw 20. 聊天消息撤回
|
||||
* @api {get} api/dialog/msg/withdraw 22. 聊天消息撤回
|
||||
*
|
||||
* @apiDescription 消息撤回限制24小时内,需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
@ -1145,7 +1144,7 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/msg/mark 21. 消息标记操作
|
||||
* @api {get} api/dialog/msg/mark 23. 消息标记操作
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
@ -1212,7 +1211,7 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/msg/silence 22. 消息免打扰
|
||||
* @api {get} api/dialog/msg/silence 24. 消息免打扰
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
@ -1275,7 +1274,7 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/msg/forward 23. 转发消息给
|
||||
* @api {get} api/dialog/msg/forward 25. 转发消息给
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
@ -1312,7 +1311,7 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/msg/emoji 24. emoji回复
|
||||
* @api {get} api/dialog/msg/emoji 26. emoji回复
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
@ -1347,7 +1346,7 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/msg/tag 25. 标注/取消标注
|
||||
* @api {get} api/dialog/msg/tag 27. 标注/取消标注
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
@ -1376,7 +1375,7 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/msg/todo 26. 设待办/取消待办
|
||||
* @api {get} api/dialog/msg/todo 28. 设待办/取消待办
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
@ -1419,7 +1418,7 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/msg/todolist 27. 获取消息待办情况
|
||||
* @api {get} api/dialog/msg/todolist 29. 获取消息待办情况
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
@ -1449,7 +1448,7 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/msg/done 28. 完成待办
|
||||
* @api {get} api/dialog/msg/done 30. 完成待办
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
@ -1496,7 +1495,7 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/group/add 29. 新增群组
|
||||
* @api {get} api/dialog/group/add 31. 新增群组
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
@ -1558,7 +1557,7 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/group/edit 30. 修改群组
|
||||
* @api {get} api/dialog/group/edit 32. 修改群组
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
@ -1619,7 +1618,7 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/group/adduser 31. 添加群成员
|
||||
* @api {get} api/dialog/group/adduser 33. 添加群成员
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* - 有群主时:只有群主可以邀请
|
||||
@ -1655,7 +1654,7 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/group/deluser 32. 移出(退出)群成员
|
||||
* @api {get} api/dialog/group/deluser 34. 移出(退出)群成员
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* - 只有群主、邀请人可以踢人
|
||||
@ -1699,7 +1698,7 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/group/transfer 33. 转让群组
|
||||
* @api {get} api/dialog/group/transfer 35. 转让群组
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* - 只有群主且是个人类型群可以解散
|
||||
@ -1743,7 +1742,7 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/group/disband 34. 解散群组
|
||||
* @api {get} api/dialog/group/disband 36. 解散群组
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* - 只有群主且是个人类型群可以解散
|
||||
@ -1771,7 +1770,7 @@ class DialogController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/dialog/group/searchuser 35. 搜索个人群(仅限管理员)
|
||||
* @api {get} api/dialog/group/searchuser 37. 搜索个人群(仅限管理员)
|
||||
*
|
||||
* @apiDescription 需要token身份,用于创建部门搜索个人群组
|
||||
* @apiVersion 1.0.0
|
||||
|
||||
@ -595,8 +595,8 @@ class FileController extends AbstractController
|
||||
{
|
||||
$user = User::auth();
|
||||
//
|
||||
$id = Base::getPostInt('id');
|
||||
$content = Base::getPostValue('content');
|
||||
$id = intval(Request::input('id'));
|
||||
$content = Request::input('content');
|
||||
//
|
||||
$file = File::permissionFind($id, $user, 1);
|
||||
//
|
||||
|
||||
@ -1543,7 +1543,8 @@ class ProjectController extends AbstractController
|
||||
public function task__add()
|
||||
{
|
||||
User::auth();
|
||||
parse_str(Request::getContent(), $data);
|
||||
//
|
||||
$data = Request::input();
|
||||
$project_id = intval($data['project_id']);
|
||||
$column_id = $data['column_id'];
|
||||
// 项目
|
||||
@ -1663,7 +1664,7 @@ class ProjectController extends AbstractController
|
||||
{
|
||||
User::auth();
|
||||
//
|
||||
parse_str(Request::getContent(), $data);
|
||||
$data = Request::input();
|
||||
$task_id = intval($data['task_id']);
|
||||
//
|
||||
$task = ProjectTask::userTask($task_id, true, true, 2);
|
||||
@ -1989,8 +1990,8 @@ class ProjectController extends AbstractController
|
||||
{
|
||||
User::auth();
|
||||
//
|
||||
$project_id = intval(Base::getContentValue('project_id'));
|
||||
$flows = Base::getContentValue('flows');
|
||||
$project_id = intval(Request::input('project_id'));
|
||||
$flows = Request::input('flows');
|
||||
//
|
||||
if (!is_array($flows)) {
|
||||
return Base::retError('参数错误');
|
||||
|
||||
@ -137,14 +137,14 @@ class ReportController extends AbstractController
|
||||
$user = User::auth();
|
||||
//
|
||||
$input = [
|
||||
"id" => Base::getPostValue("id", 0),
|
||||
"sign" => Base::getPostValue("sign"),
|
||||
"title" => Base::getPostValue("title"),
|
||||
"type" => Base::getPostValue("type"),
|
||||
"content" => Base::getPostValue("content"),
|
||||
"receive" => Base::getPostValue("receive"),
|
||||
"id" => Request::input("id", 0),
|
||||
"sign" => Request::input("sign"),
|
||||
"title" => Request::input("title"),
|
||||
"type" => Request::input("type"),
|
||||
"content" => Request::input("content"),
|
||||
"receive" => Request::input("receive"),
|
||||
// 以当前日期为基础的周期偏移量。例如选择了上一周那么就是 -1,上一天同理。
|
||||
"offset" => Base::getPostValue("offset", 0),
|
||||
"offset" => Request::input("offset", 0),
|
||||
];
|
||||
$validator = Validator::make($input, [
|
||||
'id' => 'numeric',
|
||||
|
||||
@ -10,7 +10,6 @@ use App\Module\BillExport;
|
||||
use App\Module\BillMultipleExport;
|
||||
use App\Module\Doo;
|
||||
use App\Module\Extranet;
|
||||
use Arr;
|
||||
use Carbon\Carbon;
|
||||
use Guanguans\Notify\Factory;
|
||||
use Guanguans\Notify\Messages\EmailMessage;
|
||||
@ -439,7 +438,7 @@ class SystemController extends AbstractController
|
||||
$type = trim(Request::input('type'));
|
||||
if ($type == 'save') {
|
||||
User::auth('admin');
|
||||
$list = Base::getPostValue('list');
|
||||
$list = Request::input('list');
|
||||
$array = [];
|
||||
if (empty($list) || !is_array($list)) {
|
||||
return Base::retError('参数错误');
|
||||
@ -488,7 +487,7 @@ class SystemController extends AbstractController
|
||||
$type = trim(Request::input('type'));
|
||||
if ($type == 'save') {
|
||||
User::auth('admin');
|
||||
$list = Base::getPostValue('list');
|
||||
$list = Request::input('list');
|
||||
$array = [];
|
||||
if (empty($list) || !is_array($list)) {
|
||||
return Base::retError('参数错误');
|
||||
@ -514,7 +513,7 @@ class SystemController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {post} api/system/license 08. License
|
||||
* @api {post} api/system/license 10. License
|
||||
*
|
||||
* @apiDescription 获取License信息、保存License(限管理员)
|
||||
* @apiVersion 1.0.0
|
||||
@ -536,7 +535,7 @@ class SystemController extends AbstractController
|
||||
//
|
||||
$type = trim(Request::input('type'));
|
||||
if ($type == 'save') {
|
||||
$license = Base::getPostValue('license');
|
||||
$license = Request::input('license');
|
||||
Doo::licenseSave($license);
|
||||
}
|
||||
//
|
||||
@ -550,7 +549,7 @@ class SystemController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/system/get/info 10. 获取终端详细信息
|
||||
* @api {get} api/system/get/info 11. 获取终端详细信息
|
||||
*
|
||||
* @apiVersion 1.0.0
|
||||
* @apiGroup system
|
||||
@ -579,7 +578,7 @@ class SystemController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/system/get/ip 11. 获取IP地址
|
||||
* @api {get} api/system/get/ip 12. 获取IP地址
|
||||
*
|
||||
* @apiVersion 1.0.0
|
||||
* @apiGroup system
|
||||
@ -594,7 +593,7 @@ class SystemController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/system/get/cnip 12. 是否中国IP地址
|
||||
* @api {get} api/system/get/cnip 13. 是否中国IP地址
|
||||
*
|
||||
* @apiVersion 1.0.0
|
||||
* @apiGroup system
|
||||
@ -611,7 +610,7 @@ class SystemController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/system/get/ipgcj02 13. 获取IP地址经纬度
|
||||
* @api {get} api/system/get/ipgcj02 14. 获取IP地址经纬度
|
||||
*
|
||||
* @apiVersion 1.0.0
|
||||
* @apiGroup system
|
||||
@ -628,7 +627,7 @@ class SystemController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/system/get/ipinfo 14. 获取IP地址详细信息
|
||||
* @api {get} api/system/get/ipinfo 15. 获取IP地址详细信息
|
||||
*
|
||||
* @apiVersion 1.0.0
|
||||
* @apiGroup system
|
||||
@ -645,7 +644,7 @@ class SystemController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {post} api/system/imgupload 15. 上传图片
|
||||
* @api {post} api/system/imgupload 16. 上传图片
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
@ -679,8 +678,8 @@ class SystemController extends AbstractController
|
||||
$scale = [$width, $height, $whcut];
|
||||
}
|
||||
$path = "uploads/user/picture/" . User::userid() . "/" . date("Ym") . "/";
|
||||
$image64 = trim(Base::getPostValue('image64'));
|
||||
$fileName = trim(Base::getPostValue('filename'));
|
||||
$image64 = trim(Request::input('image64'));
|
||||
$fileName = trim(Request::input('filename'));
|
||||
if ($image64) {
|
||||
$data = Base::image64save([
|
||||
"image64" => $image64,
|
||||
@ -705,7 +704,7 @@ class SystemController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/system/get/imgview 16. 浏览图片空间
|
||||
* @api {get} api/system/get/imgview 17. 浏览图片空间
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
@ -801,7 +800,7 @@ class SystemController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {post} api/system/fileupload 17. 上传文件
|
||||
* @api {post} api/system/fileupload 18. 上传文件
|
||||
*
|
||||
* @apiDescription 需要token身份
|
||||
* @apiVersion 1.0.0
|
||||
@ -822,8 +821,8 @@ class SystemController extends AbstractController
|
||||
return Base::retError('身份失效,等重新登录');
|
||||
}
|
||||
$path = "uploads/user/file/" . User::userid() . "/" . date("Ym") . "/";
|
||||
$image64 = trim(Base::getPostValue('image64'));
|
||||
$fileName = trim(Base::getPostValue('filename'));
|
||||
$image64 = trim(Request::input('image64'));
|
||||
$fileName = trim(Request::input('filename'));
|
||||
if ($image64) {
|
||||
$data = Base::image64save([
|
||||
"image64" => $image64,
|
||||
@ -843,7 +842,7 @@ class SystemController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/system/get/showitem 18. 首页显示ITEM
|
||||
* @api {get} api/system/get/showitem 19. 首页显示ITEM
|
||||
*
|
||||
* @apiDescription 用于判断首页是否显示:pro、github、更新日志...
|
||||
* @apiVersion 1.0.0
|
||||
@ -875,7 +874,7 @@ class SystemController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/system/get/starthome 19. 启动首页设置信息
|
||||
* @api {get} api/system/get/starthome 20. 启动首页设置信息
|
||||
*
|
||||
* @apiDescription 用于判断注册是否需要启动首页
|
||||
* @apiVersion 1.0.0
|
||||
@ -895,7 +894,7 @@ class SystemController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/system/email/check 20. 邮件发送测试(限管理员)
|
||||
* @api {get} api/system/email/check 21. 邮件发送测试(限管理员)
|
||||
*
|
||||
* @apiDescription 测试配置邮箱是否能发送邮件
|
||||
* @apiVersion 1.0.0
|
||||
@ -941,7 +940,7 @@ class SystemController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/system/checkin/export 21. 导出签到数据(限管理员)
|
||||
* @api {get} api/system/checkin/export 22. 导出签到数据(限管理员)
|
||||
*
|
||||
* @apiVersion 1.0.0
|
||||
* @apiGroup system
|
||||
@ -1108,7 +1107,7 @@ class SystemController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/system/checkin/down 22. 下载导出的签到数据
|
||||
* @api {get} api/system/checkin/down 23. 下载导出的签到数据
|
||||
*
|
||||
* @apiVersion 1.0.0
|
||||
* @apiGroup system
|
||||
@ -1134,7 +1133,7 @@ class SystemController extends AbstractController
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/system/version 23. 获取版本号
|
||||
* @api {get} api/system/version 24. 获取版本号
|
||||
*
|
||||
* @apiVersion 1.0.0
|
||||
* @apiGroup system
|
||||
|
||||
@ -1527,7 +1527,7 @@ class UsersController extends AbstractController
|
||||
return Base::retError('未开放修改权限,请联系管理员');
|
||||
}
|
||||
//
|
||||
$list = Base::getPostValue('list');
|
||||
$list = Request::input('list');
|
||||
$array = [];
|
||||
if (empty($list) || !is_array($list)) {
|
||||
return Base::retError('参数错误');
|
||||
@ -1618,4 +1618,46 @@ class UsersController extends AbstractController
|
||||
}
|
||||
return Base::retSuccess('success', $row);
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/users/key/client 28. 客户端KEY
|
||||
*
|
||||
* @apiDescription 获取客户端KEY,用于加密数据发送给服务端
|
||||
* @apiVersion 1.0.0
|
||||
* @apiGroup users
|
||||
* @apiName key__client
|
||||
*
|
||||
* @apiParam {String} [client_id] 客户端ID(希望不变的,除非清除浏览器缓存或者卸载应用)
|
||||
*
|
||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||
* @apiSuccess {Object} data 返回数据
|
||||
*/
|
||||
public function key__client()
|
||||
{
|
||||
$clientId = (trim(Request::input('client_id')) ?: Base::generatePassword(6)) . Doo::userId();
|
||||
//
|
||||
$cacheKey = "KeyPair::" . $clientId;
|
||||
if (Cache::has($cacheKey)) {
|
||||
$cacheData = Base::json2array(Cache::get($cacheKey));
|
||||
if ($cacheData['private_key']) {
|
||||
return Base::retSuccess('success', [
|
||||
'type' => 'pgp',
|
||||
'id' => $clientId,
|
||||
'key' => $cacheData['public_key'],
|
||||
]);
|
||||
}
|
||||
}
|
||||
//
|
||||
$name = Doo::userEmail() ?: Base::generatePassword(6);
|
||||
$email = Doo::userEmail() ?: 'aa@bb.cc';
|
||||
$data = Doo::pgpGenerateKeyPair($name, $email, Base::generatePassword());
|
||||
Cache::put("KeyPair::" . $clientId, Base::array2json($data), Carbon::now()->addQuarter());
|
||||
//
|
||||
return Base::retSuccess('success', [
|
||||
'type' => 'pgp',
|
||||
'id' => $clientId,
|
||||
'key' => $data['public_key'],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,59 +12,8 @@ class VerifyCsrfToken extends Middleware
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
// 上传图片
|
||||
'api/system/imgupload/',
|
||||
|
||||
// 上传文件
|
||||
'api/system/fileupload/',
|
||||
|
||||
// 保存任务优先级
|
||||
'api/system/priority/',
|
||||
|
||||
// 保存创建项目列表模板
|
||||
'api/system/column/template/',
|
||||
|
||||
// License 设置
|
||||
'api/system/license/',
|
||||
|
||||
// 添加任务
|
||||
'api/project/task/add/',
|
||||
|
||||
// 保存工作流
|
||||
'api/project/flow/save/',
|
||||
|
||||
// 修改任务
|
||||
'api/project/task/update/',
|
||||
|
||||
// 聊天发文本
|
||||
'api/dialog/msg/sendtext/',
|
||||
|
||||
// 聊天发语音
|
||||
'api/dialog/msg/sendrecord/',
|
||||
|
||||
// 聊天发文件
|
||||
'api/dialog/msg/sendfile/',
|
||||
|
||||
// 聊天发匿名消息
|
||||
'api/dialog/msg/sendanon/',
|
||||
|
||||
// 保存文件内容
|
||||
'api/file/content/save/',
|
||||
|
||||
// 保存文件内容(office)
|
||||
'api/file/content/office/',
|
||||
|
||||
// 保存文件内容(上传)
|
||||
'api/file/content/upload/',
|
||||
|
||||
// 保存汇报
|
||||
'api/report/store/',
|
||||
|
||||
// 签到设置
|
||||
'api/users/checkin/save/',
|
||||
|
||||
// 签到上报
|
||||
'api/public/checkin/report/',
|
||||
// 接口部分
|
||||
'api/*',
|
||||
|
||||
// 发布桌面端
|
||||
'desktop/publish/',
|
||||
|
||||
@ -4,9 +4,9 @@ namespace App\Http\Middleware;
|
||||
|
||||
@error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
|
||||
|
||||
use App\Module\Base;
|
||||
use App\Module\Doo;
|
||||
use Closure;
|
||||
use Request;
|
||||
|
||||
class WebApi
|
||||
{
|
||||
@ -22,18 +22,41 @@ class WebApi
|
||||
global $_A;
|
||||
$_A = [];
|
||||
|
||||
if (Request::input('__Access-Control-Allow-Origin') || Request::header('__Access-Control-Allow-Origin')) {
|
||||
header('Access-Control-Allow-Origin:*');
|
||||
header('Access-Control-Allow-Methods:GET,POST,PUT,DELETE,OPTIONS');
|
||||
header('Access-Control-Allow-Headers:Content-Type, platform, platform-channel, token, release, Access-Control-Allow-Origin');
|
||||
Doo::load();
|
||||
|
||||
$encrypt = Doo::pgpParseStr($request->header('encrypt'));
|
||||
if ($request->isMethod('post')) {
|
||||
$version = $request->header('version');
|
||||
if ($version && version_compare($version, '0.25.48', '<')) {
|
||||
// 旧版本兼容 php://input
|
||||
parse_str($request->getContent(), $content);
|
||||
if ($content) {
|
||||
$request->merge($content);
|
||||
}
|
||||
} elseif ($encrypt['encrypt_type'] === 'pgp' && $content = $request->input('encrypted')) {
|
||||
// 新版本解密提交的内容
|
||||
$content = Doo::pgpDecryptApi($content, $encrypt['encrypt_id']);
|
||||
if ($content) {
|
||||
$request->merge($content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 强制 https
|
||||
$APP_SCHEME = env('APP_SCHEME', 'auto');
|
||||
if (in_array(strtolower($APP_SCHEME), ['https', 'on', 'ssl', '1', 'true', 'yes'], true)) {
|
||||
$request->setTrustedProxies([$request->getClientIp()], $request::HEADER_X_FORWARDED_PROTO);
|
||||
}
|
||||
Doo::load();
|
||||
|
||||
return $next($request);
|
||||
$response = $next($request);
|
||||
|
||||
// 加密返回内容
|
||||
if ($encrypt['client_type'] === 'pgp' && $content = $response->getContent()) {
|
||||
$response->setContent(json_encode([
|
||||
'encrypted' => Doo::pgpEncryptApi($content, $encrypt['client_key'])
|
||||
]));
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ use Request;
|
||||
* @property \Illuminate\Support\Carbon|null $deleted_at
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|File newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|File newQuery()
|
||||
* @method static \Illuminate\Database\Query\Builder|File onlyTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|File onlyTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|File query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|File whereCid($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|File whereCreatedAt($value)
|
||||
@ -46,8 +46,8 @@ use Request;
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|File whereType($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|File whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|File whereUserid($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|File withTrashed()
|
||||
* @method static \Illuminate\Database\Query\Builder|File withoutTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|File withTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|File withoutTrashed()
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class File extends AbstractModel
|
||||
|
||||
@ -20,7 +20,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
* @property \Illuminate\Support\Carbon|null $deleted_at
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|FileContent newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|FileContent newQuery()
|
||||
* @method static \Illuminate\Database\Query\Builder|FileContent onlyTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|FileContent onlyTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|FileContent query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|FileContent whereContent($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|FileContent whereCreatedAt($value)
|
||||
@ -31,8 +31,8 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|FileContent whereText($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|FileContent whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|FileContent whereUserid($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|FileContent withTrashed()
|
||||
* @method static \Illuminate\Database\Query\Builder|FileContent withoutTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|FileContent withTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|FileContent withoutTrashed()
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class FileContent extends AbstractModel
|
||||
|
||||
@ -28,17 +28,17 @@ use Request;
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
* @property \Illuminate\Support\Carbon|null $deleted_at
|
||||
* @property-read int $owner_userid
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectColumn[] $projectColumn
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ProjectColumn> $projectColumn
|
||||
* @property-read int|null $project_column_count
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectLog[] $projectLog
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ProjectLog> $projectLog
|
||||
* @property-read int|null $project_log_count
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectUser[] $projectUser
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ProjectUser> $projectUser
|
||||
* @property-read int|null $project_user_count
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Project allData($userid = null)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Project authData($userid = null, $owner = null)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Project newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Project newQuery()
|
||||
* @method static \Illuminate\Database\Query\Builder|Project onlyTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Project onlyTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Project query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Project whereArchivedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Project whereArchivedUserid($value)
|
||||
@ -52,8 +52,8 @@ use Request;
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Project whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Project whereUserSimple($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Project whereUserid($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|Project withTrashed()
|
||||
* @method static \Illuminate\Database\Query\Builder|Project withoutTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Project withTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|Project withoutTrashed()
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class Project extends AbstractModel
|
||||
|
||||
@ -20,11 +20,11 @@ use Request;
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
* @property \Illuminate\Support\Carbon|null $deleted_at
|
||||
* @property-read \App\Models\Project|null $project
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectTask[] $projectTask
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ProjectTask> $projectTask
|
||||
* @property-read int|null $project_task_count
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectColumn newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectColumn newQuery()
|
||||
* @method static \Illuminate\Database\Query\Builder|ProjectColumn onlyTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectColumn onlyTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectColumn query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectColumn whereColor($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectColumn whereCreatedAt($value)
|
||||
@ -34,8 +34,8 @@ use Request;
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectColumn whereProjectId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectColumn whereSort($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectColumn whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|ProjectColumn withTrashed()
|
||||
* @method static \Illuminate\Database\Query\Builder|ProjectColumn withoutTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectColumn withTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectColumn withoutTrashed()
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class ProjectColumn extends AbstractModel
|
||||
|
||||
@ -12,7 +12,7 @@ use App\Module\Base;
|
||||
* @property string|null $name 流程名称
|
||||
* @property \Illuminate\Support\Carbon|null $created_at
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectFlowItem[] $projectFlowItem
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ProjectFlowItem> $projectFlowItem
|
||||
* @property-read int|null $project_flow_item_count
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlow newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlow newQuery()
|
||||
|
||||
@ -52,18 +52,18 @@ use Request;
|
||||
* @property-read bool $today
|
||||
* @property-read \App\Models\Project|null $project
|
||||
* @property-read \App\Models\ProjectColumn|null $projectColumn
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectTaskFile[] $taskFile
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ProjectTaskFile> $taskFile
|
||||
* @property-read int|null $task_file_count
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectTaskTag[] $taskTag
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ProjectTaskTag> $taskTag
|
||||
* @property-read int|null $task_tag_count
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectTaskUser[] $taskUser
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ProjectTaskUser> $taskUser
|
||||
* @property-read int|null $task_user_count
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask allData($userid = null)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask authData($userid = null, $owner = null)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask betweenTime($start, $end, $type = 'taskTime')
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask newQuery()
|
||||
* @method static \Illuminate\Database\Query\Builder|ProjectTask onlyTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask onlyTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereArchivedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereArchivedFollow($value)
|
||||
@ -92,8 +92,8 @@ use Request;
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereStartAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereUserid($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|ProjectTask withTrashed()
|
||||
* @method static \Illuminate\Database\Query\Builder|ProjectTask withoutTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask withTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask withoutTrashed()
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class ProjectTask extends AbstractModel
|
||||
@ -530,8 +530,6 @@ class ProjectTask extends AbstractModel
|
||||
public function updateTask($data, &$updateMarking = [])
|
||||
{
|
||||
AbstractModel::transaction(function () use ($data, &$updateMarking) {
|
||||
// 判断版本
|
||||
Base::checkClientVersion('0.19.0');
|
||||
// 主任务
|
||||
$mainTask = $this->parent_id > 0 ? self::find($this->parent_id) : null;
|
||||
// 工作流
|
||||
|
||||
@ -19,7 +19,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
* @property \Illuminate\Support\Carbon|null $deleted_at
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskPushLog newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskPushLog newQuery()
|
||||
* @method static \Illuminate\Database\Query\Builder|ProjectTaskPushLog onlyTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskPushLog onlyTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskPushLog query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskPushLog whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskPushLog whereDeletedAt($value)
|
||||
@ -28,8 +28,8 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskPushLog whereType($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskPushLog whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskPushLog whereUserid($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|ProjectTaskPushLog withTrashed()
|
||||
* @method static \Illuminate\Database\Query\Builder|ProjectTaskPushLog withoutTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskPushLog withTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskPushLog withoutTrashed()
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class ProjectTaskPushLog extends AbstractModel
|
||||
|
||||
@ -23,10 +23,10 @@ use JetBrains\PhpStorm\Pure;
|
||||
* @property int $userid
|
||||
* @property string $content
|
||||
* @property string $sign 汇报唯一标识
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ReportReceive[] $Receives
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\ReportReceive> $Receives
|
||||
* @property-read int|null $receives_count
|
||||
* @property-read mixed $receives
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\User[] $receivesUser
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\User> $receivesUser
|
||||
* @property-read int|null $receives_user_count
|
||||
* @property-read \App\Models\User|null $sendUser
|
||||
* @method static Builder|Report newModelQuery()
|
||||
|
||||
@ -17,7 +17,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
* @property \Illuminate\Support\Carbon|null $deleted_at
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|TaskWorker newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|TaskWorker newQuery()
|
||||
* @method static \Illuminate\Database\Query\Builder|TaskWorker onlyTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|TaskWorker onlyTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|TaskWorker query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|TaskWorker whereArgs($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|TaskWorker whereCreatedAt($value)
|
||||
@ -27,8 +27,8 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|TaskWorker whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|TaskWorker whereStartAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|TaskWorker whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|TaskWorker withTrashed()
|
||||
* @method static \Illuminate\Database\Query\Builder|TaskWorker withoutTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|TaskWorker withTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|TaskWorker withoutTrashed()
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class TaskWorker extends AbstractModel
|
||||
|
||||
@ -24,11 +24,11 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
* @property \Illuminate\Support\Carbon|null $created_at
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
* @property \Illuminate\Support\Carbon|null $deleted_at
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\WebSocketDialogUser[] $dialogUser
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\WebSocketDialogUser> $dialogUser
|
||||
* @property-read int|null $dialog_user_count
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog newQuery()
|
||||
* @method static \Illuminate\Database\Query\Builder|WebSocketDialog onlyTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog onlyTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereAvatar($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereCreatedAt($value)
|
||||
@ -40,8 +40,8 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereOwnerId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereType($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|WebSocketDialog withTrashed()
|
||||
* @method static \Illuminate\Database\Query\Builder|WebSocketDialog withoutTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog withTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog withoutTrashed()
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class WebSocketDialog extends AbstractModel
|
||||
|
||||
@ -39,7 +39,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
* @property-read \App\Models\WebSocketDialog|null $webSocketDialog
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg newModelQuery()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg newQuery()
|
||||
* @method static \Illuminate\Database\Query\Builder|WebSocketDialogMsg onlyTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg onlyTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg query()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg whereDeletedAt($value)
|
||||
@ -61,8 +61,8 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg whereType($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg whereUserid($value)
|
||||
* @method static \Illuminate\Database\Query\Builder|WebSocketDialogMsg withTrashed()
|
||||
* @method static \Illuminate\Database\Query\Builder|WebSocketDialogMsg withoutTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg withTrashed()
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg withoutTrashed()
|
||||
* @mixin \Eloquent
|
||||
*/
|
||||
class WebSocketDialogMsg extends AbstractModel
|
||||
|
||||
@ -1933,60 +1933,6 @@ class Base
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* php://input 字符串解析到变量并获取指定值
|
||||
* @param $key
|
||||
* @return array
|
||||
*/
|
||||
public static function getContentsParse($key)
|
||||
{
|
||||
parse_str(Request::getContent(), $input);
|
||||
if ($key) {
|
||||
$input = $input[$key] ?? array();
|
||||
}
|
||||
return is_array($input) ? $input : array($input);
|
||||
}
|
||||
|
||||
/**
|
||||
* php://input 字符串解析到变量并获取指定值
|
||||
* @param $key
|
||||
* @param null $default
|
||||
* @return mixed|null
|
||||
*/
|
||||
public static function getContentValue($key, $default = null)
|
||||
{
|
||||
global $_A;
|
||||
if (!isset($_A["__static_input_content"])) {
|
||||
parse_str(Request::getContent(), $input);
|
||||
$_A["__static_input_content"] = $input;
|
||||
}
|
||||
return $_A["__static_input_content"][$key] ?? $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
* @param null $default
|
||||
* @return array|mixed|string|null
|
||||
*/
|
||||
public static function getPostValue($key, $default = null)
|
||||
{
|
||||
$value = self::getContentValue($key, $default);
|
||||
if (!isset($value)) {
|
||||
$value = Request::post($key, $default);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
* @param null $default
|
||||
* @return int
|
||||
*/
|
||||
public static function getPostInt($key, $default = null)
|
||||
{
|
||||
return intval(self::getPostValue($key, $default));
|
||||
}
|
||||
|
||||
/**
|
||||
* 多维 array_values
|
||||
* @param $array
|
||||
|
||||
@ -4,12 +4,14 @@ namespace App\Module;
|
||||
|
||||
use App\Exceptions\ApiException;
|
||||
use App\Models\User;
|
||||
use Cache;
|
||||
use Carbon\Carbon;
|
||||
use FFI;
|
||||
|
||||
class Doo
|
||||
{
|
||||
private static $doo;
|
||||
private static $passphrase = "LYHevk5n";
|
||||
|
||||
/**
|
||||
* char转为字符串
|
||||
@ -45,10 +47,21 @@ class Doo
|
||||
char* md5s(char* text, char* password);
|
||||
char* macs();
|
||||
char* dooSN();
|
||||
char* pgpGenerateKeyPair(char* name, char* email, char* passphrase);
|
||||
char* pgpEncrypt(char* plainText, char* publicKey);
|
||||
char* pgpDecrypt(char* cipherText, char* privateKey, char* passphrase);
|
||||
EOF, "/usr/lib/doo/doo.so");
|
||||
$token = $token ?: Base::headerOrInput('token');
|
||||
$language = $language ?: Base::headerOrInput('language');
|
||||
self::$doo->initialize("/var/www", $token, $language);
|
||||
//
|
||||
$priPath = config_path("PGP_PRIVATE");
|
||||
$pubPath = config_path("PGP_PUBLIC");
|
||||
if (!file_exists($priPath) || !file_exists($pubPath)) {
|
||||
$data = self::pgpGenerateKeyPair("doo", "admin@admin.com", self::$passphrase);
|
||||
file_put_contents($priPath, $data['private_key']);
|
||||
file_put_contents($pubPath, $data['public_key']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -299,4 +312,103 @@ class Doo
|
||||
{
|
||||
return self::string(self::doo()->dooSN());
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成PGP密钥对
|
||||
* @param $name
|
||||
* @param $email
|
||||
* @param string $passphrase
|
||||
* @return array
|
||||
*/
|
||||
public static function pgpGenerateKeyPair($name, $email, string $passphrase = ""): array
|
||||
{
|
||||
return Base::json2array(self::string(self::doo()->pgpGenerateKeyPair($name, $email, $passphrase)));
|
||||
}
|
||||
|
||||
/**
|
||||
* PGP加密
|
||||
* @param $plaintext
|
||||
* @param $publicKey
|
||||
* @return string
|
||||
*/
|
||||
public static function pgpEncrypt($plaintext, $publicKey): string
|
||||
{
|
||||
if (strlen($publicKey) < 50) {
|
||||
$keyCache = Base::json2array(Cache::get("KeyPair::" . $publicKey));
|
||||
$publicKey = $keyCache['public_key'];
|
||||
}
|
||||
return self::string(self::doo()->pgpEncrypt($plaintext, $publicKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* PGP解密
|
||||
* @param $encryptedText
|
||||
* @param $privateKey
|
||||
* @param null $passphrase
|
||||
* @return string
|
||||
*/
|
||||
public static function pgpDecrypt($encryptedText, $privateKey, $passphrase = null): string
|
||||
{
|
||||
if (strlen($privateKey) < 50) {
|
||||
$keyCache = Base::json2array(Cache::get("KeyPair::" . $privateKey));
|
||||
$privateKey = $keyCache['private_key'];
|
||||
$passphrase = $keyCache['passphrase'];
|
||||
}
|
||||
return self::string(self::doo()->pgpDecrypt($encryptedText, $privateKey, $passphrase));
|
||||
}
|
||||
|
||||
/**
|
||||
* PGP加密API
|
||||
* @param $plaintext
|
||||
* @param $publicKey
|
||||
* @return string
|
||||
*/
|
||||
public static function pgpEncryptApi($plaintext, $publicKey): string
|
||||
{
|
||||
$content = Base::array2json($plaintext);
|
||||
$content = self::pgpEncrypt($content, $publicKey);
|
||||
return preg_replace("/\s*-----(BEGIN|END) PGP MESSAGE-----\s*/i", "", $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* PGP解密API
|
||||
* @param $encryptedText
|
||||
* @param null $privateKey
|
||||
* @param null $passphrase
|
||||
* @return array
|
||||
*/
|
||||
public static function pgpDecryptApi($encryptedText, $privateKey, $passphrase = null): array
|
||||
{
|
||||
$content = "-----BEGIN PGP MESSAGE-----\n\n" . $encryptedText . "\n-----END PGP MESSAGE-----";
|
||||
$content = self::pgpDecrypt($content, $privateKey, $passphrase);
|
||||
return Base::json2array($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析PGP参数
|
||||
* @param $string
|
||||
* @return string[]
|
||||
*/
|
||||
public static function pgpParseStr($string): array
|
||||
{
|
||||
$array = [
|
||||
'encrypt_type' => '',
|
||||
'encrypt_id' => '',
|
||||
'client_type' => '',
|
||||
'client_key' => '',
|
||||
];
|
||||
$string = str_replace(";", "&", $string);
|
||||
parse_str($string, $params);
|
||||
foreach ($params as $key => $value) {
|
||||
$key = strtolower(trim($key));
|
||||
if ($key) {
|
||||
$array[$key] = trim($value);
|
||||
}
|
||||
}
|
||||
if ($array['client_type'] === 'pgp' && $array['client_key']) {
|
||||
$array['client_key'] = str_replace(["-", "_", "$"], ["+", "/", "\n"], $array['client_key']);
|
||||
$array['client_key'] = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\n" . $array['client_key'] . "\n-----END PGP PUBLIC KEY BLOCK-----";
|
||||
}
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,6 +13,8 @@
|
||||
"ext-gd": "*",
|
||||
"ext-json": "*",
|
||||
"ext-libxml": "*",
|
||||
"ext-gnupg": "*",
|
||||
"ext-openssl": "*",
|
||||
"ext-simplexml": "*",
|
||||
"directorytree/ldaprecord-laravel": "^2.7",
|
||||
"fideloper/proxy": "^4.4.1",
|
||||
|
||||
@ -3,8 +3,12 @@ version: '3'
|
||||
services:
|
||||
php:
|
||||
container_name: "dootask-php-${APP_ID}"
|
||||
image: "kuaifan/php:swoole-8.0.rc7"
|
||||
shm_size: "1024m"
|
||||
image: "kuaifan/php:swoole-8.0.rc9"
|
||||
shm_size: "2gb"
|
||||
ulimits:
|
||||
core:
|
||||
soft: 0
|
||||
hard: 0
|
||||
volumes:
|
||||
- ./docker/crontab/crontab.conf:/etc/supervisor/conf.d/crontab.conf
|
||||
- ./docker/php/php.conf:/etc/supervisor/conf.d/php.conf
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
<!--style-->
|
||||
<link rel="stylesheet" type="text/css" href="./css/iview.css">
|
||||
<link rel="stylesheet" type="text/css" href="./css/loading.css">
|
||||
<script src="./js/jsencrypt.min.js"></script>
|
||||
<script src="./js/scroll-into-view.min.js"></script>
|
||||
<script src="./config.js"></script>
|
||||
</head>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "DooTask",
|
||||
"version": "0.25.42",
|
||||
"version": "0.25.48",
|
||||
"description": "DooTask is task management system.",
|
||||
"scripts": {
|
||||
"start": "./cmd dev",
|
||||
@ -23,12 +23,13 @@
|
||||
"axios": "^0.24.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"css-loader": "^6.7.2",
|
||||
"dexie": "^3.2.3",
|
||||
"echarts": "^5.2.2",
|
||||
"element-ui": "git+https://github.com/kuaifan/element.git#master",
|
||||
"file-loader": "^6.2.0",
|
||||
"inquirer": "^8.2.0",
|
||||
"internal-ip": "^6.2.0",
|
||||
"jquery": "^3.6.1",
|
||||
"jquery": "^3.6.4",
|
||||
"jspdf": "^2.5.1",
|
||||
"le5le-store": "^1.0.7",
|
||||
"less": "^4.1.2",
|
||||
@ -38,6 +39,7 @@
|
||||
"moment": "^2.29.1",
|
||||
"node-sass": "^6.0.1",
|
||||
"notification-koro1": "^1.1.1",
|
||||
"openpgp": "git+https://github.com/kuaifan/openpgpjs.git#base64",
|
||||
"photoswipe": "^5.2.8",
|
||||
"postcss": "^8.4.5",
|
||||
"quill": "^1.3.7",
|
||||
|
||||
87
public/docs/assets/main.bundle.js
vendored
87
public/docs/assets/main.bundle.js
vendored
File diff suppressed because one or more lines are too long
1
public/docs/assets/main.css
vendored
1
public/docs/assets/main.css
vendored
@ -49,6 +49,7 @@ input[type="date"] {
|
||||
src: url('./glyphicons-halflings-regular.eot');
|
||||
src: url('./glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),
|
||||
url('./glyphicons-halflings-regular.woff') format('woff'),
|
||||
url('./glyphicons-halflings-regular.woff2') format('woff2'),
|
||||
url('./glyphicons-halflings-regular.ttf') format('truetype'),
|
||||
url('./glyphicons-halflings-regular.svg#glyphicons-halflingsregular') format('svg');
|
||||
}
|
||||
|
||||
@ -5,13 +5,13 @@
|
||||
<meta name="description" content="APP接口文档">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link href="assets/bootstrap.min.css" rel="stylesheet" media="screen">
|
||||
<link href="assets/prism.css" rel="stylesheet" />
|
||||
<link href="assets/main.css" rel="stylesheet" media="screen, print">
|
||||
<link href="assets/favicon.ico" rel="icon" type="image/x-icon">
|
||||
<link href="assets/apple-touch-icon.png" rel="apple-touch-icon" sizes="180x180">
|
||||
<link href="assets/favicon-32x32.png" rel="icon" type="image/png" sizes="32x32">
|
||||
<link href="assets/favicon-16x16.png"rel="icon" type="image/png" sizes="16x16">
|
||||
<link href="assets/bootstrap.min.css?v=1679925462953" rel="stylesheet" media="screen">
|
||||
<link href="assets/prism.css?v=1679925462953" rel="stylesheet" />
|
||||
<link href="assets/main.css?v=1679925462953" rel="stylesheet" media="screen, print">
|
||||
<link href="assets/favicon.ico?v=1679925462953" rel="icon" type="image/x-icon">
|
||||
<link href="assets/apple-touch-icon.png?v=1679925462953" rel="apple-touch-icon" sizes="180x180">
|
||||
<link href="assets/favicon-32x32.png?v=1679925462953" rel="icon" type="image/png" sizes="32x32">
|
||||
<link href="assets/favicon-16x16.png?v=1679925462953" rel="icon" type="image/png" sizes="16x16">
|
||||
</head>
|
||||
|
||||
<body class="container-fluid">
|
||||
@ -306,7 +306,7 @@
|
||||
{{#if optional}}
|
||||
<span class="label optional">{{__ "optional"}}</span>
|
||||
{{else}}
|
||||
{{#if ../template.showRequiredLabels}}
|
||||
{{#if ../../template.showRequiredLabels}}
|
||||
<span class="label required">{{__ "required"}}</span>
|
||||
{{/if}}
|
||||
{{/if}}</td>
|
||||
@ -928,6 +928,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="assets/main.bundle.js"></script>
|
||||
<script src="assets/main.bundle.js?v=1679925462953"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
2
public/js/jsencrypt.min.js
vendored
Normal file
2
public/js/jsencrypt.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
resources/assets/js/app.js
vendored
2
resources/assets/js/app.js
vendored
@ -212,7 +212,7 @@ store.dispatch("init").then(action => {
|
||||
$A.Notice = app.$Notice;
|
||||
$A.Modal = app.$Modal;
|
||||
|
||||
if (action === "clearCacheSuccess") {
|
||||
if (action === "handleClearCache") {
|
||||
$A.messageSuccess("清除成功");
|
||||
}
|
||||
})
|
||||
|
||||
17
resources/assets/js/functions/common.js
vendored
17
resources/assets/js/functions/common.js
vendored
@ -36,13 +36,26 @@ const localforage = require("localforage");
|
||||
* 是否在数组里
|
||||
* @param key
|
||||
* @param array
|
||||
* @param regular
|
||||
* @returns {boolean|*}
|
||||
*/
|
||||
inArray(key, array) {
|
||||
inArray(key, array, regular = false) {
|
||||
if (!this.isArray(array)) {
|
||||
return false;
|
||||
}
|
||||
return array.includes(key);
|
||||
if (regular) {
|
||||
return !!array.find(item => {
|
||||
if (item && item.indexOf("*")) {
|
||||
const rege = new RegExp("^" + item.replace(/[-\/\\^$+?.()|[\]{}]/g, '\\$&').replace(/\*/g, '.*') + "$", "g")
|
||||
if (rege.test(key)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return item == key
|
||||
});
|
||||
} else {
|
||||
return array.includes(key);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@ -514,23 +514,23 @@ export default {
|
||||
this.invite = $A.trim(this.invite)
|
||||
//
|
||||
if (!$A.isEmail(this.email)) {
|
||||
$A.messageWarning("请输入正确的邮箱地址");
|
||||
this.$refs.email.focus();
|
||||
return;
|
||||
$A.messageWarning("请输入正确的邮箱地址")
|
||||
this.$refs.email.focus()
|
||||
return
|
||||
}
|
||||
if (!this.password) {
|
||||
$A.messageWarning("请输入密码");
|
||||
this.$refs.password.focus();
|
||||
return;
|
||||
$A.messageWarning("请输入密码")
|
||||
this.$refs.password.focus()
|
||||
return
|
||||
}
|
||||
if (this.loginType == 'reg') {
|
||||
if (this.password != this.password2) {
|
||||
$A.messageWarning("确认密码输入不一致");
|
||||
this.$refs.password2.focus();
|
||||
return;
|
||||
$A.messageWarning("确认密码输入不一致")
|
||||
this.$refs.password2.focus()
|
||||
return
|
||||
}
|
||||
}
|
||||
this.loadIng++;
|
||||
this.loadIng++
|
||||
this.$store.dispatch("call", {
|
||||
url: 'users/login',
|
||||
data: {
|
||||
@ -542,35 +542,39 @@ export default {
|
||||
},
|
||||
}).then(({data}) => {
|
||||
$A.IDBSave("cacheLoginEmail", this.email)
|
||||
this.codeNeed = false;
|
||||
this.$store.dispatch("handleClearCache", data).then(this.goNext);
|
||||
this.codeNeed = false
|
||||
this.$store.dispatch("handleClearCache", data).then(this.goNext)
|
||||
}).catch(({data, msg}) => {
|
||||
if (data.code === 'email') {
|
||||
this.loginType = 'login';
|
||||
$A.modalWarning(msg);
|
||||
this.loginType = 'login'
|
||||
$A.modalWarning(msg)
|
||||
} else {
|
||||
$A.modalError(msg);
|
||||
$A.modalError({
|
||||
content: msg,
|
||||
onOk: _ => {
|
||||
this.$refs.code.focus()
|
||||
}
|
||||
})
|
||||
}
|
||||
if (data.code === 'need') {
|
||||
this.reCode();
|
||||
this.codeNeed = true;
|
||||
this.$refs.code.focus();
|
||||
this.reCode()
|
||||
this.codeNeed = true
|
||||
}
|
||||
}).finally(_ => {
|
||||
this.loadIng--;
|
||||
});
|
||||
this.loadIng--
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
goNext() {
|
||||
this.loginJump = true;
|
||||
const fromUrl = decodeURIComponent($A.getObject(this.$route.query, 'from'));
|
||||
this.loginJump = true
|
||||
const fromUrl = decodeURIComponent($A.getObject(this.$route.query, 'from'))
|
||||
if (fromUrl) {
|
||||
$A.IDBSet("clearCache", "login").then(_ => {
|
||||
window.location.replace(fromUrl);
|
||||
window.location.replace(fromUrl)
|
||||
})
|
||||
} else {
|
||||
this.goForward({name: 'manage-dashboard'}, true);
|
||||
this.goForward({name: 'manage-dashboard'}, true)
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -742,8 +742,7 @@ export default {
|
||||
Store.set('updateNotification', null);
|
||||
return;
|
||||
case 'clearCache':
|
||||
this.$store.dispatch("handleClearCache", null).then(async () => {
|
||||
await $A.IDBSet("clearCache", "handle")
|
||||
$A.IDBSet("clearCache", "handle").then(_ => {
|
||||
$A.reloadUrl()
|
||||
});
|
||||
return;
|
||||
|
||||
@ -166,7 +166,7 @@
|
||||
@on-emoji="onEmoji"
|
||||
@on-show-emoji-user="onShowEmojiUser">
|
||||
<template #header>
|
||||
<div v-if="(allMsgs.length === 0 && loadMsg) || prevId > 0" class="dialog-item loading">
|
||||
<div v-if="(allMsgs.length === 0 && loadIng) || prevId > 0" class="dialog-item loading">
|
||||
<div v-if="scrollOffset < 100" class="dialog-wrapper-loading"></div>
|
||||
</div>
|
||||
<div v-else-if="allMsgs.length === 0" class="dialog-item nothing">{{$L('暂无消息')}}</div>
|
||||
@ -537,6 +537,7 @@ export default {
|
||||
msgText: '',
|
||||
msgNew: 0,
|
||||
msgType: '',
|
||||
loadIng: 0,
|
||||
|
||||
allMsgs: [],
|
||||
tempMsgs: [],
|
||||
@ -936,6 +937,19 @@ export default {
|
||||
immediate: true
|
||||
},
|
||||
|
||||
loadMsg: {
|
||||
handler(load) {
|
||||
if (load) {
|
||||
this.loadIng++
|
||||
} else {
|
||||
setTimeout(_ => {
|
||||
this.loadIng--
|
||||
}, 300)
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
|
||||
msgType() {
|
||||
this.getMsgs({
|
||||
dialog_id: this.dialogId,
|
||||
|
||||
@ -138,8 +138,7 @@ export default {
|
||||
toggleRoute(path) {
|
||||
switch (path) {
|
||||
case 'clearCache':
|
||||
this.$store.dispatch("handleClearCache", null).then(async () => {
|
||||
await $A.IDBSet("clearCache", "handle")
|
||||
$A.IDBSet("clearCache", "handle").then(_ => {
|
||||
$A.reloadUrl()
|
||||
});
|
||||
break;
|
||||
|
||||
320
resources/assets/js/store/actions.js
vendored
320
resources/assets/js/store/actions.js
vendored
@ -1,6 +1,7 @@
|
||||
import {Store} from 'le5le-store';
|
||||
import * as openpgp from 'openpgp/lightweight';
|
||||
import {languageType} from "../language";
|
||||
import {$callData} from './utils'
|
||||
import {$callData, $urlSafe} from './utils'
|
||||
|
||||
export default {
|
||||
/**
|
||||
@ -26,6 +27,7 @@ export default {
|
||||
}
|
||||
|
||||
// 读取缓存
|
||||
state.clientId = await $A.IDBString("clientId")
|
||||
state.cacheServerUrl = await $A.IDBString("cacheServerUrl")
|
||||
state.cacheUserBasic = await $A.IDBArray("cacheUserBasic")
|
||||
state.cacheDialogs = (await $A.IDBArray("cacheDialogs")).map(item => Object.assign(item, {loading: false, extra_draft_has: item.extra_draft_content ? 1 : 0}))
|
||||
@ -40,13 +42,19 @@ export default {
|
||||
state.callAt = await $A.IDBArray("callAt")
|
||||
state.cacheEmojis = await $A.IDBArray("cacheEmojis")
|
||||
|
||||
// 客户端ID
|
||||
if (!state.clientId) {
|
||||
state.clientId = $A.randomString(6)
|
||||
await $A.IDBSet("clientId", state.clientId)
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
const clearCache = await $A.IDBString("clearCache")
|
||||
if (clearCache) {
|
||||
await $A.IDBRemove("clearCache")
|
||||
await $A.IDBSet("callAt", state.callAt = [])
|
||||
if (clearCache === "handle") {
|
||||
action = "clearCacheSuccess"
|
||||
await dispatch(action = "handleClearCache")
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,7 +85,15 @@ export default {
|
||||
}
|
||||
state.themeIsDark = $A.dark.isDarkEnabled()
|
||||
|
||||
//
|
||||
dispatch("call", {
|
||||
url: "users/key/client",
|
||||
data: {client_id: state.clientId},
|
||||
encrypt: false,
|
||||
}).then(({data}) => {
|
||||
state.apiKeyData = data;
|
||||
})
|
||||
|
||||
// 加载语言包
|
||||
$A.loadScriptS([
|
||||
`language/web/key.js`,
|
||||
`language/web/${languageType}.js`,
|
||||
@ -91,7 +107,7 @@ export default {
|
||||
* 访问接口
|
||||
* @param state
|
||||
* @param dispatch
|
||||
* @param params // {url,data,method,timeout,header,spinner,websocket, before,complete,success,error,after}
|
||||
* @param params // {url,data,method,timeout,header,spinner,websocket,encrypt, before,complete,success,error,after}
|
||||
* @returns {Promise<unknown>}
|
||||
*/
|
||||
call({state, dispatch}, params) {
|
||||
@ -107,34 +123,68 @@ export default {
|
||||
if ($A.isJson(params.header)) {
|
||||
params.header = Object.assign(header, params.header)
|
||||
} else {
|
||||
params.header = header;
|
||||
params.header = header
|
||||
}
|
||||
params.url = $A.apiUrl(params.url);
|
||||
params.data = $A.date2string(params.data);
|
||||
if (params.encrypt === undefined && $A.inArray(params.url, [
|
||||
'users/login',
|
||||
'users/editpass',
|
||||
'users/operation',
|
||||
'users/delete/account',
|
||||
'dialog/msg/*',
|
||||
], true)) {
|
||||
params.encrypt = true
|
||||
}
|
||||
params.url = $A.apiUrl(params.url)
|
||||
params.data = $A.date2string(params.data)
|
||||
//
|
||||
const cloneParams = $A.cloneJSON(params);
|
||||
return new Promise(function (resolve, reject) {
|
||||
const cloneParams = $A.cloneJSON(params)
|
||||
return new Promise(async (resolve, reject) => {
|
||||
// 加密传输
|
||||
const encrypt = []
|
||||
if (params.encrypt === true) {
|
||||
// 有数据才加密
|
||||
if (params.data) {
|
||||
// PGP加密
|
||||
if (state.apiKeyData.type === 'pgp') {
|
||||
encrypt.push(`encrypt_type=${state.apiKeyData.type};encrypt_id=${state.apiKeyData.id}`)
|
||||
params.method = "post" // 加密传输时强制使用post
|
||||
params.data = {encrypted: await dispatch("pgpEncryptApi", params.data)}
|
||||
}
|
||||
}
|
||||
encrypt.push("client_type=pgp;client_key=" + $urlSafe((await dispatch("pgpGetLocalKey")).publicKeyB64))
|
||||
}
|
||||
if (encrypt.length > 0) {
|
||||
params.header.encrypt = encrypt.join(";")
|
||||
}
|
||||
// 数据转换
|
||||
if (params.method === "post") {
|
||||
params.data = JSON.stringify(params.data)
|
||||
}
|
||||
// Spinner
|
||||
if (params.spinner === true || (typeof params.spinner === "number" && params.spinner > 0)) {
|
||||
const {before, complete} = params;
|
||||
const {before, complete} = params
|
||||
params.before = () => {
|
||||
dispatch("showSpinner", typeof params.spinner === "number" ? params.spinner : 0)
|
||||
typeof before === "function" && before()
|
||||
};
|
||||
}
|
||||
//
|
||||
params.complete = () => {
|
||||
dispatch("hiddenSpinner")
|
||||
typeof complete === "function" && complete()
|
||||
};
|
||||
}
|
||||
//
|
||||
params.success = (result, status, xhr) => {
|
||||
state.ajaxNetworkException = false;
|
||||
if (!$A.isJson(result)) {
|
||||
console.log(result, status, xhr);
|
||||
reject({ret: -1, data: {}, msg: "Return error"})
|
||||
return;
|
||||
}
|
||||
const {ret, data, msg} = result;
|
||||
}
|
||||
// 请求回调
|
||||
params.success = async (result, status, xhr) => {
|
||||
state.ajaxNetworkException = false
|
||||
if (!$A.isJson(result)) {
|
||||
console.log(result, status, xhr)
|
||||
reject({ret: -1, data: {}, msg: "Return error"})
|
||||
return
|
||||
}
|
||||
if (params.encrypt === true && result.encrypted) {
|
||||
result = await dispatch("pgpDecryptApi", result.encrypted)
|
||||
}
|
||||
const {ret, data, msg} = result
|
||||
if (ret === -1) {
|
||||
state.userId = 0
|
||||
if (params.skipAuthError !== true) {
|
||||
@ -144,109 +194,110 @@ export default {
|
||||
onOk: () => {
|
||||
dispatch("logout")
|
||||
}
|
||||
});
|
||||
})
|
||||
reject(result)
|
||||
return;
|
||||
return
|
||||
}
|
||||
}
|
||||
if (ret === -2 && params.checkNick !== false) {
|
||||
// 需要昵称
|
||||
dispatch("userEditInput", 'nickname').then(() => {
|
||||
dispatch("call", cloneParams).then(resolve).catch(reject);
|
||||
dispatch("call", cloneParams).then(resolve).catch(reject)
|
||||
}).catch(err => {
|
||||
reject({ret: -1, data, msg: err || $A.L('请设置昵称!')})
|
||||
});
|
||||
return;
|
||||
})
|
||||
return
|
||||
}
|
||||
if (ret === -3 && params.checkTel !== false) {
|
||||
// 需要联系电话
|
||||
dispatch("userEditInput", 'tel').then(() => {
|
||||
dispatch("call", cloneParams).then(resolve).catch(reject);
|
||||
dispatch("call", cloneParams).then(resolve).catch(reject)
|
||||
}).catch(err => {
|
||||
reject({ret: -1, data, msg: err || $A.L('请设置联系电话!')})
|
||||
});
|
||||
return;
|
||||
})
|
||||
return
|
||||
}
|
||||
if (ret === 1) {
|
||||
resolve({data, msg});
|
||||
resolve({data, msg})
|
||||
} else {
|
||||
reject({ret, data, msg: msg || "Unknown error"})
|
||||
//
|
||||
if (ret === -4001) {
|
||||
dispatch("forgetProject", data.project_id);
|
||||
dispatch("forgetProject", data.project_id)
|
||||
} else if (ret === -4002) {
|
||||
dispatch("forgetTask", data.task_id);
|
||||
dispatch("forgetTask", data.task_id)
|
||||
} else if (ret === -4003) {
|
||||
dispatch("forgetDialog", data.dialog_id);
|
||||
dispatch("forgetDialog", data.dialog_id)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
params.error = (xhr, status) => {
|
||||
const networkException = window.navigator.onLine === false || (status === 0 && xhr.readyState === 4);
|
||||
const networkException = window.navigator.onLine === false || (status === 0 && xhr.readyState === 4)
|
||||
if (params.checkNetwork !== false) {
|
||||
state.ajaxNetworkException = networkException;
|
||||
state.ajaxNetworkException = networkException
|
||||
}
|
||||
if (networkException) {
|
||||
reject({ret: -1001, data: {}, msg: "Network exception"})
|
||||
} else {
|
||||
reject({ret: -1, data: {}, msg: "System error"})
|
||||
}
|
||||
};
|
||||
//
|
||||
if (params.websocket === true || params.ws === true) {
|
||||
const apiWebsocket = $A.randomString(16);
|
||||
}
|
||||
// WebSocket
|
||||
if (params.websocket === true) {
|
||||
const apiWebsocket = $A.randomString(16)
|
||||
const apiTimeout = setTimeout(() => {
|
||||
const WListener = state.ajaxWsListener.find((item) => item.apiWebsocket == apiWebsocket);
|
||||
const WListener = state.ajaxWsListener.find((item) => item.apiWebsocket == apiWebsocket)
|
||||
if (WListener) {
|
||||
WListener.complete();
|
||||
WListener.error("timeout");
|
||||
WListener.after();
|
||||
WListener.complete()
|
||||
WListener.error("timeout")
|
||||
WListener.after()
|
||||
}
|
||||
state.ajaxWsListener = state.ajaxWsListener.filter((item) => item.apiWebsocket != apiWebsocket);
|
||||
}, params.timeout || 30000);
|
||||
state.ajaxWsListener = state.ajaxWsListener.filter((item) => item.apiWebsocket != apiWebsocket)
|
||||
}, params.timeout || 30000)
|
||||
state.ajaxWsListener.push({
|
||||
apiWebsocket: apiWebsocket,
|
||||
complete: typeof params.complete === "function" ? params.complete : () => { },
|
||||
success: typeof params.success === "function" ? params.success : () => { },
|
||||
error: typeof params.error === "function" ? params.error : () => { },
|
||||
after: typeof params.after === "function" ? params.after : () => { },
|
||||
});
|
||||
})
|
||||
//
|
||||
params.complete = () => { };
|
||||
params.success = () => { };
|
||||
params.error = () => { };
|
||||
params.after = () => { };
|
||||
params.header['Api-Websocket'] = apiWebsocket;
|
||||
params.complete = () => { }
|
||||
params.success = () => { }
|
||||
params.error = () => { }
|
||||
params.after = () => { }
|
||||
params.header['Api-Websocket'] = apiWebsocket
|
||||
//
|
||||
if (state.ajaxWsReady === false) {
|
||||
state.ajaxWsReady = true;
|
||||
state.ajaxWsReady = true
|
||||
dispatch("websocketMsgListener", {
|
||||
name: "apiWebsocket",
|
||||
callback: (msg) => {
|
||||
switch (msg.type) {
|
||||
case 'apiWebsocket':
|
||||
clearTimeout(apiTimeout);
|
||||
const apiWebsocket = msg.apiWebsocket;
|
||||
const apiSuccess = msg.apiSuccess;
|
||||
const apiResult = msg.data;
|
||||
const WListener = state.ajaxWsListener.find((item) => item.apiWebsocket == apiWebsocket);
|
||||
clearTimeout(apiTimeout)
|
||||
const apiWebsocket = msg.apiWebsocket
|
||||
const apiSuccess = msg.apiSuccess
|
||||
const apiResult = msg.data
|
||||
const WListener = state.ajaxWsListener.find((item) => item.apiWebsocket == apiWebsocket)
|
||||
if (WListener) {
|
||||
WListener.complete();
|
||||
WListener.complete()
|
||||
if (apiSuccess) {
|
||||
WListener.success(apiResult);
|
||||
WListener.success(apiResult)
|
||||
} else {
|
||||
WListener.error(apiResult);
|
||||
WListener.error(apiResult)
|
||||
}
|
||||
WListener.after();
|
||||
WListener.after()
|
||||
}
|
||||
state.ajaxWsListener = state.ajaxWsListener.filter((item) => item.apiWebsocket != apiWebsocket);
|
||||
break;
|
||||
state.ajaxWsListener = state.ajaxWsListener.filter((item) => item.apiWebsocket != apiWebsocket)
|
||||
break
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
$A.ajaxc(params);
|
||||
//
|
||||
$A.ajaxc(params)
|
||||
})
|
||||
},
|
||||
|
||||
@ -668,6 +719,7 @@ export default {
|
||||
const cacheLoginEmail = await $A.IDBString("cacheLoginEmail");
|
||||
const cacheFileSort = await $A.IDBJson("cacheFileSort");
|
||||
await $A.IDBClear();
|
||||
await $A.IDBSet("clientId", state.clientId);
|
||||
await $A.IDBSet("cacheServerUrl", state.cacheServerUrl);
|
||||
await $A.IDBSet("cacheProjectParameter", state.cacheProjectParameter);
|
||||
await $A.IDBSet("cacheLoginEmail", cacheLoginEmail);
|
||||
@ -3132,5 +3184,141 @@ export default {
|
||||
state.ws.close();
|
||||
state.ws = null;
|
||||
}
|
||||
},
|
||||
|
||||
/** *****************************************************************************************/
|
||||
/** *************************************** pgp *********************************************/
|
||||
/** *****************************************************************************************/
|
||||
|
||||
/**
|
||||
* 创建密钥对
|
||||
* @param state
|
||||
* @returns {Promise<unknown>}
|
||||
*/
|
||||
pgpGenerate({state}) {
|
||||
return new Promise(async resolve => {
|
||||
const data = await openpgp.generateKey({
|
||||
type: 'ecc',
|
||||
curve: 'curve25519',
|
||||
passphrase: state.clientId,
|
||||
userIDs: [{name: 'doo', email: 'admin@admin.com'}],
|
||||
})
|
||||
data.publicKeyB64 = data.publicKey.replace(/\s*-----(BEGIN|END) PGP PUBLIC KEY BLOCK-----\s*/g, '').replace(/\n+/g, '$')
|
||||
resolve(data)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取密钥对(不存在自动创建)
|
||||
* @param state
|
||||
* @param dispatch
|
||||
* @returns {Promise<unknown>}
|
||||
*/
|
||||
pgpGetLocalKey({state, dispatch}) {
|
||||
return new Promise(async resolve => {
|
||||
// 已存在
|
||||
if (state.localKeyPair.privateKey) {
|
||||
return resolve(state.localKeyPair)
|
||||
}
|
||||
// 避免重复生成
|
||||
while (state.localKeyLock === true) {
|
||||
await new Promise(r => setTimeout(r, 100));
|
||||
}
|
||||
if (state.localKeyPair.privateKey) {
|
||||
return resolve(state.localKeyPair)
|
||||
}
|
||||
// 生成密钥对
|
||||
state.localKeyLock = true
|
||||
state.localKeyPair = await dispatch("pgpGenerate")
|
||||
state.localKeyLock = false
|
||||
resolve(state.localKeyPair)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 加密
|
||||
* @param state
|
||||
* @param dispatch
|
||||
* @param data {message:any, ?publicKey:string}
|
||||
* @returns {Promise<unknown>}
|
||||
*/
|
||||
pgpEncrypt({state, dispatch}, data) {
|
||||
return new Promise(async resolve => {
|
||||
if (!$A.isJson(data)) {
|
||||
data = {message: data}
|
||||
}
|
||||
const message = data.message || data.text
|
||||
const publicKeyArmored = data.publicKey || data.key || (await dispatch("pgpGetLocalKey")).publicKey
|
||||
const encryptionKeys = await openpgp.readKey({armoredKey: publicKeyArmored})
|
||||
//
|
||||
const encrypted = await openpgp.encrypt({
|
||||
message: await openpgp.createMessage({text: message}),
|
||||
encryptionKeys,
|
||||
})
|
||||
resolve(encrypted)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 解密
|
||||
* @param state
|
||||
* @param dispatch
|
||||
* @param data {encrypted:any, ?privateKey:string, ?passphrase:string}
|
||||
* @returns {Promise<unknown>}
|
||||
*/
|
||||
pgpDecrypt({state, dispatch}, data) {
|
||||
return new Promise(async resolve => {
|
||||
if (!$A.isJson(data)) {
|
||||
data = {encrypted: data}
|
||||
}
|
||||
const encrypted = data.encrypted || data.text
|
||||
const privateKeyArmored = data.privateKey || data.key || (await dispatch("pgpGetLocalKey")).privateKey
|
||||
const decryptionKeys = await openpgp.decryptKey({
|
||||
privateKey: await openpgp.readPrivateKey({armoredKey: privateKeyArmored}),
|
||||
passphrase: data.passphrase || state.clientId
|
||||
})
|
||||
//
|
||||
const {data: decryptData} = await openpgp.decrypt({
|
||||
message: await openpgp.readMessage({armoredMessage: encrypted}),
|
||||
decryptionKeys
|
||||
})
|
||||
resolve(decryptData)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* API加密
|
||||
* @param state
|
||||
* @param dispatch
|
||||
* @param data
|
||||
* @returns {Promise<unknown>}
|
||||
*/
|
||||
pgpEncryptApi({state, dispatch}, data) {
|
||||
return new Promise(resolve => {
|
||||
data = $A.jsonStringify(data)
|
||||
dispatch("pgpEncrypt", {
|
||||
message: data,
|
||||
publicKey: state.apiKeyData.key
|
||||
}).then(data => {
|
||||
resolve(data.replace(/\s*-----(BEGIN|END) PGP MESSAGE-----\s*/g, ''))
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* API解密
|
||||
* @param state
|
||||
* @param dispatch
|
||||
* @param data
|
||||
* @returns {Promise<unknown>}
|
||||
*/
|
||||
pgpDecryptApi({state, dispatch}, data) {
|
||||
return new Promise(resolve => {
|
||||
dispatch("pgpDecrypt", {
|
||||
encrypted: "-----BEGIN PGP MESSAGE-----\n\n" + data + "\n-----END PGP MESSAGE-----"
|
||||
}).then(data => {
|
||||
resolve($A.jsonParse(data))
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
8
resources/assets/js/store/state.js
vendored
8
resources/assets/js/store/state.js
vendored
@ -1,4 +1,7 @@
|
||||
export default {
|
||||
// 客户端ID(希望不变的,除非清除浏览器缓存或者卸载应用)
|
||||
clientId: "",
|
||||
|
||||
// 是否移动端(支持触摸)
|
||||
supportTouch: "ontouchend" in document,
|
||||
|
||||
@ -170,4 +173,9 @@ export default {
|
||||
// 表单布局
|
||||
formLabelPosition: $A(window).width() > 576 ? 'right' : 'top',
|
||||
formLabelWidth: $A(window).width() > 576 ? 'auto' : '',
|
||||
|
||||
// 加密相关
|
||||
apiKeyData: {},
|
||||
localKeyPair: {},
|
||||
localKeyLock: false,
|
||||
};
|
||||
|
||||
11
resources/assets/js/store/utils.js
vendored
11
resources/assets/js/store/utils.js
vendored
@ -73,3 +73,14 @@ function __callData(key, requestData, state) {
|
||||
export function $callData(key, requestData, state) {
|
||||
return new __callData(key, requestData, state)
|
||||
}
|
||||
|
||||
export function $urlSafe(value, encode = true) {
|
||||
if (value) {
|
||||
if (encode) {
|
||||
value = String(value).replace(/\+/g, "-").replace(/\//g, "_")
|
||||
} else {
|
||||
value = String(value).replace(/-/g, "+").replace(/_/g, "/")
|
||||
}
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
2
resources/assets/statics/public/js/jsencrypt.min.js
vendored
Normal file
2
resources/assets/statics/public/js/jsencrypt.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -16,6 +16,7 @@
|
||||
@endif
|
||||
<link rel="stylesheet" type="text/css" href="{{ asset_main('css/iview.css') }}?v={{ $version }}">
|
||||
<link rel="stylesheet" type="text/css" href="{{ asset_main('css/loading.css') }}?v={{ $version }}">
|
||||
<script src="{{ asset_main('js/jsencrypt.min.js') }}?v={{ $version }}"></script>
|
||||
<script src="{{ asset_main('js/scroll-into-view.min.js') }}?v={{ $version }}"></script>
|
||||
<script>
|
||||
window.csrfToken = {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user