From 306346820bf6d20f17876a71452929780656a3ae Mon Sep 17 00:00:00 2001 From: liugang Date: Fri, 13 Apr 2018 15:53:14 +0800 Subject: [PATCH] * Add report block and overview block. --- module/block/control.php | 153 ++++++++++++++++++++++- module/block/lang/en.php | 97 ++++++++------ module/block/lang/zh-cn.php | 101 +++++++++------ module/block/lang/zh-tw.php | 101 +++++++++------ module/block/model.php | 59 ++++++--- module/block/view/overviewblock.html.php | 17 +++ module/block/view/reportblock.html.php | 15 +++ module/block/view/set.html.php | 2 +- module/block/view/setmodule.html.php | 13 +- module/datatable/lang/zh-tw.php | 16 +-- module/product/control.php | 2 +- module/product/lang/zh-tw.php | 20 ++- module/product/model.php | 43 +++---- module/project/model.php | 2 +- module/search/lang/zh-tw.php | 2 +- module/story/lang/zh-tw.php | 2 +- 16 files changed, 455 insertions(+), 190 deletions(-) create mode 100644 module/block/view/overviewblock.html.php create mode 100644 module/block/view/reportblock.html.php diff --git a/module/block/control.php b/module/block/control.php index a8f6cb432b..db45cccc07 100644 --- a/module/block/control.php +++ b/module/block/control.php @@ -111,10 +111,10 @@ class block extends control $this->view->params = json_decode($params, true); } - $this->view->source = $source; - $this->view->type = $type; - $this->view->id = $id; - $this->view->block = ($block) ? $block : array(); + $this->view->source = $source; + $this->view->type = $type; + $this->view->id = $id; + $this->view->block = ($block) ? $block : array(); $this->display(); } @@ -621,7 +621,7 @@ class block extends control /** * Print releases block. - * + * * @access public * @return void */ @@ -642,7 +642,7 @@ class block extends control /** * Print Build block. - * + * * @access public * @return void */ @@ -687,6 +687,147 @@ class block extends control $this->view->productStats = $productStats; } + /** + * Print report block. + * + * @access public + * @return void + */ + public function printReportBlock() + { + if(!empty($this->params->type) and preg_match('/[^a-zA-Z0-9_]/', $this->params->type)) die(); + + $status = isset($this->params->type) ? $this->params->type : ''; + $orderBy = isset($this->params->type) ? $this->params->orderBy : 'id_asc'; + + /* Get products. */ + $products = $this->loadModel('product')->getList($status); + foreach($products as $productID => $product) + { + if(!$this->product->checkPriv($product)) unset($products[$productID]); + } + $productIDList = array_keys($products); + if(!$productIDList) + { + $this->view->products = $products; + return false; + } + $products = $this->dao->select('*')->from(TABLE_PRODUCT) + ->where('id')->in($productIDList) + ->orderBy($orderBy) + ->fetchAll('id'); + + /* Get stories. */ + $stories = $this->dao->select('product, stage, COUNT(status) AS count') + ->from(TABLE_STORY) + ->where('deleted')->eq(0) + ->andWhere('product')->in($productIDList) + ->groupBy('product, stage') + ->fetchGroup('product', 'stage'); + /* Padding the stories to sure all status have records. */ + foreach($stories as $product => $story) + { + foreach(array_keys($this->lang->story->stageList) as $stage) + { + $story[$stage] = isset($story[$stage]) ? $story[$stage]->count : 0; + } + $stories[$product] = $story; + } + + /* Get plans. */ + $plans = $this->dao->select('product, end')->from(TABLE_PRODUCTPLAN) + ->where('deleted')->eq(0) + ->andWhere('product')->in($productIDList) + ->fetchGroup('product'); + foreach($plans as $product => $productPlans) + { + $expired = 0; + $unexpired = 0; + + foreach($productPlans as $plan) + { + if($plan->end < helper::today()) $expired++; + if($plan->end >= helper::today()) $unexpired++; + } + + $plan = new stdclass; + $plan->expired = $expired; + $plan->unexpired = $unexpired; + + $plans[$product] = $plan; + } + + /* Get projects. */ + $projects = $this->dao->select('t1.product, t2.status, t2.end')->from(TABLE_PROJECTPRODUCT)->alias('t1') + ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project=t2.id') + ->where('t1.product')->in($productIDList) + ->andWhere('t2.deleted')->eq(0) + ->fetchGroup('product'); + foreach($projects as $product => $productProjects) + { + $doing = 0; + $done = 0; + $delay = 0; + + foreach($productProjects as $project) + { + if($project->status == 'doing') $doing++; + if($project->status == 'done' or $project->status == 'closed') $done++; + if($project->status != 'done' && $project->status != 'closed' && $project->status != 'suspended' && $project->end < helper::today()) $delay++; + } + + $project = new stdclass(); + $project->doing = $doing; + $project->done = $done; + $project->delay = $delay; + + $projects[$product] = $project; + } + + /* Get releases. */ + $releases = $this->dao->select('product, COUNT(*) AS count') + ->from(TABLE_RELEASE) + ->where('deleted')->eq(0) + ->andWhere('product')->in($productIDList) + ->groupBy('product') + ->fetchPairs(); + + foreach($products as $productID => $product) + { + $product->stories = isset($stories[$productID]) ? $stories[$productID] : 0; + $product->plans = isset($plans[$productID]) ? $plans[$productID] : 0; + $product->projects = isset($projects[$productID]) ? $projects[$productID] : 0; + $product->releases = isset($releases[$productID]) ? $releases[$productID] : 0; + } + + $this->view->products = $products; + } + + /** + * Print overview block. + * + * @access public + * @return void + */ + public function printOverviewBlock() + { + $normal = 0; + $closed = 0; + + $products = $this->loadModel('product')->getList(); + foreach($products as $product) + { + if(!$this->product->checkPriv($product)) continue; + + if($product->status == 'normal') $normal++; + if($product->status == 'closed') $closed++; + } + + $this->view->total = $normal + $closed; + $this->view->normal = $normal; + $this->view->closed = $closed; + } + /** * Print project block. * diff --git a/module/block/lang/en.php b/module/block/lang/en.php index 5c890c4459..8493ae604f 100644 --- a/module/block/lang/en.php +++ b/module/block/lang/en.php @@ -16,13 +16,13 @@ $lang->block->style = 'Style'; $lang->block->grid = 'Grid'; $lang->block->color = 'Color'; -$lang->block->account = 'Account'; -$lang->block->module = 'Module'; -$lang->block->title = 'Title'; -$lang->block->source = 'Source module'; -$lang->block->block = 'Source block'; -$lang->block->order = 'Order'; -$lang->block->height = 'Height'; +$lang->block->account = 'Account'; +$lang->block->module = 'Module'; +$lang->block->title = 'Title'; +$lang->block->source = 'Source module'; +$lang->block->block = 'Source block'; +$lang->block->order = 'Order'; +$lang->block->height = 'Height'; $lang->block->lblModule = 'Module'; $lang->block->lblBlock = 'Block'; @@ -56,20 +56,31 @@ $lang->block->refresh = 'Refresh'; $lang->block->hidden = 'Hide'; $lang->block->dynamicInfo = "%s, %s %s %s %s"; -$lang->block->default['product']['1']['title'] = 'Open ' . $lang->productCommon . 's'; -$lang->block->default['product']['1']['block'] = 'list'; +$lang->block->default['product']['1']['title'] = $lang->productCommon . ' Report'; +$lang->block->default['product']['1']['block'] = 'report'; $lang->block->default['product']['1']['grid'] = 8; -$lang->block->default['product']['1']['params']['num'] = 15; -$lang->block->default['product']['1']['params']['type'] = 'noclosed'; +$lang->block->default['product']['1']['params']['orderBy'] = 'id_desc'; +$lang->block->default['product']['1']['params']['type'] = 'noclosed'; -$lang->block->default['product']['2']['title'] = 'My Stories'; -$lang->block->default['product']['2']['block'] = 'story'; +$lang->block->default['product']['2']['title'] = $lang->productCommon . ' Overview'; +$lang->block->default['product']['2']['block'] = 'overview'; $lang->block->default['product']['2']['grid'] = 4; -$lang->block->default['product']['2']['params']['num'] = 15; -$lang->block->default['product']['2']['params']['orderBy'] = 'id_desc'; -$lang->block->default['product']['2']['params']['type'] = 'assignedTo'; +$lang->block->default['product']['3']['title'] = 'Open ' . $lang->productCommon . 's'; +$lang->block->default['product']['3']['block'] = 'list'; +$lang->block->default['product']['3']['grid'] = 8; + +$lang->block->default['product']['3']['params']['num'] = 15; +$lang->block->default['product']['3']['params']['type'] = 'noclosed'; + +$lang->block->default['product']['4']['title'] = 'My Stories'; +$lang->block->default['product']['4']['block'] = 'story'; +$lang->block->default['product']['4']['grid'] = 4; + +$lang->block->default['product']['4']['params']['num'] = 15; +$lang->block->default['product']['4']['params']['orderBy'] = 'id_desc'; +$lang->block->default['product']['4']['params']['type'] = 'assignedTo'; $lang->block->default['project']['1']['title'] = 'Active ' . $lang->projectCommon . 's'; $lang->block->default['project']['1']['block'] = 'list'; @@ -187,9 +198,9 @@ $lang->block->default['onlyTask']['my']['4'] = $lang->block->default['project'][ $lang->block->default['onlyTask']['my']['4']['source'] = 'project'; $lang->block->default['onlyTask']['my']['4']['grid'] = 6; -$lang->block->num = 'Number'; -$lang->block->type = 'Type'; -$lang->block->orderBy = 'Order by'; +$lang->block->num = 'Number'; +$lang->block->type = 'Type'; +$lang->block->orderBy = 'Order by'; $lang->block->availableBlocks = new stdclass(); @@ -212,16 +223,18 @@ $lang->block->moduleList['todo'] = 'Todo'; $lang->block->modules['product'] = new stdclass(); $lang->block->modules['product']->availableBlocks = new stdclass(); -$lang->block->modules['product']->availableBlocks->list = $lang->productCommon . 'List'; -$lang->block->modules['product']->availableBlocks->story = 'Stories'; -$lang->block->modules['product']->availableBlocks->plan = 'Plans'; -$lang->block->modules['product']->availableBlocks->release = 'Releases'; +$lang->block->modules['product']->availableBlocks->report = $lang->productCommon . ' Report'; +$lang->block->modules['product']->availableBlocks->overview = $lang->productCommon . ' Overview'; +$lang->block->modules['product']->availableBlocks->list = $lang->productCommon . 'List'; +$lang->block->modules['product']->availableBlocks->story = 'Stories'; +$lang->block->modules['product']->availableBlocks->plan = 'Plans'; +$lang->block->modules['product']->availableBlocks->release = 'Releases'; $lang->block->modules['project'] = new stdclass(); $lang->block->modules['project']->availableBlocks = new stdclass(); $lang->block->modules['project']->availableBlocks->list = $lang->projectCommon . 'List'; $lang->block->modules['project']->availableBlocks->task = 'Tasks'; $lang->block->modules['project']->availableBlocks->build = 'Builds'; -$lang->block->modules['qa'] = new stdclass(); +$lang->block->modules['qa'] = new stdclass(); $lang->block->modules['qa']->availableBlocks = new stdclass(); $lang->block->modules['qa']->availableBlocks->bug = 'Bugs'; $lang->block->modules['qa']->availableBlocks->case = 'Cases'; @@ -232,6 +245,12 @@ $lang->block->modules['todo']->availableBlocks->list = 'Todo'; $lang->block->orderByList = new stdclass(); +$lang->block->orderByList->product = array(); +$lang->block->orderByList->product['id_asc'] = 'ID Ascending'; +$lang->block->orderByList->product['id_desc'] = 'ID Descending'; +$lang->block->orderByList->product['status_asc'] = 'Status Ascending'; +$lang->block->orderByList->product['status_desc'] = 'Status Descending'; + $lang->block->orderByList->task = array(); $lang->block->orderByList->task['id_asc'] = 'ID Ascending'; $lang->block->orderByList->task['id_desc'] = 'ID Descending'; @@ -253,20 +272,20 @@ $lang->block->orderByList->bug['severity_asc'] = 'Severity Ascending'; $lang->block->orderByList->bug['severity_desc'] = 'Severity Descending'; $lang->block->orderByList->case = array(); -$lang->block->orderByList->case['id_asc'] = 'ID Ascending'; -$lang->block->orderByList->case['id_desc'] = 'ID Descending'; -$lang->block->orderByList->case['pri_asc'] = 'Priority Ascending'; -$lang->block->orderByList->case['pri_desc'] = 'Priority Descending'; +$lang->block->orderByList->case['id_asc'] = 'ID Ascending'; +$lang->block->orderByList->case['id_desc'] = 'ID Descending'; +$lang->block->orderByList->case['pri_asc'] = 'Priority Ascending'; +$lang->block->orderByList->case['pri_desc'] = 'Priority Descending'; $lang->block->orderByList->story = array(); -$lang->block->orderByList->story['id_asc'] = 'ID Ascending'; -$lang->block->orderByList->story['id_desc'] = 'ID Descending'; -$lang->block->orderByList->story['pri_asc'] = 'Priority Ascending'; -$lang->block->orderByList->story['pri_desc'] = 'Priority Descending'; -$lang->block->orderByList->story['status_asc'] = 'Status Ascending'; -$lang->block->orderByList->story['status_desc'] = 'Status Descending'; -$lang->block->orderByList->story['stage_asc'] = 'Stage Ascending'; -$lang->block->orderByList->story['stage_desc'] = 'Stage Descending'; +$lang->block->orderByList->story['id_asc'] = 'ID Ascending'; +$lang->block->orderByList->story['id_desc'] = 'ID Descending'; +$lang->block->orderByList->story['pri_asc'] = 'Priority Ascending'; +$lang->block->orderByList->story['pri_desc'] = 'Priority Descending'; +$lang->block->orderByList->story['status_asc'] = 'Status Ascending'; +$lang->block->orderByList->story['status_desc'] = 'Status Descending'; +$lang->block->orderByList->story['stage_asc'] = 'Stage Ascending'; +$lang->block->orderByList->story['stage_desc'] = 'Stage Descending'; $lang->block->todoNum = 'Todo Number'; $lang->block->taskNum = 'Task Number'; @@ -310,8 +329,8 @@ $lang->block->typeList->testtask['done'] = 'Done'; $lang->block->typeList->testtask['all'] = 'All'; $lang->block->modules['product']->moreLinkList = new stdclass(); -$lang->block->modules['product']->moreLinkList->list = 'product|all|product=&status=%s'; -$lang->block->modules['product']->moreLinkList->story = 'my|story|type=%s'; +$lang->block->modules['product']->moreLinkList->list = 'product|all|product=&status=%s'; +$lang->block->modules['product']->moreLinkList->story = 'my|story|type=%s'; $lang->block->modules['project']->moreLinkList = new stdclass(); $lang->block->modules['project']->moreLinkList->list = 'project|all|status=%s&project='; $lang->block->modules['project']->moreLinkList->task = 'my|task|type=%s'; @@ -334,7 +353,7 @@ $lang->block->gridOptions[8] = 'Left'; $lang->block->gridOptions[4] = 'Right'; $lang->block->flowchart = array(); -$lang->block->flowchart[] = array('Administration', 'Manage a Company', 'Add Users', 'Maintain Privileges'); +$lang->block->flowchart[] = array('Administration', 'Manage a Company', 'Add Users', 'Maintain Privileges'); $lang->block->flowchart[] = array($lang->productCommon . ' Manager', 'Add ' . $lang->productCommon, 'Maintain Modules', 'Maintain Plans', 'Maintain Stories', 'Create Release'); $lang->block->flowchart[] = array($lang->projectCommon . ' Manager', 'Add ' . $lang->projectCommon, 'Maintain Teams', 'Link ' . $lang->productCommon . 's', 'Link Stories', 'Decompose Tasks'); $lang->block->flowchart[] = array('DEV Team', 'Claim Tasks/Bugs', 'Update Status', 'Finish Tasks/Bugs'); diff --git a/module/block/lang/zh-cn.php b/module/block/lang/zh-cn.php index 0b6466a6a2..19864c430d 100644 --- a/module/block/lang/zh-cn.php +++ b/module/block/lang/zh-cn.php @@ -16,13 +16,13 @@ $lang->block->style = '外观'; $lang->block->grid = '位置'; $lang->block->color = '颜色'; -$lang->block->account = '所属用户'; -$lang->block->module = '所属模块'; -$lang->block->title = '区块名称'; -$lang->block->source = '来源模块'; -$lang->block->block = '来源区块'; -$lang->block->order = '排序'; -$lang->block->height = '高度'; +$lang->block->account = '所属用户'; +$lang->block->module = '所属模块'; +$lang->block->title = '区块名称'; +$lang->block->source = '来源模块'; +$lang->block->block = '来源区块'; +$lang->block->order = '排序'; +$lang->block->height = '高度'; $lang->block->lblModule = '模块'; $lang->block->lblBlock = '区块'; @@ -56,20 +56,31 @@ $lang->block->refresh = '刷新'; $lang->block->hidden = '隐藏'; $lang->block->dynamicInfo = "%s, %s %s %s %s"; -$lang->block->default['product']['1']['title'] = '未关闭的' . $lang->productCommon; -$lang->block->default['product']['1']['block'] = 'list'; +$lang->block->default['product']['1']['title'] = $lang->productCommon . '统计'; +$lang->block->default['product']['1']['block'] = 'report'; $lang->block->default['product']['1']['grid'] = 8; -$lang->block->default['product']['1']['params']['num'] = 15; -$lang->block->default['product']['1']['params']['type'] = 'noclosed'; +$lang->block->default['product']['1']['params']['orderBy'] = 'id_desc'; +$lang->block->default['product']['1']['params']['type'] = 'noclosed'; -$lang->block->default['product']['2']['title'] = '指派给我的需求'; -$lang->block->default['product']['2']['block'] = 'story'; +$lang->block->default['product']['2']['title'] = $lang->productCommon . '总览'; +$lang->block->default['product']['2']['block'] = 'overview'; $lang->block->default['product']['2']['grid'] = 4; -$lang->block->default['product']['2']['params']['num'] = 15; -$lang->block->default['product']['2']['params']['orderBy'] = 'id_desc'; -$lang->block->default['product']['2']['params']['type'] = 'assignedTo'; +$lang->block->default['product']['3']['title'] = '未关闭的' . $lang->productCommon; +$lang->block->default['product']['3']['block'] = 'list'; +$lang->block->default['product']['3']['grid'] = 8; + +$lang->block->default['product']['3']['params']['num'] = 15; +$lang->block->default['product']['3']['params']['type'] = 'noclosed'; + +$lang->block->default['product']['4']['title'] = '指派给我的需求'; +$lang->block->default['product']['4']['block'] = 'story'; +$lang->block->default['product']['4']['grid'] = 4; + +$lang->block->default['product']['4']['params']['num'] = 15; +$lang->block->default['product']['4']['params']['orderBy'] = 'id_desc'; +$lang->block->default['product']['4']['params']['type'] = 'assignedTo'; $lang->block->default['project']['1']['title'] = '进行中的' . $lang->projectCommon; $lang->block->default['project']['1']['block'] = 'list'; @@ -187,9 +198,9 @@ $lang->block->default['onlyTask']['my']['4'] = $lang->block->default['project'][ $lang->block->default['onlyTask']['my']['4']['source'] = 'project'; $lang->block->default['onlyTask']['my']['4']['grid'] = 6; -$lang->block->num = '数量'; -$lang->block->type = '类型'; -$lang->block->orderBy = '排序'; +$lang->block->num = '数量'; +$lang->block->type = '类型'; +$lang->block->orderBy = '排序'; $lang->block->availableBlocks = new stdclass(); @@ -212,16 +223,18 @@ $lang->block->moduleList['todo'] = '待办'; $lang->block->modules['product'] = new stdclass(); $lang->block->modules['product']->availableBlocks = new stdclass(); -$lang->block->modules['product']->availableBlocks->list = $lang->productCommon . '列表'; -$lang->block->modules['product']->availableBlocks->story = '需求列表'; -$lang->block->modules['product']->availableBlocks->plan = '计划列表'; -$lang->block->modules['product']->availableBlocks->release = '发布列表'; +$lang->block->modules['product']->availableBlocks->report = $lang->productCommon . '统计'; +$lang->block->modules['product']->availableBlocks->overview = $lang->productCommon . '总览'; +$lang->block->modules['product']->availableBlocks->list = $lang->productCommon . '列表'; +$lang->block->modules['product']->availableBlocks->story = '需求列表'; +$lang->block->modules['product']->availableBlocks->plan = '计划列表'; +$lang->block->modules['product']->availableBlocks->release = '发布列表'; $lang->block->modules['project'] = new stdclass(); $lang->block->modules['project']->availableBlocks = new stdclass(); $lang->block->modules['project']->availableBlocks->list = $lang->projectCommon . '列表'; $lang->block->modules['project']->availableBlocks->task = '任务列表'; $lang->block->modules['project']->availableBlocks->build = '版本列表'; -$lang->block->modules['qa'] = new stdclass(); +$lang->block->modules['qa'] = new stdclass(); $lang->block->modules['qa']->availableBlocks = new stdclass(); $lang->block->modules['qa']->availableBlocks->bug = 'Bug列表'; $lang->block->modules['qa']->availableBlocks->case = '用例列表'; @@ -232,6 +245,12 @@ $lang->block->modules['todo']->availableBlocks->list = '待办列表'; $lang->block->orderByList = new stdclass(); +$lang->block->orderByList->product = array(); +$lang->block->orderByList->product['id_asc'] = 'ID 递增'; +$lang->block->orderByList->product['id_desc'] = 'ID 递减'; +$lang->block->orderByList->product['status_asc'] = '状态正序'; +$lang->block->orderByList->product['status_desc'] = '状态倒序'; + $lang->block->orderByList->task = array(); $lang->block->orderByList->task['id_asc'] = 'ID 递增'; $lang->block->orderByList->task['id_desc'] = 'ID 递减'; @@ -253,20 +272,20 @@ $lang->block->orderByList->bug['severity_asc'] = '级别递增'; $lang->block->orderByList->bug['severity_desc'] = '级别递减'; $lang->block->orderByList->case = array(); -$lang->block->orderByList->case['id_asc'] = 'ID 递增'; -$lang->block->orderByList->case['id_desc'] = 'ID 递减'; -$lang->block->orderByList->case['pri_asc'] = '优先级递增'; -$lang->block->orderByList->case['pri_desc'] = '优先级递减'; +$lang->block->orderByList->case['id_asc'] = 'ID 递增'; +$lang->block->orderByList->case['id_desc'] = 'ID 递减'; +$lang->block->orderByList->case['pri_asc'] = '优先级递增'; +$lang->block->orderByList->case['pri_desc'] = '优先级递减'; $lang->block->orderByList->story = array(); -$lang->block->orderByList->story['id_asc'] = 'ID 递增'; -$lang->block->orderByList->story['id_desc'] = 'ID 递减'; -$lang->block->orderByList->story['pri_asc'] = '优先级递增'; -$lang->block->orderByList->story['pri_desc'] = '优先级递减'; -$lang->block->orderByList->story['status_asc'] = '状态正序'; -$lang->block->orderByList->story['status_desc'] = '状态倒序'; -$lang->block->orderByList->story['stage_asc'] = '阶段正序'; -$lang->block->orderByList->story['stage_desc'] = '阶段倒序'; +$lang->block->orderByList->story['id_asc'] = 'ID 递增'; +$lang->block->orderByList->story['id_desc'] = 'ID 递减'; +$lang->block->orderByList->story['pri_asc'] = '优先级递增'; +$lang->block->orderByList->story['pri_desc'] = '优先级递减'; +$lang->block->orderByList->story['status_asc'] = '状态正序'; +$lang->block->orderByList->story['status_desc'] = '状态倒序'; +$lang->block->orderByList->story['stage_asc'] = '阶段正序'; +$lang->block->orderByList->story['stage_desc'] = '阶段倒序'; $lang->block->todoNum = '待办数'; $lang->block->taskNum = '任务数'; @@ -310,11 +329,11 @@ $lang->block->typeList->testtask['done'] = '已测版本'; $lang->block->typeList->testtask['all'] = '全部'; $lang->block->modules['product']->moreLinkList = new stdclass(); -$lang->block->modules['product']->moreLinkList->list = 'product|all|product=&status=%s'; -$lang->block->modules['product']->moreLinkList->story = 'my|story|type=%s'; +$lang->block->modules['product']->moreLinkList->list = 'product|all|product=&status=%s'; +$lang->block->modules['product']->moreLinkList->story = 'my|story|type=%s'; $lang->block->modules['project']->moreLinkList = new stdclass(); -$lang->block->modules['project']->moreLinkList->list = 'project|all|status=%s&project='; -$lang->block->modules['project']->moreLinkList->task = 'my|task|type=%s'; +$lang->block->modules['project']->moreLinkList->list = 'project|all|status=%s&project='; +$lang->block->modules['project']->moreLinkList->task = 'my|task|type=%s'; $lang->block->modules['qa']->moreLinkList = new stdclass(); $lang->block->modules['qa']->moreLinkList->bug = 'my|bug|type=%s'; $lang->block->modules['qa']->moreLinkList->case = 'my|testcase|type=%s'; @@ -334,7 +353,7 @@ $lang->block->gridOptions[8] = '左侧'; $lang->block->gridOptions[4] = '右侧'; $lang->block->flowchart = array(); -$lang->block->flowchart[] = array('管理员', '维护公司', '添加用户', '维护权限'); +$lang->block->flowchart[] = array('管理员', '维护公司', '添加用户', '维护权限'); $lang->block->flowchart[] = array($lang->productCommon . '经理', '创建' . $lang->productCommon, '维护模块', '维护计划', '维护需求', '创建发布'); $lang->block->flowchart[] = array($lang->projectCommon . '经理', '创建' . $lang->projectCommon, '维护团队', '关联' . $lang->productCommon, '关联需求', '分解任务'); $lang->block->flowchart[] = array('研发人员', '领取任务和Bug', '更新状态', '完成任务和Bug'); diff --git a/module/block/lang/zh-tw.php b/module/block/lang/zh-tw.php index c675271ed0..f0d3f7f8d2 100644 --- a/module/block/lang/zh-tw.php +++ b/module/block/lang/zh-tw.php @@ -16,13 +16,13 @@ $lang->block->style = '外觀'; $lang->block->grid = '位置'; $lang->block->color = '顏色'; -$lang->block->account = '所屬用戶'; -$lang->block->module = '所屬模組'; -$lang->block->title = '區塊名稱'; -$lang->block->source = '來源模組'; -$lang->block->block = '來源區塊'; -$lang->block->order = '排序'; -$lang->block->height = '高度'; +$lang->block->account = '所屬用戶'; +$lang->block->module = '所屬模組'; +$lang->block->title = '區塊名稱'; +$lang->block->source = '來源模組'; +$lang->block->block = '來源區塊'; +$lang->block->order = '排序'; +$lang->block->height = '高度'; $lang->block->lblModule = '模組'; $lang->block->lblBlock = '區塊'; @@ -56,20 +56,31 @@ $lang->block->refresh = '刷新'; $lang->block->hidden = '隱藏'; $lang->block->dynamicInfo = "%s, %s %s %s %s"; -$lang->block->default['product']['1']['title'] = '未關閉的' . $lang->productCommon; -$lang->block->default['product']['1']['block'] = 'list'; +$lang->block->default['product']['1']['title'] = $lang->productCommon . '統計'; +$lang->block->default['product']['1']['block'] = 'report'; $lang->block->default['product']['1']['grid'] = 8; -$lang->block->default['product']['1']['params']['num'] = 15; -$lang->block->default['product']['1']['params']['type'] = 'noclosed'; +$lang->block->default['product']['1']['params']['orderBy'] = 'id_desc'; +$lang->block->default['product']['1']['params']['type'] = 'noclosed'; -$lang->block->default['product']['2']['title'] = '指派給我的需求'; -$lang->block->default['product']['2']['block'] = 'story'; +$lang->block->default['product']['2']['title'] = $lang->productCommon . '總覽'; +$lang->block->default['product']['2']['block'] = 'overview'; $lang->block->default['product']['2']['grid'] = 4; -$lang->block->default['product']['2']['params']['num'] = 15; -$lang->block->default['product']['2']['params']['orderBy'] = 'id_desc'; -$lang->block->default['product']['2']['params']['type'] = 'assignedTo'; +$lang->block->default['product']['3']['title'] = '未關閉的' . $lang->productCommon; +$lang->block->default['product']['3']['block'] = 'list'; +$lang->block->default['product']['3']['grid'] = 8; + +$lang->block->default['product']['3']['params']['num'] = 15; +$lang->block->default['product']['3']['params']['type'] = 'noclosed'; + +$lang->block->default['product']['4']['title'] = '指派給我的需求'; +$lang->block->default['product']['4']['block'] = 'story'; +$lang->block->default['product']['4']['grid'] = 4; + +$lang->block->default['product']['4']['params']['num'] = 15; +$lang->block->default['product']['4']['params']['orderBy'] = 'id_desc'; +$lang->block->default['product']['4']['params']['type'] = 'assignedTo'; $lang->block->default['project']['1']['title'] = '進行中的' . $lang->projectCommon; $lang->block->default['project']['1']['block'] = 'list'; @@ -187,9 +198,9 @@ $lang->block->default['onlyTask']['my']['4'] = $lang->block->default['project'][ $lang->block->default['onlyTask']['my']['4']['source'] = 'project'; $lang->block->default['onlyTask']['my']['4']['grid'] = 6; -$lang->block->num = '數量'; -$lang->block->type = '類型'; -$lang->block->orderBy = '排序'; +$lang->block->num = '數量'; +$lang->block->type = '類型'; +$lang->block->orderBy = '排序'; $lang->block->availableBlocks = new stdclass(); @@ -212,16 +223,18 @@ $lang->block->moduleList['todo'] = '待辦'; $lang->block->modules['product'] = new stdclass(); $lang->block->modules['product']->availableBlocks = new stdclass(); -$lang->block->modules['product']->availableBlocks->list = $lang->productCommon . '列表'; -$lang->block->modules['product']->availableBlocks->story = '需求列表'; -$lang->block->modules['product']->availableBlocks->plan = '計劃列表'; -$lang->block->modules['product']->availableBlocks->release = '發佈列表'; +$lang->block->modules['product']->availableBlocks->report = $lang->productCommon . '統計'; +$lang->block->modules['product']->availableBlocks->overview = $lang->productCommon . '總覽'; +$lang->block->modules['product']->availableBlocks->list = $lang->productCommon . '列表'; +$lang->block->modules['product']->availableBlocks->story = '需求列表'; +$lang->block->modules['product']->availableBlocks->plan = '計劃列表'; +$lang->block->modules['product']->availableBlocks->release = '發佈列表'; $lang->block->modules['project'] = new stdclass(); $lang->block->modules['project']->availableBlocks = new stdclass(); $lang->block->modules['project']->availableBlocks->list = $lang->projectCommon . '列表'; $lang->block->modules['project']->availableBlocks->task = '任務列表'; $lang->block->modules['project']->availableBlocks->build = '版本列表'; -$lang->block->modules['qa'] = new stdclass(); +$lang->block->modules['qa'] = new stdclass(); $lang->block->modules['qa']->availableBlocks = new stdclass(); $lang->block->modules['qa']->availableBlocks->bug = 'Bug列表'; $lang->block->modules['qa']->availableBlocks->case = '用例列表'; @@ -232,6 +245,12 @@ $lang->block->modules['todo']->availableBlocks->list = '待辦列表'; $lang->block->orderByList = new stdclass(); +$lang->block->orderByList->product = array(); +$lang->block->orderByList->product['id_asc'] = 'ID 遞增'; +$lang->block->orderByList->product['id_desc'] = 'ID 遞減'; +$lang->block->orderByList->product['status_asc'] = '狀態正序'; +$lang->block->orderByList->product['status_desc'] = '狀態倒序'; + $lang->block->orderByList->task = array(); $lang->block->orderByList->task['id_asc'] = 'ID 遞增'; $lang->block->orderByList->task['id_desc'] = 'ID 遞減'; @@ -253,20 +272,20 @@ $lang->block->orderByList->bug['severity_asc'] = '級別遞增'; $lang->block->orderByList->bug['severity_desc'] = '級別遞減'; $lang->block->orderByList->case = array(); -$lang->block->orderByList->case['id_asc'] = 'ID 遞增'; -$lang->block->orderByList->case['id_desc'] = 'ID 遞減'; -$lang->block->orderByList->case['pri_asc'] = '優先順序遞增'; -$lang->block->orderByList->case['pri_desc'] = '優先順序遞減'; +$lang->block->orderByList->case['id_asc'] = 'ID 遞增'; +$lang->block->orderByList->case['id_desc'] = 'ID 遞減'; +$lang->block->orderByList->case['pri_asc'] = '優先順序遞增'; +$lang->block->orderByList->case['pri_desc'] = '優先順序遞減'; $lang->block->orderByList->story = array(); -$lang->block->orderByList->story['id_asc'] = 'ID 遞增'; -$lang->block->orderByList->story['id_desc'] = 'ID 遞減'; -$lang->block->orderByList->story['pri_asc'] = '優先順序遞增'; -$lang->block->orderByList->story['pri_desc'] = '優先順序遞減'; -$lang->block->orderByList->story['status_asc'] = '狀態正序'; -$lang->block->orderByList->story['status_desc'] = '狀態倒序'; -$lang->block->orderByList->story['stage_asc'] = '階段正序'; -$lang->block->orderByList->story['stage_desc'] = '階段倒序'; +$lang->block->orderByList->story['id_asc'] = 'ID 遞增'; +$lang->block->orderByList->story['id_desc'] = 'ID 遞減'; +$lang->block->orderByList->story['pri_asc'] = '優先順序遞增'; +$lang->block->orderByList->story['pri_desc'] = '優先順序遞減'; +$lang->block->orderByList->story['status_asc'] = '狀態正序'; +$lang->block->orderByList->story['status_desc'] = '狀態倒序'; +$lang->block->orderByList->story['stage_asc'] = '階段正序'; +$lang->block->orderByList->story['stage_desc'] = '階段倒序'; $lang->block->todoNum = '待辦數'; $lang->block->taskNum = '任務數'; @@ -310,11 +329,11 @@ $lang->block->typeList->testtask['done'] = '已測版本'; $lang->block->typeList->testtask['all'] = '全部'; $lang->block->modules['product']->moreLinkList = new stdclass(); -$lang->block->modules['product']->moreLinkList->list = 'product|all|product=&status=%s'; -$lang->block->modules['product']->moreLinkList->story = 'my|story|type=%s'; +$lang->block->modules['product']->moreLinkList->list = 'product|all|product=&status=%s'; +$lang->block->modules['product']->moreLinkList->story = 'my|story|type=%s'; $lang->block->modules['project']->moreLinkList = new stdclass(); -$lang->block->modules['project']->moreLinkList->list = 'project|all|status=%s&project='; -$lang->block->modules['project']->moreLinkList->task = 'my|task|type=%s'; +$lang->block->modules['project']->moreLinkList->list = 'project|all|status=%s&project='; +$lang->block->modules['project']->moreLinkList->task = 'my|task|type=%s'; $lang->block->modules['qa']->moreLinkList = new stdclass(); $lang->block->modules['qa']->moreLinkList->bug = 'my|bug|type=%s'; $lang->block->modules['qa']->moreLinkList->case = 'my|testcase|type=%s'; @@ -334,7 +353,7 @@ $lang->block->gridOptions[8] = '左側'; $lang->block->gridOptions[4] = '右側'; $lang->block->flowchart = array(); -$lang->block->flowchart[] = array('管理員', '維護公司', '添加用戶', '維護權限'); +$lang->block->flowchart[] = array('管理員', '維護公司', '添加用戶', '維護權限'); $lang->block->flowchart[] = array($lang->productCommon . '經理', '創建' . $lang->productCommon, '維護模組', '維護計劃', '維護需求', '創建發佈'); $lang->block->flowchart[] = array($lang->projectCommon . '經理', '創建' . $lang->projectCommon, '維護團隊', '關聯' . $lang->productCommon, '關聯需求', '分解任務'); $lang->block->flowchart[] = array('研發人員', '領取任務和Bug', '更新狀態', '完成任務和Bug'); diff --git a/module/block/model.php b/module/block/model.php index 20054b403a..223713e21a 100644 --- a/module/block/model.php +++ b/module/block/model.php @@ -198,7 +198,7 @@ class blockModel extends model * * @param string $module * @access public - * @return void + * @return string */ public function getListParams($module = '') { @@ -206,7 +206,7 @@ class blockModel extends model if($module == 'project') return $this->getProjectParams($module); $params = new stdclass(); - $params = $this->onlyNumParams($module, $params); + $params = $this->onlyNumParams($params); return json_encode($params); } @@ -348,9 +348,9 @@ class blockModel extends model * @access public * @return json */ - public function getPlanParams($module = '') + public function getPlanParams() { - $params = $this->onlyNumParams($module); + $params = $this->onlyNumParams(); return json_encode($params); } @@ -360,9 +360,9 @@ class blockModel extends model * @access public * @return json */ - public function getReleaseParams($module = '') + public function getReleaseParams() { - $params = $this->onlyNumParams($module); + $params = $this->onlyNumParams(); return json_encode($params); } @@ -372,9 +372,9 @@ class blockModel extends model * @access public * @return json */ - public function getBuildParams($module = '') + public function getBuildParams() { - $params = $this->onlyNumParams($module); + $params = $this->onlyNumParams(); return json_encode($params); } @@ -384,13 +384,45 @@ class blockModel extends model * @access public * @return json */ - public function getProductParams($module = '') + public function getProductParams() { $params->type['name'] = $this->lang->block->type; $params->type['options'] = $this->lang->block->typeList->product; $params->type['control'] = 'select'; - return json_encode($this->onlyNumParams($module, $params)); + return json_encode($this->onlyNumParams($params)); + } + + /** + * Get product report params. + * + * @access public + * @return string + */ + public function getReportParams() + { + $params = new stdclass(); + $params->type['name'] = $this->lang->block->type; + $params->type['options'] = $this->lang->block->typeList->product; + $params->type['control'] = 'select'; + + $params->orderBy['name'] = $this->lang->block->orderBy; + $params->orderBy['default'] = 'id_desc'; + $params->orderBy['options'] = $this->lang->block->orderByList->product; + $params->orderBy['control'] = 'select'; + + return json_encode($params); + } + + /** + * Get product overview pararms. + * + * @access public + * @return string + */ + public function getOverviewParams() + { + return false; } /** @@ -399,13 +431,13 @@ class blockModel extends model * @access public * @return json */ - public function getProjectParams($module = '') + public function getProjectParams() { $params->type['name'] = $this->lang->block->type; $params->type['options'] = $this->lang->block->typeList->project; $params->type['control'] = 'select'; - return json_encode($this->onlyNumParams($module, $params)); + return json_encode($this->onlyNumParams($params)); } public function getAssignToMeParams() @@ -461,12 +493,11 @@ class blockModel extends model /** * Build number params. * - * @param string $module * @param object $params * @access public * @return object */ - public function onlyNumParams($module = '', $params = '') + public function onlyNumParams($params = '') { if(empty($params)) $params = new stdclass(); $params->num['name'] = $this->lang->block->num; diff --git a/module/block/view/overviewblock.html.php b/module/block/view/overviewblock.html.php new file mode 100644 index 0000000000..024c4cd10b --- /dev/null +++ b/module/block/view/overviewblock.html.php @@ -0,0 +1,17 @@ + + * @package block + * @version $Id$ + * @link http://www.zentao.net + */ +?> +
+product->all . $total;?> +product->statusList['normal'] . $normal;?> +product->statusList['closed'] . $closed;?> +
diff --git a/module/block/view/reportblock.html.php b/module/block/view/reportblock.html.php new file mode 100644 index 0000000000..405a68b10f --- /dev/null +++ b/module/block/view/reportblock.html.php @@ -0,0 +1,15 @@ + + * @package block + * @version $Id$ + * @link http://www.zentao.net + */ +?> +
+ +
diff --git a/module/block/view/set.html.php b/module/block/view/set.html.php index 4ba840919a..6126c66360 100644 --- a/module/block/view/set.html.php +++ b/module/block/view/set.html.php @@ -11,7 +11,7 @@ */ ?> createLink('block', 'set', "id=$id&type=$type&source=$source"));?> + $param):?>
@@ -28,7 +29,7 @@ $themeRoot = $webRoot . "theme/"; $control = $param['control']; $attr = empty($param['attr']) ? '' : $param['attr']; $default = $block ? (isset($block->params->$key) ? $block->params->$key : '') : (isset($param['default']) ? $param['default'] : ''); - $options = isset($param['options']) ? $param['options'] : array(); + $options = isset($param['options']) ? $param['options'] : array(); if($control == 'select' or $control == 'radio' or $control == 'checkbox') { $chosen = $control == 'select' ? 'chosen' : ''; @@ -49,12 +50,18 @@ $themeRoot = $webRoot . "theme/";
+ name)):?> diff --git a/module/datatable/lang/zh-tw.php b/module/datatable/lang/zh-tw.php index 73e2a69142..e879e1c042 100644 --- a/module/datatable/lang/zh-tw.php +++ b/module/datatable/lang/zh-tw.php @@ -6,14 +6,14 @@ $lang->datatable->show = '顯示'; $lang->datatable->hide = '隱藏'; $lang->datatable->reset = '恢復預設'; -$lang->datatable->custom = '自定義列'; -$lang->datatable->customTip = '勾選需要顯示的列'; -$lang->datatable->switchToTable = '切換到簡單表格'; -$lang->datatable->switchToDatatable = '切換到高級表格'; -$lang->datatable->required = '必選'; -$lang->datatable->confirmReset = '是否恢復預設設置?'; -$lang->datatable->setGlobal = '全局'; -$lang->datatable->resetGlobal = '全局恢復預設'; +$lang->datatable->custom = '自定義列'; +$lang->datatable->customTip = '勾選需要顯示的列'; +$lang->datatable->table = '簡單表格'; +$lang->datatable->datatable = '高級表格'; +$lang->datatable->required = '必選'; +$lang->datatable->confirmReset = '是否恢復預設設置?'; +$lang->datatable->setGlobal = '全局'; +$lang->datatable->resetGlobal = '全局恢復預設'; $lang->datatable->branch = '分支'; $lang->datatable->platform = '平台'; diff --git a/module/product/control.php b/module/product/control.php index 6ad8a3d421..ffd5ab4fdd 100644 --- a/module/product/control.php +++ b/module/product/control.php @@ -390,7 +390,7 @@ class product extends control { $this->product->setMenu($this->products, $productID); - $product = $this->product->getStatByID($productID); + $product = $this->product->getStatByID($productID); $product->desc = $this->loadModel('file')->setImgSize($product->desc); if(!$product) die(js::error($this->lang->notFound) . js::locate('back')); diff --git a/module/product/lang/zh-tw.php b/module/product/lang/zh-tw.php index 0d5d6113ac..3c6dc12185 100644 --- a/module/product/lang/zh-tw.php +++ b/module/product/lang/zh-tw.php @@ -114,20 +114,16 @@ $lang->product->storySummary = "本頁共 %s 個需求,預 $lang->product->checkedSummary = "選中 %total% 個需求,預計 %estimate% 個工時,用例覆蓋率%rate%。"; $lang->product->noMatched = '找不到包含"%s"的' . $lang->productCommon; - - - - -$lang->product->featureBar['browse']['unclosed'] = $lang->product->unclosed; -$lang->product->featureBar['browse']['unplan'] = $lang->product->unplan; $lang->product->featureBar['browse']['allstory'] = $lang->product->allStory; +$lang->product->featureBar['browse']['unclosed'] = $lang->product->unclosed; $lang->product->featureBar['browse']['assignedtome'] = $lang->product->assignedToMe; $lang->product->featureBar['browse']['openedbyme'] = $lang->product->openedByMe; $lang->product->featureBar['browse']['reviewedbyme'] = $lang->product->reviewedByMe; - -$lang->product->featureBar['browse']['closedbyme'] = $lang->product->closedByMe; $lang->product->featureBar['browse']['draftstory'] = $lang->product->draftStory; -$lang->product->featureBar['browse']['activestory'] = $lang->product->activeStory; -$lang->product->featureBar['browse']['changedstory'] = $lang->product->changedStory; -$lang->product->featureBar['browse']['willclose'] = $lang->product->willClose; -$lang->product->featureBar['browse']['closedstory'] = $lang->product->closedStory; +$lang->product->featureBar['browse']['more'] = $lang->more; + +$lang->product->moreSelects['closedbyme'] = $lang->product->closedByMe; +$lang->product->moreSelects['activestory'] = $lang->product->activeStory; +$lang->product->moreSelects['changedstory'] = $lang->product->changedStory; +$lang->product->moreSelects['willclose'] = $lang->product->willClose; +$lang->product->moreSelects['closedstory'] = $lang->product->closedStory; diff --git a/module/product/model.php b/module/product/model.php index bdef15a55d..358811d185 100644 --- a/module/product/model.php +++ b/module/product/model.php @@ -720,7 +720,6 @@ class productModel extends model ->page($pager) ->fetchAll('id'); - $stats = array(); $stories = $this->dao->select('product, status, count(status) AS count') ->from(TABLE_STORY) ->where('deleted')->eq(0) @@ -761,33 +760,35 @@ class productModel extends model ->fetchPairs(); $bugs = $this->dao->select('product,count(*) AS conut') - ->from(TABLE_BUG) - ->where('deleted')->eq(0) - ->andWhere('product')->in(array_keys($products)) - ->groupBy('product') - ->fetchPairs(); - $unResolved = $this->dao->select('product,count(*) AS count') - ->from(TABLE_BUG) - ->where('status')->eq('active') - ->andwhere('deleted')->eq(0) - ->andWhere('product')->in(array_keys($products)) - ->groupBy('product') - ->fetchPairs(); - $assignToNull = $this->dao->select('product,count(*) AS count') ->from(TABLE_BUG) - ->where('AssignedTo')->eq('') - ->andwhere('deleted')->eq(0) + ->where('deleted')->eq(0) ->andWhere('product')->in(array_keys($products)) ->groupBy('product') ->fetchPairs(); + $unResolved = $this->dao->select('product,count(*) AS count') + ->from(TABLE_BUG) + ->where('deleted')->eq(0) + ->andwhere('status')->eq('active') + ->andWhere('product')->in(array_keys($products)) + ->groupBy('product') + ->fetchPairs(); + $assignToNull = $this->dao->select('product,count(*) AS count') + ->from(TABLE_BUG) + ->where('deleted')->eq(0) + ->andwhere('assignedTo')->eq('') + ->andWhere('product')->in(array_keys($products)) + ->groupBy('product') + ->fetchPairs(); + + $stats = array(); foreach($products as $key => $product) { - $product->stories = $stories[$product->id]; - $product->plans = isset($plans[$product->id]) ? $plans[$product->id] : 0; - $product->releases= isset($releases[$product->id]) ? $releases[$product->id] : 0; + $product->stories = $stories[$product->id]; + $product->plans = isset($plans[$product->id]) ? $plans[$product->id] : 0; + $product->releases = isset($releases[$product->id]) ? $releases[$product->id] : 0; - $product->bugs = isset($bugs[$product->id]) ? $bugs[$product->id] : 0; - $product->unResolved = isset($unResolved[$product->id]) ? $unResolved[$product->id] : 0; + $product->bugs = isset($bugs[$product->id]) ? $bugs[$product->id] : 0; + $product->unResolved = isset($unResolved[$product->id]) ? $unResolved[$product->id] : 0; $product->assignToNull = isset($assignToNull[$product->id]) ? $assignToNull[$product->id] : 0; $stats[] = $product; } diff --git a/module/project/model.php b/module/project/model.php index 49284f2f0a..abcc891ce3 100644 --- a/module/project/model.php +++ b/module/project/model.php @@ -869,7 +869,7 @@ class projectModel extends model foreach($projects as $key => $project) { // Process the end time. - $project->end = date("Y-m-d", strtotime($project->end)); + $project->end = date(DT_DATE1, strtotime($project->end)); /* Judge whether the project is delayed. */ if($project->status != 'done' and $project->status != 'suspended') diff --git a/module/search/lang/zh-tw.php b/module/search/lang/zh-tw.php index 4685cf2821..5a9e95dc55 100644 --- a/module/search/lang/zh-tw.php +++ b/module/search/lang/zh-tw.php @@ -17,7 +17,7 @@ $lang->search->group1 = '第一組'; $lang->search->group2 = '第二組'; $lang->search->buildForm = '搜索表單'; $lang->search->buildQuery = '執行搜索'; -$lang->search->saveQuery = '保存查詢'; +$lang->search->savedQuery = '已保存的檢索歷史'; $lang->search->deleteQuery = '刪除查詢'; $lang->search->setQueryTitle = '請輸入查詢標題(保存之前請先查詢):'; $lang->search->select = '需求/任務篩選'; diff --git a/module/story/lang/zh-tw.php b/module/story/lang/zh-tw.php index f42730ab48..228e22c989 100644 --- a/module/story/lang/zh-tw.php +++ b/module/story/lang/zh-tw.php @@ -10,7 +10,7 @@ * @link http://www.zentao.net */ $lang->story->create = "提需求"; -$lang->story->batchCreate = "批量提需求"; +$lang->story->batchCreate = "批量添加"; $lang->story->change = "變更"; $lang->story->changed = '需求變更'; $lang->story->review = '評審';