From c9e629d9123c822a839c4466229a2b38c399160f Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Thu, 4 May 2023 13:58:34 +0800 Subject: [PATCH 01/20] * Modify unit test for project getList function. --- .../model/{getinfolist.php => getlist.php} | 21 +++++++------------ test/data/project.yaml | 5 +++++ test/lib/init.php | 8 ++++--- 3 files changed, 18 insertions(+), 16 deletions(-) rename module/project/test/model/{getinfolist.php => getlist.php} (51%) diff --git a/module/project/test/model/getinfolist.php b/module/project/test/model/getlist.php similarity index 51% rename from module/project/test/model/getinfolist.php rename to module/project/test/model/getlist.php index 179a55ed9d..9460b619c1 100755 --- a/module/project/test/model/getinfolist.php +++ b/module/project/test/model/getlist.php @@ -2,32 +2,27 @@ gen(90); /** title=测试 projectModel::getInfoList; +timeout=0 cid=1 -pid=1 - -查询正在进行的项目数量 >> 44 -查询wait状态的Id为11的项目名称 >> 项目1 -查询暂停状态的项目数量 >> 11 -查询关闭状态的项目数量 >> 11 -查询所有状态的项目数量 >> 110 */ global $tester; $tester->loadModel('project'); -$doingProjects = $tester->project->getInfoList('doing'); -$waitProjects = $tester->project->getInfoList('wait'); -$suspendedProjects = $tester->project->getInfoList('suspended'); -$closedProjects = $tester->project->getInfoList('closed'); -$allProjects = $tester->project->getInfoList('all'); +$doingProjects = $tester->project->getList('doing'); +$waitProjects = $tester->project->getList('wait'); +$suspendedProjects = $tester->project->getList('suspended'); +$closedProjects = $tester->project->getList('closed'); +$allProjects = $tester->project->getList('all'); r(count($doingProjects)) && p() && e('44'); //查询正在进行的项目数量 r($waitProjects) && p('11:name') && e('项目1'); //查询wait状态的Id为11的项目名称 r(count($suspendedProjects)) && p() && e('11'); //查询暂停状态的项目数量 r(count($closedProjects)) && p() && e('11'); //查询关闭状态的项目数量 -r(count($allProjects)) && p() && e('110'); //查询所有状态的项目数量 +r(count($allProjects)) && p() && e('90'); //查询所有状态的项目数量 diff --git a/test/data/project.yaml b/test/data/project.yaml index 2c9bc17a08..18cfabde77 100644 --- a/test/data/project.yaml +++ b/test/data/project.yaml @@ -81,5 +81,10 @@ fields: range: 5-10000:5 - field: openedVersion range: "16.5" + - field: openedDate + range: "(-3M)-(+M):1D" + type: timestamp + format: "YY/MM/DD" + postfix: "\t" - field: deleted range: 0 diff --git a/test/lib/init.php b/test/lib/init.php index 07d3e3308f..387ef1f449 100644 --- a/test/lib/init.php +++ b/test/lib/init.php @@ -115,7 +115,7 @@ function p($keys = '', $delimiter = ',') { $values = getValues($_result, $part, $delimiter); if(!is_array($values)) continue; - + foreach($values as $value) echo $value . "\n"; } @@ -272,7 +272,7 @@ function genModuleAndMethod($rParams) { $param = trim($param, "'"); if($param[0] != '$') $param = trim(strchr($param, '$'), ')'); - + $objArrowCount = substr_count($param, '->'); $rParamsStructureList = explode('->', $param); @@ -474,7 +474,9 @@ function zdImport($table, $yaml, $count = 10) function su($account) { $userModel = new userModel(); - $user = $userModel->identify($account, '123Qwe!@#'); + $user = $userModel->getByID($account); if($user) return $userModel->login($user); + + $user = $userModel->identify($account, $user->password); return false; } From a3d31e42f34bb7d7ab69f546c1ad94101e13ab2f Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Thu, 4 May 2023 14:02:17 +0800 Subject: [PATCH 02/20] * Split project getInfoList function. --- module/block/control.php | 18 +++--- module/project/control.php | 3 +- module/project/model.php | 14 ++--- module/project/tao.php | 59 ++++++++++++++++++++ module/project/test/project.class.php | 32 ++++++++--- module/project/test/tao/fetchprojectlist.php | 59 ++++++++++++++++++++ test/data/team.yaml | 2 +- 7 files changed, 157 insertions(+), 30 deletions(-) create mode 100755 module/project/test/tao/fetchprojectlist.php diff --git a/module/block/control.php b/module/block/control.php index 6dca159028..a72bb72640 100755 --- a/module/block/control.php +++ b/module/block/control.php @@ -27,10 +27,10 @@ class block extends control /** * Create a block under a dashboard. - * - * @param string $dashboard + * + * @param string $dashboard * @param string $module - * @param string $code + * @param string $code * @access public * @return void */ @@ -61,11 +61,11 @@ class block extends control } /** - * Update a block. - * - * @param string $dashboard - * @param string $module - * @param string $code + * Update a block. + * + * @param string $dashboard + * @param string $module + * @param string $code * @access public * @return void */ @@ -1862,7 +1862,7 @@ class block extends control /* load pager. */ $this->app->loadClass('pager', $static = true); $pager = new pager(0, 3, 1); - $this->view->projects = $this->loadModel('project')->getInfoList('all', 'id_desc', $pager, 1); + $this->view->projects = $this->loadModel('project')->getList('all', 'id_desc', 1, $pager); } /** diff --git a/module/project/control.php b/module/project/control.php index 089e997f9e..5c9f6d7ce1 100755 --- a/module/project/control.php +++ b/module/project/control.php @@ -73,8 +73,7 @@ class project extends control if(isset($fields['hasProduct'])) $fields['hasProduct'] = $projectLang->type; - $involved = $this->cookie->involved ? $this->cookie->involved : 0; - $projects = $this->project->getInfoList($status, $orderBy, '', $involved); + $projects = $this->project->getList($status, $orderBy, null); $users = $this->loadModel('user')->getPairs('noletter'); $this->loadModel('product'); diff --git a/module/project/model.php b/module/project/model.php index ae5e956611..f1b36bcdf4 100755 --- a/module/project/model.php +++ b/module/project/model.php @@ -235,7 +235,8 @@ class projectModel extends model } /** - * Get project info. + * 根据状态和和我参与的查询项目列表。 + * Get project list by status and with my participation. * * @param string $status * @param string $orderBy @@ -244,19 +245,14 @@ class projectModel extends model * @access public * @return array */ - public function getInfoList($status = 'undone', $orderBy = 'order_desc', $pager = null, $involved = 0) + public function getList($status = 'undone', $orderBy = 'order_desc', $pager = null, $involved = 0) { /* Init vars. */ - $projects = $this->loadModel('program')->getProjectList(0, $status, 0, $orderBy, $pager, 0, $involved); + $projects = $this->projectTao->fetchProjectList($status, $orderBy, $involved, $pager); if(empty($projects)) return array(); $projectIdList = array_keys($projects); - $teams = $this->dao->select('t1.root, count(t1.id) as count')->from(TABLE_TEAM)->alias('t1') - ->leftJoin(TABLE_USER)->alias('t2')->on('t1.account=t2.account') - ->where('t1.root')->in($projectIdList) - ->andWhere('t2.deleted')->eq(0) - ->groupBy('t1.root') - ->fetchAll('root'); + $teams = $this->projectTao->fetchTeamGroupByIdList($projectIdList); $estimates = $this->dao->select("t2.project as project, sum(estimate) as estimate")->from(TABLE_TASK)->alias('t1') ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.execution = t2.id') diff --git a/module/project/tao.php b/module/project/tao.php index ae68697a94..8e2311e065 100755 --- a/module/project/tao.php +++ b/module/project/tao.php @@ -529,4 +529,63 @@ class projectTao extends projectModel $oldExecutionProducts = $this->dao->select('project,product')->from(TABLE_PROJECTPRODUCT)->where('project')->in($executionIDs)->fetchGroup('project', 'product'); return !dao::isError(); } + + /** + * 根据状态和和我参与的查询项目列表。 + * Get project list by status and with my participation. + * + * @param string $status + * @param string $orderBy + * @param int $involved + * @param object $pager + * @access protected + * @return array + */ + protected function fetchProjectList(string $status, string $orderBy, int $involved, object|null $pager): array + { + return $this->dao->select('DISTINCT t1.*')->from(TABLE_PROJECT)->alias('t1') + ->leftJoin(TABLE_TEAM)->alias('t2')->on('t1.id=t2.root') + ->leftJoin(TABLE_STAKEHOLDER)->alias('t3')->on('t1.id=t3.objectID') + ->where('t1.deleted')->eq('0') + ->andWhere('t1.vision')->eq($this->config->vision) + ->andWhere('t1.type')->eq('project') + ->beginIF(!in_array($status, array('all', 'undone', 'review', 'unclosed'), true))->andWhere('t1.status')->eq($status)->fi() + ->beginIF($status == 'undone' or $status == 'unclosed')->andWhere('t1.status')->in('wait,doing')->fi() + ->beginIF($status == 'review') + ->andWhere("FIND_IN_SET('{$this->app->user->account}', t1.reviewers)") + ->andWhere('t1.reviewStatus')->eq('doing') + ->fi() + ->beginIF($this->cookie->involved or $involved) + ->andWhere('t2.type')->eq('project') + ->andWhere('t1.openedBy', true)->eq($this->app->user->account) + ->orWhere('t1.PM')->eq($this->app->user->account) + ->orWhere('t2.account')->eq($this->app->user->account) + ->orWhere('(t3.user')->eq($this->app->user->account) + ->andWhere('t3.deleted')->eq(0) + ->markRight(1) + ->orWhere("CONCAT(',', t1.whitelist, ',')")->like("%,{$this->app->user->account},%") + ->markRight(1) + ->fi() + ->orderBy($orderBy) + ->page($pager, 't1.id') + ->fetchAll('id'); + } + + /** + * 根据项目ID列表查询团队成员分组。 + * Get project team members by project id list. + * + * @param array $projectIdList + * @access protected + * @return array + */ + protected function fetchTeamGroupByIdList(array $projectIdList): array + { + return $this->dao->select('t1.root, count(t1.id) as count')->from(TABLE_TEAM)->alias('t1') + ->leftJoin(TABLE_USER)->alias('t2')->on('t1.account=t2.account') + ->where('t1.root')->in($projectIdList) + ->andWhere('t2.deleted')->eq(0) + ->groupBy('t1.root') + ->fetchAll('root'); + } } diff --git a/module/project/test/project.class.php b/module/project/test/project.class.php index b272a5721e..934f541b87 100644 --- a/module/project/test/project.class.php +++ b/module/project/test/project.class.php @@ -162,10 +162,10 @@ class Project /** * Activate a project. * - * @param int $projectID - * @param object $project + * @param int $projectID + * @param object $project * @access public - * @return array $changes + * @return array */ public function activate($projectID, $project) { @@ -175,8 +175,8 @@ class Project /** * Do activate a project. * - * @param int $projectID - * @param object $project + * @param int $projectID + * @param object $project * @access public * @return bool */ @@ -190,7 +190,7 @@ class Project * * @param int $budget * @access public - * @return int|string $projectBudget + * @return int|string */ public function getBudgetWithUnit($budget) { @@ -202,13 +202,27 @@ class Project * * @param int $budget * @access public - * @return int|string $projectBudget + * @return int|string */ public function addProjectAdminTest($projectID) { - global $tester; - $tester->loadModel('project')->addProjectAdmin($projectID); + $this->project->addProjectAdmin($projectID); return $tester->dao->select('*')->from(TABLE_PROJECTADMIN)->fetch(); } + + /** + * Test fetchProjectList function. + * + * @param int $status + * @param string $orderBy + * @param int $involved + * @access public + * @return array + */ + public function testFetchProjectList($status, $involved = 0) + { + $projects = $this->project->fetchProjectList($status, 'id_desc', $involved, null); + return $projects; + } } diff --git a/module/project/test/tao/fetchprojectlist.php b/module/project/test/tao/fetchprojectlist.php new file mode 100755 index 0000000000..43ec659913 --- /dev/null +++ b/module/project/test/tao/fetchprojectlist.php @@ -0,0 +1,59 @@ +#!/usr/bin/env php +id->range('11-19'); + $project->project->range('11-19'); + $project->name->prefix("项目")->range('11-19'); + $project->code->prefix("project")->range('11-19'); + $project->model->range("scrum"); + $project->auth->range("[]"); + $project->path->range("[]"); + $project->type->range("project"); + $project->grade->range("1"); + $project->days->range("1"); + $project->status->range("wait,doing,suspended,closed"); + $project->desc->range("[]"); + $project->budget->range("100000,200000"); + $project->budgetUnit->range("CNY"); + $project->percent->range("0-0"); + $project->openedDate->range("`2023-05-01 10:00:10`"); + $project->gen(9); + + zdTable('team')->gen(10); + + $stakeholder = zdTable('stakeholder'); + $stakeholder->id->range('1-9'); + $stakeholder->objectID->range('11-19'); + $stakeholder->objectType->range('program,project'); + $stakeholder->user->range("admin"); + $stakeholder->type->range("inside"); + $stakeholder->from->range("[]"); + $stakeholder->createdBy->range("admin"); + $stakeholder->createdDate->range("`2023-05-01 10:00:10`"); + $stakeholder->gen(9); +} + +/** + +title=测试 projectModel::fetchProjectList(); +timeout=0 +cid=1 + + +*/ + +initData(); +$statusList = array('', 'all', 'undone', 'unclosed', 'error'); + +$projectTester = new Project(); +r($projectTester->testFetchProjectList($statusList[0])) && p() && e('0'); // 查询状态为空的项目 +r(count($projectTester->testFetchProjectList($statusList[1]))) && p() && e('9'); // 获取所有项目数量 +r($projectTester->testFetchProjectList($statusList[2])) && p('11:code') && e('project11'); // 查询未完成的第一个项目的code +r($projectTester->testFetchProjectList($statusList[3], 1)) && p('12:name') && e('项目12'); // 获取我参与的一个项目的项目名 +r($projectTester->testFetchProjectList($statusList[4])) && p() && e('0'); // 获取错误类型的项目 diff --git a/test/data/team.yaml b/test/data/team.yaml index db08ac1352..99ea1c6781 100644 --- a/test/data/team.yaml +++ b/test/data/team.yaml @@ -32,7 +32,7 @@ fields: - field: account1 range: admin,user{98},test{100},pm{100},po{100} - field: account2 - range: [],3-100,1-100,1-100,1-100 + range: "[],3-100,1-100,1-100,1-100" prefix: "" postfix: "" loop: 0 From 0591838853aa3bbea7ee29a9dde8afc470c09e53 Mon Sep 17 00:00:00 2001 From: xushenjie Date: Thu, 4 May 2023 06:08:10 +0000 Subject: [PATCH 03/20] * Adjust the argument to todoModel::create(). --- module/todo/model.php | 5 +++-- module/todo/tao.php | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/module/todo/model.php b/module/todo/model.php index 20ca9449d9..678a2effe6 100755 --- a/module/todo/model.php +++ b/module/todo/model.php @@ -17,12 +17,13 @@ class todoModel extends model * Create todo data. * * @param object $todo + * @param object $formData * @access public * @return int|false */ - public function create(object $todo): int|false + public function create(object $todo, object $formData): int|false { - $processedTodo = $this->todoTao->processCreateData($todo); + $processedTodo = $this->todoTao->processCreateData($todo, $formData); if(!$processedTodo) return false; $todoID = $this->todoTao->insert($processedTodo); diff --git a/module/todo/tao.php b/module/todo/tao.php index 16de84e351..aa9d806e6a 100644 --- a/module/todo/tao.php +++ b/module/todo/tao.php @@ -340,7 +340,7 @@ class todoTao extends todoModel /** * 获取用户的待办事项数量。 * Get todo count on the account. - * + * * @param string $account * @access protected * @return int From 3a4a905463cabbc66ed6ca37f4aefa5dcc94bee5 Mon Sep 17 00:00:00 2001 From: guofeilong Date: Thu, 4 May 2023 14:08:37 +0800 Subject: [PATCH 04/20] * Code for fix bug in tao func doUpdate . --- module/project/model.php | 2 +- module/project/tao.php | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/module/project/model.php b/module/project/model.php index f1b36bcdf4..ffd3605ce6 100755 --- a/module/project/model.php +++ b/module/project/model.php @@ -1394,7 +1394,7 @@ class projectModel extends model $this->lang->error->unique = $this->lang->error->repeat; if(!empty($executionsCount) and $oldProject->multiple) $this->checkDatesValidByProject($projectID ,$project); - $this->projectTao->doUpdate($projectID, $project); + $this->projectTao->doUpdate($projectID, $project, $oldProject); if(dao::isError()) return false; if(!$oldProject->hasProduct and ($oldProject->name != $project->name or $oldProject->parent != $project->parent or $oldProject->acl != $project->acl)) $this->updateShadowProduct($project); diff --git a/module/project/tao.php b/module/project/tao.php index 8e2311e065..78ed14a4af 100755 --- a/module/project/tao.php +++ b/module/project/tao.php @@ -101,10 +101,11 @@ class projectTao extends projectModel * * @param int $projectID * @param object $project + * @param object $oldProject * @access protected * @return bool */ - protected function doUpdate(int $projectID ,object $project): bool + protected function doUpdate(int $projectID ,object $project, object $oldProject): bool { $this->dao->update(TABLE_PROJECT)->data($project) ->autoCheck($skipFields = 'begin,end') From 22cfb7c4095ad07d00b57a9791c5d8c54545ca0d Mon Sep 17 00:00:00 2001 From: dingguodong Date: Thu, 4 May 2023 14:12:57 +0800 Subject: [PATCH 05/20] * Refactor todoModel::getByID. --- module/todo/model.php | 21 ++------------------- module/todo/tao.php | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/module/todo/model.php b/module/todo/model.php index 39c532b52e..2029fa46ee 100755 --- a/module/todo/model.php +++ b/module/todo/model.php @@ -256,18 +256,9 @@ class todoModel extends model $todo = $this->loadModel('file')->replaceImgURL((object)$todo, 'desc'); if($setImgSize) $todo->desc = $this->file->setImgSize($todo->desc); - if($todo->type == 'story') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_STORY)->fetch('title'); - if($todo->type == 'task') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_TASK)->fetch('name'); - if($todo->type == 'bug') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_BUG)->fetch('title'); - if($todo->type == 'issue' and $this->config->edition == 'max') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_ISSUE)->fetch('title'); - if($todo->type == 'risk' and $this->config->edition == 'max') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_RISK)->fetch('name'); - if($todo->type == 'opportunity' and $this->config->edition == 'max') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_OPPORTUNITY)->fetch('name'); - if($todo->type == 'review' and $this->config->edition == 'max') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_REVIEW)->fetch('title'); - if($todo->type == 'testtask') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_TESTTASK)->fetch('name'); - if($todo->type == 'feedback') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_FEEDBACK)->fetch('title'); $todo->date = str_replace('-', '', $todo->date); - return $todo; + return $this->todoTao->setTodoNameByType($todo); } /** @@ -375,15 +366,7 @@ class todoModel extends model while($todo = $stmt->fetch()) { - if($todo->type == 'story') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_STORY)->fetch('title'); - if($todo->type == 'task') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_TASK)->fetch('name'); - if($todo->type == 'bug') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_BUG)->fetch('title'); - if($todo->type == 'testtask') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_TESTTASK)->fetch('name'); - if($todo->type == 'issue' && $this->config->edition == 'max') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_ISSUE)->fetch('title'); - if($todo->type == 'risk' && $this->config->edition == 'max') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_RISK)->fetch('name'); - if($todo->type == 'opportunity' && $this->config->edition == 'max') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_OPPORTUNITY)->fetch('name'); - if($todo->type == 'review' && $this->config->edition == 'max') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_REVIEW)->fetch('title'); - if($todo->type == 'feedback' and $this->config->edition != 'open') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_FEEDBACK)->fetch('title'); + $todo = $this->todoTao->setTodoNameByType($todo); $todo->begin = date::formatTime($todo->begin); $todo->end = date::formatTime($todo->end); diff --git a/module/todo/tao.php b/module/todo/tao.php index 16de84e351..228e71f606 100644 --- a/module/todo/tao.php +++ b/module/todo/tao.php @@ -340,7 +340,7 @@ class todoTao extends todoModel /** * 获取用户的待办事项数量。 * Get todo count on the account. - * + * * @param string $account * @access protected * @return int @@ -357,4 +357,35 @@ class todoTao extends todoModel ->markRight(1) ->fetch('count'); } + + /** + * 根据待办类型设置待办名称。 + * Set todo name by its type. + * + * @param object $todo + * @access protected + * @return object + */ + protected function setTodoNameByType(object $todo): object + { + if($todo->type == 'story') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_STORY)->fetch('title'); + if($todo->type == 'task') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_TASK)->fetch('name'); + if($todo->type == 'bug') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_BUG)->fetch('title'); + if($todo->type == 'testtask') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_TESTTASK)->fetch('name'); + + if($this->config->edition == 'max') + { + if($todo->type == 'risk' ) $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_RISK)->fetch('name'); + if($todo->type == 'issue') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_ISSUE)->fetch('title'); + if($todo->type == 'review') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_REVIEW)->fetch('title'); + if($todo->type == 'opportunity') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_OPPORTUNITY)->fetch('name'); + } + + if($this->config->edition == 'biz' || $this->config->edition == 'max') + { + if($todo->type == 'feedback') $todo->name = $this->dao->findByID($todo->objectID)->from(TABLE_FEEDBACK)->fetch('title'); + } + + return $todo; + } } From 8cc017b2164fd4db220d62ef9ced61a1b80287f4 Mon Sep 17 00:00:00 2001 From: Wangyuting <851424971@qq.com> Date: Thu, 4 May 2023 14:18:57 +0800 Subject: [PATCH 06/20] * Optimize block control. --- module/block/control.php | 122 ++++++++--------------------- module/block/model.php | 75 ++++++++++++++++++ module/block/ui/dashboard.html.php | 8 +- 3 files changed, 111 insertions(+), 94 deletions(-) diff --git a/module/block/control.php b/module/block/control.php index a72bb72640..1ca79413a4 100755 --- a/module/block/control.php +++ b/module/block/control.php @@ -97,81 +97,39 @@ class block extends control $this->display(); } - public function set($id, $type, $module = '') - { - $block = $this->block->getByID($id); - if($block and empty($type)) $type = $block->code; - if(isset($block->params->num) and !isset($block->params->count)) - { - $block->params->count = $block->params->num; - unset($block->params->num); - } - - if(isset($this->lang->block->moduleList[$module])) - { - $params = $this->block->getParams($type, $module); - $this->view->params = json_decode($params, true); - } - elseif($type == 'assigntome') - { - $params = $this->block->getParams('assignedToMe'); - $this->view->params = json_decode($params, true); - } - - $this->view->source = $module; - $this->view->type = $type; - $this->view->id = $id; - $this->view->block = ($block) ? $block : array(); - $this->display(); - } - /** - * Delete block + * Delete or hidd block by blockid. * * @param int $id - * @param string $sys * @param string $type * @access public * @return void */ - public function delete($id, $module = 'my', $type = 'delete') + public function delete($blockID, $type = 'delete') { - if($type == 'hidden') - { - $this->dao->update(TABLE_BLOCK)->set('hidden')->eq(1)->where('`id`')->eq($id)->andWhere('account')->eq($this->app->user->account)->andWhere('module')->eq($module)->exec(); - } - else - { - $this->dao->delete()->from(TABLE_BLOCK)->where('`id`')->eq($id)->andWhere('account')->eq($this->app->user->account)->andWhere('module')->eq($module)->exec(); - } + $blockID = (int)$blockID; + if($type == 'delete') $this->block->deleteBlock($blockID); + if($type == 'hidden') $this->block->hidden($blockID); if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); + $this->loadModel('score')->create('block', 'set'); return $this->send(array('result' => 'success')); } /** - * Sort block. + * Sort dashboard blocks. * - * @param string $oldOrder - * @param string $newOrder - * @param string $module + * @param string $orders * @access public * @return void */ - public function sort($orders, $module = 'my') + public function sort($orders) { - $orders = explode(',', $orders); - $blockList = $this->block->getMyDashboard($module); - - foreach ($orders as $order => $blockID) - { - $block = $blockList[$blockID]; - if(!isset($block)) continue; - $block->order = $order; - $this->dao->replace(TABLE_BLOCK)->data($block)->exec(); - } + $orders = explode(',', $orders); + foreach($orders as $order => $blockID) $this->block->setOrder($blockID, $order); if(dao::isError()) return $this->send(array('result' => 'fail')); + $this->loadModel('score')->create('block', 'set'); return $this->send(array('result' => 'success')); } @@ -182,26 +140,22 @@ class block extends control * @access public * @return void */ - public function resize($id, $type, $data) + public function resize($blockID, $type, $data) { - $block = $this->block->getByID($id); - if($block) - { - $field = ''; - if($type == 'vertical') $field = 'height'; - if($type == 'horizontal') $field = 'grid'; - if(empty($field)) return $this->send(array('result' => 'fail', 'code' => 400)); + $block = $this->block->getByID($blockID); + if(!$block) return $this->send(array('result' => 'fail', 'code' => 404)); - $block->$field = $data; - $block->params = helper::jsonEncode($block->params); - $this->dao->replace(TABLE_BLOCK)->data($block)->exec(); - if(dao::isError()) return $this->send(array('result' => 'fail', 'code' => 500)); - return $this->send(array('result' => 'success')); - } - else - { - return $this->send(array('result' => 'fail', 'code' => 404)); - } + $field = ''; + if($type == 'vertical') $field = 'height'; + if($type == 'horizontal') $field = 'grid'; + if(empty($field)) return $this->send(array('result' => 'fail', 'code' => 400)); + + $block->$field = $data; + $block->params = helper::jsonEncode($block->params); + $this->block->update($block); + + if(dao::isError()) return $this->send(array('result' => 'fail', 'code' => 500)); + return $this->send(array('result' => 'success')); } /** @@ -2155,30 +2109,18 @@ class block extends control } /** - * Ajax reset. + * Reset dashboard blocks. * - * @param string $module - * @param string $confirm + * @param string $dashboard * @access public * @return void */ - public function ajaxReset($module, $confirm = 'no') + public function reset($dashboard) { - if($confirm != 'yes') return print(js::confirm($this->lang->block->confirmReset, inlink('ajaxReset', "module=$module&confirm=yes"))); + $this->block->reset($dashboard); + if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); - $this->dao->delete()->from(TABLE_BLOCK) - ->where('module')->eq($module) - ->andWhere('vision')->eq($this->config->vision) - ->andWhere('account')->eq($this->app->user->account) - ->exec(); - - $this->dao->delete()->from(TABLE_CONFIG) - ->where('module')->eq($module) - ->andWhere('vision')->eq($this->config->vision) - ->andWhere('owner')->eq($this->app->user->account) - ->andWhere('`key`')->eq('blockInited') - ->exec(); - return print(js::reload('parent')); + return $this->send(array('result' => 'success')); } /** diff --git a/module/block/model.php b/module/block/model.php index 1102e6f891..2c20cb4e5f 100644 --- a/module/block/model.php +++ b/module/block/model.php @@ -295,6 +295,81 @@ class blockModel extends model return (int)$formData->id; } + /** + * Reset dashboard blocks. + * + * @param string $dashboard + * @access public + * @return bool + */ + public function reset(string $dashboard): bool + { + $this->dao->delete()->from(TABLE_BLOCK) + ->where('dashboard')->eq($dashboard) + ->andWhere('vision')->eq($this->config->vision) + ->andWhere('account')->eq($this->app->user->account) + ->exec(); + + $this->dao->delete()->from(TABLE_CONFIG) + ->where('module')->eq($dashboard) + ->andWhere('vision')->eq($this->config->vision) + ->andWhere('owner')->eq($this->app->user->account) + ->andWhere('`key`')->eq('blockInited') + ->exec(); + + return true; + } + + /** + * Hidden a block. + * + * @param int $blockID + * @access public + * @return bool + */ + public function hidden(int $blockID): bool + { + $this->dao->update(TABLE_BLOCK)->set('hidden')->eq(1) + ->where('id')->eq($blockID) + ->andWhere('account')->eq($this->app->user->account) + ->andWhere('vision')->eq($this->config->vision) + ->exec(); + + return true; + } + + /** + * Delete a block. + * + * @param int $blockID + * @access public + * @return bool + */ + public function deleteBlock(int $blockID = 0): bool + { + $this->dao->delete()->from(TABLE_BLOCK) + ->where('id')->eq($blockID) + ->andWhere('account')->eq($this->app->user->account) + ->andWhere('vision')->eq($this->config->vision) + ->exec(); + + return true; + } + + /** + * Set block order. + * + * @param int $blockID + * @param int $order + * @access public + * @return bool + */ + public function setOrder(int $blockID, int $order): bool + { + $this->dao->update(TABLE_BLOCK)->set('order')->eq($order)->where('id')->eq($blockID)->exec(); + return true; + } + /** * Save a block. * diff --git a/module/block/ui/dashboard.html.php b/module/block/ui/dashboard.html.php index c4979b4900..62b02dd635 100644 --- a/module/block/ui/dashboard.html.php +++ b/module/block/ui/dashboard.html.php @@ -30,9 +30,9 @@ foreach($longBlocks as $index => $block) ([ ['text' => $lang->block->refresh, 'url' => ''], ['text' => $lang->edit, 'url' => $this->createLink("block", "edit", "blockID=$block->id"), 'data-toggle' => 'modal'], - ['text' => $lang->block->hidden, 'url' => ''], + ['text' => $lang->block->hidden, 'url' => $this->createLink("block", "delete", "blockID=$block->id&type=hidden")], ['text' => $lang->block->createBlock, 'url' => $this->createLink("block", "create", "dashboard=$dashboard"), 'data-toggle' => 'modal'], - ['text' => $lang->block->reset, 'url' => ''], + ['text' => $lang->block->reset, 'url' => $this->createLink("block", "reset", "dashboard=$dashboard")], ]), ) ) @@ -78,9 +78,9 @@ foreach($shortBlocks as $index => $block) ([ ['text' => $lang->block->refresh, 'url' => ''], ['text' => $lang->edit, 'url' => $this->createLink("block", "edit", "blockID=$block->id"), 'data-toggle' => 'modal'], - ['text' => $lang->block->hidden, 'url' => ''], + ['text' => $lang->block->hidden, 'url' => $this->createLink("block", "delete", "blockID=$block->id&type=hidden")], ['text' => $lang->block->createBlock, 'url' => $this->createLink("block", "create", "dashboard=$dashboard"), 'data-toggle' => 'modal'], - ['text' => $lang->block->reset, 'url' => ''], + ['text' => $lang->block->reset, 'url' => $this->createLink("block", "reset", "dashboard=$dashboard")], ]), ) ) From 63419d70349f1db2292faaaaae267bff8d2cac93 Mon Sep 17 00:00:00 2001 From: dingguodong Date: Thu, 4 May 2023 14:20:14 +0800 Subject: [PATCH 07/20] + Add missing fields. --- module/todo/test/model/yaml/getbyid/getbyid.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/module/todo/test/model/yaml/getbyid/getbyid.yaml b/module/todo/test/model/yaml/getbyid/getbyid.yaml index dc2bf56d81..96a2bffb6b 100644 --- a/module/todo/test/model/yaml/getbyid/getbyid.yaml +++ b/module/todo/test/model/yaml/getbyid/getbyid.yaml @@ -27,5 +27,11 @@ fields: prefix: '这是待办描述' - field: status range: 'wait,doing,done,closed,closed' + - field: finishedDate + range: 1-9 + prefix: '2023-04-2' + - field: closedDate + range: 1-9 + prefix: '2023-04-2' From a8a1429b9e6db9021ec802d12ba7ccf0fe3f5db3 Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Thu, 4 May 2023 14:36:12 +0800 Subject: [PATCH 08/20] * Adjust codes. --- module/project/control.php | 17 ++++++++--------- module/project/model.php | 15 +++++---------- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/module/project/control.php b/module/project/control.php index 5c9f6d7ce1..2eb965fc9c 100755 --- a/module/project/control.php +++ b/module/project/control.php @@ -315,7 +315,7 @@ class project extends control if($project->model == 'kanban' and $this->config->vision != 'lite') { /* Load pager and get kanban list. */ - $this->app->loadClass('pager', $static = true); + $this->app->loadClass('pager', true); $pager = new pager($recTotal, $recPerPage, $pageID); $kanbanList = $this->loadModel('execution')->getList($projectID, 'all', $browseType, 0, 0, 0, $pager); @@ -369,7 +369,7 @@ class project extends control $browseType = strtolower($browseType); /* Load pager. */ - $this->app->loadClass('pager', $static = true); + $this->app->loadClass('pager', true); $pager = new pager($recTotal, $recPerPage, $pageID); $queryID = ($browseType == 'bysearch') ? (int)$param : 0; @@ -518,9 +518,8 @@ class project extends control $this->loadModel('program'); $this->loadModel('execution'); - $projectID = (int)$projectID; - $project = $this->project->getByID($projectID); - $programID = $project->parent; + $projectID = (int)$projectID; + $project = $this->project->getByID($projectID); $this->project->setMenu($projectID); if($project->model == 'kanban') @@ -735,7 +734,7 @@ class project extends control } /* Load pager. */ - $this->app->loadClass('pager', $static = true); + $this->app->loadClass('pager', true); $pager = new pager(0, 30, 1); /* Check exist extend fields. */ @@ -864,8 +863,8 @@ class project extends control $orderBy = $direction == 'next' ? 'date_desc' : 'date_asc'; /* Set the pager. */ - $this->app->loadClass('pager', $static = true); - $pager = new pager($recTotal, $recPerPage = 50, $pageID = 1); + $this->app->loadClass('pager', true); + $pager = new pager($recTotal, 50, 1); /* Set the user and type. */ $account = 'all'; @@ -933,7 +932,7 @@ class project extends control if(!empty($project->model) and $project->model == 'kanban' and !(defined('RUN_MODE') and RUN_MODE == 'api')) return print(js::locate($this->createLink('project', 'index', "projectID=$projectID"))); /* Load pager and get tasks. */ - $this->app->loadClass('pager', $static = true); + $this->app->loadClass('pager', true); $pager = new pager($recTotal, $recPerPage, $pageID); $allExecution = $this->execution->getStatData($projectID, 'all'); diff --git a/module/project/model.php b/module/project/model.php index f1b36bcdf4..89869cfbab 100755 --- a/module/project/model.php +++ b/module/project/model.php @@ -47,10 +47,8 @@ class projectModel extends model { if(defined('TUTORIAL')) return true; - echo(js::alert($this->lang->project->accessDenied)); $this->session->set('project', ''); - - return print(js::locate(helper::createLink('project', 'index'))); + return print(js::alert($this->lang->project->accessDenied) . js::locate(helper::createLink('project', 'index'))); } /** @@ -148,8 +146,8 @@ class projectModel extends model */ public function getMultiLinkedProducts($projectID) { - $linkedProducts = $this->dao->select('product')->from(TABLE_PROJECTPRODUCT)->where('project')->eq($projectID)->fetchPairs(); - $multiLinkedProducts = $this->dao->select('t3.id,t3.name')->from(TABLE_PROJECTPRODUCT)->alias('t1') + $linkedProducts = $this->dao->select('product')->from(TABLE_PROJECTPRODUCT)->where('project')->eq($projectID)->fetchPairs(); + return $this->dao->select('t3.id,t3.name')->from(TABLE_PROJECTPRODUCT)->alias('t1') ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id') ->leftJoin(TABLE_PRODUCT)->alias('t3')->on('t1.product = t3.id') ->where('t1.product')->in($linkedProducts) @@ -158,8 +156,6 @@ class projectModel extends model ->andWhere('t2.deleted')->eq('0') ->andWhere('t3.deleted')->eq('0') ->fetchPairs('id', 'name'); - - return $multiLinkedProducts; } /* @@ -263,7 +259,7 @@ class projectModel extends model ->groupBy('t2.project') ->fetchAll('project'); - $this->app->loadClass('pager', $static = true); + $this->app->loadClass('pager', true); foreach($projects as $projectID => $project) { $orderBy = $project->model == 'waterfall' ? 'id_asc' : 'id_desc'; @@ -864,12 +860,11 @@ class projectModel extends model ->orderBy('grade desc') ->fetch(); - $projects = $this->dao->select('id')->from(TABLE_PROJECT) + return $this->dao->select('id')->from(TABLE_PROJECT) ->where('type')->eq('project') ->andWhere('deleted')->eq(0) ->andWhere('path')->like("{$parentProgram->path}%") ->fetchPairs('id'); - return $projects; } /** From 15f4e9363498812e93bc024183ee1720c9777b5d Mon Sep 17 00:00:00 2001 From: weizhenlong Date: Thu, 4 May 2023 14:57:48 +0800 Subject: [PATCH 09/20] add doc folder exclusion --- sonar-project.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonar-project.properties b/sonar-project.properties index e787def4f9..0ecd58d8aa 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -3,4 +3,4 @@ sonar.sourceEncoding=UTF-8 sonar.qualitygate.wait=true sonar.coverage.exclusions=**/*.* sonar.inclusions=**/**.php -sonar.exclusions=**/*.bak,**/*.sql,**/*.js,**/*.css,**/*.yaml,**/*.zip,**/*.out,**/lang/*,**/test/** +sonar.exclusions=**/*.bak,**/*.sql,**/*.js,**/*.css,**/*.yaml,**/*.zip,**/*.out,**/lang/*,**/test/**,doc/* From 7bf13344455f89b2c362f5ef8c47728b3ee6d268 Mon Sep 17 00:00:00 2001 From: guofeilong Date: Thu, 4 May 2023 15:03:56 +0800 Subject: [PATCH 10/20] * Code for delete vars and newPlans . --- module/project/model.php | 7 ++----- module/project/tao.php | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/module/project/model.php b/module/project/model.php index 7bc550d095..7f36d3eb80 100755 --- a/module/project/model.php +++ b/module/project/model.php @@ -1539,7 +1539,7 @@ class projectModel extends model $parentID = !isset($project->parent) ? $oldProject->parent : $project->parent; $this->dao->update(TABLE_PROJECT)->data($project) - ->autoCheck($skipFields = 'begin,end') + ->autoCheck('begin,end') ->batchCheck($this->config->project->edit->requiredFields, 'notempty') ->checkIF($project->begin != '', 'begin', 'date') ->checkIF($project->end != '', 'end', 'date') @@ -3056,10 +3056,7 @@ class projectModel extends model { foreach($plans as $planList) { - foreach($planList as $planIDList) - { - foreach($planIDList as $planID) $newPlans[$planID] = $planID; - } + foreach($planList as $planID) $newPlans[$planID] = $planID; } } if(empty($newPlans)) return; diff --git a/module/project/tao.php b/module/project/tao.php index 78ed14a4af..17d5567aed 100755 --- a/module/project/tao.php +++ b/module/project/tao.php @@ -108,7 +108,7 @@ class projectTao extends projectModel protected function doUpdate(int $projectID ,object $project, object $oldProject): bool { $this->dao->update(TABLE_PROJECT)->data($project) - ->autoCheck($skipFields = 'begin,end') + ->autoCheck('begin,end') ->batchcheck($requiredFields, 'notempty') ->checkIF($project->begin != '', 'begin', 'date') ->checkIF($project->end != '', 'end', 'date') From 20e548e422fb41b976e73a8bfb94219fb17f5e21 Mon Sep 17 00:00:00 2001 From: wangzemei Date: Thu, 4 May 2023 15:06:35 +0800 Subject: [PATCH 11/20] * Refactor to create todo page --- module/todo/css/common.ui.css | 10 + module/todo/js/common.ui.js | 192 ++++++++++++++ module/todo/js/create.ui.js | 60 +++++ module/todo/ui/create.html.php | 458 +++++++++++++++++++++++++++++++++ 4 files changed, 720 insertions(+) create mode 100644 module/todo/css/common.ui.css create mode 100644 module/todo/js/common.ui.js create mode 100644 module/todo/js/create.ui.js create mode 100644 module/todo/ui/create.html.php diff --git a/module/todo/css/common.ui.css b/module/todo/css/common.ui.css new file mode 100644 index 0000000000..f63711e746 --- /dev/null +++ b/module/todo/css/common.ui.css @@ -0,0 +1,10 @@ +.private-row .checkbox-primary {margin-top: 5px;} +.every-checkbox .checkbox-primary {width: 50px;} +.cycle-config .tab-content>.tab-pane {padding-left: 0; padding-right: 0;} +.cycle-config .tab-content>.tab-pane:first-child, +.cycle-config .tab-content>.input-group {width: 44.5%;} +.switch-time {min-height: 32px;} +.form-row .form-group.align-center {align-items: center;} +#nameInputBox {width: 80%;} +#nameInputBox .form-control {width: 99.8%;} + diff --git a/module/todo/js/common.ui.js b/module/todo/js/common.ui.js new file mode 100644 index 0000000000..6b2174ae3e --- /dev/null +++ b/module/todo/js/common.ui.js @@ -0,0 +1,192 @@ +/** + * 切换日期选择的禁用状态。 + * Toggle the disabled state of the date select. + * + * @param object switcher + * @return void + */ +function toggleDateTodo(switcher) +{ + $('#date').prop('disabled', switcher.checked); +} + +/** + * Load data. + * @param type $type Type of selected todo. + * @param id $id ID of selected todo. + * @param objectID $objectID ID of the closed todo type. + * @return void + */ +function loadList(type, id, objectID) +{ + if(id) + { + divClass = '.name-box' + id; + divID = '#nameBox' + id; + } + else + { + divClass = '.name-box'; + divID = '#nameBox'; + } + id = id ? id : ''; + var param = 'userID=' + userID + '&id=' + id; + if(type == "task") param += '&status=wait,doing'; + if(defaultType && type == defaultType && objectID != 0) param += '&objectID=' + objectID; + + if(moduleList.indexOf(type) !== -1) + { + link = '/index.php?m=' + type + '&f=' + objectsMethod[type] + '&' + param + '&t=html'; + $.get(link, function(data, status) + { + if(data.length != 0) + { + $(divClass).find('#nameInputBox').html(data).find('select').chosen(); + if(config.currentMethod == 'edit' || type == 'feedback') $(divClass).find('select').val(objectID).trigger('chosen:updated'); + if($(divClass + " select").val() == null) $(divClass + " select").attr("data-placeholder", noOptions.replace("%s", chosenType[type])).trigger('chosen:updated'); + } + else + { + $(divClass).html("").find('select').chosen(); + } + }); + } + else + { + $(divClass).html($(divID).html()); + } + + if(nameBoxLabel) return; + var formLabel = type == 'custom' ||(vision && vision == 'rnd') ? nameBoxLabel.custom : nameBoxLabel.objectID; + $('#nameBox .form-label').text(formLabel); +} + +/** + * 选择开始时间后,自动给出默认终止时间。 + * After selecting the start time, the default end time is automatically given. + * + * @return viod + */ +function selectNext() +{ + $("#end ")[0].selectedIndex = $("#begin ")[0].selectedIndex + 3; + $('#end').trigger('chosen:updated'); +} + +function setBeginsAndEnds(i, beginOrEnd) +{ + if(!i) + { + for(j = 0; j < batchCreateNum; j++) + { + if(j != 0) $("#begins" + j)[0].selectedIndex = $("#ends" + (j - 1))[0].selectedIndex; + $("#ends" + j)[0].selectedIndex = $("#begins" + j)[0].selectedIndex + 3; + $("#begins" + j, "#ends" + j).trigger('chosen:updated'); + } + } + else + { + if(beginOrEnd == 'begin') + { + $("#ends" + i)[0].selectedIndex = $("#begins" + i)[0].selectedIndex + 3; + $("#ends" + i).trigger('chosen:updated'); + } + + if(batchCreateNum) + { + for(j = i+1; j < batchCreateNum; j++) + { + $("#begins" + j)[0].selectedIndex = $("#ends" + (j - 1))[0].selectedIndex; + $("#ends" + j)[0].selectedIndex = $("#begins" + j)[0].selectedIndex + 3; + $("#begins" + j, "#ends" + j).trigger('chosen:updated'); + } + } + } +} + +function switchTimeList(number) +{ + if($('#switchTime' + number).prop('checked')) + { + $('#begins' + number, '#ends' + number).attr('disabled', 'disabled').trigger('chosen:updated'); + } + else + { + $('#begins' + number, '#ends' + number).removeAttr('disabled').trigger('chosen:updated'); + } +} + +function switchDateFeature(switcher) +{ + if(switcher.checked) + { + $('#begin, #end').attr('disabled','disabled').trigger('chosen:updated'); + } + else + { + $('#begin, #end').removeAttr('disabled').trigger('chosen:updated'); + } +} + +/** + * 周期待办切换指定复选框时的交互展示。 + * Interactive display when switching the specified checkbox for cycle. + * + * @param object switcher + * @return void + */ +function showSpecifiedDate(switcher) +{ + if(switcher.checked) + { + $('#everyInput').attr('disabled','disabled'); + $('.specify').removeClass('hidden'); + $('.every').addClass('hidden') + $('#configEvery').prop('checked', false); + } +} + +/** + * 切换周期复选框的回调函数,用于页面交互展示。 + * Switch the cycle checkbox for page interactive display. + * + * @param object switcher + * @return void + */ +function showEvery(switcher) +{ + if(switcher.checked) + { + $('#everyInput').removeAttr('disabled'); + $('.specify').addClass('hidden'); + $('.every').removeClass('hidden'); + $('#cycleYear').removeAttr('checked'); + $('#configSpecify, #configEvery').prop('checked', false); + } +} + +/** + * 周期设置为天并为指定时,更改月份时获取天数。 + * When the cycle is set to days and specified, obtain the number of days when changing the month. + * + * @param int $specifiedMonth + * @return void + */ +function setDays(specifiedMonth) +{ + /* Get last day in specified month. */ + var date = new Date(); + date.setMonth(specifiedMonth); + var month = date.getMonth() + 1; + date.setMonth(month); + date.setDate(0); + var specifiedMonthLastDay = date.getDate(); + + $('#specifiedDay').empty(''); + for(var i = 1; i <= specifiedMonthLastDay; i++) + { + html = ""; + + $('#specifiedDay').append(html); + } +} diff --git a/module/todo/js/create.ui.js b/module/todo/js/create.ui.js new file mode 100644 index 0000000000..fbb5e05204 --- /dev/null +++ b/module/todo/js/create.ui.js @@ -0,0 +1,60 @@ +/** + * 切换周期类型,用于展示周期类型的交互。 + * Toggle cycle, used to display the interaction of cycle. + * + * @param object tab + * @return void + */ +function toggleCycle(switcher) +{ + if(switcher.checked) + { + $('#date').attr('disabled','disabled'); + $('.cycle-config').removeClass('hidden'); + $('#switchDate').closest('.checkbox-primary').addClass('hidden'); + $('#type').closest('.form-row').addClass('hidden'); + $('#type').val('custom'); + loadList('custom'); //Fix bug 3278. + } + else + { + $('#date').removeAttr('disabled'); + $('.cycle-config').addClass('hidden'); + $('#switchDate').closest('.checkbox-primary').removeClass('hidden'); + $('#type').closest('.form-row').removeClass('hidden'); + } +} + +/** + * 更改待办日期。 + * Change todo date. + * + * @param object tab + * @return void + */ +function changeCreateDate(dateInput) +{ + var selectTime = $(dateInput).val() != today ? start : nowTime; + $('#begin').val(selectTime); + $('#begin').trigger("chosen:updated"); + selectNext(); +} + +/** + * 切换标签页,用于更新标签页的样式和更新类型。 + * Toggle tabs to update the style and type. + * + * @param object tab + * @return void + */ +function toggleNavTabs(tab) +{ + $(tab).parent().siblings().find('a').prop('class', ''); + $(tab).addClass('active'); + if($(tab).data('type'))$('input[id*=type][id*=config]').val($(tab).data('type')); +} + +function changeType(typeSelect) +{ + loadList($(typeSelect).find('select').val(), ''); +} diff --git a/module/todo/ui/create.html.php b/module/todo/ui/create.html.php new file mode 100644 index 0000000000..2cf75144b2 --- /dev/null +++ b/module/todo/ui/create.html.php @@ -0,0 +1,458 @@ + + * @package todo + * @link http://www.zentao.net + */ +namespace zin; + +jsVar('noTodo', $lang->todo->noTodo); +jsVar('moduleList', $config->todo->moduleList); +jsVar('objectsMethod', $config->todo->getUserObjectsMethod); +jsVar('nameBoxLabel', array('custom' => $lang->todo->name, 'idvalue' => isset($lang->todo->idvalue) ? $lang->todo->idvalue : null)); +jsVar('vision', $config->vision); +jsVar('noOptions', $lang->todo->noOptions); +jsVar('chosenType', $lang->todo->typeList); +jsVar('today', date('Y-m-d')); +jsVar('nowTime', $time); +jsVar('start', key($times)); +jsVar('userID', $app->user->id); +jsVar('defaultType', ''); + +/** + * 构建周期设置的天的标签内容,待办为周期类型进行展示。 + * Build tab-pane content of day. + * + * @return mixed Any type supported by zin widget function 任何 zin 部件函数参数支持的类型。 + */ +function buildDayPane(): mixed +{ + global $lang, $app; + + return fragment + ( + inputGroup + ( + set::class('every'), + span + ( + set::class('input-group-addon'), + $lang->todo->every + ), + + input + ( + set::id('everyInput'), + set::name('config[day]') + ), + span + ( + set::class('input-group-addon'), + $lang->todo->cycleDay + ), + div + ( + set::class('pl-3 flex items-center input-group-addon every-checkbox'), + checkbox + ( + set::id('configSpecify'), + set::name('config[specifiedDate]'), + set::text($lang->todo->specify), + set::value(1), + on::change('showSpecifiedDate(this)') + ) + ) + ), + + inputGroup + ( + set::class('specify hidden'), + span + ( + set::class('input-group-addon'), + $lang->todo->specify + ), + select + ( + set::id('config[specify][month]'), + set::name('config[specify][month]'), + set::items($lang->datepicker->monthNames), + set::value(0), + set::multiple(false), + on::change('setDays(this.value)') + ), + select + ( + set::id('specifiedDay'), + set::name('config[specify][day]'), + set::items($lang->todo->specifiedDay), + set::multiple(false), + set::value(1) + ), + span + ( + set::class('input-group-addon', strpos($app->getClientLang(), 'zh') !== false ? '' : 'hidden'), + $lang->todo->day + ), + div + ( + set::class('w-36 pl-3 flex items-center gap-3 input-group-addon'), + checkbox + ( + set::id('cycleYear'), + set::name('config[cycleYear]'), + set::value(1), + set::text($lang->todo->everyYear) + ), + checkbox + ( + set::id('configEvery'), + set::name('configEvery'), + set::value(1), + set::text($lang->todo->every), + on::change('showEvery(this)') + ) + ) + ) + ); +} + +/** + * 构建月的标签页,用于周期设置。 + * Build tab-pane content of month. + * + * @return mixed Any type supported by zin widget function 任何 zin 部件函数参数支持的类型。 + */ + +function buildMonthDays(): mixed +{ + $days = array(); + for($i = 1; $i <= 31; $i ++) $days[$i] = $i; + + return checkList + ( + set::class('flex-wrap gap-4'), + set::name('config[month]'), + set::inline(true), + set::items($days), + ); +} + +/** + * 构建周期设置的标签导航,待办为周期类型进行展示。 + * Build navTabs header for cycle. + * + * @return mixed Any type supported by zin widget function 任何 zin 部件函数参数支持的类型。 + */ + +function buildNavTabsBar(): mixed +{ + global $lang; + + $navTabs = [ + [ + 'type' => 'day', + 'text' => $lang->todo->cycleDay, + 'class' => ' active' + ], + [ + 'type' => 'week', + 'text' => $lang->todo->cycleWeek, + 'class' => '' + ], + [ + 'type' => 'month', + 'text' => $lang->todo->cycleMonth, + 'class' => '', + ], + ]; + + $nav = ul(set::class('nav nav-tabs')); + foreach($navTabs as $tab) + { + $nav->add( + li + ( + set::class('nav-item'. $tab['class']), + a + ( + set::href('#' . $tab['type']), + set::class($tab['class']), + set('data-toggle', 'tab'), + $tab['text'], + on::click('toggleNavTabs(this)') + ) + ), + ); + } + + return $nav; +} + +/** + * 构建周期设置的标签页,当待办为周期时进行展示。 + * Build navTabs for cycle. + * + * @return mixed Any type supported by zin widget function 任何 zin 部件函数参数支持的类型。 + */ +function buildNavTabs(): mixed +{ + global $lang; + + return div + ( + set::class('w-full'), + buildNavTabsBar(), + div + ( + set::class('tab-content'), + div + ( + set::class('tab-pane active'), + set::id('day'), + buildDayPane(), + ), + div + ( + set::class('tab-pane'), + set::id('week'), + checkList + ( + set::primary(true), + set::id('config[week]'), + set::name('config[week]'), + set::inline(true), + set::items($lang->todo->dayNames), + ), + ), + div + ( + set::class('tab-pane h-28'), + set::id('month'), + buildMonthDays(), + ), + inputGroup + ( + div + ( + set::class('input-group-addon'), + '提前', + ), + input + ( + set::id('name'), + set::name('config[beforeDays]'), + set::value(0), + ), + div + ( + set::class('input-group-addon'), + '天生成待办', + ), + ), + + ), + ); +} + +formPanel +( + formRow + ( + formGroup + ( + set::width('1/2'), + set::label($lang->todo->date), + set::strong(true), + set::class('align-center'), + inputGroup + ( + input + ( + set::name('date'), + set::value(date('Y-m-d')), + set::type('date'), + set::width('1/3'), + on::change('changeCreateDate(this)') + ), + div + ( + set::class('flex items-center gap-3 pl-3 input-group-addon'), + checkbox + ( + set::id('switchDate'), + set::name('switchDate'), + set::text($lang->todo->periods['future']), + set::width('100px'), + on::change('toggleDateTodo(this)') + ), + checkbox + ( + set::id('cycle'), + set::name('cycle'), + set::value(1), + set::text($lang->todo->cycle), + on::change('toggleCycle(this)') + ) + ) + + ) + + ) + ), + formRow + ( + set::class('cycle-config hidden'), + formGroup + ( + set::label($lang->todo->cycleConfig), + set::strong(true), + buildNavTabs() + ) + ), + formRow + ( + set::class('cycle-config hidden'), + formGroup + ( + set::width('1/2'), + set::label($lang->todo->deadline), + set::strong(true), + input + ( + set::type('date'), + set::name('config[end]') + ) + ) + ), + formGroup + ( + set::width('1/2'), + set::name('type'), + set::strong(true), + set::label($lang->todo->type), + set::items($lang->todo->typeList), + on::change('changeType(this)'), + ), + formGroup + ( + set::width('1/2'), + set::name('assignedTo'), + set::strong(true), + set::label($lang->todo->assignTo), + set::items($users), + set::value($app->user->account) + ), + formRow + ( + formGroup + ( + set::id('nameBox'), + set::class('name-box'), + set::label($lang->todo->name), + set::strong(true), + set::required(true), + inputGroup + ( + set::class('title-group'), + div + ( + set::id('nameInputBox'), + input + ( + set::id('name'), + set::name('name') + ) + ), + div + ( + set::class('input-group-addon fix-border br-0'), + $lang->todo->pri + ), + select + ( + set::class('w-20'), + set::id('pri'), + set::name('pri'), + set::items($lang->todo->priList), + set::value(3) + ) + ) + ) + ), + + formGroup + ( + set::name('desc'), + set::strong(true), + set::type('textarea'), + set::label($lang->todo->desc) + ), + formGroup + ( + set::width('1/2'), + set::id('status'), + set::name('status'), + set::items($lang->todo->statusList), + set::label($lang->todo->status), + set::strong(true) + ), + formRow + ( + set::class('items-center'), + formGroup + ( + set::width('1/2'), + set::label($lang->todo->beginAndEnd), + set::strong(true), + inputGroup + ( + select + ( + set::id('begin'), + set::name('begin'), + set::items($times), + set::value(date('Y-m-d') != $date ? key($times) : $time), + on::change('selectNext()') + ), + select + ( + set::id('end'), + set::name('end'), + set::items($times) + ) + ), + div + ( + set::class('ml-3 flex items-center switch-time'), + checkbox + ( + set::id('switchTime'), + set::name('switchTime'), + set::text($lang->todo->lblDisableDate), + on::change('switchDateFeature(this)') + ) + ) + + ) + ), + formGroup + ( + set::label($lang->todo->private), + set::strong(true), + set::class('private-row'), + checkbox + ( + set::id('private'), + set::name('private'), + set::value(1) + ) + ) +); + +render(); From d56a828e22294215b69b3c4077db57408eed48b8 Mon Sep 17 00:00:00 2001 From: dingguodong Date: Thu, 4 May 2023 15:06:56 +0800 Subject: [PATCH 12/20] * Refactor todoModel::getByList. --- module/todo/model.php | 7 +++++-- module/todo/test/model/getbylist.php | 18 ++++++++---------- module/todo/test/todo.class.php | 21 ++++++++++----------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/module/todo/model.php b/module/todo/model.php index b7e86aa772..bd5c52a166 100755 --- a/module/todo/model.php +++ b/module/todo/model.php @@ -381,11 +381,14 @@ class todoModel extends model } /** - * Get by id list. + * 通过包含一个或多个待办ID的列表获取待办列表,这个列表是以todoID为key、以todo对象为value的数组。 + * 如果待办ID列表为空则返回所有待办。 + * Get a array with todos which todoID as key, todo object as value by todo id list. + * Return all todos if the todo id list is empty. * * @param array $todoIDList * @access public - * @return object + * @return array */ public function getByList($todoIDList = 0) { diff --git a/module/todo/test/model/getbylist.php b/module/todo/test/model/getbylist.php index 426f22dd00..3c5ce1f7ee 100755 --- a/module/todo/test/model/getbylist.php +++ b/module/todo/test/model/getbylist.php @@ -10,18 +10,16 @@ title=测试 todoModel->getByList(); cid=1 pid=1 -获取todo 1 2 3 4的名称 >> 自定义1的待办,BUG2的待办,任务3的待办,需求4的待办 -获取todo 5 6 7 8的名称 >> 测试单5的待办,自定义6的待办,BUG7的待办,任务8的待办 -获取todo 9 10 11 12的名称 >> 需求9的待办,测试单10的待办,自定义11的待办,BUG12的待办 - */ -$todoIDList1 = array('1', '2', '3', '4'); -$todoIDList2 = array('5', '6', '7', '8'); -$todoIDList3 = array('9', '10', '11', '12'); +$todoIDList1 = array('1'); +$todoIDList2 = array('1', '2', '3', '4'); +$todoIDList3 = array('9', '10', '11', '12'); /* Test not existed items. */ +$todoIDList4 = array(); /* Test empty todoIDList. */ $todo = new todoTest(); -r($todo->getByListTest($todoIDList1)) && p() && e('自定义1的待办,BUG2的待办,任务3的待办,需求4的待办'); // 获取todo 1 2 3 4的名称 -r($todo->getByListTest($todoIDList2)) && p() && e('测试单5的待办,自定义6的待办,BUG7的待办,任务8的待办'); // 获取todo 5 6 7 8的名称 -r($todo->getByListTest($todoIDList3)) && p() && e('需求9的待办,测试单10的待办,自定义11的待办,BUG12的待办'); // 获取todo 9 10 11 12的名称 \ No newline at end of file +r($todo->getByListTest($todoIDList1)) && p() && e('1'); +r($todo->getByListTest($todoIDList2)) && p() && e('1234'); +r($todo->getByListTest($todoIDList3)) && p() && e(''); +r($todo->getByListTest($todoIDList4)) && p() && e('12345'); diff --git a/module/todo/test/todo.class.php b/module/todo/test/todo.class.php index 94d51fc3fe..9d8acb475a 100755 --- a/module/todo/test/todo.class.php +++ b/module/todo/test/todo.class.php @@ -263,23 +263,22 @@ class todoTest } /** - * Test get todo by id list. + * Test todoModel::getByList. * - * @parami array $todoIDList + * @param array $todoIDList * @access public - * @return void + * @return string */ public function getByListTest($todoIDList = 0) { $objects = $this->objectModel->getByList($todoIDList); - - $name = ''; - foreach($objects as $todo) $name .= ',' . $todo->name; - $name = trim($name, ','); - - if(dao::isError()) return dao::getError(); - - return $name; + $result = ''; + foreach($objects as $id => $todo) + { + $result .= (string) $todo->id; + } + if(empty($result)) return "pass"; + return $result; } /** From cade2fe9b1e6f3c4b10989ae1b2773a97cf3cfbe Mon Sep 17 00:00:00 2001 From: sunhao Date: Thu, 4 May 2023 15:07:10 +0800 Subject: [PATCH 13/20] * zin: auto set rel=noopener for external link --- zin/core/h.class.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/zin/core/h.class.php b/zin/core/h.class.php index 1b57303928..967a6a0db2 100644 --- a/zin/core/h.class.php +++ b/zin/core/h.class.php @@ -100,6 +100,13 @@ class h extends wg return new h(prop('tagName', $tagName), $args); } + public static function a() + { + $a = static::create('a', func_get_args()); + if($a->prop('target') === '_blank' && !$a->hasProp('rel')) $a->prop('rel', 'noopener noreferrer'); + return $a; + } + public static function button() { return static::create('button', prop('type', 'button'), func_get_args()); From f6aa33df3f3dbc34f267a187f95e8c77fde5c309 Mon Sep 17 00:00:00 2001 From: dingguodong Date: Thu, 4 May 2023 15:08:38 +0800 Subject: [PATCH 14/20] + Add yaml for test todoModel::getByList. --- .../test/model/yaml/getbylist/getbylist.yaml | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 module/todo/test/model/yaml/getbylist/getbylist.yaml diff --git a/module/todo/test/model/yaml/getbylist/getbylist.yaml b/module/todo/test/model/yaml/getbylist/getbylist.yaml new file mode 100644 index 0000000000..c86e1a3a3e --- /dev/null +++ b/module/todo/test/model/yaml/getbylist/getbylist.yaml @@ -0,0 +1,37 @@ +title: zt_getbylist +author: jukui +version: "1.0" +fields: + - field: id + range: 1-5 + - field: account + range: 'admin' + - field: date + range: 1-9 + prefix: '2023-04-2' + - field: begin + range: 1000-1100 + - field: end + range: 1200-1300 + - field: type + range: 'custom' + - field: cycle + range: 0 + - field: pri + range: 3 + - field: name + range: 1-5 + prefix: '自定义的待办' + - field: desc + range: 1-5 + prefix: '这是待办描述' + - field: status + range: 'wait,doing,done,closed,closed' + - field: finishedDate + range: 1-9 + prefix: '2023-04-2' + - field: closedDate + range: 1-9 + prefix: '2023-04-2' + + From 928ff7ee667cc3e56ac0fcf47f4d91af03cdee7e Mon Sep 17 00:00:00 2001 From: liuruogu Date: Thu, 4 May 2023 15:11:18 +0800 Subject: [PATCH 15/20] + Add Welcome Block. --- module/block/css/welcome.ui.css | 4 + module/block/js/create.ui.js | 24 +++++ module/block/ui/create.html.php | 9 +- module/block/ui/welcome.html.php | 146 +++++++++++++++++++++++++++++++ module/block/zen.php | 8 +- 5 files changed, 184 insertions(+), 7 deletions(-) create mode 100644 module/block/ui/welcome.html.php diff --git a/module/block/css/welcome.ui.css b/module/block/css/welcome.ui.css index 39ca83a150..8ba8d8a1f2 100644 --- a/module/block/css/welcome.ui.css +++ b/module/block/css/welcome.ui.css @@ -1,3 +1,7 @@ .welcome-block {background-image: linear-gradient( 90deg, #EDF7FE 0%, #FFF 20%);} .border-right {position: relative;} .border-right::after {content: ''; position: absolute; right: 0px; width: 1px; height: 40px; background: #EEE; top: 50%; margin-top: -20px;} +.avatar-border-one {width: 4.2rem; height: 4.2rem; background: #f4f5f3; position: relative;} +.avatar-border-two {width: 3.6rem; height: 3.6rem; background: #F5EBDE; position: absolute;} +.welcome-avatar {border: 2px solid #FBC962; position: absolute;} +.tile-amount {font-size: 32px; font-weight: 700; line-height: 56px; } diff --git a/module/block/js/create.ui.js b/module/block/js/create.ui.js index 92294d73a5..7a157fefdf 100644 --- a/module/block/js/create.ui.js +++ b/module/block/js/create.ui.js @@ -6,3 +6,27 @@ function getForm(event) const url = $.createLink('block', 'create', 'dashboard='+ dashboard +'&module=' + module + '&code=' + (code ? code : '')); loadPage(url, '#codesRow, #paramsRow'); } + +function onParamsTypeChange(event) +{ + const lang = config.clientLang; + const $code = document.querySelector('#code'); + + if($('#module').val() == 'scrumtest' && $('#paramstype').val() != 'all') + { + $('#title').val($code.options[$code.selectedIndex].text); + } + else + { + if(lang.indexOf('zh') >= 0) + { + const $paramstype = document.querySelector('#paramstype'); + const blockTitle = $paramstype.options[$paramstype.selectedIndex].text + of + $code.options[$code.selectedIndex].text; + $('#title').val(blockTitle); + } + else + { + /* TODO */ + } + } +} diff --git a/module/block/ui/create.html.php b/module/block/ui/create.html.php index 44c2807d3c..5f0836a951 100644 --- a/module/block/ui/create.html.php +++ b/module/block/ui/create.html.php @@ -13,8 +13,9 @@ namespace zin; set::title($title); jsVar('dashboard', $dashboard); +jsVar('of', $lang->block->of); -$paramsRows = array(); +$paramsRows = array(); $showModules = ($dashboard == 'my' and $modules); $showCodes = (($showModules and $module and $codes) or $dashboard != 'my'); @@ -28,6 +29,7 @@ foreach($params as $key => $row) set::value(zget($row, 'default', '')), set::control(array ( + 'id' => "params$key", 'type' => $row['control'], 'items' => isset($row['options']) ? $row['options'] : null )) @@ -38,10 +40,11 @@ form ( on::change('#module', 'getForm'), on::change('#code', 'getForm'), + on::change('#paramstype', 'onParamsTypeChange'), formGroup ( set::class($showModules ? '' : 'hidden'), - set::value($showModules ? $block : $dashboard), + set::value($showModules ? $code : $dashboard), set::label($lang->block->lblModule), set::name('module'), set::control($showModules ? array @@ -76,8 +79,8 @@ form ( set::label($lang->block->name), set::name('title'), + set::value(zget($codes, $code)), set::class('form-row'), - set::value(zget($modules, $module, '') . zget($codes, $code, '')), set::control('input') ), $paramsRows, diff --git a/module/block/ui/welcome.html.php b/module/block/ui/welcome.html.php new file mode 100644 index 0000000000..fea5226879 --- /dev/null +++ b/module/block/ui/welcome.html.php @@ -0,0 +1,146 @@ + +* @package block +* @link https://www.zentao.net +*/ + +namespace zin; + +panel +( + set('class', 'welcome-block'), + div + ( + setClass('flex'), + col + ( + setStyle(['width' => '20%', 'height' => '176px']), + set('class', 'border-right p-3'), + set('align', 'center'), + center + ( + set('class', 'font-bold'), + sprintf($lang->block->welcomeList[$welcomeType], $app->user->realname) + ), + center + ( + set('class', 'rounded-full avatar-border-one m-5'), + center + ( + set('class', 'rounded-full avatar-border-two'), + userAvatar + ( + set('size', 'lg'), + set('class', 'welcome-avatar'), + set('user', $this->app->user) + ) + ) + ) + ), + cell + ( + set('width', '45%'), + set('class', 'border-right p-3'), + div + ( + set('class', 'font-bold'), + '待我评审:' + ), + div + ( + setClass('flex items-center justify-around pt-6'), + center + ( + col + ( + set('justify', 'center'), + set('class', 'text-center'), + span + ( + set('class', 'tile-amount text-primary'), + 81 + ), + span('研发需求数') + ) + ), + center + ( + col + ( + set('justify', 'center'), + set('class', 'text-center'), + span + ( + set('class', 'tile-amount text-primary'), + 81 + ), + span('研发需求数') + ) + ), + center + ( + col + ( + set('justify', 'center'), + set('class', 'text-center'), + span + ( + set('class', 'tile-amount text-primary'), + 81 + ), + span('研发需求数') + ) + ) + ) + ), + cell + ( + set::width('35%'), + set('class', 'p-3'), + div + ( + set('class', 'font-bold'), + '待我评审:' + ), + div + ( + setClass('flex items-center justify-around pt-6'), + center + ( + col + ( + set('justify', 'center'), + set('class', 'text-center'), + span + ( + set('class', 'tile-amount text-primary'), + 81 + ), + span('研发需求数') + ) + ), + center + ( + col + ( + set('justify', 'center'), + set('class', 'text-center'), + span + ( + set('class', 'tile-amount text-primary'), + 81 + ), + span('研发需求数') + ) + ) + ) + ) + ) +); + +render(); diff --git a/module/block/zen.php b/module/block/zen.php index f0d5daf32c..78df03fe66 100644 --- a/module/block/zen.php +++ b/module/block/zen.php @@ -2,8 +2,8 @@ class blockZen extends block { /** - * Get module options when adding or editing blocks. * 添加或编辑区块时获取可使用的模块选项 + * Get module options when adding or editing blocks. * * @param string $dashboard * @access protected @@ -51,8 +51,8 @@ class blockZen extends block } /** - * Get block options when adding or editing blocks. * 添加或编辑区块时获取可使用的区块选项 + * Get block options when adding or editing blocks. * * @param string $dashboard * @param string $module @@ -112,12 +112,12 @@ class blockZen extends block } /** - * Get other form items when adding or editing blocks * 添加或编辑区块时获取其他表单项 + * Get other form items when adding or editing blocks * * @param string $dashboard * @param string $module - * @param string $block + * @param string $code * @access protected * @return array */ From f8270f6154667310e73f4552a07aa37a63c07395 Mon Sep 17 00:00:00 2001 From: xushenjie Date: Thu, 4 May 2023 07:27:15 +0000 Subject: [PATCH 16/20] * Adjust the unit test script for todoModel::create(). --- module/todo/test/model/create.php | 125 ++++++------------ .../todo/test/model/yaml/create/create.yaml | 22 +++ module/todo/test/todo.class.php | 33 +---- 3 files changed, 69 insertions(+), 111 deletions(-) create mode 100644 module/todo/test/model/yaml/create/create.yaml diff --git a/module/todo/test/model/create.php b/module/todo/test/model/create.php index 5fcaa8ac2e..bf9754648e 100755 --- a/module/todo/test/model/create.php +++ b/module/todo/test/model/create.php @@ -1,105 +1,62 @@ #!/usr/bin/env php id->range('1'); - $todo->name->prefix("待办")->range('1'); - $todo->date->range('`2023-04-23`'); - $todo->type->range('custom'); - $todo->gen(1, '', true); -} +su('admin'); /** title=测试 todoModel->create(); +timeout=0 cid=1 -pid=1 + +- 执行todoTest模块的createTest方法,参数是$todoWithoutName, $formData @0 + +- 执行todoTest模块的createTest方法,参数是$todoInvalidEnd, $formData @0 + +- 执行todoTest模块的createTest方法,参数是$todo, $formData @2 + +- 执行todoTest模块的createTest方法,参数是$todoWithCycle, $formData @3 */ -$accountList = array('admin', 'dev1', 'test1'); - -$b_noname = new stdclass(); -$b_noname->name = ''; -$b_noname->date = 'today'; -$b_noname->type = 'custom'; - -$todo1 = new stdclass(); -$todo1->name = '时间待定的月周期待办'; -$todo1->type = 'custom'; -$todo1->date = '+3 days'; -$todo1->config = array('day' => '', 'specify' => array('month' => 0, 'day' => 1), 'month' => array(1,3,5), 'type' => 'month', 'beforeDays' => 2, 'end' => '2025-01-01'); - -$todo2 = new stdclass(); -$todo2->name = 'bug待办'; -$todo2->type = 'bug'; -$todo2->date = 'today'; -$todo2->bug = '313'; -$todo2->status = 'doing'; -$todo2->uid = '313'; - -$todo3 = new stdclass(); -$todo3->name = 'task待办'; -$todo3->type = 'task'; -$todo3->date = 'today'; -$todo3->task = '1'; -$todo3->status = 'done'; -$todo3->uid = '1'; - -$todo4 = new stdclass(); -$todo4->name = 'story待办'; -$todo4->type = 'story'; -$todo4->date = 'today'; -$todo4->story = '1'; -$todo4->status = 'closed'; -$todo4->uid = '1'; - -$todo = new todoTest(); - global $tester; $tester->loadModel('todo'); -initData(); +zdTable('todo')->config('create')->gen(1); -$todoWithoutName = new stdclass; +$today = date('Y-m-d'); + +$formData = new stdClass; +$formData->rawdata = new stdclass; +$formData->rawdata->uid = ''; + +$todo = new stdclass; +$todo->name = 'TODO Create Test'; +$todo->account = 'admin'; +$todo->date = date('Y-m-d'); +$todo->type = 'custom'; +$todo->begin = '0800'; +$todo->end = '1700'; +$todo->assignedTo = 'admin'; + +$todoWithoutName = clone $todo; $todoWithoutName->name = ''; -$todoWithoutName->date = date('Y-m-d'); -$todoWithoutName->type = 'custom'; -$todoInvalidDate = new stdclass; -$todoInvalidDate->name = 'todoInvalidDate'; -$todoInvalidDate->date = 'today'; -$todoInvalidDate->type = 'custom'; +$todoInvalidEnd = clone $todo; +$todoInvalidEnd->name = 'todoInvalidDate'; +$todoInvalidEnd->begin = '1000'; +$todoInvalidEnd->end = '0800'; -$todoValid = new stdclass; -$todoValid->name = 'todoValid'; -$todoValid->date = date('Y-m-d'); -$todoValid->type = 'custom'; +$todoWithCycle = clone $todo; +$todoWithCycle->type = 'cycle'; +$todoWithCycle->cycle = 1; +$todoWithCycle->config = array('day' => 1, 'specify' => array('month' => 0, 'day' => 1), 'type' => 'day', 'beforeDays' => 1, 'end' => ''); +$todoWithCycle->objectID = 0; -$todoValid1 = new stdclass; -$todoValid1->name = 'todoValid1'; -$todoValid1->date = date('Y-m-d'); -$todoValid1->type = 'custom'; - -/** - * 1. 如果r函数返回的是一个复杂的结构,比如混合内容的数组或者嵌套的数组,p函数是无法获取返回值中的某些特定值的,需要自己编写助手函数,比如在../todo.class.php中编写。 - * 2. 如果ztf执行没有生成注释,需要检查php脚本是否执行报错,建议先使用php执行编写的测试用例再用ztf执行。 - */ -r($tester->todo->create($todoValid)) && p() && e('2'); -r($tester->todo->create($todoWithoutName)) && p() && e('0'); -r($tester->todo->create($todoInvalidDate)) && p() && e('0'); -r($tester->todo->create($todoValid1)) && p() && e('3'); -exit(0); - -r($todo->createTest($accountList[0], $b_noname)) && p() && e('『待办名称』不能为空。'); -r($todo->createTest($accountList[1], $todo1)) && p('name,type,status') && e('时间待定的月周期待办,custom,wait'); -r($todo->createTest($accountList[2], $todo2)) && p('name,type,status') && e('测试单转Bug13,bug,doing'); -r($todo->createTest($accountList[0], $todo3)) && p('name,type,status') && e('开发任务11,task,done'); -r($todo->createTest($accountList[0], $todo4)) && p('name,type,status') && e('用户需求1,story,closed'); +$todoTest = new todoTest(); +r($todoTest->createTest($todoWithoutName, $formData)) && p() && e('0'); +r($todoTest->createTest($todoInvalidEnd, $formData)) && p() && e('0'); +r($todoTest->createTest($todo, $formData)) && p() && e('2'); +r($todoTest->createTest($todoWithCycle, $formData)) && p() && e('3'); diff --git a/module/todo/test/model/yaml/create/create.yaml b/module/todo/test/model/yaml/create/create.yaml new file mode 100644 index 0000000000..363fb624d9 --- /dev/null +++ b/module/todo/test/model/yaml/create/create.yaml @@ -0,0 +1,22 @@ +title: Create todos for todoModel::create UTC. +desc: Create todos for todoModel::create UTC. +author: xushenjie +version: 1.0.0 + +fields: + - field: id + range: 1 + - field: account + range: 'admin' + - field: name + range: '待办' + - field: date + range: '`2023-04-23`' + - field: type + range: 'custom' + - field: begin + range: '0800' + - field: end + range: '1700' + - field: assignedTo + range: 'admin' diff --git a/module/todo/test/todo.class.php b/module/todo/test/todo.class.php index 9d8acb475a..346c1dd9da 100755 --- a/module/todo/test/todo.class.php +++ b/module/todo/test/todo.class.php @@ -12,37 +12,16 @@ class todoTest /** * Test create a todo. * - * @param string $account - * @param array $param + * @param object $todoData + * @param object $formData * @access public - * @return object + * @return int */ - public function createTest($account, $param = array()) + public function createTest($todoData, $formData) { - $config = array('day' => '', 'specify' => array('month' => 0, 'day' => 1), 'type' => 'day', 'beforeDays' => 0, 'end' => ''); - if(isset($param->date)) $param->date = $param->date == 'today' ? date('Y-m-d',time()) : date('Y-m-d',strtotime('+3 days')); + $objectID = $this->objectModel->create($todoData, $formData); - $createFields['config'] = $config; - $createFields['type'] = 'custom'; - $createFields['name'] = ''; - $createFields['pri'] = 3; - $createFields['desc'] = ''; - $createFields['status'] = 'wait'; - $createFields['begin'] = '0830'; - $createFields['end'] = '0900'; - - foreach($createFields as $field => $defaultValue) $_POST[$field] = $defaultValue; - - foreach($param as $key => $value) $_POST[$key] = $value; - - $objectID = $this->objectModel->create(date('Y').date('m'), $account); - - unset($_POST); - - if(dao::isError()) return array_values(dao::getError())[0][0]; - - $object = $objectID ? $this->objectModel->getByID($objectID) : 0; - return $object; + return $objectID ?: 0; } /** From ee1ca62e06db1fb60b0c086a107651e8e1aea330 Mon Sep 17 00:00:00 2001 From: caoyanyi Date: Thu, 4 May 2023 15:27:48 +0800 Subject: [PATCH 17/20] * Add unit test. --- module/project/model.php | 2 +- module/project/tao.php | 6 +-- .../test/tao/fetchmembercountbyidlist.php | 50 +++++++++++++++++++ test/data/user.yaml | 12 ++--- 4 files changed, 60 insertions(+), 10 deletions(-) create mode 100644 module/project/test/tao/fetchmembercountbyidlist.php diff --git a/module/project/model.php b/module/project/model.php index 7f36d3eb80..c2354d033b 100755 --- a/module/project/model.php +++ b/module/project/model.php @@ -248,7 +248,7 @@ class projectModel extends model if(empty($projects)) return array(); $projectIdList = array_keys($projects); - $teams = $this->projectTao->fetchTeamGroupByIdList($projectIdList); + $teams = $this->projectTao->fetchMemberCountByIdList($projectIdList); $estimates = $this->dao->select("t2.project as project, sum(estimate) as estimate")->from(TABLE_TASK)->alias('t1') ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.execution = t2.id') diff --git a/module/project/tao.php b/module/project/tao.php index 17d5567aed..e319836a87 100755 --- a/module/project/tao.php +++ b/module/project/tao.php @@ -573,14 +573,14 @@ class projectTao extends projectModel } /** - * 根据项目ID列表查询团队成员分组。 - * Get project team members by project id list. + * 根据项目ID列表查询团队成员数量。 + * Get project team member count by project id list. * * @param array $projectIdList * @access protected * @return array */ - protected function fetchTeamGroupByIdList(array $projectIdList): array + protected function fetchMemberCountByIdList(array $projectIdList): array { return $this->dao->select('t1.root, count(t1.id) as count')->from(TABLE_TEAM)->alias('t1') ->leftJoin(TABLE_USER)->alias('t2')->on('t1.account=t2.account') diff --git a/module/project/test/tao/fetchmembercountbyidlist.php b/module/project/test/tao/fetchmembercountbyidlist.php new file mode 100644 index 0000000000..20c8dbed9b --- /dev/null +++ b/module/project/test/tao/fetchmembercountbyidlist.php @@ -0,0 +1,50 @@ +#!/usr/bin/env php +id->range('11-19'); + $project->project->range('11-19'); + $project->name->prefix("项目")->range('11-19'); + $project->code->prefix("project")->range('11-19'); + $project->model->range("scrum"); + $project->auth->range("[]"); + $project->path->range("[]"); + $project->type->range("project"); + $project->grade->range("1"); + $project->days->range("1"); + $project->status->range("wait,doing,suspended,closed"); + $project->desc->range("[]"); + $project->budget->range("100000,200000"); + $project->budgetUnit->range("CNY"); + $project->percent->range("0-0"); + $project->openedDate->range("`2023-05-01 10:00:10`"); + $project->gen(9); + + zdTable('team')->gen(10); + zdTable('user')->gen(10); +} + +/** + +title=测试 projectModel::fetchProjectList(); +timeout=0 +cid=1 + + +*/ + +initData(); +$noneIDList = array(); +$wrongIDList = array('1', '2'); +$realIDList = array('11', '12'); + +global $tester; +$projectTester = $tester->loadModel('project'); +r($projectTester->fetchMemberCountByIdList($noneIDList)) && p() && e('0'); // 查询没有项目ID的情况 +r($projectTester->fetchMemberCountByIdList($wrongIDList)) && p() && e('0'); // 查询错误ID的情况 +r($projectTester->fetchMemberCountByIdList($realIDList)) && p('11:count') && e('1'); // 查询正常ID的情况 diff --git a/test/data/user.yaml b/test/data/user.yaml index 9170c716a7..bd2aa6dc32 100644 --- a/test/data/user.yaml +++ b/test/data/user.yaml @@ -26,7 +26,7 @@ fields: - field: account1 range: admin,user{99},test{100},dev{100},pm{100},po{100},td{100},pd{100},qd{100},top{100},outside{100},others{100},a,bb,ccc,qwuiadsd?!2as@#%$aasd~aj1!@#1 - field: account2 - range: [],1-99,1-100,1-100,1-100,1-100,1-100,1-100,1-100,1-100,1-100,1-100,[]{4} + range: "[],1-99,1-100,1-100,1-100,1-100,1-100,1-100,1-100,1-100,1-100,1-100,[]{4}" - field: password note: "密码" range: 123Qwe!@#{346} @@ -53,7 +53,7 @@ fields: - field: commiter1 range: admin,user{99},test{100},dev{100},pm{100},po{100},td{100},pd{100},qd{100},top{100},outside{100},others{100},a,bb,ccc,qwuiadsd?!2as@#%$aasd~aj1!@#1 - field: commiter2 - range: [],1-99,1-100,1-100,1-100,1-100,1-100,1-100,1-100,1-100,1-100,1-100,[]{4} + range: "[],1-99,1-100,1-100,1-100,1-100,1-100,1-100,1-100,1-100,1-100,1-100,[]{4}" - field: avatar note: "" range: "" @@ -78,7 +78,7 @@ fields: - field: email2 range: 1000-9999:2 - field: email3 - range: [@qq.com,@163.com,@gmail.com] + range: "[@qq.com,@163.com,@gmail.com]" - field: skype note: "Skype" range: Skype @@ -125,9 +125,8 @@ fields: note: "入职日期" range: "(M)-(w)" type: timestamp - prefix: "DateTime" postfix: "" - format: "YY/MM/DD" + format: "YY/MM/DD hh:mm:ss" - field: visits note: "访问次数" range: 0-10000:R @@ -154,7 +153,7 @@ fields: range: 1-10000 - field: locked note: "锁定时间" - range: 0 + range: "`2023-01-02 10:00:00`" - field: company note: "公司" range: 1 @@ -170,6 +169,7 @@ fields: range: 1-10000:R - field: scoreLevel note: "积分等级" + range: 0 - field: deleted note: "是否删除" range: 0 From a4d71abdb66d220729ad57b8132b2077eb81d048 Mon Sep 17 00:00:00 2001 From: jukui Date: Thu, 4 May 2023 15:31:37 +0800 Subject: [PATCH 18/20] * Modify getList function for todo model and optimized the code. --- module/todo/config.php | 16 ++++++++ module/todo/model.php | 84 +++--------------------------------------- module/todo/tao.php | 38 +++++++++++++++++++ 3 files changed, 60 insertions(+), 78 deletions(-) diff --git a/module/todo/config.php b/module/todo/config.php index c15fc11932..bc0123f58f 100644 --- a/module/todo/config.php +++ b/module/todo/config.php @@ -1,6 +1,7 @@ todo = new stdclass(); $config->todo->batchCreate = 8; @@ -49,3 +50,18 @@ $config->todo->sessionUri['bugList'] = 'qa'; $config->todo->sessionUri['taskList'] = 'execution'; $config->todo->sessionUri['storyList'] = 'product'; $config->todo->sessionUri['testtaskList'] = 'qa'; + +$config->todo->dateRange = array(); +$config->todo->dateRange['all'] = array('begin' => '1970-01-01', 'end' => '2109-01-01'); +$config->todo->dateRange['assignedtoother'] = array('begin' => '1970-01-01', 'end' => '2109-01-01'); +$config->todo->dateRange['today'] = array('begin' => date::today(), 'end' => date::today()); +$config->todo->dateRange['future'] = array('begin' => '2030-01-01', 'end' => '2030-01-01'); +$config->todo->dateRange['before'] = array('begin' => '1970-01-01', 'end' => date::today()); +$config->todo->dateRange['cycle'] = array('begin' => '', 'end' => ''); +$config->todo->dateRange['yesterday'] = array('begin' => date::yesterday(), 'end' => date::yesterday()); +$config->todo->dateRange['thisweek'] = array('begin' => date::getThisWeek()['begin'], 'end' => date::getThisWeek()['end']); +$config->todo->dateRange['lastweek'] = array('begin' => date::getLastWeek()['begin'], 'end' => date::getLastWeek()['end']); +$config->todo->dateRange['thismonth'] = array('begin' => date::getThisMonth()['begin'], 'end' => date::getThisMonth()['end']); +$config->todo->dateRange['lastmonth'] = array('begin' => date::getLastMonth()['begin'], 'end' => date::getLastMonth()['end']); +$config->todo->dateRange['thisseason'] = array('begin' => date::getThisSeason()['begin'], 'end' => date::getThisSeason()['end']); +$config->todo->dateRange['thisyear'] = array('begin' => date::getThisYear()['begin'], 'end' => date::getThisYear()['end']); diff --git a/module/todo/model.php b/module/todo/model.php index bd5c52a166..32e4a82464 100755 --- a/module/todo/model.php +++ b/module/todo/model.php @@ -272,93 +272,21 @@ class todoModel extends model * @param object $pager * @param string $orderBy * @access public - * @return void + * @return array */ - public function getList($type = 'today', $account = '', $status = 'all', $limit = 0, $pager = null, $orderBy="date, status, begin") + public function getList(string $type = 'today', string $account = '', string|array $status = 'all', int $limit = 0, object $pager = null, string $orderBy="date, status, begin"): array { $this->app->loadClass('date'); $todos = array(); $type = strtolower($type); - if($type == 'all' or $type == 'assignedtoother') - { - $begin = '1970-01-01'; - $end = '2109-01-01'; - } - elseif($type == 'today') - { - $begin = date::today(); - $end = $begin; - } - elseif($type == 'yesterday') - { - $begin = date::yesterday(); - $end = $begin; - } - elseif($type == 'thisweek') - { - extract(date::getThisWeek()); - } - elseif($type == 'lastweek') - { - extract(date::getLastWeek()); - } - elseif($type == 'thismonth') - { - extract(date::getThisMonth()); - } - elseif($type == 'lastmonth') - { - extract(date::getLastMonth()); - } - elseif($type == 'thisseason') - { - extract(date::getThisSeason()); - } - elseif($type == 'thisyear') - { - extract(date::getThisYear()); - } - elseif($type == 'future') - { - $begin = '2030-01-01'; - $end = $begin; - } - elseif($type == 'before') - { - $begin = '1970-01-01'; - $end = date::today(); - } - elseif($type == 'cycle') - { - $begin = $end = ''; - } - else - { - $begin = $end = $type; - } + $dateRange = $this->config->todo->dateRange[$type] ? $this->config->todo->dateRange[$type] : array('begin' => $type, 'end' => $type); + $begin = (string)$dateRange['begin']; + $end = (string)$dateRange['end']; if(empty($account)) $account = $this->app->user->account; - $stmt = $this->dao->select('*')->from(TABLE_TODO) - ->where('deleted')->eq('0') - ->andWhere('vision')->eq($this->config->vision) - ->beginIF($type == 'assignedtoother')->andWhere('account', true)->eq($account)->fi() - ->beginIF($type != 'assignedtoother')->andWhere('assignedTo', true)->eq($account)->fi() - ->orWhere('finishedBy')->eq($account) - ->orWhere('closedBy')->eq($account) - ->markRight(1) - ->beginIF($begin)->andWhere('date')->ge($begin)->fi() - ->beginIF($end)->andWhere('date')->le($end)->fi() - ->beginIF($status != 'all' and $status != 'undone')->andWhere('status')->in($status)->fi() - ->beginIF($status == 'undone')->andWhere('status')->notin('done,closed')->fi() - ->beginIF($type == 'cycle')->andWhere('cycle')->eq('1')->fi() - ->beginIF($type != 'cycle')->andWhere('cycle')->eq('0')->fi() - ->beginIF($type == 'assignedtoother')->andWhere('assignedTo')->notin(array($account, ''))->fi() - ->orderBy($orderBy) - ->beginIF($limit > 0)->limit($limit)->fi() - ->page($pager) - ->query(); + $stmt = $this->todoTao->getListQuery($type, $account, $status, $begin, $end, $pager, $limit, $orderBy); /* Set session. */ $sql = explode('WHERE', $this->dao->get()); diff --git a/module/todo/tao.php b/module/todo/tao.php index 228e71f606..bb6bcf7d18 100644 --- a/module/todo/tao.php +++ b/module/todo/tao.php @@ -388,4 +388,42 @@ class todoTao extends todoModel return $todo; } + + /** + * 构造待办列表查询语句。 + * Build query for todo list. + * + * @param string $type + * @param string $account + * @param string|array $status + * @param string $begin + * @param string $end + * @param object $pager + * @param int $limit + * @param string $orderBy + * @access protected + * @return object + */ + protected function getListQuery(string $type, string $account, array|string $status, string $begin, string $end, object $pager, int $limit, string $orderBy): object + { + return $this->dao->select('*')->from(TABLE_TODO) + ->where('deleted')->eq('0') + ->andWhere('vision')->eq($this->config->vision) + ->beginIF($type == 'assignedtoother')->andWhere('account', true)->eq($account)->fi() + ->beginIF($type != 'assignedtoother')->andWhere('assignedTo', true)->eq($account)->fi() + ->orWhere('finishedBy')->eq($account) + ->orWhere('closedBy')->eq($account) + ->markRight(1) + ->beginIF($begin)->andWhere('date')->ge($begin)->fi() + ->beginIF($end)->andWhere('date')->le($end)->fi() + ->beginIF($status != 'all' and $status != 'undone')->andWhere('status')->in($status)->fi() + ->beginIF($status == 'undone')->andWhere('status')->notin('done,closed')->fi() + ->beginIF($type == 'cycle')->andWhere('cycle')->eq('1')->fi() + ->beginIF($type != 'cycle')->andWhere('cycle')->eq('0')->fi() + ->beginIF($type == 'assignedtoother')->andWhere('assignedTo')->notin(array($account, ''))->fi() + ->orderBy($orderBy) + ->beginIF($limit > 0)->limit($limit)->fi() + ->page($pager) + ->query(); + } } From b8ff52ec86e290e9bd9270b8f0945794e88a1750 Mon Sep 17 00:00:00 2001 From: guofeilong Date: Thu, 4 May 2023 15:37:41 +0800 Subject: [PATCH 19/20] * Code for add space . --- module/project/config/form.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/module/project/config/form.php b/module/project/config/form.php index f54e198505..e3eb4978a9 100644 --- a/module/project/config/form.php +++ b/module/project/config/form.php @@ -37,8 +37,9 @@ $config->project->form->edit['acl'] = array('type' => 'string', 'required $config->project->form->edit['whitelist'] = array('type' => 'array', 'required' => false, 'default' => '', 'filter' => 'join'); $config->project->form->edit['auth'] = array('type' => 'array', 'required' => false, 'default' => ''); $config->project->form->edit['model'] = array('type' => 'string', 'required' => false, 'default' => ''); -$config->project->form->edit['plans'] = array('type' => 'array', 'required' => false, 'default' => ''); -$config->project->form->edit['products'] = array('type' => 'array', 'required' => false, 'default' => ''); +$config->project->form->edit['plans'] = array('type' => 'array', 'required' => false, 'default' => ''); +$config->project->form->edit['products'] = array('type' => 'array', 'required' => false, 'default' => ''); +$config->project->form->edit['product'] = array('type' => 'array', 'required' => false, 'default' => ''); $config->project->form->start['realBegan'] = array('type' => 'date', 'required' => true, 'filter' => 'trim'); From 468b7196bf0084f972ded78dd070014b898de284 Mon Sep 17 00:00:00 2001 From: xushenjie Date: Thu, 4 May 2023 07:48:31 +0000 Subject: [PATCH 20/20] * Split todoController:: batchCreate() function's display logic. --- module/todo/control.php | 34 ++++++++-------------------------- module/todo/zen.php | 27 +++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 26 deletions(-) diff --git a/module/todo/control.php b/module/todo/control.php index 2f7772537a..5254aa844a 100755 --- a/module/todo/control.php +++ b/module/todo/control.php @@ -73,15 +73,17 @@ class todo extends control } /** - * Batch create todo + * 批量创建待办。 + * Batch create todo. * * @param string $date * @access public * @return void */ - public function batchCreate($date = 'today') + public function batchCreate(string $date = 'today') { if($date == 'today') $date = date(DT_DATE1, time()); + if(!empty($_POST)) { $todoIDList = $this->todo->batchCreate(); @@ -89,37 +91,17 @@ class todo extends control /* Locate the browser. */ $date = str_replace('-', '', $this->post->date); - if($date == '') - { - $date = 'future'; - } - else if($date == date('Ymd')) - { - $date= 'today'; - } + if($date == '') $date = 'future'; + if($date == date('Ymd')) $date= 'today'; if($this->viewType == 'json') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'idList' => $todoIDList)); if(isonlybody()) return print(js::reload('parent.parent')); - return print(js::locate($this->createLink('my', 'todo', "type=$date"), 'parent')); + return print(js::locate($this->createLink('my', 'todo', "type={$date}"), 'parent')); } unset($this->lang->todo->typeList['cycle']); - /* Set Custom*/ - foreach(explode(',', $this->config->todo->list->customBatchCreateFields) as $field) $customFields[$field] = $this->lang->todo->$field; - - $this->view->customFields = $customFields; - $this->view->showFields = $this->config->todo->custom->batchCreateFields; - - $this->view->title = $this->lang->todo->common . $this->lang->colon . $this->lang->todo->batchCreate; - $this->view->position[] = $this->lang->todo->common; - $this->view->position[] = $this->lang->todo->batchCreate; - $this->view->date = (int)$date == 0 ? $date : date('Y-m-d', strtotime($date)); - $this->view->times = date::buildTimeList($this->config->todo->times->begin, $this->config->todo->times->end, $this->config->todo->times->delta); - $this->view->time = date::now(); - $this->view->users = $this->loadModel('user')->getPairs('noclosed|nodeleted|noempty'); - - $this->display(); + $this->todoZen->buildBatchCreateView($date); } /** diff --git a/module/todo/zen.php b/module/todo/zen.php index 48cf9b5754..25afbcd8df 100755 --- a/module/todo/zen.php +++ b/module/todo/zen.php @@ -22,6 +22,33 @@ class todoZen extends todo $this->display(); } + /** + * 生成批量创建待办视图数据。 + * Build batch create form data. + * + * @param string $date + * @access protected + * @return void + */ + protected function buildBatchCreateView(string $date) + { + /* Set Custom. */ + foreach(explode(',', $this->config->todo->list->customBatchCreateFields) as $field) $customFields[$field] = $this->lang->todo->$field; + + $this->view->customFields = $customFields; + $this->view->showFields = $this->config->todo->custom->batchCreateFields; + + $this->view->title = $this->lang->todo->common . $this->lang->colon . $this->lang->todo->batchCreate; + $this->view->position[] = $this->lang->todo->common; + $this->view->position[] = $this->lang->todo->batchCreate; + $this->view->date = (int)$date == 0 ? $date : date('Y-m-d', strtotime($date)); + $this->view->times = date::buildTimeList($this->config->todo->times->begin, $this->config->todo->times->end, $this->config->todo->times->delta); + $this->view->time = date::now(); + $this->view->users = $this->loadModel('user')->getPairs('noclosed|nodeleted|noempty'); + + $this->display(); + } + /** * 生成编辑待办视图数据。 * Build create form data.