Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
470772341f | ||
|
675f00b8a0 | ||
|
ae52803aec | ||
|
fb8cf78958 |
29
.github/workflows/electron.yml
vendored
29
.github/workflows/electron.yml
vendored
@ -2,34 +2,9 @@ name: Build
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
tags:
|
branches: [ build ]
|
||||||
- 'v*'
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
if: startsWith(github.event.ref, 'refs/tags/v')
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Create changelog text
|
|
||||||
id: changelog
|
|
||||||
uses: loopwerk/tag-changelog@v1
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.GH_PAT }}
|
|
||||||
exclude_types: other,chore,build
|
|
||||||
|
|
||||||
- name: Create release
|
|
||||||
uses: actions/create-release@latest
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GH_PAT }}
|
|
||||||
with:
|
|
||||||
tag_name: ${{ github.ref }}
|
|
||||||
release_name: Release ${{ github.ref }}
|
|
||||||
body: ${{ steps.changelog.outputs.changes }}
|
|
||||||
|
|
||||||
build:
|
build:
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
environment: build
|
environment: build
|
||||||
@ -43,7 +18,6 @@ jobs:
|
|||||||
build-win
|
build-win
|
||||||
]
|
]
|
||||||
|
|
||||||
if: startsWith(github.event.ref, 'refs/tags/v')
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
@ -56,6 +30,5 @@ jobs:
|
|||||||
- name: Build
|
- name: Build
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ secrets.GH_PAT }}
|
GH_TOKEN: ${{ secrets.GH_PAT }}
|
||||||
EP_PRE_RELEASE: true
|
|
||||||
run: ./cmd electron ${{ matrix.platform }}
|
run: ./cmd electron ${{ matrix.platform }}
|
||||||
|
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -19,6 +19,7 @@ Homestead.yaml
|
|||||||
npm-debug.log
|
npm-debug.log
|
||||||
yarn-error.log
|
yarn-error.log
|
||||||
test.*
|
test.*
|
||||||
|
composer.lock
|
||||||
package-lock.json
|
package-lock.json
|
||||||
laravels-timer-process.pid
|
laravels-timer-process.pid
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -1,3 +0,0 @@
|
|||||||
[submodule "resources/drawio"]
|
|
||||||
path = resources/drawio
|
|
||||||
url = https://github.com/jgraph/drawio.git
|
|
49
README.md
49
README.md
@ -5,15 +5,10 @@ English | **[中文文档](./README_CN.md)**
|
|||||||
- [Screenshot Preview](README_PREVIEW.md)
|
- [Screenshot Preview](README_PREVIEW.md)
|
||||||
- [Demo site](http://www.dootask.com/)
|
- [Demo site](http://www.dootask.com/)
|
||||||
|
|
||||||
**QQ Group**
|
|
||||||
|
|
||||||
Group No.: `546574618`
|
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
- `Docker` & `Docker Compose v2.0+` must be installed
|
> `Docker` & `Docker Compose` must be installed
|
||||||
- System: `Centos/Debian/Ubuntu/macOS`
|
|
||||||
- Hardware suggestion: 2 cores and above 2G memory
|
|
||||||
|
|
||||||
### Deployment project
|
### Deployment project
|
||||||
|
|
||||||
@ -21,14 +16,14 @@ Group No.: `546574618`
|
|||||||
# 1、Clone the repository
|
# 1、Clone the repository
|
||||||
|
|
||||||
# Clone projects on github
|
# Clone projects on github
|
||||||
git clone --depth=1 https://github.com/kuaifan/dootask.git
|
git clone https://github.com/kuaifan/dootask.git
|
||||||
# Or you can use gitee
|
# or you can use gitee
|
||||||
git clone --depth=1 https://gitee.com/aipaw/dootask.git
|
git clone https://gitee.com/aipaw/dootask.git
|
||||||
|
|
||||||
# 2、Enter directory
|
# 2、enter directory
|
||||||
cd dootask
|
cd dootask
|
||||||
|
|
||||||
# 3、Installation(Custom port installation: ./cmd install --port 2222)
|
# 3、Build project
|
||||||
./cmd install
|
./cmd install
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -42,7 +37,8 @@ cd dootask
|
|||||||
### Change port
|
### Change port
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./cmd port 2222
|
./cmd php bin/run --port=2222
|
||||||
|
./cmd up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
### Stop server
|
### Stop server
|
||||||
@ -54,28 +50,18 @@ cd dootask
|
|||||||
./cmd start
|
./cmd start
|
||||||
```
|
```
|
||||||
|
|
||||||
### Development compilation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Development mode, Mac OS only
|
|
||||||
./cmd dev
|
|
||||||
|
|
||||||
# Production projects, macOS only
|
|
||||||
./cmd prod
|
|
||||||
```
|
|
||||||
|
|
||||||
### Shortcuts for running command
|
### Shortcuts for running command
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# You can do this using the following command
|
# You can do this using the following command
|
||||||
./cmd artisan "your command" # To run a artisan command
|
./cmd artisan "your command" // To run a artisan command
|
||||||
./cmd php "your command" # To run a php command
|
./cmd php "your command" // To run a php command
|
||||||
./cmd nginx "your command" # To run a nginx command
|
./cmd nginx "your command" // To run a nginx command
|
||||||
./cmd redis "your command" # To run a redis command
|
./cmd redis "your command" // To run a redis command
|
||||||
./cmd composer "your command" # To run a composer command
|
./cmd composer "your command" // To run a composer command
|
||||||
./cmd supervisorctl "your command" # To run a supervisorctl command
|
./cmd supervisorctl "your command" // To run a supervisorctl command
|
||||||
./cmd test "your command" # To run a phpunit command
|
./cmd test "your command" // To run a phpunit command
|
||||||
./cmd mysql "your command" # To run a mysql command (backup: Backup database, recovery: Restore database)
|
./cmd mysql "your command" // To run a mysql command (backup: Backup database, recovery: Restore database)
|
||||||
```
|
```
|
||||||
|
|
||||||
### NGINX PROXY SSL
|
### NGINX PROXY SSL
|
||||||
@ -104,7 +90,6 @@ git pull
|
|||||||
./cmd uninstall
|
./cmd uninstall
|
||||||
./cmd install
|
./cmd install
|
||||||
./cmd mysql recovery
|
./cmd mysql recovery
|
||||||
./cmd artisan migrate
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Uninstall
|
## Uninstall
|
||||||
|
46
README_CN.md
46
README_CN.md
@ -5,15 +5,10 @@
|
|||||||
- [截图预览](README_PREVIEW.md)
|
- [截图预览](README_PREVIEW.md)
|
||||||
- [演示站点](http://www.dootask.com/)
|
- [演示站点](http://www.dootask.com/)
|
||||||
|
|
||||||
**QQ交流群**
|
|
||||||
|
|
||||||
- QQ群号: `546574618`
|
|
||||||
|
|
||||||
## 安装程序
|
## 安装程序
|
||||||
|
|
||||||
- 必须安装:`Docker` 和 `Docker Compose v2.0+`
|
> 必须安装 `Docker` 和 `Docker Compose`
|
||||||
- 支持环境:`Centos/Debian/Ubuntu/macOS`
|
|
||||||
- 硬件建议:2核2G以上
|
|
||||||
|
|
||||||
### 部署项目
|
### 部署项目
|
||||||
|
|
||||||
@ -21,14 +16,14 @@
|
|||||||
# 1、克隆项目到您的本地或服务器
|
# 1、克隆项目到您的本地或服务器
|
||||||
|
|
||||||
# 通过github克隆项目
|
# 通过github克隆项目
|
||||||
git clone --depth=1 https://github.com/kuaifan/dootask.git
|
git clone https://github.com/kuaifan/dootask.git
|
||||||
# 或者你也可以使用gitee
|
# 或者你也可以使用gitee
|
||||||
git clone --depth=1 https://gitee.com/aipaw/dootask.git
|
git clone https://gitee.com/aipaw/dootask.git
|
||||||
|
|
||||||
# 2、进入目录
|
# 2、进入目录
|
||||||
cd dootask
|
cd dootask
|
||||||
|
|
||||||
# 3、一键安装项目(自定义端口安装 ./cmd install --port 2222)
|
# 3、一键构建项目
|
||||||
./cmd install
|
./cmd install
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -42,7 +37,8 @@ cd dootask
|
|||||||
### 更换端口
|
### 更换端口
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./cmd port 2222
|
./cmd php bin/run --port=2222
|
||||||
|
./cmd up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
### 停止服务
|
### 停止服务
|
||||||
@ -54,29 +50,18 @@ cd dootask
|
|||||||
./cmd start
|
./cmd start
|
||||||
```
|
```
|
||||||
|
|
||||||
### 开发编译
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 开发模式,仅限macOS
|
|
||||||
./cmd dev
|
|
||||||
|
|
||||||
# 编译项目,仅限macOS
|
|
||||||
./cmd prod
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
### 运行命令的快捷方式
|
### 运行命令的快捷方式
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 你可以使用以下命令来执行
|
# 你可以使用以下命令来执行
|
||||||
./cmd artisan "your command" # 运行 artisan 命令
|
./cmd artisan "your command" // 运行 artisan 命令
|
||||||
./cmd php "your command" # 运行 php 命令
|
./cmd php "your command" // 运行 php 命令
|
||||||
./cmd nginx "your command" # 运行 nginx 命令
|
./cmd nginx "your command" // 运行 nginx 命令
|
||||||
./cmd redis "your command" # 运行 redis 命令
|
./cmd redis "your command" // 运行 redis 命令
|
||||||
./cmd composer "your command" # 运行 composer 命令
|
./cmd composer "your command" // 运行 composer 命令
|
||||||
./cmd supervisorctl "your command" # 运行 supervisorctl 命令
|
./cmd supervisorctl "your command" // 运行 supervisorctl 命令
|
||||||
./cmd test "your command" # 运行 phpunit 命令
|
./cmd test "your command" // 运行 phpunit 命令
|
||||||
./cmd mysql "your command" # 运行 mysql 命令 (backup: 备份数据库,recovery: 还原数据库)
|
./cmd mysql "your command" // 运行 mysql 命令 (backup: 备份数据库,recovery: 还原数据库)
|
||||||
```
|
```
|
||||||
|
|
||||||
### NGINX 代理 SSL
|
### NGINX 代理 SSL
|
||||||
@ -105,7 +90,6 @@ git pull
|
|||||||
./cmd uninstall
|
./cmd uninstall
|
||||||
./cmd install
|
./cmd install
|
||||||
./cmd mysql recovery
|
./cmd mysql recovery
|
||||||
./cmd artisan migrate
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 卸载项目
|
## 卸载项目
|
||||||
|
@ -10,7 +10,7 @@ if (!function_exists('asset_main')) {
|
|||||||
if (!function_exists('seeders_at')) {
|
if (!function_exists('seeders_at')) {
|
||||||
function seeders_at($data)
|
function seeders_at($data)
|
||||||
{
|
{
|
||||||
$diff = time() - strtotime("2021-07-02");
|
$diff = time() - strtotime("2021-07-01");
|
||||||
$time = strtotime($data) + $diff;
|
$time = strtotime($data) + $diff;
|
||||||
return date("Y-m-d H:i:s", $time);
|
return date("Y-m-d H:i:s", $time);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Api;
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
use App\Models\File;
|
|
||||||
use App\Models\ProjectTask;
|
use App\Models\ProjectTask;
|
||||||
use App\Models\ProjectTaskFile;
|
use App\Models\ProjectTaskFile;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
@ -11,9 +10,7 @@ use App\Models\WebSocketDialogMsg;
|
|||||||
use App\Models\WebSocketDialogMsgRead;
|
use App\Models\WebSocketDialogMsgRead;
|
||||||
use App\Models\WebSocketDialogUser;
|
use App\Models\WebSocketDialogUser;
|
||||||
use App\Module\Base;
|
use App\Module\Base;
|
||||||
use Carbon\Carbon;
|
|
||||||
use Request;
|
use Request;
|
||||||
use Response;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @apiDefine dialog
|
* @apiDefine dialog
|
||||||
@ -23,28 +20,18 @@ use Response;
|
|||||||
class DialogController extends AbstractController
|
class DialogController extends AbstractController
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @api {get} api/dialog/lists 01. 对话列表
|
* 对话列表
|
||||||
*
|
|
||||||
* @apiDescription 需要token身份
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup dialog
|
|
||||||
* @apiName lists
|
|
||||||
*
|
*
|
||||||
* @apiParam {Number} [page] 当前页,默认:1
|
* @apiParam {Number} [page] 当前页,默认:1
|
||||||
* @apiParam {Number} [pagesize] 每页显示数量,默认:100,最大:200
|
* @apiParam {Number} [pagesize] 每页显示数量,默认:100,最大:200
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
*/
|
||||||
public function lists()
|
public function lists()
|
||||||
{
|
{
|
||||||
$user = User::auth();
|
$user = User::auth();
|
||||||
//
|
//
|
||||||
$list = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at'])
|
$list = WebSocketDialog::select(['web_socket_dialogs.*'])
|
||||||
->join('web_socket_dialog_users as u', 'web_socket_dialogs.id', '=', 'u.dialog_id')
|
->join('web_socket_dialog_users as u', 'web_socket_dialogs.id', '=', 'u.dialog_id')
|
||||||
->where('u.userid', $user->userid)
|
->where('u.userid', $user->userid)
|
||||||
->orderByDesc('u.top_at')
|
|
||||||
->orderByDesc('web_socket_dialogs.last_at')
|
->orderByDesc('web_socket_dialogs.last_at')
|
||||||
->paginate(Base::getPaginate(200, 100));
|
->paginate(Base::getPaginate(200, 100));
|
||||||
$list->transform(function (WebSocketDialog $item) use ($user) {
|
$list->transform(function (WebSocketDialog $item) use ($user) {
|
||||||
@ -55,18 +42,9 @@ class DialogController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/dialog/one 02. 获取单个会话信息
|
* 获取单个会话信息
|
||||||
*
|
|
||||||
* @apiDescription 需要token身份
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup dialog
|
|
||||||
* @apiName one
|
|
||||||
*
|
*
|
||||||
* @apiParam {Number} dialog_id 对话ID
|
* @apiParam {Number} dialog_id 对话ID
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
*/
|
||||||
public function one()
|
public function one()
|
||||||
{
|
{
|
||||||
@ -87,18 +65,9 @@ class DialogController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/dialog/msg/user 03. 打开会话
|
* 打开会话
|
||||||
*
|
|
||||||
* @apiDescription 需要token身份
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup dialog
|
|
||||||
* @apiName open__user
|
|
||||||
*
|
*
|
||||||
* @apiParam {Number} userid 对话会员ID
|
* @apiParam {Number} userid 对话会员ID
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
*/
|
||||||
public function open__user()
|
public function open__user()
|
||||||
{
|
{
|
||||||
@ -121,21 +90,12 @@ class DialogController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/dialog/msg/lists 04. 获取消息列表
|
* 获取消息列表
|
||||||
*
|
|
||||||
* @apiDescription 需要token身份
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup dialog
|
|
||||||
* @apiName msg__lists
|
|
||||||
*
|
*
|
||||||
* @apiParam {Number} dialog_id 对话ID
|
* @apiParam {Number} dialog_id 对话ID
|
||||||
*
|
*
|
||||||
* @apiParam {Number} [page] 当前页,默认:1
|
* @apiParam {Number} [page] 当前页,默认:1
|
||||||
* @apiParam {Number} [pagesize] 每页显示数量,默认:50,最大:100
|
* @apiParam {Number} [pagesize] 每页显示数量,默认:50,最大:100
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
*/
|
||||||
public function msg__lists()
|
public function msg__lists()
|
||||||
{
|
{
|
||||||
@ -164,51 +124,24 @@ class DialogController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/dialog/msg/unread 05. 获取未读消息数量
|
* 未读消息
|
||||||
*
|
|
||||||
* @apiDescription 需要token身份
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup dialog
|
|
||||||
* @apiName msg__unread
|
|
||||||
*
|
|
||||||
* @apiParam {Number} [dialog_id] 对话ID,留空获取总未读消息数量
|
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
*/
|
||||||
public function msg__unread()
|
public function msg__unread()
|
||||||
{
|
{
|
||||||
$dialog_id = intval(Request::input('dialog_id'));
|
$unread = WebSocketDialogMsgRead::whereUserid(User::userid())->whereReadAt(null)->count();
|
||||||
//
|
|
||||||
$builder = WebSocketDialogMsgRead::whereUserid(User::userid())->whereReadAt(null);
|
|
||||||
if ($dialog_id > 0) {
|
|
||||||
$builder->whereDialogId($dialog_id);
|
|
||||||
}
|
|
||||||
$unread = $builder->count();
|
|
||||||
return Base::retSuccess('success', [
|
return Base::retSuccess('success', [
|
||||||
'unread' => $unread,
|
'unread' => $unread,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {post} api/dialog/msg/sendtext 06. 发送消息
|
* 发送消息
|
||||||
*
|
|
||||||
* @apiDescription 需要token身份
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup dialog
|
|
||||||
* @apiName msg__sendtext
|
|
||||||
*
|
*
|
||||||
* @apiParam {Number} dialog_id 对话ID
|
* @apiParam {Number} dialog_id 对话ID
|
||||||
* @apiParam {String} text 消息内容
|
* @apiParam {String} text 消息内容
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
*/
|
||||||
public function msg__sendtext()
|
public function msg__sendtext()
|
||||||
{
|
{
|
||||||
Base::checkClientVersion('0.8.1');
|
|
||||||
$user = User::auth();
|
$user = User::auth();
|
||||||
//
|
//
|
||||||
$chat_nickname = Base::settingFind('system', 'chat_nickname');
|
$chat_nickname = Base::settingFind('system', 'chat_nickname');
|
||||||
@ -219,8 +152,8 @@ class DialogController extends AbstractController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
$dialog_id = Base::getPostInt('dialog_id');
|
$dialog_id = intval(Request::input('dialog_id'));
|
||||||
$text = trim(Base::getPostValue('text'));
|
$text = trim(Request::input('text'));
|
||||||
//
|
//
|
||||||
if (mb_strlen($text) < 1) {
|
if (mb_strlen($text) < 1) {
|
||||||
return Base::retError('消息内容不能为空');
|
return Base::retError('消息内容不能为空');
|
||||||
@ -230,39 +163,20 @@ class DialogController extends AbstractController
|
|||||||
//
|
//
|
||||||
WebSocketDialog::checkDialog($dialog_id);
|
WebSocketDialog::checkDialog($dialog_id);
|
||||||
//
|
//
|
||||||
if (mb_strlen($text) > 2000) {
|
$msg = [
|
||||||
$array = mb_str_split($text, 2000);
|
'text' => $text
|
||||||
} else {
|
];
|
||||||
$array = [$text];
|
|
||||||
}
|
|
||||||
//
|
//
|
||||||
$list = [];
|
return WebSocketDialogMsg::sendMsg($dialog_id, 'text', $msg, $user->userid);
|
||||||
foreach ($array as $item) {
|
|
||||||
$res = WebSocketDialogMsg::sendMsg($dialog_id, 'text', ['text' => $item], $user->userid);
|
|
||||||
if (Base::isSuccess($res)) {
|
|
||||||
$list[] = $res['data'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//
|
|
||||||
return Base::retSuccess('发送成功', $list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {post} api/dialog/msg/sendfile 07. 文件上传
|
* {post}文件上传
|
||||||
*
|
|
||||||
* @apiDescription 需要token身份
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup dialog
|
|
||||||
* @apiName msg__sendfile
|
|
||||||
*
|
*
|
||||||
* @apiParam {Number} dialog_id 对话ID
|
* @apiParam {Number} dialog_id 对话ID
|
||||||
* @apiParam {String} [filename] post-文件名称
|
* @apiParam {String} [filename] post-文件名称
|
||||||
* @apiParam {String} [image64] post-base64图片(二选一)
|
* @apiParam {String} [image64] post-base64图片(二选一)
|
||||||
* @apiParam {File} [files] post-文件对象(二选一)
|
* @apiParam {File} [files] post-文件对象(二选一)
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
*/
|
||||||
public function msg__sendfile()
|
public function msg__sendfile()
|
||||||
{
|
{
|
||||||
@ -272,7 +186,7 @@ class DialogController extends AbstractController
|
|||||||
//
|
//
|
||||||
$dialog = WebSocketDialog::checkDialog($dialog_id);
|
$dialog = WebSocketDialog::checkDialog($dialog_id);
|
||||||
//
|
//
|
||||||
$path = "uploads/chat/" . date("Ym") . "/" . $dialog_id . "/";
|
$path = "uploads/chat/" . $user->userid . "/";
|
||||||
$image64 = Base::getPostValue('image64');
|
$image64 = Base::getPostValue('image64');
|
||||||
$fileName = Base::getPostValue('filename');
|
$fileName = Base::getPostValue('filename');
|
||||||
if ($image64) {
|
if ($image64) {
|
||||||
@ -284,7 +198,7 @@ class DialogController extends AbstractController
|
|||||||
} else {
|
} else {
|
||||||
$data = Base::upload([
|
$data = Base::upload([
|
||||||
"file" => Request::file('files'),
|
"file" => Request::file('files'),
|
||||||
"type" => 'more',
|
"type" => 'file',
|
||||||
"path" => $path,
|
"path" => $path,
|
||||||
"fileName" => $fileName,
|
"fileName" => $fileName,
|
||||||
]);
|
]);
|
||||||
@ -327,18 +241,9 @@ class DialogController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/dialog/msg/readlist 08. 获取消息阅读情况
|
* 获取消息阅读情况
|
||||||
*
|
|
||||||
* @apiDescription 需要token身份
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup dialog
|
|
||||||
* @apiName msg__readlist
|
|
||||||
*
|
*
|
||||||
* @apiParam {Number} msg_id 消息ID(需要是消息的发送人)
|
* @apiParam {Number} msg_id 消息ID(需要是消息的发送人)
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
*/
|
||||||
public function msg__readlist()
|
public function msg__readlist()
|
||||||
{
|
{
|
||||||
@ -354,137 +259,4 @@ class DialogController extends AbstractController
|
|||||||
$read = WebSocketDialogMsgRead::whereMsgId($msg_id)->get();
|
$read = WebSocketDialogMsgRead::whereMsgId($msg_id)->get();
|
||||||
return Base::retSuccess('success', $read ?: []);
|
return Base::retSuccess('success', $read ?: []);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @api {get} api/dialog/msg/detail 09. 消息详情
|
|
||||||
*
|
|
||||||
* @apiDescription 需要token身份
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup dialog
|
|
||||||
* @apiName msg__detail
|
|
||||||
*
|
|
||||||
* @apiParam {Number} msg_id 消息ID
|
|
||||||
* @apiParam {String} only_update_at 仅获取update_at字段
|
|
||||||
* - no (默认)
|
|
||||||
* - yes
|
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
|
||||||
public function msg__detail()
|
|
||||||
{
|
|
||||||
User::auth();
|
|
||||||
//
|
|
||||||
$msg_id = intval(Request::input('msg_id'));
|
|
||||||
$only_update_at = Request::input('only_update_at', 'no');
|
|
||||||
//
|
|
||||||
$dialogMsg = WebSocketDialogMsg::whereId($msg_id)->first();
|
|
||||||
if (empty($dialogMsg)) {
|
|
||||||
return Base::retError("文件不存在");
|
|
||||||
}
|
|
||||||
//
|
|
||||||
if ($only_update_at == 'yes') {
|
|
||||||
return Base::retSuccess('success', [
|
|
||||||
'id' => $dialogMsg->id,
|
|
||||||
'update_at' => Carbon::parse($dialogMsg->updated_at)->toDateTimeString()
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
//
|
|
||||||
$data = $dialogMsg->toArray();
|
|
||||||
//
|
|
||||||
if ($data['type'] == 'file') {
|
|
||||||
$msg = Base::json2array($dialogMsg->getRawOriginal('msg'));
|
|
||||||
$msg = File::formatFileData($msg);
|
|
||||||
$data['content'] = $msg['content'];
|
|
||||||
$data['file_mode'] = $msg['file_mode'];
|
|
||||||
}
|
|
||||||
//
|
|
||||||
return Base::retSuccess('success', $data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @api {get} api/dialog/msg/download 10. 文件下载
|
|
||||||
*
|
|
||||||
* @apiDescription 需要token身份
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup dialog
|
|
||||||
* @apiName msg__download
|
|
||||||
*
|
|
||||||
* @apiParam {Number} msg_id 消息ID
|
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
|
||||||
public function msg__download()
|
|
||||||
{
|
|
||||||
User::auth();
|
|
||||||
//
|
|
||||||
$msg_id = intval(Request::input('msg_id'));
|
|
||||||
//
|
|
||||||
$msg = WebSocketDialogMsg::whereId($msg_id)->first();
|
|
||||||
if (empty($msg)) {
|
|
||||||
abort(403, "This file not exist.");
|
|
||||||
}
|
|
||||||
if ($msg->type != 'file') {
|
|
||||||
abort(403, "This file not support download.");
|
|
||||||
}
|
|
||||||
$array = Base::json2array($msg->getRawOriginal('msg'));
|
|
||||||
//
|
|
||||||
return Response::download(public_path($array['path']), $array['name']);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @api {get} api/dialog/msg/withdraw 11. 聊天消息撤回
|
|
||||||
*
|
|
||||||
* @apiDescription 消息撤回限制24小时内,需要token身份
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup dialog
|
|
||||||
* @apiName msg__withdraw
|
|
||||||
*
|
|
||||||
* @apiParam {Number} msg_id 消息ID
|
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
|
||||||
public function msg__withdraw()
|
|
||||||
{
|
|
||||||
$user = User::auth();
|
|
||||||
$msg_id = intval(Request::input("msg_id"));
|
|
||||||
$msg = WebSocketDialogMsg::whereId($msg_id)->whereUserid($user->userid)->first();
|
|
||||||
if (empty($msg)) {
|
|
||||||
return Base::retError("消息不存在或已被删除");
|
|
||||||
}
|
|
||||||
$msg->deleteMsg();
|
|
||||||
return Base::retSuccess("success");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @api {get} api/dialog/top 12. 会话置顶
|
|
||||||
*
|
|
||||||
* @apiDescription 需要token身份
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup dialog
|
|
||||||
* @apiName top
|
|
||||||
*
|
|
||||||
* @apiParam {Number} dialog_id 会话ID
|
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
|
||||||
public function top()
|
|
||||||
{
|
|
||||||
$user = User::auth();
|
|
||||||
$dialogId = intval(Request::input('dialog_id'));
|
|
||||||
$dialogUser = WebSocketDialogUser::whereUserid($user->userid)->whereDialogId($dialogId)->first();
|
|
||||||
if (!$dialogUser) {
|
|
||||||
return Base::retError("会话不存在");
|
|
||||||
}
|
|
||||||
$dialogUser->top_at = $dialogUser->top_at ? null : Carbon::now();
|
|
||||||
$dialogUser->save();
|
|
||||||
return Base::retSuccess("success", $dialogId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -2,18 +2,18 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Api;
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
use App\Exceptions\ApiException;
|
|
||||||
use App\Models\AbstractModel;
|
use App\Models\AbstractModel;
|
||||||
use App\Models\File;
|
use App\Models\File;
|
||||||
use App\Models\FileContent;
|
use App\Models\FileContent;
|
||||||
use App\Models\FileLink;
|
|
||||||
use App\Models\FileUser;
|
use App\Models\FileUser;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use App\Models\WebSocket;
|
||||||
use App\Module\Base;
|
use App\Module\Base;
|
||||||
use App\Module\Ihttp;
|
use App\Module\Ihttp;
|
||||||
use Carbon\Carbon;
|
use Arr;
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
use Request;
|
use Request;
|
||||||
|
use Response;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @apiDefine file
|
* @apiDefine file
|
||||||
@ -23,18 +23,9 @@ use Request;
|
|||||||
class FileController extends AbstractController
|
class FileController extends AbstractController
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @api {get} api/file/lists 01. 获取文件列表
|
* 获取文件列表
|
||||||
*
|
|
||||||
* @apiDescription 需要token身份
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup file
|
|
||||||
* @apiName lists
|
|
||||||
*
|
*
|
||||||
* @apiParam {Number} [pid] 父级ID
|
* @apiParam {Number} [pid] 父级ID
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
*/
|
||||||
public function lists()
|
public function lists()
|
||||||
{
|
{
|
||||||
@ -43,18 +34,18 @@ class FileController extends AbstractController
|
|||||||
$data = Request::all();
|
$data = Request::all();
|
||||||
$pid = intval($data['pid']);
|
$pid = intval($data['pid']);
|
||||||
//
|
//
|
||||||
$permission = 1000;
|
|
||||||
if ($pid > 0) {
|
if ($pid > 0) {
|
||||||
File::permissionFind($pid, 0, $permission);
|
$file = File::find($pid);
|
||||||
|
if (empty($file)) {
|
||||||
|
return Base::retError('Not exist');
|
||||||
|
}
|
||||||
|
$file->exceAllow($user->userid);
|
||||||
|
//
|
||||||
$builder = File::wherePid($pid);
|
$builder = File::wherePid($pid);
|
||||||
} else {
|
} else {
|
||||||
$builder = File::whereUserid($user->userid);
|
$builder = File::whereUserid($user->userid);
|
||||||
}
|
}
|
||||||
//
|
|
||||||
$array = $builder->take(500)->get()->toArray();
|
$array = $builder->take(500)->get()->toArray();
|
||||||
foreach ($array as &$item) {
|
|
||||||
$item['permission'] = $permission;
|
|
||||||
}
|
|
||||||
//
|
//
|
||||||
if ($pid > 0) {
|
if ($pid > 0) {
|
||||||
// 遍历获取父级
|
// 遍历获取父级
|
||||||
@ -65,23 +56,18 @@ class FileController extends AbstractController
|
|||||||
}
|
}
|
||||||
$pid = $file->pid;
|
$pid = $file->pid;
|
||||||
$temp = $file->toArray();
|
$temp = $file->toArray();
|
||||||
$temp['permission'] = $file->getPermission($user->userid);
|
$temp['allow'] = $file->chackAllow($user->userid);
|
||||||
$array[] = $temp;
|
$array[] = $temp;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 获取共享相关
|
// 获取共享相关
|
||||||
DB::statement("SET SQL_MODE=''");
|
$list = File::where('userid', '!=', $user->userid)->where(function ($query) use ($user) {
|
||||||
$pre = DB::connection()->getTablePrefix();
|
$query->where('share', 1)->orWhere(function ($q2) use ($user) {
|
||||||
$list = File::select(["files.*", DB::raw("MAX({$pre}file_users.permission) as permission")])
|
$q2->where('share', 2)->whereIn('id', function ($q3) use ($user) {
|
||||||
->join('file_users', 'files.id', '=', 'file_users.file_id')
|
$q3->select('file_id')->from('file_users')->where('userid', $user->userid);
|
||||||
->where('files.userid', '!=', $user->userid)
|
});
|
||||||
->where(function ($query) use ($user) {
|
});
|
||||||
$query->where('file_users.userid', 0);
|
})->get();
|
||||||
$query->orWhere('file_users.userid', $user->userid);
|
|
||||||
})
|
|
||||||
->groupBy('files.id')
|
|
||||||
->take(100)
|
|
||||||
->get();
|
|
||||||
if ($list->isNotEmpty()) {
|
if ($list->isNotEmpty()) {
|
||||||
foreach ($list as $file) {
|
foreach ($list as $file) {
|
||||||
$temp = $file->toArray();
|
$temp = $file->toArray();
|
||||||
@ -94,57 +80,9 @@ class FileController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/file/one 02. 获取单条数据
|
* 搜索文件列表
|
||||||
*
|
|
||||||
* @apiDescription 需要token身份
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup file
|
|
||||||
* @apiName one
|
|
||||||
*
|
|
||||||
* @apiParam {Number|String} id
|
|
||||||
* - Number 文件ID(需要登录)
|
|
||||||
* - String 链接码(不需要登录,用于预览)
|
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
|
||||||
public function one()
|
|
||||||
{
|
|
||||||
$id = Request::input('id');
|
|
||||||
//
|
|
||||||
$permission = 0;
|
|
||||||
if (Base::isNumber($id)) {
|
|
||||||
User::auth();
|
|
||||||
$file = File::permissionFind(intval($id), 0, $permission);
|
|
||||||
} elseif ($id) {
|
|
||||||
$fileLink = FileLink::whereCode($id)->first();
|
|
||||||
$file = $fileLink?->file;
|
|
||||||
if (empty($file)) {
|
|
||||||
return Base::retError('链接不存在');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return Base::retError('参数错误');
|
|
||||||
}
|
|
||||||
//
|
|
||||||
$array = $file->toArray();
|
|
||||||
$array['permission'] = $permission;
|
|
||||||
return Base::retSuccess('success', $array);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @api {get} api/file/search 03. 搜索文件列表
|
|
||||||
*
|
|
||||||
* @apiDescription 需要token身份
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup file
|
|
||||||
* @apiName search
|
|
||||||
*
|
*
|
||||||
* @apiParam {String} [key] 关键词
|
* @apiParam {String} [key] 关键词
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
*/
|
||||||
public function search()
|
public function search()
|
||||||
{
|
{
|
||||||
@ -162,21 +100,12 @@ class FileController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/file/add 04. 添加、修改文件(夹)
|
* 添加、修改文件(夹)
|
||||||
*
|
|
||||||
* @apiDescription 需要token身份
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup file
|
|
||||||
* @apiName add
|
|
||||||
*
|
*
|
||||||
* @apiParam {String} name 项目名称
|
* @apiParam {String} name 项目名称
|
||||||
* @apiParam {String} type 文件类型
|
* @apiParam {String} type 文件类型
|
||||||
* @apiParam {Number} [id] 文件ID(赋值修改文件名称)
|
* @apiParam {Number} [id] 文件ID(赋值修改文件名称)
|
||||||
* @apiParam {Number} [pid] 父级ID
|
* @apiParam {Number} [pid] 父级ID
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
*/
|
||||||
public function add()
|
public function add()
|
||||||
{
|
{
|
||||||
@ -194,7 +123,7 @@ class FileController extends AbstractController
|
|||||||
//
|
//
|
||||||
if ($id > 0) {
|
if ($id > 0) {
|
||||||
// 修改
|
// 修改
|
||||||
$file = File::permissionFind($id, 1);
|
$file = File::allowFind($id);
|
||||||
//
|
//
|
||||||
$file->name = $name;
|
$file->name = $name;
|
||||||
$file->save();
|
$file->save();
|
||||||
@ -206,37 +135,29 @@ class FileController extends AbstractController
|
|||||||
'folder',
|
'folder',
|
||||||
'document',
|
'document',
|
||||||
'mind',
|
'mind',
|
||||||
'drawio',
|
'sheet',
|
||||||
|
'flow',
|
||||||
'word',
|
'word',
|
||||||
'excel',
|
'excel',
|
||||||
'ppt',
|
'ppt',
|
||||||
])) {
|
])) {
|
||||||
return Base::retError('类型错误');
|
return Base::retError('类型错误');
|
||||||
}
|
}
|
||||||
$ext = str_replace([
|
$ext = '';
|
||||||
'folder',
|
if (in_array($type, [
|
||||||
'document',
|
|
||||||
'mind',
|
|
||||||
'drawio',
|
|
||||||
'word',
|
'word',
|
||||||
'excel',
|
'excel',
|
||||||
'ppt',
|
'ppt',
|
||||||
], [
|
])) {
|
||||||
'',
|
$ext = str_replace(['word', 'excel', 'ppt'], ['docx', 'xlsx', 'pptx'], $type);
|
||||||
'md',
|
}
|
||||||
'mind',
|
|
||||||
'drawio',
|
|
||||||
'docx',
|
|
||||||
'xlsx',
|
|
||||||
'pptx',
|
|
||||||
], $type);
|
|
||||||
//
|
//
|
||||||
$userid = $user->userid;
|
$userid = $user->userid;
|
||||||
if ($pid > 0) {
|
if ($pid > 0) {
|
||||||
if (File::wherePid($pid)->count() >= 300) {
|
if (File::wherePid($pid)->count() >= 300) {
|
||||||
return Base::retError('每个文件夹里最多只能创建300个文件或文件夹');
|
return Base::retError('每个文件夹里最多只能创建300个文件或文件夹');
|
||||||
}
|
}
|
||||||
$row = File::permissionFind($pid, 1);
|
$row = File::allowFind($pid, '主文件不存在');
|
||||||
$userid = $row->userid;
|
$userid = $row->userid;
|
||||||
} else {
|
} else {
|
||||||
if (File::whereUserid($user->userid)->wherePid(0)->count() >= 300) {
|
if (File::whereUserid($user->userid)->wherePid(0)->count() >= 300) {
|
||||||
@ -261,18 +182,9 @@ class FileController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/file/copy 05. 复制文件(夹)
|
* 复制文件(夹)
|
||||||
*
|
|
||||||
* @apiDescription 需要token身份
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup file
|
|
||||||
* @apiName copy
|
|
||||||
*
|
*
|
||||||
* @apiParam {Number} id 文件ID
|
* @apiParam {Number} id 文件ID
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
*/
|
||||||
public function copy()
|
public function copy()
|
||||||
{
|
{
|
||||||
@ -280,7 +192,7 @@ class FileController extends AbstractController
|
|||||||
//
|
//
|
||||||
$id = intval(Request::input('id'));
|
$id = intval(Request::input('id'));
|
||||||
//
|
//
|
||||||
$row = File::permissionFind($id);
|
$row = File::allowFind($id);
|
||||||
//
|
//
|
||||||
$userid = $user->userid;
|
$userid = $user->userid;
|
||||||
if ($row->pid > 0) {
|
if ($row->pid > 0) {
|
||||||
@ -302,199 +214,99 @@ class FileController extends AbstractController
|
|||||||
'userid' => $userid,
|
'userid' => $userid,
|
||||||
'created_id' => $user->userid,
|
'created_id' => $user->userid,
|
||||||
]);
|
]);
|
||||||
$data = AbstractModel::transaction(function() use ($file) {
|
$file->save();
|
||||||
$content = FileContent::select(['content', 'text', 'size'])->whereFid($file->cid)->orderByDesc('id')->first();
|
|
||||||
$file->size = $content?->size ?: 0;
|
|
||||||
$file->save();
|
|
||||||
if ($content) {
|
|
||||||
$content = $content->toArray();
|
|
||||||
$content['fid'] = $file->id;
|
|
||||||
$content['userid'] = $file->userid;
|
|
||||||
FileContent::createInstance($content)->save();
|
|
||||||
}
|
|
||||||
return File::find($file->id);
|
|
||||||
});
|
|
||||||
//
|
//
|
||||||
|
$data = File::find($file->id);
|
||||||
$data->pushMsg('add', $data);
|
$data->pushMsg('add', $data);
|
||||||
return Base::retSuccess('复制成功', $data);
|
return Base::retSuccess('复制成功', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/file/move 06. 移动文件(夹)
|
* 移动文件(夹)
|
||||||
*
|
*
|
||||||
* @apiDescription 需要token身份
|
* @apiParam {Number} id 文件ID
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup file
|
|
||||||
* @apiName move
|
|
||||||
*
|
|
||||||
* @apiParam {Numbers} ids 文件ID(格式:[id1, id2])
|
|
||||||
* @apiParam {Number} pid 移动到的文件夹ID
|
* @apiParam {Number} pid 移动到的文件夹ID
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
*/
|
||||||
public function move()
|
public function move()
|
||||||
{
|
{
|
||||||
$user = User::auth();
|
$user = User::auth();
|
||||||
//
|
//
|
||||||
$ids = Request::input('ids');
|
$id = intval(Request::input('id'));
|
||||||
$pid = intval(Request::input('pid'));
|
$pid = intval(Request::input('pid'));
|
||||||
//
|
//
|
||||||
if (!is_array($ids) || empty($ids)) {
|
$file = File::whereId($id)->first();
|
||||||
return Base::retError('请选择移动的文件或文件夹');
|
if (empty($file)) {
|
||||||
|
return Base::retError('文件不存在或已被删除');
|
||||||
}
|
}
|
||||||
if (count($ids) > 100) {
|
if ($file->userid != $user->userid) {
|
||||||
return Base::retError('一次最多只能移动100个文件或文件夹');
|
return Base::retError('仅限所有者操作');
|
||||||
}
|
|
||||||
if ($pid > 0) {
|
|
||||||
File::permissionFind($pid, 1);
|
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
$files = [];
|
if ($pid > 0) {
|
||||||
AbstractModel::transaction(function() use ($pid, $ids, &$files) {
|
if (!File::whereUserid($user->userid)->whereId($pid)->exists()) {
|
||||||
foreach ($ids as $id) {
|
return Base::retError('参数错误');
|
||||||
$file = File::permissionFind($id, 1000);
|
}
|
||||||
//
|
$arr = [];
|
||||||
if ($pid > 0) {
|
$tid = $pid;
|
||||||
$arr = [];
|
while ($tid > 0) {
|
||||||
$tid = $pid;
|
$arr[] = $tid;
|
||||||
while ($tid > 0) {
|
$tid = intval(File::whereId($tid)->value('pid'));
|
||||||
$arr[] = $tid;
|
}
|
||||||
$tid = intval(File::whereId($tid)->value('pid'));
|
if (in_array($id, $arr)) {
|
||||||
}
|
return Base::retError('位置错误');
|
||||||
if (in_array($id, $arr)) {
|
|
||||||
throw new ApiException('移动位置错误');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//
|
|
||||||
$file->pid = $pid;
|
|
||||||
$file->save();
|
|
||||||
$files[] = $file;
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
foreach ($files as $file) {
|
|
||||||
$file->pushMsg('update', $file);
|
|
||||||
}
|
}
|
||||||
return Base::retSuccess('操作成功', $files);
|
//
|
||||||
|
$file->pid = $pid;
|
||||||
|
$file->save();
|
||||||
|
$file->pushMsg('update', $file);
|
||||||
|
return Base::retSuccess('操作成功', $file);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/file/remove 07. 删除文件(夹)
|
* 删除文件(夹)
|
||||||
*
|
*
|
||||||
* @apiDescription 需要token身份
|
* @apiParam {Number} id 文件ID
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup file
|
|
||||||
* @apiName remove
|
|
||||||
*
|
|
||||||
* @apiParam {Numbers} ids 文件ID(格式:[id1, id2])
|
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
*/
|
||||||
public function remove()
|
public function remove()
|
||||||
{
|
{
|
||||||
User::auth();
|
$id = intval(Request::input('id'));
|
||||||
//
|
//
|
||||||
$ids = Request::input('ids');
|
$file = File::allowFind($id);
|
||||||
//
|
$file->deleteFile();
|
||||||
if (!is_array($ids) || empty($ids)) {
|
return Base::retSuccess('删除成功', $file);
|
||||||
return Base::retError('请选择删除的文件或文件夹');
|
|
||||||
}
|
|
||||||
if (count($ids) > 100) {
|
|
||||||
return Base::retError('一次最多只能删除100个文件或文件夹');
|
|
||||||
}
|
|
||||||
//
|
|
||||||
$files = [];
|
|
||||||
AbstractModel::transaction(function() use ($ids, &$files) {
|
|
||||||
foreach ($ids as $id) {
|
|
||||||
$file = File::permissionFind($id, 1000);
|
|
||||||
$file->deleteFile();
|
|
||||||
$files[] = $file;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
//
|
|
||||||
return Base::retSuccess('删除成功', $files);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/file/content 08. 获取文件内容
|
* 获取文件内容
|
||||||
*
|
*
|
||||||
* @apiDescription 需要token身份
|
* @apiParam {Number} id 文件ID
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup file
|
|
||||||
* @apiName content
|
|
||||||
*
|
|
||||||
* @apiParam {Number|String} id
|
|
||||||
* - Number: 文件ID(需要登录)
|
|
||||||
* - String: 链接码(不需要登录,用于预览)
|
|
||||||
* @apiParam {String} only_update_at 仅获取update_at字段
|
|
||||||
* - no (默认)
|
|
||||||
* - yes
|
|
||||||
* @apiParam {String} down 直接下载
|
|
||||||
* - no: 浏览(默认)
|
|
||||||
* - yes: 下载(office文件直接下载)
|
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
*/
|
||||||
public function content()
|
public function content()
|
||||||
{
|
{
|
||||||
$id = Request::input('id');
|
$id = intval(Request::input('id'));
|
||||||
$down = Request::input('down', 'no');
|
|
||||||
$only_update_at = Request::input('only_update_at', 'no');
|
|
||||||
//
|
//
|
||||||
if (Base::isNumber($id)) {
|
$file = File::allowFind($id);
|
||||||
User::auth();
|
|
||||||
$file = File::permissionFind(intval($id));
|
|
||||||
} elseif ($id) {
|
|
||||||
$fileLink = FileLink::whereCode($id)->first();
|
|
||||||
$file = $fileLink?->file;
|
|
||||||
if (empty($file)) {
|
|
||||||
return Base::retError('链接不存在');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return Base::retError('参数错误');
|
|
||||||
}
|
|
||||||
//
|
|
||||||
if ($only_update_at == 'yes') {
|
|
||||||
return Base::retSuccess('success', [
|
|
||||||
'id' => $file->id,
|
|
||||||
'update_at' => Carbon::parse($file->updated_at)->toDateTimeString()
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
//
|
//
|
||||||
$content = FileContent::whereFid($file->id)->orderByDesc('id')->first();
|
$content = FileContent::whereFid($file->id)->orderByDesc('id')->first();
|
||||||
return FileContent::formatContent($file, $content?->content, $down == 'yes');
|
return FileContent::formatContent($file->type, $content ? $content->content : []);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/file/content/save 09. 保存文件内容
|
* 保存文件内容
|
||||||
*
|
*
|
||||||
* @apiDescription 需要token身份
|
* @apiParam {Number} id 文件ID
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup file
|
|
||||||
* @apiName content__save
|
|
||||||
*
|
|
||||||
* @apiParam {Number} id 文件ID
|
|
||||||
* @apiParam {Object} [D] Request Payload 提交
|
* @apiParam {Object} [D] Request Payload 提交
|
||||||
* - content: 内容
|
* - content: 内容
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
*/
|
||||||
public function content__save()
|
public function content__save()
|
||||||
{
|
{
|
||||||
Base::checkClientVersion('0.9.13');
|
|
||||||
$user = User::auth();
|
$user = User::auth();
|
||||||
//
|
//
|
||||||
$id = Base::getPostInt('id');
|
$id = Base::getPostInt('id');
|
||||||
$content = Base::getPostValue('content');
|
$content = Base::getPostValue('content');
|
||||||
//
|
//
|
||||||
$file = File::permissionFind($id, 1);
|
$file = File::allowFind($id);
|
||||||
//
|
//
|
||||||
$text = '';
|
$text = '';
|
||||||
if ($file->type == 'document') {
|
if ($file->type == 'document') {
|
||||||
@ -502,11 +314,12 @@ class FileController extends AbstractController
|
|||||||
$isRep = false;
|
$isRep = false;
|
||||||
preg_match_all("/<img\s*src=\"data:image\/(png|jpg|jpeg);base64,(.*?)\"/s", $data['content'], $matchs);
|
preg_match_all("/<img\s*src=\"data:image\/(png|jpg|jpeg);base64,(.*?)\"/s", $data['content'], $matchs);
|
||||||
foreach ($matchs[2] as $key => $text) {
|
foreach ($matchs[2] as $key => $text) {
|
||||||
$tmpPath = "uploads/file/document/" . date("Ym") . "/" . $id . "/attached/";
|
$p = "uploads/files/document/" . $id . "/";
|
||||||
Base::makeDir(public_path($tmpPath));
|
Base::makeDir(public_path($p));
|
||||||
$tmpPath .= md5($text) . "." . $matchs[1][$key];
|
$p.= md5($text) . "." . $matchs[1][$key];
|
||||||
if (file_put_contents(public_path($tmpPath), base64_decode($text))) {
|
$r = file_put_contents(public_path($p), base64_decode($text));
|
||||||
$data['content'] = str_replace($matchs[0][$key], '<img src="' . Base::fillUrl($tmpPath) . '"', $data['content']);
|
if ($r) {
|
||||||
|
$data['content'] = str_replace($matchs[0][$key], '<img src="' . Base::fillUrl($p) . '"', $data['content']);
|
||||||
$isRep = true;
|
$isRep = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -516,41 +329,11 @@ class FileController extends AbstractController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
switch ($file->type) {
|
|
||||||
case 'document':
|
|
||||||
$contentArray = Base::json2array($content);
|
|
||||||
$contentString = $contentArray['content'];
|
|
||||||
$file->ext = $contentArray['type'] == 'md' ? 'md' : 'text';
|
|
||||||
break;
|
|
||||||
case 'drawio':
|
|
||||||
$contentArray = Base::json2array($content);
|
|
||||||
$contentString = $contentArray['xml'];
|
|
||||||
$file->ext = 'drawio';
|
|
||||||
break;
|
|
||||||
case 'mind':
|
|
||||||
$contentString = $content;
|
|
||||||
$file->ext = 'mind';
|
|
||||||
break;
|
|
||||||
case 'code':
|
|
||||||
case 'txt':
|
|
||||||
$contentString = $content;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return Base::retError('参数错误');
|
|
||||||
}
|
|
||||||
$path = "uploads/file/" . $file->type . "/" . date("Ym") . "/" . $id . "/" . md5($contentString);
|
|
||||||
$save = public_path($path);
|
|
||||||
Base::makeDir(dirname($save));
|
|
||||||
file_put_contents($save, $contentString);
|
|
||||||
//
|
|
||||||
$content = FileContent::createInstance([
|
$content = FileContent::createInstance([
|
||||||
'fid' => $file->id,
|
'fid' => $file->id,
|
||||||
'content' => [
|
'content' => $content,
|
||||||
'type' => $file->ext,
|
|
||||||
'url' => $path
|
|
||||||
],
|
|
||||||
'text' => $text,
|
'text' => $text,
|
||||||
'size' => filesize($save),
|
'size' => strlen($content),
|
||||||
'userid' => $user->userid,
|
'userid' => $user->userid,
|
||||||
]);
|
]);
|
||||||
$content->save();
|
$content->save();
|
||||||
@ -563,18 +346,9 @@ class FileController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/file/content/office 10. 保存文件内容(office)
|
* 保存文件内容(office)
|
||||||
*
|
|
||||||
* @apiDescription 需要token身份
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup file
|
|
||||||
* @apiName content__office
|
|
||||||
*
|
*
|
||||||
* @apiParam {Number} id 文件ID
|
* @apiParam {Number} id 文件ID
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
*/
|
||||||
public function content__office()
|
public function content__office()
|
||||||
{
|
{
|
||||||
@ -585,12 +359,12 @@ class FileController extends AbstractController
|
|||||||
$key = Request::input('key');
|
$key = Request::input('key');
|
||||||
$url = Request::input('url');
|
$url = Request::input('url');
|
||||||
//
|
//
|
||||||
$file = File::permissionFind($id, 1);
|
$file = File::allowFind($id);
|
||||||
//
|
//
|
||||||
if ($status === 2) {
|
if ($status === 2) {
|
||||||
$parse = parse_url($url);
|
$parse = parse_url($url);
|
||||||
$from = 'http://' . env('APP_IPPR') . '.3' . $parse['path'] . '?' . $parse['query'];
|
$from = 'http://' . env('APP_IPPR') . '.3' . $parse['path'] . '?' . $parse['query'];
|
||||||
$path = 'uploads/file/' . $file->type . '/' . date("Ym") . '/' . $file->id . '/' . $key;
|
$path = 'uploads/office/' . date("Ym") . '/' . $file->id . '/' . $user->userid . '-' . $key;
|
||||||
$save = public_path($path);
|
$save = public_path($path);
|
||||||
Base::makeDir(dirname($save));
|
Base::makeDir(dirname($save));
|
||||||
$res = Ihttp::download($from, $save);
|
$res = Ihttp::download($from, $save);
|
||||||
@ -608,7 +382,6 @@ class FileController extends AbstractController
|
|||||||
$content->save();
|
$content->save();
|
||||||
//
|
//
|
||||||
$file->size = $content->size;
|
$file->size = $content->size;
|
||||||
$file->updated_at = Carbon::now();
|
|
||||||
$file->save();
|
$file->save();
|
||||||
$file->pushMsg('update', $file);
|
$file->pushMsg('update', $file);
|
||||||
}
|
}
|
||||||
@ -617,33 +390,23 @@ class FileController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/file/content/upload 11. 保存文件内容(上传文件)
|
* 保存文件内容(上传文件)
|
||||||
*
|
|
||||||
* @apiDescription 需要token身份
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup file
|
|
||||||
* @apiName content__upload
|
|
||||||
*
|
*
|
||||||
* @apiParam {Number} [pid] 父级ID
|
* @apiParam {Number} [pid] 父级ID
|
||||||
* @apiParam {String} [files] 文件名
|
* @apiParam {String} [files] 文件名
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
*/
|
||||||
public function content__upload()
|
public function content__upload()
|
||||||
{
|
{
|
||||||
$user = User::auth();
|
$user = User::auth();
|
||||||
//
|
//
|
||||||
$pid = intval(Request::input('pid'));
|
$pid = intval(Request::input('pid'));
|
||||||
$webkitRelativePath = Request::input('webkitRelativePath');
|
|
||||||
//
|
//
|
||||||
$userid = $user->userid;
|
$userid = $user->userid;
|
||||||
if ($pid > 0) {
|
if ($pid > 0) {
|
||||||
if (File::wherePid($pid)->count() >= 300) {
|
if (File::wherePid($pid)->count() >= 300) {
|
||||||
return Base::retError('每个文件夹里最多只能创建300个文件或文件夹');
|
return Base::retError('每个文件夹里最多只能创建300个文件或文件夹');
|
||||||
}
|
}
|
||||||
$row = File::permissionFind($pid, 1);
|
$row = File::allowFind($pid, '主文件不存在');
|
||||||
$userid = $row->userid;
|
$userid = $row->userid;
|
||||||
} else {
|
} else {
|
||||||
if (File::whereUserid($user->userid)->wherePid(0)->count() >= 300) {
|
if (File::whereUserid($user->userid)->wherePid(0)->count() >= 300) {
|
||||||
@ -651,37 +414,7 @@ class FileController extends AbstractController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
$dirs = explode("/", $webkitRelativePath);
|
$path = 'uploads/office/' . date("Ym") . '/u' . $user->userid . '/';
|
||||||
while (count($dirs) > 1) {
|
|
||||||
$dirName = array_shift($dirs);
|
|
||||||
if ($dirName) {
|
|
||||||
$pushMsg = [];
|
|
||||||
AbstractModel::transaction(function () use ($dirName, $user, $userid, &$pid, &$pushMsg) {
|
|
||||||
$dirRow = File::wherePid($pid)->whereType('folder')->whereName($dirName)->lockForUpdate()->first();
|
|
||||||
if (empty($dirRow)) {
|
|
||||||
$dirRow = File::createInstance([
|
|
||||||
'pid' => $pid,
|
|
||||||
'type' => 'folder',
|
|
||||||
'name' => $dirName,
|
|
||||||
'userid' => $userid,
|
|
||||||
'created_id' => $user->userid,
|
|
||||||
]);
|
|
||||||
if ($dirRow->save()) {
|
|
||||||
$pushMsg[] = File::find($dirRow->id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (empty($dirRow)) {
|
|
||||||
throw new ApiException('创建文件夹失败');
|
|
||||||
}
|
|
||||||
$pid = $dirRow->id;
|
|
||||||
});
|
|
||||||
foreach ($pushMsg as $tmpRow) {
|
|
||||||
$tmpRow->pushMsg('add', $tmpRow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//
|
|
||||||
$path = 'uploads/tmp/' . date("Ym") . '/';
|
|
||||||
$data = Base::upload([
|
$data = Base::upload([
|
||||||
"file" => Request::file('files'),
|
"file" => Request::file('files'),
|
||||||
"type" => 'more',
|
"type" => 'more',
|
||||||
@ -694,9 +427,6 @@ class FileController extends AbstractController
|
|||||||
$data = $data['data'];
|
$data = $data['data'];
|
||||||
//
|
//
|
||||||
$type = match ($data['ext']) {
|
$type = match ($data['ext']) {
|
||||||
'text', 'md', 'markdown' => 'document',
|
|
||||||
'drawio' => 'drawio',
|
|
||||||
'mind' => 'mind',
|
|
||||||
'doc', 'docx' => "word",
|
'doc', 'docx' => "word",
|
||||||
'xls', 'xlsx' => "excel",
|
'xls', 'xlsx' => "excel",
|
||||||
'ppt', 'pptx' => "ppt",
|
'ppt', 'pptx' => "ppt",
|
||||||
@ -708,22 +438,12 @@ class FileController extends AbstractController
|
|||||||
'ofd' => "ofd",
|
'ofd' => "ofd",
|
||||||
'pdf' => "pdf",
|
'pdf' => "pdf",
|
||||||
'txt' => "txt",
|
'txt' => "txt",
|
||||||
'htaccess', 'htgroups', 'htpasswd', 'conf', 'bat', 'cmd', 'cpp', 'c', 'cc', 'cxx', 'h', 'hh', 'hpp', 'ino', 'cs', 'css',
|
'html', 'htm', 'asp', 'jsp', 'xml', 'json', 'properties', 'md', 'gitignore', 'log', 'java', 'py', 'c', 'cpp', 'sql', 'sh', 'bat', 'm', 'bas', 'prg', 'cmd',
|
||||||
'dockerfile', 'go', 'html', 'htm', 'xhtml', 'vue', 'we', 'wpy', 'java', 'js', 'jsm', 'jsx', 'json', 'jsp', 'less', 'lua', 'makefile', 'gnumakefile',
|
'php', 'go', 'python', 'js', 'ftl', 'css', 'lua', 'rb', 'yaml', 'yml', 'h', 'cs', 'aspx' => "code",
|
||||||
'ocamlmakefile', 'make', 'mysql', 'nginx', 'ini', 'cfg', 'prefs', 'm', 'mm', 'pl', 'pm', 'p6', 'pl6', 'pm6', 'pgsql', 'php',
|
|
||||||
'inc', 'phtml', 'shtml', 'php3', 'php4', 'php5', 'phps', 'phpt', 'aw', 'ctp', 'module', 'ps1', 'py', 'r', 'rb', 'ru', 'gemspec', 'rake', 'guardfile', 'rakefile',
|
|
||||||
'gemfile', 'rs', 'sass', 'scss', 'sh', 'bash', 'bashrc', 'sql', 'sqlserver', 'swift', 'ts', 'typescript', 'str', 'vbs', 'vb', 'v', 'vh', 'sv', 'svh', 'xml',
|
|
||||||
'rdf', 'rss', 'wsdl', 'xslt', 'atom', 'mathml', 'mml', 'xul', 'xbl', 'xaml', 'yaml', 'yml',
|
|
||||||
'asp', 'properties', 'gitignore', 'log', 'bas', 'prg', 'python', 'ftl', 'aspx' => "code",
|
|
||||||
'mp3', 'wav', 'mp4', 'flv',
|
'mp3', 'wav', 'mp4', 'flv',
|
||||||
'avi', 'mov', 'wmv', 'mkv', '3gp', 'rm' => "media",
|
'avi', 'mov', 'wmv', 'mkv', '3gp', 'rm' => "media",
|
||||||
'xmind' => "xmind",
|
|
||||||
'rp' => "axure",
|
|
||||||
default => "",
|
default => "",
|
||||||
};
|
};
|
||||||
if ($data['ext'] == 'markdown') {
|
|
||||||
$data['ext'] = 'md';
|
|
||||||
}
|
|
||||||
$file = File::createInstance([
|
$file = File::createInstance([
|
||||||
'pid' => $pid,
|
'pid' => $pid,
|
||||||
'name' => Base::rightDelete($data['name'], '.' . $data['ext']),
|
'name' => Base::rightDelete($data['name'], '.' . $data['ext']),
|
||||||
@ -733,11 +453,9 @@ class FileController extends AbstractController
|
|||||||
'created_id' => $user->userid,
|
'created_id' => $user->userid,
|
||||||
]);
|
]);
|
||||||
// 开始创建
|
// 开始创建
|
||||||
return AbstractModel::transaction(function () use ($webkitRelativePath, $type, $user, $data, $file) {
|
return AbstractModel::transaction(function () use ($type, $user, $data, $file) {
|
||||||
$file->size = $data['size'] * 1024;
|
|
||||||
$file->save();
|
$file->save();
|
||||||
//
|
//
|
||||||
$data = Base::uploadMove($data, "uploads/file/" . $file->type . "/" . date("Ym") . "/" . $file->id . "/");
|
|
||||||
$content = FileContent::createInstance([
|
$content = FileContent::createInstance([
|
||||||
'fid' => $file->id,
|
'fid' => $file->id,
|
||||||
'content' => [
|
'content' => [
|
||||||
@ -747,33 +465,24 @@ class FileController extends AbstractController
|
|||||||
'url' => $data['path']
|
'url' => $data['path']
|
||||||
],
|
],
|
||||||
'text' => '',
|
'text' => '',
|
||||||
'size' => $file->size,
|
'size' => $data['size'] * 1024,
|
||||||
'userid' => $user->userid,
|
'userid' => $user->userid,
|
||||||
]);
|
]);
|
||||||
$content->save();
|
$content->save();
|
||||||
//
|
//
|
||||||
$tmpRow = File::find($file->id);
|
$file->size = $content->size;
|
||||||
$tmpRow->pushMsg('add', $tmpRow);
|
$file->save();
|
||||||
//
|
//
|
||||||
$data = $tmpRow->toArray();
|
$data = File::find($file->id);
|
||||||
$data['full_name'] = $webkitRelativePath ?: $data['name'];
|
$data->pushMsg('add', $data);
|
||||||
return Base::retSuccess($data['name'] . ' 上传成功', $data);
|
return Base::retSuccess($data['name'] . ' 上传成功', $data);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/file/share 12. 获取共享信息
|
* 获取共享信息
|
||||||
*
|
|
||||||
* @apiDescription 需要token身份
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup file
|
|
||||||
* @apiName share
|
|
||||||
*
|
*
|
||||||
* @apiParam {Number} id 文件ID
|
* @apiParam {Number} id 文件ID
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
*/
|
||||||
public function share()
|
public function share()
|
||||||
{
|
{
|
||||||
@ -789,44 +498,34 @@ class FileController extends AbstractController
|
|||||||
return Base::retError('仅限所有者操作');
|
return Base::retError('仅限所有者操作');
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
$list = FileUser::whereFileId($file->id)->get();
|
$userids = FileUser::whereFileId($file->id)->pluck('userid')->toArray();
|
||||||
//
|
//
|
||||||
return Base::retSuccess('success', [
|
return Base::retSuccess('success', [
|
||||||
'id' => $file->id,
|
'id' => $file->id,
|
||||||
'list' => $list
|
'userids' => $userids
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/file/share/update 13. 设置共享
|
* 获取共享信息
|
||||||
*
|
|
||||||
* @apiDescription 需要token身份
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup file
|
|
||||||
* @apiName share__update
|
|
||||||
*
|
*
|
||||||
* @apiParam {Number} id 文件ID
|
* @apiParam {Number} id 文件ID
|
||||||
|
* @apiParam {String} action 动作
|
||||||
|
* - share: 设置共享
|
||||||
|
* - unshare: 取消共享
|
||||||
|
* @apiParam {Number} [share] 共享对象
|
||||||
|
* - 1: 共享给所有人(限管理员)
|
||||||
|
* - 2: 共享给指定成员
|
||||||
* @apiParam {Array} [userids] 共享成员,格式: [userid1, userid2, userid3]
|
* @apiParam {Array} [userids] 共享成员,格式: [userid1, userid2, userid3]
|
||||||
* @apiParam {Number} [permission] 共享方式
|
|
||||||
* - 0:只读
|
|
||||||
* - 1:读写
|
|
||||||
* - -1: 删除
|
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
*/
|
||||||
public function share__update()
|
public function share__update()
|
||||||
{
|
{
|
||||||
$user = User::auth();
|
$user = User::auth();
|
||||||
//
|
//
|
||||||
$id = intval(Request::input('id'));
|
$id = intval(Request::input('id'));
|
||||||
|
$action = Request::input('action');
|
||||||
|
$share = intval(Request::input('share'));
|
||||||
$userids = Request::input('userids');
|
$userids = Request::input('userids');
|
||||||
$permission = intval(Request::input('permission'));
|
|
||||||
//
|
|
||||||
if (!in_array($permission, [-1, 0, 1])) {
|
|
||||||
return Base::retError('参数错误');
|
|
||||||
}
|
|
||||||
//
|
//
|
||||||
$file = File::whereId($id)->first();
|
$file = File::whereId($id)->first();
|
||||||
if (empty($file)) {
|
if (empty($file)) {
|
||||||
@ -840,131 +539,56 @@ class FileController extends AbstractController
|
|||||||
return Base::retError('已经处于共享文件夹中');
|
return Base::retError('已经处于共享文件夹中');
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
if (!is_array($userids) || empty($userids)) {
|
if ($action == 'unshare') {
|
||||||
return Base::retError('请选择共享对象');
|
|
||||||
}
|
|
||||||
//
|
|
||||||
$array = [];
|
|
||||||
if ($permission === -1) {
|
|
||||||
// 取消共享
|
// 取消共享
|
||||||
$action = "delete";
|
if ($file->share == 1) {
|
||||||
foreach ($userids as $userid) {
|
$uids = WebSocket::select(['userid'])->pluck('userid')->toArray();
|
||||||
if (FileUser::where([
|
} else {
|
||||||
'file_id' => $file->id,
|
$uids = FileUser::whereFileId($file->id)->pluck('userid')->toArray();
|
||||||
'userid' => $userid,
|
|
||||||
])->delete()) {
|
|
||||||
$array[] = $userid;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
$uids = array_values(array_diff($uids, [$user->userid]));
|
||||||
|
//
|
||||||
|
$file->setShare(0);
|
||||||
|
$message = '取消成功';
|
||||||
} else {
|
} else {
|
||||||
// 设置共享
|
// 设置共享
|
||||||
$action = "update";
|
switch ($share) {
|
||||||
if (FileUser::whereFileId($file->id)->count() + count($userids) > 100) {
|
case 1:
|
||||||
return Base::retError('共享人数上限100个成员');
|
$user->isAdmin();
|
||||||
}
|
break;
|
||||||
foreach ($userids as $userid) {
|
|
||||||
if (FileUser::updateInsert([
|
|
||||||
'file_id' => $file->id,
|
|
||||||
'userid' => $userid,
|
|
||||||
], [
|
|
||||||
'permission' => $permission,
|
|
||||||
])) {
|
|
||||||
$array[] = $userid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//
|
|
||||||
$file->setShare();
|
|
||||||
$file->pushMsg($action, $action == "delete" ? null : $file, $array);
|
|
||||||
return Base::retSuccess($action == "delete" ? "删除成功" : "设置成功", $file);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
case 2:
|
||||||
* @api {get} api/file/share/out 14. 退出共享
|
$array = [];
|
||||||
*
|
if (is_array($userids)) {
|
||||||
* @apiDescription 需要token身份
|
foreach ($userids as $userid) {
|
||||||
* @apiVersion 1.0.0
|
if (!intval($userid)) continue;
|
||||||
* @apiGroup file
|
if (!User::whereUserid($userid)->exists()) continue;
|
||||||
* @apiName share__out
|
FileUser::updateInsert([
|
||||||
*
|
'file_id' => $file->id,
|
||||||
* @apiParam {Number} id 文件ID
|
'userid' => $userid,
|
||||||
*
|
]);
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
$array[] = $userid;
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
}
|
||||||
* @apiSuccess {Object} data 返回数据
|
}
|
||||||
*/
|
if (empty($array)) {
|
||||||
public function share__out()
|
return Base::retError('请选择共享成员');
|
||||||
{
|
}
|
||||||
$user = User::auth();
|
$builder = FileUser::whereFileId($file->id)->whereNotIn('userid', $array);
|
||||||
//
|
$uids = (clone $builder)->pluck('userid')->toArray();
|
||||||
$id = intval(Request::input('id'));
|
$builder->delete();
|
||||||
//
|
break;
|
||||||
$file = File::permissionFind($id);
|
|
||||||
//
|
|
||||||
if ($file->userid == $user->userid) {
|
|
||||||
return Base::retError('不能退出自己共享的文件');
|
|
||||||
}
|
|
||||||
if (FileUser::where([
|
|
||||||
'file_id' => $file->id,
|
|
||||||
'userid' => 0,
|
|
||||||
])->exists()) {
|
|
||||||
return Base::retError('无法退出共享所有人的文件或文件夹');
|
|
||||||
}
|
|
||||||
FileUser::where([
|
|
||||||
'file_id' => $file->id,
|
|
||||||
'userid' => $user->userid,
|
|
||||||
])->delete();
|
|
||||||
//
|
|
||||||
$file->setShare();
|
|
||||||
return Base::retSuccess("退出成功");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
default:
|
||||||
* @api {get} api/file/link 15. 获取链接
|
return Base::retError('请选择共享对象');
|
||||||
*
|
|
||||||
* @apiDescription 需要token身份
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup file
|
|
||||||
* @apiName link
|
|
||||||
*
|
|
||||||
* @apiParam {Number} id 文件ID
|
|
||||||
* @apiParam {String} refresh 刷新链接
|
|
||||||
* - no: 只获取(默认)
|
|
||||||
* - yes: 刷新链接,之前的将失效
|
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
|
||||||
public function link()
|
|
||||||
{
|
|
||||||
User::auth();
|
|
||||||
//
|
|
||||||
$id = intval(Request::input('id'));
|
|
||||||
$refresh = Request::input('refresh', 'no');
|
|
||||||
//
|
|
||||||
$file = File::permissionFind($id, 1000);
|
|
||||||
if ($file->type == 'folder') {
|
|
||||||
return Base::retError('文件夹暂不支持此功能');
|
|
||||||
}
|
|
||||||
//
|
|
||||||
$fileLink = FileLink::whereFileId($file->id)->first();
|
|
||||||
if (empty($fileLink)) {
|
|
||||||
$fileLink = FileLink::createInstance([
|
|
||||||
'file_id' => $file->id,
|
|
||||||
'code' => Base::generatePassword(64),
|
|
||||||
]);
|
|
||||||
$fileLink->save();
|
|
||||||
} else {
|
|
||||||
if ($refresh == 'yes') {
|
|
||||||
$fileLink->code = Base::generatePassword(64);
|
|
||||||
$fileLink->save();
|
|
||||||
}
|
}
|
||||||
|
$file->setShare($share);
|
||||||
|
$message = '设置成功';
|
||||||
}
|
}
|
||||||
return Base::retSuccess('success', [
|
//
|
||||||
'id' => $file->id,
|
$file->pushMsg('update', $file);
|
||||||
'url' => Base::fillUrl('single/file/' . $fileLink->code),
|
if (isset($uids)) {
|
||||||
'num' => $fileLink->num
|
$file->pushMsg('delete', null, $uids);
|
||||||
]);
|
}
|
||||||
|
return Base::retSuccess($message, $file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,466 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Api;
|
|
||||||
|
|
||||||
use App\Exceptions\ApiException;
|
|
||||||
use App\Models\ProjectTask;
|
|
||||||
use App\Models\Report;
|
|
||||||
use App\Models\ReportReceive;
|
|
||||||
use App\Models\User;
|
|
||||||
use App\Module\Base;
|
|
||||||
use App\Tasks\PushTask;
|
|
||||||
use Carbon\Carbon;
|
|
||||||
use Hhxsv5\LaravelS\Swoole\Task\Task;
|
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
use Request;
|
|
||||||
use Illuminate\Support\Facades\Validator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @apiDefine report
|
|
||||||
*
|
|
||||||
* 汇报
|
|
||||||
*/
|
|
||||||
class ReportController extends AbstractController
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @api {get} api/report/my 01. 我发送的汇报
|
|
||||||
*
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup report
|
|
||||||
* @apiName my
|
|
||||||
*
|
|
||||||
* @apiParam {String} [type] 汇报类型,weekly:周报,daily:日报
|
|
||||||
* @apiParam {Array} [created_at] 汇报时间
|
|
||||||
* @apiParam {Number} [page] 当前页,默认:1
|
|
||||||
* @apiParam {Number} [pagesize] 每页显示数量,默认:20,最大:50
|
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
|
||||||
public function my(): array
|
|
||||||
{
|
|
||||||
$user = User::auth();
|
|
||||||
// 搜索当前用户
|
|
||||||
$builder = Report::with(['receivesUser'])->whereUserid($user->userid);
|
|
||||||
$type = trim(Request::input('type'));
|
|
||||||
$createAt = Request::input('created_at');
|
|
||||||
in_array($type, [Report::WEEKLY, Report::DAILY]) && $builder->whereType($type);
|
|
||||||
$whereArray = [];
|
|
||||||
if (is_array($createAt)) {
|
|
||||||
if ($createAt[0] > 0) $whereArray[] = ['created_at', '>=', date('Y-m-d H:i:s', Base::dayTimeF($createAt[0]))];
|
|
||||||
if ($createAt[1] > 0) $whereArray[] = ['created_at', '<=', date('Y-m-d H:i:s', Base::dayTimeE($createAt[1]))];
|
|
||||||
}
|
|
||||||
$list = $builder->where($whereArray)->orderByDesc('created_at')->paginate(Base::getPaginate(50, 20));
|
|
||||||
return Base::retSuccess('success', $list);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @api {get} api/report/receive 02. 我接收的汇报
|
|
||||||
*
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup report
|
|
||||||
* @apiName receive
|
|
||||||
*
|
|
||||||
* @apiParam {String} [username] 会员名
|
|
||||||
* @apiParam {String} [type] 汇报类型,weekly:周报,daily:日报
|
|
||||||
* @apiParam {Array} [created_at] 汇报时间
|
|
||||||
* @apiParam {Number} [page] 当前页,默认:1
|
|
||||||
* @apiParam {Number} [pagesize] 每页显示数量,默认:20,最大:50
|
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
|
||||||
public function receive(): array
|
|
||||||
{
|
|
||||||
$user = User::auth();
|
|
||||||
$builder = Report::with(['receivesUser']);
|
|
||||||
$builder->whereHas("receivesUser", function ($query) use ($user) {
|
|
||||||
$query->where("report_receives.userid", $user->userid);
|
|
||||||
});
|
|
||||||
$type = trim(Request::input('type'));
|
|
||||||
$createAt = Request::input('created_at');
|
|
||||||
$username = trim(Request::input('username', ''));
|
|
||||||
$builder->whereHas('sendUser', function ($query) use ($username) {
|
|
||||||
if (!empty($username)) {
|
|
||||||
$query->where('users.email', 'LIKE', '%' . $username . '%');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
in_array($type, [Report::WEEKLY, Report::DAILY]) && $builder->whereType($type);
|
|
||||||
$whereArray = [];
|
|
||||||
if (is_array($createAt)) {
|
|
||||||
if ($createAt[0] > 0) $whereArray[] = ['created_at', '>=', date('Y-m-d H:i:s', Base::dayTimeF($createAt[0]))];
|
|
||||||
if ($createAt[1] > 0) $whereArray[] = ['created_at', '<=', date('Y-m-d H:i:s', Base::dayTimeE($createAt[1]))];
|
|
||||||
}
|
|
||||||
$list = $builder->where($whereArray)->orderByDesc('created_at')->paginate(Base::getPaginate(50, 20));
|
|
||||||
if ($list->items()) {
|
|
||||||
foreach ($list->items() as $item) {
|
|
||||||
$item->receive_time = ReportReceive::query()->whereRid($item["id"])->whereUserid($user->userid)->value("receive_time");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Base::retSuccess('success', $list);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @api {get} api/report/store 03. 保存并发送工作汇报
|
|
||||||
*
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup report
|
|
||||||
* @apiName store
|
|
||||||
*
|
|
||||||
* @apiParam {Number} [id] 汇报ID
|
|
||||||
* @apiParam {String} [title] 汇报标题
|
|
||||||
* @apiParam {Array} [type] 汇报类型,weekly:周报,daily:日报
|
|
||||||
* @apiParam {Number} [content] 内容
|
|
||||||
* @apiParam {Number} [receive] 汇报对象
|
|
||||||
* @apiParam {Number} [offset] 偏移量
|
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
|
||||||
public function store(): array
|
|
||||||
{
|
|
||||||
$input = [
|
|
||||||
"id" => Base::getPostValue("id", 0),
|
|
||||||
"title" => Base::getPostValue("title"),
|
|
||||||
"type" => Base::getPostValue("type"),
|
|
||||||
"content" => Base::getPostValue("content"),
|
|
||||||
"receive" => Base::getPostValue("receive"),
|
|
||||||
// 以当前日期为基础的周期偏移量。例如选择了上一周那么就是 -1,上一天同理。
|
|
||||||
"offset" => Base::getPostValue("offset", 0),
|
|
||||||
];
|
|
||||||
$validator = Validator::make($input, [
|
|
||||||
'id' => 'numeric',
|
|
||||||
'title' => 'required',
|
|
||||||
'type' => ['required', Rule::in([Report::WEEKLY, Report::DAILY])],
|
|
||||||
'content' => 'required',
|
|
||||||
'receive' => 'required',
|
|
||||||
'offset' => ['numeric', 'max:0'],
|
|
||||||
], [
|
|
||||||
'id.numeric' => 'ID只能是数字',
|
|
||||||
'title.required' => '请填写标题',
|
|
||||||
'type.required' => '请选择汇报类型',
|
|
||||||
'type.in' => '汇报类型错误',
|
|
||||||
'content.required' => '请填写汇报内容',
|
|
||||||
'receive.required' => '请选择接收人',
|
|
||||||
'offset.numeric' => '工作汇报周期格式错误,只能是数字',
|
|
||||||
'offset.max' => '只能提交当天/本周或者之前的的工作汇报',
|
|
||||||
]);
|
|
||||||
if ($validator->fails())
|
|
||||||
return Base::retError($validator->errors()->first());
|
|
||||||
|
|
||||||
$user = User::auth();
|
|
||||||
// 接收人
|
|
||||||
if (is_array($input["receive"])) {
|
|
||||||
// 删除当前登录人
|
|
||||||
$input["receive"] = array_diff($input["receive"], [$user->userid]);
|
|
||||||
|
|
||||||
// 查询用户是否存在
|
|
||||||
if (count($input["receive"]) !== User::whereIn("userid", $input["receive"])->count())
|
|
||||||
return Base::retError("用户不存在");
|
|
||||||
|
|
||||||
foreach ($input["receive"] as $userid) {
|
|
||||||
$input["receive_content"][] = [
|
|
||||||
"receive_time" => Carbon::now()->toDateTimeString(),
|
|
||||||
"userid" => $userid,
|
|
||||||
"read" => 0,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 在事务中运行
|
|
||||||
Report::transaction(function () use ($input, $user) {
|
|
||||||
$id = $input["id"];
|
|
||||||
if ($id) {
|
|
||||||
// 编辑
|
|
||||||
$report = Report::getOne($id);
|
|
||||||
$report->updateInstance([
|
|
||||||
"title" => $input["title"],
|
|
||||||
"type" => $input["type"],
|
|
||||||
"content" => htmlspecialchars($input["content"]),
|
|
||||||
]);
|
|
||||||
} else {
|
|
||||||
// 生成唯一标识
|
|
||||||
$sign = Report::generateSign($input["type"], $input["offset"]);
|
|
||||||
// 检查唯一标识是否存在
|
|
||||||
if (empty($input["id"])) {
|
|
||||||
if (Report::query()->whereSign($sign)->whereType($input["type"])->count() > 0)
|
|
||||||
throw new ApiException("请勿重复提交工作汇报");
|
|
||||||
}
|
|
||||||
$report = Report::createInstance([
|
|
||||||
"title" => $input["title"],
|
|
||||||
"type" => $input["type"],
|
|
||||||
"content" => htmlspecialchars($input["content"]),
|
|
||||||
"userid" => $user->userid,
|
|
||||||
"sign" => $sign,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$report->save();
|
|
||||||
if (!empty($input["receive_content"])) {
|
|
||||||
// 删除关联
|
|
||||||
$report->Receives()->delete();
|
|
||||||
// 保存接收人
|
|
||||||
$report->Receives()->createMany($input["receive_content"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 推送消息
|
|
||||||
$userids = [];
|
|
||||||
foreach ($input["receive_content"] as $item) {
|
|
||||||
$userids[] = $item['userid'];
|
|
||||||
}
|
|
||||||
if ($userids) {
|
|
||||||
$params = [
|
|
||||||
'ignoreFd' => Request::header('fd'),
|
|
||||||
'userid' => $userids,
|
|
||||||
'msg' => [
|
|
||||||
'type' => 'report',
|
|
||||||
'action' => 'unreadUpdate',
|
|
||||||
]
|
|
||||||
];
|
|
||||||
Task::deliver(new PushTask($params, false));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return Base::retSuccess('保存成功');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @api {get} api/report/template 04. 生成汇报模板
|
|
||||||
*
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup report
|
|
||||||
* @apiName template
|
|
||||||
*
|
|
||||||
* @apiParam {Array} [type] 汇报类型,weekly:周报,daily:日报
|
|
||||||
* @apiParam {Number} [offset] 偏移量
|
|
||||||
* @apiParam {String} [date] 时间
|
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
|
||||||
public function template(): array
|
|
||||||
{
|
|
||||||
$user = User::auth();
|
|
||||||
$type = trim(Request::input("type"));
|
|
||||||
$offset = abs(intval(Request::input("offset", 0)));
|
|
||||||
$id = intval(Request::input("offset", 0));
|
|
||||||
$now_dt = trim(Request::input("date")) ? Carbon::parse(Request::input("date")) : Carbon::now();
|
|
||||||
// 获取开始时间
|
|
||||||
if ($type === Report::DAILY) {
|
|
||||||
$start_time = Carbon::today();
|
|
||||||
if ($offset > 0) {
|
|
||||||
// 将当前时间调整为偏移量当天结束
|
|
||||||
$now_dt->subDays($offset)->endOfDay();
|
|
||||||
// 开始时间偏移量计算
|
|
||||||
$start_time->subDays($offset);
|
|
||||||
}
|
|
||||||
$end_time = Carbon::instance($start_time)->endOfDay();
|
|
||||||
} else {
|
|
||||||
$start_time = Carbon::now();
|
|
||||||
if ($offset > 0) {
|
|
||||||
// 将当前时间调整为偏移量当周结束
|
|
||||||
$now_dt->subWeeks($offset)->endOfDay();
|
|
||||||
// 开始时间偏移量计算
|
|
||||||
$start_time->subWeeks($offset);
|
|
||||||
}
|
|
||||||
$start_time->startOfWeek();
|
|
||||||
$end_time = Carbon::instance($start_time)->endOfWeek();
|
|
||||||
}
|
|
||||||
// 生成唯一标识
|
|
||||||
$sign = Report::generateSign($type, 0, Carbon::instance($start_time));
|
|
||||||
$one = Report::query()->whereSign($sign)->whereType($type)->first();
|
|
||||||
// 如果已经提交了相关汇报
|
|
||||||
if ($one && $id > 0) {
|
|
||||||
return Base::retSuccess('success', [
|
|
||||||
"content" => $one->content,
|
|
||||||
"title" => $one->title,
|
|
||||||
"id" => $one->id,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 已完成的任务
|
|
||||||
$completeContent = "";
|
|
||||||
$complete_task = ProjectTask::query()
|
|
||||||
->whereNotNull("complete_at")
|
|
||||||
->whereBetween("complete_at", [$start_time->toDateTimeString(), $end_time->toDateTimeString()])
|
|
||||||
->whereHas("taskUser", function ($query) use ($user) {
|
|
||||||
$query->where("userid", $user->userid);
|
|
||||||
})
|
|
||||||
->orderByDesc("id")
|
|
||||||
->get();
|
|
||||||
if ($complete_task->isNotEmpty()) {
|
|
||||||
foreach ($complete_task as $task) {
|
|
||||||
$complete_at = Carbon::parse($task->complete_at);
|
|
||||||
$pre = $type == Report::WEEKLY ? ('<span>[' . Base::Lang('周' . ['日', '一', '二', '三', '四', '五', '六'][$complete_at->dayOfWeek]) . ']</span> ') : '';
|
|
||||||
$completeContent .= '<li>' . $pre . $task->name . '</li>';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$completeContent = '<li> </li>';
|
|
||||||
}
|
|
||||||
|
|
||||||
// 未完成的任务
|
|
||||||
$unfinishedContent = "";
|
|
||||||
$unfinished_task = ProjectTask::query()
|
|
||||||
->whereNull("complete_at")
|
|
||||||
->whereNotNull("start_at")
|
|
||||||
->where("end_at", "<", $end_time->toDateTimeString())
|
|
||||||
->whereHas("taskUser", function ($query) use ($user) {
|
|
||||||
$query->where("userid", $user->userid);
|
|
||||||
})
|
|
||||||
->orderByDesc("id")
|
|
||||||
->get();
|
|
||||||
if ($unfinished_task->isNotEmpty()) {
|
|
||||||
foreach ($unfinished_task as $task) {
|
|
||||||
empty($task->end_at) || $end_at = Carbon::parse($task->end_at);
|
|
||||||
$pre = (!empty($end_at) && $end_at->lt($now_dt)) ? '<span style="color:#ff0000;">[' . Base::Lang('超期') . ']</span> ' : '';
|
|
||||||
$unfinishedContent .= '<li>' . $pre . $task->name . '</li>';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$unfinishedContent = '<li> </li>';
|
|
||||||
}
|
|
||||||
// 生成标题
|
|
||||||
if ($type === Report::WEEKLY) {
|
|
||||||
$title = $user->nickname . "的周报[" . $start_time->format("m/d") . "-" . $end_time->format("m/d") . "]";
|
|
||||||
$title .= "[" . $start_time->month . "月第" . $start_time->weekOfMonth . "周]";
|
|
||||||
} else {
|
|
||||||
$title = $user->nickname . "的日报[" . $start_time->format("Y/m/d") . "]";
|
|
||||||
}
|
|
||||||
$data = [
|
|
||||||
"time" => $start_time->toDateTimeString(),
|
|
||||||
"complete_task" => $complete_task,
|
|
||||||
"unfinished_task" => $unfinished_task,
|
|
||||||
"content" => '<h2>' . Base::Lang('已完成工作') . '</h2><ol>' .
|
|
||||||
$completeContent . '</ol><h2>' .
|
|
||||||
Base::Lang('未完成的工作') . '</h2><ol>' .
|
|
||||||
$unfinishedContent . '</ol>',
|
|
||||||
"title" => $title,
|
|
||||||
];
|
|
||||||
if ($one) {
|
|
||||||
$data['id'] = $one->id;
|
|
||||||
}
|
|
||||||
return Base::retSuccess('success', $data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @api {get} api/report/detail 05. 报告详情
|
|
||||||
*
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup report
|
|
||||||
* @apiName detail
|
|
||||||
*
|
|
||||||
* @apiParam {Number} [id] 报告id
|
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
|
||||||
public function detail(): array
|
|
||||||
{
|
|
||||||
$id = intval(trim(Request::input("id")));
|
|
||||||
if (empty($id))
|
|
||||||
return Base::retError("缺少ID参数");
|
|
||||||
|
|
||||||
$one = Report::getOne($id);
|
|
||||||
$one->type_val = $one->getRawOriginal("type");
|
|
||||||
|
|
||||||
$user = User::auth();
|
|
||||||
// 标记为已读
|
|
||||||
if (!empty($one->receivesUser)) {
|
|
||||||
foreach ($one->receivesUser as $item) {
|
|
||||||
if ($item->userid === $user->userid && $item->pivot->read === 0) {
|
|
||||||
$one->receivesUser()->updateExistingPivot($user->userid, [
|
|
||||||
"read" => 1,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Base::retSuccess("success", $one);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @api {get} api/report/last_submitter 06. 获取最后一次提交的接收人
|
|
||||||
*
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup report
|
|
||||||
* @apiName last_submitter
|
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
|
||||||
public function last_submitter(): array
|
|
||||||
{
|
|
||||||
$one = Report::getLastOne();
|
|
||||||
return Base::retSuccess("success", empty($one["receives"]) ? [] : $one["receives"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @api {get} api/report/unread 07. 获取未读
|
|
||||||
*
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup report
|
|
||||||
* @apiName unread
|
|
||||||
*
|
|
||||||
* @apiParam {Number} [userid] 用户id
|
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
|
||||||
public function unread(): array
|
|
||||||
{
|
|
||||||
$userid = intval(trim(Request::input("userid")));
|
|
||||||
$user = empty($userid) ? User::auth() : User::find($userid);
|
|
||||||
|
|
||||||
$data = Report::whereHas("Receives", function (Builder $query) use ($user) {
|
|
||||||
$query->where("userid", $user->userid)->where("read", 0);
|
|
||||||
})->orderByDesc('created_at')->paginate(Base::getPaginate(50, 20));
|
|
||||||
return Base::retSuccess("success", $data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @api {get} api/report/read 08. 标记汇报已读,可批量
|
|
||||||
*
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup report
|
|
||||||
* @apiName read
|
|
||||||
*
|
|
||||||
* @apiParam {String} [ids] 报告id
|
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
|
||||||
public function read(): array
|
|
||||||
{
|
|
||||||
$user = User::auth();
|
|
||||||
$ids = Request::input("ids");
|
|
||||||
if (!is_array($ids) && !is_string($ids)) {
|
|
||||||
return Base::retError("请传入正确的工作汇报Id");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_string($ids)) {
|
|
||||||
$ids = explode(",", $ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
$data = Report::with(["receivesUser" => function (BelongsToMany $query) use ($user) {
|
|
||||||
$query->where("report_receives.userid", $user->userid)->where("read", 0);
|
|
||||||
}])->whereIn("id", $ids)->get();
|
|
||||||
|
|
||||||
if ($data->isNotEmpty()) {
|
|
||||||
foreach ($data as $item) {
|
|
||||||
(!empty($item->receivesUser) && $item->receivesUser->isNotEmpty()) && $item->receivesUser()->updateExistingPivot($user->userid, [
|
|
||||||
"read" => 1,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Base::retSuccess("success", $data);
|
|
||||||
}
|
|
||||||
}
|
|
@ -24,8 +24,7 @@ class SystemController extends AbstractController
|
|||||||
*
|
*
|
||||||
* @apiParam {String} type
|
* @apiParam {String} type
|
||||||
* - get: 获取(默认)
|
* - get: 获取(默认)
|
||||||
* - all: 获取所有(需要管理员权限)
|
* - save: 保存设置(参数:reg、login_code、password_policy、chat_nickname)
|
||||||
* - save: 保存设置(参数:reg、reg_invite、login_code、password_policy、project_invite、chat_nickname、auto_archived、archived_day)
|
|
||||||
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||||
@ -41,37 +40,19 @@ class SystemController extends AbstractController
|
|||||||
User::auth('admin');
|
User::auth('admin');
|
||||||
$all = Request::input();
|
$all = Request::input();
|
||||||
foreach ($all AS $key => $value) {
|
foreach ($all AS $key => $value) {
|
||||||
if (!in_array($key, ['reg', 'reg_invite', 'login_code', 'password_policy', 'project_invite', 'chat_nickname', 'auto_archived', 'archived_day'])) {
|
if (!in_array($key, ['reg', 'login_code', 'password_policy', 'chat_nickname'])) {
|
||||||
unset($all[$key]);
|
unset($all[$key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$all['archived_day'] = floatval($all['archived_day']);
|
|
||||||
if ($all['auto_archived'] == 'open') {
|
|
||||||
if ($all['archived_day'] <= 0) {
|
|
||||||
return Base::retError('自动归档时间不可小于1天!');
|
|
||||||
} elseif ($all['archived_day'] > 100) {
|
|
||||||
return Base::retError('自动归档时间不可大于100天!');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$setting = Base::setting('system', Base::newTrim($all));
|
$setting = Base::setting('system', Base::newTrim($all));
|
||||||
} else {
|
} else {
|
||||||
$setting = Base::setting('system');
|
$setting = Base::setting('system');
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
if ($type == 'all' || $type == 'save') {
|
|
||||||
User::auth('admin');
|
|
||||||
$setting['reg_invite'] = $setting['reg_invite'] ?: Base::generatePassword(8);
|
|
||||||
} else {
|
|
||||||
if (isset($setting['reg_invite'])) unset($setting['reg_invite']);
|
|
||||||
}
|
|
||||||
//
|
|
||||||
$setting['reg'] = $setting['reg'] ?: 'open';
|
$setting['reg'] = $setting['reg'] ?: 'open';
|
||||||
$setting['login_code'] = $setting['login_code'] ?: 'auto';
|
$setting['login_code'] = $setting['login_code'] ?: 'auto';
|
||||||
$setting['password_policy'] = $setting['password_policy'] ?: 'simple';
|
$setting['password_policy'] = $setting['password_policy'] ?: 'simple';
|
||||||
$setting['project_invite'] = $setting['project_invite'] ?: 'open';
|
|
||||||
$setting['chat_nickname'] = $setting['chat_nickname'] ?: 'optional';
|
$setting['chat_nickname'] = $setting['chat_nickname'] ?: 'optional';
|
||||||
$setting['auto_archived'] = $setting['auto_archived'] ?: 'close';
|
|
||||||
$setting['archived_day'] = floatval($setting['archived_day']) ?: 7;
|
|
||||||
//
|
//
|
||||||
return Base::retSuccess('success', $setting ?: json_decode('{}'));
|
return Base::retSuccess('success', $setting ?: json_decode('{}'));
|
||||||
}
|
}
|
||||||
@ -101,16 +82,12 @@ class SystemController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {post} api/system/priority 03. 任务优先级
|
* @api {post} api/system/priority 03. 获取优先级、保存优先级
|
||||||
*
|
*
|
||||||
* @apiDescription 获取任务优先级、保存任务优先级
|
|
||||||
* @apiVersion 1.0.0
|
* @apiVersion 1.0.0
|
||||||
* @apiGroup system
|
* @apiGroup system
|
||||||
* @apiName priority
|
* @apiName priority
|
||||||
*
|
*
|
||||||
* @apiParam {String} type
|
|
||||||
* - get: 获取(默认)
|
|
||||||
* - save: 保存(限管理员)
|
|
||||||
* @apiParam {Array} list 优先级数据,格式:[{name,color,days,priority}]
|
* @apiParam {Array} list 优先级数据,格式:[{name,color,days,priority}]
|
||||||
*
|
*
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||||
@ -128,7 +105,7 @@ class SystemController extends AbstractController
|
|||||||
return Base::retError('参数错误');
|
return Base::retError('参数错误');
|
||||||
}
|
}
|
||||||
foreach ($list AS $item) {
|
foreach ($list AS $item) {
|
||||||
if (empty($item['name']) || empty($item['color']) || empty($item['priority'])) {
|
if (empty($item['name']) || empty($item['color']) || empty($item['days']) || empty($item['priority'])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$array[] = [
|
$array[] = [
|
||||||
@ -150,54 +127,7 @@ class SystemController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {post} api/system/column/template 04. 创建项目模板
|
* @api {get} api/system/get/info 04. 获取终端详细信息
|
||||||
*
|
|
||||||
* @apiDescription 获取创建项目模板、保存创建项目模板
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup system
|
|
||||||
* @apiName column__template
|
|
||||||
*
|
|
||||||
* @apiParam {String} type
|
|
||||||
* - get: 获取(默认)
|
|
||||||
* - save: 保存(限管理员)
|
|
||||||
* @apiParam {Array} list 优先级数据,格式:[{name,columns}]
|
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
|
||||||
public function column__template()
|
|
||||||
{
|
|
||||||
$type = trim(Request::input('type'));
|
|
||||||
if ($type == 'save') {
|
|
||||||
User::auth('admin');
|
|
||||||
$list = Base::getPostValue('list');
|
|
||||||
$array = [];
|
|
||||||
if (empty($list) || !is_array($list)) {
|
|
||||||
return Base::retError('参数错误');
|
|
||||||
}
|
|
||||||
foreach ($list AS $item) {
|
|
||||||
if (empty($item['name']) || empty($item['columns'])) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$array[] = [
|
|
||||||
'name' => $item['name'],
|
|
||||||
'columns' => array_values(array_filter(array_unique(explode(",", $item['columns']))))
|
|
||||||
];
|
|
||||||
}
|
|
||||||
if (empty($array)) {
|
|
||||||
return Base::retError('参数为空');
|
|
||||||
}
|
|
||||||
$setting = Base::setting('columnTemplate', $array);
|
|
||||||
} else {
|
|
||||||
$setting = Base::setting('columnTemplate');
|
|
||||||
}
|
|
||||||
//
|
|
||||||
return Base::retSuccess('success', $setting);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @api {get} api/system/get/info 05. 获取终端详细信息
|
|
||||||
*
|
*
|
||||||
* @apiVersion 1.0.0
|
* @apiVersion 1.0.0
|
||||||
* @apiGroup system
|
* @apiGroup system
|
||||||
@ -226,7 +156,7 @@ class SystemController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/system/get/ip 06. 获取IP地址
|
* @api {get} api/system/get/ip 05. 获取IP地址
|
||||||
*
|
*
|
||||||
* @apiVersion 1.0.0
|
* @apiVersion 1.0.0
|
||||||
* @apiGroup system
|
* @apiGroup system
|
||||||
@ -241,7 +171,7 @@ class SystemController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/system/get/cnip 07. 是否中国IP地址
|
* @api {get} api/system/get/cnip 06. 是否中国IP地址
|
||||||
*
|
*
|
||||||
* @apiVersion 1.0.0
|
* @apiVersion 1.0.0
|
||||||
* @apiGroup system
|
* @apiGroup system
|
||||||
@ -258,7 +188,7 @@ class SystemController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/system/get/ipgcj02 08. 获取IP地址经纬度
|
* @api {get} api/system/get/ipgcj02 07. 获取IP地址经纬度
|
||||||
*
|
*
|
||||||
* @apiVersion 1.0.0
|
* @apiVersion 1.0.0
|
||||||
* @apiGroup system
|
* @apiGroup system
|
||||||
@ -275,7 +205,7 @@ class SystemController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/system/get/ipinfo 09. 获取IP地址详细信息
|
* @api {get} api/system/get/ipinfo 08. 获取IP地址详细信息
|
||||||
*
|
*
|
||||||
* @apiVersion 1.0.0
|
* @apiVersion 1.0.0
|
||||||
* @apiGroup system
|
* @apiGroup system
|
||||||
@ -292,7 +222,90 @@ class SystemController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {post} api/system/imgupload 10. 上传图片
|
* @api {get} api/system/get/appinfo 09. 获取应用下载信息
|
||||||
|
*
|
||||||
|
* @apiVersion 1.0.0
|
||||||
|
* @apiGroup system
|
||||||
|
* @apiName get__appinfo
|
||||||
|
*
|
||||||
|
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||||
|
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||||
|
* @apiSuccess {Object} data 返回数据
|
||||||
|
*/
|
||||||
|
public function get__appinfo() {
|
||||||
|
$array = [
|
||||||
|
'name' => '',
|
||||||
|
'version' => '',
|
||||||
|
'list' => [],
|
||||||
|
];
|
||||||
|
//
|
||||||
|
$files = [
|
||||||
|
base_path("package.json"),
|
||||||
|
base_path("electron/package.json")
|
||||||
|
];
|
||||||
|
$dist = base_path("electron/dist");
|
||||||
|
foreach ($files as $file) {
|
||||||
|
if (file_exists($file)) {
|
||||||
|
$packageArray = json_decode(file_get_contents($file), true);
|
||||||
|
$array['name'] = $packageArray['name'] ?? 'No app';
|
||||||
|
$array['version'] = $packageArray['version'] ?? '';
|
||||||
|
//
|
||||||
|
$list = [
|
||||||
|
[
|
||||||
|
'icon' => 'logo-apple',
|
||||||
|
'name' => 'macOS Intel',
|
||||||
|
'file' => "{$array['name']}-{$array['version']}.dmg"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'icon' => 'logo-apple',
|
||||||
|
'name' => 'macOS M1',
|
||||||
|
'file' => "{$array['name']}-{$array['version']}-arm64.dmg"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'icon' => 'logo-windows',
|
||||||
|
'name' => 'Windows x64',
|
||||||
|
'file' => "{$array['name']} Setup {$array['version']}.exe"
|
||||||
|
]
|
||||||
|
];
|
||||||
|
foreach ($list as $item) {
|
||||||
|
if (file_exists("{$dist}/{$item['file']}")) {
|
||||||
|
$item['url'] = Base::fillUrl('api/system/get/appdown?file=' . urlencode($item['file']));
|
||||||
|
$item['size'] = filesize("{$dist}/{$item['file']}");
|
||||||
|
$array['list'][] = $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count($array['list']) > 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
if (count($array['list']) == 0) {
|
||||||
|
return Base::retError('No file');
|
||||||
|
}
|
||||||
|
return Base::retSuccess('success', $array);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api {get} api/system/get/appdown 10. 下载应用
|
||||||
|
*
|
||||||
|
* @apiVersion 1.0.0
|
||||||
|
* @apiGroup system
|
||||||
|
* @apiName get__appdown
|
||||||
|
*
|
||||||
|
* @apiParam {String} file 文件名称
|
||||||
|
*/
|
||||||
|
public function get__appdown() {
|
||||||
|
$file = Request::input("file");
|
||||||
|
$path = base_path("electron/dist/" . $file);
|
||||||
|
if (!file_exists($path)) {
|
||||||
|
return Base::ajaxError("No file");
|
||||||
|
}
|
||||||
|
return Response::download($path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api {post} api/system/imgupload 11. 上传图片
|
||||||
*
|
*
|
||||||
* @apiDescription 需要token身份
|
* @apiDescription 需要token身份
|
||||||
* @apiVersion 1.0.0
|
* @apiVersion 1.0.0
|
||||||
@ -315,7 +328,7 @@ class SystemController extends AbstractController
|
|||||||
if (!$scale[0] && !$scale[1]) {
|
if (!$scale[0] && !$scale[1]) {
|
||||||
$scale = [2160, 4160, -1];
|
$scale = [2160, 4160, -1];
|
||||||
}
|
}
|
||||||
$path = "uploads/user/picture/" . User::userid() . "/" . date("Ym") . "/";
|
$path = "uploads/picture/" . User::userid() . "/" . date("Ym") . "/";
|
||||||
$image64 = trim(Base::getPostValue('image64'));
|
$image64 = trim(Base::getPostValue('image64'));
|
||||||
$fileName = trim(Base::getPostValue('filename'));
|
$fileName = trim(Base::getPostValue('filename'));
|
||||||
if ($image64) {
|
if ($image64) {
|
||||||
@ -342,7 +355,7 @@ class SystemController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/system/get/imgview 11. 浏览图片空间
|
* @api {get} api/system/get/imgview 12. 浏览图片空间
|
||||||
*
|
*
|
||||||
* @apiDescription 需要token身份
|
* @apiDescription 需要token身份
|
||||||
* @apiVersion 1.0.0
|
* @apiVersion 1.0.0
|
||||||
@ -360,7 +373,7 @@ class SystemController extends AbstractController
|
|||||||
if (User::userid() === 0) {
|
if (User::userid() === 0) {
|
||||||
return Base::retError('身份失效,等重新登录');
|
return Base::retError('身份失效,等重新登录');
|
||||||
}
|
}
|
||||||
$publicPath = "uploads/user/picture/" . User::userid() . "/";
|
$publicPath = "uploads/picture/" . User::userid() . "/";
|
||||||
$dirPath = public_path($publicPath);
|
$dirPath = public_path($publicPath);
|
||||||
$dirs = $files = [];
|
$dirs = $files = [];
|
||||||
//
|
//
|
||||||
@ -438,7 +451,7 @@ class SystemController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {post} api/system/fileupload 12. 上传文件
|
* @api {post} api/system/fileupload 13. 上传文件
|
||||||
*
|
*
|
||||||
* @apiDescription 需要token身份
|
* @apiDescription 需要token身份
|
||||||
* @apiVersion 1.0.0
|
* @apiVersion 1.0.0
|
||||||
@ -458,7 +471,7 @@ class SystemController extends AbstractController
|
|||||||
if (User::userid() === 0) {
|
if (User::userid() === 0) {
|
||||||
return Base::retError('身份失效,等重新登录');
|
return Base::retError('身份失效,等重新登录');
|
||||||
}
|
}
|
||||||
$path = "uploads/user/file/" . User::userid() . "/" . date("Ym") . "/";
|
$path = "uploads/files/" . User::userid() . "/" . date("Ym") . "/";
|
||||||
$image64 = trim(Base::getPostValue('image64'));
|
$image64 = trim(Base::getPostValue('image64'));
|
||||||
$fileName = trim(Base::getPostValue('filename'));
|
$fileName = trim(Base::getPostValue('filename'));
|
||||||
if ($image64) {
|
if ($image64) {
|
||||||
|
@ -31,7 +31,7 @@ class UsersController extends AbstractController
|
|||||||
* @apiParam {String} email 邮箱
|
* @apiParam {String} email 邮箱
|
||||||
* @apiParam {String} password 密码
|
* @apiParam {String} password 密码
|
||||||
* @apiParam {String} [code] 登录验证码
|
* @apiParam {String} [code] 登录验证码
|
||||||
* @apiParam {String} [invite] 注册邀请码
|
* @apiParam {String} [key] 登陆验证码key
|
||||||
*
|
*
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||||
@ -46,22 +46,24 @@ class UsersController extends AbstractController
|
|||||||
$setting = Base::setting('system');
|
$setting = Base::setting('system');
|
||||||
if ($setting['reg'] == 'close') {
|
if ($setting['reg'] == 'close') {
|
||||||
return Base::retError('未开放注册');
|
return Base::retError('未开放注册');
|
||||||
} elseif ($setting['reg'] == 'invite') {
|
|
||||||
$invite = trim(Request::input('invite'));
|
|
||||||
if (empty($invite) || $invite != $setting['reg_invite']) {
|
|
||||||
return Base::retError('请输入正确的邀请码');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$user = User::reg($email, $password);
|
$user = User::reg($email, $password);
|
||||||
} else {
|
} else {
|
||||||
$needCode = !Base::isError(User::needCode($email));
|
$needCode = !Base::isError(User::needCode($email));
|
||||||
if ($needCode) {
|
if ($needCode) {
|
||||||
$code = trim(Request::input('code'));
|
$code = trim(Request::input('code'));
|
||||||
|
$key = trim(Request::input('key'));
|
||||||
if (empty($code)) {
|
if (empty($code)) {
|
||||||
return Base::retError('请输入验证码', ['code' => 'need']);
|
return Base::retError('请输入验证码', ['code' => 'need']);
|
||||||
}
|
}
|
||||||
if (!Captcha::check($code)) {
|
if (empty($key)) {
|
||||||
return Base::retError('请输入正确的验证码', ['code' => 'need']);
|
if (!Captcha::check($code)) {
|
||||||
|
return Base::retError('请输入正确的验证码', ['code' => 'need']);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!Captcha::check_api($code, $key)) {
|
||||||
|
return Base::retError('请输入正确的验证码', ['code' => 'need']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
@ -153,26 +155,7 @@ class UsersController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/users/reg/needinvite 05. 是否需要邀请码
|
* @api {get} api/users/info 05. 获取我的信息
|
||||||
*
|
|
||||||
* @apiDescription 用于判断注册是否需要邀请码
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup users
|
|
||||||
* @apiName reg__needinvite
|
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
|
||||||
public function reg__needinvite()
|
|
||||||
{
|
|
||||||
return Base::retSuccess('success', [
|
|
||||||
'need' => Base::settingFind('system', 'reg') == 'invite'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @api {get} api/users/info 06. 获取我的信息
|
|
||||||
*
|
*
|
||||||
* @apiDescription 需要token身份
|
* @apiDescription 需要token身份
|
||||||
* @apiVersion 1.0.0
|
* @apiVersion 1.0.0
|
||||||
@ -208,7 +191,7 @@ class UsersController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/users/editdata 07. 修改自己的资料
|
* @api {get} api/users/editdata 06. 修改自己的资料
|
||||||
*
|
*
|
||||||
* @apiDescription 需要token身份
|
* @apiDescription 需要token身份
|
||||||
* @apiVersion 1.0.0
|
* @apiVersion 1.0.0
|
||||||
@ -235,13 +218,13 @@ class UsersController extends AbstractController
|
|||||||
$userimg = is_array($userimg) ? $userimg[0]['path'] : $userimg;
|
$userimg = is_array($userimg) ? $userimg[0]['path'] : $userimg;
|
||||||
$user->userimg = Base::unFillUrl($userimg);
|
$user->userimg = Base::unFillUrl($userimg);
|
||||||
} else {
|
} else {
|
||||||
$user->userimg = $user->getUserimgAttribute(null);
|
$user->userimg = '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//昵称
|
//昵称
|
||||||
if (Arr::exists($data, 'nickname')) {
|
if (Arr::exists($data, 'nickname')) {
|
||||||
$nickname = trim(Request::input('nickname'));
|
$nickname = trim(Request::input('nickname'));
|
||||||
if ($nickname && mb_strlen($nickname) < 2) {
|
if (mb_strlen($nickname) < 2) {
|
||||||
return Base::retError('昵称不可以少于2个字');
|
return Base::retError('昵称不可以少于2个字');
|
||||||
} elseif (mb_strlen($nickname) > 20) {
|
} elseif (mb_strlen($nickname) > 20) {
|
||||||
return Base::retError('昵称最多只能设置20个字');
|
return Base::retError('昵称最多只能设置20个字');
|
||||||
@ -252,7 +235,7 @@ class UsersController extends AbstractController
|
|||||||
//职位/职称
|
//职位/职称
|
||||||
if (Arr::exists($data, 'profession')) {
|
if (Arr::exists($data, 'profession')) {
|
||||||
$profession = trim(Request::input('profession'));
|
$profession = trim(Request::input('profession'));
|
||||||
if ($profession && mb_strlen($profession) < 2) {
|
if (mb_strlen($profession) < 2) {
|
||||||
return Base::retError('职位/职称不可以少于2个字');
|
return Base::retError('职位/职称不可以少于2个字');
|
||||||
} elseif (mb_strlen($profession) > 20) {
|
} elseif (mb_strlen($profession) > 20) {
|
||||||
return Base::retError('职位/职称最多只能设置20个字');
|
return Base::retError('职位/职称最多只能设置20个字');
|
||||||
@ -268,7 +251,7 @@ class UsersController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/users/editpass 08. 修改自己的密码
|
* @api {get} api/users/editpass 07. 修改自己的密码
|
||||||
*
|
*
|
||||||
* @apiDescription 需要token身份
|
* @apiDescription 需要token身份
|
||||||
* @apiVersion 1.0.0
|
* @apiVersion 1.0.0
|
||||||
@ -308,7 +291,7 @@ class UsersController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/users/search 09. 搜索会员列表
|
* @api {get} api/users/search 08. 搜索会员列表
|
||||||
*
|
*
|
||||||
* @apiDescription 搜索会员列表
|
* @apiDescription 搜索会员列表
|
||||||
* @apiVersion 1.0.0
|
* @apiVersion 1.0.0
|
||||||
@ -316,12 +299,11 @@ class UsersController extends AbstractController
|
|||||||
* @apiName searchinfo
|
* @apiName searchinfo
|
||||||
*
|
*
|
||||||
* @apiParam {Object} keys 搜索条件
|
* @apiParam {Object} keys 搜索条件
|
||||||
* - keys.key 昵称、邮箱关键字
|
* - keys.key 昵称、邮箱
|
||||||
* - keys.disable 0-排除禁止(默认),1-含禁止,2-仅禁止
|
|
||||||
* - keys.project_id 在指定项目ID
|
* - keys.project_id 在指定项目ID
|
||||||
* - keys.no_project_id 不在指定项目ID
|
* - keys.no_project_id 不在指定项目ID
|
||||||
* @apiParam {Object} sorts 排序方式
|
* @apiParam {Object} sorts 排序方式
|
||||||
* - sorts.az 按字母:asc|desc
|
* - sorts.az 字母
|
||||||
*
|
*
|
||||||
* @apiParam {Number} [take] 获取数量,10-100
|
* @apiParam {Number} [take] 获取数量,10-100
|
||||||
* @apiParam {Number} [page] 当前页,默认:1(赋值分页模式,take参数无效)
|
* @apiParam {Number} [page] 当前页,默认:1(赋值分页模式,take参数无效)
|
||||||
@ -337,32 +319,28 @@ class UsersController extends AbstractController
|
|||||||
//
|
//
|
||||||
$keys = Request::input('keys');
|
$keys = Request::input('keys');
|
||||||
$sorts = Request::input('sorts');
|
$sorts = Request::input('sorts');
|
||||||
$keys = is_array($keys) ? $keys : [];
|
if (is_array($keys)) {
|
||||||
$sorts = is_array($sorts) ? $sorts : [];
|
if ($keys['key']) {
|
||||||
//
|
$builder->where(function($query) use ($keys) {
|
||||||
if ($keys['key']) {
|
$query->where("email", "like", "%{$keys['key']}%")
|
||||||
$builder->where(function($query) use ($keys) {
|
->orWhere("nickname", "like", "%{$keys['key']}%");
|
||||||
$query->where("email", "like", "%{$keys['key']}%")
|
});
|
||||||
->orWhere("nickname", "like", "%{$keys['key']}%");
|
}
|
||||||
});
|
if (intval($keys['project_id']) > 0) {
|
||||||
|
$builder->whereIn('userid', function ($query) use ($keys) {
|
||||||
|
$query->select('userid')->from('project_users')->where('project_id', $keys['project_id']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (intval($keys['no_project_id']) > 0) {
|
||||||
|
$builder->whereNotIn('userid', function ($query) use ($keys) {
|
||||||
|
$query->select('userid')->from('project_users')->where('project_id', $keys['no_project_id']);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (intval($keys['disable']) == 0) {
|
if (is_array($sorts)) {
|
||||||
$builder->whereNull("disable_at");
|
if (in_array($sorts['az'], ['asc', 'desc'])) {
|
||||||
} elseif (intval($keys['disable']) == 2) {
|
$builder->orderBy('az', $sorts['az']);
|
||||||
$builder->whereNotNull("disable_at");
|
}
|
||||||
}
|
|
||||||
if (intval($keys['project_id']) > 0) {
|
|
||||||
$builder->whereIn('userid', function ($query) use ($keys) {
|
|
||||||
$query->select('userid')->from('project_users')->where('project_id', $keys['project_id']);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (intval($keys['no_project_id']) > 0) {
|
|
||||||
$builder->whereNotIn('userid', function ($query) use ($keys) {
|
|
||||||
$query->select('userid')->from('project_users')->where('project_id', $keys['no_project_id']);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (in_array($sorts['az'], ['asc', 'desc'])) {
|
|
||||||
$builder->orderBy('az', $sorts['az']);
|
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
if (Request::exists('page')) {
|
if (Request::exists('page')) {
|
||||||
@ -374,7 +352,7 @@ class UsersController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/users/basic 10. 获取指定会员基础信息
|
* @api {get} api/users/basic 09. 获取指定会员基础信息
|
||||||
*
|
*
|
||||||
* @apiDescription 需要token身份
|
* @apiDescription 需要token身份
|
||||||
* @apiVersion 1.0.0
|
* @apiVersion 1.0.0
|
||||||
@ -408,12 +386,7 @@ class UsersController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/users/lists 11. 会员列表(限管理员)
|
* 会员列表(限管理员)
|
||||||
*
|
|
||||||
* @apiDescription 需要token身份
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup users
|
|
||||||
* @apiName lists
|
|
||||||
*
|
*
|
||||||
* @apiParam {Object} [keys] 搜索条件
|
* @apiParam {Object} [keys] 搜索条件
|
||||||
* - keys.email 邮箱
|
* - keys.email 邮箱
|
||||||
@ -421,10 +394,6 @@ class UsersController extends AbstractController
|
|||||||
* - keys.profession 职位
|
* - keys.profession 职位
|
||||||
* @apiParam {Number} [page] 当前页,默认:1
|
* @apiParam {Number} [page] 当前页,默认:1
|
||||||
* @apiParam {Number} [pagesize] 每页显示数量,默认:20,最大:50
|
* @apiParam {Number} [pagesize] 每页显示数量,默认:20,最大:50
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
*/
|
||||||
public function lists()
|
public function lists()
|
||||||
{
|
{
|
||||||
@ -457,12 +426,7 @@ class UsersController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} api/users/operation 12. 操作会员(限管理员)
|
* 操作会员(限管理员)
|
||||||
*
|
|
||||||
* @apiDescription 需要token身份
|
|
||||||
* @apiVersion 1.0.0
|
|
||||||
* @apiGroup users
|
|
||||||
* @apiName operation
|
|
||||||
*
|
*
|
||||||
* @apiParam {Number} userid 会员ID
|
* @apiParam {Number} userid 会员ID
|
||||||
* @apiParam {String} [type] 操作
|
* @apiParam {String} [type] 操作
|
||||||
@ -474,10 +438,6 @@ class UsersController extends AbstractController
|
|||||||
* @apiParam {String} [password] 新的密码
|
* @apiParam {String} [password] 新的密码
|
||||||
* @apiParam {String} [nickname] 昵称
|
* @apiParam {String} [nickname] 昵称
|
||||||
* @apiParam {String} [profession] 职位
|
* @apiParam {String} [profession] 职位
|
||||||
*
|
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
|
||||||
* @apiSuccess {Object} data 返回数据
|
|
||||||
*/
|
*/
|
||||||
public function operation()
|
public function operation()
|
||||||
{
|
{
|
||||||
@ -507,12 +467,10 @@ class UsersController extends AbstractController
|
|||||||
case 'setdisable':
|
case 'setdisable':
|
||||||
$upArray['identity'] = array_diff($userInfo->identity, ['disable']);
|
$upArray['identity'] = array_diff($userInfo->identity, ['disable']);
|
||||||
$upArray['identity'][] = 'disable';
|
$upArray['identity'][] = 'disable';
|
||||||
$upArray['disable_at'] = Carbon::now();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'cleardisable':
|
case 'cleardisable':
|
||||||
$upArray['identity'] = array_diff($userInfo->identity, ['disable']);
|
$upArray['identity'] = array_diff($userInfo->identity, ['disable']);
|
||||||
$upArray['disable_at'] = null;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'delete':
|
case 'delete':
|
||||||
@ -533,7 +491,7 @@ class UsersController extends AbstractController
|
|||||||
// 昵称
|
// 昵称
|
||||||
if (Arr::exists($data, 'nickname')) {
|
if (Arr::exists($data, 'nickname')) {
|
||||||
$nickname = trim($data['nickname']);
|
$nickname = trim($data['nickname']);
|
||||||
if ($nickname && mb_strlen($nickname) < 2) {
|
if (mb_strlen($nickname) < 2) {
|
||||||
return Base::retError('昵称不可以少于2个字');
|
return Base::retError('昵称不可以少于2个字');
|
||||||
} elseif (mb_strlen($nickname) > 20) {
|
} elseif (mb_strlen($nickname) > 20) {
|
||||||
return Base::retError('昵称最多只能设置20个字');
|
return Base::retError('昵称最多只能设置20个字');
|
||||||
@ -544,7 +502,7 @@ class UsersController extends AbstractController
|
|||||||
// 职位/职称
|
// 职位/职称
|
||||||
if (Arr::exists($data, 'profession')) {
|
if (Arr::exists($data, 'profession')) {
|
||||||
$profession = trim($data['profession']);
|
$profession = trim($data['profession']);
|
||||||
if ($profession && mb_strlen($profession) < 2) {
|
if (mb_strlen($profession) < 2) {
|
||||||
return Base::retError('职位/职称不可以少于2个字');
|
return Base::retError('职位/职称不可以少于2个字');
|
||||||
} elseif (mb_strlen($profession) > 20) {
|
} elseif (mb_strlen($profession) > 20) {
|
||||||
return Base::retError('职位/职称最多只能设置20个字');
|
return Base::retError('职位/职称最多只能设置20个字');
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* 给apidoc项目增加顺序编号
|
* 给apidoc项目增加顺序编号
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
|
error_reporting(E_ALL & ~E_NOTICE);
|
||||||
|
|
||||||
$path = dirname(__FILE__). '/';
|
$path = dirname(__FILE__). '/';
|
||||||
$lists = scandir($path);
|
$lists = scandir($path);
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Module\Base;
|
use App\Module\Base;
|
||||||
use App\Tasks\AutoArchivedTask;
|
|
||||||
use App\Tasks\DeleteTmpTask;
|
use App\Tasks\DeleteTmpTask;
|
||||||
use Hhxsv5\LaravelS\Swoole\Task\Task;
|
use Hhxsv5\LaravelS\Swoole\Task\Task;
|
||||||
use Redirect;
|
use Redirect;
|
||||||
@ -59,8 +58,6 @@ class IndexController extends InvokeController
|
|||||||
// 删除过期的临时表数据
|
// 删除过期的临时表数据
|
||||||
Task::deliver(new DeleteTmpTask('wg_tmp_msgs', 1));
|
Task::deliver(new DeleteTmpTask('wg_tmp_msgs', 1));
|
||||||
Task::deliver(new DeleteTmpTask('tmp', 24));
|
Task::deliver(new DeleteTmpTask('tmp', 24));
|
||||||
// 自动归档任务
|
|
||||||
Task::deliver(new AutoArchivedTask());
|
|
||||||
|
|
||||||
return "success";
|
return "success";
|
||||||
}
|
}
|
||||||
|
@ -21,20 +21,14 @@ class VerifyCsrfToken extends Middleware
|
|||||||
// 保存任务优先级
|
// 保存任务优先级
|
||||||
'api/system/priority/',
|
'api/system/priority/',
|
||||||
|
|
||||||
// 保存创建项目列表模板
|
|
||||||
'api/system/column/template/',
|
|
||||||
|
|
||||||
// 添加任务
|
// 添加任务
|
||||||
'api/project/task/add/',
|
'api/project/task/add/',
|
||||||
|
|
||||||
// 保存工作流
|
|
||||||
'api/project/flow/save/',
|
|
||||||
|
|
||||||
// 修改任务
|
// 修改任务
|
||||||
'api/project/task/update/',
|
'api/project/task/update/',
|
||||||
|
|
||||||
// 聊天发文本
|
// 上传任务问题
|
||||||
'api/dialog/msg/sendtext/',
|
'api/project/task/upload/',
|
||||||
|
|
||||||
// 聊天发文件
|
// 聊天发文件
|
||||||
'api/dialog/msg/sendfile/',
|
'api/dialog/msg/sendfile/',
|
||||||
@ -47,8 +41,5 @@ class VerifyCsrfToken extends Middleware
|
|||||||
|
|
||||||
// 保存文件内容(上传)
|
// 保存文件内容(上传)
|
||||||
'api/file/content/upload/',
|
'api/file/content/upload/',
|
||||||
|
|
||||||
// 保存汇报
|
|
||||||
'api/report/store/',
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,6 @@ use Illuminate\Support\Facades\DB;
|
|||||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel query()
|
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel query()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel saveOrIgnore()
|
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel saveOrIgnore()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel getKeyValue()
|
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel getKeyValue()
|
||||||
* @method static \Illuminate\Database\Eloquent\Model|object|static|null cancelAppend()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Model|object|static|null cancelHidden()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|static with($relations)
|
* @method static \Illuminate\Database\Eloquent\Builder|static with($relations)
|
||||||
* @method static \Illuminate\Database\Query\Builder|static select($columns = [])
|
* @method static \Illuminate\Database\Query\Builder|static select($columns = [])
|
||||||
* @method static \Illuminate\Database\Query\Builder|static whereNotIn($column, $values, $boolean = 'and')
|
* @method static \Illuminate\Database\Query\Builder|static whereNotIn($column, $values, $boolean = 'and')
|
||||||
@ -64,24 +62,6 @@ class AbstractModel extends Model
|
|||||||
return $this->$key;
|
return $this->$key;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 取消附加值
|
|
||||||
* @return static
|
|
||||||
*/
|
|
||||||
protected function scopeCancelAppend()
|
|
||||||
{
|
|
||||||
return $this->setAppends([]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 取消隐藏值
|
|
||||||
* @return static
|
|
||||||
*/
|
|
||||||
protected function scopeCancelHidden()
|
|
||||||
{
|
|
||||||
return $this->setHidden([]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 为数组 / JSON 序列化准备日期。
|
* 为数组 / JSON 序列化准备日期。
|
||||||
* @param DateTimeInterface $date
|
* @param DateTimeInterface $date
|
||||||
@ -153,23 +133,16 @@ class AbstractModel extends Model
|
|||||||
* @param $where
|
* @param $where
|
||||||
* @param array $update 存在时更新的内容
|
* @param array $update 存在时更新的内容
|
||||||
* @param array $insert 不存在时插入的内容,如果没有则插入更新内容
|
* @param array $insert 不存在时插入的内容,如果没有则插入更新内容
|
||||||
* @param bool $isInsert 是否是插入数据
|
|
||||||
* @return AbstractModel|\Illuminate\Database\Eloquent\Builder|Model|object|static|null
|
* @return AbstractModel|\Illuminate\Database\Eloquent\Builder|Model|object|static|null
|
||||||
*/
|
*/
|
||||||
public static function updateInsert($where, $update = [], $insert = [], &$isInsert = true)
|
public static function updateInsert($where, $update = [], $insert = [])
|
||||||
{
|
{
|
||||||
$row = static::where($where)->first();
|
$row = static::where($where)->first();
|
||||||
if (empty($row)) {
|
if (empty($row)) {
|
||||||
$row = new static;
|
$row = new static;
|
||||||
$array = array_merge($where, $insert ?: $update);
|
$row->updateInstance(array_merge($where, $insert ?: $update));
|
||||||
if (isset($array[$row->primaryKey])) {
|
|
||||||
unset($array[$row->primaryKey]);
|
|
||||||
}
|
|
||||||
$row->updateInstance($array);
|
|
||||||
$isInsert = true;
|
|
||||||
} elseif ($update) {
|
} elseif ($update) {
|
||||||
$row->updateInstance($update);
|
$row->updateInstance($update);
|
||||||
$isInsert = false;
|
|
||||||
}
|
}
|
||||||
if (!$row->save()) {
|
if (!$row->save()) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -51,61 +51,43 @@ class File extends AbstractModel
|
|||||||
use SoftDeletes;
|
use SoftDeletes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件文件
|
* 是否有访问权限(没有时抛出异常)
|
||||||
|
* @param $userid
|
||||||
*/
|
*/
|
||||||
const codeExt = [
|
public function exceAllow($userid)
|
||||||
'txt',
|
{
|
||||||
'htaccess', 'htgroups', 'htpasswd', 'conf', 'bat', 'cmd', 'cpp', 'c', 'cc', 'cxx', 'h', 'hh', 'hpp', 'ino', 'cs', 'css',
|
if (!$this->chackAllow($userid)) {
|
||||||
'dockerfile', 'go', 'html', 'htm', 'xhtml', 'vue', 'we', 'wpy', 'java', 'js', 'jsm', 'jsx', 'json', 'jsp', 'less', 'lua', 'makefile', 'gnumakefile',
|
throw new ApiException('没有访问权限');
|
||||||
'ocamlmakefile', 'make', 'mysql', 'nginx', 'ini', 'cfg', 'prefs', 'm', 'mm', 'pl', 'pm', 'p6', 'pl6', 'pm6', 'pgsql', 'php',
|
}
|
||||||
'inc', 'phtml', 'shtml', 'php3', 'php4', 'php5', 'phps', 'phpt', 'aw', 'ctp', 'module', 'ps1', 'py', 'r', 'rb', 'ru', 'gemspec', 'rake', 'guardfile', 'rakefile',
|
}
|
||||||
'gemfile', 'rs', 'sass', 'scss', 'sh', 'bash', 'bashrc', 'sql', 'sqlserver', 'swift', 'ts', 'typescript', 'str', 'vbs', 'vb', 'v', 'vh', 'sv', 'svh', 'xml',
|
|
||||||
'rdf', 'rss', 'wsdl', 'xslt', 'atom', 'mathml', 'mml', 'xul', 'xbl', 'xaml', 'yaml', 'yml',
|
|
||||||
'asp', 'properties', 'gitignore', 'log', 'bas', 'prg', 'python', 'ftl', 'aspx'
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* office文件
|
|
||||||
*/
|
|
||||||
const officeExt = [
|
|
||||||
'doc', 'docx',
|
|
||||||
'xls', 'xlsx',
|
|
||||||
'ppt', 'pptx',
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 本地媒体文件
|
|
||||||
*/
|
|
||||||
const localExt = [
|
|
||||||
'jpg', 'jpeg', 'png', 'gif', 'bmp', 'ico', 'raw',
|
|
||||||
'tif', 'tiff',
|
|
||||||
'mp3', 'wav', 'mp4', 'flv',
|
|
||||||
'avi', 'mov', 'wmv', 'mkv', '3gp', 'rm',
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否有访问权限
|
* 是否有访问权限
|
||||||
|
* ① 自己的文件夹
|
||||||
|
* ② 共享所有人的文件夹
|
||||||
|
* ③ 在指定共享人员内
|
||||||
* @param $userid
|
* @param $userid
|
||||||
* @return int -1:没有权限,0:访问权限,1:读写权限,1000:所有者或创建者
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function getPermission($userid)
|
public function chackAllow($userid)
|
||||||
{
|
{
|
||||||
if ($userid == $this->userid || $userid == $this->created_id) {
|
if ($userid == $this->userid) {
|
||||||
// ① 自己的文件夹 或 自己创建的文件夹
|
// ① 自己的文件夹
|
||||||
return 1000;
|
return true;
|
||||||
}
|
}
|
||||||
$row = $this->getShareInfo();
|
$row = $this->getShareInfo();
|
||||||
if ($row) {
|
if ($row) {
|
||||||
$fileUser = FileUser::whereFileId($row->id)->where(function ($query) use ($userid) {
|
if ($row->share == 1) {
|
||||||
$query->where('userid', 0);
|
// ② 共享所有人的文件夹
|
||||||
$query->orWhere('userid', $userid);
|
return true;
|
||||||
})->orderByDesc('permission')->first();
|
} elseif ($row->share == 2) {
|
||||||
if ($fileUser) {
|
// ③ 在指定共享人员内
|
||||||
// ② 在指定共享成员内
|
if (FileUser::whereFileId($row->id)->whereUserid($userid)->exists()) {
|
||||||
return $fileUser->permission;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -114,7 +96,7 @@ class File extends AbstractModel
|
|||||||
*/
|
*/
|
||||||
public function getShareInfo()
|
public function getShareInfo()
|
||||||
{
|
{
|
||||||
if ($this->share) {
|
if ($this->share > 0) {
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
$pid = $this->pid;
|
$pid = $this->pid;
|
||||||
@ -123,7 +105,7 @@ class File extends AbstractModel
|
|||||||
if (empty($row)) {
|
if (empty($row)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ($row->share) {
|
if ($row->share > 0) {
|
||||||
return $row;
|
return $row;
|
||||||
}
|
}
|
||||||
$pid = $row->pid;
|
$pid = $row->pid;
|
||||||
@ -143,7 +125,7 @@ class File extends AbstractModel
|
|||||||
if (empty($row)) {
|
if (empty($row)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ($row->share) {
|
if ($row->share > 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
$pid = $row->pid;
|
$pid = $row->pid;
|
||||||
@ -156,23 +138,18 @@ class File extends AbstractModel
|
|||||||
* @param $share
|
* @param $share
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function setShare($share = null)
|
public function setShare($share)
|
||||||
{
|
{
|
||||||
if ($share === null) {
|
AbstractModel::transaction(function () use ($share) {
|
||||||
$share = FileUser::whereFileId($this->id)->count() == 0 ? 0 : 1;
|
$this->share = $share;
|
||||||
}
|
$this->save();
|
||||||
if ($this->share != $share) {
|
$list = self::wherePid($this->id)->get();
|
||||||
AbstractModel::transaction(function () use ($share) {
|
if ($list->isNotEmpty()) {
|
||||||
$this->share = $share;
|
foreach ($list as $item) {
|
||||||
$this->save();
|
$item->setShare(0);
|
||||||
$list = self::wherePid($this->id)->get();
|
|
||||||
if ($list->isNotEmpty()) {
|
|
||||||
foreach ($list as $item) {
|
|
||||||
$item->setShare(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,8 +162,6 @@ class File extends AbstractModel
|
|||||||
AbstractModel::transaction(function () {
|
AbstractModel::transaction(function () {
|
||||||
$this->delete();
|
$this->delete();
|
||||||
$this->pushMsg('delete');
|
$this->pushMsg('delete');
|
||||||
FileLink::whereFileId($this->id)->delete();
|
|
||||||
FileUser::whereFileId($this->id)->delete();
|
|
||||||
FileContent::whereFid($this->id)->delete();
|
FileContent::whereFid($this->id)->delete();
|
||||||
$list = self::wherePid($this->id)->get();
|
$list = self::wherePid($this->id)->get();
|
||||||
if ($list->isNotEmpty()) {
|
if ($list->isNotEmpty()) {
|
||||||
@ -250,99 +225,16 @@ class File extends AbstractModel
|
|||||||
/**
|
/**
|
||||||
* 获取文件并检测权限
|
* 获取文件并检测权限
|
||||||
* @param $id
|
* @param $id
|
||||||
* @param int $limit 要求权限: 0-访问权限、1-读写权限、1000-所有者或创建者
|
* @param null $noExistTis
|
||||||
* @param $permission
|
|
||||||
* @return File
|
* @return File
|
||||||
*/
|
*/
|
||||||
public static function permissionFind($id, $limit = 0, &$permission = -1)
|
public static function allowFind($id, $noExistTis = null)
|
||||||
{
|
{
|
||||||
$file = File::find($id);
|
$file = File::find($id);
|
||||||
if (empty($file)) {
|
if (empty($file)) {
|
||||||
throw new ApiException('文件不存在或已被删除');
|
throw new ApiException($noExistTis ?: '文件不存在或已被删除');
|
||||||
}
|
|
||||||
//
|
|
||||||
$permission = $file->getPermission(User::userid());
|
|
||||||
if ($permission < $limit) {
|
|
||||||
$msg = match ($limit) {
|
|
||||||
1000 => '仅限所有者或创建者操作',
|
|
||||||
1 => '没有读写权限',
|
|
||||||
default => '没有访问权限',
|
|
||||||
};
|
|
||||||
throw new ApiException($msg);
|
|
||||||
}
|
}
|
||||||
|
$file->exceAllow(User::userid());
|
||||||
return $file;
|
return $file;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 格式化内容数据
|
|
||||||
* @param array $data [path, size, ext, name]
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public static function formatFileData(array $data)
|
|
||||||
{
|
|
||||||
$filePath = $data['path'];
|
|
||||||
$fileSize = $data['size'];
|
|
||||||
$fileExt = $data['ext'];
|
|
||||||
$fileDotExt = '.' . $fileExt;
|
|
||||||
$fileName = Base::rightDelete($data['name'], $fileDotExt) . $fileDotExt;
|
|
||||||
$publicPath = public_path($filePath);
|
|
||||||
//
|
|
||||||
switch ($fileExt) {
|
|
||||||
case 'md':
|
|
||||||
case 'text':
|
|
||||||
// 文本
|
|
||||||
$data['content'] = [
|
|
||||||
'type' => $fileExt,
|
|
||||||
'content' => file_get_contents($publicPath),
|
|
||||||
];
|
|
||||||
$data['file_mode'] = $fileExt;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'drawio':
|
|
||||||
// 图表
|
|
||||||
$data['content'] = [
|
|
||||||
'xml' => file_get_contents($publicPath)
|
|
||||||
];
|
|
||||||
$data['file_mode'] = $fileExt;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'mind':
|
|
||||||
// 思维导图
|
|
||||||
$data['content'] = Base::json2array(file_get_contents($publicPath));
|
|
||||||
$data['file_mode'] = $fileExt;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
if (in_array($fileExt, self::codeExt) && $fileSize < 2 * 1024 * 1024)
|
|
||||||
{
|
|
||||||
// 文本预览,限制2M内的文件
|
|
||||||
$data['content'] = file_get_contents($publicPath);
|
|
||||||
$data['file_mode'] = 'code';
|
|
||||||
}
|
|
||||||
elseif (in_array($fileExt, File::officeExt))
|
|
||||||
{
|
|
||||||
// office预览
|
|
||||||
$data['content'] = '';
|
|
||||||
$data['file_mode'] = 'office';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 其他预览
|
|
||||||
if (in_array($fileExt, File::localExt)) {
|
|
||||||
$url = Base::fillUrl($filePath);
|
|
||||||
} else {
|
|
||||||
$url = 'http://' . env('APP_IPPR') . '.3/' . $filePath;
|
|
||||||
}
|
|
||||||
$data['content'] = [
|
|
||||||
'preview' => true,
|
|
||||||
'url' => base64_encode(Base::urlAddparameter($url, [
|
|
||||||
'fullfilename' => $fileName
|
|
||||||
])),
|
|
||||||
];
|
|
||||||
$data['file_mode'] = 'preview';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,9 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
|||||||
use Response;
|
use Response;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App\Models\FileContent
|
* Class FileContent
|
||||||
*
|
*
|
||||||
|
* @package App\Models
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property int|null $fid 文件ID
|
* @property int|null $fid 文件ID
|
||||||
* @property string|null $content 内容
|
* @property string|null $content 内容
|
||||||
@ -41,53 +42,43 @@ class FileContent extends AbstractModel
|
|||||||
use SoftDeletes;
|
use SoftDeletes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取格式内容(或下载)
|
* 获取格式内容
|
||||||
* @param File $file
|
* @param $type
|
||||||
* @param $content
|
* @param $content
|
||||||
* @param $download
|
|
||||||
* @return array|\Symfony\Component\HttpFoundation\BinaryFileResponse
|
* @return array|\Symfony\Component\HttpFoundation\BinaryFileResponse
|
||||||
*/
|
*/
|
||||||
public static function formatContent($file, $content, $download = false)
|
public static function formatContent($type, $content)
|
||||||
{
|
{
|
||||||
$name = $file->ext ? "{$file->name}.{$file->ext}" : null;
|
$content = Base::json2array($content);
|
||||||
$content = Base::json2array($content ?: []);
|
if (in_array($type, ['word', 'excel', 'ppt'])) {
|
||||||
if (in_array($file->type, ['word', 'excel', 'ppt'])) {
|
|
||||||
if (empty($content)) {
|
if (empty($content)) {
|
||||||
return Response::download(resource_path('assets/statics/office/empty.' . str_replace(['word', 'excel', 'ppt'], ['docx', 'xlsx', 'pptx'], $file->type)), $name);
|
return Response::download(resource_path('assets/statics/office/empty.' . str_replace(['word', 'excel', 'ppt'], ['docx', 'xlsx', 'pptx'], $type)));
|
||||||
}
|
}
|
||||||
return Response::download(public_path($content['url']), $name);
|
return Response::download(public_path($content['url']));
|
||||||
}
|
}
|
||||||
if (empty($content)) {
|
if (empty($content)) {
|
||||||
$content = match ($file->type) {
|
$content = match ($type) {
|
||||||
'document' => [
|
'document' => [
|
||||||
"type" => $file->ext,
|
"type" => "md",
|
||||||
"content" => "",
|
"content" => "",
|
||||||
],
|
],
|
||||||
|
'sheet' => [
|
||||||
|
[
|
||||||
|
"name" => "Sheet1",
|
||||||
|
"config" => json_decode('{}'),
|
||||||
|
]
|
||||||
|
],
|
||||||
default => json_decode('{}'),
|
default => json_decode('{}'),
|
||||||
};
|
};
|
||||||
if ($download) {
|
|
||||||
abort(403, "This file is empty.");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
$path = $content['url'];
|
$content['preview'] = false;
|
||||||
if ($file->ext) {
|
if ($content['ext'] && !in_array($content['ext'], ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'])) {
|
||||||
$res = File::formatFileData([
|
$url = 'http://' . env('APP_IPPR') . '.3/' . $content['url'];
|
||||||
'path' => $path,
|
if ($type == 'image') {
|
||||||
'ext' => $file->ext,
|
$url = Base::fillUrl($content['url']);
|
||||||
'size' => $file->size,
|
|
||||||
'name' => $file->name,
|
|
||||||
]);
|
|
||||||
$content = $res['content'];
|
|
||||||
} else {
|
|
||||||
$content['preview'] = false;
|
|
||||||
}
|
|
||||||
if ($download) {
|
|
||||||
$filePath = public_path($path);
|
|
||||||
if (isset($filePath)) {
|
|
||||||
return Response::download($filePath, $name);
|
|
||||||
} else {
|
|
||||||
abort(403, "This file not support download.");
|
|
||||||
}
|
}
|
||||||
|
$content['url'] = base64_encode($url);
|
||||||
|
$content['preview'] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Base::retSuccess('success', [ 'content' => $content ]);
|
return Base::retSuccess('success', [ 'content' => $content ]);
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* App\Models\FileLink
|
|
||||||
*
|
|
||||||
* @property int $id
|
|
||||||
* @property int|null $file_id 项目ID
|
|
||||||
* @property int|null $num 累计访问
|
|
||||||
* @property string|null $code 链接码
|
|
||||||
* @property \Illuminate\Support\Carbon|null $created_at
|
|
||||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
|
||||||
* @property-read \App\Models\File|null $file
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|FileLink newModelQuery()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|FileLink newQuery()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|FileLink query()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|FileLink whereCode($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|FileLink whereCreatedAt($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|FileLink whereFileId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|FileLink whereId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|FileLink whereNum($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|FileLink whereUpdatedAt($value)
|
|
||||||
* @mixin \Eloquent
|
|
||||||
*/
|
|
||||||
class FileLink extends AbstractModel
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
|
||||||
*/
|
|
||||||
public function file(): \Illuminate\Database\Eloquent\Relations\HasOne
|
|
||||||
{
|
|
||||||
return $this->hasOne(File::class, 'id', 'file_id');
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,12 +4,12 @@ namespace App\Models;
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App\Models\FileUser
|
* Class FileUser
|
||||||
*
|
*
|
||||||
|
* @package App\Models
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property int|null $file_id 项目ID
|
* @property int|null $file_id 项目ID
|
||||||
* @property int|null $userid 成员ID
|
* @property int|null $userid 成员ID
|
||||||
* @property int|null $permission 权限:0只读,1读写
|
|
||||||
* @property \Illuminate\Support\Carbon|null $created_at
|
* @property \Illuminate\Support\Carbon|null $created_at
|
||||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|FileUser newModelQuery()
|
* @method static \Illuminate\Database\Eloquent\Builder|FileUser newModelQuery()
|
||||||
@ -18,7 +18,6 @@ namespace App\Models;
|
|||||||
* @method static \Illuminate\Database\Eloquent\Builder|FileUser whereCreatedAt($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|FileUser whereCreatedAt($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|FileUser whereFileId($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|FileUser whereFileId($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|FileUser whereId($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|FileUser whereId($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|FileUser wherePermission($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|FileUser whereUpdatedAt($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|FileUser whereUpdatedAt($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|FileUser whereUserid($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|FileUser whereUserid($value)
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
|
@ -3,36 +3,40 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use App\Exceptions\ApiException;
|
use App\Exceptions\ApiException;
|
||||||
use App\Module\Base;
|
|
||||||
use App\Tasks\PushTask;
|
use App\Tasks\PushTask;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use DB;
|
|
||||||
use Hhxsv5\LaravelS\Swoole\Task\Task;
|
use Hhxsv5\LaravelS\Swoole\Task\Task;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
use Request;
|
use Request;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App\Models\Project
|
* Class Project
|
||||||
*
|
*
|
||||||
|
* @package App\Models
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property string|null $name 名称
|
* @property string|null $name 名称
|
||||||
* @property string|null $desc 描述、备注
|
* @property string|null $desc 描述、备注
|
||||||
* @property int|null $userid 创建人
|
* @property int|null $userid 创建人
|
||||||
* @property int|null $dialog_id 聊天会话ID
|
* @property int|mixed $dialog_id 聊天会话ID
|
||||||
* @property string|null $archived_at 归档时间
|
* @property string|null $archived_at 归档时间
|
||||||
* @property int|null $archived_userid 归档会员
|
* @property int|null $archived_userid 归档会员
|
||||||
* @property \Illuminate\Support\Carbon|null $created_at
|
* @property \Illuminate\Support\Carbon|null $created_at
|
||||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||||
* @property \Illuminate\Support\Carbon|null $deleted_at
|
* @property \Illuminate\Support\Carbon|null $deleted_at
|
||||||
* @property-read int $owner_userid
|
* @property-read int $owner_userid
|
||||||
|
* @property-read int $task_complete
|
||||||
|
* @property-read int $task_my_complete
|
||||||
|
* @property-read int $task_my_num
|
||||||
|
* @property-read int $task_my_percent
|
||||||
|
* @property-read int $task_num
|
||||||
|
* @property-read int $task_percent
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectColumn[] $projectColumn
|
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectColumn[] $projectColumn
|
||||||
* @property-read int|null $project_column_count
|
* @property-read int|null $project_column_count
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectLog[] $projectLog
|
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectLog[] $projectLog
|
||||||
* @property-read int|null $project_log_count
|
* @property-read int|null $project_log_count
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectUser[] $projectUser
|
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectUser[] $projectUser
|
||||||
* @property-read int|null $project_user_count
|
* @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)
|
||||||
* @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 newModelQuery()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|Project newQuery()
|
* @method static \Illuminate\Database\Eloquent\Builder|Project newQuery()
|
||||||
* @method static \Illuminate\Database\Query\Builder|Project onlyTrashed()
|
* @method static \Illuminate\Database\Query\Builder|Project onlyTrashed()
|
||||||
@ -55,14 +59,99 @@ class Project extends AbstractModel
|
|||||||
{
|
{
|
||||||
use SoftDeletes;
|
use SoftDeletes;
|
||||||
|
|
||||||
protected $hidden = [
|
const projectSelect = [
|
||||||
'deleted_at',
|
'projects.*',
|
||||||
|
'project_users.owner',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $appends = [
|
protected $appends = [
|
||||||
|
'task_num',
|
||||||
|
'task_complete',
|
||||||
|
'task_percent',
|
||||||
|
'task_my_num',
|
||||||
|
'task_my_complete',
|
||||||
|
'task_my_percent',
|
||||||
'owner_userid',
|
'owner_userid',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成任务数据
|
||||||
|
*/
|
||||||
|
private function generateTaskData()
|
||||||
|
{
|
||||||
|
if (!isset($this->appendattrs['task_num'])) {
|
||||||
|
$builder = ProjectTask::whereProjectId($this->id)->whereParentId(0)->whereNull('archived_at');
|
||||||
|
$this->appendattrs['task_num'] = $builder->count();
|
||||||
|
$this->appendattrs['task_complete'] = $builder->whereNotNull('complete_at')->count();
|
||||||
|
$this->appendattrs['task_percent'] = $this->appendattrs['task_num'] ? intval($this->appendattrs['task_complete'] / $this->appendattrs['task_num'] * 100) : 0;
|
||||||
|
//
|
||||||
|
$builder = ProjectTask::whereProjectId($this->id)->whereParentId(0)->authData(User::userid())->whereNull('archived_at');
|
||||||
|
$this->appendattrs['task_my_num'] = $builder->count();
|
||||||
|
$this->appendattrs['task_my_complete'] = $builder->whereNotNull('complete_at')->count();
|
||||||
|
$this->appendattrs['task_my_percent'] = $this->appendattrs['task_my_num'] ? intval($this->appendattrs['task_my_complete'] / $this->appendattrs['task_my_num'] * 100) : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务数量
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getTaskNumAttribute()
|
||||||
|
{
|
||||||
|
$this->generateTaskData();
|
||||||
|
return $this->appendattrs['task_num'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务完成数量
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getTaskCompleteAttribute()
|
||||||
|
{
|
||||||
|
$this->generateTaskData();
|
||||||
|
return $this->appendattrs['task_complete'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务完成率
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getTaskPercentAttribute()
|
||||||
|
{
|
||||||
|
$this->generateTaskData();
|
||||||
|
return $this->appendattrs['task_percent'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务数量(我的)
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getTaskMyNumAttribute()
|
||||||
|
{
|
||||||
|
$this->generateTaskData();
|
||||||
|
return $this->appendattrs['task_my_num'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务完成数量(我的)
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getTaskMyCompleteAttribute()
|
||||||
|
{
|
||||||
|
$this->generateTaskData();
|
||||||
|
return $this->appendattrs['task_my_complete'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 任务完成率(我的)
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getTaskMyPercentAttribute()
|
||||||
|
{
|
||||||
|
$this->generateTaskData();
|
||||||
|
return $this->appendattrs['task_my_percent'];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 负责人会员ID
|
* 负责人会员ID
|
||||||
* @return int
|
* @return int
|
||||||
@ -70,7 +159,7 @@ class Project extends AbstractModel
|
|||||||
public function getOwnerUseridAttribute()
|
public function getOwnerUseridAttribute()
|
||||||
{
|
{
|
||||||
if (!isset($this->appendattrs['owner_userid'])) {
|
if (!isset($this->appendattrs['owner_userid'])) {
|
||||||
$ownerUser = ProjectUser::whereProjectId($this->id)->whereOwner(1)->first();
|
$ownerUser = $this->projectUser->where('owner', 1)->first();
|
||||||
$this->appendattrs['owner_userid'] = $ownerUser ? $ownerUser->userid : 0;
|
$this->appendattrs['owner_userid'] = $ownerUser ? $ownerUser->userid : 0;
|
||||||
}
|
}
|
||||||
return $this->appendattrs['owner_userid'];
|
return $this->appendattrs['owner_userid'];
|
||||||
@ -101,73 +190,19 @@ class Project extends AbstractModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询所有项目(与正常查询多返回owner字段)
|
* 查询自己的项目
|
||||||
* @param self $query
|
* @param self $query
|
||||||
* @param null $userid
|
* @param null $userid
|
||||||
* @return self
|
* @return self
|
||||||
*/
|
*/
|
||||||
public function scopeAllData($query, $userid = null)
|
public function scopeAuthData($query, $userid = null)
|
||||||
{
|
{
|
||||||
$userid = $userid ?: User::userid();
|
$userid = $userid ?: User::userid();
|
||||||
$query
|
$query->join('project_users', 'projects.id', '=', 'project_users.project_id')
|
||||||
->select([
|
|
||||||
'projects.*',
|
|
||||||
'project_users.owner',
|
|
||||||
'project_users.top_at',
|
|
||||||
])
|
|
||||||
->leftJoin('project_users', function ($leftJoin) use ($userid) {
|
|
||||||
$leftJoin
|
|
||||||
->on('project_users.userid', '=', DB::raw($userid))
|
|
||||||
->on('projects.id', '=', 'project_users.project_id');
|
|
||||||
});
|
|
||||||
return $query;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询自己负责或参与的项目
|
|
||||||
* @param self $query
|
|
||||||
* @param null $userid
|
|
||||||
* @param null $owner
|
|
||||||
* @return self
|
|
||||||
*/
|
|
||||||
public function scopeAuthData($query, $userid = null, $owner = null)
|
|
||||||
{
|
|
||||||
$userid = $userid ?: User::userid();
|
|
||||||
$query
|
|
||||||
->select([
|
|
||||||
'projects.*',
|
|
||||||
'project_users.owner',
|
|
||||||
'project_users.top_at',
|
|
||||||
])
|
|
||||||
->join('project_users', 'projects.id', '=', 'project_users.project_id')
|
|
||||||
->where('project_users.userid', $userid);
|
->where('project_users.userid', $userid);
|
||||||
if ($owner !== null) {
|
|
||||||
$query->where('project_users.owner', $owner);
|
|
||||||
}
|
|
||||||
return $query;
|
return $query;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取任务统计数据
|
|
||||||
* @param $userid
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getTaskStatistics($userid)
|
|
||||||
{
|
|
||||||
$array = [];
|
|
||||||
$builder = ProjectTask::whereProjectId($this->id)->whereNull('archived_at');
|
|
||||||
$array['task_num'] = $builder->count();
|
|
||||||
$array['task_complete'] = $builder->whereNotNull('complete_at')->count();
|
|
||||||
$array['task_percent'] = $array['task_num'] ? intval($array['task_complete'] / $array['task_num'] * 100) : 0;
|
|
||||||
//
|
|
||||||
$builder = ProjectTask::authData($userid, 1)->where('project_tasks.project_id', $this->id)->whereNull('project_tasks.archived_at');
|
|
||||||
$array['task_my_num'] = $builder->count();
|
|
||||||
$array['task_my_complete'] = $builder->whereNotNull('project_tasks.complete_at')->count();
|
|
||||||
$array['task_my_percent'] = $array['task_my_num'] ? intval($array['task_my_complete'] / $array['task_my_num'] * 100) : 0;
|
|
||||||
//
|
|
||||||
return $array;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加入项目
|
* 加入项目
|
||||||
* @param int $userid 加入的会员ID
|
* @param int $userid 加入的会员ID
|
||||||
@ -214,7 +249,7 @@ class Project extends AbstractModel
|
|||||||
*/
|
*/
|
||||||
public function relationUserids()
|
public function relationUserids()
|
||||||
{
|
{
|
||||||
return ProjectUser::whereProjectId($this->id)->orderBy('id')->pluck('userid')->toArray();
|
return $this->projectUser->pluck('userid')->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -242,7 +277,6 @@ class Project extends AbstractModel
|
|||||||
if ($archived_at === null) {
|
if ($archived_at === null) {
|
||||||
// 取消归档
|
// 取消归档
|
||||||
$this->archived_at = null;
|
$this->archived_at = null;
|
||||||
$this->archived_userid = User::userid();
|
|
||||||
$this->addLog("项目取消归档");
|
$this->addLog("项目取消归档");
|
||||||
$this->pushMsg('add', $this);
|
$this->pushMsg('add', $this);
|
||||||
ProjectTask::whereProjectId($this->id)->whereArchivedFollow(1)->update([
|
ProjectTask::whereProjectId($this->id)->whereArchivedFollow(1)->update([
|
||||||
@ -288,23 +322,18 @@ class Project extends AbstractModel
|
|||||||
/**
|
/**
|
||||||
* 添加项目日志
|
* 添加项目日志
|
||||||
* @param string $detail
|
* @param string $detail
|
||||||
* @param array $record
|
|
||||||
* @param int $userid
|
* @param int $userid
|
||||||
* @return ProjectLog
|
* @return ProjectLog
|
||||||
*/
|
*/
|
||||||
public function addLog($detail, $record = [], $userid = 0)
|
public function addLog($detail, $userid = 0)
|
||||||
{
|
{
|
||||||
$array = [
|
$log = ProjectLog::createInstance([
|
||||||
'project_id' => $this->id,
|
'project_id' => $this->id,
|
||||||
'column_id' => 0,
|
'column_id' => 0,
|
||||||
'task_id' => 0,
|
'task_id' => 0,
|
||||||
'userid' => $userid ?: User::userid(),
|
'userid' => $userid ?: User::userid(),
|
||||||
'detail' => $detail,
|
'detail' => $detail,
|
||||||
];
|
]);
|
||||||
if ($record) {
|
|
||||||
$array['record'] = $record;
|
|
||||||
}
|
|
||||||
$log = ProjectLog::createInstance($array);
|
|
||||||
$log->save();
|
$log->save();
|
||||||
return $log;
|
return $log;
|
||||||
}
|
}
|
||||||
@ -312,180 +341,45 @@ class Project extends AbstractModel
|
|||||||
/**
|
/**
|
||||||
* 推送消息
|
* 推送消息
|
||||||
* @param string $action
|
* @param string $action
|
||||||
* @param array|self $data 发送内容,默认为[id=>项目ID]
|
* @param array $data 发送内容,默认为[id=>项目ID]
|
||||||
* @param array $userid 指定会员,默认为项目所有成员
|
* @param array $userid 指定会员,默认为项目所有成员
|
||||||
*/
|
*/
|
||||||
public function pushMsg($action, $data = null, $userid = null)
|
public function pushMsg($action, $data = null, $userid = null)
|
||||||
{
|
{
|
||||||
if ($data === null) {
|
if ($data === null) {
|
||||||
$data = ['id' => $this->id];
|
$data = ['id' => $this->id];
|
||||||
} elseif ($data instanceof self) {
|
|
||||||
$data = $data->toArray();
|
|
||||||
}
|
}
|
||||||
//
|
|
||||||
$array = [$userid, []];
|
|
||||||
if ($userid === null) {
|
if ($userid === null) {
|
||||||
$array[0] = $this->relationUserids();
|
$userid = $this->relationUserids();
|
||||||
} elseif (!is_array($userid)) {
|
|
||||||
$array[0] = [$userid];
|
|
||||||
}
|
|
||||||
//
|
|
||||||
if (isset($data['owner'])) {
|
|
||||||
$owners = ProjectUser::whereProjectId($data['id'])->whereOwner(1)->pluck('userid')->toArray();
|
|
||||||
$array = [array_intersect($array[0], $owners), array_diff($array[0], $owners)];
|
|
||||||
}
|
|
||||||
//
|
|
||||||
foreach ($array as $index => $item) {
|
|
||||||
if ($index > 0) {
|
|
||||||
$data['owner'] = 0;
|
|
||||||
}
|
|
||||||
$params = [
|
|
||||||
'ignoreFd' => Request::header('fd'),
|
|
||||||
'userid' => array_values($item),
|
|
||||||
'msg' => [
|
|
||||||
'type' => 'project',
|
|
||||||
'action' => $action,
|
|
||||||
'data' => $data,
|
|
||||||
]
|
|
||||||
];
|
|
||||||
$task = new PushTask($params, false);
|
|
||||||
Task::deliver($task);
|
|
||||||
}
|
}
|
||||||
|
$params = [
|
||||||
|
'ignoreFd' => Request::header('fd'),
|
||||||
|
'userid' => $userid,
|
||||||
|
'msg' => [
|
||||||
|
'type' => 'project',
|
||||||
|
'action' => $action,
|
||||||
|
'data' => $data,
|
||||||
|
]
|
||||||
|
];
|
||||||
|
$task = new PushTask($params, false);
|
||||||
|
Task::deliver($task);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加工作流
|
* 根据用户获取项目信息(用于判断会员是否存在项目内)
|
||||||
* @param $flows
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function addFlow($flows)
|
|
||||||
{
|
|
||||||
return AbstractModel::transaction(function() use ($flows) {
|
|
||||||
$projectFlow = ProjectFlow::whereProjectId($this->id)->first();
|
|
||||||
if (empty($projectFlow)) {
|
|
||||||
$projectFlow = ProjectFlow::createInstance([
|
|
||||||
'project_id' => $this->id,
|
|
||||||
'name' => 'Default'
|
|
||||||
]);
|
|
||||||
if (!$projectFlow->save()) {
|
|
||||||
throw new ApiException('工作流创建失败');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//
|
|
||||||
$ids = [];
|
|
||||||
$idc = [];
|
|
||||||
$hasStart = false;
|
|
||||||
$hasEnd = false;
|
|
||||||
$upTaskList = [];
|
|
||||||
foreach ($flows as $item) {
|
|
||||||
$id = intval($item['id']);
|
|
||||||
$turns = Base::arrayRetainInt($item['turns'] ?: [], true);
|
|
||||||
$userids = Base::arrayRetainInt($item['userids'] ?: [], true);
|
|
||||||
$usertype = trim($item['usertype']);
|
|
||||||
$userlimit = intval($item['userlimit']);
|
|
||||||
if ($usertype == 'replace' && empty($userids)) {
|
|
||||||
throw new ApiException("状态[{$item['name']}]设置错误,设置流转模式时必须填写状态负责人");
|
|
||||||
}
|
|
||||||
if ($usertype == 'merge' && empty($userids)) {
|
|
||||||
throw new ApiException("状态[{$item['name']}]设置错误,设置剔除模式时必须填写状态负责人");
|
|
||||||
}
|
|
||||||
if ($userlimit && empty($userids)) {
|
|
||||||
throw new ApiException("状态[{$item['name']}]设置错误,设置限制负责人时必须填写状态负责人");
|
|
||||||
}
|
|
||||||
$flow = ProjectFlowItem::updateInsert([
|
|
||||||
'id' => $id,
|
|
||||||
'project_id' => $this->id,
|
|
||||||
'flow_id' => $projectFlow->id,
|
|
||||||
], [
|
|
||||||
'name' => trim($item['name']),
|
|
||||||
'status' => trim($item['status']),
|
|
||||||
'sort' => intval($item['sort']),
|
|
||||||
'turns' => $turns,
|
|
||||||
'userids' => $userids,
|
|
||||||
'usertype' => trim($item['usertype']),
|
|
||||||
'userlimit' => $userlimit,
|
|
||||||
], [], $isInsert);
|
|
||||||
if ($flow) {
|
|
||||||
$ids[] = $flow->id;
|
|
||||||
if ($flow->id != $id) {
|
|
||||||
$idc[$id] = $flow->id;
|
|
||||||
}
|
|
||||||
if ($flow->status == 'start') {
|
|
||||||
$hasStart = true;
|
|
||||||
}
|
|
||||||
if ($flow->status == 'end') {
|
|
||||||
$hasEnd = true;
|
|
||||||
}
|
|
||||||
if (!$isInsert) {
|
|
||||||
$upTaskList[$flow->id] = $flow->status . "|" . $flow->name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!$hasStart) {
|
|
||||||
throw new ApiException('至少需要1个开始状态');
|
|
||||||
}
|
|
||||||
if (!$hasEnd) {
|
|
||||||
throw new ApiException('至少需要1个结束状态');
|
|
||||||
}
|
|
||||||
ProjectFlowItem::whereFlowId($projectFlow->id)->whereNotIn('id', $ids)->chunk(100, function($list) {
|
|
||||||
foreach ($list as $item) {
|
|
||||||
$item->deleteFlowItem();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
//
|
|
||||||
foreach ($upTaskList as $id => $value) {
|
|
||||||
ProjectTask::whereFlowItemId($id)->update([
|
|
||||||
'flow_item_name' => $value
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
//
|
|
||||||
$projectFlow = ProjectFlow::with(['projectFlowItem'])->whereProjectId($this->id)->find($projectFlow->id);
|
|
||||||
$itemIds = $projectFlow->projectFlowItem->pluck('id')->toArray();
|
|
||||||
foreach ($projectFlow->projectFlowItem as $item) {
|
|
||||||
$turns = $item->turns;
|
|
||||||
foreach ($idc as $oid => $nid) {
|
|
||||||
if (in_array($oid, $turns)) {
|
|
||||||
$turns = array_diff($turns, [$oid]);
|
|
||||||
$turns[] = $nid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!in_array($item->id, $turns)) {
|
|
||||||
$turns[] = $item->id;
|
|
||||||
}
|
|
||||||
$turns = array_values(array_filter(array_unique(array_intersect($turns, $itemIds))));
|
|
||||||
sort($turns);
|
|
||||||
$item->turns = $turns;
|
|
||||||
ProjectFlowItem::whereId($item->id)->update([ 'turns' => Base::array2json($turns) ]);
|
|
||||||
}
|
|
||||||
return $projectFlow;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取项目信息(用于判断会员是否存在项目内)
|
|
||||||
* @param int $project_id
|
* @param int $project_id
|
||||||
* @param null|bool $archived true:仅限未归档, false:仅限已归档, null:不限制
|
* @param bool $ignoreArchived 排除已归档
|
||||||
* @param null|bool $mustOwner true:仅限项目负责人, false:仅限非项目负责人, null:不限制
|
|
||||||
* @return self
|
* @return self
|
||||||
*/
|
*/
|
||||||
public static function userProject($project_id, $archived = true, $mustOwner = null)
|
public static function userProject($project_id, $ignoreArchived = true)
|
||||||
{
|
{
|
||||||
$project = self::authData()->where('projects.id', intval($project_id))->first();
|
$project = self::select(self::projectSelect)->authData()->where('projects.id', intval($project_id))->first();
|
||||||
if (empty($project)) {
|
if (empty($project)) {
|
||||||
throw new ApiException('项目不存在或不在成员列表内', [ 'project_id' => $project_id ], -4001);
|
throw new ApiException('项目不存在或不在成员列表内', [ 'project_id' => $project_id ], -4001);
|
||||||
}
|
}
|
||||||
if ($archived === true && $project->archived_at != null) {
|
if ($ignoreArchived && $project->archived_at != null) {
|
||||||
throw new ApiException('项目已归档', [ 'project_id' => $project_id ], -4001);
|
throw new ApiException('项目已归档', [ 'project_id' => $project_id ], -4001);
|
||||||
}
|
}
|
||||||
if ($archived === false && $project->archived_at == null) {
|
|
||||||
throw new ApiException('项目未归档', [ 'project_id' => $project_id ]);
|
|
||||||
}
|
|
||||||
if ($mustOwner === true && !$project->owner) {
|
|
||||||
throw new ApiException('仅限项目负责人操作', [ 'project_id' => $project_id ]);
|
|
||||||
}
|
|
||||||
if ($mustOwner === false && $project->owner) {
|
|
||||||
throw new ApiException('禁止项目负责人操作', [ 'project_id' => $project_id ]);
|
|
||||||
}
|
|
||||||
return $project;
|
return $project;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,9 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
|||||||
use Request;
|
use Request;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App\Models\ProjectColumn
|
* Class ProjectColumn
|
||||||
*
|
*
|
||||||
|
* @package App\Models
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property int|null $project_id 项目ID
|
* @property int|null $project_id 项目ID
|
||||||
* @property string|null $name 列表名称
|
* @property string|null $name 列表名称
|
||||||
|
@ -1,51 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use App\Module\Base;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* App\Models\ProjectFlow
|
|
||||||
*
|
|
||||||
* @property int $id
|
|
||||||
* @property int|null $project_id 项目ID
|
|
||||||
* @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 int|null $project_flow_item_count
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlow newModelQuery()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlow newQuery()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlow query()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlow whereCreatedAt($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlow whereId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlow whereName($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlow whereProjectId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlow whereUpdatedAt($value)
|
|
||||||
* @mixin \Eloquent
|
|
||||||
*/
|
|
||||||
class ProjectFlow extends AbstractModel
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
|
||||||
*/
|
|
||||||
public function projectFlowItem(): \Illuminate\Database\Eloquent\Relations\HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(ProjectFlowItem::class, 'flow_id', 'id')->orderBy('sort');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function deleteFlow()
|
|
||||||
{
|
|
||||||
return AbstractModel::transaction(function() {
|
|
||||||
ProjectFlowItem::whereProjectId($this->project_id)->chunk(100, function($list) {
|
|
||||||
foreach ($list as $item) {
|
|
||||||
$item->deleteFlowItem();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return $this->delete();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,90 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use App\Module\Base;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* App\Models\ProjectFlowItem
|
|
||||||
*
|
|
||||||
* @property int $id
|
|
||||||
* @property int|null $project_id 项目ID
|
|
||||||
* @property int|null $flow_id 流程ID
|
|
||||||
* @property string|null $name 名称
|
|
||||||
* @property string|null $status 状态
|
|
||||||
* @property array $turns 可流转
|
|
||||||
* @property array $userids 自动负责人ID
|
|
||||||
* @property string|null $usertype 流转模式
|
|
||||||
* @property int|null $userlimit 限制负责人
|
|
||||||
* @property int|null $sort 排序
|
|
||||||
* @property \Illuminate\Support\Carbon|null $created_at
|
|
||||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
|
||||||
* @property-read \App\Models\ProjectFlow|null $projectFlow
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem newModelQuery()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem newQuery()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem query()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem whereCreatedAt($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem whereFlowId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem whereId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem whereName($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem whereProjectId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem whereSort($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem whereStatus($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem whereTurns($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem whereUpdatedAt($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem whereUserids($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem whereUserlimit($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem whereUsertype($value)
|
|
||||||
* @mixin \Eloquent
|
|
||||||
*/
|
|
||||||
class ProjectFlowItem extends AbstractModel
|
|
||||||
{
|
|
||||||
protected $hidden = [
|
|
||||||
'created_at',
|
|
||||||
'updated_at',
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $value
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getTurnsAttribute($value)
|
|
||||||
{
|
|
||||||
if (is_array($value)) {
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
return Base::json2array($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $value
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getUseridsAttribute($value)
|
|
||||||
{
|
|
||||||
if (is_array($value)) {
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
return Base::json2array($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
|
||||||
*/
|
|
||||||
public function projectFlow(): \Illuminate\Database\Eloquent\Relations\HasOne
|
|
||||||
{
|
|
||||||
return $this->hasOne(ProjectFlow::class, 'id', 'flow_id');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool|null
|
|
||||||
*/
|
|
||||||
public function deleteFlowItem()
|
|
||||||
{
|
|
||||||
ProjectTask::whereFlowItemId($this->id)->update([
|
|
||||||
'flow_item_id' => 0,
|
|
||||||
'flow_item_name' => "",
|
|
||||||
]);
|
|
||||||
return $this->delete();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* App\Models\ProjectInvite
|
|
||||||
*
|
|
||||||
* @property int $id
|
|
||||||
* @property int|null $project_id 项目ID
|
|
||||||
* @property int|null $num 累计邀请
|
|
||||||
* @property string|null $code 链接码
|
|
||||||
* @property \Illuminate\Support\Carbon|null $created_at
|
|
||||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
|
||||||
* @property-read bool $already
|
|
||||||
* @property-read \App\Models\Project|null $project
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectInvite newModelQuery()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectInvite newQuery()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectInvite query()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectInvite whereCode($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectInvite whereCreatedAt($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectInvite whereId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectInvite whereNum($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectInvite whereProjectId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectInvite whereUpdatedAt($value)
|
|
||||||
* @mixin \Eloquent
|
|
||||||
*/
|
|
||||||
class ProjectInvite extends AbstractModel
|
|
||||||
{
|
|
||||||
protected $appends = [
|
|
||||||
'already',
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否已加入
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function getAlreadyAttribute()
|
|
||||||
{
|
|
||||||
if (!isset($this->appendattrs['already'])) {
|
|
||||||
$this->appendattrs['already'] = false;
|
|
||||||
if (User::userid()) {
|
|
||||||
$this->appendattrs['already'] = (bool)$this->project?->projectUser?->where('userid', User::userid())->count();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $this->appendattrs['already'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
|
||||||
*/
|
|
||||||
public function project(): \Illuminate\Database\Eloquent\Relations\HasOne
|
|
||||||
{
|
|
||||||
return $this->hasOne(Project::class, 'id', 'project_id');
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,21 +2,18 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use App\Module\Base;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App\Models\ProjectLog
|
* Class ProjectLog
|
||||||
*
|
*
|
||||||
|
* @package App\Models
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property int|null $project_id 项目ID
|
* @property int|null $project_id 项目ID
|
||||||
* @property int|null $column_id 列表ID
|
* @property int|null $column_id 列表ID
|
||||||
* @property int|null $task_id 项目ID
|
* @property int|null $task_id 项目ID
|
||||||
* @property int|null $userid 会员ID
|
* @property int|null $userid 会员ID
|
||||||
* @property string|null $detail 详细信息
|
* @property string|null $detail 详细信息
|
||||||
* @property array $record 记录数据
|
|
||||||
* @property \Illuminate\Support\Carbon|null $created_at
|
* @property \Illuminate\Support\Carbon|null $created_at
|
||||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||||
* @property-read \App\Models\ProjectTask|null $projectTask
|
|
||||||
* @property-read \App\Models\User|null $user
|
* @property-read \App\Models\User|null $user
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog newModelQuery()
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog newModelQuery()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog newQuery()
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog newQuery()
|
||||||
@ -26,7 +23,6 @@ use App\Module\Base;
|
|||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereDetail($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereDetail($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereId($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereId($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereProjectId($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereProjectId($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereRecord($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereTaskId($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereTaskId($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereUpdatedAt($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereUpdatedAt($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereUserid($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereUserid($value)
|
||||||
@ -35,18 +31,6 @@ use App\Module\Base;
|
|||||||
class ProjectLog extends AbstractModel
|
class ProjectLog extends AbstractModel
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $value
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getRecordAttribute($value)
|
|
||||||
{
|
|
||||||
if (is_array($value)) {
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
return Base::json2array($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
||||||
*/
|
*/
|
||||||
@ -55,12 +39,4 @@ class ProjectLog extends AbstractModel
|
|||||||
return $this->hasOne(User::class, 'userid', 'userid');
|
return $this->hasOne(User::class, 'userid', 'userid');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
|
||||||
*/
|
|
||||||
public function projectTask(): \Illuminate\Database\Eloquent\Relations\HasOne
|
|
||||||
{
|
|
||||||
return $this->hasOne(ProjectTask::class, 'id', 'task_id');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ use App\Module\Base;
|
|||||||
use App\Tasks\PushTask;
|
use App\Tasks\PushTask;
|
||||||
use Arr;
|
use Arr;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use DB;
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use Hhxsv5\LaravelS\Swoole\Task\Task;
|
use Hhxsv5\LaravelS\Swoole\Task\Task;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
@ -21,8 +20,6 @@ use Request;
|
|||||||
* @property int|null $project_id 项目ID
|
* @property int|null $project_id 项目ID
|
||||||
* @property int|null $column_id 列表ID
|
* @property int|null $column_id 列表ID
|
||||||
* @property int|null $dialog_id 聊天会话ID
|
* @property int|null $dialog_id 聊天会话ID
|
||||||
* @property int|null $flow_item_id 工作流状态ID
|
|
||||||
* @property string|null $flow_item_name 工作流状态名称
|
|
||||||
* @property string|null $name 标题
|
* @property string|null $name 标题
|
||||||
* @property string|null $color 颜色
|
* @property string|null $color 颜色
|
||||||
* @property string|null $desc 描述
|
* @property string|null $desc 描述
|
||||||
@ -44,21 +41,19 @@ use Request;
|
|||||||
* @property-read int $file_num
|
* @property-read int $file_num
|
||||||
* @property-read int $msg_num
|
* @property-read int $msg_num
|
||||||
* @property-read bool $overdue
|
* @property-read bool $overdue
|
||||||
|
* @property-read bool $owner
|
||||||
* @property-read int $percent
|
* @property-read int $percent
|
||||||
* @property-read int $sub_complete
|
* @property-read int $sub_complete
|
||||||
* @property-read int $sub_num
|
* @property-read int $sub_num
|
||||||
* @property-read bool $today
|
* @property-read bool $today
|
||||||
* @property-read \App\Models\Project|null $project
|
* @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|\App\Models\ProjectTaskFile[] $taskFile
|
||||||
* @property-read int|null $task_file_count
|
* @property-read int|null $task_file_count
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectTaskTag[] $taskTag
|
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectTaskTag[] $taskTag
|
||||||
* @property-read int|null $task_tag_count
|
* @property-read int|null $task_tag_count
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectTaskUser[] $taskUser
|
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectTaskUser[] $taskUser
|
||||||
* @property-read int|null $task_user_count
|
* @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)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask authData($userid = null, $owner = null)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask betweenTime($start, $end)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask newModelQuery()
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask newModelQuery()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask newQuery()
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask newQuery()
|
||||||
* @method static \Illuminate\Database\Query\Builder|ProjectTask onlyTrashed()
|
* @method static \Illuminate\Database\Query\Builder|ProjectTask onlyTrashed()
|
||||||
@ -74,8 +69,6 @@ use Request;
|
|||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereDesc($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereDesc($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereDialogId($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereDialogId($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereEndAt($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereEndAt($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereFlowItemId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereFlowItemName($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereId($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereId($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereName($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereName($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask wherePColor($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask wherePColor($value)
|
||||||
@ -96,6 +89,7 @@ class ProjectTask extends AbstractModel
|
|||||||
use SoftDeletes;
|
use SoftDeletes;
|
||||||
|
|
||||||
protected $appends = [
|
protected $appends = [
|
||||||
|
'owner',
|
||||||
'file_num',
|
'file_num',
|
||||||
'msg_num',
|
'msg_num',
|
||||||
'sub_num',
|
'sub_num',
|
||||||
@ -105,6 +99,22 @@ class ProjectTask extends AbstractModel
|
|||||||
'overdue',
|
'overdue',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否我是负责人
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function getOwnerAttribute()
|
||||||
|
{
|
||||||
|
if (!isset($this->appendattrs['owner'])) {
|
||||||
|
if ($this->parent_id > 0) {
|
||||||
|
$this->appendattrs['owner'] = ProjectTaskUser::whereTaskId($this->id)->whereUserid(User::userid())->whereOwner(1)->exists();
|
||||||
|
} else {
|
||||||
|
$this->appendattrs['owner'] = ProjectTaskUser::whereTaskPid($this->id)->whereUserid(User::userid())->whereOwner(1)->exists();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->appendattrs['owner'];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 附件数量
|
* 附件数量
|
||||||
* @return int
|
* @return int
|
||||||
@ -112,7 +122,7 @@ class ProjectTask extends AbstractModel
|
|||||||
public function getFileNumAttribute()
|
public function getFileNumAttribute()
|
||||||
{
|
{
|
||||||
if (!isset($this->appendattrs['file_num'])) {
|
if (!isset($this->appendattrs['file_num'])) {
|
||||||
$this->appendattrs['file_num'] = $this->parent_id > 0 ? 0 : ProjectTaskFile::whereTaskId($this->id)->count();
|
$this->appendattrs['file_num'] = ProjectTaskFile::whereTaskId($this->id)->count();
|
||||||
}
|
}
|
||||||
return $this->appendattrs['file_num'];
|
return $this->appendattrs['file_num'];
|
||||||
}
|
}
|
||||||
@ -222,14 +232,6 @@ class ProjectTask extends AbstractModel
|
|||||||
return $this->hasOne(Project::class, 'id', 'project_id');
|
return $this->hasOne(Project::class, 'id', 'project_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
|
||||||
*/
|
|
||||||
public function projectColumn(): \Illuminate\Database\Eloquent\Relations\HasOne
|
|
||||||
{
|
|
||||||
return $this->hasOne(ProjectColumn::class, 'id', 'column_id');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
||||||
*/
|
*/
|
||||||
@ -263,67 +265,16 @@ class ProjectTask extends AbstractModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询所有任务(与正常查询多返回owner字段)
|
* 查询自己的任务
|
||||||
* @param self $query
|
* @param self $query
|
||||||
* @param null $userid
|
* @param null $userid
|
||||||
* @return self
|
* @return self
|
||||||
*/
|
*/
|
||||||
public function scopeAllData($query, $userid = null)
|
public function scopeAuthData($query, $userid = null)
|
||||||
{
|
{
|
||||||
$userid = $userid ?: User::userid();
|
$userid = $userid ?: User::userid();
|
||||||
$query
|
$query->whereIn('id', function ($qy) use ($userid) {
|
||||||
->select([
|
$qy->select('task_pid')->from('project_task_users')->where('userid', $userid);
|
||||||
'project_tasks.*',
|
|
||||||
'project_task_users.owner'
|
|
||||||
])
|
|
||||||
->leftJoin('project_task_users', function ($leftJoin) use ($userid) {
|
|
||||||
$leftJoin
|
|
||||||
->on('project_task_users.userid', '=', DB::raw($userid))
|
|
||||||
->on('project_tasks.id', '=', 'project_task_users.task_id');
|
|
||||||
});
|
|
||||||
return $query;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询自己负责或参与的任务
|
|
||||||
* @param self $query
|
|
||||||
* @param null $userid
|
|
||||||
* @param null $owner
|
|
||||||
* @return self
|
|
||||||
*/
|
|
||||||
public function scopeAuthData($query, $userid = null, $owner = null)
|
|
||||||
{
|
|
||||||
$userid = $userid ?: User::userid();
|
|
||||||
$query
|
|
||||||
->select([
|
|
||||||
'project_tasks.*',
|
|
||||||
'project_task_users.owner'
|
|
||||||
])
|
|
||||||
->join('project_task_users', 'project_tasks.id', '=', 'project_task_users.task_id')
|
|
||||||
->where('project_task_users.userid', $userid);
|
|
||||||
if ($owner !== null) {
|
|
||||||
$query->where('project_task_users.owner', $owner);
|
|
||||||
}
|
|
||||||
return $query;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 指定范围内的任务
|
|
||||||
* @param $query
|
|
||||||
* @param $start
|
|
||||||
* @param $end
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function scopeBetweenTime($query, $start, $end)
|
|
||||||
{
|
|
||||||
$query->where(function ($q1) use ($start, $end) {
|
|
||||||
$q1->where(function ($q2) use ($start) {
|
|
||||||
$q2->where('project_tasks.start_at', '<=', $start)->where('project_tasks.end_at', '>=', $start);
|
|
||||||
})->orWhere(function ($q2) use ($end) {
|
|
||||||
$q2->where('project_tasks.start_at', '<=', $end)->where('project_tasks.end_at', '>=', $end);
|
|
||||||
})->orWhere(function ($q2) use ($start, $end) {
|
|
||||||
$q2->where('project_tasks.start_at', '>', $start)->where('project_tasks.end_at', '<', $end);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
return $query;
|
return $query;
|
||||||
}
|
}
|
||||||
@ -342,32 +293,11 @@ class ProjectTask extends AbstractModel
|
|||||||
$content = $data['content'];
|
$content = $data['content'];
|
||||||
$times = $data['times'];
|
$times = $data['times'];
|
||||||
$owner = $data['owner'];
|
$owner = $data['owner'];
|
||||||
$add_assist = intval($data['add_assist']);
|
|
||||||
$subtasks = $data['subtasks'];
|
$subtasks = $data['subtasks'];
|
||||||
$p_level = intval($data['p_level']);
|
$p_level = intval($data['p_level']);
|
||||||
$p_name = $data['p_name'];
|
$p_name = $data['p_name'];
|
||||||
$p_color = $data['p_color'];
|
$p_color = $data['p_color'];
|
||||||
$top = intval($data['top']);
|
$top = intval($data['top']);
|
||||||
$userid = User::userid();
|
|
||||||
//
|
|
||||||
if (ProjectTask::whereProjectId($project_id)
|
|
||||||
->whereNull('project_tasks.complete_at')
|
|
||||||
->whereNull('project_tasks.archived_at')
|
|
||||||
->count() > 2000) {
|
|
||||||
throw new ApiException('项目内未完成任务最多不能超过2000个');
|
|
||||||
}
|
|
||||||
if (ProjectTask::whereColumnId($column_id)
|
|
||||||
->whereNull('project_tasks.complete_at')
|
|
||||||
->whereNull('project_tasks.archived_at')
|
|
||||||
->count() > 500) {
|
|
||||||
throw new ApiException('单个列表未完成任务最多不能超过500个');
|
|
||||||
}
|
|
||||||
if ($parent_id > 0 && ProjectTask::whereParentId($parent_id)
|
|
||||||
->whereNull('project_tasks.complete_at')
|
|
||||||
->whereNull('project_tasks.archived_at')
|
|
||||||
->count() > 50) {
|
|
||||||
throw new ApiException('每个任务的子任务最多不能超过50个');
|
|
||||||
}
|
|
||||||
//
|
//
|
||||||
$retPre = $parent_id ? '子任务' : '任务';
|
$retPre = $parent_id ? '子任务' : '任务';
|
||||||
$task = self::createInstance([
|
$task = self::createInstance([
|
||||||
@ -379,7 +309,7 @@ class ProjectTask extends AbstractModel
|
|||||||
'p_color' => $p_color,
|
'p_color' => $p_color,
|
||||||
]);
|
]);
|
||||||
if ($content) {
|
if ($content) {
|
||||||
$task->desc = Base::getHtml($content, 100);
|
$task->desc = Base::getHtml($content);
|
||||||
}
|
}
|
||||||
// 标题
|
// 标题
|
||||||
if (empty($name)) {
|
if (empty($name)) {
|
||||||
@ -391,9 +321,11 @@ class ProjectTask extends AbstractModel
|
|||||||
// 时间
|
// 时间
|
||||||
if ($times) {
|
if ($times) {
|
||||||
list($start, $end) = is_string($times) ? explode(",", $times) : (is_array($times) ? $times : []);
|
list($start, $end) = is_string($times) ? explode(",", $times) : (is_array($times) ? $times : []);
|
||||||
if (Base::isDate($start) && Base::isDate($end) && $start != $end) {
|
if (Base::isDate($start) && Base::isDate($end)) {
|
||||||
$task->start_at = Carbon::parse($start);
|
if ($start != $end) {
|
||||||
$task->end_at = Carbon::parse($end);
|
$task->start_at = Carbon::parse($start);
|
||||||
|
$task->end_at = Carbon::parse($end);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 负责人
|
// 负责人
|
||||||
@ -404,46 +336,20 @@ class ProjectTask extends AbstractModel
|
|||||||
if (!ProjectUser::whereProjectId($project_id)->whereUserid($uid)->exists()) {
|
if (!ProjectUser::whereProjectId($project_id)->whereUserid($uid)->exists()) {
|
||||||
throw new ApiException($retPre . '负责人填写错误');
|
throw new ApiException($retPre . '负责人填写错误');
|
||||||
}
|
}
|
||||||
if (ProjectTask::authData($uid)
|
|
||||||
->whereNull('project_tasks.complete_at')
|
|
||||||
->whereNull('project_tasks.archived_at')
|
|
||||||
->count() > 500) {
|
|
||||||
throw new ApiException(User::userid2nickname($uid) . '负责或参与的未完成任务最多不能超过500个');
|
|
||||||
}
|
|
||||||
$tmpArray[] = $uid;
|
$tmpArray[] = $uid;
|
||||||
}
|
}
|
||||||
$owner = $tmpArray;
|
$owner = $tmpArray;
|
||||||
// 协助人员
|
|
||||||
$assist = [];
|
|
||||||
if (!in_array($userid, $owner) && $add_assist) {
|
|
||||||
$assist = [$userid];
|
|
||||||
}
|
|
||||||
// 创建人
|
// 创建人
|
||||||
$task->userid = $userid;
|
$task->userid = User::userid();
|
||||||
// 排序位置
|
// 排序位置
|
||||||
if ($top) {
|
if ($top) {
|
||||||
$task->sort = intval(self::whereColumnId($task->column_id)->orderBy('sort')->value('sort')) - 1;
|
$task->sort = intval(self::whereColumnId($task->column_id)->orderBy('sort')->value('sort')) - 1;
|
||||||
} else {
|
} else {
|
||||||
$task->sort = intval(self::whereColumnId($task->column_id)->orderByDesc('sort')->value('sort')) + 1;
|
$task->sort = intval(self::whereColumnId($task->column_id)->orderByDesc('sort')->value('sort')) + 1;
|
||||||
}
|
}
|
||||||
// 工作流
|
|
||||||
$projectFlow = ProjectFlow::whereProjectId($project_id)->orderByDesc('id')->first();
|
|
||||||
if ($projectFlow) {
|
|
||||||
$projectFlowItem = ProjectFlowItem::whereFlowId($projectFlow->id)->orderBy('sort')->get();
|
|
||||||
// 赋一个开始状态
|
|
||||||
foreach ($projectFlowItem as $item) {
|
|
||||||
if ($item->status == 'start') {
|
|
||||||
$task->flow_item_id = $item->id;
|
|
||||||
$task->flow_item_name = $item->status . "|" . $item->name;
|
|
||||||
$owner = array_merge($owner, $item->userids);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//
|
//
|
||||||
return AbstractModel::transaction(function() use ($assist, $times, $subtasks, $content, $owner, $task) {
|
return AbstractModel::transaction(function() use ($subtasks, $content, $owner, $task) {
|
||||||
$task->save();
|
$task->save();
|
||||||
$owner = array_values(array_unique($owner));
|
|
||||||
foreach ($owner as $uid) {
|
foreach ($owner as $uid) {
|
||||||
ProjectTaskUser::createInstance([
|
ProjectTaskUser::createInstance([
|
||||||
'project_id' => $task->project_id,
|
'project_id' => $task->project_id,
|
||||||
@ -453,16 +359,6 @@ class ProjectTask extends AbstractModel
|
|||||||
'owner' => 1,
|
'owner' => 1,
|
||||||
])->save();
|
])->save();
|
||||||
}
|
}
|
||||||
$assist = array_values(array_unique(array_diff($assist, $owner)));
|
|
||||||
foreach ($assist as $uid) {
|
|
||||||
ProjectTaskUser::createInstance([
|
|
||||||
'project_id' => $task->project_id,
|
|
||||||
'task_id' => $task->id,
|
|
||||||
'task_pid' => $task->parent_id ?: $task->id,
|
|
||||||
'userid' => $uid,
|
|
||||||
'owner' => 0,
|
|
||||||
])->save();
|
|
||||||
}
|
|
||||||
if ($content) {
|
if ($content) {
|
||||||
ProjectTaskContent::createInstance([
|
ProjectTaskContent::createInstance([
|
||||||
'project_id' => $task->project_id,
|
'project_id' => $task->project_id,
|
||||||
@ -472,24 +368,13 @@ class ProjectTask extends AbstractModel
|
|||||||
}
|
}
|
||||||
if ($task->parent_id == 0 && $subtasks && is_array($subtasks)) {
|
if ($task->parent_id == 0 && $subtasks && is_array($subtasks)) {
|
||||||
foreach ($subtasks as $subtask) {
|
foreach ($subtasks as $subtask) {
|
||||||
list($start, $end) = is_string($subtask['times']) ? explode(",", $subtask['times']) : (is_array($subtask['times']) ? $subtask['times'] : []);
|
|
||||||
if (Base::isDate($start) && Base::isDate($end) && $start != $end) {
|
|
||||||
if (Carbon::parse($start)->lt($task->start_at)) {
|
|
||||||
throw new ApiException('子任务开始时间不能小于主任务开始时间');
|
|
||||||
}
|
|
||||||
if (Carbon::parse($end)->gt($task->end_at)) {
|
|
||||||
throw new ApiException('子任务结束时间不能大于主任务结束时间');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$subtask['times'] = $times;
|
|
||||||
}
|
|
||||||
$subtask['parent_id'] = $task->id;
|
$subtask['parent_id'] = $task->id;
|
||||||
$subtask['project_id'] = $task->project_id;
|
$subtask['project_id'] = $task->project_id;
|
||||||
$subtask['column_id'] = $task->column_id;
|
$subtask['column_id'] = $task->column_id;
|
||||||
self::addTask($subtask);
|
self::addTask($subtask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$task->addLog("创建{任务}");
|
$task->addLog("创建{任务}:" . $task->name);
|
||||||
return $task;
|
return $task;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -497,124 +382,12 @@ class ProjectTask extends AbstractModel
|
|||||||
/**
|
/**
|
||||||
* 修改任务
|
* 修改任务
|
||||||
* @param $data
|
* @param $data
|
||||||
* @param array $updateMarking 更新的标记
|
* @param $updateContent
|
||||||
* - is_update_project 是否更新项目数据(项目统计)
|
|
||||||
* - is_update_content 是否更新任务详情
|
|
||||||
* - is_update_maintask 是否更新主任务
|
|
||||||
* - is_update_subtask 是否更新子任务
|
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function updateTask($data, &$updateMarking = [])
|
public function updateTask($data, &$updateContent)
|
||||||
{
|
{
|
||||||
AbstractModel::transaction(function () use ($data, &$updateMarking) {
|
AbstractModel::transaction(function () use ($data, &$updateContent) {
|
||||||
// 判断版本
|
|
||||||
Base::checkClientVersion('0.6.0');
|
|
||||||
// 主任务
|
|
||||||
$mainTask = $this->parent_id > 0 ? self::find($this->parent_id) : null;
|
|
||||||
// 工作流
|
|
||||||
if (Arr::exists($data, 'flow_item_id')) {
|
|
||||||
$isProjectOwner = $this->useridInTheProject(User::userid()) === 2;
|
|
||||||
if (!$isProjectOwner && !$this->isOwner()) {
|
|
||||||
throw new ApiException('仅限项目或任务负责人修改任务状态');
|
|
||||||
}
|
|
||||||
if ($this->flow_item_id == $data['flow_item_id']) {
|
|
||||||
throw new ApiException('任务状态未发生改变');
|
|
||||||
}
|
|
||||||
$flowData = [
|
|
||||||
'flow_item_id' => $this->flow_item_id,
|
|
||||||
'flow_item_name' => $this->flow_item_name,
|
|
||||||
];
|
|
||||||
$currentFlowItem = null;
|
|
||||||
$newFlowItem = ProjectFlowItem::whereProjectId($this->project_id)->find(intval($data['flow_item_id']));
|
|
||||||
if (empty($newFlowItem) || empty($newFlowItem->projectFlow)) {
|
|
||||||
throw new ApiException('任务状态不存在');
|
|
||||||
}
|
|
||||||
if ($this->flow_item_id) {
|
|
||||||
// 判断符合流转
|
|
||||||
$currentFlowItem = ProjectFlowItem::find($this->flow_item_id);
|
|
||||||
if ($currentFlowItem) {
|
|
||||||
if (!in_array($newFlowItem->id, $currentFlowItem->turns)) {
|
|
||||||
throw new ApiException("当前状态[{$currentFlowItem->name}]不可流转到[{$newFlowItem->name}]");
|
|
||||||
}
|
|
||||||
if ($currentFlowItem->userlimit) {
|
|
||||||
if (!$isProjectOwner && !in_array(User::userid(), $currentFlowItem->userids)) {
|
|
||||||
throw new ApiException("当前状态[{$currentFlowItem->name}]仅限状态负责人或项目负责人修改");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($newFlowItem->status == 'end') {
|
|
||||||
// 判断自动完成
|
|
||||||
if (!$this->complete_at) {
|
|
||||||
$flowData['complete_at'] = $this->complete_at;
|
|
||||||
$data['complete_at'] = date("Y-m-d H:i");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 判断自动打开
|
|
||||||
if ($this->complete_at) {
|
|
||||||
$flowData['complete_at'] = $this->complete_at;
|
|
||||||
$data['complete_at'] = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($newFlowItem->userids) {
|
|
||||||
// 判断自动添加负责人
|
|
||||||
$flowData['owner'] = $data['owner'] = $this->taskUser->where('owner', 1)->pluck('userid')->toArray();
|
|
||||||
if (in_array($newFlowItem->usertype, ["replace", "merge"])) {
|
|
||||||
// 流转模式、剔除模式
|
|
||||||
if ($this->parent_id === 0) {
|
|
||||||
$flowData['assist'] = $data['assist'] = $this->taskUser->where('owner', 0)->pluck('userid')->toArray();
|
|
||||||
$data['assist'] = array_merge($data['assist'], $data['owner']);
|
|
||||||
}
|
|
||||||
$data['owner'] = $newFlowItem->userids;
|
|
||||||
// 判断剔除模式:保留操作状态的人员
|
|
||||||
if ($newFlowItem->usertype == "merge") {
|
|
||||||
$data['owner'][] = User::userid();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 添加模式
|
|
||||||
$data['owner'] = array_merge($data['owner'], $newFlowItem->userids);
|
|
||||||
}
|
|
||||||
$data['owner'] = array_values(array_unique($data['owner']));
|
|
||||||
if (isset($data['assist'])) {
|
|
||||||
$data['assist'] = array_values(array_unique(array_diff($data['assist'], $data['owner'])));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$this->flow_item_id = $newFlowItem->id;
|
|
||||||
$this->flow_item_name = $newFlowItem->status . "|" . $newFlowItem->name;
|
|
||||||
$this->addLog("修改{任务}状态", [
|
|
||||||
'flow' => $flowData,
|
|
||||||
'change' => [$currentFlowItem?->name, $newFlowItem->name]
|
|
||||||
]);
|
|
||||||
ProjectTaskFlowChange::createInstance([
|
|
||||||
'task_id' => $this->id,
|
|
||||||
'userid' => User::userid(),
|
|
||||||
'before_flow_item_id' => $flowData['flow_item_id'],
|
|
||||||
'before_flow_item_name' => $flowData['flow_item_name'],
|
|
||||||
'after_flow_item_id' => $this->flow_item_id,
|
|
||||||
'after_flow_item_name' => $this->flow_item_name,
|
|
||||||
])->save();
|
|
||||||
}
|
|
||||||
// 状态
|
|
||||||
if (Arr::exists($data, 'complete_at')) {
|
|
||||||
// 子任务:主任务已完成时无法修改
|
|
||||||
if ($mainTask?->complete_at) {
|
|
||||||
throw new ApiException('主任务已完成,无法修改子任务状态');
|
|
||||||
}
|
|
||||||
if (Base::isDate($data['complete_at'])) {
|
|
||||||
// 标记已完成
|
|
||||||
if ($this->complete_at) {
|
|
||||||
throw new ApiException('任务已完成');
|
|
||||||
}
|
|
||||||
$this->completeTask(Carbon::now());
|
|
||||||
} else {
|
|
||||||
// 标记未完成
|
|
||||||
if (!$this->complete_at) {
|
|
||||||
throw new ApiException('未完成任务');
|
|
||||||
}
|
|
||||||
$this->completeTask(null);
|
|
||||||
}
|
|
||||||
$updateMarking['is_update_project'] = true;
|
|
||||||
}
|
|
||||||
// 标题
|
// 标题
|
||||||
if (Arr::exists($data, 'name') && $this->name != $data['name']) {
|
if (Arr::exists($data, 'name') && $this->name != $data['name']) {
|
||||||
if (empty($data['name'])) {
|
if (empty($data['name'])) {
|
||||||
@ -622,19 +395,14 @@ class ProjectTask extends AbstractModel
|
|||||||
} elseif (mb_strlen($data['name']) > 255) {
|
} elseif (mb_strlen($data['name']) > 255) {
|
||||||
throw new ApiException('任务描述最多只能设置255个字');
|
throw new ApiException('任务描述最多只能设置255个字');
|
||||||
}
|
}
|
||||||
$this->addLog("修改{任务}标题", [
|
$this->addLog("修改{任务}标题:{$this->name} => {$data['name']}");
|
||||||
'change' => [$this->name, $data['name']]
|
|
||||||
]);
|
|
||||||
$this->name = $data['name'];
|
$this->name = $data['name'];
|
||||||
}
|
}
|
||||||
// 负责人
|
// 负责人
|
||||||
if (Arr::exists($data, 'owner')) {
|
if (Arr::exists($data, 'owner')) {
|
||||||
$count = $this->taskUser->where('owner', 1)->count();
|
$count = $this->taskUser->count();
|
||||||
$array = [];
|
$array = [];
|
||||||
$owner = is_array($data['owner']) ? $data['owner'] : [$data['owner']];
|
$owner = is_array($data['owner']) ? $data['owner'] : [$data['owner']];
|
||||||
if (count($owner) > 10) {
|
|
||||||
throw new ApiException('任务负责人最多不能超过10个');
|
|
||||||
}
|
|
||||||
foreach ($owner as $uid) {
|
foreach ($owner as $uid) {
|
||||||
if (intval($uid) == 0) continue;
|
if (intval($uid) == 0) continue;
|
||||||
if (!$this->project->useridInTheProject($uid)) continue;
|
if (!$this->project->useridInTheProject($uid)) continue;
|
||||||
@ -656,90 +424,31 @@ class ProjectTask extends AbstractModel
|
|||||||
if ($count == 0 && count($array) == 1 && $array[0] == User::userid()) {
|
if ($count == 0 && count($array) == 1 && $array[0] == User::userid()) {
|
||||||
$this->addLog("认领{任务}");
|
$this->addLog("认领{任务}");
|
||||||
} else {
|
} else {
|
||||||
$this->addLog("修改{任务}负责人", ['userid' => $array]);
|
$this->addLog("修改{任务}负责人:" . implode(",", $array));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$rows = ProjectTaskUser::whereTaskId($this->id)->whereOwner(1)->whereNotIn('userid', $array)->get();
|
$rows = ProjectTaskUser::whereTaskId($this->id)->whereOwner(1)->whereNotIn('userid', $array)->get();
|
||||||
if ($rows->isNotEmpty()) {
|
if ($rows->isNotEmpty()) {
|
||||||
$this->addLog("删除{任务}负责人", ['userid' => $rows->implode('userid', ',')]);
|
$this->addLog("删除{任务}负责人:" . $rows->implode('userid', ','));
|
||||||
foreach ($rows as $row) {
|
foreach ($rows as $row) {
|
||||||
$row->delete();
|
$row->delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$updateMarking['is_update_project'] = true;
|
|
||||||
$this->syncDialogUser();
|
$this->syncDialogUser();
|
||||||
}
|
}
|
||||||
// 计划时间(原则:子任务时间在主任务时间内)
|
// 计划时间
|
||||||
if (Arr::exists($data, 'times')) {
|
if (Arr::exists($data, 'times')) {
|
||||||
$oldAt = [Carbon::parse($this->start_at), Carbon::parse($this->end_at)];
|
|
||||||
$oldStringAt = $this->start_at ? ($oldAt[0]->toDateTimeString() . '~' . $oldAt[1]->toDateTimeString()) : '';
|
|
||||||
$this->start_at = null;
|
$this->start_at = null;
|
||||||
$this->end_at = null;
|
$this->end_at = null;
|
||||||
$times = $data['times'];
|
$times = $data['times'];
|
||||||
list($start, $end) = is_string($times) ? explode(",", $times) : (is_array($times) ? $times : []);
|
list($start, $end) = is_string($times) ? explode(",", $times) : (is_array($times) ? $times : []);
|
||||||
if (Base::isDate($start) && Base::isDate($end) && $start != $end) {
|
if (Base::isDate($start) && Base::isDate($end)) {
|
||||||
$start_at = Carbon::parse($start);
|
if ($start != $end) {
|
||||||
$end_at = Carbon::parse($end);
|
$this->start_at = Carbon::parse($start);
|
||||||
if ($this->parent_id > 0) {
|
$this->end_at = Carbon::parse($end);
|
||||||
// 判断同步主任务时间(子任务时间 超出 主任务)
|
|
||||||
if ($mainTask) {
|
|
||||||
$isUp = false;
|
|
||||||
if ($start_at->lt(Carbon::parse($mainTask->start_at))) {
|
|
||||||
$mainTask->start_at = $start_at;
|
|
||||||
$isUp = true;
|
|
||||||
}
|
|
||||||
if ($end_at->gt(Carbon::parse($mainTask->end_at))) {
|
|
||||||
$mainTask->end_at = $end_at;
|
|
||||||
$isUp = true;
|
|
||||||
}
|
|
||||||
if ($isUp) {
|
|
||||||
$updateMarking['is_update_maintask'] = true;
|
|
||||||
$mainTask->addLog("同步修改{任务}时间");
|
|
||||||
$mainTask->save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$this->start_at = $start_at;
|
|
||||||
$this->end_at = $end_at;
|
|
||||||
} else {
|
|
||||||
if ($this->parent_id > 0) {
|
|
||||||
// 清空子任务时间(子任务时间等于主任务时间)
|
|
||||||
$this->start_at = $mainTask->start_at;
|
|
||||||
$this->end_at = $mainTask->end_at;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($this->parent_id == 0) {
|
$this->addLog("修改{任务}时间");
|
||||||
// 判断同步子任务时间(主任务时间 不在 子任务时间 之外)
|
|
||||||
self::whereParentId($this->id)->chunk(100, function($list) use ($oldAt, &$updateMarking) {
|
|
||||||
/** @var self $subTask */
|
|
||||||
foreach ($list as $subTask) {
|
|
||||||
$start_at = Carbon::parse($subTask->start_at);
|
|
||||||
$end_at = Carbon::parse($subTask->end_at);
|
|
||||||
$isUp = false;
|
|
||||||
if (empty($subTask->start_at) || $start_at->eq($oldAt[0]) || $start_at->lt(Carbon::parse($this->start_at))) {
|
|
||||||
$subTask->start_at = $this->start_at;
|
|
||||||
$isUp = true;
|
|
||||||
}
|
|
||||||
if (empty($subTask->end_at) || $end_at->eq($oldAt[1]) || $end_at->gt(Carbon::parse($this->end_at))) {
|
|
||||||
$subTask->end_at = $this->end_at;
|
|
||||||
$isUp = true;
|
|
||||||
}
|
|
||||||
if ($subTask->start_at && Carbon::parse($subTask->start_at)->gt($subTask->end_at)) {
|
|
||||||
$subTask->start_at = $this->start_at;
|
|
||||||
$isUp = true;
|
|
||||||
}
|
|
||||||
if ($isUp) {
|
|
||||||
$updateMarking['is_update_subtask'] = true;
|
|
||||||
$subTask->addLog("同步修改{任务}时间");
|
|
||||||
$subTask->save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
$newStringAt = $this->start_at ? ($this->start_at->toDateTimeString() . '~' . $this->end_at->toDateTimeString()) : '';
|
|
||||||
$this->addLog("修改{任务}时间", [
|
|
||||||
'change' => [$oldStringAt, $newStringAt]
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
// 以下紧顶级任务可修改
|
// 以下紧顶级任务可修改
|
||||||
if ($this->parent_id === 0) {
|
if ($this->parent_id === 0) {
|
||||||
@ -747,9 +456,6 @@ class ProjectTask extends AbstractModel
|
|||||||
if (Arr::exists($data, 'assist')) {
|
if (Arr::exists($data, 'assist')) {
|
||||||
$array = [];
|
$array = [];
|
||||||
$assist = is_array($data['assist']) ? $data['assist'] : [$data['assist']];
|
$assist = is_array($data['assist']) ? $data['assist'] : [$data['assist']];
|
||||||
if (count($assist) > 10) {
|
|
||||||
throw new ApiException('任务协助人员最多不能超过10个');
|
|
||||||
}
|
|
||||||
foreach ($assist as $uid) {
|
foreach ($assist as $uid) {
|
||||||
if (intval($uid) == 0) continue;
|
if (intval($uid) == 0) continue;
|
||||||
if (!$this->project->useridInTheProject($uid)) continue;
|
if (!$this->project->useridInTheProject($uid)) continue;
|
||||||
@ -759,17 +465,17 @@ class ProjectTask extends AbstractModel
|
|||||||
'userid' => $uid,
|
'userid' => $uid,
|
||||||
], [
|
], [
|
||||||
'project_id' => $this->project_id,
|
'project_id' => $this->project_id,
|
||||||
'task_pid' => $this->id,
|
'task_pid' => $this->parent_id ?: $this->id,
|
||||||
'owner' => 0,
|
'owner' => 0,
|
||||||
]);
|
]);
|
||||||
$array[] = $uid;
|
$array[] = $uid;
|
||||||
}
|
}
|
||||||
if ($array) {
|
if ($array) {
|
||||||
$this->addLog("修改{任务}协助人员", ['userid' => $array]);
|
$this->addLog("修改{任务}协助人员:" . implode(",", $array));
|
||||||
}
|
}
|
||||||
$rows = ProjectTaskUser::whereTaskId($this->id)->whereOwner(0)->whereNotIn('userid', $array)->get();
|
$rows = ProjectTaskUser::whereTaskId($this->id)->whereOwner(0)->whereNotIn('userid', $array)->get();
|
||||||
if ($rows->isNotEmpty()) {
|
if ($rows->isNotEmpty()) {
|
||||||
$this->addLog("删除{任务}协助人员", ['userid' => $rows->implode('userid', ',')]);
|
$this->addLog("删除{任务}协助人员:" . $rows->implode('userid', ','));
|
||||||
foreach ($rows as $row) {
|
foreach ($rows as $row) {
|
||||||
$row->delete();
|
$row->delete();
|
||||||
}
|
}
|
||||||
@ -778,9 +484,7 @@ class ProjectTask extends AbstractModel
|
|||||||
}
|
}
|
||||||
// 背景色
|
// 背景色
|
||||||
if (Arr::exists($data, 'color') && $this->color != $data['color']) {
|
if (Arr::exists($data, 'color') && $this->color != $data['color']) {
|
||||||
$this->addLog("修改{任务}背景色", [
|
$this->addLog("修改{任务}背景色:{$this->color} => {$data['color']}");
|
||||||
'change' => [$this->color, $data['color']]
|
|
||||||
]);
|
|
||||||
$this->color = $data['color'];
|
$this->color = $data['color'];
|
||||||
}
|
}
|
||||||
// 列表
|
// 列表
|
||||||
@ -790,9 +494,7 @@ class ProjectTask extends AbstractModel
|
|||||||
if (empty($column)) {
|
if (empty($column)) {
|
||||||
throw new ApiException('请选择正确的列表');
|
throw new ApiException('请选择正确的列表');
|
||||||
}
|
}
|
||||||
$this->addLog("修改{任务}列表", [
|
$this->addLog("修改{任务}列表:{$oldName} => {$column->name}");
|
||||||
'change' => [$oldName, $column->name]
|
|
||||||
]);
|
|
||||||
$this->column_id = $column->id;
|
$this->column_id = $column->id;
|
||||||
}
|
}
|
||||||
// 内容
|
// 内容
|
||||||
@ -803,13 +505,12 @@ class ProjectTask extends AbstractModel
|
|||||||
], [
|
], [
|
||||||
'content' => $data['content'],
|
'content' => $data['content'],
|
||||||
]);
|
]);
|
||||||
$this->desc = Base::getHtml($data['content'], 100);
|
$this->desc = Base::getHtml($data['content']);
|
||||||
$this->addLog("修改{任务}详细描述");
|
$this->addLog("修改{任务}详细描述");
|
||||||
$updateMarking['is_update_content'] = true;
|
$updateContent = true;
|
||||||
}
|
}
|
||||||
// 优先级
|
// 优先级
|
||||||
$p = false;
|
$p = false;
|
||||||
$oldPName = $this->p_name;
|
|
||||||
if (Arr::exists($data, 'p_level') && $this->p_level != $data['p_level']) {
|
if (Arr::exists($data, 'p_level') && $this->p_level != $data['p_level']) {
|
||||||
$this->p_level = intval($data['p_level']);
|
$this->p_level = intval($data['p_level']);
|
||||||
$p = true;
|
$p = true;
|
||||||
@ -823,9 +524,7 @@ class ProjectTask extends AbstractModel
|
|||||||
$p = true;
|
$p = true;
|
||||||
}
|
}
|
||||||
if ($p) {
|
if ($p) {
|
||||||
$this->addLog("修改{任务}优先级", [
|
$this->addLog("修改{任务}优先级");
|
||||||
'change' => [$oldPName, $this->p_name]
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->save();
|
$this->save();
|
||||||
@ -842,7 +541,9 @@ class ProjectTask extends AbstractModel
|
|||||||
{
|
{
|
||||||
if ($this->parent_id > 0) {
|
if ($this->parent_id > 0) {
|
||||||
$task = self::find($this->parent_id);
|
$task = self::find($this->parent_id);
|
||||||
$task?->syncDialogUser();
|
if ($task) {
|
||||||
|
$task->syncDialogUser();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (empty($this->dialog_id)) {
|
if (empty($this->dialog_id)) {
|
||||||
@ -866,7 +567,7 @@ class ProjectTask extends AbstractModel
|
|||||||
*/
|
*/
|
||||||
public function relationUserids()
|
public function relationUserids()
|
||||||
{
|
{
|
||||||
$userids = ProjectTaskUser::whereTaskId($this->id)->orderByDesc('owner')->orderByDesc('id')->pluck('userid')->toArray();
|
$userids = $this->taskUser->pluck('userid')->toArray();
|
||||||
$items = ProjectTask::with(['taskUser'])->where('parent_id', $this->id)->whereNull('archived_at')->get();
|
$items = ProjectTask::with(['taskUser'])->where('parent_id', $this->id)->whereNull('archived_at')->get();
|
||||||
foreach ($items as $item) {
|
foreach ($items as $item) {
|
||||||
$userids = array_merge($userids, $item->taskUser->pluck('userid')->toArray());
|
$userids = array_merge($userids, $item->taskUser->pluck('userid')->toArray());
|
||||||
@ -902,74 +603,6 @@ class ProjectTask extends AbstractModel
|
|||||||
return $user->owner ? 2 : 1;
|
return $user->owner ? 2 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 权限版本
|
|
||||||
* @param int $level 1-负责人,2-协助人/负责人,3-创建人/协助人/负责人
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function permission($level = 1)
|
|
||||||
{
|
|
||||||
if ($level >= 3 && $this->isCreater()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if ($level >= 2 && $this->isAssister()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return $this->isOwner();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断是否创建者
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isCreater()
|
|
||||||
{
|
|
||||||
return $this->userid == User::userid();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断是否协助人员
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isAssister()
|
|
||||||
{
|
|
||||||
$row = $this;
|
|
||||||
while ($row->parent_id > 0) {
|
|
||||||
$row = self::find($row->parent_id);
|
|
||||||
}
|
|
||||||
return ProjectTaskUser::whereTaskId($row->id)->whereUserid(User::userid())->whereOwner(0)->exists();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断是否负责人(或者是主任务的负责人)
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isOwner()
|
|
||||||
{
|
|
||||||
if ($this->owner) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if ($this->parent_id > 0) {
|
|
||||||
$mainTask = self::allData()->find($this->parent_id);
|
|
||||||
if ($mainTask->owner) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否有负责人
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function hasOwner()
|
|
||||||
{
|
|
||||||
if (!isset($this->appendattrs['has_owner'])) {
|
|
||||||
$this->appendattrs['has_owner'] = ProjectTaskUser::whereTaskId($this->id)->whereOwner(1)->exists();
|
|
||||||
}
|
|
||||||
return $this->appendattrs['has_owner'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 标记已完成、未完成
|
* 标记已完成、未完成
|
||||||
* @param Carbon|null $complete_at 完成时间
|
* @param Carbon|null $complete_at 完成时间
|
||||||
@ -981,7 +614,7 @@ class ProjectTask extends AbstractModel
|
|||||||
if ($complete_at === null) {
|
if ($complete_at === null) {
|
||||||
// 标记未完成
|
// 标记未完成
|
||||||
$this->complete_at = null;
|
$this->complete_at = null;
|
||||||
$this->addLog("标记{任务}未完成");
|
$this->addLog("{任务}标记未完成:" . $this->name);
|
||||||
} else {
|
} else {
|
||||||
// 标记已完成
|
// 标记已完成
|
||||||
if ($this->parent_id == 0) {
|
if ($this->parent_id == 0) {
|
||||||
@ -989,11 +622,8 @@ class ProjectTask extends AbstractModel
|
|||||||
throw new ApiException('子任务未完成');
|
throw new ApiException('子任务未完成');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!$this->hasOwner()) {
|
|
||||||
throw new ApiException('请先领取任务');
|
|
||||||
}
|
|
||||||
$this->complete_at = $complete_at;
|
$this->complete_at = $complete_at;
|
||||||
$this->addLog("标记{任务}已完成");
|
$this->addLog("{任务}标记已完成:" . $this->name);
|
||||||
}
|
}
|
||||||
$this->save();
|
$this->save();
|
||||||
});
|
});
|
||||||
@ -1005,49 +635,26 @@ class ProjectTask extends AbstractModel
|
|||||||
* @param Carbon|null $archived_at 归档时间
|
* @param Carbon|null $archived_at 归档时间
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function archivedTask($archived_at, $isAuto = false)
|
public function archivedTask($archived_at)
|
||||||
{
|
{
|
||||||
if (!$this->complete_at) {
|
AbstractModel::transaction(function () use ($archived_at) {
|
||||||
$flowItems = ProjectFlowItem::whereProjectId($this->project_id)->whereStatus('end')->pluck('name');
|
|
||||||
if ($flowItems) {
|
|
||||||
$flowItems = implode(",", array_values(array_unique($flowItems->toArray())));
|
|
||||||
}
|
|
||||||
if (empty($flowItems)) {
|
|
||||||
$flowItems = "已完成";
|
|
||||||
}
|
|
||||||
throw new ApiException('仅限【' . $flowItems . '】状态的任务归档');
|
|
||||||
}
|
|
||||||
AbstractModel::transaction(function () use ($isAuto, $archived_at) {
|
|
||||||
if ($archived_at === null) {
|
if ($archived_at === null) {
|
||||||
// 取消归档
|
// 取消归档
|
||||||
$this->archived_at = null;
|
$this->archived_at = null;
|
||||||
$this->archived_userid = User::userid();
|
|
||||||
$this->archived_follow = 0;
|
$this->archived_follow = 0;
|
||||||
$this->addLog("任务取消归档");
|
$this->addLog("任务取消归档:" . $this->name);
|
||||||
|
$this->pushMsg('add', [
|
||||||
|
'new_column' => null,
|
||||||
|
'task' => ProjectTask::with(['taskUser', 'taskTag'])->find($this->id),
|
||||||
|
]);
|
||||||
} else {
|
} else {
|
||||||
// 归档任务
|
// 归档任务
|
||||||
if ($isAuto === true) {
|
|
||||||
$logText = "自动任务归档";
|
|
||||||
$userid = 0;
|
|
||||||
} else {
|
|
||||||
$logText = "任务归档";
|
|
||||||
$userid = User::userid();
|
|
||||||
}
|
|
||||||
$this->archived_at = $archived_at;
|
$this->archived_at = $archived_at;
|
||||||
$this->archived_userid = $userid;
|
$this->archived_userid = User::userid();
|
||||||
$this->archived_follow = 0;
|
$this->archived_follow = 0;
|
||||||
$this->addLog($logText, [], $userid);
|
$this->addLog("任务归档:" . $this->name);
|
||||||
|
$this->pushMsg('archived');
|
||||||
}
|
}
|
||||||
$this->pushMsg('update', [
|
|
||||||
'id' => $this->id,
|
|
||||||
'archived_at' => $this->archived_at,
|
|
||||||
'archived_userid' => $this->archived_userid,
|
|
||||||
]);
|
|
||||||
self::whereParentId($this->id)->update([
|
|
||||||
'archived_at' => $this->archived_at,
|
|
||||||
'archived_userid' => $this->archived_userid,
|
|
||||||
'archived_follow' => $this->archived_follow,
|
|
||||||
]);
|
|
||||||
$this->save();
|
$this->save();
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
@ -1063,11 +670,12 @@ class ProjectTask extends AbstractModel
|
|||||||
AbstractModel::transaction(function () {
|
AbstractModel::transaction(function () {
|
||||||
if ($this->dialog_id) {
|
if ($this->dialog_id) {
|
||||||
$dialog = WebSocketDialog::find($this->dialog_id);
|
$dialog = WebSocketDialog::find($this->dialog_id);
|
||||||
$dialog?->deleteDialog();
|
if ($dialog) {
|
||||||
|
$dialog->deleteDialog();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self::whereParentId($this->id)->delete();
|
|
||||||
$this->addLog("删除{任务}");
|
|
||||||
$this->delete();
|
$this->delete();
|
||||||
|
$this->addLog("删除{任务}:" . $this->name);
|
||||||
});
|
});
|
||||||
if ($pushMsg) {
|
if ($pushMsg) {
|
||||||
$this->pushMsg('delete');
|
$this->pushMsg('delete');
|
||||||
@ -1078,27 +686,19 @@ class ProjectTask extends AbstractModel
|
|||||||
/**
|
/**
|
||||||
* 添加任务日志
|
* 添加任务日志
|
||||||
* @param string $detail
|
* @param string $detail
|
||||||
* @param array $record
|
|
||||||
* @param int $userid
|
* @param int $userid
|
||||||
* @return ProjectLog
|
* @return ProjectLog
|
||||||
*/
|
*/
|
||||||
public function addLog($detail, $record = [], $userid = 0)
|
public function addLog($detail, $userid = 0)
|
||||||
{
|
{
|
||||||
$detail = str_replace("{任务}", $this->parent_id ? "子任务" : "任务", $detail);
|
$detail = str_replace("{任务}", $this->parent_id > 0 ? "子任务" : "任务", $detail);
|
||||||
$array = [
|
$log = ProjectLog::createInstance([
|
||||||
'project_id' => $this->project_id,
|
'project_id' => $this->project_id,
|
||||||
'column_id' => $this->column_id,
|
'column_id' => $this->column_id,
|
||||||
'task_id' => $this->parent_id ?: $this->id,
|
'task_id' => $this->parent_id ?: $this->id,
|
||||||
'userid' => $userid ?: User::userid(),
|
'userid' => $userid ?: User::userid(),
|
||||||
'detail' => $detail,
|
'detail' => $detail,
|
||||||
];
|
]);
|
||||||
if ($this->parent_id) {
|
|
||||||
$record['subtitle'] = $this->name;
|
|
||||||
}
|
|
||||||
if ($record) {
|
|
||||||
$array['record'] = $record;
|
|
||||||
}
|
|
||||||
$log = ProjectLog::createInstance($array);
|
|
||||||
$log->save();
|
$log->save();
|
||||||
return $log;
|
return $log;
|
||||||
}
|
}
|
||||||
@ -1106,8 +706,8 @@ class ProjectTask extends AbstractModel
|
|||||||
/**
|
/**
|
||||||
* 推送消息
|
* 推送消息
|
||||||
* @param string $action
|
* @param string $action
|
||||||
* @param array|self $data 发送内容,默认为[id, parent_id, project_id, column_id, dialog_id]
|
* @param array $data 发送内容,默认为[id, parent_id, project_id, column_id, dialog_id]
|
||||||
* @param array $userid 指定会员,默认为项目所有成员
|
* @param array $userid 指定会员,默认为项目所有成员
|
||||||
*/
|
*/
|
||||||
public function pushMsg($action, $data = null, $userid = null)
|
public function pushMsg($action, $data = null, $userid = null)
|
||||||
{
|
{
|
||||||
@ -1122,88 +722,52 @@ class ProjectTask extends AbstractModel
|
|||||||
'column_id' => $this->column_id,
|
'column_id' => $this->column_id,
|
||||||
'dialog_id' => $this->dialog_id,
|
'dialog_id' => $this->dialog_id,
|
||||||
];
|
];
|
||||||
} elseif ($data instanceof self) {
|
|
||||||
$data = $data->toArray();
|
|
||||||
}
|
}
|
||||||
//
|
|
||||||
$array = [$userid, []];
|
|
||||||
if ($userid === null) {
|
if ($userid === null) {
|
||||||
$array[0] = $this->project->relationUserids();
|
$userid = $this->project->relationUserids();
|
||||||
} elseif (!is_array($userid)) {
|
|
||||||
$array[0] = [$userid];
|
|
||||||
}
|
|
||||||
//
|
|
||||||
if (isset($data['owner'])) {
|
|
||||||
$owners = ProjectTaskUser::whereTaskId($data['id'])->whereOwner(1)->pluck('userid')->toArray();
|
|
||||||
$array = [array_intersect($array[0], $owners), array_diff($array[0], $owners)];
|
|
||||||
}
|
|
||||||
foreach ($array as $index => $item) {
|
|
||||||
if ($index > 0) {
|
|
||||||
$data['owner'] = 0;
|
|
||||||
}
|
|
||||||
$params = [
|
|
||||||
'ignoreFd' => Request::header('fd'),
|
|
||||||
'userid' => array_values($item),
|
|
||||||
'msg' => [
|
|
||||||
'type' => 'projectTask',
|
|
||||||
'action' => $action,
|
|
||||||
'data' => $data,
|
|
||||||
]
|
|
||||||
];
|
|
||||||
$task = new PushTask($params, false);
|
|
||||||
Task::deliver($task);
|
|
||||||
}
|
}
|
||||||
|
$params = [
|
||||||
|
'ignoreFd' => Request::header('fd'),
|
||||||
|
'userid' => $userid,
|
||||||
|
'msg' => [
|
||||||
|
'type' => 'projectTask',
|
||||||
|
'action' => $action,
|
||||||
|
'data' => $data,
|
||||||
|
]
|
||||||
|
];
|
||||||
|
$task = new PushTask($params, false);
|
||||||
|
Task::deliver($task);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取任务
|
* 根据会员ID获取任务、项目信息(会员有任务权限 或 会员存在项目内)
|
||||||
* @param $task_id
|
|
||||||
* @return ProjectTask|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|null
|
|
||||||
*/
|
|
||||||
public static function oneTask($task_id)
|
|
||||||
{
|
|
||||||
return self::with(['taskUser', 'taskTag'])->allData()->where("project_tasks.id", intval($task_id))->first();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取任务(会员有任务权限 或 会员存在项目内)
|
|
||||||
* @param int $task_id
|
* @param int $task_id
|
||||||
* @param bool $archived true:仅限未归档, false:仅限已归档, null:不限制
|
|
||||||
* @param int|bool $permission 0|false:不限制, 1|true:限制项目负责人、任务负责人、协助人员及任务创建者, 2:已有负责人才限制true (子任务时如果是主任务负责人也可以)
|
|
||||||
* @param array $with
|
* @param array $with
|
||||||
|
* @param bool $ignoreArchived 排除已归档
|
||||||
|
* @param null $project
|
||||||
* @return self
|
* @return self
|
||||||
*/
|
*/
|
||||||
public static function userTask($task_id, $archived = true, $permission = 0, $with = [])
|
public static function userTask($task_id, $with = [], $ignoreArchived = true, &$project = null)
|
||||||
{
|
{
|
||||||
$task = self::with($with)->allData()->where("project_tasks.id", intval($task_id))->first();
|
$task = self::with($with)->whereId(intval($task_id))->first();
|
||||||
//
|
|
||||||
if (empty($task)) {
|
if (empty($task)) {
|
||||||
throw new ApiException('任务不存在', [ 'task_id' => $task_id ], -4002);
|
throw new ApiException('任务不存在', [ 'task_id' => $task_id ], -4002);
|
||||||
}
|
}
|
||||||
if ($archived === true && $task->archived_at != null) {
|
if ($ignoreArchived && $task->archived_at != null) {
|
||||||
throw new ApiException('任务已归档', [ 'task_id' => $task_id ]);
|
throw new ApiException('任务已归档', [ 'task_id' => $task_id ], -4002);
|
||||||
}
|
|
||||||
if ($archived === false && $task->archived_at == null) {
|
|
||||||
throw new ApiException('任务未归档', [ 'task_id' => $task_id ]);
|
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
try {
|
try {
|
||||||
$project = Project::userProject($task->project_id);
|
$project = Project::userProject($task->project_id, $ignoreArchived);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
if ($task->owner === null) {
|
if (ProjectTaskUser::whereUserid(User::userid())->whereTaskPid($task->id)->exists()) {
|
||||||
|
$project = Project::find($task->project_id);
|
||||||
|
if (empty($project)) {
|
||||||
|
throw new ApiException('项目不存在或已被删除', [ 'task_id' => $task_id ], -4002);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
throw new ApiException($e->getMessage(), [ 'task_id' => $task_id ], -4002);
|
throw new ApiException($e->getMessage(), [ 'task_id' => $task_id ], -4002);
|
||||||
}
|
}
|
||||||
$project = Project::find($task->project_id);
|
|
||||||
if (empty($project)) {
|
|
||||||
throw new ApiException('项目不存在或已被删除', [ 'task_id' => $task_id ], -4002);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//
|
|
||||||
if ($permission === 2) {
|
|
||||||
$permission = $task->hasOwner() ? 1 : 0;
|
|
||||||
}
|
|
||||||
if (($permission === 1 || $permission === true) && !$project->owner && !$task->permission(3)) {
|
|
||||||
throw new ApiException('仅限项目负责人、任务负责人、协助人员或任务创建者操作');
|
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
return $task;
|
return $task;
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App\Models\ProjectTaskContent
|
* Class ProjectTaskContent
|
||||||
*
|
*
|
||||||
|
* @package App\Models
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property int|null $project_id 项目ID
|
* @property int|null $project_id 项目ID
|
||||||
* @property int|null $task_id 任务ID
|
* @property int|null $task_id 任务ID
|
||||||
|
@ -5,16 +5,17 @@ namespace App\Models;
|
|||||||
use App\Module\Base;
|
use App\Module\Base;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App\Models\ProjectTaskFile
|
* Class ProjectTaskFile
|
||||||
*
|
*
|
||||||
|
* @package App\Models
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property int|null $project_id 项目ID
|
* @property int|null $project_id 项目ID
|
||||||
* @property int|null $task_id 任务ID
|
* @property int|null $task_id 任务ID
|
||||||
* @property string|null $name 文件名称
|
* @property string|null $name 文件名称
|
||||||
* @property int|null $size 文件大小(B)
|
* @property int|null $size 文件大小(B)
|
||||||
* @property string|null $ext 文件格式
|
* @property string|null $ext 文件格式
|
||||||
* @property string $path 文件地址
|
* @property string|null $path 文件地址
|
||||||
* @property string $thumb 缩略图
|
* @property string|null $thumb 缩略图
|
||||||
* @property int|null $userid 上传用户ID
|
* @property int|null $userid 上传用户ID
|
||||||
* @property int|null $download 下载次数
|
* @property int|null $download 下载次数
|
||||||
* @property \Illuminate\Support\Carbon|null $created_at
|
* @property \Illuminate\Support\Carbon|null $created_at
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* App\Models\ProjectTaskFlowChange
|
|
||||||
*
|
|
||||||
* @property int $id
|
|
||||||
* @property int|null $task_id 任务ID
|
|
||||||
* @property int|null $userid 会员ID
|
|
||||||
* @property int|null $before_flow_item_id (变化前)工作流状态ID
|
|
||||||
* @property string|null $before_flow_item_name (变化前)工作流状态名称
|
|
||||||
* @property int|null $after_flow_item_id (变化后)工作流状态ID
|
|
||||||
* @property string|null $after_flow_item_name (变化后)工作流状态名称
|
|
||||||
* @property \Illuminate\Support\Carbon|null $created_at
|
|
||||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskFlowChange newModelQuery()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskFlowChange newQuery()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskFlowChange query()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskFlowChange whereAfterFlowItemId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskFlowChange whereAfterFlowItemName($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskFlowChange whereBeforeFlowItemId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskFlowChange whereBeforeFlowItemName($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskFlowChange whereCreatedAt($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskFlowChange whereId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskFlowChange whereTaskId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskFlowChange whereUpdatedAt($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTaskFlowChange whereUserid($value)
|
|
||||||
* @mixin \Eloquent
|
|
||||||
*/
|
|
||||||
class ProjectTaskFlowChange extends AbstractModel
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
@ -3,8 +3,9 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App\Models\ProjectTaskTag
|
* Class ProjectTaskTag
|
||||||
*
|
*
|
||||||
|
* @package App\Models
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property int|null $project_id 项目ID
|
* @property int|null $project_id 项目ID
|
||||||
* @property int|null $task_id 任务ID
|
* @property int|null $task_id 任务ID
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App\Models\ProjectTaskUser
|
* Class ProjectTaskUser
|
||||||
*
|
*
|
||||||
|
* @package App\Models
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property int|null $project_id 项目ID
|
* @property int|null $project_id 项目ID
|
||||||
* @property int|null $task_id 任务ID
|
* @property int|null $task_id 任务ID
|
||||||
|
@ -5,13 +5,13 @@ namespace App\Models;
|
|||||||
use App\Module\Base;
|
use App\Module\Base;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App\Models\ProjectUser
|
* Class ProjectUser
|
||||||
*
|
*
|
||||||
|
* @package App\Models
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property int|null $project_id 项目ID
|
* @property int|null $project_id 项目ID
|
||||||
* @property int|null $userid 成员ID
|
* @property int|null $userid 成员ID
|
||||||
* @property int|null $owner 是否负责人
|
* @property int|null $owner 是否负责人
|
||||||
* @property string|null $top_at 置顶时间
|
|
||||||
* @property \Illuminate\Support\Carbon|null $created_at
|
* @property \Illuminate\Support\Carbon|null $created_at
|
||||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||||
* @property-read \App\Models\Project|null $project
|
* @property-read \App\Models\Project|null $project
|
||||||
@ -22,7 +22,6 @@ use App\Module\Base;
|
|||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectUser whereId($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectUser whereId($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectUser whereOwner($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectUser whereOwner($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectUser whereProjectId($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectUser whereProjectId($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectUser whereTopAt($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectUser whereUpdatedAt($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectUser whereUpdatedAt($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ProjectUser whereUserid($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|ProjectUser whereUserid($value)
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
@ -43,21 +42,12 @@ class ProjectUser extends AbstractModel
|
|||||||
*/
|
*/
|
||||||
public function exitProject()
|
public function exitProject()
|
||||||
{
|
{
|
||||||
ProjectTaskUser::whereProjectId($this->project_id)
|
$tasks = ProjectTask::whereProjectId($this->project_id)->authData($this->userid)->get();
|
||||||
->whereUserid($this->userid)
|
foreach ($tasks as $task) {
|
||||||
->chunk(100, function ($list) {
|
if (ProjectTaskUser::whereTaskId($task->id)->whereUserid($this->userid)->delete()) {
|
||||||
$tastIds = [];
|
$task->syncDialogUser();
|
||||||
foreach ($list as $item) {
|
}
|
||||||
if (!in_array($item->task_pid, $tastIds)) {
|
}
|
||||||
$tastIds[] = $item->task_pid;
|
|
||||||
}
|
|
||||||
$item->delete();
|
|
||||||
}
|
|
||||||
$tasks = ProjectTask::whereIn('id', $tastIds)->get();
|
|
||||||
foreach ($tasks as $task) {
|
|
||||||
$task->syncDialogUser();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$this->delete();
|
$this->delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,158 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use App\Exceptions\ApiException;
|
|
||||||
use Carbon\Carbon;
|
|
||||||
use Carbon\Traits\Creator;
|
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
||||||
use JetBrains\PhpStorm\Pure;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* App\Models\Report
|
|
||||||
*
|
|
||||||
* @property int $id
|
|
||||||
* @property \Illuminate\Support\Carbon|null $created_at
|
|
||||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
|
||||||
* @property string $title 标题
|
|
||||||
* @property string $type 汇报类型
|
|
||||||
* @property int $userid
|
|
||||||
* @property string $content
|
|
||||||
* @property string $sign 汇报唯一标识
|
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection|\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 int|null $receives_user_count
|
|
||||||
* @property-read \App\Models\User|null $sendUser
|
|
||||||
* @method static Builder|Report newModelQuery()
|
|
||||||
* @method static Builder|Report newQuery()
|
|
||||||
* @method static Builder|Report query()
|
|
||||||
* @method static Builder|Report whereContent($value)
|
|
||||||
* @method static Builder|Report whereCreatedAt($value)
|
|
||||||
* @method static Builder|Report whereId($value)
|
|
||||||
* @method static Builder|Report whereSign($value)
|
|
||||||
* @method static Builder|Report whereTitle($value)
|
|
||||||
* @method static Builder|Report whereType($value)
|
|
||||||
* @method static Builder|Report whereUpdatedAt($value)
|
|
||||||
* @method static Builder|Report whereUserid($value)
|
|
||||||
* @mixin \Eloquent
|
|
||||||
*/
|
|
||||||
class Report extends AbstractModel
|
|
||||||
{
|
|
||||||
use HasFactory;
|
|
||||||
|
|
||||||
const WEEKLY = "weekly";
|
|
||||||
const DAILY = "daily";
|
|
||||||
|
|
||||||
protected $fillable = [
|
|
||||||
"title",
|
|
||||||
"type",
|
|
||||||
"userid",
|
|
||||||
"content",
|
|
||||||
];
|
|
||||||
|
|
||||||
protected $appends = [
|
|
||||||
'receives',
|
|
||||||
];
|
|
||||||
|
|
||||||
public function Receives(): HasMany
|
|
||||||
{
|
|
||||||
return $this->hasMany(ReportReceive::class, "rid");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function receivesUser(): BelongsToMany
|
|
||||||
{
|
|
||||||
return $this->belongsToMany(User::class, ReportReceive::class, "rid", "userid")
|
|
||||||
->withPivot("receive_time", "read");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function sendUser()
|
|
||||||
{
|
|
||||||
return $this->hasOne(User::class, "userid", "userid");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTypeAttribute($value): string
|
|
||||||
{
|
|
||||||
return match ($value) {
|
|
||||||
Report::WEEKLY => "周报",
|
|
||||||
Report::DAILY => "日报",
|
|
||||||
default => "",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getContentAttribute($value): string
|
|
||||||
{
|
|
||||||
return htmlspecialchars_decode($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getReceivesAttribute()
|
|
||||||
{
|
|
||||||
if (!isset($this->appendattrs['receives'])) {
|
|
||||||
$this->appendattrs['receives'] = empty( $this->receivesUser ) ? [] : array_column($this->receivesUser->toArray(), "userid");
|
|
||||||
}
|
|
||||||
return $this->appendattrs['receives'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取单条记录
|
|
||||||
* @param $id
|
|
||||||
* @param User|null $user
|
|
||||||
* @return Report|Builder|Model|object|null
|
|
||||||
* @throw ApiException
|
|
||||||
*/
|
|
||||||
public static function getOne($id, User $user = null)
|
|
||||||
{
|
|
||||||
$user === null && $user = User::auth();
|
|
||||||
$one = self::whereUserid($user->userid)->whereId($id)->first();
|
|
||||||
if ( empty($one) )
|
|
||||||
throw new ApiException("记录不存在");
|
|
||||||
return $one;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取最后一条提交记录
|
|
||||||
* @param User|null $user
|
|
||||||
* @return Builder|Model|\Illuminate\Database\Query\Builder|object
|
|
||||||
*/
|
|
||||||
public static function getLastOne(User $user = null)
|
|
||||||
{
|
|
||||||
$user === null && $user = User::auth();
|
|
||||||
$one = self::whereUserid($user->userid)->orderByDesc("created_at")->first();
|
|
||||||
if ( empty($one) )
|
|
||||||
throw new ApiException("记录不存在");
|
|
||||||
return $one;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 生成唯一标识
|
|
||||||
* @param $type
|
|
||||||
* @param $offset
|
|
||||||
* @param Carbon|null $time
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function generateSign($type, $offset, Carbon $time = null): string
|
|
||||||
{
|
|
||||||
$user = User::auth();
|
|
||||||
$now_dt = $time === null ? Carbon::now() : $time;
|
|
||||||
$time_s = match ($type) {
|
|
||||||
Report::WEEKLY => function() use ($now_dt, $offset) {
|
|
||||||
// 如果设置了周期偏移量
|
|
||||||
empty( $offset ) || $now_dt->subWeeks( abs( $offset ) );
|
|
||||||
$now_dt->startOfWeek(); // 设置为当周第一天
|
|
||||||
return $now_dt->year . $now_dt->weekOfYear;
|
|
||||||
},
|
|
||||||
Report::DAILY => function() use ($now_dt, $offset) {
|
|
||||||
// 如果设置了周期偏移量
|
|
||||||
empty( $offset ) || $now_dt->subDays( abs( $offset ) );
|
|
||||||
return $now_dt->format("Ymd");
|
|
||||||
},
|
|
||||||
default => "",
|
|
||||||
};
|
|
||||||
return $user->userid . ( is_callable($time_s) ? $time_s() : "" );
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* App\Models\ReportReceive
|
|
||||||
*
|
|
||||||
* @property int $id
|
|
||||||
* @property int $rid
|
|
||||||
* @property string|null $receive_time 接收时间
|
|
||||||
* @property int $userid 接收人
|
|
||||||
* @property int $read 是否已读
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ReportReceive newModelQuery()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ReportReceive newQuery()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ReportReceive query()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ReportReceive whereId($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ReportReceive whereRead($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ReportReceive whereReceiveTime($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ReportReceive whereRid($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|ReportReceive whereUserid($value)
|
|
||||||
* @mixin \Eloquent
|
|
||||||
*/
|
|
||||||
class ReportReceive extends AbstractModel
|
|
||||||
{
|
|
||||||
use HasFactory;
|
|
||||||
|
|
||||||
// 关闭时间戳自动写入
|
|
||||||
public $timestamps = false;
|
|
||||||
|
|
||||||
protected $fillable = [
|
|
||||||
"rid",
|
|
||||||
"receive_time",
|
|
||||||
"userid",
|
|
||||||
"read",
|
|
||||||
];
|
|
||||||
}
|
|
@ -3,8 +3,9 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App\Models\Setting
|
* Class Setting
|
||||||
*
|
*
|
||||||
|
* @package App\Models
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property string|null $name
|
* @property string|null $name
|
||||||
* @property string|null $desc 参数描述、备注
|
* @property string|null $desc 参数描述、备注
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App\Models\Tmp
|
* Class Tmp
|
||||||
*
|
*
|
||||||
|
* @package App\Models
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property string|null $name
|
* @property string|null $name
|
||||||
* @property string|null $value
|
* @property string|null $value
|
||||||
|
@ -9,8 +9,9 @@ use Cache;
|
|||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App\Models\User
|
* Class User
|
||||||
*
|
*
|
||||||
|
* @package App\Models
|
||||||
* @property int $userid
|
* @property int $userid
|
||||||
* @property array $identity 身份
|
* @property array $identity 身份
|
||||||
* @property string|null $az A-Z
|
* @property string|null $az A-Z
|
||||||
@ -28,10 +29,8 @@ use Carbon\Carbon;
|
|||||||
* @property string|null $line_at 最后在线时间(接口)
|
* @property string|null $line_at 最后在线时间(接口)
|
||||||
* @property int|null $task_dialog_id 最后打开的任务会话ID
|
* @property int|null $task_dialog_id 最后打开的任务会话ID
|
||||||
* @property string|null $created_ip 注册IP
|
* @property string|null $created_ip 注册IP
|
||||||
* @property string|null $disable_at 禁用时间
|
|
||||||
* @property \Illuminate\Support\Carbon|null $created_at
|
* @property \Illuminate\Support\Carbon|null $created_at
|
||||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||||
* @method static \Database\Factories\UserFactory factory(...$parameters)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|User newModelQuery()
|
* @method static \Illuminate\Database\Eloquent\Builder|User newModelQuery()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|User newQuery()
|
* @method static \Illuminate\Database\Eloquent\Builder|User newQuery()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|User query()
|
* @method static \Illuminate\Database\Eloquent\Builder|User query()
|
||||||
@ -39,7 +38,6 @@ use Carbon\Carbon;
|
|||||||
* @method static \Illuminate\Database\Eloquent\Builder|User whereChangepass($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|User whereChangepass($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|User whereCreatedAt($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|User whereCreatedAt($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|User whereCreatedIp($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|User whereCreatedIp($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|User whereDisableAt($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|User whereEmail($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|User whereEmail($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|User whereEncrypt($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|User whereEncrypt($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|User whereIdentity($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|User whereIdentity($value)
|
||||||
@ -62,7 +60,6 @@ class User extends AbstractModel
|
|||||||
protected $primaryKey = 'userid';
|
protected $primaryKey = 'userid';
|
||||||
|
|
||||||
protected $hidden = [
|
protected $hidden = [
|
||||||
'disable_at',
|
|
||||||
'updated_at',
|
'updated_at',
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -181,7 +178,7 @@ class User extends AbstractModel
|
|||||||
public static function reg($email, $password, $other = [])
|
public static function reg($email, $password, $other = [])
|
||||||
{
|
{
|
||||||
//邮箱
|
//邮箱
|
||||||
if (!Base::isEmail($email)) {
|
if (!Base::isMail($email)) {
|
||||||
throw new ApiException('请输入正确的邮箱地址');
|
throw new ApiException('请输入正确的邮箱地址');
|
||||||
}
|
}
|
||||||
if (User::email2userid($email) > 0) {
|
if (User::email2userid($email) > 0) {
|
||||||
|
@ -4,13 +4,14 @@ namespace App\Models;
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App\Models\WebSocket
|
* Class WebSocket
|
||||||
*
|
*
|
||||||
|
* @package App\Models
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property string $key
|
* @property string $key
|
||||||
* @property string|null $fd
|
* @property string|null $fd
|
||||||
* @property string|null $path
|
|
||||||
* @property int|null $userid
|
* @property int|null $userid
|
||||||
|
* @property string|null $path
|
||||||
* @property \Illuminate\Support\Carbon|null $created_at
|
* @property \Illuminate\Support\Carbon|null $created_at
|
||||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocket newModelQuery()
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocket newModelQuery()
|
||||||
|
@ -7,8 +7,9 @@ use Carbon\Carbon;
|
|||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App\Models\WebSocketDialog
|
* Class WebSocketDialog
|
||||||
*
|
*
|
||||||
|
* @package App\Models
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property string|null $type 对话类型
|
* @property string|null $type 对话类型
|
||||||
* @property string|null $group_type 聊天室类型
|
* @property string|null $group_type 聊天室类型
|
||||||
@ -120,10 +121,10 @@ class WebSocketDialog extends AbstractModel
|
|||||||
break;
|
break;
|
||||||
case "group":
|
case "group":
|
||||||
if ($dialog->group_type === 'project') {
|
if ($dialog->group_type === 'project') {
|
||||||
$dialog->group_info = Project::withTrashed()->select(['id', 'name', 'archived_at', 'deleted_at'])->whereDialogId($dialog->id)->first()?->cancelAppend()->cancelHidden();
|
$dialog->group_info = Project::withTrashed()->select(['id', 'name'])->whereDialogId($dialog->id)->first();
|
||||||
$dialog->name = $dialog->group_info ? $dialog->group_info->name : '';
|
$dialog->name = $dialog->group_info ? $dialog->group_info->name : '';
|
||||||
} elseif ($dialog->group_type === 'task') {
|
} elseif ($dialog->group_type === 'task') {
|
||||||
$dialog->group_info = ProjectTask::withTrashed()->select(['id', 'name', 'complete_at', 'archived_at', 'deleted_at'])->whereDialogId($dialog->id)->first()?->cancelAppend()->cancelHidden();
|
$dialog->group_info = ProjectTask::withTrashed()->select(['id', 'name'])->whereDialogId($dialog->id)->first();
|
||||||
$dialog->name = $dialog->group_info ? $dialog->group_info->name : '';
|
$dialog->name = $dialog->group_info ? $dialog->group_info->name : '';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -8,11 +8,11 @@ use App\Tasks\PushTask;
|
|||||||
use App\Tasks\WebSocketDialogMsgTask;
|
use App\Tasks\WebSocketDialogMsgTask;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Hhxsv5\LaravelS\Swoole\Task\Task;
|
use Hhxsv5\LaravelS\Swoole\Task\Task;
|
||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App\Models\WebSocketDialogMsg
|
* Class WebSocketDialogMsg
|
||||||
*
|
*
|
||||||
|
* @package App\Models
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property int|null $dialog_id 对话ID
|
* @property int|null $dialog_id 对话ID
|
||||||
* @property int|null $userid 发送会员ID
|
* @property int|null $userid 发送会员ID
|
||||||
@ -22,15 +22,11 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
|||||||
* @property int|null $send 发送数量
|
* @property int|null $send 发送数量
|
||||||
* @property \Illuminate\Support\Carbon|null $created_at
|
* @property \Illuminate\Support\Carbon|null $created_at
|
||||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||||
* @property \Illuminate\Support\Carbon|null $deleted_at
|
|
||||||
* @property-read int|mixed $percentage
|
* @property-read int|mixed $percentage
|
||||||
* @property-read \App\Models\WebSocketDialog|null $webSocketDialog
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg newModelQuery()
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg newModelQuery()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg newQuery()
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg newQuery()
|
||||||
* @method static \Illuminate\Database\Query\Builder|WebSocketDialogMsg onlyTrashed()
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg query()
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg query()
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg whereCreatedAt($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg whereCreatedAt($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg whereDeletedAt($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg whereDialogId($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg whereDialogId($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg whereId($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg whereId($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg whereMsg($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg whereMsg($value)
|
||||||
@ -39,14 +35,10 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
|||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg whereType($value)
|
* @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 whereUpdatedAt($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsg whereUserid($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()
|
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
*/
|
*/
|
||||||
class WebSocketDialogMsg extends AbstractModel
|
class WebSocketDialogMsg extends AbstractModel
|
||||||
{
|
{
|
||||||
use SoftDeletes;
|
|
||||||
|
|
||||||
protected $appends = [
|
protected $appends = [
|
||||||
'percentage',
|
'percentage',
|
||||||
];
|
];
|
||||||
@ -55,14 +47,6 @@ class WebSocketDialogMsg extends AbstractModel
|
|||||||
'updated_at',
|
'updated_at',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
|
||||||
*/
|
|
||||||
public function webSocketDialog(): \Illuminate\Database\Eloquent\Relations\HasOne
|
|
||||||
{
|
|
||||||
return $this->hasOne(WebSocketDialog::class, 'id', 'dialog_id');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 阅读占比
|
* 阅读占比
|
||||||
* @return int|mixed
|
* @return int|mixed
|
||||||
@ -70,7 +54,11 @@ class WebSocketDialogMsg extends AbstractModel
|
|||||||
public function getPercentageAttribute()
|
public function getPercentageAttribute()
|
||||||
{
|
{
|
||||||
if (!isset($this->appendattrs['percentage'])) {
|
if (!isset($this->appendattrs['percentage'])) {
|
||||||
$this->generatePercentage();
|
if ($this->read > $this->send || empty($this->send)) {
|
||||||
|
$this->appendattrs['percentage'] = 100;
|
||||||
|
} else {
|
||||||
|
$this->appendattrs['percentage'] = intval($this->read / $this->send * 100);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return $this->appendattrs['percentage'];
|
return $this->appendattrs['percentage'];
|
||||||
}
|
}
|
||||||
@ -94,22 +82,6 @@ class WebSocketDialogMsg extends AbstractModel
|
|||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取占比
|
|
||||||
* @param bool $increment 是否新增阅读数
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function generatePercentage($increment = false) {
|
|
||||||
if ($increment) {
|
|
||||||
$this->increment('read');
|
|
||||||
}
|
|
||||||
if ($this->read > $this->send || empty($this->send)) {
|
|
||||||
return $this->appendattrs['percentage'] = 100;
|
|
||||||
} else {
|
|
||||||
return $this->appendattrs['percentage'] = intval($this->read / $this->send * 100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 标记已送达 同时 告诉发送人已送达
|
* 标记已送达 同时 告诉发送人已送达
|
||||||
* @param $userid
|
* @param $userid
|
||||||
@ -139,17 +111,13 @@ class WebSocketDialogMsg extends AbstractModel
|
|||||||
if (!$msgRead->read_at) {
|
if (!$msgRead->read_at) {
|
||||||
$msgRead->read_at = Carbon::now();
|
$msgRead->read_at = Carbon::now();
|
||||||
$msgRead->save();
|
$msgRead->save();
|
||||||
$this->generatePercentage(true);
|
$this->increment('read');
|
||||||
PushTask::push([
|
PushTask::push([
|
||||||
'userid' => $this->userid,
|
'userid' => $this->userid,
|
||||||
'msg' => [
|
'msg' => [
|
||||||
'type' => 'dialog',
|
'type' => 'dialog',
|
||||||
'mode' => 'readed',
|
'mode' => 'update',
|
||||||
'data' => [
|
'data' => $this->toArray(),
|
||||||
'id' => $this->id,
|
|
||||||
'read' => $this->read,
|
|
||||||
'percentage' => $this->percentage,
|
|
||||||
],
|
|
||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@ -157,47 +125,6 @@ class WebSocketDialogMsg extends AbstractModel
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除消息
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function deleteMsg()
|
|
||||||
{
|
|
||||||
$send_dt = Carbon::parse($this->created_at)->addDay();
|
|
||||||
if ($send_dt->lt(Carbon::now())) {
|
|
||||||
throw new ApiException('已超过24小时,此消息不能撤回');
|
|
||||||
}
|
|
||||||
AbstractModel::transaction(function() {
|
|
||||||
$deleteRead = WebSocketDialogMsgRead::whereMsgId($this->id)->whereNull('read_at')->delete(); // 未阅读记录不需要软删除,直接删除即可
|
|
||||||
$this->delete();
|
|
||||||
//
|
|
||||||
$last_msg = null;
|
|
||||||
if ($this->webSocketDialog) {
|
|
||||||
$last_msg = WebSocketDialogMsg::whereDialogId($this->dialog_id)->orderByDesc('id')->first();
|
|
||||||
$this->webSocketDialog->last_at = $last_msg->created_at;
|
|
||||||
$this->webSocketDialog->save();
|
|
||||||
}
|
|
||||||
//
|
|
||||||
$dialog = WebSocketDialog::find($this->dialog_id);
|
|
||||||
if ($dialog) {
|
|
||||||
$userids = $dialog->dialogUser->pluck('userid')->toArray();
|
|
||||||
PushTask::push([
|
|
||||||
'userid' => $userids,
|
|
||||||
'msg' => [
|
|
||||||
'type' => 'dialog',
|
|
||||||
'mode' => 'delete',
|
|
||||||
'data' => [
|
|
||||||
'id' => $this->id,
|
|
||||||
'dialog_id' => $this->dialog_id,
|
|
||||||
'last_msg' => $last_msg,
|
|
||||||
'update_read' => $deleteRead ? 1 : 0
|
|
||||||
],
|
|
||||||
]
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送消息
|
* 发送消息
|
||||||
* @param int $dialog_id 会话ID(即 聊天室ID)
|
* @param int $dialog_id 会话ID(即 聊天室ID)
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App\Models\WebSocketDialogMsgRead
|
* Class WebSocketDialogMsgRead
|
||||||
*
|
*
|
||||||
|
* @package App\Models
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property int|null $dialog_id 对话ID
|
* @property int|null $dialog_id 对话ID
|
||||||
* @property int|null $msg_id 消息ID
|
* @property int|null $msg_id 消息ID
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App\Models\WebSocketDialogUser
|
* Class WebSocketDialogUser
|
||||||
*
|
*
|
||||||
|
* @package App\Models
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property int|null $dialog_id 对话ID
|
* @property int|null $dialog_id 对话ID
|
||||||
* @property int|null $userid 会员ID
|
* @property int|null $userid 会员ID
|
||||||
* @property string|null $top_at 置顶时间
|
|
||||||
* @property \Illuminate\Support\Carbon|null $created_at
|
* @property \Illuminate\Support\Carbon|null $created_at
|
||||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser newModelQuery()
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser newModelQuery()
|
||||||
@ -17,7 +17,6 @@ namespace App\Models;
|
|||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereCreatedAt($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereCreatedAt($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereDialogId($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereDialogId($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereId($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereId($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereTopAt($value)
|
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereUpdatedAt($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereUpdatedAt($value)
|
||||||
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereUserid($value)
|
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogUser whereUserid($value)
|
||||||
* @mixin \Eloquent
|
* @mixin \Eloquent
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App\Models\WebSocketTmpMsg
|
* Class WebSocketTmpMsg
|
||||||
*
|
*
|
||||||
|
* @package App\Models
|
||||||
* @property int $id
|
* @property int $id
|
||||||
* @property string|null $md5 MD5(会员ID-消息)
|
* @property string|null $md5 MD5(会员ID-消息)
|
||||||
* @property string|null $msg 详细消息
|
* @property string|null $msg 详细消息
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace App\Module;
|
namespace App\Module;
|
||||||
|
|
||||||
use App\Exceptions\ApiException;
|
|
||||||
use App\Models\Setting;
|
use App\Models\Setting;
|
||||||
use App\Models\Tmp;
|
use App\Models\Tmp;
|
||||||
use Cache;
|
use Cache;
|
||||||
@ -75,31 +74,6 @@ class Base
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取客户端版本号
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function getClientVersion()
|
|
||||||
{
|
|
||||||
global $_A;
|
|
||||||
if (!isset($_A["__static_client_version"])) {
|
|
||||||
$_A["__static_client_version"] = Request::header('version') ?: '0.0.1';
|
|
||||||
}
|
|
||||||
return $_A["__static_client_version"];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 检查客户端版本
|
|
||||||
* @param string $min 最小版本
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public static function checkClientVersion($min)
|
|
||||||
{
|
|
||||||
if (version_compare(Base::getClientVersion(), $min, '<')) {
|
|
||||||
throw new ApiException('当前版本 (v' . Base::getClientVersion() . ') 过低');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断是否域名格式
|
* 判断是否域名格式
|
||||||
* @param $domain
|
* @param $domain
|
||||||
@ -342,15 +316,19 @@ class Base
|
|||||||
{
|
{
|
||||||
if (strtolower($charset) == 'utf-8') {
|
if (strtolower($charset) == 'utf-8') {
|
||||||
if (Base::getStrlen($string) <= $length) return $string;
|
if (Base::getStrlen($string) <= $length) return $string;
|
||||||
$strcut = Base::utf8Substr($string, $length, $start);
|
$strcut = str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $string);
|
||||||
|
$strcut = Base::utf8Substr($strcut, $length, $start);
|
||||||
|
$strcut = str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $strcut);
|
||||||
return $strcut . $dot;
|
return $strcut . $dot;
|
||||||
} else {
|
} else {
|
||||||
$length = $length * 2;
|
$length = $length * 2;
|
||||||
if (strlen($string) <= $length) return $string;
|
if (strlen($string) <= $length) return $string;
|
||||||
|
$string = str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $string);
|
||||||
$strcut = '';
|
$strcut = '';
|
||||||
for ($i = 0; $i < $length; $i++) {
|
for ($i = 0; $i < $length; $i++) {
|
||||||
$strcut .= ord($string[$i]) > 127 ? $string[$i] . $string[++$i] : $string[$i];
|
$strcut .= ord($string[$i]) > 127 ? $string[$i] . $string[++$i] : $string[$i];
|
||||||
}
|
}
|
||||||
|
$strcut = str_replace(array('&', '"', '<', '>'), array('&', '"', '<', '>'), $strcut);
|
||||||
}
|
}
|
||||||
return $strcut . $dot;
|
return $strcut . $dot;
|
||||||
}
|
}
|
||||||
@ -747,7 +725,6 @@ class Base
|
|||||||
*/
|
*/
|
||||||
public static function fillUrl($str = '')
|
public static function fillUrl($str = '')
|
||||||
{
|
{
|
||||||
global $_A;
|
|
||||||
if (is_array($str)) {
|
if (is_array($str)) {
|
||||||
foreach ($str as $key => $item) {
|
foreach ($str as $key => $item) {
|
||||||
$str[$key] = Base::fillUrl($item);
|
$str[$key] = Base::fillUrl($item);
|
||||||
@ -766,12 +743,9 @@ class Base
|
|||||||
) {
|
) {
|
||||||
return $str;
|
return $str;
|
||||||
} else {
|
} else {
|
||||||
if ($_A['__fill_url_remote_url'] === true) {
|
|
||||||
return "{{RemoteURL}}" . $str;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
return url($str);
|
return url($str);
|
||||||
} catch (\Throwable) {
|
} catch (\Throwable $e) {
|
||||||
return self::getSchemeAndHost() . "/" . $str;
|
return self::getSchemeAndHost() . "/" . $str;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -792,7 +766,7 @@ class Base
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
$find = url('');
|
$find = url('');
|
||||||
} catch (\Throwable) {
|
} catch (\Throwable $e) {
|
||||||
$find = self::getSchemeAndHost();
|
$find = self::getSchemeAndHost();
|
||||||
}
|
}
|
||||||
return Base::leftDelete($str, $find . '/');
|
return Base::leftDelete($str, $find . '/');
|
||||||
@ -808,31 +782,6 @@ class Base
|
|||||||
return $scheme.($_SERVER['HTTP_HOST'] ?? '');
|
return $scheme.($_SERVER['HTTP_HOST'] ?? '');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 地址后拼接参数
|
|
||||||
* @param $url
|
|
||||||
* @param $parames
|
|
||||||
* @return mixed|string
|
|
||||||
*/
|
|
||||||
public static function urlAddparameter($url, $parames)
|
|
||||||
{
|
|
||||||
if ($parames && is_array($parames)) {
|
|
||||||
$array = [];
|
|
||||||
foreach ($parames as $key => $val) {
|
|
||||||
$array[] = $key . "=" . $val;
|
|
||||||
}
|
|
||||||
if ($array) {
|
|
||||||
$query = implode("&", $array);
|
|
||||||
if (str_contains($url, "?")) {
|
|
||||||
$url .= "&" . $query;
|
|
||||||
} else {
|
|
||||||
$url .= "?" . $query;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $url;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式化内容图片地址
|
* 格式化内容图片地址
|
||||||
* @param $content
|
* @param $content
|
||||||
@ -881,16 +830,13 @@ class Base
|
|||||||
/**
|
/**
|
||||||
* 数组只保留数字的
|
* 数组只保留数字的
|
||||||
* @param $array
|
* @param $array
|
||||||
* @param bool $int 是否格式化值
|
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public static function arrayRetainInt($array, $int = false)
|
public static function arrayRetainInt($array)
|
||||||
{
|
{
|
||||||
foreach ($array as $k => $v) {
|
foreach ($array as $k => $v) {
|
||||||
if (!is_numeric($v)) {
|
if (!is_numeric($v)) {
|
||||||
unset($array[$k]);
|
unset($array[$k]);
|
||||||
} elseif ($int === true) {
|
|
||||||
$array[$k] = intval($v);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return array_values($array);
|
return array_values($array);
|
||||||
@ -988,7 +934,7 @@ class Base
|
|||||||
* @param string $str 需要检测的字符串
|
* @param string $str 需要检测的字符串
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public static function isEmail($str)
|
public static function isMail($str)
|
||||||
{
|
{
|
||||||
$RegExp = '/^[a-z0-9][a-z\.0-9-_]+@[a-z0-9_-]+(?:\.[a-z]{0,3}\.[a-z]{0,2}|\.[a-z]{0,3}|\.[a-z]{0,2})$/i';
|
$RegExp = '/^[a-z0-9][a-z\.0-9-_]+@[a-z0-9_-]+(?:\.[a-z]{0,3}\.[a-z]{0,2}|\.[a-z]{0,3}|\.[a-z]{0,2})$/i';
|
||||||
return preg_match($RegExp, $str);
|
return preg_match($RegExp, $str);
|
||||||
@ -2270,7 +2216,7 @@ class Base
|
|||||||
$type = ['zip'];
|
$type = ['zip'];
|
||||||
break;
|
break;
|
||||||
case 'file':
|
case 'file':
|
||||||
$type = ['jpg', 'jpeg', 'png', 'gif', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'esp', 'pdf', 'rar', 'zip', 'gz', 'ai', 'avi', 'bmp', 'cdr', 'eps', 'mov', 'mp3', 'mp4', 'pr', 'psd', 'svg', 'tif'];
|
$type = ['jpg', 'jpeg', 'png', 'gif', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'esp', 'pdf', 'rar', 'zip', 'gz'];
|
||||||
break;
|
break;
|
||||||
case 'firmware':
|
case 'firmware':
|
||||||
$type = ['img', 'tar', 'bin'];
|
$type = ['img', 'tar', 'bin'];
|
||||||
@ -2280,9 +2226,6 @@ class Base
|
|||||||
break;
|
break;
|
||||||
case 'more':
|
case 'more':
|
||||||
$type = [
|
$type = [
|
||||||
'text', 'md', 'markdown',
|
|
||||||
'drawio',
|
|
||||||
'mind',
|
|
||||||
'docx', 'wps', 'doc', 'xls', 'xlsx', 'ppt', 'pptx',
|
'docx', 'wps', 'doc', 'xls', 'xlsx', 'ppt', 'pptx',
|
||||||
'jpg', 'jpeg', 'png', 'gif', 'bmp', 'ico', 'raw',
|
'jpg', 'jpeg', 'png', 'gif', 'bmp', 'ico', 'raw',
|
||||||
'rar', 'zip', 'jar', '7-zip', 'tar', 'gzip', '7z',
|
'rar', 'zip', 'jar', '7-zip', 'tar', 'gzip', '7z',
|
||||||
@ -2291,17 +2234,10 @@ class Base
|
|||||||
'ofd',
|
'ofd',
|
||||||
'pdf',
|
'pdf',
|
||||||
'txt',
|
'txt',
|
||||||
'htaccess', 'htgroups', 'htpasswd', 'conf', 'bat', 'cmd', 'cpp', 'c', 'cc', 'cxx', 'h', 'hh', 'hpp', 'ino', 'cs', 'css',
|
'html', 'htm', 'asp', 'jsp', 'xml', 'json', 'properties', 'md', 'gitignore', 'log', 'java', 'py', 'c', 'cpp', 'sql', 'sh', 'bat', 'm', 'bas', 'prg', 'cmd',
|
||||||
'dockerfile', 'go', 'html', 'htm', 'xhtml', 'vue', 'we', 'wpy', 'java', 'js', 'jsm', 'jsx', 'json', 'jsp', 'less', 'lua', 'makefile', 'gnumakefile',
|
'php', 'go', 'python', 'js', 'ftl', 'css', 'lua', 'rb', 'yaml', 'yml', 'h', 'cs', 'aspx',
|
||||||
'ocamlmakefile', 'make', 'mysql', 'nginx', 'ini', 'cfg', 'prefs', 'm', 'mm', 'pl', 'pm', 'p6', 'pl6', 'pm6', 'pgsql', 'php',
|
|
||||||
'inc', 'phtml', 'shtml', 'php3', 'php4', 'php5', 'phps', 'phpt', 'aw', 'ctp', 'module', 'ps1', 'py', 'r', 'rb', 'ru', 'gemspec', 'rake', 'guardfile', 'rakefile',
|
|
||||||
'gemfile', 'rs', 'sass', 'scss', 'sh', 'bash', 'bashrc', 'sql', 'sqlserver', 'swift', 'ts', 'typescript', 'str', 'vbs', 'vb', 'v', 'vh', 'sv', 'svh', 'xml',
|
|
||||||
'rdf', 'rss', 'wsdl', 'xslt', 'atom', 'mathml', 'mml', 'xul', 'xbl', 'xaml', 'yaml', 'yml',
|
|
||||||
'asp', 'properties', 'gitignore', 'log', 'bas', 'prg', 'python', 'ftl', 'aspx',
|
|
||||||
'mp3', 'wav', 'mp4', 'flv',
|
'mp3', 'wav', 'mp4', 'flv',
|
||||||
'avi', 'mov', 'wmv', 'mkv', '3gp', 'rm',
|
'avi', 'mov', 'wmv', 'mkv', '3gp', 'rm',
|
||||||
'xmind',
|
|
||||||
'rp',
|
|
||||||
];
|
];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -2423,37 +2359,6 @@ class Base
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 上传文件移动
|
|
||||||
* @param array $uploadResult
|
|
||||||
* @param string $newPath "/" 结尾
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public static function uploadMove($uploadResult, $newPath)
|
|
||||||
{
|
|
||||||
if (str_ends_with($newPath, "/") && file_exists($uploadResult['file'])) {
|
|
||||||
Base::makeDir(public_path($newPath));
|
|
||||||
$oldPath = dirname($uploadResult['path']) . "/";
|
|
||||||
$newFile = str_replace($oldPath, $newPath, $uploadResult['file']);
|
|
||||||
if (rename($uploadResult['file'], $newFile)) {
|
|
||||||
$oldUrl = $uploadResult['url'];
|
|
||||||
$uploadResult['file'] = $newFile;
|
|
||||||
$uploadResult['path'] = str_replace($oldPath, $newPath, $uploadResult['path']);
|
|
||||||
$uploadResult['url'] = str_replace($oldPath, $newPath, $uploadResult['url']);
|
|
||||||
if ($uploadResult['thumb'] == $oldUrl) {
|
|
||||||
$uploadResult['thumb'] = $uploadResult['url'];
|
|
||||||
} elseif ($uploadResult['thumb']) {
|
|
||||||
$oldThumb = substr($uploadResult['thumb'], strpos($uploadResult['thumb'], $newPath));
|
|
||||||
$newThumb = str_replace($oldPath, $newPath, $oldThumb);
|
|
||||||
if (file_exists(public_path($oldThumb)) && rename(public_path($oldThumb), public_path($newThumb))) {
|
|
||||||
$uploadResult['thumb'] = str_replace($oldPath, $newPath, $uploadResult['thumb']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $uploadResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成缩略图
|
* 生成缩略图
|
||||||
* @param string $src_img 源图绝对完整地址{带文件名及后缀名}
|
* @param string $src_img 源图绝对完整地址{带文件名及后缀名}
|
||||||
@ -2963,19 +2868,4 @@ class Base
|
|||||||
$matrix = array_unique($matrix, SORT_REGULAR);
|
$matrix = array_unique($matrix, SORT_REGULAR);
|
||||||
return array_merge($matrix);
|
return array_merge($matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 去除emoji表情
|
|
||||||
* @param $str
|
|
||||||
* @return string|string[]|null
|
|
||||||
*/
|
|
||||||
public static function filterEmoji($str)
|
|
||||||
{
|
|
||||||
return preg_replace_callback(
|
|
||||||
'/./u',
|
|
||||||
function (array $match) {
|
|
||||||
return strlen($match[0]) >= 4 ? '' : $match[0];
|
|
||||||
},
|
|
||||||
$str);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,144 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Module;
|
|
||||||
|
|
||||||
use Excel;
|
|
||||||
use Maatwebsite\Excel\Concerns\FromCollection;
|
|
||||||
use Maatwebsite\Excel\Concerns\WithEvents;
|
|
||||||
use Maatwebsite\Excel\Concerns\WithHeadings;
|
|
||||||
use Maatwebsite\Excel\Concerns\WithStrictNullComparison;
|
|
||||||
use Maatwebsite\Excel\Concerns\WithTitle;
|
|
||||||
use Maatwebsite\Excel\Events\AfterSheet;
|
|
||||||
use PhpOffice\PhpSpreadsheet\Cell\DataValidation;
|
|
||||||
use PhpOffice\PhpSpreadsheet\Writer\Exception;
|
|
||||||
|
|
||||||
class BillExport implements WithHeadings, WithEvents, FromCollection, WithTitle, WithStrictNullComparison
|
|
||||||
{
|
|
||||||
public $title;
|
|
||||||
public $headings = [];
|
|
||||||
public $data = [];
|
|
||||||
public $typeLists = [];
|
|
||||||
public $typeNumber = 0;
|
|
||||||
|
|
||||||
public function __construct($title, array $data)
|
|
||||||
{
|
|
||||||
$this->title = $title;
|
|
||||||
$this->data = $data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function create($data = [], $title = "Sheet1") {
|
|
||||||
if (is_string($data)) {
|
|
||||||
list($title, $data) = [$data, $title];
|
|
||||||
}
|
|
||||||
if (!is_array($data)) {
|
|
||||||
$data = [];
|
|
||||||
}
|
|
||||||
return new BillExport($title, $data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setTitle($title) {
|
|
||||||
$this->title = $title;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setHeadings(array $headings) {
|
|
||||||
$this->headings = $headings;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setData(array $data) {
|
|
||||||
$this->data = $data;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setTypeList(array $typeList, $number = 0) {
|
|
||||||
$this->typeLists = $typeList;
|
|
||||||
$this->typeNumber = $number;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function store($fileName = '') {
|
|
||||||
if (empty($fileName)) {
|
|
||||||
$fileName = date("YmdHis") . '.xls';
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return Excel::store($this, $fileName);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
return "导出错误:" . $e->getMessage();
|
|
||||||
} catch (\PhpOffice\PhpSpreadsheet\Exception $e) {
|
|
||||||
return "导出错误:" . $e->getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function download($fileName = '') {
|
|
||||||
if (empty($fileName)) {
|
|
||||||
$fileName = date("YmdHis") . '.xls';
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return Excel::download($this, $fileName);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
return "导出错误:" . $e->getMessage();
|
|
||||||
} catch (\PhpOffice\PhpSpreadsheet\Exception $e) {
|
|
||||||
return "导出错误:" . $e->getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 导出的文件标题
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function title(): string
|
|
||||||
{
|
|
||||||
return $this->title;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 标题行
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function headings(): array
|
|
||||||
{
|
|
||||||
return $this->headings;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 导出的内容
|
|
||||||
* @return \Illuminate\Support\Collection
|
|
||||||
*/
|
|
||||||
public function collection()
|
|
||||||
{
|
|
||||||
return collect($this->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置单元格事件
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function registerEvents(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
AfterSheet::Class => function (AfterSheet $event) {
|
|
||||||
$count = count($this->data);
|
|
||||||
foreach ($this->typeLists AS $cell => $typeList) {
|
|
||||||
if ($cell && $typeList) {
|
|
||||||
$p = $this->headings ? 1 : 0;
|
|
||||||
for ($i = 1 + $p; $i <= max($count, $this->typeNumber) + $p; $i++) {
|
|
||||||
$validation = $event->sheet->getDelegate()->getCell($cell . $i)->getDataValidation();
|
|
||||||
$validation->setType(DataValidation::TYPE_LIST);
|
|
||||||
$validation->setErrorStyle(DataValidation::STYLE_WARNING);
|
|
||||||
$validation->setAllowBlank(false);
|
|
||||||
$validation->setShowDropDown(true);
|
|
||||||
$validation->setShowInputMessage(true);
|
|
||||||
$validation->setShowErrorMessage(true);
|
|
||||||
$validation->setErrorTitle('输入的值不合法');
|
|
||||||
$validation->setError('选择的值不在列表中,请选择列表中的值');
|
|
||||||
$validation->setPromptTitle('从列表中选择');
|
|
||||||
$validation->setPrompt('请选择下拉列表中的值');
|
|
||||||
$validation->setFormula1('"' . implode(',', $typeList) . '"');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
|
|
||||||
namespace App\Module;
|
|
||||||
|
|
||||||
|
|
||||||
use Maatwebsite\Excel\Concerns\ToArray;
|
|
||||||
|
|
||||||
class BillImport implements ToArray
|
|
||||||
{
|
|
||||||
public function Array(Array $tables)
|
|
||||||
{
|
|
||||||
return $tables;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -23,14 +23,6 @@ class AppServiceProvider extends ServiceProvider
|
|||||||
*/
|
*/
|
||||||
public function boot()
|
public function boot()
|
||||||
{
|
{
|
||||||
\Illuminate\Database\Query\Builder::macro('rawSql', function(){
|
//
|
||||||
return array_reduce($this->getBindings(), function($sql, $binding){
|
|
||||||
return preg_replace('/\?/', is_numeric($binding) ? $binding : "'".$binding."'" , $sql, 1);
|
|
||||||
}, $this->toSql());
|
|
||||||
});
|
|
||||||
|
|
||||||
\Illuminate\Database\Eloquent\Builder::macro('rawSql', function(){
|
|
||||||
return ($this->getQuery()->rawSql());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,11 +127,9 @@ class WebSocketService implements WebSocketHandlerInterface
|
|||||||
case 'readMsg':
|
case 'readMsg':
|
||||||
$ids = is_array($data['id']) ? $data['id'] : [$data['id']];
|
$ids = is_array($data['id']) ? $data['id'] : [$data['id']];
|
||||||
$userid = $this->getUserid($frame->fd);
|
$userid = $this->getUserid($frame->fd);
|
||||||
WebSocketDialogMsg::whereIn('id', $ids)->chunkById(20, function($list) use ($userid) {
|
$list = WebSocketDialogMsg::whereIn('id', $ids)->get();
|
||||||
/** @var WebSocketDialogMsg $item */
|
$list->transform(function(WebSocketDialogMsg $item) use ($userid) {
|
||||||
foreach ($list as $item) {
|
$item->readSuccess($userid);
|
||||||
$item->readSuccess($userid);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -206,19 +204,7 @@ class WebSocketService implements WebSocketHandlerInterface
|
|||||||
*/
|
*/
|
||||||
private function deleteUser($fd)
|
private function deleteUser($fd)
|
||||||
{
|
{
|
||||||
$array = [];
|
WebSocket::whereFd($fd)->delete();
|
||||||
WebSocket::whereFd($fd)->chunk(10, function($list) use (&$array) {
|
|
||||||
/** @var WebSocket $item */
|
|
||||||
foreach ($list as $item) {
|
|
||||||
$item->delete();
|
|
||||||
if ($item->path && str_starts_with($item->path, "file/content/")) {
|
|
||||||
$array[$item->path] = $item->path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
foreach ($array as $path) {
|
|
||||||
$this->pushPath($path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace App\Tasks;
|
|
||||||
|
|
||||||
@error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
|
|
||||||
|
|
||||||
use App\Models\AbstractModel;
|
|
||||||
use App\Models\ProjectTask;
|
|
||||||
use App\Module\Base;
|
|
||||||
use Carbon\Carbon;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 完成的任务自动归档
|
|
||||||
* Class AutoArchivedTask
|
|
||||||
* @package App\Tasks
|
|
||||||
*/
|
|
||||||
class AutoArchivedTask extends AbstractTask
|
|
||||||
{
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
public function start()
|
|
||||||
{
|
|
||||||
$setting = Base::setting('system');
|
|
||||||
if ($setting['auto_archived'] === 'open') {
|
|
||||||
$archivedDay = floatval($setting['archived_day']);
|
|
||||||
if ($archivedDay > 0) {
|
|
||||||
$archivedDay = min(100, $archivedDay);
|
|
||||||
$archivedTime = Carbon::now()->subDays($archivedDay);
|
|
||||||
//获取已完成未归档的任务
|
|
||||||
$taskLists = ProjectTask::whereNotNull('complete_at')
|
|
||||||
->where('complete_at', '<=', $archivedTime)
|
|
||||||
->where('archived_userid', 0)
|
|
||||||
->whereNull('archived_at')
|
|
||||||
->take(100)
|
|
||||||
->get();
|
|
||||||
foreach ($taskLists AS $task) {
|
|
||||||
$task->archivedTask(Carbon::now(), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -33,11 +33,6 @@ class WebSocketDialogMsgTask extends AbstractTask
|
|||||||
|
|
||||||
public function start()
|
public function start()
|
||||||
{
|
{
|
||||||
global $_A;
|
|
||||||
$_A = [
|
|
||||||
'__fill_url_remote_url' => true,
|
|
||||||
];
|
|
||||||
//
|
|
||||||
$msg = WebSocketDialogMsg::find($this->id);
|
$msg = WebSocketDialogMsg::find($this->id);
|
||||||
if (empty($msg)) {
|
if (empty($msg)) {
|
||||||
return;
|
return;
|
||||||
|
180
cmd
180
cmd
@ -12,8 +12,6 @@ OK="${Green}[OK]${Font}"
|
|||||||
Error="${Red}[错误]${Font}"
|
Error="${Red}[错误]${Font}"
|
||||||
|
|
||||||
cur_path="$(pwd)"
|
cur_path="$(pwd)"
|
||||||
cur_arg=$@
|
|
||||||
COMPOSE="docker-compose"
|
|
||||||
|
|
||||||
judge() {
|
judge() {
|
||||||
if [[ 0 -eq $? ]]; then
|
if [[ 0 -eq $? ]]; then
|
||||||
@ -32,15 +30,6 @@ rand() {
|
|||||||
echo $(($num%$max+$min))
|
echo $(($num%$max+$min))
|
||||||
}
|
}
|
||||||
|
|
||||||
rand_string() {
|
|
||||||
local lan=$1
|
|
||||||
if [[ `uname` == 'Linux' ]]; then
|
|
||||||
echo "$(date +%s%N | md5sum | cut -c 1-${lan})"
|
|
||||||
else
|
|
||||||
echo "$(docker run -it --rm alpine sh -c "date +%s%N | md5sum | cut -c 1-${lan}")"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
supervisorctl_restart() {
|
supervisorctl_restart() {
|
||||||
local RES=`run_exec php "supervisorctl update $1"`
|
local RES=`run_exec php "supervisorctl update $1"`
|
||||||
if [ -z "$RES" ]; then
|
if [ -z "$RES" ]; then
|
||||||
@ -56,24 +45,15 @@ check_docker() {
|
|||||||
echo -e "${Error} ${RedBG} 未安装 Docker!${Font}"
|
echo -e "${Error} ${RedBG} 未安装 Docker!${Font}"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
docker-compose version &> /dev/null
|
docker-compose --version &> /dev/null
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
docker compose version &> /dev/null
|
echo -e "${Error} ${RedBG} 未安装 Docker-compose!${Font}"
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo -e "${Error} ${RedBG} 未安装 Docker-compose!${Font}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
COMPOSE="docker compose"
|
|
||||||
fi
|
|
||||||
if [[ -n `$COMPOSE version | grep -E "\sv*1"` ]]; then
|
|
||||||
$COMPOSE version
|
|
||||||
echo -e "${Error} ${RedBG} Docker-compose 版本过低,请升级至v2+!${Font}"
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
check_node() {
|
check_node() {
|
||||||
npm --version &> /dev/null
|
npm --version > /dev/null
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo -e "${Error} ${RedBG} 未安装nodejs!${Font}"
|
echo -e "${Error} ${RedBG} 未安装nodejs!${Font}"
|
||||||
exit 1
|
exit 1
|
||||||
@ -81,11 +61,12 @@ check_node() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
docker_name() {
|
docker_name() {
|
||||||
echo `$COMPOSE ps | awk '{print $1}' | grep "\-$1\-"`
|
echo `docker-compose ps | awk '{print $1}' | grep "\-$1\-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
run_compile() {
|
run_compile() {
|
||||||
local type=$1
|
local type=$1
|
||||||
|
local npxcmd=""
|
||||||
check_node
|
check_node
|
||||||
if [ ! -d "./node_modules" ]; then
|
if [ ! -d "./node_modules" ]; then
|
||||||
npm install
|
npm install
|
||||||
@ -93,38 +74,29 @@ run_compile() {
|
|||||||
run_exec php "php bin/run --mode=$type"
|
run_exec php "php bin/run --mode=$type"
|
||||||
supervisorctl_restart php
|
supervisorctl_restart php
|
||||||
#
|
#
|
||||||
|
mix -V &> /dev/null
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
npxcmd="npx"
|
||||||
|
fi
|
||||||
if [ "$type" = "prod" ]; then
|
if [ "$type" = "prod" ]; then
|
||||||
rm -rf "./public/js/build"
|
rm -rf "./public/js/build"
|
||||||
npx mix --production
|
$npxcmd mix --production
|
||||||
else
|
else
|
||||||
npx mix watch --hot
|
$npxcmd mix watch --hot
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
run_electron() {
|
run_electron() {
|
||||||
local argv=$@
|
local argv=$@
|
||||||
check_node
|
check_node
|
||||||
if [ ! -d "./node_modules" ]; then
|
|
||||||
npm install
|
|
||||||
fi
|
|
||||||
if [ ! -d "./electron/node_modules" ]; then
|
if [ ! -d "./electron/node_modules" ]; then
|
||||||
pushd electron
|
pushd electron
|
||||||
npm install
|
npm install
|
||||||
popd
|
popd
|
||||||
fi
|
fi
|
||||||
#
|
|
||||||
if [ -d "./electron/dist" ]; then
|
if [ -d "./electron/dist" ]; then
|
||||||
rm -rf "./electron/dist"
|
rm -rf "./electron/dist"
|
||||||
fi
|
fi
|
||||||
if [ -d "./electron/public" ] && [ "$argv" != "--nobuild" ]; then
|
|
||||||
rm -rf "./electron/public"
|
|
||||||
fi
|
|
||||||
mkdir -p ./electron/public
|
|
||||||
cp ./electron/index.html ./electron/public/index.html
|
|
||||||
#
|
|
||||||
if [ "$argv" != "dev" ] && [ "$argv" != "--nobuild" ]; then
|
|
||||||
npx mix --production -- --env --electron
|
|
||||||
fi
|
|
||||||
node ./electron/build.js $argv
|
node ./electron/build.js $argv
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,7 +108,11 @@ run_exec() {
|
|||||||
echo -e "${Error} ${RedBG} 没有找到 $container 容器! ${Font}"
|
echo -e "${Error} ${RedBG} 没有找到 $container 容器! ${Font}"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
docker exec -it "$name" /bin/sh -c "$cmd"
|
if [ "$container" = "mariadb" ] || [ "$container" = "nginx" ] || [ "$container" = "redis" ]; then
|
||||||
|
docker exec -it "$name" /bin/sh -c "$cmd"
|
||||||
|
else
|
||||||
|
docker exec -it "$name" /bin/bash -c "$cmd"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
run_mysql() {
|
run_mysql() {
|
||||||
@ -175,7 +151,6 @@ run_mysql() {
|
|||||||
fi
|
fi
|
||||||
docker cp $filename $container_name:/
|
docker cp $filename $container_name:/
|
||||||
run_exec mariadb "gunzip < /$inputname | mysql -u$username -p$password $database"
|
run_exec mariadb "gunzip < /$inputname | mysql -u$username -p$password $database"
|
||||||
run_exec php "php artisan migrate"
|
|
||||||
judge "还原数据库"
|
judge "还原数据库"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
@ -193,11 +168,8 @@ env_set() {
|
|||||||
if [ -z "$exist" ]; then
|
if [ -z "$exist" ]; then
|
||||||
echo "$key=$val" >> $cur_path/.env
|
echo "$key=$val" >> $cur_path/.env
|
||||||
else
|
else
|
||||||
if [[ `uname` == 'Linux' ]]; then
|
command="sed -i '/^$key=/c\\$key=$val' /www/.env"
|
||||||
sed -i "/^${key}=/c\\${key}=${val}" ${cur_path}/.env
|
docker run -it --rm -v ${cur_path}:/www alpine sh -c "$command"
|
||||||
else
|
|
||||||
docker run -it --rm -v ${cur_path}:/www alpine sh -c "sed -i "/^${key}=/c\\${key}=${val}" /www/.env"
|
|
||||||
fi
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo -e "${Error} ${RedBG} 设置env参数失败!${Font}"
|
echo -e "${Error} ${RedBG} 设置env参数失败!${Font}"
|
||||||
exit 1
|
exit 1
|
||||||
@ -210,43 +182,16 @@ env_init() {
|
|||||||
cp .env.docker .env
|
cp .env.docker .env
|
||||||
fi
|
fi
|
||||||
if [ -z "$(env_get DB_ROOT_PASSWORD)" ]; then
|
if [ -z "$(env_get DB_ROOT_PASSWORD)" ]; then
|
||||||
env_set DB_ROOT_PASSWORD "$(rand_string 16)"
|
env_set DB_ROOT_PASSWORD "$(docker run -it --rm alpine sh -c "date +%s%N | md5sum | cut -c 1-16")"
|
||||||
fi
|
fi
|
||||||
if [ -z "$(env_get APP_ID)" ]; then
|
if [ -z "$(env_get APP_ID)" ]; then
|
||||||
env_set APP_ID "$(rand_string 6)"
|
env_set APP_ID "$(docker run -it --rm alpine sh -c "date +%s%N | md5sum | cut -c 1-6")"
|
||||||
fi
|
fi
|
||||||
if [ -z "$(env_get APP_IPPR)" ]; then
|
if [ -z "$(env_get APP_IPPR)" ]; then
|
||||||
env_set APP_IPPR "10.$(rand 50 100).$(rand 100 200)"
|
env_set APP_IPPR "10.$(rand 50 100).$(rand 100 200)"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
arg_get() {
|
|
||||||
local find="n"
|
|
||||||
local value=""
|
|
||||||
for var in $cur_arg; do
|
|
||||||
if [[ "$find" == "y" ]]; then
|
|
||||||
if [[ ! $var =~ "--" ]]; then
|
|
||||||
value=$var
|
|
||||||
fi
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
if [[ "--$1" == "$var" ]] || [[ "-$1" == "$var" ]]; then
|
|
||||||
find="y"
|
|
||||||
value="yes"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
echo $value
|
|
||||||
}
|
|
||||||
|
|
||||||
is_arm() {
|
|
||||||
local get_arch=`arch`
|
|
||||||
if [[ $get_arch =~ "aarch" ]] || [[ $get_arch =~ "arm" ]]; then
|
|
||||||
echo "yes"
|
|
||||||
else
|
|
||||||
echo "no"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
####################################################################################
|
####################################################################################
|
||||||
####################################################################################
|
####################################################################################
|
||||||
####################################################################################
|
####################################################################################
|
||||||
@ -259,67 +204,31 @@ fi
|
|||||||
if [ $# -gt 0 ]; then
|
if [ $# -gt 0 ]; then
|
||||||
if [[ "$1" == "init" ]] || [[ "$1" == "install" ]]; then
|
if [[ "$1" == "init" ]] || [[ "$1" == "install" ]]; then
|
||||||
shift 1
|
shift 1
|
||||||
# 判断架构
|
rm -rf composer.lock
|
||||||
if [[ "$(is_arm)" == "yes" ]] && [[ -z "$(arg_get force)" ]]; then
|
rm -rf package-lock.json
|
||||||
echo -e "${Error} ${RedBG}暂不支持arm架构,强制安装请使用:./cmd install --force${Font}"
|
mkdir -p ${cur_path}/docker/mysql/data
|
||||||
exit 1
|
chmod -R 777 ${cur_path}/docker/mysql/data
|
||||||
fi
|
docker-compose up -d
|
||||||
# 初始化文件
|
docker-compose restart php
|
||||||
if [[ -n "$(arg_get relock)" ]]; then
|
|
||||||
rm -rf node_modules
|
|
||||||
rm -rf package-lock.json
|
|
||||||
rm -rf vendor
|
|
||||||
rm -rf composer.lock
|
|
||||||
fi
|
|
||||||
mkdir -p "${cur_path}/docker/log/supervisor"
|
|
||||||
mkdir -p "${cur_path}/docker/mysql/data"
|
|
||||||
chmod -R 775 "${cur_path}/docker/log/supervisor"
|
|
||||||
chmod -R 775 "${cur_path}/docker/mysql/data"
|
|
||||||
# 启动容器
|
|
||||||
[[ "$(arg_get port)" -gt 0 ]] && env_set APP_PORT "$(arg_get port)"
|
|
||||||
$COMPOSE up php -d
|
|
||||||
# 安装composer依赖
|
|
||||||
run_exec php "composer install"
|
run_exec php "composer install"
|
||||||
if [ ! -f "${cur_path}/vendor/autoload.php" ]; then
|
[ -z "$(env_get APP_KEY)" ] && run_exec php "php artisan key:generate"
|
||||||
run_exec php "composer config repo.packagist composer https://packagist.phpcomposer.com"
|
|
||||||
run_exec php "composer install"
|
|
||||||
run_exec php "composer config --unset repos.packagist"
|
|
||||||
fi
|
|
||||||
if [ ! -f "${cur_path}/vendor/autoload.php" ]; then
|
|
||||||
echo -e "${Error} ${RedBG}composer install 失败,请重试! ${Font}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
[[ -z "$(env_get APP_KEY)" ]] && run_exec php "php artisan key:generate"
|
|
||||||
run_exec php "php bin/run --mode=prod"
|
|
||||||
# 检查数据库
|
|
||||||
remaining=10
|
|
||||||
while [ ! -f "${cur_path}/docker/mysql/data/$(env_get DB_DATABASE)/db.opt" ]; do
|
|
||||||
((remaining=$remaining-1))
|
|
||||||
if [ $remaining -lt 0 ]; then
|
|
||||||
echo -e "${Error} ${RedBG} 数据库安装失败! ${Font}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
chmod -R 775 "${cur_path}/docker/mysql/data"
|
|
||||||
sleep 3
|
|
||||||
done
|
|
||||||
run_exec php "php artisan migrate --seed"
|
run_exec php "php artisan migrate --seed"
|
||||||
# 设置初始化密码
|
run_exec php "php bin/run --mode=prod"
|
||||||
res=`run_exec mariadb "sh /etc/mysql/repassword.sh"`
|
res=`run_exec mariadb "sh /etc/mysql/repassword.sh"`
|
||||||
$COMPOSE up -d
|
docker-compose stop
|
||||||
supervisorctl_restart php
|
docker-compose start
|
||||||
echo -e "${OK} ${GreenBG} 安装完成 ${Font}"
|
echo -e "${OK} ${GreenBG} 安装完成 ${Font}"
|
||||||
echo -e "地址: http://${GreenBG}127.0.0.1:$(env_get APP_PORT)${Font}"
|
echo -e "地址: http://${GreenBG}127.0.0.1:$(env_get APP_PORT)${Font}"
|
||||||
echo -e "$res"
|
echo -e "$res"
|
||||||
elif [[ "$1" == "update" ]]; then
|
elif [[ "$1" == "update" ]]; then
|
||||||
shift 1
|
shift 1
|
||||||
run_mysql backup
|
|
||||||
git fetch --all
|
git fetch --all
|
||||||
git reset --hard origin/$(git branch | sed -n -e 's/^\* \(.*\)/\1/p')
|
git reset --hard origin/$(git branch | sed -n -e 's/^\* \(.*\)/\1/p')
|
||||||
git pull
|
git pull
|
||||||
run_exec php "composer update"
|
run_exec php "composer update"
|
||||||
run_exec php "php artisan migrate"
|
run_exec php "php artisan migrate"
|
||||||
supervisorctl_restart php
|
supervisorctl_restart php
|
||||||
$COMPOSE up -d
|
docker-compose up -d
|
||||||
elif [[ "$1" == "uninstall" ]]; then
|
elif [[ "$1" == "uninstall" ]]; then
|
||||||
shift 1
|
shift 1
|
||||||
read -rp "确定要卸载(含:删除容器、数据库、日志)吗?(y/n): " uninstall
|
read -rp "确定要卸载(含:删除容器、数据库、日志)吗?(y/n): " uninstall
|
||||||
@ -333,22 +242,11 @@ if [ $# -gt 0 ]; then
|
|||||||
exit 2
|
exit 2
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
$COMPOSE down
|
docker-compose down
|
||||||
rm -rf "./docker/mysql/data"
|
rm -rf "./docker/mysql/data"
|
||||||
rm -rf "./docker/log/supervisor"
|
rm -rf "./docker/log/supervisor"
|
||||||
find "./storage/logs" -name "*.log" | xargs rm -rf
|
find "./storage/logs" -name "*.log" | xargs rm -rf
|
||||||
echo -e "${OK} ${GreenBG} 卸载完成 ${Font}"
|
echo -e "${OK} ${GreenBG} 卸载完成 ${Font}"
|
||||||
elif [[ "$1" == "reinstall" ]]; then
|
|
||||||
shift 1
|
|
||||||
./cmd uninstall $@
|
|
||||||
sleep 3
|
|
||||||
./cmd install $@
|
|
||||||
elif [[ "$1" == "port" ]]; then
|
|
||||||
shift 1
|
|
||||||
env_set APP_PORT "$1"
|
|
||||||
$COMPOSE up -d
|
|
||||||
echo -e "${OK} ${GreenBG} 修改成功 ${Font}"
|
|
||||||
echo -e "地址: http://${GreenBG}127.0.0.1:$(env_get APP_PORT)${Font}"
|
|
||||||
elif [[ "$1" == "repassword" ]]; then
|
elif [[ "$1" == "repassword" ]]; then
|
||||||
shift 1
|
shift 1
|
||||||
run_exec mariadb "sh /etc/mysql/repassword.sh \"$@\""
|
run_exec mariadb "sh /etc/mysql/repassword.sh \"$@\""
|
||||||
@ -405,10 +303,10 @@ if [ $# -gt 0 ]; then
|
|||||||
elif [[ "$1" == "composer" ]]; then
|
elif [[ "$1" == "composer" ]]; then
|
||||||
shift 1
|
shift 1
|
||||||
e="composer $@" && run_exec php "$e"
|
e="composer $@" && run_exec php "$e"
|
||||||
elif [[ "$1" == "service" ]]; then
|
elif [[ "$1" == "super" ]]; then
|
||||||
shift 1
|
shift 1
|
||||||
e="service $@" && run_exec php "$e"
|
supervisorctl_restart "$@"
|
||||||
elif [[ "$1" == "super" ]] || [[ "$1" == "supervisorctl" ]]; then
|
elif [[ "$1" == "supervisorctl" ]]; then
|
||||||
shift 1
|
shift 1
|
||||||
e="supervisorctl $@" && run_exec php "$e"
|
e="supervisorctl $@" && run_exec php "$e"
|
||||||
elif [[ "$1" == "models" ]]; then
|
elif [[ "$1" == "models" ]]; then
|
||||||
@ -419,11 +317,11 @@ if [ $# -gt 0 ]; then
|
|||||||
e="./vendor/bin/phpunit $@" && run_exec php "$e"
|
e="./vendor/bin/phpunit $@" && run_exec php "$e"
|
||||||
elif [[ "$1" == "restart" ]]; then
|
elif [[ "$1" == "restart" ]]; then
|
||||||
shift 1
|
shift 1
|
||||||
$COMPOSE stop "$@"
|
docker-compose stop "$@"
|
||||||
$COMPOSE start "$@"
|
docker-compose start "$@"
|
||||||
else
|
else
|
||||||
$COMPOSE "$@"
|
docker-compose "$@"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
$COMPOSE ps
|
docker-compose ps
|
||||||
fi
|
fi
|
||||||
|
9554
composer.lock
generated
9554
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -17,7 +17,7 @@ class CreateProjectLogsTable extends Migration
|
|||||||
$table->bigIncrements('id');
|
$table->bigIncrements('id');
|
||||||
$table->bigInteger('project_id')->nullable()->default(0)->comment('项目ID');
|
$table->bigInteger('project_id')->nullable()->default(0)->comment('项目ID');
|
||||||
$table->bigInteger('column_id')->nullable()->default(0)->comment('列表ID');
|
$table->bigInteger('column_id')->nullable()->default(0)->comment('列表ID');
|
||||||
$table->bigInteger('task_id')->nullable()->default(0)->comment('任务ID');
|
$table->bigInteger('task_id')->nullable()->default(0)->comment('项目ID');
|
||||||
$table->bigInteger('userid')->nullable()->default(0)->comment('会员ID');
|
$table->bigInteger('userid')->nullable()->default(0)->comment('会员ID');
|
||||||
$table->string('detail', 500)->nullable()->default('')->comment('详细信息');
|
$table->string('detail', 500)->nullable()->default('')->comment('详细信息');
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
class CreateProjectInvitesTable extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
Schema::create('project_invites', function (Blueprint $table) {
|
|
||||||
$table->bigIncrements('id');
|
|
||||||
$table->bigInteger('project_id')->nullable()->default(0)->comment('项目ID');
|
|
||||||
$table->integer('num')->nullable()->default(0)->comment('累计邀请');
|
|
||||||
$table->string('code')->nullable()->default('')->comment('链接码');
|
|
||||||
$table->timestamps();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
Schema::dropIfExists('project_invites');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
class CreateFileLinksTable extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
Schema::create('file_links', function (Blueprint $table) {
|
|
||||||
$table->bigIncrements('id');
|
|
||||||
$table->bigInteger('file_id')->nullable()->default(0)->comment('项目ID');
|
|
||||||
$table->integer('num')->nullable()->default(0)->comment('累计访问');
|
|
||||||
$table->string('code')->nullable()->default('')->comment('链接码');
|
|
||||||
$table->timestamps();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
Schema::dropIfExists('file_links');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use App\Models\File;
|
|
||||||
use App\Models\FileUser;
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
class FileUsersAddPermission extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
$isAdd = false;
|
|
||||||
Schema::table('file_users', function (Blueprint $table) use (&$isAdd) {
|
|
||||||
if (!Schema::hasColumn('file_users', 'permission')) {
|
|
||||||
$isAdd = true;
|
|
||||||
$table->tinyInteger('permission')->nullable()->default(0)->after('userid')->comment('权限:0只读,1读写');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if ($isAdd) {
|
|
||||||
// 更新数据
|
|
||||||
File::whereShare(1)->chunkById(100, function ($lists) {
|
|
||||||
foreach ($lists as $file) {
|
|
||||||
FileUser::updateInsert([
|
|
||||||
'file_id' => $file->id,
|
|
||||||
'userid' => 0,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
File::whereShare(2)->update([
|
|
||||||
'share' => 1,
|
|
||||||
]);
|
|
||||||
FileUser::wherePermission(0)->update([
|
|
||||||
'permission' => 1,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
Schema::table('file_users', function (Blueprint $table) {
|
|
||||||
$table->dropColumn("permission");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
class CreateReportsTable extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
if ( Schema::hasTable('reports') )
|
|
||||||
return;
|
|
||||||
|
|
||||||
Schema::create('reports', function (Blueprint $table) {
|
|
||||||
$table->id();
|
|
||||||
$table->timestamps();
|
|
||||||
$table->string("title")->default("")->comment("标题");
|
|
||||||
$table->enum("type", ["weekly", "daily"])->default("daily")->comment("汇报类型");
|
|
||||||
$table->unsignedBigInteger("userid")->default(0);
|
|
||||||
$table->longText("content")->nullable();
|
|
||||||
$table->index(["userid", "created_at"], "default");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
Schema::dropIfExists('reports');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
class CreateReportReceivesTable extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
if ( Schema::hasTable('report_receives') )
|
|
||||||
return;
|
|
||||||
|
|
||||||
Schema::create('report_receives', function (Blueprint $table) {
|
|
||||||
$table->bigIncrements("id");
|
|
||||||
$table->unsignedInteger("rid")->default(0);
|
|
||||||
$table->timestamp("receive_time")->nullable()->comment("接收时间");
|
|
||||||
$table->unsignedBigInteger("userid")->default(0)->comment("接收人");
|
|
||||||
$table->unsignedTinyInteger("read")->default(0)->comment("是否已读");
|
|
||||||
$table->index(["userid", "receive_time"], "default");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
Schema::dropIfExists('report_receives');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
class AddReportSign extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
Schema::table('reports', function (Blueprint $table) {
|
|
||||||
$table->string("sign")->default("")->comment("汇报唯一标识");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
Schema::table('reports', function (Blueprint $table) {
|
|
||||||
$table->dropColumn("sign");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use App\Models\User;
|
|
||||||
use Carbon\Carbon;
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
class UsersAddDisableAt extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
$isAdd = false;
|
|
||||||
Schema::table('users', function (Blueprint $table) use (&$isAdd) {
|
|
||||||
if (!Schema::hasColumn('users', 'disable_at')) {
|
|
||||||
$isAdd = true;
|
|
||||||
$table->timestamp('disable_at')->nullable()->after('created_ip')->comment('禁用时间');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if ($isAdd) {
|
|
||||||
User::where("identity", "like", "%,disable,%")->update([
|
|
||||||
'disable_at' => Carbon::now(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
Schema::table('users', function (Blueprint $table) {
|
|
||||||
$table->dropColumn("disable_at");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use App\Models\ProjectTask;
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
|
|
||||||
class ProjectTasksUpdateSubtaskTime extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* 子任务同步主任务(任务时间)
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
ProjectTask::where('parent_id', '>', 0)
|
|
||||||
->whereNull('end_at')
|
|
||||||
->chunkById(100, function ($lists) {
|
|
||||||
/** @var ProjectTask $task */
|
|
||||||
foreach ($lists as $task) {
|
|
||||||
$parent = ProjectTask::whereNotNull('end_at')->find($task->parent_id);
|
|
||||||
if ($parent) {
|
|
||||||
$task->start_at = $parent->start_at;
|
|
||||||
$task->end_at = $parent->end_at;
|
|
||||||
$task->save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use App\Models\ProjectTask;
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
|
|
||||||
class ProjectTasksUpdateSubtaskArchivedDelete extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* 子任务同步主任务(归档、删除)
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
// 归档
|
|
||||||
ProjectTask::whereParentId(0)
|
|
||||||
->whereNotNull('archived_at')
|
|
||||||
->chunkById(100, function ($lists) {
|
|
||||||
/** @var ProjectTask $task */
|
|
||||||
foreach ($lists as $task) {
|
|
||||||
ProjectTask::whereParentId($task->id)->update([
|
|
||||||
'archived_at' => $task->archived_at,
|
|
||||||
'archived_userid' => $task->archived_userid,
|
|
||||||
'archived_follow' => $task->archived_follow,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 删除
|
|
||||||
ProjectTask::onlyTrashed()
|
|
||||||
->whereParentId(0)
|
|
||||||
->chunkById(100, function ($lists) {
|
|
||||||
/** @var ProjectTask $task */
|
|
||||||
foreach ($lists as $task) {
|
|
||||||
ProjectTask::whereParentId($task->id)->update([
|
|
||||||
'deleted_at' => $task->deleted_at,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
class CreateProjectFlowItemsTable extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
Schema::create('project_flow_items', function (Blueprint $table) {
|
|
||||||
$table->bigIncrements('id');
|
|
||||||
$table->bigInteger('project_id')->nullable()->default(0)->comment('项目ID');
|
|
||||||
$table->bigInteger('flow_id')->nullable()->default(0)->comment('流程ID');
|
|
||||||
$table->string('name', 50)->nullable()->default('')->comment('名称');
|
|
||||||
$table->string('status', 20)->nullable()->default('')->comment('状态');
|
|
||||||
$table->string('turns')->nullable()->default('')->comment('可流转');
|
|
||||||
$table->string('userids')->nullable()->default('')->comment('状态负责人ID');
|
|
||||||
$table->integer('sort')->nullable()->comment('排序');
|
|
||||||
$table->timestamps();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
Schema::dropIfExists('project_flow_items');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
class CreateProjectFlowsTable extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
Schema::create('project_flows', function (Blueprint $table) {
|
|
||||||
$table->bigIncrements('id');
|
|
||||||
$table->bigInteger('project_id')->nullable()->default(0)->comment('项目ID');
|
|
||||||
$table->string('name', 50)->nullable()->default('')->comment('流程名称');
|
|
||||||
$table->timestamps();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
Schema::dropIfExists('project_flows');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
class ProjectTasksAddFlowItemIdFlowItemName extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
Schema::table('project_tasks', function (Blueprint $table) {
|
|
||||||
if (!Schema::hasColumn('project_tasks', 'flow_item_id')) {
|
|
||||||
$table->bigInteger('flow_item_id')->nullable()->default(0)->after('dialog_id')->comment('工作流状态ID');
|
|
||||||
$table->string('flow_item_name', 50)->nullable()->default('')->after('flow_item_id')->comment('工作流状态名称');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
Schema::table('project_tasks', function (Blueprint $table) {
|
|
||||||
$table->dropColumn("flow_item_id");
|
|
||||||
$table->dropColumn("flow_item_name");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use App\Models\ProjectFlowItem;
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
class ProjectFlowItemsAddUsertype extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
$isAdd = false;
|
|
||||||
Schema::table('project_flow_items', function (Blueprint $table) use (&$isAdd) {
|
|
||||||
if (!Schema::hasColumn('project_flow_items', 'usertype')) {
|
|
||||||
$isAdd = true;
|
|
||||||
$table->string('usertype', 10)->nullable()->default('')->after('userids')->comment('流转模式');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if ($isAdd) {
|
|
||||||
ProjectFlowItem::where("usertype", "")->update([
|
|
||||||
'usertype' => 'add',
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
Schema::table('project_flow_items', function (Blueprint $table) {
|
|
||||||
$table->dropColumn("usertype");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
class ProjectLogsAddRecord extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
Schema::table('project_logs', function (Blueprint $table) {
|
|
||||||
if (!Schema::hasColumn('project_logs', 'record')) {
|
|
||||||
$table->text('record')->nullable()->after('detail')->comment('记录数据');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
Schema::table('project_logs', function (Blueprint $table) {
|
|
||||||
$table->dropColumn("record");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
class ProjectFlowItemsAddUserlimit extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
Schema::table('project_flow_items', function (Blueprint $table) {
|
|
||||||
if (!Schema::hasColumn('project_flow_items', 'userlimit')) {
|
|
||||||
$table->tinyInteger('userlimit')->nullable()->default(0)->after('usertype')->comment('限制负责人');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
Schema::table('project_flow_items', function (Blueprint $table) {
|
|
||||||
$table->dropColumn("userlimit");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
class WebSocketDialogMsgsAddDeletes extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
Schema::table('web_socket_dialog_msgs', function (Blueprint $table) {
|
|
||||||
if (!Schema::hasColumn('web_socket_dialog_msgs', 'deleted_at')) {
|
|
||||||
$table->softDeletes();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
Schema::table('web_socket_dialog_msgs', function (Blueprint $table) {
|
|
||||||
$table->dropSoftDeletes();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
class InsertSettingColumnTemplate extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
$array = \App\Module\Base::setting('columnTemplate');
|
|
||||||
if (empty($array)) {
|
|
||||||
\App\Module\Base::setting('columnTemplate', [
|
|
||||||
[
|
|
||||||
'name' => '软件开发',
|
|
||||||
'columns' => ['产品规划', '前端开发', '后端开发', '测试', '发布', '其他'],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'name' => '产品开发',
|
|
||||||
'columns' => ['产品计划', '正在设计', '正在研发', '测试', '准备发布', '发布成功'],
|
|
||||||
],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
class WebSocketDialogUsersAddTopAt extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
Schema::table('web_socket_dialog_users', function (Blueprint $table) {
|
|
||||||
if (!Schema::hasColumn('web_socket_dialog_users', 'top_at')) {
|
|
||||||
$table->timestamp('top_at')->nullable()->after('userid')->comment('置顶时间');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
Schema::table('web_socket_dialog_users', function (Blueprint $table) {
|
|
||||||
$table->dropColumn("top_at");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use App\Models\File;
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
|
|
||||||
class FilesUpdateType extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* 更改流程图文件类型
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
File::whereType('flow')->update([
|
|
||||||
'type' => 'drawio'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
File::whereType('drawio')->update([
|
|
||||||
'type' => 'flow'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,75 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
@error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
|
|
||||||
|
|
||||||
use App\Models\File;
|
|
||||||
use App\Models\FileContent;
|
|
||||||
use App\Module\Base;
|
|
||||||
use Carbon\Carbon;
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
|
|
||||||
class FilesUpdateExt extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* 更新后缀
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
File::whereIn('type', ['mind', 'drawio', 'document'])->where('ext', '')->orderBy('id')->chunk(100, function($files) {
|
|
||||||
/** @var File $file */
|
|
||||||
foreach ($files as $file) {
|
|
||||||
$fileContent = FileContent::whereFid($file->id)->orderByDesc('id')->first();
|
|
||||||
$contentArray = Base::json2array($fileContent?->content);
|
|
||||||
$contentString = '';
|
|
||||||
//
|
|
||||||
switch ($file->type) {
|
|
||||||
case 'document':
|
|
||||||
$file->ext = $contentArray['type'] ?: 'md';
|
|
||||||
$contentString = $contentArray['content'];
|
|
||||||
break;
|
|
||||||
case 'drawio':
|
|
||||||
$file->ext = 'drawio';
|
|
||||||
$contentString = $contentArray['xml'];
|
|
||||||
break;
|
|
||||||
case 'mind':
|
|
||||||
$file->ext = 'mind';
|
|
||||||
$contentString = $fileContent?->content;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$file->save();
|
|
||||||
//
|
|
||||||
$path = 'uploads/file/' . $file->type . '/' . date("Ym", Carbon::parse($file->created_at)->timestamp) . '/' . $file->id . '/' . md5($contentString);
|
|
||||||
$save = public_path($path);
|
|
||||||
Base::makeDir(dirname($save));
|
|
||||||
file_put_contents($save, $contentString);
|
|
||||||
$content = [
|
|
||||||
'type' => $file->ext,
|
|
||||||
'url' => $path
|
|
||||||
];
|
|
||||||
//
|
|
||||||
$content = FileContent::createInstance([
|
|
||||||
'fid' => $file->id,
|
|
||||||
'content' => $content,
|
|
||||||
'text' => $fileContent?->text,
|
|
||||||
'size' => $file->size,
|
|
||||||
'userid' => $file->userid,
|
|
||||||
]);
|
|
||||||
$content->save();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
File::whereIn('ext', ['mind', 'drawio', 'md'])->update([
|
|
||||||
'ext' => ''
|
|
||||||
]);
|
|
||||||
// ... 退回去意义不大,文件内容不做回滚操作
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
class ProjectUsersAddTopAt extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
Schema::table('project_users', function (Blueprint $table) {
|
|
||||||
if (!Schema::hasColumn('project_users', 'top_at')) {
|
|
||||||
$table->timestamp('top_at')->nullable()->after('owner')->comment('置顶时间');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
Schema::table('project_users', function (Blueprint $table) {
|
|
||||||
$table->dropColumn("top_at");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
class CreateProjectTaskFlowChangesTable extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
Schema::create('project_task_flow_changes', function (Blueprint $table) {
|
|
||||||
$table->bigIncrements('id');
|
|
||||||
$table->bigInteger('task_id')->nullable()->default(0)->comment('任务ID');
|
|
||||||
$table->bigInteger('userid')->nullable()->default(0)->comment('会员ID');
|
|
||||||
$table->bigInteger('before_item_id')->nullable()->default(0)->comment('(变化前)工作流状态ID');
|
|
||||||
$table->string('before_item_name', 50)->nullable()->default('')->comment('(变化前)工作流状态名称');
|
|
||||||
$table->bigInteger('after_item_id')->nullable()->default(0)->comment('(变化后)工作流状态ID');
|
|
||||||
$table->string('after_item_name', 50)->nullable()->default('')->comment('(变化后)工作流状态名称');
|
|
||||||
$table->timestamps();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
Schema::dropIfExists('project_task_flow_changes');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
|
||||||
use Illuminate\Support\Facades\Schema;
|
|
||||||
|
|
||||||
class RenamePreProjectTaskFlowChangesItem extends Migration
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function up()
|
|
||||||
{
|
|
||||||
Schema::table('project_task_flow_changes', function (Blueprint $table) {
|
|
||||||
if (Schema::hasColumn('project_task_flow_changes', 'before_item_id')) {
|
|
||||||
$table->renameColumn('before_item_id', 'before_flow_item_id');
|
|
||||||
$table->renameColumn('before_item_name', 'before_flow_item_name');
|
|
||||||
$table->renameColumn('after_item_id', 'after_flow_item_id');
|
|
||||||
$table->renameColumn('after_item_name', 'after_flow_item_name');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverse the migrations.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function down()
|
|
||||||
{
|
|
||||||
Schema::table('project_task_flow_changes', function (Blueprint $table) {
|
|
||||||
//
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -16,10 +16,7 @@ class DatabaseSeeder extends Seeder
|
|||||||
|
|
||||||
$this->call(FileContentsTableSeeder::class);
|
$this->call(FileContentsTableSeeder::class);
|
||||||
$this->call(FilesTableSeeder::class);
|
$this->call(FilesTableSeeder::class);
|
||||||
$this->call(FileUsersTableSeeder::class);
|
|
||||||
$this->call(ProjectColumnsTableSeeder::class);
|
$this->call(ProjectColumnsTableSeeder::class);
|
||||||
$this->call(ProjectFlowItemsTableSeeder::class);
|
|
||||||
$this->call(ProjectFlowsTableSeeder::class);
|
|
||||||
$this->call(ProjectLogsTableSeeder::class);
|
$this->call(ProjectLogsTableSeeder::class);
|
||||||
$this->call(ProjectTaskContentsTableSeeder::class);
|
$this->call(ProjectTaskContentsTableSeeder::class);
|
||||||
$this->call(ProjectTaskUsersTableSeeder::class);
|
$this->call(ProjectTaskUsersTableSeeder::class);
|
||||||
|
@ -599,5 +599,7 @@ curl -O https://task.hitosea.com/uploads/files/3/202105/ba786dfc2f4c2fe916880474
|
|||||||
'deleted_at' => NULL,
|
'deleted_at' => NULL,
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,82 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Database\Seeders;
|
|
||||||
|
|
||||||
use Illuminate\Database\Seeder;
|
|
||||||
|
|
||||||
class FileUsersTableSeeder extends Seeder
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Auto generated seed file
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function run()
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
if (\DB::table('file_users')->count() > 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
\DB::table('file_users')->insert(array (
|
|
||||||
0 =>
|
|
||||||
array (
|
|
||||||
'id' => 1,
|
|
||||||
'file_id' => 1,
|
|
||||||
'userid' => 0,
|
|
||||||
'permission' => 1,
|
|
||||||
'created_at' => seeders_at('2021-07-01 14:03:29'),
|
|
||||||
'updated_at' => seeders_at('2021-07-01 14:03:29'),
|
|
||||||
),
|
|
||||||
1 =>
|
|
||||||
array (
|
|
||||||
'id' => 2,
|
|
||||||
'file_id' => 11,
|
|
||||||
'userid' => 0,
|
|
||||||
'permission' => 1,
|
|
||||||
'created_at' => seeders_at('2021-07-01 14:03:29'),
|
|
||||||
'updated_at' => seeders_at('2021-07-01 14:03:29'),
|
|
||||||
),
|
|
||||||
2 =>
|
|
||||||
array (
|
|
||||||
'id' => 3,
|
|
||||||
'file_id' => 12,
|
|
||||||
'userid' => 0,
|
|
||||||
'permission' => 1,
|
|
||||||
'created_at' => seeders_at('2021-07-01 14:03:29'),
|
|
||||||
'updated_at' => seeders_at('2021-07-01 14:03:29'),
|
|
||||||
),
|
|
||||||
3 =>
|
|
||||||
array (
|
|
||||||
'id' => 4,
|
|
||||||
'file_id' => 13,
|
|
||||||
'userid' => 0,
|
|
||||||
'permission' => 1,
|
|
||||||
'created_at' => seeders_at('2021-07-01 14:03:29'),
|
|
||||||
'updated_at' => seeders_at('2021-07-01 14:03:29'),
|
|
||||||
),
|
|
||||||
4 =>
|
|
||||||
array (
|
|
||||||
'id' => 5,
|
|
||||||
'file_id' => 15,
|
|
||||||
'userid' => 0,
|
|
||||||
'permission' => 1,
|
|
||||||
'created_at' => seeders_at('2021-07-01 14:03:29'),
|
|
||||||
'updated_at' => seeders_at('2021-07-01 14:03:29'),
|
|
||||||
),
|
|
||||||
5 =>
|
|
||||||
array (
|
|
||||||
'id' => 6,
|
|
||||||
'file_id' => 16,
|
|
||||||
'userid' => 0,
|
|
||||||
'permission' => 1,
|
|
||||||
'created_at' => seeders_at('2021-07-01 14:03:29'),
|
|
||||||
'updated_at' => seeders_at('2021-07-01 14:03:29'),
|
|
||||||
),
|
|
||||||
));
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,10 +2,6 @@
|
|||||||
|
|
||||||
namespace Database\Seeders;
|
namespace Database\Seeders;
|
||||||
|
|
||||||
use App\Models\File;
|
|
||||||
use App\Models\FileContent;
|
|
||||||
use App\Module\Base;
|
|
||||||
use Carbon\Carbon;
|
|
||||||
use Illuminate\Database\Seeder;
|
use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
class FilesTableSeeder extends Seeder
|
class FilesTableSeeder extends Seeder
|
||||||
@ -32,7 +28,6 @@ class FilesTableSeeder extends Seeder
|
|||||||
'cid' => 0,
|
'cid' => 0,
|
||||||
'name' => '设计知识',
|
'name' => '设计知识',
|
||||||
'type' => 'folder',
|
'type' => 'folder',
|
||||||
'ext' => '',
|
|
||||||
'size' => 0,
|
'size' => 0,
|
||||||
'userid' => 1,
|
'userid' => 1,
|
||||||
'share' => 1,
|
'share' => 1,
|
||||||
@ -48,7 +43,6 @@ class FilesTableSeeder extends Seeder
|
|||||||
'cid' => 0,
|
'cid' => 0,
|
||||||
'name' => '如何搭建B端设计规范?',
|
'name' => '如何搭建B端设计规范?',
|
||||||
'type' => 'document',
|
'type' => 'document',
|
||||||
'ext' => '',
|
|
||||||
'size' => 16976,
|
'size' => 16976,
|
||||||
'userid' => 1,
|
'userid' => 1,
|
||||||
'share' => 0,
|
'share' => 0,
|
||||||
@ -64,7 +58,6 @@ class FilesTableSeeder extends Seeder
|
|||||||
'cid' => 0,
|
'cid' => 0,
|
||||||
'name' => '页面设计中的信息组织策略探索-言之有序',
|
'name' => '页面设计中的信息组织策略探索-言之有序',
|
||||||
'type' => 'document',
|
'type' => 'document',
|
||||||
'ext' => '',
|
|
||||||
'size' => 11971,
|
'size' => 11971,
|
||||||
'userid' => 1,
|
'userid' => 1,
|
||||||
'share' => 0,
|
'share' => 0,
|
||||||
@ -80,7 +73,6 @@ class FilesTableSeeder extends Seeder
|
|||||||
'cid' => 0,
|
'cid' => 0,
|
||||||
'name' => '素材整理',
|
'name' => '素材整理',
|
||||||
'type' => 'folder',
|
'type' => 'folder',
|
||||||
'ext' => '',
|
|
||||||
'size' => 0,
|
'size' => 0,
|
||||||
'userid' => 1,
|
'userid' => 1,
|
||||||
'share' => 0,
|
'share' => 0,
|
||||||
@ -96,7 +88,6 @@ class FilesTableSeeder extends Seeder
|
|||||||
'cid' => 0,
|
'cid' => 0,
|
||||||
'name' => '配置静态IP地址',
|
'name' => '配置静态IP地址',
|
||||||
'type' => 'document',
|
'type' => 'document',
|
||||||
'ext' => '',
|
|
||||||
'size' => 285,
|
'size' => 285,
|
||||||
'userid' => 1,
|
'userid' => 1,
|
||||||
'share' => 0,
|
'share' => 0,
|
||||||
@ -112,7 +103,6 @@ class FilesTableSeeder extends Seeder
|
|||||||
'cid' => 0,
|
'cid' => 0,
|
||||||
'name' => '脑图',
|
'name' => '脑图',
|
||||||
'type' => 'mind',
|
'type' => 'mind',
|
||||||
'ext' => '',
|
|
||||||
'size' => 1947,
|
'size' => 1947,
|
||||||
'userid' => 1,
|
'userid' => 1,
|
||||||
'share' => 0,
|
'share' => 0,
|
||||||
@ -128,7 +118,6 @@ class FilesTableSeeder extends Seeder
|
|||||||
'cid' => 0,
|
'cid' => 0,
|
||||||
'name' => '数据统计',
|
'name' => '数据统计',
|
||||||
'type' => 'excel',
|
'type' => 'excel',
|
||||||
'ext' => 'xlsx',
|
|
||||||
'size' => 8128,
|
'size' => 8128,
|
||||||
'userid' => 1,
|
'userid' => 1,
|
||||||
'share' => 0,
|
'share' => 0,
|
||||||
@ -144,7 +133,6 @@ class FilesTableSeeder extends Seeder
|
|||||||
'cid' => 0,
|
'cid' => 0,
|
||||||
'name' => '会议纪要',
|
'name' => '会议纪要',
|
||||||
'type' => 'document',
|
'type' => 'document',
|
||||||
'ext' => '',
|
|
||||||
'size' => 8088,
|
'size' => 8088,
|
||||||
'userid' => 1,
|
'userid' => 1,
|
||||||
'share' => 0,
|
'share' => 0,
|
||||||
@ -160,7 +148,6 @@ class FilesTableSeeder extends Seeder
|
|||||||
'cid' => 0,
|
'cid' => 0,
|
||||||
'name' => '部门周报',
|
'name' => '部门周报',
|
||||||
'type' => 'document',
|
'type' => 'document',
|
||||||
'ext' => '',
|
|
||||||
'size' => 23266,
|
'size' => 23266,
|
||||||
'userid' => 1,
|
'userid' => 1,
|
||||||
'share' => 0,
|
'share' => 0,
|
||||||
@ -176,7 +163,6 @@ class FilesTableSeeder extends Seeder
|
|||||||
'cid' => 0,
|
'cid' => 0,
|
||||||
'name' => '项目管理',
|
'name' => '项目管理',
|
||||||
'type' => 'excel',
|
'type' => 'excel',
|
||||||
'ext' => 'xlsx',
|
|
||||||
'size' => 8128,
|
'size' => 8128,
|
||||||
'userid' => 1,
|
'userid' => 1,
|
||||||
'share' => 0,
|
'share' => 0,
|
||||||
@ -192,7 +178,6 @@ class FilesTableSeeder extends Seeder
|
|||||||
'cid' => 0,
|
'cid' => 0,
|
||||||
'name' => '工作计划',
|
'name' => '工作计划',
|
||||||
'type' => 'excel',
|
'type' => 'excel',
|
||||||
'ext' => 'xlsx',
|
|
||||||
'size' => 8128,
|
'size' => 8128,
|
||||||
'userid' => 1,
|
'userid' => 1,
|
||||||
'share' => 1,
|
'share' => 1,
|
||||||
@ -207,8 +192,7 @@ class FilesTableSeeder extends Seeder
|
|||||||
'pid' => 0,
|
'pid' => 0,
|
||||||
'cid' => 0,
|
'cid' => 0,
|
||||||
'name' => '流程图',
|
'name' => '流程图',
|
||||||
'type' => 'drawio',
|
'type' => 'flow',
|
||||||
'ext' => '',
|
|
||||||
'size' => 5418,
|
'size' => 5418,
|
||||||
'userid' => 1,
|
'userid' => 1,
|
||||||
'share' => 1,
|
'share' => 1,
|
||||||
@ -224,7 +208,6 @@ class FilesTableSeeder extends Seeder
|
|||||||
'cid' => 0,
|
'cid' => 0,
|
||||||
'name' => '项目管理',
|
'name' => '项目管理',
|
||||||
'type' => 'folder',
|
'type' => 'folder',
|
||||||
'ext' => '',
|
|
||||||
'size' => 0,
|
'size' => 0,
|
||||||
'userid' => 1,
|
'userid' => 1,
|
||||||
'share' => 1,
|
'share' => 1,
|
||||||
@ -240,7 +223,6 @@ class FilesTableSeeder extends Seeder
|
|||||||
'cid' => 0,
|
'cid' => 0,
|
||||||
'name' => '会议纪要',
|
'name' => '会议纪要',
|
||||||
'type' => 'folder',
|
'type' => 'folder',
|
||||||
'ext' => '',
|
|
||||||
'size' => 0,
|
'size' => 0,
|
||||||
'userid' => 1,
|
'userid' => 1,
|
||||||
'share' => 0,
|
'share' => 0,
|
||||||
@ -256,7 +238,6 @@ class FilesTableSeeder extends Seeder
|
|||||||
'cid' => 0,
|
'cid' => 0,
|
||||||
'name' => '会议发言',
|
'name' => '会议发言',
|
||||||
'type' => 'word',
|
'type' => 'word',
|
||||||
'ext' => 'docx',
|
|
||||||
'size' => 10994,
|
'size' => 10994,
|
||||||
'userid' => 1,
|
'userid' => 1,
|
||||||
'share' => 1,
|
'share' => 1,
|
||||||
@ -272,7 +253,6 @@ class FilesTableSeeder extends Seeder
|
|||||||
'cid' => 0,
|
'cid' => 0,
|
||||||
'name' => '产品介绍',
|
'name' => '产品介绍',
|
||||||
'type' => 'ppt',
|
'type' => 'ppt',
|
||||||
'ext' => 'pptx',
|
|
||||||
'size' => 26882,
|
'size' => 26882,
|
||||||
'userid' => 1,
|
'userid' => 1,
|
||||||
'share' => 1,
|
'share' => 1,
|
||||||
@ -284,47 +264,5 @@ class FilesTableSeeder extends Seeder
|
|||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
File::whereIn('type', ['mind', 'drawio', 'document'])->where('ext', '')->orderBy('id')->chunk(100, function($files) {
|
|
||||||
/** @var File $file */
|
|
||||||
foreach ($files as $file) {
|
|
||||||
$fileContent = FileContent::whereFid($file->id)->orderByDesc('id')->first();
|
|
||||||
$contentArray = Base::json2array($fileContent?->content);
|
|
||||||
$contentString = '';
|
|
||||||
//
|
|
||||||
switch ($file->type) {
|
|
||||||
case 'document':
|
|
||||||
$file->ext = $contentArray['type'] ?: 'md';
|
|
||||||
$contentString = $contentArray['content'];
|
|
||||||
break;
|
|
||||||
case 'drawio':
|
|
||||||
$file->ext = 'drawio';
|
|
||||||
$contentString = $contentArray['xml'];
|
|
||||||
break;
|
|
||||||
case 'mind':
|
|
||||||
$file->ext = 'mind';
|
|
||||||
$contentString = $fileContent?->content;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$file->save();
|
|
||||||
//
|
|
||||||
$path = 'uploads/file/' . $file->type . '/' . date("Ym", Carbon::parse($file->created_at)->timestamp) . '/' . $file->id . '/' . md5($contentString);
|
|
||||||
$save = public_path($path);
|
|
||||||
Base::makeDir(dirname($save));
|
|
||||||
file_put_contents($save, $contentString);
|
|
||||||
$content = [
|
|
||||||
'type' => $file->ext,
|
|
||||||
'url' => $path
|
|
||||||
];
|
|
||||||
//
|
|
||||||
$content = FileContent::createInstance([
|
|
||||||
'fid' => $file->id,
|
|
||||||
'content' => $content,
|
|
||||||
'text' => $fileContent?->text,
|
|
||||||
'size' => $file->size,
|
|
||||||
'userid' => $file->userid,
|
|
||||||
]);
|
|
||||||
$content->save();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,388 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Database\Seeders;
|
|
||||||
|
|
||||||
use Illuminate\Database\Seeder;
|
|
||||||
|
|
||||||
class ProjectFlowItemsTableSeeder extends Seeder
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Auto generated seed file
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function run()
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
if (\DB::table('project_flow_items')->count() > 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
\DB::table('project_flow_items')->insert(array (
|
|
||||||
0 =>
|
|
||||||
array (
|
|
||||||
'id' => 1,
|
|
||||||
'project_id' => 2,
|
|
||||||
'flow_id' => 1,
|
|
||||||
'name' => '待处理',
|
|
||||||
'status' => 'start',
|
|
||||||
'turns' => '[1,2,3,4]',
|
|
||||||
'userids' => '[]',
|
|
||||||
'usertype' => 'add',
|
|
||||||
'userlimit' => 0,
|
|
||||||
'sort' => 0,
|
|
||||||
'created_at' => '2022-01-15 23:43:15',
|
|
||||||
'updated_at' => '2022-01-15 23:43:15',
|
|
||||||
),
|
|
||||||
1 =>
|
|
||||||
array (
|
|
||||||
'id' => 2,
|
|
||||||
'project_id' => 2,
|
|
||||||
'flow_id' => 1,
|
|
||||||
'name' => '进行中',
|
|
||||||
'status' => 'progress',
|
|
||||||
'turns' => '[1,2,3,4]',
|
|
||||||
'userids' => '[]',
|
|
||||||
'usertype' => 'add',
|
|
||||||
'userlimit' => 0,
|
|
||||||
'sort' => 1,
|
|
||||||
'created_at' => '2022-01-15 23:43:15',
|
|
||||||
'updated_at' => '2022-01-15 23:43:15',
|
|
||||||
),
|
|
||||||
2 =>
|
|
||||||
array (
|
|
||||||
'id' => 3,
|
|
||||||
'project_id' => 2,
|
|
||||||
'flow_id' => 1,
|
|
||||||
'name' => '已完成',
|
|
||||||
'status' => 'end',
|
|
||||||
'turns' => '[1,2,3,4]',
|
|
||||||
'userids' => '[]',
|
|
||||||
'usertype' => 'add',
|
|
||||||
'userlimit' => 0,
|
|
||||||
'sort' => 2,
|
|
||||||
'created_at' => '2022-01-15 23:43:15',
|
|
||||||
'updated_at' => '2022-01-15 23:43:15',
|
|
||||||
),
|
|
||||||
3 =>
|
|
||||||
array (
|
|
||||||
'id' => 4,
|
|
||||||
'project_id' => 2,
|
|
||||||
'flow_id' => 1,
|
|
||||||
'name' => '已取消',
|
|
||||||
'status' => 'end',
|
|
||||||
'turns' => '[1,2,3,4]',
|
|
||||||
'userids' => '[]',
|
|
||||||
'usertype' => 'add',
|
|
||||||
'userlimit' => 0,
|
|
||||||
'sort' => 3,
|
|
||||||
'created_at' => '2022-01-15 23:43:15',
|
|
||||||
'updated_at' => '2022-01-15 23:43:15',
|
|
||||||
),
|
|
||||||
4 =>
|
|
||||||
array (
|
|
||||||
'id' => 5,
|
|
||||||
'project_id' => 3,
|
|
||||||
'flow_id' => 2,
|
|
||||||
'name' => '待处理',
|
|
||||||
'status' => 'start',
|
|
||||||
'turns' => '[5,6,7,8]',
|
|
||||||
'userids' => '[]',
|
|
||||||
'usertype' => 'add',
|
|
||||||
'userlimit' => 0,
|
|
||||||
'sort' => 0,
|
|
||||||
'created_at' => '2022-01-15 23:43:23',
|
|
||||||
'updated_at' => '2022-01-15 23:43:23',
|
|
||||||
),
|
|
||||||
5 =>
|
|
||||||
array (
|
|
||||||
'id' => 6,
|
|
||||||
'project_id' => 3,
|
|
||||||
'flow_id' => 2,
|
|
||||||
'name' => '进行中',
|
|
||||||
'status' => 'progress',
|
|
||||||
'turns' => '[5,6,7,8]',
|
|
||||||
'userids' => '[]',
|
|
||||||
'usertype' => 'add',
|
|
||||||
'userlimit' => 0,
|
|
||||||
'sort' => 1,
|
|
||||||
'created_at' => '2022-01-15 23:43:23',
|
|
||||||
'updated_at' => '2022-01-15 23:43:23',
|
|
||||||
),
|
|
||||||
6 =>
|
|
||||||
array (
|
|
||||||
'id' => 7,
|
|
||||||
'project_id' => 3,
|
|
||||||
'flow_id' => 2,
|
|
||||||
'name' => '已完成',
|
|
||||||
'status' => 'end',
|
|
||||||
'turns' => '[5,6,7,8]',
|
|
||||||
'userids' => '[]',
|
|
||||||
'usertype' => 'add',
|
|
||||||
'userlimit' => 0,
|
|
||||||
'sort' => 2,
|
|
||||||
'created_at' => '2022-01-15 23:43:23',
|
|
||||||
'updated_at' => '2022-01-15 23:43:23',
|
|
||||||
),
|
|
||||||
7 =>
|
|
||||||
array (
|
|
||||||
'id' => 8,
|
|
||||||
'project_id' => 3,
|
|
||||||
'flow_id' => 2,
|
|
||||||
'name' => '已取消',
|
|
||||||
'status' => 'end',
|
|
||||||
'turns' => '[5,6,7,8]',
|
|
||||||
'userids' => '[]',
|
|
||||||
'usertype' => 'add',
|
|
||||||
'userlimit' => 0,
|
|
||||||
'sort' => 3,
|
|
||||||
'created_at' => '2022-01-15 23:43:23',
|
|
||||||
'updated_at' => '2022-01-15 23:43:23',
|
|
||||||
),
|
|
||||||
8 =>
|
|
||||||
array (
|
|
||||||
'id' => 9,
|
|
||||||
'project_id' => 4,
|
|
||||||
'flow_id' => 3,
|
|
||||||
'name' => '待处理',
|
|
||||||
'status' => 'start',
|
|
||||||
'turns' => '[9,10,11,12]',
|
|
||||||
'userids' => '[]',
|
|
||||||
'usertype' => 'add',
|
|
||||||
'userlimit' => 0,
|
|
||||||
'sort' => 0,
|
|
||||||
'created_at' => '2022-01-15 23:43:28',
|
|
||||||
'updated_at' => '2022-01-15 23:43:28',
|
|
||||||
),
|
|
||||||
9 =>
|
|
||||||
array (
|
|
||||||
'id' => 10,
|
|
||||||
'project_id' => 4,
|
|
||||||
'flow_id' => 3,
|
|
||||||
'name' => '进行中',
|
|
||||||
'status' => 'progress',
|
|
||||||
'turns' => '[9,10,11,12]',
|
|
||||||
'userids' => '[]',
|
|
||||||
'usertype' => 'add',
|
|
||||||
'userlimit' => 0,
|
|
||||||
'sort' => 1,
|
|
||||||
'created_at' => '2022-01-15 23:43:28',
|
|
||||||
'updated_at' => '2022-01-15 23:43:28',
|
|
||||||
),
|
|
||||||
10 =>
|
|
||||||
array (
|
|
||||||
'id' => 11,
|
|
||||||
'project_id' => 4,
|
|
||||||
'flow_id' => 3,
|
|
||||||
'name' => '已完成',
|
|
||||||
'status' => 'end',
|
|
||||||
'turns' => '[9,10,11,12]',
|
|
||||||
'userids' => '[]',
|
|
||||||
'usertype' => 'add',
|
|
||||||
'userlimit' => 0,
|
|
||||||
'sort' => 2,
|
|
||||||
'created_at' => '2022-01-15 23:43:28',
|
|
||||||
'updated_at' => '2022-01-15 23:43:28',
|
|
||||||
),
|
|
||||||
11 =>
|
|
||||||
array (
|
|
||||||
'id' => 12,
|
|
||||||
'project_id' => 4,
|
|
||||||
'flow_id' => 3,
|
|
||||||
'name' => '已取消',
|
|
||||||
'status' => 'end',
|
|
||||||
'turns' => '[9,10,11,12]',
|
|
||||||
'userids' => '[]',
|
|
||||||
'usertype' => 'add',
|
|
||||||
'userlimit' => 0,
|
|
||||||
'sort' => 3,
|
|
||||||
'created_at' => '2022-01-15 23:43:28',
|
|
||||||
'updated_at' => '2022-01-15 23:43:28',
|
|
||||||
),
|
|
||||||
12 =>
|
|
||||||
array (
|
|
||||||
'id' => 13,
|
|
||||||
'project_id' => 5,
|
|
||||||
'flow_id' => 4,
|
|
||||||
'name' => '待处理',
|
|
||||||
'status' => 'start',
|
|
||||||
'turns' => '[13,14,15,16]',
|
|
||||||
'userids' => '[]',
|
|
||||||
'usertype' => 'add',
|
|
||||||
'userlimit' => 0,
|
|
||||||
'sort' => 0,
|
|
||||||
'created_at' => '2022-01-15 23:43:34',
|
|
||||||
'updated_at' => '2022-01-15 23:43:34',
|
|
||||||
),
|
|
||||||
13 =>
|
|
||||||
array (
|
|
||||||
'id' => 14,
|
|
||||||
'project_id' => 5,
|
|
||||||
'flow_id' => 4,
|
|
||||||
'name' => '进行中',
|
|
||||||
'status' => 'progress',
|
|
||||||
'turns' => '[13,14,15,16]',
|
|
||||||
'userids' => '[]',
|
|
||||||
'usertype' => 'add',
|
|
||||||
'userlimit' => 0,
|
|
||||||
'sort' => 1,
|
|
||||||
'created_at' => '2022-01-15 23:43:34',
|
|
||||||
'updated_at' => '2022-01-15 23:43:34',
|
|
||||||
),
|
|
||||||
14 =>
|
|
||||||
array (
|
|
||||||
'id' => 15,
|
|
||||||
'project_id' => 5,
|
|
||||||
'flow_id' => 4,
|
|
||||||
'name' => '已完成',
|
|
||||||
'status' => 'end',
|
|
||||||
'turns' => '[13,14,15,16]',
|
|
||||||
'userids' => '[]',
|
|
||||||
'usertype' => 'add',
|
|
||||||
'userlimit' => 0,
|
|
||||||
'sort' => 2,
|
|
||||||
'created_at' => '2022-01-15 23:43:34',
|
|
||||||
'updated_at' => '2022-01-15 23:43:34',
|
|
||||||
),
|
|
||||||
15 =>
|
|
||||||
array (
|
|
||||||
'id' => 16,
|
|
||||||
'project_id' => 5,
|
|
||||||
'flow_id' => 4,
|
|
||||||
'name' => '已取消',
|
|
||||||
'status' => 'end',
|
|
||||||
'turns' => '[13,14,15,16]',
|
|
||||||
'userids' => '[]',
|
|
||||||
'usertype' => 'add',
|
|
||||||
'userlimit' => 0,
|
|
||||||
'sort' => 3,
|
|
||||||
'created_at' => '2022-01-15 23:43:34',
|
|
||||||
'updated_at' => '2022-01-15 23:43:34',
|
|
||||||
),
|
|
||||||
16 =>
|
|
||||||
array (
|
|
||||||
'id' => 17,
|
|
||||||
'project_id' => 6,
|
|
||||||
'flow_id' => 5,
|
|
||||||
'name' => '待处理',
|
|
||||||
'status' => 'start',
|
|
||||||
'turns' => '[17,18,19,20]',
|
|
||||||
'userids' => '[]',
|
|
||||||
'usertype' => 'add',
|
|
||||||
'userlimit' => 0,
|
|
||||||
'sort' => 0,
|
|
||||||
'created_at' => '2022-01-15 23:43:40',
|
|
||||||
'updated_at' => '2022-01-15 23:43:40',
|
|
||||||
),
|
|
||||||
17 =>
|
|
||||||
array (
|
|
||||||
'id' => 18,
|
|
||||||
'project_id' => 6,
|
|
||||||
'flow_id' => 5,
|
|
||||||
'name' => '进行中',
|
|
||||||
'status' => 'progress',
|
|
||||||
'turns' => '[17,18,19,20]',
|
|
||||||
'userids' => '[]',
|
|
||||||
'usertype' => 'add',
|
|
||||||
'userlimit' => 0,
|
|
||||||
'sort' => 1,
|
|
||||||
'created_at' => '2022-01-15 23:43:40',
|
|
||||||
'updated_at' => '2022-01-15 23:43:40',
|
|
||||||
),
|
|
||||||
18 =>
|
|
||||||
array (
|
|
||||||
'id' => 19,
|
|
||||||
'project_id' => 6,
|
|
||||||
'flow_id' => 5,
|
|
||||||
'name' => '已完成',
|
|
||||||
'status' => 'end',
|
|
||||||
'turns' => '[17,18,19,20]',
|
|
||||||
'userids' => '[]',
|
|
||||||
'usertype' => 'add',
|
|
||||||
'userlimit' => 0,
|
|
||||||
'sort' => 2,
|
|
||||||
'created_at' => '2022-01-15 23:43:40',
|
|
||||||
'updated_at' => '2022-01-15 23:43:40',
|
|
||||||
),
|
|
||||||
19 =>
|
|
||||||
array (
|
|
||||||
'id' => 20,
|
|
||||||
'project_id' => 6,
|
|
||||||
'flow_id' => 5,
|
|
||||||
'name' => '已取消',
|
|
||||||
'status' => 'end',
|
|
||||||
'turns' => '[17,18,19,20]',
|
|
||||||
'userids' => '[]',
|
|
||||||
'usertype' => 'add',
|
|
||||||
'userlimit' => 0,
|
|
||||||
'sort' => 3,
|
|
||||||
'created_at' => '2022-01-15 23:43:40',
|
|
||||||
'updated_at' => '2022-01-15 23:43:40',
|
|
||||||
),
|
|
||||||
20 =>
|
|
||||||
array (
|
|
||||||
'id' => 21,
|
|
||||||
'project_id' => 7,
|
|
||||||
'flow_id' => 6,
|
|
||||||
'name' => '待处理',
|
|
||||||
'status' => 'start',
|
|
||||||
'turns' => '[21,22,23,24]',
|
|
||||||
'userids' => '[]',
|
|
||||||
'usertype' => 'add',
|
|
||||||
'userlimit' => 0,
|
|
||||||
'sort' => 0,
|
|
||||||
'created_at' => '2022-01-15 23:43:45',
|
|
||||||
'updated_at' => '2022-01-15 23:43:45',
|
|
||||||
),
|
|
||||||
21 =>
|
|
||||||
array (
|
|
||||||
'id' => 22,
|
|
||||||
'project_id' => 7,
|
|
||||||
'flow_id' => 6,
|
|
||||||
'name' => '进行中',
|
|
||||||
'status' => 'progress',
|
|
||||||
'turns' => '[21,22,23,24]',
|
|
||||||
'userids' => '[]',
|
|
||||||
'usertype' => 'add',
|
|
||||||
'userlimit' => 0,
|
|
||||||
'sort' => 1,
|
|
||||||
'created_at' => '2022-01-15 23:43:45',
|
|
||||||
'updated_at' => '2022-01-15 23:43:45',
|
|
||||||
),
|
|
||||||
22 =>
|
|
||||||
array (
|
|
||||||
'id' => 23,
|
|
||||||
'project_id' => 7,
|
|
||||||
'flow_id' => 6,
|
|
||||||
'name' => '已完成',
|
|
||||||
'status' => 'end',
|
|
||||||
'turns' => '[21,22,23,24]',
|
|
||||||
'userids' => '[]',
|
|
||||||
'usertype' => 'add',
|
|
||||||
'userlimit' => 0,
|
|
||||||
'sort' => 2,
|
|
||||||
'created_at' => '2022-01-15 23:43:45',
|
|
||||||
'updated_at' => '2022-01-15 23:43:45',
|
|
||||||
),
|
|
||||||
23 =>
|
|
||||||
array (
|
|
||||||
'id' => 24,
|
|
||||||
'project_id' => 7,
|
|
||||||
'flow_id' => 6,
|
|
||||||
'name' => '已取消',
|
|
||||||
'status' => 'end',
|
|
||||||
'turns' => '[21,22,23,24]',
|
|
||||||
'userids' => '[]',
|
|
||||||
'usertype' => 'add',
|
|
||||||
'userlimit' => 0,
|
|
||||||
'sort' => 3,
|
|
||||||
'created_at' => '2022-01-15 23:43:45',
|
|
||||||
'updated_at' => '2022-01-15 23:43:45',
|
|
||||||
),
|
|
||||||
));
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,76 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Database\Seeders;
|
|
||||||
|
|
||||||
use Illuminate\Database\Seeder;
|
|
||||||
|
|
||||||
class ProjectFlowsTableSeeder extends Seeder
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Auto generated seed file
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function run()
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
if (\DB::table('project_flows')->count() > 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
\DB::table('project_flows')->insert(array (
|
|
||||||
0 =>
|
|
||||||
array (
|
|
||||||
'id' => 1,
|
|
||||||
'project_id' => 2,
|
|
||||||
'name' => 'Default',
|
|
||||||
'created_at' => '2022-01-15 23:43:15',
|
|
||||||
'updated_at' => '2022-01-15 23:43:15',
|
|
||||||
),
|
|
||||||
1 =>
|
|
||||||
array (
|
|
||||||
'id' => 2,
|
|
||||||
'project_id' => 3,
|
|
||||||
'name' => 'Default',
|
|
||||||
'created_at' => '2022-01-15 23:43:23',
|
|
||||||
'updated_at' => '2022-01-15 23:43:23',
|
|
||||||
),
|
|
||||||
2 =>
|
|
||||||
array (
|
|
||||||
'id' => 3,
|
|
||||||
'project_id' => 4,
|
|
||||||
'name' => 'Default',
|
|
||||||
'created_at' => '2022-01-15 23:43:28',
|
|
||||||
'updated_at' => '2022-01-15 23:43:28',
|
|
||||||
),
|
|
||||||
3 =>
|
|
||||||
array (
|
|
||||||
'id' => 4,
|
|
||||||
'project_id' => 5,
|
|
||||||
'name' => 'Default',
|
|
||||||
'created_at' => '2022-01-15 23:43:34',
|
|
||||||
'updated_at' => '2022-01-15 23:43:34',
|
|
||||||
),
|
|
||||||
4 =>
|
|
||||||
array (
|
|
||||||
'id' => 5,
|
|
||||||
'project_id' => 6,
|
|
||||||
'name' => 'Default',
|
|
||||||
'created_at' => '2022-01-15 23:43:40',
|
|
||||||
'updated_at' => '2022-01-15 23:43:40',
|
|
||||||
),
|
|
||||||
5 =>
|
|
||||||
array (
|
|
||||||
'id' => 6,
|
|
||||||
'project_id' => 7,
|
|
||||||
'name' => 'Default',
|
|
||||||
'created_at' => '2022-01-15 23:43:45',
|
|
||||||
'updated_at' => '2022-01-15 23:43:45',
|
|
||||||
),
|
|
||||||
));
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -296,7 +296,7 @@ class ProjectLogsTableSeeder extends Seeder
|
|||||||
'column_id' => 6,
|
'column_id' => 6,
|
||||||
'task_id' => 8,
|
'task_id' => 8,
|
||||||
'userid' => 1,
|
'userid' => 1,
|
||||||
'detail' => '标记任务已完成:官网项目一期',
|
'detail' => '任务标记已完成:官网项目一期',
|
||||||
'created_at' => seeders_at('2021-07-01 10:53:47'),
|
'created_at' => seeders_at('2021-07-01 10:53:47'),
|
||||||
'updated_at' => seeders_at('2021-07-01 10:53:47'),
|
'updated_at' => seeders_at('2021-07-01 10:53:47'),
|
||||||
),
|
),
|
||||||
@ -2998,7 +2998,7 @@ class ProjectLogsTableSeeder extends Seeder
|
|||||||
'column_id' => 27,
|
'column_id' => 27,
|
||||||
'task_id' => 77,
|
'task_id' => 77,
|
||||||
'userid' => 1,
|
'userid' => 1,
|
||||||
'detail' => '标记任务已完成:🚴 里程碑 1 需求评审完成,资源准备到位',
|
'detail' => '任务标记已完成:🚴 里程碑 1 需求评审完成,资源准备到位',
|
||||||
'created_at' => seeders_at('2021-07-01 15:39:46'),
|
'created_at' => seeders_at('2021-07-01 15:39:46'),
|
||||||
'updated_at' => seeders_at('2021-07-01 15:39:46'),
|
'updated_at' => seeders_at('2021-07-01 15:39:46'),
|
||||||
),
|
),
|
||||||
@ -3229,7 +3229,7 @@ class ProjectLogsTableSeeder extends Seeder
|
|||||||
'column_id' => 32,
|
'column_id' => 32,
|
||||||
'task_id' => 85,
|
'task_id' => 85,
|
||||||
'userid' => 1,
|
'userid' => 1,
|
||||||
'detail' => '子标记任务已完成:首页',
|
'detail' => '子任务标记已完成:首页',
|
||||||
'created_at' => seeders_at('2021-07-01 16:17:30'),
|
'created_at' => seeders_at('2021-07-01 16:17:30'),
|
||||||
'updated_at' => seeders_at('2021-07-01 16:17:30'),
|
'updated_at' => seeders_at('2021-07-01 16:17:30'),
|
||||||
),
|
),
|
||||||
@ -3240,7 +3240,7 @@ class ProjectLogsTableSeeder extends Seeder
|
|||||||
'column_id' => 32,
|
'column_id' => 32,
|
||||||
'task_id' => 85,
|
'task_id' => 85,
|
||||||
'userid' => 1,
|
'userid' => 1,
|
||||||
'detail' => '子标记任务已完成:公司介绍',
|
'detail' => '子任务标记已完成:公司介绍',
|
||||||
'created_at' => seeders_at('2021-07-01 16:17:31'),
|
'created_at' => seeders_at('2021-07-01 16:17:31'),
|
||||||
'updated_at' => seeders_at('2021-07-01 16:17:31'),
|
'updated_at' => seeders_at('2021-07-01 16:17:31'),
|
||||||
),
|
),
|
||||||
@ -3251,7 +3251,7 @@ class ProjectLogsTableSeeder extends Seeder
|
|||||||
'column_id' => 32,
|
'column_id' => 32,
|
||||||
'task_id' => 85,
|
'task_id' => 85,
|
||||||
'userid' => 1,
|
'userid' => 1,
|
||||||
'detail' => '子标记任务已完成:新闻动态',
|
'detail' => '子任务标记已完成:新闻动态',
|
||||||
'created_at' => seeders_at('2021-07-01 16:17:32'),
|
'created_at' => seeders_at('2021-07-01 16:17:32'),
|
||||||
'updated_at' => seeders_at('2021-07-01 16:17:32'),
|
'updated_at' => seeders_at('2021-07-01 16:17:32'),
|
||||||
),
|
),
|
||||||
@ -3262,7 +3262,7 @@ class ProjectLogsTableSeeder extends Seeder
|
|||||||
'column_id' => 32,
|
'column_id' => 32,
|
||||||
'task_id' => 85,
|
'task_id' => 85,
|
||||||
'userid' => 1,
|
'userid' => 1,
|
||||||
'detail' => '子标记任务已完成:产品介绍',
|
'detail' => '子任务标记已完成:产品介绍',
|
||||||
'created_at' => seeders_at('2021-07-01 16:17:34'),
|
'created_at' => seeders_at('2021-07-01 16:17:34'),
|
||||||
'updated_at' => seeders_at('2021-07-01 16:17:34'),
|
'updated_at' => seeders_at('2021-07-01 16:17:34'),
|
||||||
),
|
),
|
||||||
@ -3273,7 +3273,7 @@ class ProjectLogsTableSeeder extends Seeder
|
|||||||
'column_id' => 32,
|
'column_id' => 32,
|
||||||
'task_id' => 85,
|
'task_id' => 85,
|
||||||
'userid' => 1,
|
'userid' => 1,
|
||||||
'detail' => '子标记任务已完成:案例展示',
|
'detail' => '子任务标记已完成:案例展示',
|
||||||
'created_at' => seeders_at('2021-07-01 16:17:35'),
|
'created_at' => seeders_at('2021-07-01 16:17:35'),
|
||||||
'updated_at' => seeders_at('2021-07-01 16:17:35'),
|
'updated_at' => seeders_at('2021-07-01 16:17:35'),
|
||||||
),
|
),
|
||||||
@ -3284,7 +3284,7 @@ class ProjectLogsTableSeeder extends Seeder
|
|||||||
'column_id' => 32,
|
'column_id' => 32,
|
||||||
'task_id' => 85,
|
'task_id' => 85,
|
||||||
'userid' => 1,
|
'userid' => 1,
|
||||||
'detail' => '子标记任务已完成:联系我们',
|
'detail' => '子任务标记已完成:联系我们',
|
||||||
'created_at' => seeders_at('2021-07-01 16:17:36'),
|
'created_at' => seeders_at('2021-07-01 16:17:36'),
|
||||||
'updated_at' => seeders_at('2021-07-01 16:17:36'),
|
'updated_at' => seeders_at('2021-07-01 16:17:36'),
|
||||||
),
|
),
|
||||||
@ -3295,7 +3295,7 @@ class ProjectLogsTableSeeder extends Seeder
|
|||||||
'column_id' => 32,
|
'column_id' => 32,
|
||||||
'task_id' => 85,
|
'task_id' => 85,
|
||||||
'userid' => 1,
|
'userid' => 1,
|
||||||
'detail' => '标记任务已完成:产品官网设计',
|
'detail' => '任务标记已完成:产品官网设计',
|
||||||
'created_at' => seeders_at('2021-07-01 16:17:37'),
|
'created_at' => seeders_at('2021-07-01 16:17:37'),
|
||||||
'updated_at' => seeders_at('2021-07-01 16:17:37'),
|
'updated_at' => seeders_at('2021-07-01 16:17:37'),
|
||||||
),
|
),
|
||||||
@ -3306,7 +3306,7 @@ class ProjectLogsTableSeeder extends Seeder
|
|||||||
'column_id' => 32,
|
'column_id' => 32,
|
||||||
'task_id' => 85,
|
'task_id' => 85,
|
||||||
'userid' => 1,
|
'userid' => 1,
|
||||||
'detail' => '标记子任务未完成:联系我们',
|
'detail' => '子任务标记未完成:联系我们',
|
||||||
'created_at' => seeders_at('2021-07-01 16:17:41'),
|
'created_at' => seeders_at('2021-07-01 16:17:41'),
|
||||||
'updated_at' => seeders_at('2021-07-01 16:17:41'),
|
'updated_at' => seeders_at('2021-07-01 16:17:41'),
|
||||||
),
|
),
|
||||||
@ -3317,7 +3317,7 @@ class ProjectLogsTableSeeder extends Seeder
|
|||||||
'column_id' => 32,
|
'column_id' => 32,
|
||||||
'task_id' => 85,
|
'task_id' => 85,
|
||||||
'userid' => 1,
|
'userid' => 1,
|
||||||
'detail' => '标记任务未完成:产品官网设计',
|
'detail' => '任务标记未完成:产品官网设计',
|
||||||
'created_at' => seeders_at('2021-07-01 16:17:44'),
|
'created_at' => seeders_at('2021-07-01 16:17:44'),
|
||||||
'updated_at' => seeders_at('2021-07-01 16:17:44'),
|
'updated_at' => seeders_at('2021-07-01 16:17:44'),
|
||||||
),
|
),
|
||||||
|
@ -28,8 +28,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 2,
|
'project_id' => 2,
|
||||||
'column_id' => 2,
|
'column_id' => 2,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 1,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '说明:将进度分成多级
|
'name' => '说明:将进度分成多级
|
||||||
每张卡片为一个项目任务,标签表示任务状况
|
每张卡片为一个项目任务,标签表示任务状况
|
||||||
通过将卡片拖至不同的进度列表下,来表示各项目进度',
|
通过将卡片拖至不同的进度列表下,来表示各项目进度',
|
||||||
@ -56,8 +54,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 2,
|
'project_id' => 2,
|
||||||
'column_id' => 2,
|
'column_id' => 2,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 1,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '官网项目',
|
'name' => '官网项目',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -82,9 +78,7 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 2,
|
'project_id' => 2,
|
||||||
'column_id' => 2,
|
'column_id' => 2,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 1,
|
'name' => '1',
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '新增职位需求',
|
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
'start_at' => NULL,
|
'start_at' => NULL,
|
||||||
@ -108,9 +102,7 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 2,
|
'project_id' => 2,
|
||||||
'column_id' => 2,
|
'column_id' => 2,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 1,
|
'name' => '11',
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '更新公司简介',
|
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
'start_at' => NULL,
|
'start_at' => NULL,
|
||||||
@ -134,8 +126,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 2,
|
'project_id' => 2,
|
||||||
'column_id' => 3,
|
'column_id' => 3,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 1,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '官网项目四期',
|
'name' => '官网项目四期',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -160,8 +150,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 2,
|
'project_id' => 2,
|
||||||
'column_id' => 4,
|
'column_id' => 4,
|
||||||
'dialog_id' => 16,
|
'dialog_id' => 16,
|
||||||
'flow_item_id' => 1,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '官网项目三期',
|
'name' => '官网项目三期',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -186,8 +174,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 2,
|
'project_id' => 2,
|
||||||
'column_id' => 5,
|
'column_id' => 5,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 1,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '官网项目二期',
|
'name' => '官网项目二期',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -212,8 +198,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 2,
|
'project_id' => 2,
|
||||||
'column_id' => 6,
|
'column_id' => 6,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 3,
|
|
||||||
'flow_item_name' => 'end|已完成',
|
|
||||||
'name' => '官网项目一期',
|
'name' => '官网项目一期',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -238,8 +222,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 7,
|
'column_id' => 7,
|
||||||
'dialog_id' => 18,
|
'dialog_id' => 18,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '免费高品质的Sketch资源',
|
'name' => '免费高品质的Sketch资源',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => 'https://sketchrepo.com/',
|
'desc' => 'https://sketchrepo.com/',
|
||||||
@ -264,8 +246,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 7,
|
'column_id' => 7,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '免费高品质的PSD资源',
|
'name' => '免费高品质的PSD资源',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => 'https://psdrepo.com/',
|
'desc' => 'https://psdrepo.com/',
|
||||||
@ -290,8 +270,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 7,
|
'column_id' => 7,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '免费高清灵感图片网(偏文艺)',
|
'name' => '免费高清灵感图片网(偏文艺)',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => 'https://magdeleine.co/',
|
'desc' => 'https://magdeleine.co/',
|
||||||
@ -316,8 +294,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 7,
|
'column_id' => 7,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '每天发现充满灵感且美丽的图片',
|
'name' => '每天发现充满灵感且美丽的图片',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => 'https://weheartit.com/',
|
'desc' => 'https://weheartit.com/',
|
||||||
@ -342,8 +318,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 8,
|
'column_id' => 8,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '花瓣网:设计师寻找灵感的天堂',
|
'name' => '花瓣网:设计师寻找灵感的天堂',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => 'https://huaban.com/',
|
'desc' => 'https://huaban.com/',
|
||||||
@ -368,8 +342,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 8,
|
'column_id' => 8,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'WallHaven:高清壁纸图片搜索引擎',
|
'name' => 'WallHaven:高清壁纸图片搜索引擎',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => 'https://wallhaven.typepad.com/',
|
'desc' => 'https://wallhaven.typepad.com/',
|
||||||
@ -394,8 +366,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 8,
|
'column_id' => 8,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'Pexels:免费高品质图片 可商用',
|
'name' => 'Pexels:免费高品质图片 可商用',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => 'https://www.pexels.com/',
|
'desc' => 'https://www.pexels.com/',
|
||||||
@ -420,8 +390,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 9,
|
'column_id' => 9,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'Retinize:iOS切图神器',
|
'name' => 'Retinize:iOS切图神器',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => 'http://retinize.it/',
|
'desc' => 'http://retinize.it/',
|
||||||
@ -446,8 +414,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 9,
|
'column_id' => 9,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'GuideGuide:一款PS参考线插件',
|
'name' => 'GuideGuide:一款PS参考线插件',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => 'https://guideguide.me/photoshop/',
|
'desc' => 'https://guideguide.me/photoshop/',
|
||||||
@ -472,8 +438,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 9,
|
'column_id' => 9,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'Assistor PS:一个功能强大的PS辅助工具',
|
'name' => 'Assistor PS:一个功能强大的PS辅助工具',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => 'http://wit-web.azurewebsites.net/assistor/download',
|
'desc' => 'http://wit-web.azurewebsites.net/assistor/download',
|
||||||
@ -498,8 +462,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 10,
|
'column_id' => 10,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'Fontello:图标字体生成器',
|
'name' => 'Fontello:图标字体生成器',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => 'http://fontello.com/',
|
'desc' => 'http://fontello.com/',
|
||||||
@ -524,8 +486,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 10,
|
'column_id' => 10,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'inconfont: 免费提供高度可辨识符号图标',
|
'name' => 'inconfont: 免费提供高度可辨识符号图标',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => 'https://www.iconfont.cn/',
|
'desc' => 'https://www.iconfont.cn/',
|
||||||
@ -550,8 +510,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 10,
|
'column_id' => 10,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'The Noun Project:免费提供高度可辨识符号图标',
|
'name' => 'The Noun Project:免费提供高度可辨识符号图标',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => 'https://thenounproject.com/',
|
'desc' => 'https://thenounproject.com/',
|
||||||
@ -576,8 +534,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 10,
|
'column_id' => 10,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'EasyIcon:免费图标搜索和下载平台',
|
'name' => 'EasyIcon:免费图标搜索和下载平台',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => 'https://www.easyicon.net/',
|
'desc' => 'https://www.easyicon.net/',
|
||||||
@ -602,8 +558,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 10,
|
'column_id' => 10,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'Icon Deposit:一个奇妙的图标下载站',
|
'name' => 'Icon Deposit:一个奇妙的图标下载站',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => 'https://www.icondeposit.com/',
|
'desc' => 'https://www.icondeposit.com/',
|
||||||
@ -628,8 +582,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 10,
|
'column_id' => 10,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'iConify:Mac平台的苹果应用图标自动化生成工具',
|
'name' => 'iConify:Mac平台的苹果应用图标自动化生成工具',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => 'https://iconify.net/',
|
'desc' => 'https://iconify.net/',
|
||||||
@ -654,8 +606,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 11,
|
'column_id' => 11,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'Logaster:教你在线几分钟内搞定专业的LOGO',
|
'name' => 'Logaster:教你在线几分钟内搞定专业的LOGO',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '设计https://www.logaster.cn/',
|
'desc' => '设计https://www.logaster.cn/',
|
||||||
@ -680,8 +630,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 11,
|
'column_id' => 11,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'LogoLounge:国际知名的LOGO设计权威网站',
|
'name' => 'LogoLounge:国际知名的LOGO设计权威网站',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => 'https://www.logolounge.com/',
|
'desc' => 'https://www.logolounge.com/',
|
||||||
@ -706,8 +654,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 11,
|
'column_id' => 11,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'LogoMoose:一个优秀的logo素材站点',
|
'name' => 'LogoMoose:一个优秀的logo素材站点',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => 'https://www.logomoose.com/',
|
'desc' => 'https://www.logomoose.com/',
|
||||||
@ -732,8 +678,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 11,
|
'column_id' => 11,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'LOGOED:一个展示Logo设计的博客',
|
'name' => 'LOGOED:一个展示Logo设计的博客',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => 'http://www.logoed.co.uk/page/2/',
|
'desc' => 'http://www.logoed.co.uk/page/2/',
|
||||||
@ -758,8 +702,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 11,
|
'column_id' => 11,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'Logo of the Day:汇集世界各地优秀LOGO作品的站点',
|
'name' => 'Logo of the Day:汇集世界各地优秀LOGO作品的站点',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => 'https://logooftheday.com/',
|
'desc' => 'https://logooftheday.com/',
|
||||||
@ -784,8 +726,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 2,
|
'project_id' => 2,
|
||||||
'column_id' => 5,
|
'column_id' => 5,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 1,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'asdasdad1111',
|
'name' => 'asdasdad1111',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '7777777',
|
'desc' => '7777777',
|
||||||
@ -810,8 +750,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 2,
|
'project_id' => 2,
|
||||||
'column_id' => 5,
|
'column_id' => 5,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 1,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'hjhjhjjh',
|
'name' => 'hjhjhjjh',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -836,8 +774,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 11,
|
'column_id' => 11,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'Logo of the Day:汇集世界各地优秀LOGO作品的站点',
|
'name' => 'Logo of the Day:汇集世界各地优秀LOGO作品的站点',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -862,8 +798,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 11,
|
'column_id' => 11,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'LogoDesignLove:Logo设计技巧分享网',
|
'name' => 'LogoDesignLove:Logo设计技巧分享网',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => 'LogoDesignLove:Logo设计技巧分享网',
|
'desc' => 'LogoDesignLove:Logo设计技巧分享网',
|
||||||
@ -888,8 +822,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 11,
|
'column_id' => 11,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'LogoDesignLove:Logo设计技巧分享网',
|
'name' => 'LogoDesignLove:Logo设计技巧分享网',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -914,8 +846,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 12,
|
'column_id' => 12,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'Coolors:自动生成配色色板的小工具',
|
'name' => 'Coolors:自动生成配色色板的小工具',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => 'https://coolors.co/',
|
'desc' => 'https://coolors.co/',
|
||||||
@ -940,8 +870,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 12,
|
'column_id' => 12,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'Material Palette:Material Design专用在线配色工具',
|
'name' => 'Material Palette:Material Design专用在线配色工具',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => 'https://www.materialpalette.com/',
|
'desc' => 'https://www.materialpalette.com/',
|
||||||
@ -966,8 +894,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 12,
|
'column_id' => 12,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'Web安全色:WEB设计、开发中常用的安全颜色',
|
'name' => 'Web安全色:WEB设计、开发中常用的安全颜色',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => 'https://www.bootcss.com/p/websafecolors/',
|
'desc' => 'https://www.bootcss.com/p/websafecolors/',
|
||||||
@ -992,8 +918,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 12,
|
'column_id' => 12,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'ColorZilla:火狐浏览器网页取色器插件',
|
'name' => 'ColorZilla:火狐浏览器网页取色器插件',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => 'https://www.colorzilla.com/',
|
'desc' => 'https://www.colorzilla.com/',
|
||||||
@ -1018,8 +942,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 12,
|
'column_id' => 12,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'Color Palette Generator:图片配色工具',
|
'name' => 'Color Palette Generator:图片配色工具',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1044,8 +966,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 12,
|
'column_id' => 12,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'inconfont: 免费提供高度可辨识符号图标',
|
'name' => 'inconfont: 免费提供高度可辨识符号图标',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => 'https://www.iconfont.cn/',
|
'desc' => 'https://www.iconfont.cn/',
|
||||||
@ -1070,8 +990,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 12,
|
'column_id' => 12,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'inconfont: 免费提供高度可辨识符号图标https://www.iconfont.cn/',
|
'name' => 'inconfont: 免费提供高度可辨识符号图标https://www.iconfont.cn/',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => 'https://www.iconfont.cn/',
|
'desc' => 'https://www.iconfont.cn/',
|
||||||
@ -1096,8 +1014,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 3,
|
'project_id' => 3,
|
||||||
'column_id' => 12,
|
'column_id' => 12,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 5,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => 'https://www.iconfont.cn/',
|
'name' => 'https://www.iconfont.cn/',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1122,8 +1038,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 4,
|
'project_id' => 4,
|
||||||
'column_id' => 13,
|
'column_id' => 13,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 9,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '将收集箱的事务进行判断。要立即执行:进入Q2列表。非立即执行:判断——1.不做(删掉)、2.稍晚再做(进入「稍后做」)、3.可做可不做的任务或可能有用的资源(进入「Mark」列表)',
|
'name' => '将收集箱的事务进行判断。要立即执行:进入Q2列表。非立即执行:判断——1.不做(删掉)、2.稍晚再做(进入「稍后做」)、3.可做可不做的任务或可能有用的资源(进入「Mark」列表)',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1148,8 +1062,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 4,
|
'project_id' => 4,
|
||||||
'column_id' => 13,
|
'column_id' => 13,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 9,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '2分钟内能做完贴上2分钟标签(进入「2分钟速战」列表)。2分钟以上做完的事务进入Q3',
|
'name' => '2分钟内能做完贴上2分钟标签(进入「2分钟速战」列表)。2分钟以上做完的事务进入Q3',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1174,8 +1086,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 4,
|
'project_id' => 4,
|
||||||
'column_id' => 13,
|
'column_id' => 13,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 9,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '判断能否一步做完,能进入Q4,不能打上多步标签(进入「项目清单」);或将多步骤任务分解成多个一步做完任务,进入Q4。',
|
'name' => '判断能否一步做完,能进入Q4,不能打上多步标签(进入「项目清单」);或将多步骤任务分解成多个一步做完任务,进入Q4。',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1200,8 +1110,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 4,
|
'project_id' => 4,
|
||||||
'column_id' => 13,
|
'column_id' => 13,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 9,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '如果自己做,打上自己做标签(进入「执行清单」);如果别人做,打上别人做标签(进入「等待清单」)。',
|
'name' => '如果自己做,打上自己做标签(进入「执行清单」);如果别人做,打上别人做标签(进入「等待清单」)。',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1226,8 +1134,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 2,
|
'project_id' => 2,
|
||||||
'column_id' => 2,
|
'column_id' => 2,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 1,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '❓❗ 说明:将进度分成多级
|
'name' => '❓❗ 说明:将进度分成多级
|
||||||
|
|
||||||
每张卡片为一个项目任务,标签表示任务状况
|
每张卡片为一个项目任务,标签表示任务状况
|
||||||
@ -1256,8 +1162,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 4,
|
'project_id' => 4,
|
||||||
'column_id' => 13,
|
'column_id' => 13,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 9,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '每天晚上复查整套流程',
|
'name' => '每天晚上复查整套流程',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1282,8 +1186,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 4,
|
'project_id' => 4,
|
||||||
'column_id' => 13,
|
'column_id' => 13,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 9,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '1.检查「收集箱」是否清空。',
|
'name' => '1.检查「收集箱」是否清空。',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1308,8 +1210,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 4,
|
'project_id' => 4,
|
||||||
'column_id' => 13,
|
'column_id' => 13,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 9,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '2.检查「Mark」是否有条目需要执行,转化成行动或项目。',
|
'name' => '2.检查「Mark」是否有条目需要执行,转化成行动或项目。',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1334,8 +1234,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 4,
|
'project_id' => 4,
|
||||||
'column_id' => 13,
|
'column_id' => 13,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 9,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '3.检查「项目清单」了解项目进度。',
|
'name' => '3.检查「项目清单」了解项目进度。',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1360,8 +1258,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 4,
|
'project_id' => 4,
|
||||||
'column_id' => 13,
|
'column_id' => 13,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 9,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '4.检查「等待清单」是否有条目需要转化成行动,也就是催促。',
|
'name' => '4.检查「等待清单」是否有条目需要转化成行动,也就是催促。',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1386,8 +1282,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 4,
|
'project_id' => 4,
|
||||||
'column_id' => 13,
|
'column_id' => 13,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 9,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '5.检查各清单是否有已完成,完成的、已作废的卡片,立刻删除。',
|
'name' => '5.检查各清单是否有已完成,完成的、已作废的卡片,立刻删除。',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1412,8 +1306,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 4,
|
'project_id' => 4,
|
||||||
'column_id' => 14,
|
'column_id' => 14,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 9,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '任何事务或信息,先以最简单的方式记录到“收集箱”。然后判断,贴上标签后,拖动到相应列表里',
|
'name' => '任何事务或信息,先以最简单的方式记录到“收集箱”。然后判断,贴上标签后,拖动到相应列表里',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1438,8 +1330,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 4,
|
'project_id' => 4,
|
||||||
'column_id' => 15,
|
'column_id' => 15,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 9,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '优先级1:立即去做的事',
|
'name' => '优先级1:立即去做的事',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1464,8 +1354,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 4,
|
'project_id' => 4,
|
||||||
'column_id' => 14,
|
'column_id' => 14,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 9,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '任何事务或信息,先以最简单的方式记录到“收集箱”。然后判断,贴上标签后,拖动到相应列表里',
|
'name' => '任何事务或信息,先以最简单的方式记录到“收集箱”。然后判断,贴上标签后,拖动到相应列表里',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1490,8 +1378,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 4,
|
'project_id' => 4,
|
||||||
'column_id' => 16,
|
'column_id' => 16,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 9,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '优先级2:主要的执行清单',
|
'name' => '优先级2:主要的执行清单',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1516,8 +1402,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 4,
|
'project_id' => 4,
|
||||||
'column_id' => 17,
|
'column_id' => 17,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 9,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '优先级3:存放需要多步骤做的事,持续追踪',
|
'name' => '优先级3:存放需要多步骤做的事,持续追踪',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1542,8 +1426,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 4,
|
'project_id' => 4,
|
||||||
'column_id' => 17,
|
'column_id' => 17,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 9,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '可以为这个多步骤项目单独建一个项目,并把项目的链接放到卡片的详情页里,点击就能跳转进去。',
|
'name' => '可以为这个多步骤项目单独建一个项目,并把项目的链接放到卡片的详情页里,点击就能跳转进去。',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1568,8 +1450,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 4,
|
'project_id' => 4,
|
||||||
'column_id' => 17,
|
'column_id' => 17,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 9,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '活动策划',
|
'name' => '活动策划',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1594,8 +1474,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 4,
|
'project_id' => 4,
|
||||||
'column_id' => 16,
|
'column_id' => 16,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 9,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '填问卷',
|
'name' => '填问卷',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1620,8 +1498,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 4,
|
'project_id' => 4,
|
||||||
'column_id' => 18,
|
'column_id' => 18,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 9,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '存放等待协同的事',
|
'name' => '存放等待协同的事',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1646,8 +1522,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 4,
|
'project_id' => 4,
|
||||||
'column_id' => 18,
|
'column_id' => 18,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 9,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '设计稿反馈',
|
'name' => '设计稿反馈',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1672,8 +1546,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 4,
|
'project_id' => 4,
|
||||||
'column_id' => 18,
|
'column_id' => 18,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 9,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '存放等待协同的事',
|
'name' => '存放等待协同的事',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1698,8 +1570,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 4,
|
'project_id' => 4,
|
||||||
'column_id' => 19,
|
'column_id' => 19,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 9,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '存放稍后做的任务',
|
'name' => '存放稍后做的任务',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1724,8 +1594,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 4,
|
'project_id' => 4,
|
||||||
'column_id' => 19,
|
'column_id' => 19,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 9,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '阅实习生简历',
|
'name' => '阅实习生简历',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1750,8 +1618,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 4,
|
'project_id' => 4,
|
||||||
'column_id' => 20,
|
'column_id' => 20,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 9,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '存放可做可不做的任务,以及各种可能用到的资源',
|
'name' => '存放可做可不做的任务,以及各种可能用到的资源',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1776,8 +1642,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 4,
|
'project_id' => 4,
|
||||||
'column_id' => 20,
|
'column_id' => 20,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 9,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '团建KTV',
|
'name' => '团建KTV',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1802,8 +1666,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 5,
|
'project_id' => 5,
|
||||||
'column_id' => 21,
|
'column_id' => 21,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 13,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '产品新需求',
|
'name' => '产品新需求',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1828,8 +1690,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 5,
|
'project_id' => 5,
|
||||||
'column_id' => 22,
|
'column_id' => 22,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 13,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '需要调研的需求',
|
'name' => '需要调研的需求',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1854,8 +1714,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 5,
|
'project_id' => 5,
|
||||||
'column_id' => 23,
|
'column_id' => 23,
|
||||||
'dialog_id' => 17,
|
'dialog_id' => 17,
|
||||||
'flow_item_id' => 13,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '进入交互设计的需求',
|
'name' => '进入交互设计的需求',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1880,8 +1738,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 5,
|
'project_id' => 5,
|
||||||
'column_id' => 25,
|
'column_id' => 25,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 13,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '设计稿(放入设计稿)',
|
'name' => '设计稿(放入设计稿)',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1906,8 +1762,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 5,
|
'project_id' => 5,
|
||||||
'column_id' => 25,
|
'column_id' => 25,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 13,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '提测(放入提测时间规划表)',
|
'name' => '提测(放入提测时间规划表)',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1932,8 +1786,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 5,
|
'project_id' => 5,
|
||||||
'column_id' => 25,
|
'column_id' => 25,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 13,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '发布流程(放入发布流程,应用文案等)',
|
'name' => '发布流程(放入发布流程,应用文案等)',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1958,8 +1810,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 5,
|
'project_id' => 5,
|
||||||
'column_id' => 25,
|
'column_id' => 25,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 13,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '-----上线需求-----(将左边列表中的需求拖动至下方,表示本版本上线需求)',
|
'name' => '-----上线需求-----(将左边列表中的需求拖动至下方,表示本版本上线需求)',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -1984,8 +1834,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 6,
|
'project_id' => 6,
|
||||||
'column_id' => 26,
|
'column_id' => 26,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 17,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '将小组一年工作目标拆解,设置出里程碑时间节点。并指派相关责任人。用标签来展示进行状况',
|
'name' => '将小组一年工作目标拆解,设置出里程碑时间节点。并指派相关责任人。用标签来展示进行状况',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -2010,8 +1858,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 6,
|
'project_id' => 6,
|
||||||
'column_id' => 27,
|
'column_id' => 27,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 19,
|
|
||||||
'flow_item_name' => 'end|已完成',
|
|
||||||
'name' => '🚴 里程碑 1 需求评审完成,资源准备到位',
|
'name' => '🚴 里程碑 1 需求评审完成,资源准备到位',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -2036,8 +1882,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 6,
|
'project_id' => 6,
|
||||||
'column_id' => 27,
|
'column_id' => 27,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 17,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '🚴 里程碑 2 设计完成,进行评审',
|
'name' => '🚴 里程碑 2 设计完成,进行评审',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -2062,8 +1906,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 6,
|
'project_id' => 6,
|
||||||
'column_id' => 28,
|
'column_id' => 28,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 17,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '🚴 里程碑 3 产品开发完成,开始提测',
|
'name' => '🚴 里程碑 3 产品开发完成,开始提测',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -2088,8 +1930,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 6,
|
'project_id' => 6,
|
||||||
'column_id' => 28,
|
'column_id' => 28,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 17,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '🚴 里程碑 4 测试完成准备线上发布',
|
'name' => '🚴 里程碑 4 测试完成准备线上发布',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -2114,13 +1954,11 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 6,
|
'project_id' => 6,
|
||||||
'column_id' => 28,
|
'column_id' => 28,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 17,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '测试1',
|
'name' => '测试1',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
'start_at' => seeders_at('2021-07-01 16:33:00'),
|
'start_at' => NULL,
|
||||||
'end_at' => seeders_at('2021-07-02 23:59:00'),
|
'end_at' => NULL,
|
||||||
'archived_at' => NULL,
|
'archived_at' => NULL,
|
||||||
'archived_userid' => 0,
|
'archived_userid' => 0,
|
||||||
'complete_at' => NULL,
|
'complete_at' => NULL,
|
||||||
@ -2140,13 +1978,11 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 6,
|
'project_id' => 6,
|
||||||
'column_id' => 28,
|
'column_id' => 28,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 17,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '测试2',
|
'name' => '测试2',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
'start_at' => seeders_at('2021-07-01 16:33:00'),
|
'start_at' => NULL,
|
||||||
'end_at' => seeders_at('2021-07-02 23:59:00'),
|
'end_at' => NULL,
|
||||||
'archived_at' => NULL,
|
'archived_at' => NULL,
|
||||||
'archived_userid' => 0,
|
'archived_userid' => 0,
|
||||||
'complete_at' => NULL,
|
'complete_at' => NULL,
|
||||||
@ -2166,13 +2002,11 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 6,
|
'project_id' => 6,
|
||||||
'column_id' => 28,
|
'column_id' => 28,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 17,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '测试3',
|
'name' => '测试3',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
'start_at' => seeders_at('2021-07-01 16:33:00'),
|
'start_at' => NULL,
|
||||||
'end_at' => seeders_at('2021-07-02 23:59:00'),
|
'end_at' => NULL,
|
||||||
'archived_at' => NULL,
|
'archived_at' => NULL,
|
||||||
'archived_userid' => 0,
|
'archived_userid' => 0,
|
||||||
'complete_at' => NULL,
|
'complete_at' => NULL,
|
||||||
@ -2192,8 +2026,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 6,
|
'project_id' => 6,
|
||||||
'column_id' => 29,
|
'column_id' => 29,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 17,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '🚴 里程碑 5 市场发布',
|
'name' => '🚴 里程碑 5 市场发布',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -2218,8 +2050,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 7,
|
'project_id' => 7,
|
||||||
'column_id' => 32,
|
'column_id' => 32,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 21,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '产品官网设计',
|
'name' => '产品官网设计',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -2244,13 +2074,11 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 7,
|
'project_id' => 7,
|
||||||
'column_id' => 32,
|
'column_id' => 32,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 23,
|
|
||||||
'flow_item_name' => 'end|已完成',
|
|
||||||
'name' => '首页',
|
'name' => '首页',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
'start_at' => seeders_at('2021-07-01 16:15:55'),
|
'start_at' => NULL,
|
||||||
'end_at' => seeders_at('2021-07-02 16:15:55'),
|
'end_at' => NULL,
|
||||||
'archived_at' => NULL,
|
'archived_at' => NULL,
|
||||||
'archived_userid' => 0,
|
'archived_userid' => 0,
|
||||||
'complete_at' => seeders_at('2021-07-01 16:17:30'),
|
'complete_at' => seeders_at('2021-07-01 16:17:30'),
|
||||||
@ -2270,13 +2098,11 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 7,
|
'project_id' => 7,
|
||||||
'column_id' => 32,
|
'column_id' => 32,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 23,
|
|
||||||
'flow_item_name' => 'end|已完成',
|
|
||||||
'name' => '公司介绍',
|
'name' => '公司介绍',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
'start_at' => seeders_at('2021-07-01 16:15:55'),
|
'start_at' => NULL,
|
||||||
'end_at' => seeders_at('2021-07-02 16:15:55'),
|
'end_at' => NULL,
|
||||||
'archived_at' => NULL,
|
'archived_at' => NULL,
|
||||||
'archived_userid' => 0,
|
'archived_userid' => 0,
|
||||||
'complete_at' => seeders_at('2021-07-01 16:17:31'),
|
'complete_at' => seeders_at('2021-07-01 16:17:31'),
|
||||||
@ -2296,13 +2122,11 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 7,
|
'project_id' => 7,
|
||||||
'column_id' => 32,
|
'column_id' => 32,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 23,
|
|
||||||
'flow_item_name' => 'end|已完成',
|
|
||||||
'name' => '新闻动态',
|
'name' => '新闻动态',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
'start_at' => seeders_at('2021-07-01 16:15:55'),
|
'start_at' => NULL,
|
||||||
'end_at' => seeders_at('2021-07-02 16:15:55'),
|
'end_at' => NULL,
|
||||||
'archived_at' => NULL,
|
'archived_at' => NULL,
|
||||||
'archived_userid' => 0,
|
'archived_userid' => 0,
|
||||||
'complete_at' => seeders_at('2021-07-01 16:17:32'),
|
'complete_at' => seeders_at('2021-07-01 16:17:32'),
|
||||||
@ -2322,13 +2146,11 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 7,
|
'project_id' => 7,
|
||||||
'column_id' => 32,
|
'column_id' => 32,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 23,
|
|
||||||
'flow_item_name' => 'end|已完成',
|
|
||||||
'name' => '产品介绍',
|
'name' => '产品介绍',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
'start_at' => seeders_at('2021-07-01 16:15:55'),
|
'start_at' => NULL,
|
||||||
'end_at' => seeders_at('2021-07-02 16:15:55'),
|
'end_at' => NULL,
|
||||||
'archived_at' => NULL,
|
'archived_at' => NULL,
|
||||||
'archived_userid' => 0,
|
'archived_userid' => 0,
|
||||||
'complete_at' => seeders_at('2021-07-01 16:17:34'),
|
'complete_at' => seeders_at('2021-07-01 16:17:34'),
|
||||||
@ -2348,13 +2170,11 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 7,
|
'project_id' => 7,
|
||||||
'column_id' => 32,
|
'column_id' => 32,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 23,
|
|
||||||
'flow_item_name' => 'end|已完成',
|
|
||||||
'name' => '案例展示',
|
'name' => '案例展示',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
'start_at' => seeders_at('2021-07-01 16:15:55'),
|
'start_at' => NULL,
|
||||||
'end_at' => seeders_at('2021-07-02 16:15:55'),
|
'end_at' => NULL,
|
||||||
'archived_at' => NULL,
|
'archived_at' => NULL,
|
||||||
'archived_userid' => 0,
|
'archived_userid' => 0,
|
||||||
'complete_at' => seeders_at('2021-07-01 16:17:35'),
|
'complete_at' => seeders_at('2021-07-01 16:17:35'),
|
||||||
@ -2374,13 +2194,11 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 7,
|
'project_id' => 7,
|
||||||
'column_id' => 32,
|
'column_id' => 32,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 21,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '联系我们',
|
'name' => '联系我们',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
'start_at' => seeders_at('2021-07-01 16:15:55'),
|
'start_at' => NULL,
|
||||||
'end_at' => seeders_at('2021-07-02 16:15:55'),
|
'end_at' => NULL,
|
||||||
'archived_at' => NULL,
|
'archived_at' => NULL,
|
||||||
'archived_userid' => 0,
|
'archived_userid' => 0,
|
||||||
'complete_at' => NULL,
|
'complete_at' => NULL,
|
||||||
@ -2400,8 +2218,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 7,
|
'project_id' => 7,
|
||||||
'column_id' => 32,
|
'column_id' => 32,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 21,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '官网新增一级栏目,“招聘信息”',
|
'name' => '官网新增一级栏目,“招聘信息”',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -2426,8 +2242,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 7,
|
'project_id' => 7,
|
||||||
'column_id' => 33,
|
'column_id' => 33,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 21,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '产品官网',
|
'name' => '产品官网',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
@ -2452,8 +2266,6 @@ class ProjectTasksTableSeeder extends Seeder
|
|||||||
'project_id' => 5,
|
'project_id' => 5,
|
||||||
'column_id' => 24,
|
'column_id' => 24,
|
||||||
'dialog_id' => 0,
|
'dialog_id' => 0,
|
||||||
'flow_item_id' => 13,
|
|
||||||
'flow_item_name' => 'start|待处理',
|
|
||||||
'name' => '版本的确定',
|
'name' => '版本的确定',
|
||||||
'color' => '',
|
'color' => '',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
|
@ -16,24 +16,26 @@ class SettingsTableSeeder extends Seeder
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
if (\DB::table('settings')->where('name', 'system')->count() > 0) {
|
if (\DB::table('settings')->count() > 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
\DB::table('settings')->insert(array (
|
\DB::table('settings')->insert(array (
|
||||||
0 =>
|
0 =>
|
||||||
array (
|
array (
|
||||||
|
'id' => 1,
|
||||||
'name' => 'system',
|
'name' => 'system',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
'setting' => '{"reg":"open","project_invite":"open","login_code":"auto"}',
|
'setting' => '{"reg":"open","login_code":"auto"}',
|
||||||
'created_at' => seeders_at('2021-07-01 11:05:06'),
|
'created_at' => seeders_at('2021-07-01 11:05:06'),
|
||||||
'updated_at' => seeders_at('2021-07-01 12:27:12'),
|
'updated_at' => seeders_at('2021-07-01 12:27:12'),
|
||||||
),
|
),
|
||||||
1 =>
|
1 =>
|
||||||
array (
|
array (
|
||||||
|
'id' => 2,
|
||||||
'name' => 'priority',
|
'name' => 'priority',
|
||||||
'desc' => '',
|
'desc' => '',
|
||||||
'setting' => '[{"name":"\\u91cd\\u8981\\u4e14\\u7d27\\u6025","color":"#ED4014","days":1,"priority":1},{"name":"\\u91cd\\u8981\\u4e0d\\u7d27\\u6025","color":"#F16B62","days":3,"priority":2},{"name":"\\u7d27\\u6025\\u4e0d\\u91cd\\u8981","color":"#19C919","days":5,"priority":3},{"name":"\\u4e0d\\u91cd\\u8981\\u4e0d\\u7d27\\u6025","color":"#2D8CF0","days":0,"priority":4}]',
|
'setting' => '[{"name":"\\u91cd\\u8981\\u4e14\\u7d27\\u6025","color":"#ED4014","days":1,"priority":1},{"name":"\\u91cd\\u8981\\u4e0d\\u7d27\\u6025","color":"#F16B62","days":3,"priority":2},{"name":"\\u7d27\\u6025\\u4e0d\\u91cd\\u8981","color":"#19C919","days":5,"priority":3},{"name":"\\u4e0d\\u91cd\\u8981\\u4e0d\\u7d27\\u6025","color":"#2D8CF0","days":7,"priority":4}]',
|
||||||
'created_at' => seeders_at('2021-07-01 08:04:30'),
|
'created_at' => seeders_at('2021-07-01 08:04:30'),
|
||||||
'updated_at' => seeders_at('2021-07-01 09:20:26'),
|
'updated_at' => seeders_at('2021-07-01 09:20:26'),
|
||||||
),
|
),
|
||||||
|
@ -40,7 +40,6 @@ class UsersTableSeeder extends Seeder
|
|||||||
'line_at' => seeders_at('2021-07-01 17:43:48'),
|
'line_at' => seeders_at('2021-07-01 17:43:48'),
|
||||||
'task_dialog_id' => 18,
|
'task_dialog_id' => 18,
|
||||||
'created_ip' => '',
|
'created_ip' => '',
|
||||||
'disable_at' => null,
|
|
||||||
'created_at' => seeders_at('2021-07-01 11:01:14'),
|
'created_at' => seeders_at('2021-07-01 11:01:14'),
|
||||||
'updated_at' => seeders_at('2021-07-01 17:43:48'),
|
'updated_at' => seeders_at('2021-07-01 17:43:48'),
|
||||||
),
|
),
|
||||||
@ -63,7 +62,6 @@ class UsersTableSeeder extends Seeder
|
|||||||
'line_at' => seeders_at('2021-07-01 16:57:40'),
|
'line_at' => seeders_at('2021-07-01 16:57:40'),
|
||||||
'task_dialog_id' => 16,
|
'task_dialog_id' => 16,
|
||||||
'created_ip' => '',
|
'created_ip' => '',
|
||||||
'disable_at' => null,
|
|
||||||
'created_at' => seeders_at('2021-07-01 11:01:14'),
|
'created_at' => seeders_at('2021-07-01 11:01:14'),
|
||||||
'updated_at' => seeders_at('2021-07-01 16:58:00'),
|
'updated_at' => seeders_at('2021-07-01 16:58:00'),
|
||||||
),
|
),
|
||||||
|
File diff suppressed because one or more lines are too long
@ -4,8 +4,8 @@ services:
|
|||||||
php:
|
php:
|
||||||
container_name: "dootask-php-${APP_ID}"
|
container_name: "dootask-php-${APP_ID}"
|
||||||
image: "kuaifan/php:swoole-8.0"
|
image: "kuaifan/php:swoole-8.0"
|
||||||
shm_size: "1024m"
|
|
||||||
volumes:
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
- ./docker/crontab/crontab.conf:/etc/supervisor/conf.d/crontab.conf
|
- ./docker/crontab/crontab.conf:/etc/supervisor/conf.d/crontab.conf
|
||||||
- ./docker/php/php.conf:/etc/supervisor/conf.d/php.conf
|
- ./docker/php/php.conf:/etc/supervisor/conf.d/php.conf
|
||||||
- ./docker/php/php.ini:/usr/local/etc/php/php.ini
|
- ./docker/php/php.ini:/usr/local/etc/php/php.ini
|
||||||
@ -45,8 +45,6 @@ services:
|
|||||||
- php
|
- php
|
||||||
- office
|
- office
|
||||||
- fileview
|
- fileview
|
||||||
- drawio-webapp
|
|
||||||
- drawio-export
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
@ -82,16 +80,13 @@ services:
|
|||||||
|
|
||||||
office:
|
office:
|
||||||
container_name: "dootask-office-${APP_ID}"
|
container_name: "dootask-office-${APP_ID}"
|
||||||
image: "onlyoffice/documentserver:7.0.0.132"
|
image: "onlyoffice/documentserver:6.4.2.6"
|
||||||
volumes:
|
volumes:
|
||||||
- ./docker/office/data:/var/www/onlyoffice/Data
|
- ./docker/office/data:/var/www/onlyoffice/Data
|
||||||
- ./docker/office/logs:/var/log/onlyoffice
|
- ./docker/office/logs:/var/log/onlyoffice
|
||||||
- ./docker/office/resources/documenteditor/css/app.css:/var/www/onlyoffice/documentserver/web-apps/apps/documenteditor/main/resources/css/app.css
|
- ./docker/office/resources/documenteditor/css/app.css:/var/www/onlyoffice/documentserver/web-apps/apps/documenteditor/main/resources/css/app.css
|
||||||
- ./docker/office/resources/presentationeditor/css/app.css:/var/www/onlyoffice/documentserver/web-apps/apps/presentationeditor/main/resources/css/app.css
|
- ./docker/office/resources/presentationeditor/css/app.css:/var/www/onlyoffice/documentserver/web-apps/apps/presentationeditor/main/resources/css/app.css
|
||||||
- ./docker/office/resources/spreadsheeteditor/css/app.css:/var/www/onlyoffice/documentserver/web-apps/apps/spreadsheeteditor/main/resources/css/app.css
|
- ./docker/office/resources/spreadsheeteditor/css/app.css:/var/www/onlyoffice/documentserver/web-apps/apps/spreadsheeteditor/main/resources/css/app.css
|
||||||
- ./docker/office/resources/documenteditor/mobile/css/app.css:/var/www/onlyoffice/documentserver/web-apps/apps/documenteditor/mobile/css/app.css
|
|
||||||
- ./docker/office/resources/presentationeditor/mobile/css/app.css:/var/www/onlyoffice/documentserver/web-apps/apps/presentationeditor/mobile/css/app.css
|
|
||||||
- ./docker/office/resources/spreadsheeteditor/mobile/css/app.css:/var/www/onlyoffice/documentserver/web-apps/apps/spreadsheeteditor/mobile/css/app.css
|
|
||||||
environment:
|
environment:
|
||||||
TZ: "Asia/Shanghai"
|
TZ: "Asia/Shanghai"
|
||||||
networks:
|
networks:
|
||||||
@ -101,7 +96,7 @@ services:
|
|||||||
|
|
||||||
fileview:
|
fileview:
|
||||||
container_name: "dootask-fileview-${APP_ID}"
|
container_name: "dootask-fileview-${APP_ID}"
|
||||||
image: "kuaifan/fileview:4.1.0-SNAPSHOT-RC3"
|
image: "kuaifan/fileview:4.1.0-SNAPSHOT"
|
||||||
environment:
|
environment:
|
||||||
TZ: "Asia/Shanghai"
|
TZ: "Asia/Shanghai"
|
||||||
KK_CONTEXT_PATH: "/fileview"
|
KK_CONTEXT_PATH: "/fileview"
|
||||||
@ -110,36 +105,6 @@ services:
|
|||||||
ipv4_address: "${APP_IPPR}.7"
|
ipv4_address: "${APP_IPPR}.7"
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
drawio-webapp:
|
|
||||||
container_name: "dootask-drawio-webapp-${APP_ID}"
|
|
||||||
image: "jgraph/drawio:16.6.1"
|
|
||||||
volumes:
|
|
||||||
- ./docker/drawio/webapp/index.html:/usr/local/tomcat/webapps/draw/index.html
|
|
||||||
- ./docker/drawio/webapp/stencils:/usr/local/tomcat/webapps/draw/stencils
|
|
||||||
- ./docker/drawio/webapp/js/app.min.js:/usr/local/tomcat/webapps/draw/js/app.min.js
|
|
||||||
- ./docker/drawio/webapp/js/croppie/croppie.min.css:/usr/local/tomcat/webapps/draw/js/croppie/croppie.min.css
|
|
||||||
- ./docker/drawio/webapp/js/diagramly/ElectronApp.js:/usr/local/tomcat/webapps/draw/js/diagramly/ElectronApp.js
|
|
||||||
networks:
|
|
||||||
extnetwork:
|
|
||||||
ipv4_address: "${APP_IPPR}.8"
|
|
||||||
environment:
|
|
||||||
TZ: "Asia/Shanghai"
|
|
||||||
depends_on:
|
|
||||||
- drawio-export
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
drawio-export:
|
|
||||||
container_name: "dootask-drawio-export-${APP_ID}"
|
|
||||||
image: "jgraph/export-server"
|
|
||||||
networks:
|
|
||||||
extnetwork:
|
|
||||||
ipv4_address: "${APP_IPPR}.9"
|
|
||||||
environment:
|
|
||||||
TZ: "Asia/Shanghai"
|
|
||||||
volumes:
|
|
||||||
- ./docker/drawio/export/fonts:/usr/share/fonts/drawio
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
extnetwork:
|
extnetwork:
|
||||||
name: "dootask-networks-${APP_ID}"
|
name: "dootask-networks-${APP_ID}"
|
||||||
|
1
docker/crontab/.gitignore
vendored
1
docker/crontab/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
*.log
|
|
@ -1,5 +1,3 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
echo "$(date "+%Y-%m-%d %H:%M:%S")" > /var/www/docker/crontab/last.log
|
curl "http://127.0.0.1:20000/crontab" >> /dev/null 2>&1
|
||||||
curl "http://127.0.0.1:20000/crontab" >> /var/www/docker/crontab/last.log
|
|
||||||
echo "\n$(date "+%Y-%m-%d %H:%M:%S")" >> /var/www/docker/crontab/last.log
|
|
||||||
|
1
docker/drawio/export/fonts/.gitignore
vendored
1
docker/drawio/export/fonts/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
|
|
@ -1,17 +0,0 @@
|
|||||||
# Change
|
|
||||||
|
|
||||||
## js/diagramly/ElectronApp.js
|
|
||||||
|
|
||||||
- 隐藏文件中的无用菜单
|
|
||||||
|
|
||||||
## js/app.min.js
|
|
||||||
|
|
||||||
- 隐藏帮助菜单
|
|
||||||
- 取消未保存关闭窗口提示
|
|
||||||
- `EmbedFile.prototype.getTitle=...` 改 `EmbedFile.prototype.getTitle=function(){return this.desc.title||(urlParams.title?decodeURIComponent(urlParams.title):"")}`
|
|
||||||
- `c.insertTemplateEnabled&&!c.isOffline()&&this.addMenuItems(b,["insertTemplate"],d)` 改 `c.insertTemplateEnabled&&this.addMenuItems(b,["insertTemplate"],d)`
|
|
||||||
- `390:270` 改 `390:285`
|
|
||||||
|
|
||||||
## index.html
|
|
||||||
|
|
||||||
- 隐藏加载中的提示
|
|
@ -1,477 +0,0 @@
|
|||||||
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=5" ><![endif]-->
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Flowchart Maker & Online Diagram Software</title>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
||||||
<meta name="Description" content="diagrams.net is free online diagram software for making flowcharts, process diagrams, org charts, UML, ER and network diagrams">
|
|
||||||
<meta name="Keywords" content="diagram, online, flow chart, flowchart maker, uml, erd">
|
|
||||||
<meta itemprop="name" content="diagrams.net - free flowchart maker and diagrams online">
|
|
||||||
<meta itemprop="description" content="diagrams.net is a free online diagramming application and flowchart maker . You can use it to create UML, entity relationship,
|
|
||||||
org charts, BPMN and BPM, database schema and networks. Also possible are telecommunication network, workflow, flowcharts, maps overlays and GIS, electronic
|
|
||||||
circuit and social network diagrams.">
|
|
||||||
<meta itemprop="image" content="https://lh4.googleusercontent.com/-cLKEldMbT_E/Tx8qXDuw6eI/AAAAAAAAAAs/Ke0pnlk8Gpg/w500-h344-k/BPMN%2Bdiagram%2Brc2f.png">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
|
||||||
<meta name="msapplication-config" content="images/browserconfig.xml">
|
|
||||||
<meta name="mobile-web-app-capable" content="yes">
|
|
||||||
<meta name="theme-color" content="#d89000">
|
|
||||||
<script type="text/javascript">
|
|
||||||
window.EXPORT_URL = window.location.origin + "/drawio/export/";
|
|
||||||
window.DRAWIO_LIGHTBOX_URL = window.location.origin + "/drawio/webapp";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* URL Parameters and protocol description are here:
|
|
||||||
*
|
|
||||||
* https://desk.draw.io/support/solutions/articles/16000042546-what-url-parameters-are-supported
|
|
||||||
*
|
|
||||||
* Parameters for developers:
|
|
||||||
*
|
|
||||||
* - dev=1: For developers only
|
|
||||||
* - test=1: For developers only
|
|
||||||
* - export=URL for export: For developers only
|
|
||||||
* - ignoremime=1: For developers only (see DriveClient.js). Use Cmd-S to override mime.
|
|
||||||
* - createindex=1: For developers only (see etc/build/README)
|
|
||||||
* - filesupport=0: For developers only (see Editor.js in core)
|
|
||||||
* - savesidebar=1: For developers only (see Sidebar.js)
|
|
||||||
* - pages=1: For developers only (see Pages.js)
|
|
||||||
* - lic=email: For developers only (see LicenseServlet.java)
|
|
||||||
* --
|
|
||||||
* - networkshapes=1: For testing network shapes (temporary)
|
|
||||||
*/
|
|
||||||
var urlParams = (function()
|
|
||||||
{
|
|
||||||
var result = new Object();
|
|
||||||
var params = window.location.search.slice(1).split('&');
|
|
||||||
|
|
||||||
for (var i = 0; i < params.length; i++)
|
|
||||||
{
|
|
||||||
idx = params[i].indexOf('=');
|
|
||||||
|
|
||||||
if (idx > 0)
|
|
||||||
{
|
|
||||||
result[params[i].substring(0, idx)] = params[i].substring(idx + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
})();
|
|
||||||
|
|
||||||
// Forces CDN caches by passing URL parameters via URL hash
|
|
||||||
if (window.location.hash != null && window.location.hash.substring(0, 2) == '#P')
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
urlParams = JSON.parse(decodeURIComponent(window.location.hash.substring(2)));
|
|
||||||
|
|
||||||
if (urlParams.hash != null)
|
|
||||||
{
|
|
||||||
window.location.hash = urlParams.hash;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (e)
|
|
||||||
{
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Global variable for desktop
|
|
||||||
var mxIsElectron = window && window.process && window.process.type;
|
|
||||||
|
|
||||||
// Redirects page if required
|
|
||||||
if (urlParams['dev'] != '1')
|
|
||||||
{
|
|
||||||
(function()
|
|
||||||
{
|
|
||||||
var proto = window.location.protocol;
|
|
||||||
|
|
||||||
if (!mxIsElectron)
|
|
||||||
{
|
|
||||||
var host = window.location.host;
|
|
||||||
|
|
||||||
// Redirects apex, drive and rt to www
|
|
||||||
if (host === 'draw.io' || host === 'rt.draw.io' || host === 'drive.draw.io')
|
|
||||||
{
|
|
||||||
host = 'www.draw.io';
|
|
||||||
}
|
|
||||||
|
|
||||||
var href = proto + '//' + host + window.location.href.substring(
|
|
||||||
window.location.protocol.length +
|
|
||||||
window.location.host.length + 2);
|
|
||||||
|
|
||||||
// Redirects if href changes
|
|
||||||
if (href != window.location.href)
|
|
||||||
{
|
|
||||||
window.location.href = href;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds meta tag to the page.
|
|
||||||
*/
|
|
||||||
function mxmeta(name, content, httpEquiv)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var s = document.createElement('meta');
|
|
||||||
|
|
||||||
if (name != null)
|
|
||||||
{
|
|
||||||
s.setAttribute('name', name);
|
|
||||||
}
|
|
||||||
|
|
||||||
s.setAttribute('content', content);
|
|
||||||
|
|
||||||
if (httpEquiv != null)
|
|
||||||
{
|
|
||||||
s.setAttribute('http-equiv', httpEquiv);
|
|
||||||
}
|
|
||||||
|
|
||||||
var t = document.getElementsByTagName('meta')[0];
|
|
||||||
t.parentNode.insertBefore(s, t);
|
|
||||||
}
|
|
||||||
catch (e)
|
|
||||||
{
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Synchronously adds scripts to the page.
|
|
||||||
*/
|
|
||||||
function mxscript(src, onLoad, id, dataAppKey, noWrite)
|
|
||||||
{
|
|
||||||
var defer = onLoad == null && !noWrite;
|
|
||||||
|
|
||||||
if ((urlParams['dev'] != '1' && typeof document.createElement('canvas').getContext === "function") ||
|
|
||||||
onLoad != null || noWrite)
|
|
||||||
{
|
|
||||||
var s = document.createElement('script');
|
|
||||||
s.setAttribute('type', 'text/javascript');
|
|
||||||
s.setAttribute('defer', 'true');
|
|
||||||
s.setAttribute('src', src);
|
|
||||||
|
|
||||||
if (id != null)
|
|
||||||
{
|
|
||||||
s.setAttribute('id', id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dataAppKey != null)
|
|
||||||
{
|
|
||||||
s.setAttribute('data-app-key', dataAppKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (onLoad != null)
|
|
||||||
{
|
|
||||||
var r = false;
|
|
||||||
|
|
||||||
s.onload = s.onreadystatechange = function()
|
|
||||||
{
|
|
||||||
if (!r && (!this.readyState || this.readyState == 'complete'))
|
|
||||||
{
|
|
||||||
r = true;
|
|
||||||
onLoad();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var t = document.getElementsByTagName('script')[0];
|
|
||||||
|
|
||||||
if (t != null)
|
|
||||||
{
|
|
||||||
t.parentNode.insertBefore(s, t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
document.write('<script src="' + src + '"' + ((id != null) ? ' id="' + id +'" ' : '') +
|
|
||||||
((dataAppKey != null) ? ' data-app-key="' + dataAppKey +'" ' : '') + '></scr' + 'ipt>');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Asynchronously adds scripts to the page.
|
|
||||||
*/
|
|
||||||
function mxinclude(src)
|
|
||||||
{
|
|
||||||
var g = document.createElement('script');
|
|
||||||
g.type = 'text/javascript';
|
|
||||||
g.async = true;
|
|
||||||
g.src = src;
|
|
||||||
|
|
||||||
var s = document.getElementsByTagName('script')[0];
|
|
||||||
s.parentNode.insertBefore(g, s);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds meta tags with application name (depends on offline URL parameter)
|
|
||||||
*/
|
|
||||||
(function()
|
|
||||||
{
|
|
||||||
var name = 'diagrams.net';
|
|
||||||
mxmeta('apple-mobile-web-app-title', name);
|
|
||||||
mxmeta('application-name', name);
|
|
||||||
|
|
||||||
if (mxIsElectron)
|
|
||||||
{
|
|
||||||
mxmeta(null, 'default-src \'self\' \'unsafe-inline\'; connect-src \'self\' https://*.draw.io https://fonts.googleapis.com https://fonts.gstatic.com; img-src * data:; media-src *; font-src *; style-src-elem \'self\' \'unsafe-inline\' https://fonts.googleapis.com', 'Content-Security-Policy');
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
// Checks for local storage
|
|
||||||
var isLocalStorage = false;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
isLocalStorage = urlParams['local'] != '1' && typeof(localStorage) != 'undefined';
|
|
||||||
}
|
|
||||||
catch (e)
|
|
||||||
{
|
|
||||||
// ignored
|
|
||||||
}
|
|
||||||
|
|
||||||
var mxScriptsLoaded = false, mxWinLoaded = false;
|
|
||||||
|
|
||||||
function checkAllLoaded()
|
|
||||||
{
|
|
||||||
if (mxScriptsLoaded && mxWinLoaded)
|
|
||||||
{
|
|
||||||
App.main();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var t0 = new Date();
|
|
||||||
|
|
||||||
// Changes paths for local development environment
|
|
||||||
if (urlParams['dev'] == '1')
|
|
||||||
{
|
|
||||||
// Used to request grapheditor/mxgraph sources in dev mode
|
|
||||||
var mxDevUrl = document.location.protocol + '//devhost.jgraph.com/drawio/src/main';
|
|
||||||
|
|
||||||
// Used to request draw.io sources in dev mode
|
|
||||||
var drawDevUrl = document.location.protocol + '//devhost.jgraph.com/drawio/src/main/webapp/';
|
|
||||||
var geBasePath = drawDevUrl + '/js/grapheditor';
|
|
||||||
var mxBasePath = mxDevUrl + '/mxgraph';
|
|
||||||
|
|
||||||
if (document.location.protocol == 'file:')
|
|
||||||
{
|
|
||||||
geBasePath = './js/grapheditor';
|
|
||||||
mxBasePath = './mxgraph';
|
|
||||||
drawDevUrl = './';
|
|
||||||
|
|
||||||
// Forces includes for dev environment in node.js
|
|
||||||
mxForceIncludes = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
mxscript(drawDevUrl + 'js/PreConfig.js');
|
|
||||||
mxscript(drawDevUrl + 'js/diagramly/Init.js');
|
|
||||||
mxscript(geBasePath + '/Init.js');
|
|
||||||
mxscript(mxBasePath + '/mxClient.js');
|
|
||||||
|
|
||||||
// Adds all JS code that depends on mxClient. This indirection via Devel.js is
|
|
||||||
// required in some browsers to make sure mxClient.js (and the files that it
|
|
||||||
// loads asynchronously) are available when the code loaded in Devel.js runs.
|
|
||||||
mxscript(drawDevUrl + 'js/diagramly/Devel.js');
|
|
||||||
|
|
||||||
// Electron
|
|
||||||
if (mxIsElectron)
|
|
||||||
{
|
|
||||||
mxscript('js/diagramly/DesktopLibrary.js');
|
|
||||||
mxscript('js/diagramly/ElectronApp.js');
|
|
||||||
}
|
|
||||||
|
|
||||||
mxscript(drawDevUrl + 'js/PostConfig.js');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
(function()
|
|
||||||
{
|
|
||||||
var hostName = window.location.hostname;
|
|
||||||
|
|
||||||
// Supported domains are *.draw.io and the packaged version in Quip
|
|
||||||
var supportedDomain = (hostName.substring(hostName.length - 8, hostName.length) === '.draw.io') ||
|
|
||||||
(hostName.substring(hostName.length - 13, hostName.length) === '.diagrams.net');
|
|
||||||
|
|
||||||
function loadAppJS()
|
|
||||||
{
|
|
||||||
mxscript('js/app.min.js', function()
|
|
||||||
{
|
|
||||||
mxScriptsLoaded = true;
|
|
||||||
checkAllLoaded();
|
|
||||||
|
|
||||||
// Electron
|
|
||||||
if (mxIsElectron)
|
|
||||||
{
|
|
||||||
mxscript('js/diagramly/DesktopLibrary.js', function()
|
|
||||||
{
|
|
||||||
mxscript('js/diagramly/ElectronApp.js', function()
|
|
||||||
{
|
|
||||||
mxscript('js/extensions.min.js', function()
|
|
||||||
{
|
|
||||||
mxscript('js/stencils.min.js', function()
|
|
||||||
{
|
|
||||||
mxscript('js/shapes-14-6-5.min.js', function()
|
|
||||||
{
|
|
||||||
mxscript('js/PostConfig.js');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else if (!supportedDomain)
|
|
||||||
{
|
|
||||||
mxscript('js/PostConfig.js');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!supportedDomain || mxIsElectron)
|
|
||||||
{
|
|
||||||
mxscript('js/PreConfig.js', loadAppJS);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
loadAppJS();
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adds basic error handling
|
|
||||||
window.onerror = function()
|
|
||||||
{
|
|
||||||
var status = document.getElementById('geStatus');
|
|
||||||
|
|
||||||
if (status != null)
|
|
||||||
{
|
|
||||||
status.innerHTML = 'Page could not be loaded. Please try refreshing.';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
<link rel="chrome-webstore-item" href="https://chrome.google.com/webstore/detail/plgmlhohecdddhbmmkncjdmlhcmaachm">
|
|
||||||
<link rel="stylesheet" type="text/css" href="js/croppie/croppie.min.css">
|
|
||||||
<link rel="stylesheet" type="text/css" href="styles/grapheditor.css">
|
|
||||||
<link rel="preconnect" href="https://storage.googleapis.com">
|
|
||||||
<link rel="canonical" href="https://app.diagrams.net">
|
|
||||||
<link rel="manifest" href="images/manifest.json">
|
|
||||||
<style type="text/css">
|
|
||||||
body { overflow:hidden; }
|
|
||||||
div.picker { z-index: 10007; }
|
|
||||||
.geSidebarContainer .geTitle input {
|
|
||||||
font-size:8pt;
|
|
||||||
color:#606060;
|
|
||||||
}
|
|
||||||
.geBlock {
|
|
||||||
display: none;
|
|
||||||
z-index:-3;
|
|
||||||
margin:100px;
|
|
||||||
margin-top:40px;
|
|
||||||
margin-bottom:30px;
|
|
||||||
padding:20px;
|
|
||||||
text-align:center;
|
|
||||||
min-width:50%;
|
|
||||||
}
|
|
||||||
.geBlock h1, .geBlock h2 {
|
|
||||||
margin-top:0px;
|
|
||||||
padding-top:0px;
|
|
||||||
}
|
|
||||||
.geEditor *:not(.geScrollable)::-webkit-scrollbar {
|
|
||||||
width:14px;
|
|
||||||
height:14px;
|
|
||||||
}
|
|
||||||
.geEditor ::-webkit-scrollbar-track {
|
|
||||||
background-clip:padding-box;
|
|
||||||
border:solid transparent;
|
|
||||||
border-width:1px;
|
|
||||||
}
|
|
||||||
.geEditor ::-webkit-scrollbar-corner {
|
|
||||||
background-color:transparent;
|
|
||||||
}
|
|
||||||
.geEditor ::-webkit-scrollbar-thumb {
|
|
||||||
background-color:rgba(0,0,0,.1);
|
|
||||||
background-clip:padding-box;
|
|
||||||
border:solid transparent;
|
|
||||||
border-radius:10px;
|
|
||||||
}
|
|
||||||
.geEditor ::-webkit-scrollbar-thumb:hover {
|
|
||||||
background-color:rgba(0,0,0,.4);
|
|
||||||
}
|
|
||||||
.geTemplate {
|
|
||||||
border:1px solid transparent;
|
|
||||||
display:inline-block;
|
|
||||||
_display:inline;
|
|
||||||
vertical-align:top;
|
|
||||||
border-radius:3px;
|
|
||||||
overflow:hidden;
|
|
||||||
font-size:14pt;
|
|
||||||
cursor:pointer;
|
|
||||||
margin:5px;
|
|
||||||
}
|
|
||||||
.geDialog h2 {
|
|
||||||
line-height: 1.2;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<!-- Workaround for binary XHR in IE 9/10, see App.loadUrl -->
|
|
||||||
<!--[if (IE 9)|(IE 10)]><!-->
|
|
||||||
<script type="text/vbscript">
|
|
||||||
Function mxUtilsBinaryToArray(Binary)
|
|
||||||
Dim i
|
|
||||||
ReDim byteArray(LenB(Binary))
|
|
||||||
For i = 1 To LenB(Binary)
|
|
||||||
byteArray(i-1) = AscB(MidB(Binary, i, 1))
|
|
||||||
Next
|
|
||||||
mxUtilsBinaryToArray = byteArray
|
|
||||||
End Function
|
|
||||||
</script>
|
|
||||||
<!--<![endif]-->
|
|
||||||
</head>
|
|
||||||
<body class="geEditor">
|
|
||||||
<div id="geInfo">
|
|
||||||
<div class="geBlock">
|
|
||||||
<h1>Flowchart Maker and Online Diagram Software</h1>
|
|
||||||
<p>
|
|
||||||
diagrams.net (formerly draw.io) is free online diagram software. You can use it as a flowchart maker, network diagram software, to create UML online, as an ER diagram tool,
|
|
||||||
to design database schema, to build BPMN online, as a circuit diagram maker, and more. draw.io can import .vsdx, Gliffy™ and Lucidchart™ files .
|
|
||||||
</p>
|
|
||||||
<h2 id="geStatus">Loading...</h2>
|
|
||||||
<p>
|
|
||||||
Please ensure JavaScript is enabled.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<script type="text/javascript">
|
|
||||||
/**
|
|
||||||
* Main
|
|
||||||
*/
|
|
||||||
if (navigator.userAgent != null && navigator.userAgent.toLowerCase().
|
|
||||||
indexOf(' electron/') >= 0 && typeof process !== 'undefined' && process.versions.electron < 5)
|
|
||||||
{
|
|
||||||
// Redirects old Electron app to latest version
|
|
||||||
var div = document.getElementById('geInfo');
|
|
||||||
|
|
||||||
if (div != null)
|
|
||||||
{
|
|
||||||
div.innerHTML = '<center><h2>You are using an out of date version of this app.<br>Please download the latest version ' +
|
|
||||||
'<a href="https://github.com/jgraph/drawio-desktop/releases/latest" target="_blank">here</a>.</h2></center>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (urlParams['dev'] != '1' && typeof document.createElement('canvas').getContext === "function")
|
|
||||||
{
|
|
||||||
window.addEventListener('load', function()
|
|
||||||
{
|
|
||||||
mxWinLoaded = true;
|
|
||||||
checkAllLoaded();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
App.main();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
12282
docker/drawio/webapp/js/app.min.js
vendored
12282
docker/drawio/webapp/js/app.min.js
vendored
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
|||||||
.croppie-container{width:100%;height:100%}.croppie-container .cr-image{z-index:-1;position:absolute;top:0;left:0;transform-origin:0 0;max-height:none;max-width:none}.croppie-container .cr-boundary{position:relative;overflow:hidden;margin:0 auto;z-index:1;width:100%;height:100%}.croppie-container .cr-resizer,.croppie-container .cr-viewport{position:absolute;border:2px solid #fff;margin:auto;top:0;bottom:0;right:0;left:0;box-shadow:0 0 2000px 2000px rgba(0,0,0,.5);z-index:0}.croppie-container .cr-resizer{z-index:2;box-shadow:none;pointer-events:none}.croppie-container .cr-resizer-horisontal,.croppie-container .cr-resizer-vertical{position:absolute;pointer-events:all}.croppie-container .cr-resizer-horisontal::after,.croppie-container .cr-resizer-vertical::after{display:block;position:absolute;box-sizing:border-box;border:1px solid #000;background:#fff;width:10px;height:10px;content:''}.croppie-container .cr-resizer-vertical{bottom:-5px;cursor:row-resize;width:100%;height:10px}.croppie-container .cr-resizer-vertical::after{left:50%;margin-left:-5px}.croppie-container .cr-resizer-horisontal{right:-5px;cursor:col-resize;width:10px;height:100%}.croppie-container .cr-resizer-horisontal::after{top:50%;margin-top:-5px}.croppie-container .cr-original-image{display:none}.croppie-container .cr-vp-circle{border-radius:50%}.croppie-container .cr-overlay{z-index:1;position:absolute;cursor:move;touch-action:none}.croppie-container .cr-slider-wrap{width:75%;margin:15px auto;text-align:center}.croppie-result{position:relative;overflow:hidden}.croppie-result img{position:absolute}.croppie-container .cr-image,.croppie-container .cr-overlay,.croppie-container .cr-viewport{-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-ms-transform:translateZ(0);transform:translateZ(0)}.cr-slider{-webkit-appearance:none;width:300px;max-width:100%;padding-top:8px;padding-bottom:8px;background-color:transparent}.cr-slider::-webkit-slider-runnable-track{width:100%;height:3px;background:rgba(0,0,0,.5);border:0;border-radius:3px}.cr-slider::-webkit-slider-thumb{-webkit-appearance:none;border:none;height:16px;width:16px;border-radius:50%;background:#ddd;margin-top:-6px}.cr-slider:focus{outline:0}.cr-slider::-moz-range-track{width:100%;height:3px;background:rgba(0,0,0,.5);border:0;border-radius:3px}.cr-slider::-moz-range-thumb{border:none;height:16px;width:16px;border-radius:50%;background:#ddd;margin-top:-6px}.cr-slider:-moz-focusring{outline:1px solid #fff;outline-offset:-1px}.cr-slider::-ms-track{width:100%;height:5px;background:0 0;border-color:transparent;border-width:6px 0;color:transparent}.cr-slider::-ms-fill-lower{background:rgba(0,0,0,.5);border-radius:10px}.cr-slider::-ms-fill-upper{background:rgba(0,0,0,.5);border-radius:10px}.cr-slider::-ms-thumb{border:none;height:16px;width:16px;border-radius:50%;background:#ddd;margin-top:1px}.cr-slider:focus::-ms-fill-lower{background:rgba(0,0,0,.5)}.cr-slider:focus::-ms-fill-upper{background:rgba(0,0,0,.5)}.cr-rotate-controls{position:absolute;bottom:5px;left:5px;z-index:1}.cr-rotate-controls button{border:0;background:0 0}.cr-rotate-controls i:before{display:inline-block;font-style:normal;font-weight:900;font-size:22px}.cr-rotate-l i:before{content:'↺'}.cr-rotate-r i:before{content:'↻'}
|
|
2206
docker/drawio/webapp/js/diagramly/ElectronApp.js
vendored
2206
docker/drawio/webapp/js/diagramly/ElectronApp.js
vendored
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Before Width: | Height: | Size: 5.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 4.5 KiB |
Binary file not shown.
Before Width: | Height: | Size: 4.6 KiB |
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user