Merge branch 'master' into zenops_66

This commit is contained in:
zhaoke
2023-04-13 09:06:59 +08:00
427 changed files with 16969 additions and 10988 deletions
+1 -1
View File
@@ -1 +1 @@
18.4
18.3
+1 -1
View File
@@ -16,7 +16,7 @@ if(!class_exists('config')){class config{}}
if(!function_exists('getWebRoot')){function getWebRoot(){}}
/* 基本设置。Basic settings. */
$config->version = '18.4'; // ZenTaoPHP的版本。 The version of ZenTaoPHP. Don't change it.
$config->version = '18.3'; // ZenTaoPHP的版本。 The version of ZenTaoPHP. Don't change it.
$config->liteVersion = '1.2'; // 迅捷版版本。 The version of Lite.
$config->charset = 'UTF-8'; // ZenTaoPHP的编码。 The encoding of ZenTaoPHP.
$config->cookieLife = time() + 2592000; // Cookie的生存时间。The cookie life time.
+19 -11
View File
@@ -90,8 +90,11 @@ $filter->doc->browse = new stdclass();
$filter->doc->alllibs = new stdclass();
$filter->doc->objectlibs = new stdclass();
$filter->doc->tablecontents = new stdclass();
$filter->doc->productspace = new stdclass();
$filter->doc->projectspace = new stdclass();
$filter->doc->showfiles = new stdclass();
$filter->doc->default = new stdclass();
$filter->api->default = new stdClass();
$filter->api->index = new stdClass();
$filter->api->create = new stdClass();
$filter->api->edit = new stdClass();
@@ -214,17 +217,22 @@ $filter->bug->export->cookie['checkedItem'] = 'reg::checked';
$filter->caselib->create->cookie['lastLibCaseModule'] = 'int';
$filter->doc->create->cookie['lastDocModule'] = 'int';
$filter->doc->browse->cookie['browseType'] = 'reg::browseType';
$filter->doc->alllibs->cookie['browseType'] = 'reg::browseType';
$filter->doc->objectlibs->cookie['browseType'] = 'reg::browseType';
$filter->doc->objectlibs->cookie['preProductID'] = 'int';
$filter->doc->objectlibs->cookie['preBranch'] = 'reg::word';
$filter->doc->default->cookie['from'] = 'code';
$filter->doc->default->cookie['product'] = 'int';
$filter->doc->showfiles->cookie['docFilesViewType'] = 'code';
$filter->doc->tablecontents->cookie['preProductID'] = 'int';
$filter->doc->tablecontents->cookie['preBranch'] = 'reg::word';
$filter->doc->create->cookie['lastDocModule'] = 'int';
$filter->doc->browse->cookie['browseType'] = 'reg::browseType';
$filter->doc->alllibs->cookie['browseType'] = 'reg::browseType';
$filter->doc->objectlibs->cookie['browseType'] = 'reg::browseType';
$filter->doc->objectlibs->cookie['preProductID'] = 'int';
$filter->doc->objectlibs->cookie['preBranch'] = 'reg::word';
$filter->doc->default->cookie['from'] = 'code';
$filter->doc->default->cookie['product'] = 'int';
$filter->doc->showfiles->cookie['docFilesViewType'] = 'code';
$filter->doc->tablecontents->cookie['preProductID'] = 'int';
$filter->doc->tablecontents->cookie['preBranch'] = 'reg::word';
$filter->doc->productspace->cookie['pagerDocTablecontents'] = 'int';
$filter->doc->projectspace->cookie['pagerDocTablecontents'] = 'int';
$filter->api->default->cookie['objectType'] = 'string';
$filter->api->default->cookie['objectID'] = 'int';
$filter->api->index->get['libID'] = 'int';
$filter->api->index->get['module'] = 'int';
$filter->api->index->get['apiID'] = 'int';
+4
View File
@@ -311,6 +311,7 @@ define('TABLE_HISTORY', '`' . $config->db->prefix . 'history`');
define('TABLE_EXTENSION', '`' . $config->db->prefix . 'extension`');
define('TABLE_CRON', '`' . $config->db->prefix . 'cron`');
define('TABLE_BLOCK', '`' . $config->db->prefix . 'block`');
define('TABLE_DOCACTION', '`' . $config->db->prefix . 'docaction`');
define('TABLE_DOCCONTENT', '`' . $config->db->prefix . 'doccontent`');
define('TABLE_TESTSUITE', '`' . $config->db->prefix . 'testsuite`');
define('TABLE_SUITECASE', '`' . $config->db->prefix . 'suitecase`');
@@ -442,3 +443,6 @@ $config->featureGroup->agileplus = array();
$config->featureGroup->waterfallplus = array();
$config->featureGroup->assetlib = array();
$config->featureGroup->other = array('devops', 'kanban');
$config->bi = new stdclass();
$config->bi->pickerHeight = 150;
+62 -62
View File
@@ -213,20 +213,20 @@ INSERT INTO `zt_block` (`id`, `account`, `module`, `type`, `title`, `source`, `b
(60, 'dev3', 'my', '', '待处理', '', 'assigntome', '{\"todoCount\":\"20\",\"taskCount\":\"20\",\"bugCount\":\"20\",\"riskCount\":\"20\",\"issueCount\":\"20\",\"storyCount\":\"20\",\"meetingCount\":\"20\"}', 7, 8, 0, 0),
(61, 'dev3', 'my', '', '项目人力投入', 'project', 'projectteam', '', 8, 8, 0, 0),
(62, 'dev3', 'my', '', '项目列表', 'project', 'project', '{\"orderBy\":\"id_desc\",\"count\":\"15\"}', 9, 8, 0, 0);
INSERT INTO `zt_bug` (`id`, `project`, `product`, `branch`, `module`, `execution`, `plan`, `story`, `storyVersion`, `task`, `toTask`, `toStory`, `title`, `keywords`, `severity`, `pri`, `type`, `os`, `browser`, `hardware`, `found`, `steps`, `status`, `subStatus`, `color`, `confirmed`, `activatedCount`, `activatedDate`, `mailto`, `openedBy`, `openedDate`, `openedBuild`, `assignedTo`, `assignedDate`, `deadline`, `resolvedBy`, `resolution`, `resolvedBuild`, `resolvedDate`, `closedBy`, `closedDate`, `duplicateBug`, `linkBug`, `case`, `caseVersion`, `result`, `repo`, `entry`, `lines`, `v1`, `v2`, `repoType`, `testtask`, `lastEditedBy`, `lastEditedDate`, `deleted`) VALUES
(1, 7, 1, 0, 8, 1, 0, 1, 1, 1, 0, 0, '首页页面问题', '', 3, 1, 'codeerror', '', '', '', '', '<p>[步骤]进入首页</p>\r\n<p>[结果]出现乱码&nbsp;&nbsp;&nbsp;&nbsp;</p>\r\n<p>[期望]正常显示</p>', 'active', '', '', 0, 0, '0000-00-00 00:00:00', '', 'tester1', '2012-06-05 10:56:11', 'trunk', 'dev1', '2012-06-05 10:56:11', '0000-00-00', '', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, '', 0, 1, 0, 0, '', '', '', '', '', 0, 'admin', '2021-04-28 11:09:08', '0'),
(2, 7, 1, 0, 9, 1, 0, 2, 1, 4, 0, 0, '新闻中心页面问题', '', 3, 2, 'codeerror', '', '', '', '', '<p>[步骤]进入新闻中心</p>\r\n<p>[结果]页面出现乱码</p>\r\n<p>[期望]正常显示</p>', 'active', '', '', 0, 0, '0000-00-00 00:00:00', '', 'tester1', '2012-06-05 10:57:11', 'trunk', 'dev1', '2012-06-05 10:57:11', '0000-00-00', '', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, '', 0, 1, 0, 0, '', '', '', '', '', 0, 'admin', '2021-04-28 11:09:08', '0'),
(3, 7, 1, 0, 10, 1, 0, 3, 2, 6, 0, 0, '成果展示页面问题', '', 3, 1, 'codeerror', '', '', '', '', '<p>[步骤]进入成果展示&nbsp;&nbsp;&nbsp;&nbsp;</p>\r\n<p>[结果]乱码</p>\r\n<p>[期望]正常显示</p>', 'active', '', '', 0, 0, '0000-00-00 00:00:00', '', 'tester2', '2012-06-05 10:58:22', 'trunk', 'dev1', '2012-06-05 10:58:22', '0000-00-00', '', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, '', 0, 1, 0, 0, '', '', '', '', '', 0, 'admin', '2021-04-28 11:09:08', '0'),
(4, 7, 1, 0, 11, 1, 0, 4, 1, 9, 0, 0, '售后服务页面问题', '', 3, 1, 'codeerror', '', '', '', '', '<p>[步骤]进入售后服务</p>\r\n<p>[结果]乱码</p>\r\n<p>[期望]正常显示</p>', 'active', '', '', 0, 0, '0000-00-00 00:00:00', '', 'tester3', '2012-06-05 11:00:19', 'trunk', 'dev1', '2012-06-05 11:00:19', '0000-00-00', '', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, '', 0, 1, 0, 0, '', '', '', '', '', 0, 'admin', '2021-04-28 11:09:08', '0');
INSERT INTO `zt_build` (`id`, `project`, `product`, `branch`, `execution`, `name`, `scmPath`, `filePath`, `date`, `stories`, `bugs`, `builder`, `desc`, `deleted`) VALUES
(1, 7, 1, 0, 1, '第一期版本', '', '', '2012-06-05', '3,2,1,4', '', 'projectManager', '', '0');
INSERT INTO `zt_bug` (`id`, `project`, `product`, `branch`, `module`, `execution`, `plan`, `story`, `storyVersion`, `task`, `toTask`, `toStory`, `title`, `keywords`, `severity`, `pri`, `type`, `os`, `browser`, `hardware`, `found`, `steps`, `status`, `subStatus`, `color`, `confirmed`, `activatedCount`, `activatedDate`, `mailto`, `openedBy`, `openedDate`, `openedBuild`, `assignedTo`, `assignedDate`, `deadline`, `resolvedBy`, `resolution`, `resolvedBuild`, `resolvedDate`, `closedBy`, `closedDate`, `duplicateBug`, `linkBug`, `case`, `caseVersion`, `result`, `repo`, `entry`, `lines`, `v1`, `v2`, `repoType`, `testtask`, `lastEditedBy`, `lastEditedDate`, `deleted`, `feedbackBy`, `mr`, `notifyEmail`) VALUES
(1, 7, 1, 0, 8, 1, 0, 1, 1, 1, 0, 0, '首页页面问题', '', 3, 1, 'codeerror', '', '', '', '', '<p>[步骤]进入首页</p>\r\n<p>[结果]出现乱码&nbsp;&nbsp;&nbsp;&nbsp;</p>\r\n<p>[期望]正常显示</p>', 'active', '', '', 0, 0, '0000-00-00 00:00:00', '', 'tester1', '2012-06-05 10:56:11', 'trunk', 'dev1', '2012-06-05 10:56:11', '0000-00-00', '', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, '', 0, 1, 0, 0, '', '', '', '', '', 0, 'admin', '2021-04-28 11:09:08', '0', '', 0, ''),
(2, 7, 1, 0, 9, 1, 0, 2, 1, 4, 0, 0, '新闻中心页面问题', '', 3, 2, 'codeerror', '', '', '', '', '<p>[步骤]进入新闻中心</p>\r\n<p>[结果]页面出现乱码</p>\r\n<p>[期望]正常显示</p>', 'active', '', '', 0, 0, '0000-00-00 00:00:00', '', 'tester1', '2012-06-05 10:57:11', 'trunk', 'dev1', '2012-06-05 10:57:11', '0000-00-00', '', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, '', 0, 1, 0, 0, '', '', '', '', '', 0, 'admin', '2021-04-28 11:09:08', '0', '', 0, ''),
(3, 7, 1, 0, 10, 1, 0, 3, 2, 6, 0, 0, '成果展示页面问题', '', 3, 1, 'codeerror', '', '', '', '', '<p>[步骤]进入成果展示&nbsp;&nbsp;&nbsp;&nbsp;</p>\r\n<p>[结果]乱码</p>\r\n<p>[期望]正常显示</p>', 'active', '', '', 0, 0, '0000-00-00 00:00:00', '', 'tester2', '2012-06-05 10:58:22', 'trunk', 'dev1', '2012-06-05 10:58:22', '0000-00-00', '', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, '', 0, 1, 0, 0, '', '', '', '', '', 0, 'admin', '2021-04-28 11:09:08', '0', '', 0, ''),
(4, 7, 1, 0, 11, 1, 0, 4, 1, 9, 0, 0, '售后服务页面问题', '', 3, 1, 'codeerror', '', '', '', '', '<p>[步骤]进入售后服务</p>\r\n<p>[结果]乱码</p>\r\n<p>[期望]正常显示</p>', 'active', '', '', 0, 0, '0000-00-00 00:00:00', '', 'tester3', '2012-06-05 11:00:19', 'trunk', 'dev1', '2012-06-05 11:00:19', '0000-00-00', '', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, '', 0, 1, 0, 0, '', '', '', '', '', 0, 'admin', '2021-04-28 11:09:08', '0', '', 0, '');
INSERT INTO `zt_build` (`id`, `project`, `product`, `branch`, `execution`, `name`, `scmPath`, `filePath`, `date`, `stories`, `bugs`, `builder`, `desc`, `deleted`, `builds`, `createdBy`, `createdDate`) VALUES
(1, 7, 1, 0, 1, '第一期版本', '', '', '2012-06-05', '3,2,1,4', '', 'projectManager', '', '0', '', 'tester1', '2012-06-05 11:11:11');
INSERT INTO `zt_burn` (`execution`, `product`, `task`, `date`, `estimate`, `left`, `consumed`, `storyPoint`) VALUES
(1, 0, 0, '2012-06-05', 0, 0, 38, 0);
INSERT INTO `zt_case` (`id`, `project`, `product`, `branch`, `lib`, `module`, `path`, `story`, `storyVersion`, `title`, `precondition`, `keywords`, `pri`, `type`, `auto`, `frame`, `stage`, `howRun`, `scriptedBy`, `scriptedDate`, `scriptStatus`, `scriptLocation`, `status`, `subStatus`, `color`, `frequency`, `order`, `openedBy`, `openedDate`, `reviewedBy`, `reviewedDate`, `lastEditedBy`, `lastEditedDate`, `version`, `linkCase`, `fromBug`, `fromCaseID`, `fromCaseVersion`, `deleted`, `lastRunner`, `lastRunDate`, `lastRunResult`, `execution`) VALUES
(1, 7, 1, 0, 0, 0, 0, 4, 1, '售后服务的测试用例', '', '', 1, 'feature', 'no', '', 'feature', '', '', '0000-00-00', '', '', 'normal', '', '', '1', 0, 'tester3', '2012-06-05 11:02:18', '', '0000-00-00', 'tester3', '2012-06-05 11:02:46', 1, '', 0, 0, 1, '0', 'testManager', '2012-06-05 11:11:00', 'pass', 0),
(2, 7, 1, 0, 0, 0, 0, 1, 1, '首页的测试用例', '', '', 3, 'feature', 'no', '', '', '', '', '0000-00-00', '', '', 'normal', '', '', '1', 0, 'tester1', '2012-06-05 11:03:28', '', '0000-00-00', '', '0000-00-00 00:00:00', 1, '', 0, 0, 1, '0', 'testManager', '2012-06-05 11:11:05', 'pass', 0),
(3, 7, 1, 0, 0, 0, 0, 2, 1, '新闻中心的测试用例', '', '', 3, 'feature', 'no', '', 'feature', '', '', '0000-00-00', '', '', 'normal', '', '', '1', 0, 'tester1', '2012-06-05 11:03:54', '', '0000-00-00', '', '0000-00-00 00:00:00', 1, '', 0, 0, 1, '0', 'testManager', '2012-06-05 11:11:07', 'pass', 0),
(4, 7, 1, 0, 0, 0, 0, 3, 2, '成果展示测试用例', '', '', 3, 'feature', 'no', '', 'feature', '', '', '0000-00-00', '', '', 'normal', '', '', '1', 0, 'tester2', '2012-06-05 11:04:48', '', '0000-00-00', '', '0000-00-00 00:00:00', 1, '', 0, 0, 1, '0', 'testManager', '2012-06-05 11:11:08', 'pass', 0);
INSERT INTO `zt_case` (`id`, `project`, `product`, `branch`, `lib`, `module`, `path`, `story`, `storyVersion`, `title`, `precondition`, `keywords`, `pri`, `type`, `auto`, `frame`, `stage`, `howRun`, `scriptedBy`, `scriptedDate`, `scriptStatus`, `scriptLocation`, `status`, `subStatus`, `color`, `frequency`, `order`, `openedBy`, `openedDate`, `reviewedBy`, `reviewedDate`, `lastEditedBy`, `lastEditedDate`, `version`, `linkCase`, `fromBug`, `fromCaseID`, `fromCaseVersion`, `deleted`, `lastRunner`, `lastRunDate`, `lastRunResult`, `execution`, `script`) VALUES
(1, 7, 1, 0, 0, 0, 0, 4, 1, '售后服务的测试用例', '', '', 1, 'feature', 'no', '', 'feature', '', '', '0000-00-00', '', '', 'normal', '', '', '1', 0, 'tester3', '2012-06-05 11:02:18', '', '0000-00-00', 'tester3', '2012-06-05 11:02:46', 1, '', 0, 0, 1, '0', 'testManager', '2012-06-05 11:11:00', 'pass', 0, ''),
(2, 7, 1, 0, 0, 0, 0, 1, 1, '首页的测试用例', '', '', 3, 'feature', 'no', '', '', '', '', '0000-00-00', '', '', 'normal', '', '', '1', 0, 'tester1', '2012-06-05 11:03:28', '', '0000-00-00', '', '0000-00-00 00:00:00', 1, '', 0, 0, 1, '0', 'testManager', '2012-06-05 11:11:05', 'pass', 0, ''),
(3, 7, 1, 0, 0, 0, 0, 2, 1, '新闻中心的测试用例', '', '', 3, 'feature', 'no', '', 'feature', '', '', '0000-00-00', '', '', 'normal', '', '', '1', 0, 'tester1', '2012-06-05 11:03:54', '', '0000-00-00', '', '0000-00-00 00:00:00', 1, '', 0, 0, 1, '0', 'testManager', '2012-06-05 11:11:07', 'pass', 0, ''),
(4, 7, 1, 0, 0, 0, 0, 3, 2, '成果展示测试用例', '', '', 3, 'feature', 'no', '', 'feature', '', '', '0000-00-00', '', '', 'normal', '', '', '1', 0, 'tester2', '2012-06-05 11:04:48', '', '0000-00-00', '', '0000-00-00 00:00:00', 1, '', 0, 0, 1, '0', 'testManager', '2012-06-05 11:11:08', 'pass', 0, '');
INSERT INTO `zt_casestep` (`id`, `parent`, `case`, `version`, `type`, `desc`, `expect`) VALUES
(1, 0, 1, 1, 'step', '进入首页', '正常显示'),
(2, 0, 2, 1, 'step', '进入首页', '正常显示'),
@@ -241,12 +241,12 @@ INSERT INTO `zt_dept` (`id`, `name`, `parent`, `path`, `grade`, `order`, `positi
(6, '项目', 1, ',1,6,', 2, 0, '', '', ''),
(7, '编程', 2, ',2,7,', 2, 0, '', '', ''),
(8, '美工', 2, ',2,8,', 2, 0, '', '', '');
INSERT INTO `zt_doclib` (`id`, `type`, `product`, `project`, `execution`, `name`, `acl`, `groups`, `users`, `main`, `collector`, `order`, `deleted`) VALUES
(1, 'product', 1, 0, 0, '产品库', 'default', '', '', '1', '', 0, '0'),
(2, 'product', 2, 0, 0, '产品库', 'default', '', '', '1', '', 0, '0'),
(3, 'execution', 0, 0, 1, '项目库', 'default', '', '', '1', '', 0, '0'),
(4, 'execution', 0, 0, 2, '项目库', 'default', '', '', '1', '', 0, '0'),
(5, 'project', 0, 7, 0, '项目主库', 'default', '', '', '1', '', 0, '0');
INSERT INTO `zt_doclib` (`id`, `type`, `product`, `project`, `execution`, `name`, `acl`, `groups`, `users`, `main`, `collector`, `order`, `deleted`, `addedBy`, `addedDate`) VALUES
(1, 'product', 1, 0, 0, '产品库', 'default', '', '', '1', '', 0, '0', 'tester1', '2012-06-05 10:11:32'),
(2, 'product', 2, 0, 0, '产品库', 'default', '', '', '1', '', 0, '0', 'tester1', '2012-06-05 10:11:32'),
(3, 'execution', 0, 0, 1, '项目库', 'default', '', '', '1', '', 0, '0', 'tester1', '2012-06-05 10:11:32'),
(4, 'execution', 0, 0, 2, '项目库', 'default', '', '', '1', '', 0, '0', 'tester1', '2012-06-05 10:11:32'),
(5, 'project', 0, 7, 0, '项目主库', 'default', '', '', '1', '', 0, '0', 'tester1', '2012-06-05 10:11:32');
INSERT INTO `zt_history` (`id`, `action`, `field`, `old`, `new`, `diff`) VALUES
(1, 14, 'version', '1', '2', ''),
(2, 14, 'spec', '&nbsp;作为一名本公司的用户,我希望可以在成果展示看到该公司网站的企业新闻,这样可以方便我进行了解该公司的产品并进行购买。&nbsp;<br />', '&nbsp;作为一名本公司的用户,我希望可以在成果展示看到该公司网站的吹产品,这样可以方便我进行了解该公司的产品并进行购买。&nbsp;<br />', '001- <del>作为一名本公司的用户,我希望可以在成果展示看到该公司网站的企业新闻,这样可以方便我进行了解该公司的产品并进行购买。<br /></del>\n001+ <ins>作为一名本公司的用户,我希望可以在成果展示看到该公司网站的吹产品,这样可以方便我进行了解该公司的产品并进行购买。<br /></ins>'),
@@ -380,8 +380,8 @@ INSERT INTO `zt_module` (`id`, `root`, `branch`, `name`, `parent`, `path`, `grad
INSERT INTO `zt_product` (`id`, `program`, `name`, `code`, `bind`, `line`, `type`, `status`, `subStatus`, `desc`, `PO`, `QD`, `RD`, `acl`, `whitelist`, `createdBy`, `createdDate`, `createdVersion`, `order`, `deleted`) VALUES
(1, 6, '公司企业网站建设', 'companyWebsite', '0', 0, 'normal', 'normal', '', '建立公司企业网站,可以更好对外展示。<br />', 'productManager', 'testManager', 'productManager', 'open', '', 'productManager', '2012-06-05 09:57:07', '', 5, '0'),
(2, 6, '企业内部工时管理系统', 'workhourManage', '0', 0, 'normal', 'normal', '', '', 'productManager', 'testManager', 'productManager', 'open', '', 'productManager', '2012-06-05 11:15:20', '5.2.1', 10, '0');
INSERT INTO `zt_productplan` (`id`, `product`, `branch`, `parent`, `title`, `desc`, `begin`, `end`, `order`, `deleted`) VALUES
(1, 1, 0, 0, '1.0版本', '开发出企业网站1.0版本。<br />', '2020-06-05', '2021-06-04', '', '0');
INSERT INTO `zt_productplan` (`id`, `product`, `branch`, `parent`, `title`, `desc`, `begin`, `end`, `order`, `deleted`, `createdBy`, `createdDate`) VALUES
(1, 1, 0, 0, '1.0版本', '开发出企业网站1.0版本。<br />', '2020-06-05', '2021-06-04', '', '0', 'tester1', '2021-04-01 11:08:09');
INSERT INTO `zt_project` (`id`, `project`, `model`, `type`, `lifetime`, `budget`, `budgetUnit`, `attribute`, `percent`, `milestone`, `output`, `auth`, `parent`, `path`, `grade`, `name`, `code`, `begin`, `end`, `realBegan`, `realEnd`, `days`, `status`, `subStatus`, `pri`, `desc`, `version`, `parentVersion`, `planDuration`, `realDuration`, `openedBy`, `openedDate`, `openedVersion`, `lastEditedBy`, `lastEditedDate`, `closedBy`, `closedDate`, `canceledBy`, `canceledDate`, `PO`, `PM`, `QD`, `RD`, `team`, `acl`, `whitelist`, `order`, `deleted`) VALUES
(1, 7, '', 'sprint', 'long', '0', 'CNY', '', 0, '0', '', '', 7, ',7,1,', 1, '企业网站第一期', 'coWeb1', '2020-06-05', '2021-12-04', '0000-00-00', '0000-00-00', 391, 'doing', '', '1', '开发企业网站的基本雏形。<br />', 0, 0, 0, 0, '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 'productManager', 'projectManager', 'testManager', 'productManager', '公司开发团队', 'open', '', 5, '0'),
(2, 7, '', 'sprint', 'long', '0', 'CNY', '', 0, '0', '', '', 7, ',7,2,', 1, '企业网站第二期', 'coWebsite2', '2021-06-05', '2022-06-04', '0000-00-00', '0000-00-00', 260, 'wait', '', '1', '', 0, 0, 0, 0, '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 'productManager', 'projectManager', 'testManager', 'productManager', '公司开发团队', 'open', '', 10, '0'),
@@ -401,15 +401,15 @@ INSERT INTO `zt_projectproduct` (`project`, `product`, `branch`, `plan`) VALUES
(2, 1, 0, 0),
(7, 1, 0, 0),
(7, 2, 0, 0);
INSERT INTO `zt_projectstory` (`project`, `product`, `story`, `version`, `order`) VALUES
(1, 1, 1, 1, 0),
(1, 1, 2, 1, 0),
(1, 1, 3, 2, 0),
(1, 1, 4, 1, 0),
(7, 1, 4, 1, 0),
(7, 1, 3, 2, 0),
(7, 1, 2, 1, 0),
(7, 1, 1, 1, 0);
INSERT INTO `zt_projectstory` (`project`, `product`, `story`, `version`, `order`, `branch`) VALUES
(1, 1, 1, 1, 0, 0),
(1, 1, 2, 1, 0, 0),
(1, 1, 3, 2, 0, 0),
(1, 1, 4, 1, 0, 0),
(7, 1, 4, 1, 0, 0),
(7, 1, 3, 2, 0, 0),
(7, 1, 2, 1, 0, 0),
(7, 1, 1, 1, 0, 0);
INSERT INTO `zt_searchdict` (`key`, `value`) VALUES
(39318, '首'),
(39029, '页'),
@@ -584,32 +584,32 @@ INSERT INTO `zt_searchindex` (`id`, `objectType`, `objectID`, `title`, `content`
(39, 'task', 15, ' 25104 26524 23637 31034 30340 24320 21457', ' 25104 26524 23637 31034 30340 24320 21457', '2021-04-28 13:16:15', '2021-04-28 13:16:15'),
(40, 'task', 16, ' 21806 21518 26381 21153 30340 35774 35745', ' 21806 21518 26381 21153 30340 35774 35745', '2021-04-28 13:16:15', '2021-04-28 13:16:15'),
(41, 'task', 17, ' 21806 21518 26381 21153 30340 24320 21457', ' 21806 21518 26381 21153 30340 24320 21457', '2021-04-28 13:16:15', '2021-04-28 13:16:15');
INSERT INTO `zt_story` (`id`, `parent`, `product`, `branch`, `module`, `plan`, `source`, `sourceNote`, `fromBug`, `title`, `keywords`, `type`, `pri`, `estimate`, `status`, `subStatus`, `color`, `stage`, `stagedBy`, `mailto`, `openedBy`, `openedDate`, `assignedTo`, `assignedDate`, `lastEditedBy`, `lastEditedDate`, `reviewedBy`, `reviewedDate`, `closedBy`, `closedDate`, `closedReason`, `toBug`, `childStories`, `linkStories`, `duplicateStory`, `version`, `URChanged`, `deleted`) VALUES
(1, 0, 1, 0, 1, '1', 'po', '', 0, '首页设计和开发', '', 'story', 1, 1, 'active', '', '', 'developing', '', '', 'productManager', '2012-06-05 10:09:49', 'productManager', '0000-00-00 00:00:00', 'productManager', '2012-06-05 10:25:19', 'productManager, ', '2012-06-05 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 1, '0', '0'),
(2, 0, 1, 0, 2, '1', 'po', '', 0, '新闻中心的设计和开发。', '', 'story', 1, 1, 'active', '', '', 'projected', '', '', 'productManager', '2012-06-05 10:16:37', 'productManager', '2012-06-05 10:16:37', 'productManager', '2012-06-05 10:25:33', 'productManager, ', '2012-06-05 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 1, '0', '0'),
(3, 0, 1, 0, 3, '1', 'po', '', 0, '成果展示的设计和开发', '', 'story', 1, 0, 'active', '', '', 'developing', '', '', 'productManager', '2012-06-05 10:18:10', 'productManager', '2012-06-05 10:18:10', 'productManager', '2012-06-05 10:25:38', 'productManager, ', '2012-06-05 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 2, '0', '0'),
(4, 0, 1, 0, 4, '1', 'po', '', 0, '售后服务的设计和开发', '', 'story', 1, 1, 'active', '', '', 'developed', '', '', 'productManager', '2012-06-05 10:20:16', 'productManager', '2012-06-05 10:20:16', 'productManager', '2012-06-05 10:25:42', 'productManager, ', '2012-06-05 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 1, '0', '0'),
(5, 0, 1, 0, 5, '1', 'po', '', 0, '诚聘英才的设计和开发', '', 'story', 1, 1, 'reviewing', '', '', 'planned', '', '', 'productManager', '2012-06-05 10:21:39', 'productManager', '2012-06-05 10:21:39', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 1, '0', '0'),
(6, 0, 1, 0, 6, '1', 'po', '', 0, '合作洽谈的设计和开发', '', 'story', 1, 1, 'reviewing', '', '', 'planned', '', '', 'productManager', '2012-06-05 10:23:11', 'productManager', '2012-06-05 10:23:11', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 1, '0', '0'),
(7, 0, 1, 0, 7, '1', 'po', '', 0, '关于我们的设计和开发', '', 'story', 1, 1, 'reviewing', '', '', 'planned', '', '', 'productManager', '2012-06-05 10:24:19', 'productManager', '2012-06-05 10:24:19', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 1, '0', '0');
INSERT INTO `zt_storyspec` (`story`, `version`, `title`, `spec`, `verify`) VALUES
(1, 1, '首页设计和开发', '作为一名本公司的用户,我希望可以在首页看到该公司网站的基本内容,例如最新动态、部分成果展示、联系信息、工商信息等。<br />', '开发并通过验收<br />'),
(2, 1, '新闻中心的设计和开发。', '作为一名本公司的用户,我希望可以在新闻中心看到该公司网站的企业新闻,这样可以通过新闻了解企业的最新动态。<br />', ''),
(3, 1, '成果展示的设计和开发', '&nbsp;作为一名本公司的用户,我希望可以在成果展示看到该公司网站的企业新闻,这样可以方便我进行了解该公司的产品并进行购买。&nbsp;<br />', ''),
(3, 2, '成果展示的设计和开发', '&nbsp;作为一名本公司的用户,我希望可以在成果展示看到该公司网站的吹产品,这样可以方便我进行了解该公司的产品并进行购买。&nbsp;<br />', ''),
(4, 1, '售后服务的设计和开发', '作为一名本公司的用户,我希望可以在售后服务看到该公司网站的售后服务,这样可以方便我联系该公司来解决我的问题。&nbsp;<br />', ''),
(5, 1, '诚聘英才的设计和开发', '作为一名求职者,我希望可以在诚聘英才里看到该公司的招聘信息,这样可以方便我应聘该公司。&nbsp;<br />', ''),
(6, 1, '合作洽谈的设计和开发', '作为一名合作商,我希望可以在合作洽谈里看到该公司对外的合作内容,这样可以方便我和该公司进行合作洽谈。&nbsp;<br />', ''),
(7, 1, '关于我们的设计和开发', '我希望可以在关于我们里看到该公司的基本信息,这样可以方便我了解该公司。<br />', '');
INSERT INTO `zt_task` (`id`, `project`, `parent`, `execution`, `module`, `design`, `story`, `storyVersion`, `designVersion`, `fromBug`, `name`, `type`, `pri`, `estimate`, `consumed`, `left`, `deadline`, `status`, `subStatus`, `color`, `mailto`, `desc`, `version`, `openedBy`, `openedDate`, `assignedTo`, `assignedDate`, `estStarted`, `realStarted`, `finishedBy`, `finishedDate`, `finishedList`, `canceledBy`, `canceledDate`, `closedBy`, `closedDate`, `realDuration`, `planDuration`, `closedReason`, `lastEditedBy`, `lastEditedDate`, `activatedDate`, `deleted`) VALUES
(17, 7, 0, 1, 0, 0, 4, 1, 0, 0, '售后服务的开发', 'devel', 1, 5, 5, 0, '0000-00-00', 'done', '', '', NULL, '售后服务的开发', 1, 'admin', '2021-04-28 13:16:15', 'dev3', '2021-04-28 13:21:51', '0000-00-00', '2021-04-02 08:00:00', 'dev3', '2021-04-06 15:30:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', 'dev3', '2021-04-28 13:21:51', '0000-00-00', '0'),
(16, 7, 0, 1, 0, 0, 4, 1, 0, 0, '售后服务的设计', 'design', 1, 5, 6, 0, '0000-00-00', 'done', '', '', NULL, '售后服务的设计', 1, 'admin', '2021-04-28 13:16:15', 'dev3', '2021-04-28 13:21:22', '0000-00-00', '2021-04-02 08:00:00', 'dev3', '2021-04-05 17:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', 'dev3', '2021-04-28 13:21:22', '0000-00-00', '0'),
(15, 7, 0, 1, 0, 0, 3, 2, 0, 0, '成果展示的开发', 'devel', 1, 7, 0, 7, '0000-00-00', 'doing', '', '', NULL, '成果展示的开发', 1, 'admin', '2021-04-28 13:16:15', 'dev2', '2021-04-28 13:16:15', '0000-00-00', '2021-04-01 08:00:00', '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', 'dev2', '2021-04-28 13:20:09', '0000-00-00', '0'),
(14, 7, 0, 1, 0, 0, 3, 2, 0, 0, '成果展示的设计', 'design', 1, 6, 0, 6, '0000-00-00', 'doing', '', '', NULL, '成果展示的设计', 1, 'admin', '2021-04-28 13:16:15', 'dev2', '2021-04-28 13:16:15', '0000-00-00', '2021-04-01 08:00:00', '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', 'dev2', '2021-04-28 13:19:54', '0000-00-00', '0'),
(13, 7, 0, 1, 0, 0, 2, 1, 0, 0, '新闻中心的开发', 'devel', 1, 7, 0, 7, '0000-00-00', 'wait', '', '', NULL, '新闻中心的开发', 1, 'admin', '2021-04-28 13:16:15', 'dev1', '2021-04-28 13:16:15', '0000-00-00', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', '', '0000-00-00 00:00:00', '0000-00-00', '0'),
(12, 7, 0, 1, 0, 0, 2, 1, 0, 0, '新闻中心的设计', 'design', 1, 7, 0, 7, '0000-00-00', 'wait', '', '', NULL, '新闻中心的设计', 1, 'admin', '2021-04-28 13:16:15', 'dev1', '2021-04-28 13:16:15', '0000-00-00', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', '', '0000-00-00 00:00:00', '0000-00-00', '0'),
(10, 7, 0, 1, 0, 0, 1, 1, 0, 0, '首页页面的设计', 'design', 1, 7, 8, 0, '0000-00-00', 'done', '', '', NULL, '首页页面的设计', 1, 'admin', '2021-04-28 13:16:15', 'dev1', '2021-04-28 13:17:54', '0000-00-00', '2021-04-28 13:17:54', 'dev1', '2021-04-01 16:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', 'dev1', '2021-04-28 13:17:54', '0000-00-00', '0'),
(11, 7, 0, 1, 0, 0, 1, 1, 0, 0, '首页页面的开发', 'devel', 1, 8, 0, 8, '0000-00-00', 'doing', '', '', NULL, '首页页面的开发', 1, 'admin', '2021-04-28 13:16:15', 'dev1', '2021-04-28 13:16:15', '0000-00-00', '2021-04-01 16:00:00', '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', 'dev1', '2021-04-28 13:18:45', '0000-00-00', '0');
INSERT INTO `zt_story` (`id`, `parent`, `product`, `branch`, `module`, `plan`, `source`, `sourceNote`, `fromBug`, `title`, `keywords`, `type`, `pri`, `estimate`, `status`, `subStatus`, `color`, `stage`, `stagedBy`, `mailto`, `openedBy`, `openedDate`, `assignedTo`, `assignedDate`, `lastEditedBy`, `lastEditedDate`, `reviewedBy`, `reviewedDate`, `closedBy`, `closedDate`, `closedReason`, `toBug`, `childStories`, `linkStories`, `duplicateStory`, `version`, `URChanged`, `deleted`, `linkRequirements`, `twins`) VALUES
(1, 0, 1, 0, 1, '1', 'po', '', 0, '首页设计和开发', '', 'story', 1, 1, 'active', '', '', 'developing', '', '', 'productManager', '2012-06-05 10:09:49', 'productManager', '0000-00-00 00:00:00', 'productManager', '2012-06-05 10:25:19', 'productManager, ', '2012-06-05 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 1, '0', '0', '', ''),
(2, 0, 1, 0, 2, '1', 'po', '', 0, '新闻中心的设计和开发。', '', 'story', 1, 1, 'active', '', '', 'projected', '', '', 'productManager', '2012-06-05 10:16:37', 'productManager', '2012-06-05 10:16:37', 'productManager', '2012-06-05 10:25:33', 'productManager, ', '2012-06-05 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 1, '0', '0', '', ''),
(3, 0, 1, 0, 3, '1', 'po', '', 0, '成果展示的设计和开发', '', 'story', 1, 0, 'active', '', '', 'developing', '', '', 'productManager', '2012-06-05 10:18:10', 'productManager', '2012-06-05 10:18:10', 'productManager', '2012-06-05 10:25:38', 'productManager, ', '2012-06-05 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 2, '0', '0', '', ''),
(4, 0, 1, 0, 4, '1', 'po', '', 0, '售后服务的设计和开发', '', 'story', 1, 1, 'active', '', '', 'developed', '', '', 'productManager', '2012-06-05 10:20:16', 'productManager', '2012-06-05 10:20:16', 'productManager', '2012-06-05 10:25:42', 'productManager, ', '2012-06-05 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 1, '0', '0', '', ''),
(5, 0, 1, 0, 5, '1', 'po', '', 0, '诚聘英才的设计和开发', '', 'story', 1, 1, 'reviewing', '', '', 'planned', '', '', 'productManager', '2012-06-05 10:21:39', 'productManager', '2012-06-05 10:21:39', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 1, '0', '0', '', ''),
(6, 0, 1, 0, 6, '1', 'po', '', 0, '合作洽谈的设计和开发', '', 'story', 1, 1, 'reviewing', '', '', 'planned', '', '', 'productManager', '2012-06-05 10:23:11', 'productManager', '2012-06-05 10:23:11', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 1, '0', '0', '', ''),
(7, 0, 1, 0, 7, '1', 'po', '', 0, '关于我们的设计和开发', '', 'story', 1, 1, 'reviewing', '', '', 'planned', '', '', 'productManager', '2012-06-05 10:24:19', 'productManager', '2012-06-05 10:24:19', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 1, '0', '0', '', '');
INSERT INTO `zt_storyspec` (`story`, `version`, `title`, `spec`, `verify`, `files`) VALUES
(1, 1, '首页设计和开发', '作为一名本公司的用户,我希望可以在首页看到该公司网站的基本内容,例如最新动态、部分成果展示、联系信息、工商信息等。<br />', '开发并通过验收<br />', ''),
(2, 1, '新闻中心的设计和开发。', '作为一名本公司的用户,我希望可以在新闻中心看到该公司网站的企业新闻,这样可以通过新闻了解企业的最新动态。<br />', '', ''),
(3, 1, '成果展示的设计和开发', '&nbsp;作为一名本公司的用户,我希望可以在成果展示看到该公司网站的企业新闻,这样可以方便我进行了解该公司的产品并进行购买。&nbsp;<br />', '', ''),
(3, 2, '成果展示的设计和开发', '&nbsp;作为一名本公司的用户,我希望可以在成果展示看到该公司网站的吹产品,这样可以方便我进行了解该公司的产品并进行购买。&nbsp;<br />', '', ''),
(4, 1, '售后服务的设计和开发', '作为一名本公司的用户,我希望可以在售后服务看到该公司网站的售后服务,这样可以方便我联系该公司来解决我的问题。&nbsp;<br />', '', ''),
(5, 1, '诚聘英才的设计和开发', '作为一名求职者,我希望可以在诚聘英才里看到该公司的招聘信息,这样可以方便我应聘该公司。&nbsp;<br />', '', ''),
(6, 1, '合作洽谈的设计和开发', '作为一名合作商,我希望可以在合作洽谈里看到该公司对外的合作内容,这样可以方便我和该公司进行合作洽谈。&nbsp;<br />', '', ''),
(7, 1, '关于我们的设计和开发', '我希望可以在关于我们里看到该公司的基本信息,这样可以方便我了解该公司。<br />', '', '');
INSERT INTO `zt_task` (`id`, `project`, `parent`, `execution`, `module`, `design`, `story`, `storyVersion`, `designVersion`, `fromBug`, `name`, `type`, `pri`, `estimate`, `consumed`, `left`, `deadline`, `status`, `subStatus`, `color`, `mailto`, `desc`, `version`, `openedBy`, `openedDate`, `assignedTo`, `assignedDate`, `estStarted`, `realStarted`, `finishedBy`, `finishedDate`, `finishedList`, `canceledBy`, `canceledDate`, `closedBy`, `closedDate`, `realDuration`, `planDuration`, `closedReason`, `lastEditedBy`, `lastEditedDate`, `activatedDate`, `deleted`, `feedback`, `mode`, `order`, `repo`, `mr`, `entry`, `lines`, `v1`, `v2`) VALUES
(17, 7, 0, 1, 0, 0, 4, 1, 0, 0, '售后服务的开发', 'devel', 1, 5, 5, 0, '0000-00-00', 'done', '', '', NULL, '售后服务的开发', 1, 'admin', '2021-04-28 13:16:15', 'dev3', '2021-04-28 13:21:51', '0000-00-00', '2021-04-02 08:00:00', 'dev3', '2021-04-06 15:30:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', 'dev3', '2021-04-28 13:21:51', '0000-00-00', '0', 0, '', 0, 0, 0, '', '', '', ''),
(16, 7, 0, 1, 0, 0, 4, 1, 0, 0, '售后服务的设计', 'design', 1, 5, 6, 0, '0000-00-00', 'done', '', '', NULL, '售后服务的设计', 1, 'admin', '2021-04-28 13:16:15', 'dev3', '2021-04-28 13:21:22', '0000-00-00', '2021-04-02 08:00:00', 'dev3', '2021-04-05 17:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', 'dev3', '2021-04-28 13:21:22', '0000-00-00', '0', 0, '', 0, 0, 0, '', '', '', ''),
(15, 7, 0, 1, 0, 0, 3, 2, 0, 0, '成果展示的开发', 'devel', 1, 7, 0, 7, '0000-00-00', 'doing', '', '', NULL, '成果展示的开发', 1, 'admin', '2021-04-28 13:16:15', 'dev2', '2021-04-28 13:16:15', '0000-00-00', '2021-04-01 08:00:00', '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', 'dev2', '2021-04-28 13:20:09', '0000-00-00', '0', 0, '', 0, 0, 0, '', '', '', ''),
(14, 7, 0, 1, 0, 0, 3, 2, 0, 0, '成果展示的设计', 'design', 1, 6, 0, 6, '0000-00-00', 'doing', '', '', NULL, '成果展示的设计', 1, 'admin', '2021-04-28 13:16:15', 'dev2', '2021-04-28 13:16:15', '0000-00-00', '2021-04-01 08:00:00', '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', 'dev2', '2021-04-28 13:19:54', '0000-00-00', '0', 0, '', 0, 0, 0, '', '', '', ''),
(13, 7, 0, 1, 0, 0, 2, 1, 0, 0, '新闻中心的开发', 'devel', 1, 7, 0, 7, '0000-00-00', 'wait', '', '', NULL, '新闻中心的开发', 1, 'admin', '2021-04-28 13:16:15', 'dev1', '2021-04-28 13:16:15', '0000-00-00', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', '', '0000-00-00 00:00:00', '0000-00-00', '0', 0, '', 0, 0, 0, '', '', '', ''),
(12, 7, 0, 1, 0, 0, 2, 1, 0, 0, '新闻中心的设计', 'design', 1, 7, 0, 7, '0000-00-00', 'wait', '', '', NULL, '新闻中心的设计', 1, 'admin', '2021-04-28 13:16:15', 'dev1', '2021-04-28 13:16:15', '0000-00-00', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', '', '0000-00-00 00:00:00', '0000-00-00', '0', 0, '', 0, 0, 0, '', '', '', ''),
(10, 7, 0, 1, 0, 0, 1, 1, 0, 0, '首页页面的设计', 'design', 1, 7, 8, 0, '0000-00-00', 'done', '', '', NULL, '首页页面的设计', 1, 'admin', '2021-04-28 13:16:15', 'dev1', '2021-04-28 13:17:54', '0000-00-00', '2021-04-28 13:17:54', 'dev1', '2021-04-01 16:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', 'dev1', '2021-04-28 13:17:54', '0000-00-00', '0', 0, '', 0, 0, 0, '', '', '', ''),
(11, 7, 0, 1, 0, 0, 1, 1, 0, 0, '首页页面的开发', 'devel', 1, 8, 0, 8, '0000-00-00', 'doing', '', '', NULL, '首页页面的开发', 1, 'admin', '2021-04-28 13:16:15', 'dev1', '2021-04-28 13:16:15', '0000-00-00', '2021-04-01 16:00:00', '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', 'dev1', '2021-04-28 13:18:45', '0000-00-00', '0', 0, '', 0, 0, 0, '', '', '', '');
INSERT INTO `zt_taskestimate` (`id`, `task`, `date`, `left`, `consumed`, `account`, `work`) VALUES
(1, 10, '2021-04-01', 0, 8, 'dev1', ''),
(2, 11, '2021-04-01', 8, 0, 'dev1', ''),
@@ -647,18 +647,18 @@ INSERT INTO `zt_team` (`id`, `root`, `type`, `account`, `role`, `limited`, `join
(17, 2, 'execution', 'testManager', '测试负责人', 'no', '2021-04-28', 260, 7.0, '0.00', '0.00', '0.00', 0),
(18, 7, 'project', 'productManager', '', 'no', '2021-04-28', 0, 0.0, '0.00', '0.00', '0.00', 0),
(19, 7, 'project', 'projectManager', '', 'no', '2021-04-28', 0, 0.0, '0.00', '0.00', '0.00', 0);
INSERT INTO `zt_testresult` (`id`, `run`, `case`, `version`, `job`, `compile`, `caseResult`, `stepResults`, `lastRunner`, `date`, `duration`, `xml`) VALUES
(1, 4, 1, 1, 0, 0, 'pass', 'a:1:{i:1;a:2:{s:6:\"result\";s:4:\"pass\";s:4:\"real\";s:0:\"\";}}', 'testManager', '2012-06-05 11:11:00', 0, ''),
(2, 3, 2, 1, 0, 0, 'pass', 'a:1:{i:2;a:2:{s:6:\"result\";s:4:\"pass\";s:4:\"real\";s:0:\"\";}}', 'testManager', '2012-06-05 11:11:05', 0, ''),
(3, 2, 3, 1, 0, 0, 'pass', 'a:1:{i:3;a:2:{s:6:\"result\";s:4:\"pass\";s:4:\"real\";s:0:\"\";}}', 'testManager', '2012-06-05 11:11:07', 0, ''),
(4, 1, 4, 1, 0, 0, 'pass', 'a:1:{i:4;a:2:{s:6:\"result\";s:4:\"pass\";s:4:\"real\";s:0:\"\";}}', 'testManager', '2012-06-05 11:11:08', 0, '');
INSERT INTO `zt_testresult` (`id`, `run`, `case`, `version`, `job`, `compile`, `caseResult`, `stepResults`, `lastRunner`, `date`, `duration`, `xml`, `ZTFResult`, `deploy`) VALUES
(1, 4, 1, 1, 0, 0, 'pass', 'a:1:{i:1;a:2:{s:6:\"result\";s:4:\"pass\";s:4:\"real\";s:0:\"\";}}', 'testManager', '2012-06-05 11:11:00', 0, '', '', 0),
(2, 3, 2, 1, 0, 0, 'pass', 'a:1:{i:2;a:2:{s:6:\"result\";s:4:\"pass\";s:4:\"real\";s:0:\"\";}}', 'testManager', '2012-06-05 11:11:05', 0, '', '', 0),
(3, 2, 3, 1, 0, 0, 'pass', 'a:1:{i:3;a:2:{s:6:\"result\";s:4:\"pass\";s:4:\"real\";s:0:\"\";}}', 'testManager', '2012-06-05 11:11:07', 0, '', '', 0),
(4, 1, 4, 1, 0, 0, 'pass', 'a:1:{i:4;a:2:{s:6:\"result\";s:4:\"pass\";s:4:\"real\";s:0:\"\";}}', 'testManager', '2012-06-05 11:11:08', 0, '', '', 0);
INSERT INTO `zt_testrun` (`id`, `task`, `case`, `version`, `assignedTo`, `lastRunner`, `lastRunDate`, `lastRunResult`, `status`) VALUES
(1, 1, 4, 1, '', 'testManager', '2012-06-05 11:11:08', 'pass', 'done'),
(2, 1, 3, 1, '', 'testManager', '2012-06-05 11:11:07', 'pass', 'done'),
(3, 1, 2, 1, '', 'testManager', '2012-06-05 11:11:05', 'pass', 'done'),
(4, 1, 1, 1, '', 'testManager', '2012-06-05 11:11:00', 'pass', 'done');
INSERT INTO `zt_testtask` (`id`, `project`, `name`, `product`, `execution`, `build`, `owner`, `pri`, `begin`, `end`, `mailto`, `desc`, `report`, `status`, `auto`, `subStatus`, `deleted`) VALUES
(1, 0, '企业网站第一期测试任务', 1, 1, '1', 'testManager', 0, '2020-06-05', '2021-06-21', '', '', '', 'wait', 'no', '', '0');
INSERT INTO `zt_testtask` (`id`, `project`, `name`, `product`, `execution`, `build`, `owner`, `pri`, `begin`, `end`, `mailto`, `desc`, `report`, `status`, `auto`, `subStatus`, `deleted`, `testreport`, `createdBy`, `createdDate`) VALUES
(1, 0, '企业网站第一期测试任务', 1, 1, '1', 'testManager', 0, '2020-06-05', '2021-06-21', '', '', '', 'wait', 'no', '', '0', '0', 'testManager', '2021-01-06 10:10:20');
REPLACE INTO `zt_user` (`company`, `dept`, `account`, `type`, `password`, `role`, `realname`, `nickname`, `commiter`, `avatar`, `birthday`, `gender`, `email`, `skype`, `qq`, `mobile`, `phone`, `weixin`, `dingding`, `slack`, `whatsapp`, `address`, `zipcode`, `nature`, `analysis`, `strategy`, `join`, `visits`, `ip`, `last`, `fails`, `locked`, `ranzhi`, `score`, `scoreLevel`, `deleted`) VALUES
(0, 5, 'productManager', 'inside', 'e10adc3949ba59abbe56e057f20f883e', 'po', '产品经理', '', '', '', '0000-00-00', 'm', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '0000-00-00', 3, '192.168.0.8', 1338866083, 0, '0000-00-00 00:00:00', '', 0, 0, '0'),
(0, 6, 'projectManager', 'inside', 'e10adc3949ba59abbe56e057f20f883e', 'pm', '项目经理', '', '', '', '0000-00-00', 'm', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '0000-00-00', 4, '10.0.2.2', 1619580798, 0, '0000-00-00 00:00:00', '', 0, 0, '0'),
+62 -62
View File
@@ -213,20 +213,20 @@ INSERT INTO `zt_block` (`id`, `account`, `module`, `type`, `title`, `source`, `b
(60, 'dev3', 'my', '', '待处理', '', 'assigntome', '{\"todoCount\":\"20\",\"taskCount\":\"20\",\"bugCount\":\"20\",\"riskCount\":\"20\",\"issueCount\":\"20\",\"storyCount\":\"20\",\"meetingCount\":\"20\"}', 7, 8, 0, 0),
(61, 'dev3', 'my', '', '项目人力投入', 'project', 'projectteam', '', 8, 8, 0, 0),
(62, 'dev3', 'my', '', '项目列表', 'project', 'project', '{\"orderBy\":\"id_desc\",\"count\":\"15\"}', 9, 8, 0, 0);
INSERT INTO `zt_bug` (`id`, `project`, `product`, `branch`, `module`, `execution`, `plan`, `story`, `storyVersion`, `task`, `toTask`, `toStory`, `title`, `keywords`, `severity`, `pri`, `type`, `os`, `browser`, `hardware`, `found`, `steps`, `status`, `subStatus`, `color`, `confirmed`, `activatedCount`, `activatedDate`, `mailto`, `openedBy`, `openedDate`, `openedBuild`, `assignedTo`, `assignedDate`, `deadline`, `resolvedBy`, `resolution`, `resolvedBuild`, `resolvedDate`, `closedBy`, `closedDate`, `duplicateBug`, `linkBug`, `case`, `caseVersion`, `result`, `repo`, `entry`, `lines`, `v1`, `v2`, `repoType`, `testtask`, `lastEditedBy`, `lastEditedDate`, `deleted`) VALUES
(1, 7, 1, 0, 8, 1, 0, 1, 1, 1, 0, 0, '首页页面问题', '', 3, 1, 'codeerror', '', '', '', '', '<p>[步骤]进入首页</p>\r\n<p>[结果]出现乱码&nbsp;&nbsp;&nbsp;&nbsp;</p>\r\n<p>[期望]正常显示</p>', 'active', '', '', 0, 0, '0000-00-00 00:00:00', '', 'tester1', '2012-06-05 10:56:11', 'trunk', 'dev1', '2012-06-05 10:56:11', '0000-00-00', '', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, '', 0, 1, 0, 0, '', '', '', '', '', 0, 'admin', '2021-04-28 11:09:08', '0'),
(2, 7, 1, 0, 9, 1, 0, 2, 1, 4, 0, 0, '新闻中心页面问题', '', 3, 2, 'codeerror', '', '', '', '', '<p>[步骤]进入新闻中心</p>\r\n<p>[结果]页面出现乱码</p>\r\n<p>[期望]正常显示</p>', 'active', '', '', 0, 0, '0000-00-00 00:00:00', '', 'tester1', '2012-06-05 10:57:11', 'trunk', 'dev1', '2012-06-05 10:57:11', '0000-00-00', '', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, '', 0, 1, 0, 0, '', '', '', '', '', 0, 'admin', '2021-04-28 11:09:08', '0'),
(3, 7, 1, 0, 10, 1, 0, 3, 2, 6, 0, 0, '成果展示页面问题', '', 3, 1, 'codeerror', '', '', '', '', '<p>[步骤]进入成果展示&nbsp;&nbsp;&nbsp;&nbsp;</p>\r\n<p>[结果]乱码</p>\r\n<p>[期望]正常显示</p>', 'active', '', '', 0, 0, '0000-00-00 00:00:00', '', 'tester2', '2012-06-05 10:58:22', 'trunk', 'dev1', '2012-06-05 10:58:22', '0000-00-00', '', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, '', 0, 1, 0, 0, '', '', '', '', '', 0, 'admin', '2021-04-28 11:09:08', '0'),
(4, 7, 1, 0, 11, 1, 0, 4, 1, 9, 0, 0, '售后服务页面问题', '', 3, 1, 'codeerror', '', '', '', '', '<p>[步骤]进入售后服务</p>\r\n<p>[结果]乱码</p>\r\n<p>[期望]正常显示</p>', 'active', '', '', 0, 0, '0000-00-00 00:00:00', '', 'tester3', '2012-06-05 11:00:19', 'trunk', 'dev1', '2012-06-05 11:00:19', '0000-00-00', '', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, '', 0, 1, 0, 0, '', '', '', '', '', 0, 'admin', '2021-04-28 11:09:08', '0');
INSERT INTO `zt_build` (`id`, `project`, `product`, `branch`, `execution`, `name`, `scmPath`, `filePath`, `date`, `stories`, `bugs`, `builder`, `desc`, `deleted`) VALUES
(1, 7, 1, 0, 1, '第一期版本', '', '', '2012-06-05', '3,2,1,4', '', 'projectManager', '', '0');
INSERT INTO `zt_bug` (`id`, `project`, `product`, `branch`, `module`, `execution`, `plan`, `story`, `storyVersion`, `task`, `toTask`, `toStory`, `title`, `keywords`, `severity`, `pri`, `type`, `os`, `browser`, `hardware`, `found`, `steps`, `status`, `subStatus`, `color`, `confirmed`, `activatedCount`, `activatedDate`, `mailto`, `openedBy`, `openedDate`, `openedBuild`, `assignedTo`, `assignedDate`, `deadline`, `resolvedBy`, `resolution`, `resolvedBuild`, `resolvedDate`, `closedBy`, `closedDate`, `duplicateBug`, `linkBug`, `case`, `caseVersion`, `result`, `repo`, `entry`, `lines`, `v1`, `v2`, `repoType`, `testtask`, `lastEditedBy`, `lastEditedDate`, `deleted`, `feedbackBy`, `mr`, `notifyEmail`) VALUES
(1, 7, 1, 0, 8, 1, 0, 1, 1, 1, 0, 0, '首页页面问题', '', 3, 1, 'codeerror', '', '', '', '', '<p>[步骤]进入首页</p>\r\n<p>[结果]出现乱码&nbsp;&nbsp;&nbsp;&nbsp;</p>\r\n<p>[期望]正常显示</p>', 'active', '', '', 0, 0, '0000-00-00 00:00:00', '', 'tester1', '2012-06-05 10:56:11', 'trunk', 'dev1', '2012-06-05 10:56:11', '0000-00-00', '', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, '', 0, 1, 0, 0, '', '', '', '', '', 0, 'admin', '2021-04-28 11:09:08', '0', '', 0, ''),
(2, 7, 1, 0, 9, 1, 0, 2, 1, 4, 0, 0, '新闻中心页面问题', '', 3, 2, 'codeerror', '', '', '', '', '<p>[步骤]进入新闻中心</p>\r\n<p>[结果]页面出现乱码</p>\r\n<p>[期望]正常显示</p>', 'active', '', '', 0, 0, '0000-00-00 00:00:00', '', 'tester1', '2012-06-05 10:57:11', 'trunk', 'dev1', '2012-06-05 10:57:11', '0000-00-00', '', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, '', 0, 1, 0, 0, '', '', '', '', '', 0, 'admin', '2021-04-28 11:09:08', '0', '', 0, ''),
(3, 7, 1, 0, 10, 1, 0, 3, 2, 6, 0, 0, '成果展示页面问题', '', 3, 1, 'codeerror', '', '', '', '', '<p>[步骤]进入成果展示&nbsp;&nbsp;&nbsp;&nbsp;</p>\r\n<p>[结果]乱码</p>\r\n<p>[期望]正常显示</p>', 'active', '', '', 0, 0, '0000-00-00 00:00:00', '', 'tester2', '2012-06-05 10:58:22', 'trunk', 'dev1', '2012-06-05 10:58:22', '0000-00-00', '', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, '', 0, 1, 0, 0, '', '', '', '', '', 0, 'admin', '2021-04-28 11:09:08', '0', '', 0, ''),
(4, 7, 1, 0, 11, 1, 0, 4, 1, 9, 0, 0, '售后服务页面问题', '', 3, 1, 'codeerror', '', '', '', '', '<p>[步骤]进入售后服务</p>\r\n<p>[结果]乱码</p>\r\n<p>[期望]正常显示</p>', 'active', '', '', 0, 0, '0000-00-00 00:00:00', '', 'tester3', '2012-06-05 11:00:19', 'trunk', 'dev1', '2012-06-05 11:00:19', '0000-00-00', '', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, '', 0, 1, 0, 0, '', '', '', '', '', 0, 'admin', '2021-04-28 11:09:08', '0', '', 0, '');
INSERT INTO `zt_build` (`id`, `project`, `product`, `branch`, `execution`, `name`, `scmPath`, `filePath`, `date`, `stories`, `bugs`, `builder`, `desc`, `deleted`, `builds`, `createdBy`, `createdDate`) VALUES
(1, 7, 1, 0, 1, '第一期版本', '', '', '2012-06-05', '3,2,1,4', '', 'projectManager', '', '0', '', 'tester1', '2012-06-05 11:11:11');
INSERT INTO `zt_burn` (`execution`, `product`, `task`, `date`, `estimate`, `left`, `consumed`, `storyPoint`) VALUES
(1, 0, 0, '2012-06-05', 0, 0, 38, 0);
INSERT INTO `zt_case` (`id`, `project`, `product`, `branch`, `lib`, `module`, `path`, `story`, `storyVersion`, `title`, `precondition`, `keywords`, `pri`, `type`, `auto`, `frame`, `stage`, `howRun`, `scriptedBy`, `scriptedDate`, `scriptStatus`, `scriptLocation`, `status`, `subStatus`, `color`, `frequency`, `order`, `openedBy`, `openedDate`, `reviewedBy`, `reviewedDate`, `lastEditedBy`, `lastEditedDate`, `version`, `linkCase`, `fromBug`, `fromCaseID`, `fromCaseVersion`, `deleted`, `lastRunner`, `lastRunDate`, `lastRunResult`, `execution`) VALUES
(1, 7, 1, 0, 0, 0, 0, 4, 1, '售后服务的测试用例', '', '', 1, 'feature', 'no', '', 'feature', '', '', '0000-00-00', '', '', 'normal', '', '', '1', 0, 'tester3', '2012-06-05 11:02:18', '', '0000-00-00', 'tester3', '2012-06-05 11:02:46', 1, '', 0, 0, 1, '0', 'testManager', '2012-06-05 11:11:00', 'pass', 0),
(2, 7, 1, 0, 0, 0, 0, 1, 1, '首页的测试用例', '', '', 3, 'feature', 'no', '', '', '', '', '0000-00-00', '', '', 'normal', '', '', '1', 0, 'tester1', '2012-06-05 11:03:28', '', '0000-00-00', '', '0000-00-00 00:00:00', 1, '', 0, 0, 1, '0', 'testManager', '2012-06-05 11:11:05', 'pass', 0),
(3, 7, 1, 0, 0, 0, 0, 2, 1, '新闻中心的测试用例', '', '', 3, 'feature', 'no', '', 'feature', '', '', '0000-00-00', '', '', 'normal', '', '', '1', 0, 'tester1', '2012-06-05 11:03:54', '', '0000-00-00', '', '0000-00-00 00:00:00', 1, '', 0, 0, 1, '0', 'testManager', '2012-06-05 11:11:07', 'pass', 0),
(4, 7, 1, 0, 0, 0, 0, 3, 2, '成果展示测试用例', '', '', 3, 'feature', 'no', '', 'feature', '', '', '0000-00-00', '', '', 'normal', '', '', '1', 0, 'tester2', '2012-06-05 11:04:48', '', '0000-00-00', '', '0000-00-00 00:00:00', 1, '', 0, 0, 1, '0', 'testManager', '2012-06-05 11:11:08', 'pass', 0);
INSERT INTO `zt_case` (`id`, `project`, `product`, `branch`, `lib`, `module`, `path`, `story`, `storyVersion`, `title`, `precondition`, `keywords`, `pri`, `type`, `auto`, `frame`, `stage`, `howRun`, `scriptedBy`, `scriptedDate`, `scriptStatus`, `scriptLocation`, `status`, `subStatus`, `color`, `frequency`, `order`, `openedBy`, `openedDate`, `reviewedBy`, `reviewedDate`, `lastEditedBy`, `lastEditedDate`, `version`, `linkCase`, `fromBug`, `fromCaseID`, `fromCaseVersion`, `deleted`, `lastRunner`, `lastRunDate`, `lastRunResult`, `execution`, `script`) VALUES
(1, 7, 1, 0, 0, 0, 0, 4, 1, '售后服务的测试用例', '', '', 1, 'feature', 'no', '', 'feature', '', '', '0000-00-00', '', '', 'normal', '', '', '1', 0, 'tester3', '2012-06-05 11:02:18', '', '0000-00-00', 'tester3', '2012-06-05 11:02:46', 1, '', 0, 0, 1, '0', 'testManager', '2012-06-05 11:11:00', 'pass', 0, ''),
(2, 7, 1, 0, 0, 0, 0, 1, 1, '首页的测试用例', '', '', 3, 'feature', 'no', '', '', '', '', '0000-00-00', '', '', 'normal', '', '', '1', 0, 'tester1', '2012-06-05 11:03:28', '', '0000-00-00', '', '0000-00-00 00:00:00', 1, '', 0, 0, 1, '0', 'testManager', '2012-06-05 11:11:05', 'pass', 0, ''),
(3, 7, 1, 0, 0, 0, 0, 2, 1, '新闻中心的测试用例', '', '', 3, 'feature', 'no', '', 'feature', '', '', '0000-00-00', '', '', 'normal', '', '', '1', 0, 'tester1', '2012-06-05 11:03:54', '', '0000-00-00', '', '0000-00-00 00:00:00', 1, '', 0, 0, 1, '0', 'testManager', '2012-06-05 11:11:07', 'pass', 0, ''),
(4, 7, 1, 0, 0, 0, 0, 3, 2, '成果展示测试用例', '', '', 3, 'feature', 'no', '', 'feature', '', '', '0000-00-00', '', '', 'normal', '', '', '1', 0, 'tester2', '2012-06-05 11:04:48', '', '0000-00-00', '', '0000-00-00 00:00:00', 1, '', 0, 0, 1, '0', 'testManager', '2012-06-05 11:11:08', 'pass', 0, '');
INSERT INTO `zt_casestep` (`id`, `parent`, `case`, `version`, `type`, `desc`, `expect`) VALUES
(1, 0, 1, 1, 'step', '进入首页', '正常显示'),
(2, 0, 2, 1, 'step', '进入首页', '正常显示'),
@@ -241,12 +241,12 @@ INSERT INTO `zt_dept` (`id`, `name`, `parent`, `path`, `grade`, `order`, `positi
(6, '项目', 1, ',1,6,', 2, 0, '', '', ''),
(7, '编程', 2, ',2,7,', 2, 0, '', '', ''),
(8, '美工', 2, ',2,8,', 2, 0, '', '', '');
INSERT INTO `zt_doclib` (`id`, `type`, `product`, `project`, `execution`, `name`, `acl`, `groups`, `users`, `main`, `collector`, `order`, `deleted`) VALUES
(1, 'product', 1, 0, 0, '产品库', 'default', '', '', '1', '', 0, '0'),
(2, 'product', 2, 0, 0, '产品库', 'default', '', '', '1', '', 0, '0'),
(3, 'execution', 0, 0, 1, '项目库', 'default', '', '', '1', '', 0, '0'),
(4, 'execution', 0, 0, 2, '项目库', 'default', '', '', '1', '', 0, '0'),
(5, 'project', 0, 7, 0, '项目主库', 'default', '', '', '1', '', 0, '0');
INSERT INTO `zt_doclib` (`id`, `type`, `product`, `project`, `execution`, `name`, `acl`, `groups`, `users`, `main`, `collector`, `order`, `deleted`, `addedBy`, `addedDate`) VALUES
(1, 'product', 1, 0, 0, '产品库', 'default', '', '', '1', '', 0, '0', 'tester1', '2012-06-05 10:11:32'),
(2, 'product', 2, 0, 0, '产品库', 'default', '', '', '1', '', 0, '0', 'tester1', '2012-06-05 10:11:32'),
(3, 'execution', 0, 0, 1, '项目库', 'default', '', '', '1', '', 0, '0', 'tester1', '2012-06-05 10:11:32'),
(4, 'execution', 0, 0, 2, '项目库', 'default', '', '', '1', '', 0, '0', 'tester1', '2012-06-05 10:11:32'),
(5, 'project', 0, 7, 0, '项目主库', 'default', '', '', '1', '', 0, '0', 'tester1', '2012-06-05 10:11:32');
INSERT INTO `zt_history` (`id`, `action`, `field`, `old`, `new`, `diff`) VALUES
(1, 14, 'version', '1', '2', ''),
(2, 14, 'spec', '&nbsp;作为一名本公司的用户,我希望可以在成果展示看到该公司网站的企业新闻,这样可以方便我进行了解该公司的产品并进行购买。&nbsp;<br />', '&nbsp;作为一名本公司的用户,我希望可以在成果展示看到该公司网站的吹产品,这样可以方便我进行了解该公司的产品并进行购买。&nbsp;<br />', '001- <del>作为一名本公司的用户,我希望可以在成果展示看到该公司网站的企业新闻,这样可以方便我进行了解该公司的产品并进行购买。<br /></del>\n001+ <ins>作为一名本公司的用户,我希望可以在成果展示看到该公司网站的吹产品,这样可以方便我进行了解该公司的产品并进行购买。<br /></ins>'),
@@ -380,8 +380,8 @@ INSERT INTO `zt_module` (`id`, `root`, `branch`, `name`, `parent`, `path`, `grad
INSERT INTO `zt_product` (`id`, `program`, `name`, `code`, `bind`, `line`, `type`, `status`, `subStatus`, `desc`, `PO`, `QD`, `RD`, `acl`, `whitelist`, `createdBy`, `createdDate`, `createdVersion`, `order`, `deleted`) VALUES
(1, 6, '公司企业网站建设', 'companyWebsite', '0', 0, 'normal', 'normal', '', '建立公司企业网站,可以更好对外展示。<br />', 'productManager', 'testManager', 'productManager', 'open', '', 'productManager', '2012-06-05 09:57:07', '', 5, '0'),
(2, 6, '企业内部工时管理系统', 'workhourManage', '0', 0, 'normal', 'normal', '', '', 'productManager', 'testManager', 'productManager', 'open', '', 'productManager', '2012-06-05 11:15:20', '5.2.1', 10, '0');
INSERT INTO `zt_productplan` (`id`, `product`, `branch`, `parent`, `title`, `desc`, `begin`, `end`, `order`, `deleted`) VALUES
(1, 1, 0, 0, '1.0版本', '开发出企业网站1.0版本。<br />', '2020-06-05', '2021-06-04', '', '0');
INSERT INTO `zt_productplan` (`id`, `product`, `branch`, `parent`, `title`, `desc`, `begin`, `end`, `order`, `deleted`, `createdBy`, `createdDate`) VALUES
(1, 1, 0, 0, '1.0版本', '开发出企业网站1.0版本。<br />', '2020-06-05', '2021-06-04', '', '0', 'tester1', '2021-04-01 11:08:09');
INSERT INTO `zt_project` (`id`, `project`, `model`, `type`, `lifetime`, `budget`, `budgetUnit`, `attribute`, `percent`, `milestone`, `output`, `auth`, `parent`, `path`, `grade`, `name`, `code`, `begin`, `end`, `realBegan`, `realEnd`, `days`, `status`, `subStatus`, `pri`, `desc`, `version`, `parentVersion`, `planDuration`, `realDuration`, `openedBy`, `openedDate`, `openedVersion`, `lastEditedBy`, `lastEditedDate`, `closedBy`, `closedDate`, `canceledBy`, `canceledDate`, `PO`, `PM`, `QD`, `RD`, `team`, `acl`, `whitelist`, `order`, `deleted`) VALUES
(1, 7, '', 'sprint', 'sprint', '0', 'CNY', '', 0, '0', '', '', 7, ',7,1,', 1, '企业网站第一期', 'coWeb1', '2020-06-05', '2021-12-04', '0000-00-00', '0000-00-00', 391, 'doing', '', '1', '开发企业网站的基本雏形。<br />', 0, 0, 0, 0, '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 'productManager', 'projectManager', 'testManager', 'productManager', '公司开发团队', 'open', '', 5, '0'),
(2, 7, '', 'sprint', 'sprint', '0', 'CNY', '', 0, '0', '', '', 7, ',7,2,', 1, '企业网站第二期', 'coWebsite2', '2021-06-05', '2022-06-04', '0000-00-00', '0000-00-00', 260, 'wait', '', '1', '', 0, 0, 0, 0, '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 'productManager', 'projectManager', 'testManager', 'productManager', '公司开发团队', 'open', '', 10, '0'),
@@ -401,15 +401,15 @@ INSERT INTO `zt_projectproduct` (`project`, `product`, `branch`, `plan`) VALUES
(2, 1, 0, 0),
(7, 1, 0, 0),
(7, 2, 0, 0);
INSERT INTO `zt_projectstory` (`project`, `product`, `story`, `version`, `order`) VALUES
(1, 1, 1, 1, 0),
(1, 1, 2, 1, 0),
(1, 1, 3, 2, 0),
(1, 1, 4, 1, 0),
(7, 1, 4, 1, 0),
(7, 1, 3, 2, 0),
(7, 1, 2, 1, 0),
(7, 1, 1, 1, 0);
INSERT INTO `zt_projectstory` (`project`, `product`, `story`, `version`, `order`, `branch`) VALUES
(1, 1, 1, 1, 0, 0),
(1, 1, 2, 1, 0, 0),
(1, 1, 3, 2, 0, 0),
(1, 1, 4, 1, 0, 0),
(7, 1, 4, 1, 0, 0),
(7, 1, 3, 2, 0, 0),
(7, 1, 2, 1, 0, 0),
(7, 1, 1, 1, 0, 0);
INSERT INTO `zt_searchdict` (`key`, `value`) VALUES
(39318, '首'),
(39029, '页'),
@@ -584,32 +584,32 @@ INSERT INTO `zt_searchindex` (`id`, `objectType`, `objectID`, `title`, `content`
(39, 'task', 15, ' 25104 26524 23637 31034 30340 24320 21457', ' 25104 26524 23637 31034 30340 24320 21457', '2021-04-28 13:16:15', '2021-04-28 13:16:15'),
(40, 'task', 16, ' 21806 21518 26381 21153 30340 35774 35745', ' 21806 21518 26381 21153 30340 35774 35745', '2021-04-28 13:16:15', '2021-04-28 13:16:15'),
(41, 'task', 17, ' 21806 21518 26381 21153 30340 24320 21457', ' 21806 21518 26381 21153 30340 24320 21457', '2021-04-28 13:16:15', '2021-04-28 13:16:15');
INSERT INTO `zt_story` (`id`, `parent`, `product`, `branch`, `module`, `plan`, `source`, `sourceNote`, `fromBug`, `title`, `keywords`, `type`, `pri`, `estimate`, `status`, `subStatus`, `color`, `stage`, `stagedBy`, `mailto`, `openedBy`, `openedDate`, `assignedTo`, `assignedDate`, `lastEditedBy`, `lastEditedDate`, `reviewedBy`, `reviewedDate`, `closedBy`, `closedDate`, `closedReason`, `toBug`, `childStories`, `linkStories`, `duplicateStory`, `version`, `URChanged`, `deleted`) VALUES
(1, 0, 1, 0, 1, '1', 'po', '', 0, '首页设计和开发', '', 'story', 1, 1, 'active', '', '', 'developing', '', '', 'productManager', '2012-06-05 10:09:49', 'productManager', '0000-00-00 00:00:00', 'productManager', '2012-06-05 10:25:19', 'productManager, ', '2012-06-05 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 1, '0', '0'),
(2, 0, 1, 0, 2, '1', 'po', '', 0, '新闻中心的设计和开发。', '', 'story', 1, 1, 'active', '', '', 'projected', '', '', 'productManager', '2012-06-05 10:16:37', 'productManager', '2012-06-05 10:16:37', 'productManager', '2012-06-05 10:25:33', 'productManager, ', '2012-06-05 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 1, '0', '0'),
(3, 0, 1, 0, 3, '1', 'po', '', 0, '成果展示的设计和开发', '', 'story', 1, 0, 'active', '', '', 'developing', '', '', 'productManager', '2012-06-05 10:18:10', 'productManager', '2012-06-05 10:18:10', 'productManager', '2012-06-05 10:25:38', 'productManager, ', '2012-06-05 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 2, '0', '0'),
(4, 0, 1, 0, 4, '1', 'po', '', 0, '售后服务的设计和开发', '', 'story', 1, 1, 'active', '', '', 'developed', '', '', 'productManager', '2012-06-05 10:20:16', 'productManager', '2012-06-05 10:20:16', 'productManager', '2012-06-05 10:25:42', 'productManager, ', '2012-06-05 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 1, '0', '0'),
(5, 0, 1, 0, 5, '1', 'po', '', 0, '诚聘英才的设计和开发', '', 'story', 1, 1, 'reviewing', '', '', 'planned', '', '', 'productManager', '2012-06-05 10:21:39', 'productManager', '2012-06-05 10:21:39', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 1, '0', '0'),
(6, 0, 1, 0, 6, '1', 'po', '', 0, '合作洽谈的设计和开发', '', 'story', 1, 1, 'reviewing', '', '', 'planned', '', '', 'productManager', '2012-06-05 10:23:11', 'productManager', '2012-06-05 10:23:11', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 1, '0', '0'),
(7, 0, 1, 0, 7, '1', 'po', '', 0, '关于我们的设计和开发', '', 'story', 1, 1, 'reviewing', '', '', 'planned', '', '', 'productManager', '2012-06-05 10:24:19', 'productManager', '2012-06-05 10:24:19', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 1, '0', '0');
INSERT INTO `zt_storyspec` (`story`, `version`, `title`, `spec`, `verify`) VALUES
(1, 1, '首页设计和开发', '作为一名本公司的用户,我希望可以在首页看到该公司网站的基本内容,例如最新动态、部分成果展示、联系信息、工商信息等。<br />', '开发并通过验收<br />'),
(2, 1, '新闻中心的设计和开发。', '作为一名本公司的用户,我希望可以在新闻中心看到该公司网站的企业新闻,这样可以通过新闻了解企业的最新动态。<br />', ''),
(3, 1, '成果展示的设计和开发', '&nbsp;作为一名本公司的用户,我希望可以在成果展示看到该公司网站的企业新闻,这样可以方便我进行了解该公司的产品并进行购买。&nbsp;<br />', ''),
(3, 2, '成果展示的设计和开发', '&nbsp;作为一名本公司的用户,我希望可以在成果展示看到该公司网站的吹产品,这样可以方便我进行了解该公司的产品并进行购买。&nbsp;<br />', ''),
(4, 1, '售后服务的设计和开发', '作为一名本公司的用户,我希望可以在售后服务看到该公司网站的售后服务,这样可以方便我联系该公司来解决我的问题。&nbsp;<br />', ''),
(5, 1, '诚聘英才的设计和开发', '作为一名求职者,我希望可以在诚聘英才里看到该公司的招聘信息,这样可以方便我应聘该公司。&nbsp;<br />', ''),
(6, 1, '合作洽谈的设计和开发', '作为一名合作商,我希望可以在合作洽谈里看到该公司对外的合作内容,这样可以方便我和该公司进行合作洽谈。&nbsp;<br />', ''),
(7, 1, '关于我们的设计和开发', '我希望可以在关于我们里看到该公司的基本信息,这样可以方便我了解该公司。<br />', '');
INSERT INTO `zt_task` (`id`, `project`, `parent`, `execution`, `module`, `design`, `story`, `storyVersion`, `designVersion`, `fromBug`, `name`, `type`, `pri`, `estimate`, `consumed`, `left`, `deadline`, `status`, `subStatus`, `color`, `mailto`, `desc`, `version`, `openedBy`, `openedDate`, `assignedTo`, `assignedDate`, `estStarted`, `realStarted`, `finishedBy`, `finishedDate`, `finishedList`, `canceledBy`, `canceledDate`, `closedBy`, `closedDate`, `realDuration`, `planDuration`, `closedReason`, `lastEditedBy`, `lastEditedDate`, `activatedDate`, `deleted`) VALUES
(17, 7, 0, 1, 0, 0, 4, 1, 0, 0, '售后服务的开发', 'devel', 1, 5, 5, 0, '0000-00-00', 'done', '', '', NULL, '售后服务的开发', 1, 'admin', '2021-04-28 13:16:15', 'dev3', '2021-04-28 13:21:51', '0000-00-00', '2021-04-02 08:00:00', 'dev3', '2021-04-06 15:30:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', 'dev3', '2021-04-28 13:21:51', '0000-00-00', '0'),
(16, 7, 0, 1, 0, 0, 4, 1, 0, 0, '售后服务的设计', 'design', 1, 5, 6, 0, '0000-00-00', 'done', '', '', NULL, '售后服务的设计', 1, 'admin', '2021-04-28 13:16:15', 'dev3', '2021-04-28 13:21:22', '0000-00-00', '2021-04-02 08:00:00', 'dev3', '2021-04-05 17:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', 'dev3', '2021-04-28 13:21:22', '0000-00-00', '0'),
(15, 7, 0, 1, 0, 0, 3, 2, 0, 0, '成果展示的开发', 'devel', 1, 7, 0, 7, '0000-00-00', 'doing', '', '', NULL, '成果展示的开发', 1, 'admin', '2021-04-28 13:16:15', 'dev2', '2021-04-28 13:16:15', '0000-00-00', '2021-04-01 08:00:00', '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', 'dev2', '2021-04-28 13:20:09', '0000-00-00', '0'),
(14, 7, 0, 1, 0, 0, 3, 2, 0, 0, '成果展示的设计', 'design', 1, 6, 0, 6, '0000-00-00', 'doing', '', '', NULL, '成果展示的设计', 1, 'admin', '2021-04-28 13:16:15', 'dev2', '2021-04-28 13:16:15', '0000-00-00', '2021-04-01 08:00:00', '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', 'dev2', '2021-04-28 13:19:54', '0000-00-00', '0'),
(13, 7, 0, 1, 0, 0, 2, 1, 0, 0, '新闻中心的开发', 'devel', 1, 7, 0, 7, '0000-00-00', 'wait', '', '', NULL, '新闻中心的开发', 1, 'admin', '2021-04-28 13:16:15', 'dev1', '2021-04-28 13:16:15', '0000-00-00', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', '', '0000-00-00 00:00:00', '0000-00-00', '0'),
(12, 7, 0, 1, 0, 0, 2, 1, 0, 0, '新闻中心的设计', 'design', 1, 7, 0, 7, '0000-00-00', 'wait', '', '', NULL, '新闻中心的设计', 1, 'admin', '2021-04-28 13:16:15', 'dev1', '2021-04-28 13:16:15', '0000-00-00', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', '', '0000-00-00 00:00:00', '0000-00-00', '0'),
(10, 7, 0, 1, 0, 0, 1, 1, 0, 0, '首页页面的设计', 'design', 1, 7, 8, 0, '0000-00-00', 'done', '', '', NULL, '首页页面的设计', 1, 'admin', '2021-04-28 13:16:15', 'dev1', '2021-04-28 13:17:54', '0000-00-00', '2021-04-28 13:17:54', 'dev1', '2021-04-01 16:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', 'dev1', '2021-04-28 13:17:54', '0000-00-00', '0'),
(11, 7, 0, 1, 0, 0, 1, 1, 0, 0, '首页页面的开发', 'devel', 1, 8, 0, 8, '0000-00-00', 'doing', '', '', NULL, '首页页面的开发', 1, 'admin', '2021-04-28 13:16:15', 'dev1', '2021-04-28 13:16:15', '0000-00-00', '2021-04-01 16:00:00', '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', 'dev1', '2021-04-28 13:18:45', '0000-00-00', '0');
INSERT INTO `zt_story` (`id`, `parent`, `product`, `branch`, `module`, `plan`, `source`, `sourceNote`, `fromBug`, `title`, `keywords`, `type`, `pri`, `estimate`, `status`, `subStatus`, `color`, `stage`, `stagedBy`, `mailto`, `openedBy`, `openedDate`, `assignedTo`, `assignedDate`, `lastEditedBy`, `lastEditedDate`, `reviewedBy`, `reviewedDate`, `closedBy`, `closedDate`, `closedReason`, `toBug`, `childStories`, `linkStories`, `duplicateStory`, `version`, `URChanged`, `deleted`, `linkRequirements`, `twins`) VALUES
(1, 0, 1, 0, 1, '1', 'po', '', 0, '首页设计和开发', '', 'story', 1, 1, 'active', '', '', 'developing', '', '', 'productManager', '2012-06-05 10:09:49', 'productManager', '0000-00-00 00:00:00', 'productManager', '2012-06-05 10:25:19', 'productManager, ', '2012-06-05 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 1, '0', '0', '', ''),
(2, 0, 1, 0, 2, '1', 'po', '', 0, '新闻中心的设计和开发。', '', 'story', 1, 1, 'active', '', '', 'projected', '', '', 'productManager', '2012-06-05 10:16:37', 'productManager', '2012-06-05 10:16:37', 'productManager', '2012-06-05 10:25:33', 'productManager, ', '2012-06-05 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 1, '0', '0', '', ''),
(3, 0, 1, 0, 3, '1', 'po', '', 0, '成果展示的设计和开发', '', 'story', 1, 0, 'active', '', '', 'developing', '', '', 'productManager', '2012-06-05 10:18:10', 'productManager', '2012-06-05 10:18:10', 'productManager', '2012-06-05 10:25:38', 'productManager, ', '2012-06-05 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 2, '0', '0', '', ''),
(4, 0, 1, 0, 4, '1', 'po', '', 0, '售后服务的设计和开发', '', 'story', 1, 1, 'active', '', '', 'developed', '', '', 'productManager', '2012-06-05 10:20:16', 'productManager', '2012-06-05 10:20:16', 'productManager', '2012-06-05 10:25:42', 'productManager, ', '2012-06-05 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 1, '0', '0', '', ''),
(5, 0, 1, 0, 5, '1', 'po', '', 0, '诚聘英才的设计和开发', '', 'story', 1, 1, 'reviewing', '', '', 'planned', '', '', 'productManager', '2012-06-05 10:21:39', 'productManager', '2012-06-05 10:21:39', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 1, '0', '0', '', ''),
(6, 0, 1, 0, 6, '1', 'po', '', 0, '合作洽谈的设计和开发', '', 'story', 1, 1, 'reviewing', '', '', 'planned', '', '', 'productManager', '2012-06-05 10:23:11', 'productManager', '2012-06-05 10:23:11', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 1, '0', '0', '', ''),
(7, 0, 1, 0, 7, '1', 'po', '', 0, '关于我们的设计和开发', '', 'story', 1, 1, 'reviewing', '', '', 'planned', '', '', 'productManager', '2012-06-05 10:24:19', 'productManager', '2012-06-05 10:24:19', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', 0, '', '', 0, 1, '0', '0', '', '');
INSERT INTO `zt_storyspec` (`story`, `version`, `title`, `spec`, `verify`, `files`) VALUES
(1, 1, '首页设计和开发', '作为一名本公司的用户,我希望可以在首页看到该公司网站的基本内容,例如最新动态、部分成果展示、联系信息、工商信息等。<br />', '开发并通过验收<br />', ''),
(2, 1, '新闻中心的设计和开发。', '作为一名本公司的用户,我希望可以在新闻中心看到该公司网站的企业新闻,这样可以通过新闻了解企业的最新动态。<br />', '', ''),
(3, 1, '成果展示的设计和开发', '&nbsp;作为一名本公司的用户,我希望可以在成果展示看到该公司网站的企业新闻,这样可以方便我进行了解该公司的产品并进行购买。&nbsp;<br />', '', ''),
(3, 2, '成果展示的设计和开发', '&nbsp;作为一名本公司的用户,我希望可以在成果展示看到该公司网站的吹产品,这样可以方便我进行了解该公司的产品并进行购买。&nbsp;<br />', '', ''),
(4, 1, '售后服务的设计和开发', '作为一名本公司的用户,我希望可以在售后服务看到该公司网站的售后服务,这样可以方便我联系该公司来解决我的问题。&nbsp;<br />', '', ''),
(5, 1, '诚聘英才的设计和开发', '作为一名求职者,我希望可以在诚聘英才里看到该公司的招聘信息,这样可以方便我应聘该公司。&nbsp;<br />', '', ''),
(6, 1, '合作洽谈的设计和开发', '作为一名合作商,我希望可以在合作洽谈里看到该公司对外的合作内容,这样可以方便我和该公司进行合作洽谈。&nbsp;<br />', '', ''),
(7, 1, '关于我们的设计和开发', '我希望可以在关于我们里看到该公司的基本信息,这样可以方便我了解该公司。<br />', '', '');
INSERT INTO `zt_task` (`id`, `project`, `parent`, `execution`, `module`, `design`, `story`, `storyVersion`, `designVersion`, `fromBug`, `name`, `type`, `pri`, `estimate`, `consumed`, `left`, `deadline`, `status`, `subStatus`, `color`, `mailto`, `desc`, `version`, `openedBy`, `openedDate`, `assignedTo`, `assignedDate`, `estStarted`, `realStarted`, `finishedBy`, `finishedDate`, `finishedList`, `canceledBy`, `canceledDate`, `closedBy`, `closedDate`, `realDuration`, `planDuration`, `closedReason`, `lastEditedBy`, `lastEditedDate`, `activatedDate`, `deleted`, `feedback`, `mode`, `order`, `repo`, `mr`, `entry`, `lines`, `v1`, `v2`) VALUES
(17, 7, 0, 1, 0, 0, 4, 1, 0, 0, '售后服务的开发', 'devel', 1, 5, 5, 0, '0000-00-00', 'done', '', '', NULL, '售后服务的开发', 1, 'admin', '2021-04-28 13:16:15', 'dev3', '2021-04-28 13:21:51', '0000-00-00', '2021-04-02 08:00:00', 'dev3', '2021-04-06 15:30:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', 'dev3', '2021-04-28 13:21:51', '0000-00-00', '0', 0, '', 0, 0, 0, '', '', '', ''),
(16, 7, 0, 1, 0, 0, 4, 1, 0, 0, '售后服务的设计', 'design', 1, 5, 6, 0, '0000-00-00', 'done', '', '', NULL, '售后服务的设计', 1, 'admin', '2021-04-28 13:16:15', 'dev3', '2021-04-28 13:21:22', '0000-00-00', '2021-04-02 08:00:00', 'dev3', '2021-04-05 17:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', 'dev3', '2021-04-28 13:21:22', '0000-00-00', '0', 0, '', 0, 0, 0, '', '', '', ''),
(15, 7, 0, 1, 0, 0, 3, 2, 0, 0, '成果展示的开发', 'devel', 1, 7, 0, 7, '0000-00-00', 'doing', '', '', NULL, '成果展示的开发', 1, 'admin', '2021-04-28 13:16:15', 'dev2', '2021-04-28 13:16:15', '0000-00-00', '2021-04-01 08:00:00', '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', 'dev2', '2021-04-28 13:20:09', '0000-00-00', '0', 0, '', 0, 0, 0, '', '', '', ''),
(14, 7, 0, 1, 0, 0, 3, 2, 0, 0, '成果展示的设计', 'design', 1, 6, 0, 6, '0000-00-00', 'doing', '', '', NULL, '成果展示的设计', 1, 'admin', '2021-04-28 13:16:15', 'dev2', '2021-04-28 13:16:15', '0000-00-00', '2021-04-01 08:00:00', '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', 'dev2', '2021-04-28 13:19:54', '0000-00-00', '0', 0, '', 0, 0, 0, '', '', '', ''),
(13, 7, 0, 1, 0, 0, 2, 1, 0, 0, '新闻中心的开发', 'devel', 1, 7, 0, 7, '0000-00-00', 'wait', '', '', NULL, '新闻中心的开发', 1, 'admin', '2021-04-28 13:16:15', 'dev1', '2021-04-28 13:16:15', '0000-00-00', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', '', '0000-00-00 00:00:00', '0000-00-00', '0', 0, '', 0, 0, 0, '', '', '', ''),
(12, 7, 0, 1, 0, 0, 2, 1, 0, 0, '新闻中心的设计', 'design', 1, 7, 0, 7, '0000-00-00', 'wait', '', '', NULL, '新闻中心的设计', 1, 'admin', '2021-04-28 13:16:15', 'dev1', '2021-04-28 13:16:15', '0000-00-00', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', '', '0000-00-00 00:00:00', '0000-00-00', '0', 0, '', 0, 0, 0, '', '', '', ''),
(10, 7, 0, 1, 0, 0, 1, 1, 0, 0, '首页页面的设计', 'design', 1, 7, 8, 0, '0000-00-00', 'done', '', '', NULL, '首页页面的设计', 1, 'admin', '2021-04-28 13:16:15', 'dev1', '2021-04-28 13:17:54', '0000-00-00', '2021-04-28 13:17:54', 'dev1', '2021-04-01 16:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', 'dev1', '2021-04-28 13:17:54', '0000-00-00', '0', 0, '', 0, 0, 0, '', '', '', ''),
(11, 7, 0, 1, 0, 0, 1, 1, 0, 0, '首页页面的开发', 'devel', 1, 8, 0, 8, '0000-00-00', 'doing', '', '', NULL, '首页页面的开发', 1, 'admin', '2021-04-28 13:16:15', 'dev1', '2021-04-28 13:16:15', '0000-00-00', '2021-04-01 16:00:00', '', '0000-00-00 00:00:00', '', '', '0000-00-00 00:00:00', '', '0000-00-00 00:00:00', 0, 0, '', 'dev1', '2021-04-28 13:18:45', '0000-00-00', '0', 0, '', 0, 0, 0, '', '', '', '');
INSERT INTO `zt_taskestimate` (`id`, `task`, `date`, `left`, `consumed`, `account`, `work`) VALUES
(1, 10, '2021-04-01', 0, 8, 'dev1', ''),
(2, 11, '2021-04-01', 8, 0, 'dev1', ''),
@@ -647,18 +647,18 @@ INSERT INTO `zt_team` (`id`, `root`, `type`, `account`, `role`, `limited`, `join
(17, 2, 'execution', 'testManager', '测试负责人', 'no', '2021-04-28', 260, 7.0, '0.00', '0.00', '0.00', 0),
(18, 7, 'project', 'productManager', '', 'no', '2021-04-28', 0, 0.0, '0.00', '0.00', '0.00', 0),
(19, 7, 'project', 'projectManager', '', 'no', '2021-04-28', 0, 0.0, '0.00', '0.00', '0.00', 0);
INSERT INTO `zt_testresult` (`id`, `run`, `case`, `version`, `job`, `compile`, `caseResult`, `stepResults`, `lastRunner`, `date`, `duration`, `xml`) VALUES
(1, 4, 1, 1, 0, 0, 'pass', 'a:1:{i:1;a:2:{s:6:\"result\";s:4:\"pass\";s:4:\"real\";s:0:\"\";}}', 'testManager', '2012-06-05 11:11:00', 0, ''),
(2, 3, 2, 1, 0, 0, 'pass', 'a:1:{i:2;a:2:{s:6:\"result\";s:4:\"pass\";s:4:\"real\";s:0:\"\";}}', 'testManager', '2012-06-05 11:11:05', 0, ''),
(3, 2, 3, 1, 0, 0, 'pass', 'a:1:{i:3;a:2:{s:6:\"result\";s:4:\"pass\";s:4:\"real\";s:0:\"\";}}', 'testManager', '2012-06-05 11:11:07', 0, ''),
(4, 1, 4, 1, 0, 0, 'pass', 'a:1:{i:4;a:2:{s:6:\"result\";s:4:\"pass\";s:4:\"real\";s:0:\"\";}}', 'testManager', '2012-06-05 11:11:08', 0, '');
INSERT INTO `zt_testresult` (`id`, `run`, `case`, `version`, `job`, `compile`, `caseResult`, `stepResults`, `lastRunner`, `date`, `duration`, `xml`, `ZTFResult`, `deploy`) VALUES
(1, 4, 1, 1, 0, 0, 'pass', 'a:1:{i:1;a:2:{s:6:\"result\";s:4:\"pass\";s:4:\"real\";s:0:\"\";}}', 'testManager', '2012-06-05 11:11:00', 0, '', '', 0),
(2, 3, 2, 1, 0, 0, 'pass', 'a:1:{i:2;a:2:{s:6:\"result\";s:4:\"pass\";s:4:\"real\";s:0:\"\";}}', 'testManager', '2012-06-05 11:11:05', 0, '', '', 0),
(3, 2, 3, 1, 0, 0, 'pass', 'a:1:{i:3;a:2:{s:6:\"result\";s:4:\"pass\";s:4:\"real\";s:0:\"\";}}', 'testManager', '2012-06-05 11:11:07', 0, '', '', 0),
(4, 1, 4, 1, 0, 0, 'pass', 'a:1:{i:4;a:2:{s:6:\"result\";s:4:\"pass\";s:4:\"real\";s:0:\"\";}}', 'testManager', '2012-06-05 11:11:08', 0, '', '', 0);
INSERT INTO `zt_testrun` (`id`, `task`, `case`, `version`, `assignedTo`, `lastRunner`, `lastRunDate`, `lastRunResult`, `status`) VALUES
(1, 1, 4, 1, '', 'testManager', '2012-06-05 11:11:08', 'pass', 'done'),
(2, 1, 3, 1, '', 'testManager', '2012-06-05 11:11:07', 'pass', 'done'),
(3, 1, 2, 1, '', 'testManager', '2012-06-05 11:11:05', 'pass', 'done'),
(4, 1, 1, 1, '', 'testManager', '2012-06-05 11:11:00', 'pass', 'done');
INSERT INTO `zt_testtask` (`id`, `project`, `name`, `product`, `execution`, `build`, `owner`, `pri`, `begin`, `end`, `mailto`, `desc`, `report`, `status`, `auto`, `subStatus`, `deleted`) VALUES
(1, 0, '企业网站第一期测试任务', 1, 1, '1', 'testManager', 0, '2020-06-05', '2021-06-21', '', '', '', 'wait', 'no', '', '0');
INSERT INTO `zt_testtask` (`id`, `project`, `name`, `product`, `execution`, `build`, `owner`, `pri`, `begin`, `end`, `mailto`, `desc`, `report`, `status`, `auto`, `subStatus`, `deleted`, `testreport`, `createdBy`, `createdDate`) VALUES
(1, 0, '企业网站第一期测试任务', 1, 1, '1', 'testManager', 0, '2020-06-05', '2021-06-21', '', '', '', 'wait', 'no', '', '0', '0', 'testManager', '2021-01-06 10:10:20');
REPLACE INTO `zt_user` (`company`, `dept`, `account`, `type`, `password`, `role`, `realname`, `nickname`, `commiter`, `avatar`, `birthday`, `gender`, `email`, `skype`, `qq`, `mobile`, `phone`, `weixin`, `dingding`, `slack`, `whatsapp`, `address`, `zipcode`, `nature`, `analysis`, `strategy`, `join`, `visits`, `ip`, `last`, `fails`, `locked`, `ranzhi`, `score`, `scoreLevel`, `deleted`) VALUES
(0, 5, 'productManager', 'inside', 'e10adc3949ba59abbe56e057f20f883e', 'po', '产品经理', '', '', '', '0000-00-00', 'm', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '0000-00-00', 3, '192.168.0.8', 1338866083, 0, '0000-00-00 00:00:00', '', 0, 0, '0'),
(0, 6, 'projectManager', 'inside', 'e10adc3949ba59abbe56e057f20f883e', 'pm', '项目经理', '', '', '', '0000-00-00', 'm', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '0000-00-00', 4, '10.0.2.2', 1619580798, 0, '0000-00-00 00:00:00', '', 0, 0, '0'),
+722 -40
View File
File diff suppressed because one or more lines are too long
+1186 -1129
View File
File diff suppressed because it is too large Load Diff
+7 -21
View File
@@ -106,45 +106,31 @@ if($config->edition != 'open') $lang->execution->menu->gantt = array('link' =
$lang->execution->menu->tree = array('link' => "Tree|execution|tree|executionID=%s");
$lang->execution->menu->grouptask = array('link' => "Group view|execution|grouptask|executionID=%s");
$lang->kanbanProject->menu->doc['subMenu'] = new stdclass();
$lang->kanbanProject->menu->settings['subMenu'] = new stdclass();
$lang->kanbanProject->menu->settings['subMenu']->view = array('link' => "$lang->overview|project|view|project=%s", 'alias' => 'edit');
$lang->kanbanProject->menu->settings['subMenu']->members = array('link' => "{$lang->team->common}|project|team|project=%s", 'alias' => 'managemembers,team');
$lang->kanbanProject->menu->settings['subMenu']->whitelist = array('link' => "{$lang->whitelist}|project|whitelist|project=%s", 'subModule' => 'personnel');
unset($lang->doc->menu->product);
unset($lang->doc->menu->api);
unset($lang->doc->menu->execution);
$lang->URCommon = 'Story';
$lang->SRCommon = 'Story';
/* Doc menu. */
$lang->doc->menu = new stdclass();
$lang->doc->menu->dashboard = array('link' => "{$lang->dashboard}|doc|index");
$lang->doc->menu->recent = array('link' => "{$lang->doc->recent}|doc|browse|browseTyp=byediteddate", 'alias' => 'recent');
$lang->doc->menu->my = array('link' => "{$lang->doc->my}|doc|browse|browseTyp=openedbyme", 'alias' => 'my');
$lang->doc->menu->collect = array('link' => "{$lang->doc->favorite}|doc|browse|browseTyp=collectedbyme", 'alias' => 'collect');
$lang->doc->menu->project = array('link' => "{$lang->doc->project}|doc|tableContents|type=project", 'alias' => 'showfiles,project');
$lang->doc->menu->custom = array('link' => "{$lang->doc->custom}|doc|tableContents|type=custom", 'alias' => 'custom');
$lang->doc->menu->my = array('link' => "{$lang->doc->mySpace}|doc|browse|browseTyp=openedbyme", 'alias' => 'my');
$lang->doc->menu->project = array('link' => "{$lang->doc->projectSpace}|doc|tableContents|type=project", 'alias' => 'showfiles,project');
$lang->doc->menu->custom = array('link' => "{$lang->doc->teamSpace}|doc|tableContents|type=custom", 'alias' => 'custom');
$lang->doc->dividerMenu = ',project,';
/* Doc menu order. */
$lang->doc->menuOrder = array();
$lang->doc->menuOrder[5] = 'dashboard';
$lang->doc->menuOrder[10] = 'recent';
$lang->doc->menuOrder[15] = 'my';
$lang->doc->menuOrder[20] = 'collect';
$lang->doc->menuOrder[25] = 'product';
$lang->doc->menuOrder[30] = 'custom';
$lang->doc->menu->project['subMenu'] = new stdclass();
$lang->doc->menu->custom['subMenu'] = new stdclass();
$lang->doc->menuOrder[10] = 'my';
$lang->doc->menuOrder[15] = 'project';
$lang->doc->menuOrder[20] = 'custom';
/* Admin menu. */
$lang->admin->menu = new stdclass();
$lang->admin->menu = new stdclass();
/* adjust items of search. */
$lang->searchObjects['all'] = 'All';
+7 -21
View File
@@ -106,45 +106,31 @@ if($config->edition != 'open') $lang->execution->menu->gantt = array('link' =
$lang->execution->menu->tree = array('link' => "Tree|execution|tree|executionID=%s");
$lang->execution->menu->grouptask = array('link' => "Group view|execution|grouptask|executionID=%s");
$lang->kanbanProject->menu->doc['subMenu'] = new stdclass();
$lang->kanbanProject->menu->settings['subMenu'] = new stdclass();
$lang->kanbanProject->menu->settings['subMenu']->view = array('link' => "$lang->overview|project|view|project=%s", 'alias' => 'edit');
$lang->kanbanProject->menu->settings['subMenu']->members = array('link' => "{$lang->team->common}|project|team|project=%s", 'alias' => 'managemembers,team');
$lang->kanbanProject->menu->settings['subMenu']->whitelist = array('link' => "{$lang->whitelist}|project|whitelist|project=%s", 'subModule' => 'personnel');
unset($lang->doc->menu->product);
unset($lang->doc->menu->api);
unset($lang->doc->menu->execution);
$lang->URCommon = 'Story';
$lang->SRCommon = 'Story';
/* Doc menu. */
$lang->doc->menu = new stdclass();
$lang->doc->menu->dashboard = array('link' => "{$lang->dashboard}|doc|index");
$lang->doc->menu->recent = array('link' => "{$lang->doc->recent}|doc|browse|browseTyp=byediteddate", 'alias' => 'recent');
$lang->doc->menu->my = array('link' => "{$lang->doc->my}|doc|browse|browseTyp=openedbyme", 'alias' => 'my');
$lang->doc->menu->collect = array('link' => "{$lang->doc->favorite}|doc|browse|browseTyp=collectedbyme", 'alias' => 'collect');
$lang->doc->menu->project = array('link' => "{$lang->doc->project}|doc|tableContents|type=project", 'alias' => 'showfiles,project');
$lang->doc->menu->custom = array('link' => "{$lang->doc->custom}|doc|tableContents|type=custom", 'alias' => 'custom');
$lang->doc->menu->my = array('link' => "{$lang->doc->mySpace}|doc|browse|browseTyp=openedbyme", 'alias' => 'my');
$lang->doc->menu->project = array('link' => "{$lang->doc->projectSpace}|doc|tableContents|type=project", 'alias' => 'showfiles,project');
$lang->doc->menu->custom = array('link' => "{$lang->doc->teamSpace}|doc|tableContents|type=custom", 'alias' => 'custom');
$lang->doc->dividerMenu = ',project,';
/* Doc menu order. */
$lang->doc->menuOrder = array();
$lang->doc->menuOrder[5] = 'dashboard';
$lang->doc->menuOrder[10] = 'recent';
$lang->doc->menuOrder[15] = 'my';
$lang->doc->menuOrder[20] = 'collect';
$lang->doc->menuOrder[25] = 'project';
$lang->doc->menuOrder[30] = 'custom';
$lang->doc->menu->project['subMenu'] = new stdclass();
$lang->doc->menu->custom['subMenu'] = new stdclass();
$lang->doc->menuOrder[10] = 'my';
$lang->doc->menuOrder[15] = 'project';
$lang->doc->menuOrder[20] = 'custom';
/* Admin menu. */
$lang->admin->menu = new stdclass();
$lang->admin->menu = new stdclass();
/* adjust items of search. */
$lang->searchObjects['all'] = 'All';
+7 -21
View File
@@ -106,45 +106,31 @@ if($config->edition != 'open') $lang->execution->menu->gantt = array('link' =
$lang->execution->menu->tree = array('link' => "Tree|execution|tree|executionID=%s");
$lang->execution->menu->grouptask = array('link' => "Group view|execution|grouptask|executionID=%s");
$lang->kanbanProject->menu->doc['subMenu'] = new stdclass();
$lang->kanbanProject->menu->settings['subMenu'] = new stdclass();
$lang->kanbanProject->menu->settings['subMenu']->view = array('link' => "$lang->overview|project|view|project=%s", 'alias' => 'edit');
$lang->kanbanProject->menu->settings['subMenu']->members = array('link' => "{$lang->team->common}|project|team|project=%s", 'alias' => 'managemembers,team');
$lang->kanbanProject->menu->settings['subMenu']->whitelist = array('link' => "{$lang->whitelist}|project|whitelist|project=%s", 'subModule' => 'personnel');
unset($lang->doc->menu->product);
unset($lang->doc->menu->api);
unset($lang->doc->menu->execution);
$lang->URCommon = 'Story';
$lang->SRCommon = 'Story';
/* Doc menu. */
$lang->doc->menu = new stdclass();
$lang->doc->menu->dashboard = array('link' => "{$lang->dashboard}|doc|index");
$lang->doc->menu->recent = array('link' => "{$lang->doc->recent}|doc|browse|browseTyp=byediteddate", 'alias' => 'recent');
$lang->doc->menu->my = array('link' => "{$lang->doc->my}|doc|browse|browseTyp=openedbyme", 'alias' => 'my');
$lang->doc->menu->collect = array('link' => "{$lang->doc->favorite}|doc|browse|browseTyp=collectedbyme", 'alias' => 'collect');
$lang->doc->menu->project = array('link' => "{$lang->doc->project}|doc|tableContents|type=project", 'alias' => 'showfiles,project');
$lang->doc->menu->custom = array('link' => "{$lang->doc->custom}|doc|tableContents|type=custom", 'alias' => 'custom');
$lang->doc->menu->my = array('link' => "{$lang->doc->mySpace}|doc|browse|browseTyp=openedbyme", 'alias' => 'my');
$lang->doc->menu->project = array('link' => "{$lang->doc->projectSpace}|doc|tableContents|type=project", 'alias' => 'showfiles,project');
$lang->doc->menu->custom = array('link' => "{$lang->doc->teamSpace}|doc|tableContents|type=custom", 'alias' => 'custom');
$lang->doc->dividerMenu = ',project,';
/* Doc menu order. */
$lang->doc->menuOrder = array();
$lang->doc->menuOrder[5] = 'dashboard';
$lang->doc->menuOrder[10] = 'recent';
$lang->doc->menuOrder[15] = 'my';
$lang->doc->menuOrder[20] = 'collect';
$lang->doc->menuOrder[25] = 'project';
$lang->doc->menuOrder[30] = 'custom';
$lang->doc->menu->project['subMenu'] = new stdclass();
$lang->doc->menu->custom['subMenu'] = new stdclass();
$lang->doc->menuOrder[10] = 'my';
$lang->doc->menuOrder[15] = 'project';
$lang->doc->menuOrder[20] = 'custom';
/* Admin menu. */
$lang->admin->menu = new stdclass();
$lang->admin->menu = new stdclass();
/* adjust items of search. */
$lang->searchObjects['all'] = 'All';
+8 -21
View File
@@ -83,7 +83,7 @@ $lang->kanbanProject->menu = new stdclass();
$lang->kanbanProject->menu->index = array('link' => "{$lang->dashboard}|project|index|project=%s");
$lang->kanbanProject->menu->execution = array('link' => "$lang->executionKanban|project|execution|status=all&projectID=%s", 'subModule' => 'execution,task');
$lang->kanbanProject->menu->story = array('link' => "{$lang->project->target}|projectstory|story|projectID=%s", 'subModule' => 'projectstory,tree,story', 'alias' => 'story,track');
$lang->kanbanProject->menu->doc = array('link' => "{$lang->doc->common}|doc|tableContents|type=project&objectID=%s", 'subModule' => 'doc');
$lang->kanbanProject->menu->doc = array('link' => "{$lang->doc->common}|doc|projectSpace|objectID=%s", 'subModule' => 'doc');
$lang->kanbanProject->menu->dynamic = array('link' => "$lang->dynamic|project|dynamic|project=%s");
$lang->kanbanProject->menu->settings = array('link' => "$lang->settings|project|view|project=%s", 'subModule' => 'stakeholder', 'alias' => 'edit,manageproducts,group,managemembers,manageview,managepriv,whitelist,addwhitelist,team');
@@ -106,45 +106,32 @@ if($config->edition != 'open') $lang->execution->menu->gantt = array('link' =
$lang->execution->menu->tree = array('link' => "树状图|execution|tree|executionID=%s");
$lang->execution->menu->grouptask = array('link' => "分组视图|execution|grouptask|executionID=%s");
$lang->kanbanProject->menu->doc['subMenu'] = new stdclass();
$lang->kanbanProject->menu->settings['subMenu'] = new stdclass();
$lang->kanbanProject->menu->settings['subMenu']->view = array('link' => "$lang->overview|project|view|project=%s", 'alias' => 'edit');
$lang->kanbanProject->menu->settings['subMenu']->members = array('link' => "{$lang->team->common}|project|team|project=%s", 'alias' => 'managemembers,team');
$lang->kanbanProject->menu->settings['subMenu']->whitelist = array('link' => "{$lang->whitelist}|project|whitelist|project=%s", 'subModule' => 'personnel');
unset($lang->doc->menu->product);
unset($lang->doc->menu->api);
unset($lang->doc->menu->execution);
$lang->URCommon = '目标';
$lang->SRCommon = '目标';
/* Doc menu. */
$lang->doc->menu = new stdclass();
$lang->doc->menu->dashboard = array('link' => "{$lang->dashboard}|doc|index");
$lang->doc->menu->recent = array('link' => "{$lang->doc->recent}|doc|browse|browseTyp=byediteddate", 'alias' => 'recent');
$lang->doc->menu->my = array('link' => "{$lang->doc->my}|doc|browse|browseTyp=openedbyme", 'alias' => 'my');
$lang->doc->menu->collect = array('link' => "{$lang->doc->favorite}|doc|browse|browseTyp=collectedbyme", 'alias' => 'collect');
$lang->doc->menu->project = array('link' => "{$lang->doc->project}|doc|tableContents|type=project", 'alias' => 'showfiles,project');
$lang->doc->menu->custom = array('link' => "{$lang->doc->custom}|doc|tableContents|type=custom", 'alias' => 'custom');
$lang->doc->menu->my = array('link' => "{$lang->doc->mySpace}|doc|mySpace|type=mine", 'alias' => 'my');
$lang->doc->menu->project = array('link' => "{$lang->doc->projectSpace}|doc|projectSpace", 'alias' => 'showfiles,project');
$lang->doc->menu->custom = array('link' => "{$lang->doc->teamSpace}|doc|tableContents|type=custom", 'alias' => 'custom');
$lang->doc->dividerMenu = ',project,';
/* Doc menu order. */
$lang->doc->menuOrder = array();
$lang->doc->menuOrder[5] = 'dashboard';
$lang->doc->menuOrder[10] = 'recent';
$lang->doc->menuOrder[15] = 'my';
$lang->doc->menuOrder[20] = 'collect';
$lang->doc->menuOrder[25] = 'project';
$lang->doc->menuOrder[30] = 'custom';
$lang->doc->menu->project['subMenu'] = new stdclass();
$lang->doc->menu->custom['subMenu'] = new stdclass();
$lang->doc->menuOrder[10] = 'my';
$lang->doc->menuOrder[15] = 'project';
$lang->doc->menuOrder[20] = 'custom';
/* Admin menu. */
$lang->admin->menu = new stdclass();
$lang->admin->menu = new stdclass();
/* adjust items of search. */
$lang->searchObjects['all'] = '全部';
+43 -30
View File
@@ -584,35 +584,49 @@ $lang->task->methodOrder[125] = 'import';
/* Doc. */
$lang->resource->doc = new stdclass();
$lang->resource->doc->index = 'index';
$lang->resource->doc->browse = 'browse';
$lang->resource->doc->createLib = 'createLib';
$lang->resource->doc->editLib = 'editLib';
$lang->resource->doc->deleteLib = 'deleteLib';
$lang->resource->doc->create = 'create';
$lang->resource->doc->view = 'view';
$lang->resource->doc->edit = 'edit';
$lang->resource->doc->delete = 'delete';
$lang->resource->doc->deleteFile = 'deleteFile';
$lang->resource->doc->allLibs = 'allLibs';
$lang->resource->doc->objectLibs = 'objectLibs';
$lang->resource->doc->collect = 'collectAction';
$lang->resource->doc->tableContents = 'tableContents';
$lang->resource->doc->index = 'index';
$lang->resource->doc->mySpace = 'mySpace';
$lang->resource->doc->myView = 'myView';
$lang->resource->doc->myCollection = 'myCollection';
$lang->resource->doc->myCreation = 'myCreation';
$lang->resource->doc->createLib = 'createLib';
$lang->resource->doc->editLib = 'editLib';
$lang->resource->doc->deleteLib = 'deleteLib';
$lang->resource->doc->create = 'create';
$lang->resource->doc->view = 'view';
$lang->resource->doc->edit = 'edit';
$lang->resource->doc->delete = 'delete';
$lang->resource->doc->deleteFile = 'deleteFile';
$lang->resource->doc->collect = 'collectAction';
$lang->resource->doc->projectSpace = 'projectSpace';
$lang->resource->doc->tableContents = 'teamSpace';
$lang->resource->doc->showFiles = 'showFiles';
$lang->resource->doc->addCatalog = 'addCatalog';
$lang->resource->doc->editCatalog = 'editCatalog';
$lang->resource->doc->deleteCatalog = 'deleteCatalog';
$lang->resource->doc->displaySetting = 'displaySetting';
$lang->doc->methodOrder[0] = 'index';
$lang->doc->methodOrder[5] = 'browse';
$lang->doc->methodOrder[10] = 'createLib';
$lang->doc->methodOrder[15] = 'editLib';
$lang->doc->methodOrder[20] = 'deleteLib';
$lang->doc->methodOrder[25] = 'create';
$lang->doc->methodOrder[30] = 'view';
$lang->doc->methodOrder[35] = 'edit';
$lang->doc->methodOrder[40] = 'delete';
$lang->doc->methodOrder[45] = 'deleteFile';
$lang->doc->methodOrder[50] = 'allLibs';
$lang->doc->methodOrder[55] = 'objectLibs';
$lang->doc->methodOrder[60] = 'collect';
$lang->doc->methodOrder[65] = 'tableContents';
$lang->doc->methodOrder[5] = 'index';
$lang->doc->methodOrder[10] = 'mySpace';
$lang->doc->methodOrder[15] = 'myView';
$lang->doc->methodOrder[20] = 'myCollection';
$lang->doc->methodOrder[25] = 'myCreation';
$lang->doc->methodOrder[30] = 'createLib';
$lang->doc->methodOrder[35] = 'editLib';
$lang->doc->methodOrder[40] = 'deleteLib';
$lang->doc->methodOrder[45] = 'create';
$lang->doc->methodOrder[50] = 'edit';
$lang->doc->methodOrder[55] = 'view';
$lang->doc->methodOrder[60] = 'delete';
$lang->doc->methodOrder[65] = 'deleteFile';
$lang->doc->methodOrder[70] = 'collect';
$lang->doc->methodOrder[75] = 'projectSpace';
$lang->doc->methodOrder[80] = 'tableContents';
$lang->doc->methodOrder[85] = 'showFiles';
$lang->doc->methodOrder[90] = 'addCatalog';
$lang->doc->methodOrder[95] = 'editCatalog';
$lang->doc->methodOrder[100] = 'deleteCatalog';
$lang->doc->methodOrder[105] = 'displaySetting';
/* Mail. */
$lang->resource->mail = new stdclass();
@@ -1171,8 +1185,7 @@ if($config->edition == 'biz' or $config->edition == 'max')
$lang->tree->methodOrder[35] = 'editHost';
$lang->host->methodOrder[40] = 'groupMaintenance';
$lang->resource->doc->diff = 'diffAction';
$lang->resource->doc->catalog = 'catalogAction';
$lang->resource->doc->diff = 'diffAction';
$lang->resource->my->review = 'review';
+13 -1
View File
@@ -308,7 +308,19 @@ class baseModel
*/
public function loadDAO()
{
$this->dao = $this->app->loadClass('dao');
global $config, $dao;
if(is_object($dao)) return $this->dao = $dao;
$driver = $config->db->driver;
if(!class_exists($driver))
{
$classFile = $this->app->coreLibRoot . 'dao' . DS . $driver . '.class.php';
include($classFile);
}
$dao = new $driver();
$this->dao = $dao;
}
/**
+3 -6
View File
@@ -391,6 +391,7 @@ class baseRouter
$this->loadClass('front', $static = true);
$this->loadClass('filter', $static = true);
$this->loadClass('dbh', $static = true);
$this->loadClass('dao', $static = true);
$this->loadClass('mobile', $static = true);
@@ -758,7 +759,7 @@ class baseRouter
*/
public function getInstalledVersion()
{
$version = $this->dbh->query("SELECT value FROM " . TABLE_CONFIG . " WHERE `owner` = 'system' AND `key` = 'version' AND `module` = 'common' AND `section` = 'global' LIMIT 1")->fetch();
$version = $this->dbh->query("SELECT `value` FROM " . TABLE_CONFIG . " WHERE `owner` = 'system' AND `key` = 'version' AND `module` = 'common' AND `section` = 'global' LIMIT 1")->fetch();
$version = $version ? $version->value : '0.3.beta'; // No version, set as 0.3.beta.
if($version == '3.0.stable') $version = '3.0'; // convert 3.0.stable to 3.0.
return $version;
@@ -2699,15 +2700,11 @@ class baseRouter
{
if(!isset($params->driver)) self::triggerError('no pdo driver defined, it should be mysql or sqlite', __FILE__, __LINE__, $exit = true);
if(!isset($params->user)) return false;
if($params->driver == 'mysql')
{
$dsn = "mysql:host={$params->host}; port={$params->port}; dbname={$params->name}";
}
try
{
$dbPassword = helper::decryptPassword($params->password);
$dbh = new PDO($dsn, $params->user, $dbPassword, array(PDO::ATTR_PERSISTENT => $params->persistant));
$dbh = new dbh($params);
$dbh->exec("SET NAMES {$params->encoding}");
/*
+6 -6
View File
@@ -78,7 +78,7 @@ class router extends baseRouter
{
if($this->dbh)
{
$langs = $this->dbh->query('SELECT value FROM' . TABLE_CONFIG . "WHERE `owner`='system' AND `module`='common' AND `section`='global' AND `key`='langs'")->fetch();
$langs = $this->dbh->query('SELECT `value` FROM ' . TABLE_CONFIG . " WHERE `owner`='system' AND `module`='common' AND `section`='global' AND `key`='langs'")->fetch();
$langs = empty($langs) ? array() : json_decode($langs->value, true);
foreach($langs as $langKey => $langData) $this->config->langs[$langKey] = $langData['name'];
}
@@ -206,7 +206,7 @@ class router extends baseRouter
try
{
$commonSettings = $this->dbh->query('SELECT section, `key`, value FROM' . TABLE_CONFIG . "WHERE `owner`='system' AND (`module`='custom' or `module`='common') and `key` in ('sprintConcept', 'hourPoint', 'URSR', 'mode', 'URAndSR', 'scoreStatus', 'disabledFeatures', 'closedFeatures')")->fetchAll();
$commonSettings = $this->dbh->query('SELECT `section`, `key`, `value` FROM' . TABLE_CONFIG . "WHERE `owner`='system' AND (`module`='custom' or `module`='common') and `key` in ('sprintConcept', 'hourPoint', 'URSR', 'mode', 'URAndSR', 'scoreStatus', 'disabledFeatures', 'closedFeatures')")->fetchAll();
}
catch (PDOException $exception)
{
@@ -274,7 +274,7 @@ class router extends baseRouter
{
$sql = new sql();
$account = $sql->quote($account);
$userSetting = $this->dbh->query('SELECT `key`, value FROM' . TABLE_CONFIG . "WHERE `owner`= $account AND `module`='common' and `key` in ('programLink', 'productLink', 'projectLink', 'executionLink', 'URSR')")->fetchAll();
$userSetting = $this->dbh->query('SELECT `key`, `value` FROM ' . TABLE_CONFIG . "WHERE `owner`= $account AND `module`='common' and `key` in ('programLink', 'productLink', 'projectLink', 'executionLink', 'URSR')")->fetchAll();
}
foreach($userSetting as $setting)
@@ -290,7 +290,7 @@ class router extends baseRouter
$lang->SRCommon = '';
if($this->dbh and !empty($this->config->db->name))
{
$productProject = $this->dbh->query('SELECT value FROM' . TABLE_CONFIG . "WHERE `owner`='system' AND `module`='custom' AND `key`='productProject'")->fetch();
$productProject = $this->dbh->query('SELECT `value` FROM ' . TABLE_CONFIG . "WHERE `owner`='system' AND `module`='custom' AND `key`='productProject'")->fetch();
if($productProject)
{
$productProject = $productProject->value;
@@ -301,8 +301,8 @@ class router extends baseRouter
{
/* Get story concept in project and product. */
$clientLang = $this->clientLang == 'zh-tw' ? 'zh-cn' : $this->clientLang;
$URSRList = $this->dbh->query('SELECT `key`, `value` FROM' . TABLE_LANG . "WHERE module = 'custom' and section = 'URSRList' and `lang` = \"{$clientLang}\"")->fetchAll();
if(empty($URSRList)) $URSRList = $this->dbh->query('SELECT `key`, `value` FROM' . TABLE_LANG . "WHERE module = 'custom' and section = 'URSRList' and `key` = \"{$config->URSR}\"")->fetchAll();
$URSRList = $this->dbh->query('SELECT `key`, `value` FROM' . TABLE_LANG . "WHERE `module` = 'custom' and `section` = 'URSRList' and `lang` = '{$clientLang}'")->fetchAll();
if(empty($URSRList)) $URSRList = $this->dbh->query('SELECT `key`, `value` FROM' . TABLE_LANG . "WHERE module = 'custom' and `section` = 'URSRList' and `key` = '{$config->URSR}'")->fetchAll();
/* Get UR pairs and SR pairs. */
$URPairs = array();
+126 -24
View File
@@ -316,6 +316,18 @@ class baseDAO
$this->dbh->commit();
}
/**
* Desc table, show fields.
*
* @param string $tableName
* @access public
* @return array
*/
public function descTable($tableName)
{
return $this->query("DESC $tableName")->fetchAll();
}
/**
* select方法,调用sql::select()。
* The select method, call sql::select().
@@ -372,7 +384,7 @@ class baseDAO
**/
try
{
$row = $this->dbh->query($sql)->fetch(PDO::FETCH_OBJ);
$row = $this->dbh->rawQuery($sql)->fetch(PDO::FETCH_OBJ);
}
catch (PDOException $e)
{
@@ -552,7 +564,7 @@ class baseDAO
public function explain($sql = '')
{
$sql = empty($sql) ? $this->processSQL() : $sql;
$result = $this->dbh->query('explain ' . $sql)->fetch();
$result = $this->dbh->rawQuery('explain ' . $sql)->fetch();
a($result);
}
@@ -567,6 +579,26 @@ class baseDAO
{
$sql = $this->sqlobj->get();
/* INSERT INTO table VALUES(...) */
if($this->method == 'insert' and !empty($this->sqlobj->data))
{
$skipFields = $this->sqlobj->skipFields;
$fields = '(';
$values = 'VALUES(';
foreach($this->sqlobj->data as $field => $value)
{
if(strpos($skipFields, ",$field,") !== false) continue;
$fields .= "`{$field}`,";
if(is_string($value)) $value = $this->sqlobj->quote($value);
$values .= $value . ',';
}
$fields = substr($fields, 0, -1);
$values = substr($values, 0, -1);
$fields .= ')';
$values .= ')';
$sql .= $fields . ' ' . $values;
}
/**
* 如果是magic模式,处理表和字段。
* If the mode is magic, process the $fields and $table.
@@ -670,7 +702,7 @@ class baseDAO
if($sql)
{
$sql = trim($sql);
$sql = $this->dbh->formatSQL($sql);
$sqlMethod = strtolower(substr($sql, 0, strpos($sql, ' ')));
$this->setMethod($sqlMethod);
$this->sqlobj = new sql();
@@ -688,11 +720,11 @@ class baseDAO
if($this->slaveDBH and $method == 'select')
{
return $this->slaveDBH->query($sql);
return $this->slaveDBH->rawQuery($sql);
}
else
{
return $this->dbh->query($sql);
return $this->dbh->rawQuery($sql);
}
}
catch (PDOException $e)
@@ -1101,7 +1133,7 @@ class baseDAO
if($funcName == 'unique')
{
$args = func_get_args();
$sql = "SELECT COUNT(*) AS count FROM $this->table WHERE `$fieldName` = " . $this->sqlobj->quote($value);
$sql = "SELECT COUNT(*) AS `count` FROM $this->table WHERE `$fieldName` = " . $this->sqlobj->quote($value);
if($condition) $sql .= ' AND ' . $condition;
try
{
@@ -1339,7 +1371,7 @@ class baseDAO
{
$this->dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
$sql = "DESC $this->table";
$rawFields = $this->dbh->query($sql)->fetchAll();
$rawFields = $this->dbh->rawQuery($sql)->fetchAll();
$this->dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_NATURAL);
}
catch (PDOException $e)
@@ -1347,6 +1379,7 @@ class baseDAO
$this->sqlError($e);
}
$fields = array();
foreach($rawFields as $rawField)
{
$firstPOS = strpos($rawField->type, '(');
@@ -1447,7 +1480,7 @@ class baseSQL
public $dbh;
/**
* 更新或插入日期。
* 更新或插入的数据。
* The data to update or insert.
*
* @var mix
@@ -1455,6 +1488,32 @@ class baseSQL
*/
public $data;
/**
* 不需要拼接SQL的字段
* skipFields
*
* @var mixed
* @access public
*/
public $skipFields;
/**
* SQL 方法, insert, update, delete ...
* SQL method, insert, update, delete ...
*
* @var mixed
* @access public
*/
public $method;
/**
* setField
*
* @var mixed
* @access public
*/
public $setField;
/**
* 是否是第一次设置。
* Is the first time to call set.
@@ -1528,6 +1587,19 @@ class baseSQL
return new sql($table);
}
/**
* 设置SQL的方法。
* Set SQL method.
*
* @param string $method
* @access public
* @return void
*/
public function setMethod($method = '')
{
$this->method = $method;
}
/**
* select语句。
* The sql is select.
@@ -1539,6 +1611,7 @@ class baseSQL
public static function select($field = '*')
{
$sqlobj = self::factory();
$sqlobj->setMethod('select');
$sqlobj->sql = "SELECT $field ";
return $sqlobj;
}
@@ -1554,6 +1627,7 @@ class baseSQL
public static function update($table)
{
$sqlobj = self::factory();
$sqlobj->setMethod('update');
$sqlobj->sql = "UPDATE $table SET ";
return $sqlobj;
}
@@ -1569,7 +1643,8 @@ class baseSQL
public static function insert($table)
{
$sqlobj = self::factory();
$sqlobj->sql = "INSERT INTO $table SET ";
$sqlobj->setMethod('insert');
$sqlobj->sql = "INSERT INTO $table ";
return $sqlobj;
}
@@ -1584,6 +1659,7 @@ class baseSQL
public static function replace($table)
{
$sqlobj = self::factory();
$sqlobj->setMethod('replace');
$sqlobj->sql = "REPLACE $table SET ";
return $sqlobj;
}
@@ -1598,6 +1674,7 @@ class baseSQL
public static function delete()
{
$sqlobj = self::factory();
$sqlobj->setMethod('delete');
$sqlobj->sql = "DELETE ";
return $sqlobj;
}
@@ -1614,17 +1691,20 @@ class baseSQL
public function data($data, $skipFields = '')
{
$data = (object) $data;
if($skipFields) $skipFields = ',' . str_replace(' ', '', $skipFields) . ',';
if($skipFields) $this->skipFields = ',' . str_replace(' ', '', $skipFields) . ',';
foreach($data as $field => $value)
if($this->method != 'insert')
{
if(!preg_match('|^\w+$|', $field))
foreach($data as $field => $value)
{
unset($data->$field);
continue;
if(!preg_match('|^\w+$|', $field))
{
unset($data->$field);
continue;
}
if(strpos($this->skipFields, ",$field,") !== false) continue;
$this->sql .= "`$field` = " . $this->quote($value) . ',';
}
if(strpos($skipFields, ",$field,") !== false) continue;
$this->sql .= "`$field` = " . $this->quote($value) . ',';
}
$this->data = $data;
@@ -1676,15 +1756,23 @@ class baseSQL
{
if($this->inCondition and !$this->conditionIsTrue) return $this;
/* Add ` to avoid keywords of mysql. */
if(strpos($set, '=') ===false)
if($this->method == 'update')
{
$set = str_replace(',', '', $set);
$set = '`' . str_replace('`', '', $set) . '`';
/* Add ` to avoid keywords of mysql. */
if(strpos($set, '=') ===false)
{
$set = str_replace(',', '', $set);
}
$this->sql .= $this->isFirstSet ? " $set" : ", $set";
if($this->isFirstSet) $this->isFirstSet = false;
}
elseif($this->method == 'insert')
{
$this->setField = $value;
$this->data->$value = '';
}
$this->sql .= $this->isFirstSet ? " $set" : ", $set";
if($this->isFirstSet) $this->isFirstSet = false;
return $this;
}
@@ -1796,7 +1884,7 @@ class baseSQL
}
else
{
$condition = $arg1;
$condition = ctype_alnum($arg1) ? '`' . $arg1 . '`' : $arg1;
}
if(!$this->inMark) $this->sql .= ' ' . DAO::WHERE ." $condition ";
@@ -1815,6 +1903,8 @@ class baseSQL
public function andWhere($condition, $addMark = false)
{
if($this->inCondition and !$this->conditionIsTrue) return $this;
if(ctype_alnum($condition)) $condition = '`' . $condition . '`';
$mark = $addMark ? '(' : '';
$this->sql .= " AND {$mark} $condition ";
return $this;
@@ -1831,6 +1921,8 @@ class baseSQL
public function orWhere($condition)
{
if($this->inCondition and !$this->conditionIsTrue) return $this;
if(ctype_alnum($condition)) $condition = '`' . $condition . '`';
$this->sql .= " OR $condition ";
return $this;
}
@@ -1846,7 +1938,17 @@ class baseSQL
public function eq($value)
{
if($this->inCondition and !$this->conditionIsTrue) return $this;
$this->sql .= " = " . $this->quote($value);
if($this->method == 'insert')
{
$field = $this->setField;
$this->data->$field = $value;
}
else
{
$this->sql .= " = " . $this->quote($value);
}
return $this;
}
+11 -4
View File
@@ -524,11 +524,18 @@ class baseHTML
}
/* If the link of the referer is not the link of the current page or the link of the index, the cookie and gobackLink will be updated. */
if(!preg_match("/(m=|\/)(index|search|$currentModule)(&f=|-)(index|buildquery|$currentMethod)(&|-|\.)?/", strtolower($refererLink)))
if(preg_match("/(?:m=|\/)([a-zA-Z0-9]+)(?:(&f=)|(-?))([a-zA-Z0-9]+)?(?:&|-|\.)?/", strtolower($refererLink), $matches))
{
$gobackList[$tab] = $referer;
$gobackLink = $referer;
setcookie('goback', json_encode($gobackList), $config->cookieLife, $config->webRoot, '', $config->cookieSecure, false);
if(!isset($matches[2])) $matches[2] = $config->default->method;
if(!in_array($matches[1], array($config->default->module, 'search')) or !in_array($matches[2], array($config->default->method, 'buildquery')))
{
if($matches[1] != $currentModule or $matches[2] != $currentMethod)
{
$gobackList[$tab] = $referer;
$gobackLink = $referer;
setcookie('goback', json_encode($gobackList), $config->cookieLife, $config->webRoot, '', $config->cookieSecure, false);
}
}
}
return "<a href='{$gobackLink}' class='btn btn-back $class' $misc>{$label}</a>";
+1 -1
View File
@@ -313,7 +313,7 @@ class sql extends baseSQL
public function groupBy($groupBy)
{
if($this->inCondition and !$this->conditionIsTrue) return $this;
if(!preg_match('/^[a-zA-Z0-9_`\.,\s]+$/', $groupBy))
if(!preg_match('/^[a-zA-Z0-9_`\.,\s\"]+$/', $groupBy))
{
$groupBy = htmlspecialchars($groupBy);
die("Group is bad query, The group is $groupBy");
+441
View File
@@ -0,0 +1,441 @@
<?php
/**
* ZenTaoPHP的dao和sql类。
* The dao and sql class file of ZenTaoPHP framework.
*
* The author disclaims copyright to this source code. In place of
* a legal notice, here is a blessing:
*
* May you do good and not evil.
* May you find forgiveness for yourself and forgive others.
* May you share freely, never taking more than you give.
*/
/**
* Dameng类。
* Dameng driver.
*
* @package framework
*/
class dm extends dao
{
/**
* 类MySQL的DESC语法。
* Desc table, show fields.
*
* @param string $tableName
* @access public
* @return array
*/
public function descTable($tableName)
{
$sql = "select * from all_tab_columns where table_name='{$this->table}'";
$rawFields = $this->dbh->rawQuery($sql)->fetchAll();
$fields = array();
foreach($rawFields as $rawField)
{
$field = new stdClass();
$field->Field = $rawField->field;
$fields[] = $field;
}
return $fields;
}
/**
* select方法,调用sql::select()。
* The select method, call sql::select().
*
* @param string $fields
* @access public
* @return static|sql|baseDAO the dao object self.
*/
public function select($fields = '*')
{
/* Split by ','. */
$fieldList = preg_split("/,(?![^(]+\))/", $fields);
foreach($fieldList as $key => $field)
{
$field = trim($field);
$pos = strrpos($field, ' ');
if($pos)
{
$originField = substr($field, 0, $pos);
$alias = trim(substr($field, $pos));
$fieldList[$key] = $this->formatField($originField, $alias);
}
else
{
$fieldList[$key] = $this->formatField($field);
}
}
return parent::select(implode(',', $fieldList));
}
/**
* Format field: date => "date", t1.date => t1."date"
*
* @param string $originField
* @param string $alias
* @access private
* @return tring
*/
private function formatField($originField, $alias = '')
{
/* Format originField. */
$replace = array(
'GROUP_CONCAT' => 'WM_CONCAT',
);
if(stripos($originField, 'if(') !== false)
{
$originField = $this->formatIfFunction($originField);
}
elseif(strcasecmp($originField, 'distinct') !== 0)
{
$tableField = explode('.', $originField);
if(count($tableField) == 2 and ctype_alnum($tableField[1]) and $tableField[1] != '*')
{
$originField = $tableField[0] . '."' . $tableField[1] . '"';
}
elseif(count($tableField) == 1 and ctype_alnum($tableField[0]) and $tableField[0] != '*')
{
$originField = '"' . $tableField[0] . '"';
}
$originField = str_ireplace(array_keys($replace), array_values($replace), $originField);
}
/* Format alias. */
if($alias and ctype_alnum($alias)) $alias = '"' . $alias . '"';
return $originField . ' ' . $alias;
}
/**
* Format if function.
*
* @param string $field
* @access private
* @return string
*/
private function formatIfFunction($field)
{
preg_match('/if\(.+\)+/i', $field, $matches);
$if = $matches[0];
if(substr_count($if, '(') == 1)
{
$pos = strpos($if, ')');
$if = substr($if, 0, $pos+1);
}
$parts = explode(',', substr($if, 3, strlen($if)-4)); // remove 'if(' and ')'
$case = 'CASE WHEN ' . implode(',', array_slice($parts, 0, count($parts)-2)) . ' THEN ' . $parts[count($parts)-2] . ' ELSE ' . $parts[count($parts)-1] . ' END';
$field = str_ireplace($if, $case, $field);
return $field;
}
/**
* 创建WHERE部分。
* Create the where part.
*
* @param string $arg1 the field name
* @param string $arg2 the operator
* @param string $arg3 the value
* @access public
* @return static|sql the sql object.
*/
public function where($arg1, $arg2 = null, $arg3 = null)
{
$arg1 = $this->formatWhere($arg1);
return parent::where($arg1, $arg2, $arg3);
}
/**
* 创建AND部分。
* Create the AND part.
*
* @param string $condition
* @access public
* @return static|sql the sql object.
*/
public function andWhere($condition = '', $addMark = false)
{
$condition = $this->formatWhere($condition);
return parent::andWhere($condition, $addMark);
}
/**
* 创建OR部分。
* Create the OR part.
*
* @param bool $condition
* @access public
* @return static|sql the sql object.
*/
public function orWhere($condition)
{
$condition = $this->formatWhere($condition);
return parent::orWhere($condition);
}
private function formatWhere($condition)
{
$condition = trim($condition);
if($condition == '1') return '1 = 1';
$pos = strrpos($condition, ' ');
if($pos)
{
$originField = substr($condition, 0, $pos);
return $this->formatField($originField) . substr($condition, $pos);
}
else
{
return $this->formatField($condition);
}
}
/**
* 创建GROUP BY部分。
* Create the groupby part.
*
* @param string $groupBy
* @access public
* @return static|sql the sql object.
*/
public function groupBy($groupBy)
{
$groups = preg_split("/,(?![^(]+\))/", $groupBy);
foreach($groups as $key => $group)
{
$groups[$key] = $this->formatField($group);
}
$groupBy = implode(',', $groups);
return parent::groupBy($groupBy);
}
/**
* 创建ORDER BY部分。
* Create the order by part.
*
* @param string $order
* @access public
* @return static|sql the sql object.
*/
public function orderBy($order)
{
$order = str_replace('"', '', $order);
return parent::orderBy($order);
}
/**
* 创建ON部分。
* Create the on part.
*
* @param string $condition
* @access public
* @return static|sql the sql object.
*/
public function on($condition)
{
$fieldList = explode('=', $condition);
foreach($fieldList as $key => $field) $fieldList[$key] = $this->formatField(trim($field));
$condition = implode(' = ', $fieldList);
return parent::on($condition);
}
public function getPKColumns()
{
$sql = "SELECT A.OWNER, A.TABLE_NAME, WM_CONCAT(B.COLUMN_NAME) PK_COLUMNS FROM ALL_CONSTRAINTS A, ALL_CONS_COLUMNS B where A.CONSTRAINT_type = 'P' AND A.OWNER = '{$this->config->db->user}' AND A.TABLE_NAME = '{$this->table}' AND B.OWNER = A.OWNER AND A.TABLE_NAME = B.TABLE_NAME GROUP BY A.OWNER, A.TABLE_NAME;";
$content = $this->dbh->query($sql)->fetch();
return empty($content) ? false : $content->PK_COLUMNS;
}
/**
* 执行SQL。query()会返回stmt对象,该方法只返回更改或删除的记录数。
* Execute the sql. It's different with query(), which return the stmt object. But this not.
*
* @param string $sql
* @access public
* @return int the modified or deleted records. 更改或删除的记录数。
*/
public function exec($sql = '')
{
if($sql)
{
$this->sqlobj = new sql();
$this->sqlobj->sql = $sql;
}
else
{
$sql = $this->processSQL();
$this->sqlobj->sql = $sql;
}
if($this->method == 'replace' && !empty($this->sqlobj->data))
{
$insertSql = "INSERT INTO {$this->table} ";
$fields = '(';
$values = 'VALUES(';
foreach($this->sqlobj->data as $field => $value)
{
$fields .= "`{$field}`,";
if(is_string($value)) $value = $this->sqlobj->quote($value);
$values .= $value . ',';
}
$fields = substr($fields, 0, -1);
$values = substr($values, 0, -1);
$fields .= ')';
$values .= ')';
$insertSql .= $fields . ' ' . $values;
$updateSql = str_replace('REPLACE', 'UPDATE', $sql);
$pk = $this->getPKColumns();
if(!empty($pk) && isset($this->sqlobj->data->{$pk})) $updateSql .= " where {$pk} = '{$this->sqlobj->data->{$pk}}'";
$deleteSql = "DELETE FROM {$this->table} WHERE ";
$ingore = array();
$ingore['`zt_config`'] = array('value');
foreach($this->sqlobj->data as $field => $value)
{
if(isset($ingore[$this->table]) and in_array($field, $ingore[$this->table])) continue;
$deleteSql .= "`{$field}` = ";
$deleteSql .= is_string($value) ? "'{$value}'" : $value;
$deleteSql .= ' AND ';
}
$deleteSql = rtrim($deleteSql, 'AND ');
$sql = <<<EOT
DECLARE
E_IDENTITY_INSERT EXCEPTION;
E_INSTALL_DUP_VAL_ON_INDEX EXCEPTION;
E_UPDATE_DUP_VAL_ON_INDEX EXCEPTION;
PRAGMA EXCEPTION_INIT (E_IDENTITY_INSERT, -2723);
PRAGMA EXCEPTION_INIT (E_INSTALL_DUP_VAL_ON_INDEX, -6602);
PRAGMA EXCEPTION_INIT (E_UPDATE_DUP_VAL_ON_INDEX, -6610);
BEGIN
BEGIN
$insertSql;
EXCEPTION
WHEN DUP_VAL_ON_INDEX OR E_IDENTITY_INSERT THEN
$updateSql;
WHEN E_INSTALL_DUP_VAL_ON_INDEX THEN
$updateSql;
END;
EXCEPTION
WHEN E_UPDATE_DUP_VAL_ON_INDEX THEN
$deleteSql;
$insertSql;
END;
EOT;
self::$querys[] = $sql;
}
$sql = str_replace('`', '"', $sql);
try
{
if($this->table) unset(dao::$cache[$this->table]);
$this->reset();
return $this->dbh->exec($sql);
}
catch (PDOException $e)
{
$this->sqlError($e);
}
}
/**
* 获取一个记录。
* Fetch one record.
*
* @param string $field 如果已经设置获取的字段,则只返回这个字段的值,否则返回这个记录。
* if the field is set, only return the value of this field, else return this record
* @access public
* @return object|mixed
*/
public function fetch($field = '')
{
return parent::fetch($field);
}
/**
* 获取所有记录。
* Fetch all records.
*
* @param string $keyField 返回以该字段做键的记录
* the key field, thus the return records is keyed by this field
* @access public
* @return array the records
*/
public function fetchAll($keyField = '')
{
return parent::fetchAll($keyField);
}
/**
* 获取表的字段类型。
* Get the defination of fields of the table.
*
* @access public
* @return array
*/
public function getFieldsType()
{
try
{
$this->dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
$sql = "select * from all_tab_columns where table_name='{$this->table}'";
$rawFields = $this->dbh->rawQuery($sql)->fetchAll();
$this->dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_NATURAL);
}
catch (PDOException $e)
{
$this->sqlError($e);
}
$fields = array();
foreach($rawFields as $rawField)
{
$firstPOS = strpos($rawField->data_type, '(');
$type = substr($rawField->data_type, 0, $firstPOS > 0 ? $firstPOS : strlen($rawField->type));
$type = str_replace(array('big', 'small', 'medium', 'tiny', 'var'), '', $type);
$field = array();
if($type == 'VARCHAR' or $type == 'CHAR')
{
$length = $rawField->data_length;
$field['rule'] = 'length';
$field['options']['max'] = $length;
$field['options']['min'] = 0;
}
elseif($type == 'INTEGER')
{
$field['rule'] = 'int';
}
elseif($type == 'FLOAT' or $type == 'DOUBLE')
{
$field['rule'] = 'float';
}
elseif($type == 'DATE')
{
$field['rule'] = 'date';
}
elseif($type == 'DATETIME')
{
$field['rule'] = 'datetime';
}
else
{
$field['rule'] = 'skip';
}
$fields[$rawField->field] = $field;
}
return $fields;
}
}
+22
View File
@@ -0,0 +1,22 @@
<?php
/**
* ZenTaoPHP的dao和sql类。
* The dao and sql class file of ZenTaoPHP framework.
*
* The author disclaims copyright to this source code. In place of
* a legal notice, here is a blessing:
*
* May you do good and not evil.
* May you find forgiveness for yourself and forgive others.
* May you share freely, never taking more than you give.
*/
/**
* MySQL类。
* MySQL driver.
*
* @package framework
*/
class mysql extends dao
{
}
+435
View File
@@ -0,0 +1,435 @@
<?php
/**
* ZenTaoPHP的dbh类。
* The dbh class file of ZenTaoPHP framework.
*
* The author disclaims copyright to this source code. In place of
* a legal notice, here is a blessing:
*
* May you do good and not evil.
* May you find forgiveness for yourself and forgive others.
* May you share freely, never taking more than you give.
*/
/**
* DBH类。
* DBH, database handler.
*
* @package lib
*/
class dbh
{
/**
* PDO.
*
* @var object
* @access private
*/
private $pdo;
/**
* Database config.
*
* @var object
* @access private
*/
private $config;
/**
* Constructor
*
* @param object $config
* @param bool $setSchema
* @access public
* @return void
*/
public function __construct($config, $setSchema = true)
{
$dsn = "{$config->driver}:host={$config->host}:{$config->port}";
if($setSchema) $dsn .= ";dbname={$config->name}";
$pdo = new PDO($dsn, $config->user, $config->password);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if($config->driver == 'mysql')
{
$pdo->exec("SET NAMES {$config->encoding}");
if(isset($this->config->strictMode) and $this->config->strictMode == false) $pdo->exec("SET @@sql_mode= ''");
}
else if($setSchema)
{
$pdo->exec("SET SCHEMA {$config->name}");
}
$this->pdo = $pdo;
$this->config = $config;
}
/**
* Execute sql.
*
* @param string $sql
* @access public
* @return PDOStatement|false
*/
public function exec($sql)
{
$sql = $this->formatSQL($sql);
if(!$sql) return true;
return $this->pdo->exec($sql);
}
/**
* Query sql.
*
* @param string $sql
* @access public
* @return PDOStatement|false
*/
public function query($sql)
{
$sql = $this->formatSQL($sql);
return $this->pdo->query($sql);
}
/**
* Query raw sql.
*
* @param string $sql
* @access public
* @return PDOStatement|false
*/
public function rawQuery($sql)
{
return $this->pdo->query($sql);
}
/**
* Set attribute.
*
* @param int $attribute
* @param mixed $value
* @access public
* @return bool
*/
public function setAttribute($attribute, $value)
{
return $this->pdo->setAttribute($attribute, $value);
}
/**
* Check db exits or not.
*
* @access public
* @return bool
*/
public function dbExists()
{
switch($this->config->driver)
{
case 'mysql':
$sql = "SHOW DATABASES like '{$this->config->name}'";
break;
case 'dm':
$sql = "SELECT * FROM dba_objects WHERE object_type='SCH' AND owner='{$this->config->name}'";
break;
default:
$sql = '';
}
return $this->rawQuery($sql)->fetch();
}
/**
* Check table exits or not.
*
* @param string $tableName
* @access public
* @return void
*/
public function tableExits($tableName)
{
$tableName = str_replace('`', "'", $tableName);
$sql = "SHOW TABLES FROM {$this->config->name} like $tableName";
switch($this->config->driver)
{
case 'mysql':
$sql = "SHOW TABLES FROM {$this->config->name} like {$tableName}";
break;
case 'dm':
$sql = "SELECT * FROM all_tables WHERE owner='{$this->config->name}' AND table_name={$tableName}";
break;
default:
$sql = '';
}
return $this->rawQuery($sql)->fetch();
}
/**
* Create database.
*
* @param string $version
* @access public
* @return PDOStatement|false
*/
public function createDB($version)
{
switch($this->config->driver)
{
case 'mysql':
$sql = "CREATE DATABASE `{$this->config->name}`";
if($version > 4.1) $sql .= " DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci";
return $this->rawQuery($sql);
case 'dm':
$tableSpace = strtoupper($this->config->name);
$res = $this->rawQuery("SELECT * FROM dba_data_files WHERE TABLESPACE_NAME = '$tableSpace'")->fetchAll();
if(empty($res))
{
$createTableSpace = "CREATE TABLESPACE $tableSpace DATAFILE '{$this->config->name}.DBF' size 150 AUTOEXTEND ON";
$createUser = "CREATE USER {$this->config->name} IDENTIFIED by {$this->config->password} DEFAULT TABLESPACE {$this->config->name} DEFAULT INDEX TABLESPACE {$this->config->name}";
$this->rawQuery($createTableSpace);
$this->rawQuery($createUser);
}
$createSchema = "CREATE SCHEMA {$this->config->name} AUTHORIZATION {$this->config->name}";
return $this->rawQuery($createSchema);
default:
return false;
}
}
/**
* Use database or schema.
*
* @param string $dbName
* @access public
* @return PDOStatement|false
*/
public function useDB($dbName)
{
switch($this->config->driver)
{
case 'mysql':
return $this->exec("USE {$this->config->name}");
case 'dm':
return $this->exec("SET SCHEMA {$this->config->name}");
default:
return false;
}
}
/**
* Format sql.
*
* @param string $sql
* @access public
* @return string
*/
public function formatSQL($sql)
{
switch($this->config->driver)
{
case 'dm':
return $this->formatDmSQL($sql);
return $sql;
default:
return $sql;
}
}
/**
* Format dm sql.
*
* @param string $sql
* @access public
* @return string
*/
public function formatDmSQL($sql)
{
$sql = trim($sql);
$sql = str_replace(array('\r', '\n'), ' ', $sql);
$actionPos = strpos($sql, ' ');
$action = strtoupper(substr($sql, 0, $actionPos));
$setPos = 0;
switch($action)
{
case 'SELECT':
return $this->formatField($sql);
case 'REPLACE':
$sql = str_replace('REPLACE', 'INSERT', $sql);
$action = 'INSERT';
case 'INSERT':
case 'UPDATE':
$setPos = stripos($sql, ' VALUES');
$sql = str_replace('0000-00-00', '1970-01-01', $sql);
$sql = str_replace('00:00:00', '00:00:01', $sql);
if(strpos($sql, "\\'") !== FALSE) $sql = str_replace("\\'", "''''", $sql);
if(strpos($sql, '\"') !== FALSE) $sql = str_replace('\"', '"', $sql);
if(strpos($sql, '\\\\') !== FALSE) $sql = str_replace('\\\\', '\\', $sql);
break;
case 'CREATE':
if(stripos($sql, 'CREATE OR REPLACE VIEW ') === 0) return '';
if(stripos($sql, 'CREATE VIEW') === 0) return '';
if(stripos($sql, 'CREATE FUNCTION') === 0) return '';
case 'ALTER':
$sql = $this->formatField($sql);
$sql = $this->formatAttr($sql);
return $sql;
case 'SET':
if(stripos($sql, 'SET SCHEMA') === 0) return $sql;
case 'USE':
return '';
case 'DROP':
return $this->formatField($sql);
}
if($setPos <= 0) return $sql;
$fields = substr($sql, 0, $setPos);
$fields = $this->formatField($fields);
$sql = $fields . substr($sql, $setPos);
/* DMDB must set IDENTITY_INSERT 'on' to insert id field. */
if($action == 'INSERT' and stripos($fields, '"id"') !== FALSE)
{
$tableBegin = strpos($sql, '"' . $this->config->prefix);
$tableEnd = strpos($sql, '"', $tableBegin + 1);
$tableName = '' . $this->config->name . '."' . substr($sql, $tableBegin + 1, $tableEnd - $tableBegin - 1) . '"';
return "SET IDENTITY_INSERT $tableName ON;" . $sql;
}
return $sql;
}
/**
* Format field.
*
* @param string $sql
* @access public
* @return string
*/
public function formatField($sql)
{
switch($this->config->driver)
{
case 'dm':
$sql = str_replace('`', '"', $sql);
return $sql;
default:
return $sql;
}
}
/**
* Format attribute of field.
*
* @param string $sql
* @access public
* @return string
*/
public function formatAttr($sql)
{
switch($this->config->driver)
{
case 'dm':
$pos = stripos($sql, ' ENGINE');
if($pos > 0) $sql = substr($sql, 0, $pos);
$sql = preg_replace('/\(\ *\d+\ *\)/', '', $sql);
$replace = array(
" AUTO_INCREMENT" => ' IDENTITY(1, 1)',
" int " => ' integer ',
" mediumint " => ' integer ',
" smallint " => ' integer ',
" tinyint " => ' integer ',
" varchar " => ' varchar(255) ',
" char " => ' varchar(255) ',
" mediumtext " => ' text ',
" mediumtext," => ' text,',
" longtext " => ' text ',
"COLLATE 'utf8_general_ci'" => ' ',
" unsigned " => ' ',
" zerofill " => ' ',
"0000-00-00" => '1970-01-01',
);
$sql = preg_replace('/ enum[\_0-9a-z\,\'\"\( ]+\)+/i', ' varchar(255) ', $sql);
$sql = str_ireplace(array_keys($replace), array_values($replace), $sql);
$sql = preg_replace('/\,\s+key[\_\"0-9a-z ]+\(+[\,\_\"0-9a-z ]+\)+/i', '', $sql);
$sql = preg_replace('/\,\s*(unique|fulltext)*\s+key[\_\"0-9a-z ]+\(+[\,\_\"0-9a-z ]+\)+/i', '', $sql);
$sql = preg_replace('/ float\s*\(+[\,\_\"0-9a-z ]+\)+/i', ' float', $sql);
}
return $sql;
}
/**
* Quote.
*
* @param string $string
* @param int $parameter_type
* @access public
* @return string
*/
public function quote($string, $parameter_type = PDO::PARAM_STR)
{
return $this->pdo->quote($string, $parameter_type);
}
/**
* Get last insert id.
*
* @param string $name
* @access public
* @return string|false
*/
public function lastInsertId($name = null)
{
return $this->pdo->lastInsertId($name);
}
/**
* Begin transaction.
*
* @access public
* @return bool
*/
public function beginTransaction()
{
return $this->pdo->beginTransaction();
}
/**
* Roll back if transaction failed.
*
* @access public
* @return bool
*/
public function rollBack()
{
return $this->pdo->rollBack();
}
/**
* Commit transaction.
*
* @access public
* @return bool
*/
public function commit()
{
return $this->pdo->commit();
}
}
+1 -1
View File
@@ -265,7 +265,7 @@ class feishuapi
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
if($_SERVER['HTTPS'] != 'on')
if(!isset($_SERVER['HTTPS']) or $_SERVER['HTTPS'] != 'on')
{
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+6 -1
View File
@@ -171,7 +171,12 @@ class html extends baseHTML
$convertedPinYin = (empty($config->isINT) and class_exists('common')) ? common::convert2Pinyin($options) : array();
if(count($options) >= $config->maxCount or isset($config->moreLinks[$name]))
{
if(strpos($attrib, 'chosen') !== false) $attrib = str_replace('chosen', 'picker-select', $attrib);
if(strpos($attrib, 'chosen') !== false)
{
$attrib = str_replace('chosen', 'picker-select', $attrib);
$attrib = preg_replace('/data-drop[-_]?direction=([\'"]?)down([\'"]?)/i', 'data-drop-direction=$1bottom$2', $attrib);
$attrib = preg_replace('/data-drop[-_]?direction=([\'"]?)up([\'"]?)/i', 'data-drop-direction=$1top$2', $attrib);
}
if(isset($config->moreLinks[$name]))
{
$link = $config->moreLinks[$name];
+34 -8
View File
@@ -1043,7 +1043,7 @@ class actionModel extends model
extract($beginAndEnd);
/* Build has priv condition. */
$condition = 1;
$condition = '1=1';
$executions = array();
if(!$this->app->user->admin)
{
@@ -1118,6 +1118,12 @@ class actionModel extends model
$noMultipleExecutions = $this->dao->select('id')->from(TABLE_PROJECT)->where('multiple')->eq(0)->andWhere('type')->in('sprint,kanban')->fetchPairs('id', 'id');
$condition = "(`objectType` IN ('doc', 'doclib') OR ($condition)) AND `objectType` NOT IN ('program', 'effort', 'execution')";
if($noMultipleExecutions) $condition .= " OR (`objectID` NOT " . helper::dbIN($noMultipleExecutions) . " AND `objectType` = 'execution')";
$condition .= " OR (`objectID` in ($programCondition) AND `objectType` = 'program')";
$condition .= " OR (`objectID` in ($efforts) AND `objectType` = 'effort')";
$condition = "($condition)";
/* Get actions. */
$actions = $this->dao->select('*')->from(TABLE_ACTION)
->where('objectType')->notIN($this->config->action->ignoreObjectType4Dynamic)
@@ -1130,7 +1136,7 @@ class actionModel extends model
->beginIF(is_numeric($productID))->andWhere('product')->like("%,$productID,%")->fi()
->andWhere()
->markLeft(1)
->where(1)
->where('1=1')
->beginIF(is_numeric($projectID))->andWhere('project')->eq($projectID)->fi()
->beginIF(!empty($executions))->andWhere('execution')->in(array_keys($executions))->fi()
->beginIF(is_numeric($executionID))->andWhere('execution')->eq($executionID)->fi()
@@ -1141,13 +1147,10 @@ class actionModel extends model
->beginIF($productID == 'notzero')->andWhere('product')->gt(0)->andWhere('product')->notlike('%,0,%')->fi()
->beginIF($projectID == 'notzero')->andWhere('project')->gt(0)->fi()
->beginIF($executionID == 'notzero')->andWhere('execution')->gt(0)->fi()
->beginIF($productID == 'all' or $projectID == 'all' or $executionID == 'all')->andWhere("IF((objectType!= 'doc' && objectType!= 'doclib'), ($condition), '1=1')")->fi()
->beginIF($noMultipleExecutions)->andWhere("IF(`objectType` = 'execution', `objectID` NOT " . helper::dbIN($noMultipleExecutions) . ", '1=1')")->fi()
->andWhere($condition)
->beginIF($actionCondition)->andWhere("($actionCondition)")->fi()
/* Filter out client login/logout actions. */
->andWhere('action')->notin('disconnectxuanxuan,reconnectxuanxuan,loginxuanxuan,logoutxuanxuan,editmr,removemr')
->andWhere("IF((objectType = 'program'), (objectID in ($programCondition)), '1=1')")
->andWhere("IF((objectType = 'effort'), (objectID in ($efforts)), '1=1')")
->orderBy($orderBy)
->page($pager)
->fetchAll();
@@ -1647,11 +1650,34 @@ class actionModel extends model
$appendLib = $docLib->deleted == '1' ? $action->objectID : 0;
if($docLib->type == 'api')
{
$action->objectLink = helper::createLink('api', 'index', "libID={$action->objectID}&moduleID=0&apiID=0&version=0&release=0&appendLib={$appendLib}");
$module = 'api';
$method = 'index';
$params = "libID={$action->objectID}&moduleID=0&apiID=0&version=0&release=0&appendLib={$appendLib}";
if(!empty($docLib->project) or !empty($docLib->product))
{
$module = 'doc';
if(!empty($docLib->product))
{
$objectID = $docLib->product;
$method = 'productspace';
}
if(!empty($docLib->project))
{
$objectID = $docLib->project;
$method = 'projectspace';
}
$params = "objectID={$objectID}&libID={$action->objectID}";
}
$action->objectLink = helper::createLink($module, $method, $params);
}
else
{
$action->objectLink = helper::createLink('doc', 'objectLibs', sprintf($vars, $docLib->type, $docLib->objectID, $action->objectID, $appendLib));
$method = 'tablecontents';
if($docLib->type == 'product') $method = 'productspace';
if(in_array($docLib->type, array('project', 'execution'))) $method = 'projectspace';
$params = $method == 'tablecontents' ? sprintf($vars, $docLib->type, $docLib->objectID, $action->objectID, $appendLib) : "objectID={$docLib->objectID}&libID={$action->objectID}";
$action->objectLink = helper::createLink('doc', $method, $params);
}
}
elseif($action->objectType == 'user')
+1 -1
View File
@@ -506,7 +506,7 @@ class admin extends control
if(stripos($table, 'searchindex') !== false)
{
$mysqlVersion = $this->loadModel('install')->getMysqlVersion();
$mysqlVersion = $this->loadModel('install')->getDatabaseVersion();
if($mysqlVersion < 5.6) continue;
}
+1 -1
View File
@@ -165,7 +165,7 @@ $lang->admin->menuList->message['menuOrder']['10'] = 'webhook';
$lang->admin->menuList->message['menuOrder']['20'] = 'browser';
$lang->admin->menuList->message['menuOrder']['25'] = 'setting';
$lang->admin->menuList->dev['subMenu']['api'] = array('link' => "{$lang->api->doc}|dev|api|module=index");
$lang->admin->menuList->dev['subMenu']['api'] = array('link' => "{$lang->api->doc}|dev|api|module=restapi");
$lang->admin->menuList->dev['subMenu']['db'] = array('link' => "{$lang->database}|dev|db|table=" . trim(TABLE_EFFORT, '`'));
$lang->admin->menuList->dev['subMenu']['langItem'] = array('link' => "{$lang->langItem}|dev|langitem|");
$lang->admin->menuList->dev['subMenu']['editor'] = array('link' => "{$lang->editor->common}|dev|editor|", 'subModule' => 'editor');
+1 -1
View File
@@ -660,7 +660,7 @@ class adminModel extends model
public function genDateUsed()
{
$firstUseDate = $this->dao->select('date')->from(TABLE_ACTION)
->where('date')->gt('0000-00-00')
->where('date')->gt('1970-01-01')
->andWhere('actor')->eq($this->app->user->account)
->orderBy('date_asc')
->limit('1')
+7 -7
View File
@@ -11,7 +11,7 @@ $config->api->struct = new stdClass();
$config->api->struct->requiredFields = 'name,params';
$config->api->create = new stdclass();
$config->api->create->requiredFields = 'lib,title,path';
$config->api->create->requiredFields = 'title,path';
$config->api->edit = new stdclass();
$config->api->edit->requiredFields = 'lib,title,path';
@@ -33,23 +33,23 @@ $config->api->search['module'] = 'api';
$config->api->search['fields']['title'] = $lang->api->title;
$config->api->search['fields']['id'] = $lang->api->id;
$config->api->search['fields']['lib'] = $lang->api->lib;
$config->api->search['fields']['path'] = $lang->api->path;
$config->api->search['fields']['method'] = $lang->api->method;
$config->api->search['fields']['status'] = $lang->api->status;
$config->api->search['fields']['addedBy'] = $lang->api->addedBy;
$config->api->search['fields']['addedDate'] = $lang->api->addedDate;
$config->api->search['fields']['editedBy'] = $lang->api->editedBy;
$config->api->search['fields']['editedDate'] = $lang->api->editedDate;
$config->api->search['fields']['path'] = $lang->api->path;
$config->api->search['fields']['method'] = $lang->api->method;
$config->api->search['fields']['status'] = $lang->api->status;
$config->api->search['fields']['version'] = $lang->api->version;
$config->api->search['params']['title'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
$config->api->search['params']['id'] = array('operator' => '=', 'control' => 'input', 'values' => '');
$config->api->search['params']['lib'] = array('operator' => '=', 'control' => 'select', 'values' => '');
$config->api->search['params']['path'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
$config->api->search['params']['method'] = array('operator' => '=', 'control' => 'select', 'values' => array('' => '') + $lang->api->methodOptions);
$config->api->search['params']['status'] = array('operator' => '=', 'control' => 'select', 'values' => array('' => '') + $lang->api->statusOptions);
$config->api->search['params']['addedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
$config->api->search['params']['addedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
$config->api->search['params']['editedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
$config->api->search['params']['editedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
$config->api->search['params']['path'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
$config->api->search['params']['method'] = array('operator' => '=', 'control' => 'select', 'values' => array('' => '') + $lang->api->methodOptions);
$config->api->search['params']['status'] = array('operator' => '=', 'control' => 'select', 'values' => array('' => '') + $lang->api->statusOptions);
$config->api->search['params']['version'] = array('operator' => '>=', 'control' => 'input', 'values' => '');
+276 -174
View File
@@ -11,12 +11,18 @@
*/
class api extends control
{
public $objectType = 'nolink';
public $objectID = 0;
public function __construct($moduleName = '', $methodName = '', $appName = '')
{
parent::__construct($moduleName, $methodName, $appName);
$this->user = $this->loadModel('user');
$this->doc = $this->loadModel('doc');
$this->action = $this->loadModel('action');
if($this->cookie->objectType) $this->objectType = $this->cookie->objectType;
if($this->cookie->objectID) $this->objectID = $this->cookie->objectID;
}
/**
@@ -35,26 +41,60 @@ class api extends control
*/
public function index($libID = 0, $moduleID = 0, $apiID = 0, $version = 0, $release = 0, $appendLib = 0, $browseType = '', $param = 0)
{
$this->session->set('spaceType', 'api', 'doc');
$this->session->set('structList', $this->app->getURI(true), 'doc');
$this->setMenu($libID);
$objectType = $this->objectType;
$objectID = $this->objectID;
$isFirstLoad = $libID ? false : true;
if($release)
{
$browseType = 'byrelease';
$param = $release;
}
/* Get all api doc libraries. */
$libs = $this->doc->getApiLibs($appendLib);
if($libID == 0 and !empty($libs)) $libID = key($libs);
$libs = $this->doc->getApiLibs($appendLib, $objectType, $objectID);
if(empty($libs) and $objectType != 'nolink')
{
$objectType = 'nolink';
$objectID = 0;
$libs = $this->doc->getApiLibs($appendLib, 'nolink');
}
if(empty($libs))
{
list($normalObjects, $closedObjects) = $this->api->getOrderedObjects();
if(!empty($normalObjects))
{
$objectType = key($normalObjects);
$objectID = key($normalObjects[$objectType]);
$libs = $this->doc->getApiLibs($appendLib, $objectType, $objectID);
}
elseif(!empty($closedObjects))
{
$objectType = key($closedObjects);
$objectID = key($closedObjects[$objectType]);
$libs = $this->doc->getApiLibs($appendLib, $objectType, $objectID);
}
}
if($libID == 0 and !empty($libs))
{
$lib = current($libs);
$libID = $lib->id;
$objectType = $lib->product ? 'product' : ($lib->project ? 'project' : '');
$objectID = $lib->product ? $lib->product : $lib->project;
}
/* Get an api doc. */
if($apiID > 0)
{
$api = $this->api->getLibById($apiID, $version, $release);
if($api)
{
$moduleID = $api->module;
$libID = $api->lib;
$api->desc = htmlspecialchars_decode($api->desc);
$this->view->api = $api;
$this->view->apiID = $apiID;
$this->view->version = $version;
$this->view->typeList = $this->api->getTypeList($api->lib);
$this->view->actions = $apiID ? $this->action->getList('api', $apiID) : array();
}
echo $this->fetch('api', 'view', "libID=$libID&apiID=$apiID&moduleID=$moduleID&release=$release&version=$version");
return;
}
else
{
@@ -68,58 +108,98 @@ class api extends control
$lib = $this->doc->getLibById($libID);
$appendLib = (!empty($lib) and $lib->deleted == '1') ? $libID : 0;
/* Generate bread crumbs dropMenu. */
if($libs) $this->lang->modulePageNav = $this->generateLibsDropMenu($libs, $libID, $release);
$this->setMenu($libID, $moduleID);
$this->lang->TRActions = '<a class="btn btn-link querybox-toggle" id="bysearchTab"><i class="icon icon-search muted"></i> ' . $this->lang->api->search . '</a>' . $this->lang->TRActions;
/* Build the search form. */
$queryID = $browseType == 'bySearch' ? (int)$param : 0;
$actionURL = $this->createLink('api', 'index', "libID=$libID&moduleID=0&apiID=0&version=0&release=0&appendLib=0&browseType=bySearch&param=myQueryID");
$this->api->buildSearchForm($lib,$queryID, $actionURL);
$this->api->buildSearchForm($lib,$queryID, $actionURL, $libs);
if($browseType == 'bySearch')
{
$this->view->apiList = $this->api->getApiListBySearch($libID, $queryID);
$this->view->apiList = $this->api->getApiListBySearch($libID, $queryID, '', array_keys($libs));
$this->view->typeList = $this->api->getTypeList($libID);
}
$this->view->lib = $lib;
$this->view->isRelease = $release > 0;
$this->view->release = $release;
$this->view->title = $this->lang->api->pageTitle;
$this->view->libID = $libID;
$this->view->apiID = $apiID;
$this->view->libs = $libs;
$this->view->browseType = $browseType;
$this->view->moduleTree = $libID ? $this->doc->getApiModuleTree($libID, $apiID, $release, $moduleID) : '';
$this->view->users = $this->user->getPairs('noclosed,noletter');
$this->view->lib = $lib;
$this->view->release = $release;
$this->view->isFirstLoad = $isFirstLoad;
$this->view->title = $this->lang->api->pageTitle;
$this->view->libID = $libID;
$this->view->apiID = $apiID;
$this->view->libs = $libs;
$this->view->browseType = $browseType;
$this->view->objectType = $objectType;
$this->view->objectID = $objectID;
$this->view->moduleID = $moduleID;
$this->view->version = $version;
$this->view->libTree = $this->doc->getLibTree($libID, $libs, 'api', $moduleID, $objectID, $browseType, $param);
$this->view->users = $this->user->getPairs('noclosed,noletter');
$this->view->objectDropdown = isset($libs[$libID]) ? $this->generateLibsDropMenu($libs[$libID], $release) : '';
$this->display();
}
/**
* View api.
*
* @param int $libID
* @param int $apiID
* @param int $moduleID
* @param int $release
* @param int $version
* @access public
* @return void
*/
public function view($libID, $apiID, $moduleID = 0, $release = 0, $version = 0)
{
$this->setMenu($libID);
/* Get all api doc libraries. */
$libs = $this->doc->getApiLibs($libID);
$api = $this->api->getLibById($apiID, $version, $release);
if($api)
{
$moduleID = $api->module;
$libID = $api->lib;
$api->desc = htmlspecialchars_decode($api->desc);
$this->view->api = $api;
$this->view->apiID = $apiID;
$this->view->version = $version;
$this->view->typeList = $this->api->getTypeList($api->lib);
$this->view->actions = $apiID ? $this->action->getList('api', $apiID) : array();
}
$this->view->title = $this->lang->api->pageTitle;
$this->view->libs = $libs;
$this->view->isRelease = $release > 0;
$this->view->release = $release;
$this->view->libID = $libID;
$this->view->apiID = $apiID;
$this->view->users = $this->user->getPairs('noclosed,noletter');
$this->view->moduleTree = $this->doc->getApiModuleTree($libID, $apiID, $release, $moduleID);
$this->view->objectDropdown = $this->generateLibsDropMenu($libs[$libID], $release);
$this->display();
}
/**
* Release list.
*
* @param int $libID
* @param int $libID
* @param string $orderBy
* @access public
* @return void
*/
public function releases($libID, $orderBy = 'id', $recTotal = 0, $recPerPage = 15, $pageID = 1)
public function releases($libID, $orderBy = 'id')
{
$libs = $this->doc->getApiLibs();
$this->app->loadClass('pager', $static = true);
$this->lang->modulePageNav = $this->generateLibsDropMenu($libs, $libID);
$pager = new pager($recTotal, $recPerPage, $pageID);
$this->lang->modulePageNav = $this->generateLibsDropMenu($libs[$libID]);
/* Append id for secend sort. */
$sort = common::appendOrder($orderBy);
$releases = $this->api->getReleaseByQuery($libID, $pager, $sort);
$releases = $this->api->getReleaseByQuery($libID, '', $sort);
$this->view->releases = $releases;
$this->view->pager = $pager;
$this->view->orderBy = $orderBy;
$this->view->title = $this->lang->api->managePublish;
$this->view->libID = $libID;
@@ -142,7 +222,7 @@ class api extends control
{
$this->api->deleteRelease($id);
if(dao::isError()) return $this->sendError(dao::getError());
return print(js::locate(inlink('releases', "libID=$libID"), 'parent'));
return print(js::execute("parent.removeRelease($id)"));
}
}
@@ -160,6 +240,7 @@ class api extends control
if(!empty($_POST))
{
$data = fixer::input('post')
->trim('version')
->add('lib', $libID)
->add('addedBy', $this->app->user->account)
->add('addedDate', helper::now())
@@ -173,7 +254,7 @@ class api extends control
$this->api->publishLib($data);
if(dao::isError()) return $this->sendError(dao::getError());
return $this->sendSuccess(array('locate' => $this->createLink('api', 'index', "libID=$libID")));
return $this->sendSuccess(array('locate' => 'parent'));
}
$libName = isset($lib->name) ? $lib->name : '';
@@ -194,16 +275,14 @@ class api extends control
* @access public
* @return void
*/
public function struct($libID = 0, $releaseID = 0, $orderBy = 'id', $recTotal = 0, $recPerPage = 15, $pageID = 1)
public function struct($libID = 0, $releaseID = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 15, $pageID = 1)
{
$libs = $this->doc->getApiLibs();
$this->app->loadClass('pager', $static = true);
$this->lang->modulePageNav = $this->generateLibsDropMenu($libs, $libID, $releaseID);
$pager = new pager($recTotal, $recPerPage, $pageID);
$this->setMenu($libID);
/* Append id for secend sort. */
$sort = common::appendOrder($orderBy);
$this->app->loadClass('pager', $static = true);
$pager = new pager($recTotal, $recPerPage, $pageID);
if($releaseID)
{
@@ -235,11 +314,14 @@ class api extends control
public function createStruct($libID = 0)
{
common::setMenuVars('doc', $libID);
$this->setMenu($libID);
if(!empty($_POST))
{
$now = helper::now();
$userId = $this->app->user->account;
$data = fixer::input('post')
->trim('name')
->add('lib', $libID)
->skipSpecial('attribute')
->add('addedBy', $userId)
@@ -280,6 +362,8 @@ class api extends control
public function editStruct($libID, $structID)
{
common::setMenuVars('doc', $libID);
$this->setMenu($libID);
$struct = $this->api->getStructByID($structID);
if(!empty($_POST))
@@ -329,30 +413,39 @@ class api extends control
/**
* Create a api doc library.
*
* @param string normal|demo
* @param string $type project|product
* @param int $objectID
* @access public
* @return void
*/
public function createLib($type = 'normal')
public function createLib($type = 'product', $objectID = 0)
{
if(!empty($_POST))
{
$libID = $type == 'demo' ? $this->api->createDemoData($this->post->name, $this->post->baseUrl) : $this->doc->createApiLib();
if(dao::isError()) return $this->sendError(dao::getError());
/* If the created api library of imported zentao api library, return directly. */
if($type == 'demo') return $this->sendSuccess(array('locate' => $this->createLink('api', 'index', "libID=$libID")));
$libID = $this->doc->createApiLib();
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
/* Record action for create api library. */
$this->action->create('docLib', $libID, 'Created');
$this->action->create('doclib', $libID, 'created');
if(isonlybody()) return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'parent'));
/* Set locate object data. */
setCookie("objectType", $this->post->libType, $this->config->cookieLife, $this->config->webRoot);
setCookie("objectID", $this->post->libType == 'project' ? $this->post->project : $this->post->product, $this->config->cookieLife, $this->config->webRoot);
if(!helper::isAjaxRequest()) return print(js::locate($this->createLink('api', 'index', "libID=$libID"), 'parent.parent'));
return $this->sendSuccess(array('locate' => $this->createLink('api', 'index', "libID=$libID")));
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->createLink('api', 'index', "libID=$libID")));
}
$this->view->type = $type;
$this->view->groups = $this->loadModel('group')->getPairs();
$this->view->users = $this->user->getPairs('nocode|noclosed');
$defaultAclLang = in_array($type, array('product', 'product')) ? $this->lang->{$type}->common : $this->lang->product->common;
$this->lang->api->aclList['default'] = sprintf($this->lang->api->aclList['default'], $defaultAclLang);
$this->view->type = $type;
$this->view->objectID = $objectID;
$this->view->groups = $this->loadModel('group')->getPairs();
$this->view->users = $this->user->getPairs('nocode|noclosed');
$this->view->projects = $this->loadModel('project')->getPairsByModel('scrum,waterfall,agileplus,waterfallplus');
$this->view->products = $this->loadModel('product')->getPairs();
$this->display();
}
@@ -366,28 +459,36 @@ class api extends control
*/
public function editLib($id)
{
$doc = $this->doc->getLibById($id);
if(!empty($_POST))
{
$lib = fixer::input('post')->join('groups', ',')->join('users', ',')->get();
if($lib->acl == 'private') $lib->users = $this->app->user->account;
$this->doc->updateApiLib($id, $doc, $lib);
$this->doc->updateApiLib($id);
if(dao::isError()) return $this->sendError(dao::getError());
$res = array(
'message' => $this->lang->saveSuccess,
'closeModal' => true,
'callback' => "redirectParentWindow($id)",
);
return $this->sendSuccess($res);
return $this->sendSuccess(array('message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => "redirectParentWindow($id)"));
}
$this->view->doc = $doc;
$this->view->groups = $this->loadModel('group')->getPairs();
$this->view->users = $this->user->getPairs('nocode|noclosed');
$lib = $this->doc->getLibById($id);
$type = 'nolink';
if(!empty($lib->product))
{
$type = 'product';
$this->view->object = $this->loadModel('product')->getByID($lib->product);
}
if(!empty($lib->project))
{
$type = 'project';
$this->view->object = $this->loadModel('project')->getById($lib->project);
}
if($type != 'nolink') $this->lang->api->aclList['default'] = sprintf($this->lang->doclib->aclList['default'], $this->lang->{$type}->common);
if($type == 'nolink') unset($this->lang->api->aclList['default']);
$this->view->lib = $lib;
$this->view->type = $type;
$this->view->groups = $this->loadModel('group')->getPairs();
$this->view->users = $this->user->getPairs('nocode|noclosed');
$this->view->projects = $this->loadModel('project')->getPairsByModel();
$this->view->products = $this->loadModel('product')->getPairs();
$this->display();
}
@@ -429,6 +530,7 @@ class api extends control
*/
public function edit($apiID)
{
$api = $this->api->getLibById($apiID);
if(helper::isAjaxRequest() && !empty($_POST))
{
$changes = $this->api->update($apiID);
@@ -440,10 +542,9 @@ class api extends control
$this->action->logHistory($actionID, $changes);
}
return $this->sendSuccess(array('locate' => helper::createLink('api', 'index', "libID=0&moduleID=0&apiID=$apiID")));
return $this->sendSuccess(array('locate' => helper::createLink('api', 'index', "libID=$api->lib&moduleID=0&apiID=$apiID")));
}
$api = $this->api->getLibById($apiID);
if($api)
{
$this->view->api = $api;
@@ -480,7 +581,9 @@ class api extends control
if($api === false) return $this->sendError(dao::getError());
$this->action->create('api', $api->id, 'Created');
return $this->sendSuccess(array('locate' => helper::createLink('api', 'index', "libID={$api->lib}&moduleID=0&apiID={$api->id}")));
if(isonlybody()) return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => 'true', 'callback' => "parentLocate({$api->id})"));
return $this->sendSuccess(array('locate' => helper::createLink('api', 'index', "libID={$api->lib}&moduleID={$api->module}&apiID={$api->id}")));
}
$libs = $this->doc->getLibs('api', '', $libID);
@@ -492,7 +595,6 @@ class api extends control
$libName = isset($lib->name) ? $lib->name . $this->lang->colon : '';
$this->getTypeOptions($libID);
$this->view->gobackLink = $this->createLink('api', 'index', "libID=$libID&moduleID=$moduleID");
$this->view->user = $this->app->user->account;
$this->view->allUsers = $this->loadModel('user')->getPairs('devfirst|noclosed');
$this->view->libID = $libID;
@@ -531,7 +633,7 @@ class api extends control
}
else
{
$this->sendSuccess(array('locate' => $this->createLink('api', 'index', "libID=$api->lib&module=$api->module")));
return print(js::locate(inlink('index', "libID=$api->lib&module=$api->module"), 'parent'));
}
}
}
@@ -605,128 +707,69 @@ class api extends control
}
/**
* Set doc menu by method name.
* Set api menu by method name.
*
* @param int $libID
* @param int $moduleID
* @access public
* @return void
*/
private function setMenu($libID = 0, $moduleID = 0)
private function setMenu($libID = 0)
{
common::setMenuVars('doc', $libID);
common::setMenuVars('doc', '');
/* Global struct link. */
$menu = '';
if($libID and common::hasPriv('api', 'createRelease'))
$lib = $this->loadModel('doc')->getLibByID($libID);
if($this->app->tab == 'product')
{
$menu .= html::a(helper::createLink('api', 'createRelease', "libID=$libID"), $this->lang->api->createRelease, '', 'class="btn btn-link iframe"');
$this->loadModel('product')->setMenu($lib->product);
}
elseif($this->app->tab == 'project')
{
$this->loadModel('project')->setMenu($lib->project);
}
/* page of index menu. */
if(common::hasPriv('api', 'create') or common::hasPriv('api', 'createLib'))
if(in_array($this->session->spaceType, array('product', 'project')))
{
$menu .= "<div class='dropdown' id='createDropdown'>";
$menu .= "<button class='btn btn-primary' type='button' data-toggle='dropdown'><i class='icon icon-plus'></i> " . $this->lang->api->createAB . " <span class='caret'></span></button>";
$menu .= "<ul class='dropdown-menu pull-right'>";
/* check has permission create api doc */
if(intval($libID) > 0 and common::hasPriv('api', 'create'))
{
$menu .= "<li>";
$menu .= html::a(helper::createLink('api', 'create', "libID=$libID&moduleID=$moduleID"), "<i class='icon-rich-text icon'></i> " . $this->lang->api->createApi, '', "data-app='{$this->app->tab}'");
$menu .= "</li>";
}
/* check has permission create api doc lib */
if(common::hasPriv('api', 'createLib'))
{
$menu .= '<li>' . html::a(helper::createLink('api', 'createLib'), "<i class='icon-doc-lib icon'></i> " . $this->lang->api->createLib, '', "class='iframe' data-width='70%'") . '</li>';
$menu .= '<li class="divider"></li>';
$menu .= '<li>' . html::a(helper::createLink('api', 'createLib', 'type=demo'), "<i class='icon-zentao icon'></i> " . $this->lang->api->createDemo, '', "class='iframe' data-width='70%'") . '</li>';
}
$menu .= "</ul></div>";
$this->lang->doc->menu->api['exclude'] = 'api-' . $this->app->rawMethod;
$this->lang->doc->menu->{$this->session->spaceType}['subModule'] = 'api';
}
$this->lang->TRActions = $menu;
}
/**
* Generate api doc index page dropMenu
*
* @param array $libs
* @param int $libID
* @param int $version
* @param object $lib
* @param int $version
* @access public
* @return string
*/
private function generateLibsDropMenu($libs, $libID, $version = 0)
private function generateLibsDropMenu($lib, $version = 0)
{
if(empty($libs)) return '';
if(!isset($libs[$libID])) return '';
if(empty($lib)) return '';
$methodName = $this->app->rawMethod;
$libName = $libs[$libID]->name;
$output = <<<EOT
<div class='btn-group angle-btn'>
<div class='btn-group'>
<button id='currentBranch' data-toggle='dropdown' type='button' class='btn btn-limit'><div class='nobr'>{$libName}</div> <span class='caret'></span>
</button>
<div id='dropMenu' class='dropdown-menu search-list' data-ride='searchList'>
<div class="input-control search-box has-icon-left has-icon-right search-example">
<input type="search" class="form-control search-input" />
<label class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label>
<a class="input-control-icon-right search-clear-btn"><i class="icon icon-close icon-sm"></i></a>
</div>
<div class='table-col'>
<div class='list-group'>
EOT;
foreach($libs as $key => $lib)
$objectTitle = $this->lang->api->noLinked;
$objectType = 'nolink';
$objectID = 0;
if($lib->product)
{
$selected = $key == $libID ? 'selected' : '';
$output .= html::a(inlink($methodName, "libID=$key"), $lib->name, '', "class='$selected' data-app='{$this->app->tab}'");
$objectType = 'product';
$objectID = $lib->product;
$product = $this->loadModel('product')->getByID($objectID);
$objectTitle = zget($product, 'name', '');
}
if(count($libs) >= 2 and common::hasPriv('doc', 'sortLibs'))
elseif($lib->project)
{
$output .= '<li class="divider"></li>';
$output .= html::a($this->createLink('doc', 'sortLibs', "type=api&objectID=0", '', true), "<i class='icon-move'></i> {$this->lang->doc->sortLibs}", '', "data-title='{$this->lang->doc->sortLibs}' data-toggle='modal' data-type='iframe' data-width='400px' data-app='{$this->app->tab}'");
}
$output .= "</div></div></div></div></div>";
/* Get lib version */
$versions = $this->api->getReleaseListByApi($libID);
if(!empty($versions))
{
$versionName = $version > 0 ? $versions[$version]->version : $this->lang->api->defaultVersion;
$output .= <<<EOT
<div class='btn-group angle-btn'>
<div class='btn-group'>
<button id='currentBranch' data-toggle='dropdown' type='button' class='btn btn-limit'><div class='nobr'>{$versionName}</div> <span class='caret'></span>
</button>
<div id='dropMenu' class='dropdown-menu search-list' data-ride='searchList'>
<div class="input-control search-box has-icon-left has-icon-right search-example">
<input type="search" class="form-control search-input" />
<label class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label>
<a class="input-control-icon-right search-clear-btn"><i class="icon icon-close icon-sm"></i></a>
</div>
<div class='table-col'>
<div class='list-group'>
EOT;
$params = $methodName == 'index' ? "libID=$libID&moduleID=0&apiID=0&version=0" : "libID=$libID";
$selected = $version > 0 ? '' : 'selected';
$output .= html::a(inlink($methodName, $params . "&release=0"), $this->lang->api->defaultVersion, '', "class='$selected'");
foreach($versions as $key => $item)
{
$selected = $key == $version ? 'selected' : '';
$output .= html::a(inlink($methodName, $params . "&release=$key"), $item->version, '', "class='$selected' data-app='{$this->app->tab}'");
}
$output .= "</div></div></div></div></div>";
$objectType = 'project';
$objectID = $lib->project;
$project = $this->loadModel('project')->getByID($objectID);
$objectTitle = zget($project, 'name', '');
}
$dropMenuLink = helper::createLink('api', 'ajaxGetDropMenu', "objectType=$objectType&objectID=$objectID&libID=$lib->id&version=$version");
$output = "<div class='btn-group selectBox' id='swapper'><button data-toggle='dropdown' type='button' class='btn' id='currentItem' title='{$objectTitle}'><span class='text'>{$objectTitle}</span> <span class='caret' style='margin-bottom: -1px'></span></button><div id='dropMenu' class='dropdown-menu search-list' data-ride='searchList' data-url='$dropMenuLink'>";
$output .= '<div class="input-control search-box has-icon-left has-icon-right search-example"><input type="search" class="form-control search-input" /><label class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label><a class="input-control-icon-right search-clear-btn"><i class="icon icon-close icon-sm"></i></a></div>';
$output .= "</div></div>";
return $output;
}
@@ -861,4 +904,63 @@ EOT;
}
$this->view->typeOptions = $options;
}
/**
* Ajax get objectType drop menu.
*
* @param string $objectType
* @param int $objectID
* @param string $module
* @param string $method
* @access public
* @return void
*/
public function ajaxGetDropMenu($objectType, $objectID, $module, $method)
{
list($normalObjects, $closedObjects) = $this->api->getOrderedObjects();
$titleList = array($this->lang->api->noLinked);
if(!empty($normalObjects['product'])) $titleList += array_values($normalObjects['product']);
if(!empty($normalObjects['project'])) $titleList += array_values($normalObjects['project']);
if(!empty($closedObjects['product'])) $titleList += array_values($closedObjects['product']);
if(!empty($closedObjects['project'])) $titleList += array_values($closedObjects['project']);
$this->view->objectType = $objectType;
$this->view->objectID = $objectID;
$this->view->module = $module;
$this->view->method = $method;
$this->view->normalObjects = $normalObjects;
$this->view->closedObjects = $closedObjects;
$this->view->nolinkLibs = $this->doc->getApiLibs(0, 'nolink');
$this->view->objectsPinYin = common::convert2Pinyin($titleList);
$this->display();
}
/**
* Edit a catalog.
*
* @param int $moduleID
* @param string $type doc|api
* @access public
* @return void
*/
public function editCatalog($moduleID, $type)
{
echo $this->fetch('tree', 'edit', "moduleID=$moduleID&type=$type");
}
/**
* Delete a catalog.
*
* @param int $rootID
* @param int $moduleID
* @param string $confirm yes|no
* @access public
* @return void
*/
public function deleteCatalog($rootID, $moduleID, $confirm = 'no')
{
echo $this->fetch('tree', 'delete', "rootID=$rootID&moduleID=$moduleID&confirm=$confirm");
}
}
+59
View File
@@ -100,3 +100,62 @@ ol, ul {margin-bottom: 0}
form .table-data, #content .table-data {border: 1px solid #e2e2e3;}
.table-data thead {background: #f9f9f9;}
#aclBox .acl-tip {color: #838a9d;}
.lib {width: 130px; margin-bottom: 10px;}
.addbtn {padding-top: 22px; height: 63px; border: 1px dashed #ddd; width: 60px;}
.addbtn .icon-plus {font-size: 18px; display: block; opacity: 0.5; transition: opacity .2s; text-shadow: 1px 1px 3px rgba(0,0,0,.2);}
.addbtn:hover .icon-plus {opacity: .9; animation: flash-icon 1s linear alternate infinite;}
#subHeader #dropMenu {min-width: 250px; box-sizing: inhert; max-height: inherit;}
#subHeader #dropMenu .table-col .list-group {padding-top: 10px;}
.main-col .block-files .panel-heading {padding-right: 20px;}
.main-col .block-files .panel-heading .panel-title {height: 35px; line-height: 30px;}
.side-col .action a {margin: 0 auto 3px; display: block; max-width: 200px;}
.side-col .tips {padding: 0 10px;}
.main-col .doc-title {display: flex; font-size: 16px; margin-bottom: 15px;}
.main-col .doc-title .title {margin: 0; line-height: 30px; font-size: 25px;}
.main-col .doc-title .http-method {line-height: 27px; height: 27px; font-size: 13px; margin-right: 10px; padding: 0 10px;}
.main-col .doc-title .path {line-height: 30px; font-size: 20px; margin-right: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
.main-col .doc-title .info {flex: 1 1 0;}
.main-col .doc-title .version a {font-size: 13px; color: #8c8c8c;}
.main-col .doc-title .version .dropdown-menu a:hover {color: #ffffff;}
.main-col .doc-title .actions {display: inline-block;}
.main-col .doc-title .actions a + a {margin-left: 8px;}
.main-col .doc-title .actions i {font-size: 15px; color: #8c8c8c;}
#content h2.title {margin: 0; font-size: 17px;}
#content h3.title {font-weight: 500; font-size: 17px!important;}
#content .desc {margin: 10px 0; color: #57585b; word-wrap: break-word;}
#content .detail-content {padding-left: 10px;}
#mainContent .scrollbar-hover {max-height: 2000px; overflow: scroll;}
#sidebar {width: 275px;}
#sidebar>.cell {width: 100%;}
#sidebar>.sidebar-toggle {left: 3px; right: auto;}
.hide-sidebar #sidebar>.cell {display: none;}
.hide-sidebar #sidebar>.sidebar-toggle>.icon:before {content: "\e314";}
.detail.empty {line-height: 200px;}
.main-col+.side-col {padding-left: 16px;}
.main-col iframe {min-height: 380px;}
.article-content .keywords {margin-bottom: 15px;}
.article-content {width: 100%; display: inline-block;}
.outline {position: relative;}
.outline .outline-toggle i.icon-angle-right, i.icon-angle-left {width: 18px; height: 18px; border-radius: 50%; position: absolute; padding-left: 2px; padding-top: 1px;}
.outline .outline-toggle i.icon-angle-right:before {content: "\e314"; cursor: pointer;}
.outline .outline-toggle i.icon-angle-left:before {content: "\e315"; cursor: pointer;}
.outline ul li {list-style: none;}
.outline-content {display: none; padding-top: 18px;}
.outline-content a {color: #838A9D;}
.outline-content li.text-ellipsis.active>a {font-weight: 700; color: #0c64eb;}
#outline li.has-list.open:before {content: unset;}
.article-content.comment {width: 100% !important;}
.cell .detail .detail-title {padding-left: 5px; list-style: none;}
.menu-actions {top: 5px!important; right: 45px;}
.no-content {width: 100px; height: 100px; margin: 0 auto;}
.notice {text-align: center; padding-left: 15px; padding-top: 20px;}
.no-content-button {text-align: center; padding-top: 20px;}
.no-content-button a:nth-child(2) {margin-left: 20px;}
.paramsTable th {text-align: left!important; font-size: 14px;}
.paramsTable td {text-align: left;}
+2 -1
View File
@@ -1,5 +1,6 @@
.modal-dialog {width: 75%;}
form {margin-bottom: 100px; padding-left: 65px;}
form {margin-bottom: 100px;}
table {width: 90% !important;}
#whiteListBox div.input-group {margin-bottom: 2px;}
#whiteListBox .input-group:last-child {margin-top: 10px;}
#aclBox > th {vertical-align: top; padding-top: 18px;}
+44 -134
View File
@@ -1,142 +1,52 @@
.lib {width: 130px; margin-bottom: 10px;}
.addbtn {padding-top: 22px; height: 63px; border: 1px dashed #ddd; width: 60px;}
.addbtn .icon-plus {font-size: 18px; display: block; opacity: 0.5; transition: opacity .2s; text-shadow: 1px 1px 3px rgba(0,0,0,.2);}
.addbtn:hover .icon-plus {opacity: .9; animation: flash-icon 1s linear alternate infinite;}
#subHeader #dropMenu {min-width: 250px; box-sizing: inhert; max-height: inherit;}
#subHeader #dropMenu .table-col .list-group {padding-top: 10px;}
.main-col .block-files .panel-heading {padding-right: 20px;}
.main-col .block-files .panel-heading .panel-title {height: 35px; line-height: 30px;}
.side-col .action a {margin: 0 auto 3px; display: block; max-width: 200px;}
.side-col .tips {padding: 0 10px;}
.main-col .doc-title {display: flex; font-size: 16px; margin-bottom: 15px;}
.main-col .doc-title .title {margin: 0; line-height: 30px; font-size: 25px;}
.main-col .doc-title .http-method {line-height: 27px; height: 27px; font-size: 13px; margin-right: 10px; padding: 0 10px;}
.main-col .doc-title .path {line-height: 30px; font-size: 20px; margin-right: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
.main-col .doc-title .info {flex: 1 1 0;}
.main-col .doc-title .version a {font-size: 13px; color: #8c8c8c;}
.main-col .doc-title .version .dropdown-menu a:hover {color: #ffffff;}
.main-col .doc-title .actions {min-width: 120px; display: inline-block;}
.main-col .doc-title .actions a + a {margin-left: 8px;}
.main-col .doc-title .actions i {font-size: 15px; color: #8c8c8c;}
#content h2.title {margin: 0; font-size: 17px;}
#content h3.title {font-weight: 500; font-size: 17px!important;}
#content .desc {margin: 10px 0; color: #57585b; word-wrap: break-word;}
#content .detail-content {padding-left: 10px;}
#mainContent .scrollbar-hover {max-height: 2000px; overflow: scroll;}
#sidebar {width: 275px;}
#sidebar>.cell {width: 100%;}
#sidebar>.sidebar-toggle {left: 3px; right: auto;}
.hide-sidebar #sidebar>.cell {display: none;}
.hide-sidebar #sidebar>.sidebar-toggle>.icon:before {content: "\e314";}
.detail.empty {line-height: 200px;}
.main-col+.side-col {padding-left: 16px;}
.main-col iframe {min-height: 380px;}
.article-content .keywords {margin-bottom: 15px;}
.lib {width: unset; margin-bottom: unset;}
.flex {display: flex;}
.flex-none {flex: none;}
.flex-auto {flex: auto;}
.flex-full > .panel {box-shadow: none;}
.float-r {float: right;}
.h-full {height: 100%;}
.w-full {width: 100%;}
.overflow-x-auto {overflow-x: auto;}
.overflow-auto {overflow: auto;}
.overflow-visible {overflow: visible;}
.overflow-hidden {overflow: hidden;}
.img-lib {width: 14px; height: 14px; margin-bottom: 2px; flex: 0 0 14px;}
.cell {padding: 0;}
#mainContent {padding-top: 0; padding-bottom: 0;}
#mainContent #createDropdown {display: inline-block;}
#mainContent #createDropdown ul {position: absolute;}
#pageNav .dropdown-menu {max-height: inherit;}
#mainContent > .panel {margin-bottom: 0; height: calc(100vh - 125px); overflow-y: auto;}
#mainContent > .main-col {padding-left: 0;}
.article-content {width: 100%; display: inline-block;}
.outline {position: relative;}
.outline .outline-toggle i.icon-angle-right, i.icon-angle-left {width: 18px; height: 18px; border-radius: 50%; position: absolute; padding-left: 2px; padding-top: 1px;}
.outline .outline-toggle i.icon-angle-right:before {content: "\e314"; cursor: pointer;}
.outline .outline-toggle i.icon-angle-left:before {content: "\e315"; cursor: pointer;}
.outline ul li {list-style: none;}
.outline-content {display: none; padding-top: 18px;}
.outline-content a {color: #838A9D;}
.outline-content li.text-ellipsis.active>a {font-weight: 700; color: #0c64eb;}
#outline li.has-list.open:before {content: unset;}
.article-content.comment {width: 100% !important;}
.cell .detail .detail-title {padding-left: 5px; list-style: none;}
.menu-actions {position: absolute; top: 7px; right: 45px; padding: 7px 8px;}
.no-content {width: 100px; height: 100px; margin: 0 auto;}
.notice {text-align: center; padding-left: 15px; padding-top: 20px;}
.no-content-button {text-align: center; padding-top: 20px;}
.no-content-button a:nth-child(2) {margin-left: 20px;}
.detail .list-group-item .heading.GET {
background-color: #e7f0f7;
}
.detail .list-group-item .heading.GET a {
color: #0f6ab4;
}
.apiList .detail .detail-title {padding-left: 5px; list-style: none;}
.menu-actions {position: absolute; top: 7px; right: 45px; padding: 7px 8px;}
.detail ul {position: relative;}
.tail-info {position: absolute; right: 0; padding-left: 10px; padding-top: 1px;}
.tail-info, .doc-title, span.item {background: #fff;}
span.item>a {padding-left: 6px;}
span.dotted-line+a {display: block;}
#modules li.doc:before, .chapterNode:before, .independent:before {content: " "; width: 100%; border-bottom: 1px dashed #b5b9c5; position: absolute; top: 13px; right: 0; left: 30px;}
.doc-title ,.item{display: inline-block !important; position: relative; padding-right: 10px; max-width:80%; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;}
#modules i.icon-file-text {color: #D0D2D6; font-size: 14px;}
.detail .list-group-item .heading.OPTIONS {
background-color: #e7f0f7;
}
.detail .list-group-item .heading.OPTIONS a {
color: #0f6ab4;
}
.sortable-sorting .module-name > a {cursor: move;}
.sortable-sorting li >.tree-group {opacity: .5;}
.sortable-sorting li:before {opacity: .3;}
.sortable-sorting .drop-here .tree-group {background-color: #fff3e0;}
.sortable-sorting .drop-here .tree-group > * {opacity: .1;}
.sortable-sorting .drag-shadow .tree-group {opacity: 1!important;}
.sortable-sorting .drag-shadow .tree-actions {visibility: hidden;}
.is-sorting > li:before {opacity: 1;}
.is-sorting > li > .tree-group {opacity: 1; border-radius: 4px;}
.is-sorting > li ul {display: none!important;}
li.drag-shadow ul {display: none!important;}
.apiList {height: 100%;}
.detail .list-group-item .heading.POST {
background-color: #e7f6ec;
}
.detail .list-group-item .heading.POST a {
color: #10a54a;
}
.detail .list-group-item .heading.PUT {
background-color: #f9f2e9;
}
.detail .list-group-item .heading.PUT a {
color: #c5862b;
}
.detail .list-group-item .heading.PATCH {
background-color: #f9f2e9;
}
.detail .list-group-item .heading.PATCH a {
color: #c5862b;
}
.detail .list-group-item .heading.DELETE {
background-color: #f5e8e8;
border: 1px solid #e8c6c7;
}
.detail .list-group-item .heading.DELETE a {
color: #a41e22;
}
.detail .list-group-item a {
display: flex;
align-items: center;
}
.detail .list-group-item .path, .detail .list-group-item .desc {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.detail .list-group-item .path {
padding-left: 10px;
font-size: 14px;
color: black;
flex: 1;
}
.detail .list-group-item .desc {
width: auto;
font-size: 14px;
line-height: 38px;
float: right;
padding-right: 10px;
max-width: 200px;
}
.detail .list-group-item {list-style: none; font-size: 14px; margin-bottom: 10px; line-height: 30px}
.detail .list-group-item span {line-height: 30px; width: 65px;}
.detail .list-group-item .label+.label {margin-left: -4px;}
.detail .list-group-item .label {border-radius: 0;}
.paramsTable th {text-align: left!important; font-size: 14px;}
.paramsTable td {text-align: left;}
.tree-group {position: relative;}
.tree-group > .module-name {white-space: nowrap; overflow: hidden; text-overflow: ellipsis; width: 100%; display: block;}
.tree li.active > .tree-group a {font-weight: 700; color: #0c64eb;}
.tree-actions {display: inline-block; margin-left: 5px; vertical-align: middle;}
.tree-group .tree-actions {display: none; position: absolute; right: 0; top: 0; background-color: #fff; white-space: nowrap;}
.tree-group:hover .tree-actions {display: block}
.tree-actions a {display: inline-block; margin-left: 5px; font-size: 13px; opacity: .6;}
.tree li.active > .tree-group a {font-weight: 700; color: #0c64eb;}
.base-url {background: #f3f3f3; margin: 0; border-top: 1px solid #eee;}
.base-url > p {margin: 0; padding-left: 20px; color: black;}
.detail+.detail {border-top: 0px;}
#queryBox #groupAndOr {min-width: 60px;}
.tree li>.list-toggle {left: -4px;}
+3 -3
View File
@@ -1,6 +1,6 @@
.c-date {width: 150px;}
.c-actions {width: 60px;}
tbody tr td {white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.m-api-releases {padding-bottom: 0px !important;}
tbody tr td {white-space: nowrap; overflow: hidden; text-overflow: clip;}
#mainContent {max-height: 400px;}
#releaseListForm {margin-bottom: 20px;}
+5 -12
View File
@@ -1,12 +1,5 @@
.col-attr {
vertical-align: middle;
margin-bottom: 8px;
}
.tree {
padding-left: 30px!important;
}
.c-date {
width: 200px;
}
.col-attr {vertical-align: middle; margin-bottom: 8px;}
.tree {padding-left: 30px!important;}
.leftBar > .btn {margin-right: 0px;}
.leftBar > .divider {color: #D9D9D9;}
.leftBar > .page-title > .text {font-weight: 400;}
+30 -6
View File
@@ -19,7 +19,7 @@ function loadDocModule(libID)
*/
function toggleAcl(acl, type)
{
if(acl == 'custom')
if(acl == 'private')
{
$('#whiteListBox').removeClass('hidden');
}
@@ -27,15 +27,39 @@ function toggleAcl(acl, type)
{
$('#whiteListBox').addClass('hidden');
}
if(type == 'lib')
}
/**
* Toggle lib type.
*
* @param string $libType
* @access public
* @return void
*/
function toggleLibType(libType)
{
if(libType == 'project')
{
var notice = typeof(noticeAcl[acl]) != 'undefined' ? noticeAcl[acl] : '';
$('#noticeAcl').html(notice);
$('#projectBox').removeClass('hidden');
$('#productBox').addClass('hidden');
$('#acldefault').closest('.radio').show();
$('#acldefault').next('.acl-tip').html($('#acldefault').next('.acl-tip').html().replace(productLang, projectLang));
}
else if(libType == 'product')
{
$('#projectBox').addClass('hidden');
$('#productBox').removeClass('hidden');
$('#acldefault').closest('.radio').show();
$('#acldefault').next('.acl-tip').html($('#acldefault').next('.acl-tip').html().replace(projectLang, productLang));
}
else
{
var notice = typeof(noticeAcl[acl]) != 'undefined' ? noticeAcl[acl] : '';
$('#noticeAcl').html(notice);
var acl = $("input[name='acl']:checked").val();
if(acl == 'default') $("input[id='aclopen']").prop('checked', true);
$('#projectBox').addClass('hidden');
$('#productBox').addClass('hidden');
$('#acldefault').closest('.radio').hide();
}
}
+14
View File
@@ -84,3 +84,17 @@ var app = new Vue({
}
}
})
/**
* locate link in parent.
*
* @param int $apiID
* @access public
* @return void
*/
function parentLocate(apiID)
{
config.onlybody = 'no';
var link = createLink('api', 'index', 'libID=0&moduleID=0&apiID=' + apiID) + '#app=doc';
window.parent.$.apps.open(link);
}
+4 -2
View File
@@ -1,4 +1,4 @@
$(document).ready(function()
$(function()
{
$('#apiForm').ajaxForm({
success: (data) => {
@@ -10,4 +10,6 @@ $(document).ready(function()
}
}
})
});
toggleLibType(libType);
});
-13
View File
@@ -1,13 +0,0 @@
$(document).ready(function()
{
$('#apiForm').ajaxForm({
success: (data) => {
if (data.result == 'success') {
if (data.locate) {
window.parent.location.href = data.locate
}
$.zui.closeModal()
}
}
})
});
@@ -1,42 +1,3 @@
$(document).ready(function()
{
/* Update doc content silently on switch doc version, story #40503 */
$(document).on('click', '.api-version-menu a, #mainActions .container a', function(event)
{
var $tmpDiv = $('<div>');
$tmpDiv.load($(this).data('url') + ' #mainContent', function()
{
$('#content').html($tmpDiv.find('#content').html());
$('#sidebarContent').html($tmpDiv.find('#sidebarContent').html());
$('#actionbox .histories-list').html($tmpDiv.find('#actionbox .histories-list').html());
if($.cookie('isFullScreen') == 1) fullScreen();
$('#content [data-ride="tree"]').tree();
$('#outline li.has-list').addClass('open in');
$('#outline li.has-list>i+ul').prev('i').remove();
});
});
});
/**
* Ajax delete api doc.
*
* @param string $link
* @param int $replaceID
* @param stirng $notice
* @access public
* @return void
*/
function ajaxDeleteApi(link, replaceID)
{
if(confirm(confirmDelete))
{
$.get(link, function(data)
{
location.href = JSON.parse(data).locate;
});
}
}
/**
* Display the document in full screen.
*
@@ -46,7 +7,7 @@ function ajaxDeleteApi(link, replaceID)
function fullScreen()
{
var element = document.getElementById('content');
var requestMethod = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || element.msRequestFullScreen;
var requestMethod = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || element.msRequestFullscreen;
if(requestMethod)
{
var afterEnterFullscreen = function()
@@ -54,6 +15,8 @@ function fullScreen()
$('#mainActions').removeClass('hidden');
$('#content').addClass('scrollbar-hover');
$('#content .actions').addClass('hidden');
$('#content .file-image .right-icon').addClass('hidden');
$('#content .detail').eq(1).addClass('hidden');
$.cookie('isFullScreen', 1);
};
@@ -79,6 +42,8 @@ function fullScreen()
whenFailEnterFullscreen(error);
}
}
$('.main-col iframe').css('min-height', $(window).height() + 'px');
}
/**
@@ -92,8 +57,12 @@ function exitFullScreen()
$('#mainActions').addClass('hidden');
$('#content').removeClass('scrollbar-hover');
$('#content .actions').removeClass('hidden');
$('#content .file-image .right-icon').removeClass('hidden');
$('#content .detail').eq(1).removeClass('hidden');
$('.main-col iframe').css('min-height', '380px');
$.cookie('isFullScreen', 0);
}
document.addEventListener('fullscreenchange', function (e)
{
if(!document.fullscreenElement) exitFullScreen();
@@ -113,3 +82,40 @@ document.addEventListener('msfullscreenChange', function (e)
{
if(!document.msfullscreenElement) exitFullScreen();
});
$(function()
{
$(document).keydown(function(event)
{
if($.cookie('isFullScreen') == 1)
{
if(event.keyCode == 37) $('#prevPage').click();
if(event.keyCode == 39) $('#nextPage').click();
}
});
if($.cookie('isFullScreen') == 1) fullScreen();
$('.menu-actions > a').click(function()
{
$(this).parent().hasClass('open') ? $(this).css('background', 'none') : $(this).css('background', '#f1f1f1');
})
$('.menu-actions > a').blur(function() {$(this).css('background', 'none');})
/* Update doc content silently on switch doc version, story #40503 */
$(document).on('click', '.api-version-menu a, #mainActions .container a', function(event)
{
var $tmpDiv = $('<div>');
$tmpDiv.load($(this).data('url') + ' #mainContent', function()
{
$('#content').html($tmpDiv.find('#content').html());
$('#sidebarContent').html($tmpDiv.find('#sidebarContent').html());
$('#actionbox .histories-list').html($tmpDiv.find('#actionbox .histories-list').html());
if($.cookie('isFullScreen') == 1) fullScreen();
$('#content [data-ride="tree"]').tree();
$('#outline li.has-list').addClass('open in');
$('#outline li.has-list>i+ul').prev('i').remove();
});
});
});
+18 -5
View File
@@ -13,7 +13,7 @@ $lang->api->common = 'API';
$lang->api->getModel = 'Super Model API';
$lang->api->sql = 'SQL Query API';
$lang->api->index = 'Home';
$lang->api->index = 'API Space';
$lang->api->editLib = 'Edit';
$lang->api->releases = 'Release';
$lang->api->deleteRelease = 'Delete Release';
@@ -39,7 +39,6 @@ $lang->api->noModule = 'No directory in the API library. Please add the
$lang->api->post = 'Auf Seiten Liste beziehen bei POST Debug';
$lang->api->noUniqueName = 'The API library name exists.';
$lang->api->noUniqueVersion = 'The version exists.';
$lang->api->version = 'Version';
$lang->api->createStruct = 'Create Data Structure';
$lang->api->editStruct = 'Edit Data Structure';
$lang->api->deleteStruct = 'Delete Data Structure';
@@ -61,12 +60,16 @@ $lang->api->defaultVersion = "Current Version";
$lang->api->zentaoAPI = "Zentao API v1";
$lang->api->search = "Search";
$lang->api->allLibs = "AllLibs";
$lang->api->noLinked = "No Linked";
$lang->api->addCatalog = 'Add Catalog';
$lang->api->editCatalog = 'Edit Catalog';
$lang->api->deleteCatalog = 'Delete Catalog';
/* Common access control lang. */
$lang->api->whiteList = 'Whitelist';
$lang->api->aclList['open'] = 'Open';
$lang->api->aclList['private'] = 'Private';
$lang->api->aclList['custom'] = 'Custom';
$lang->api->aclList['open'] = "Public <span class='acl-tip'>(Users who can access doccan access it)</span>";
$lang->api->aclList['default'] = "Default <span class='acl-tip'>(Users who can access the selected %s can access it)</span>";
$lang->api->aclList['private'] = "Private <span class='acl-tip'> (Only the one who created it or users in the whiltelist can access it)</span>";
$lang->api->group = 'Group';
$lang->api->user = 'User';
@@ -87,6 +90,7 @@ $lang->struct->desc = 'Description';
$lang->struct->descPlaceholder = 'Parameter Description';
$lang->struct->action = 'Action';
$lang->struct->addSubField = 'Add Subfield';
$lang->struct->list = 'Data Structure List';
$lang->struct->typeOptions = array(
'formData' => 'FormData',
@@ -148,6 +152,10 @@ $lang->api->default = 'Default';
$lang->api->desc = 'Beschreibung';
$lang->api->customType = 'Custom Structure';
$lang->api->format = 'Format';
$lang->api->libType = 'Api Library Type';
$lang->api->product = $lang->productCommon;
$lang->api->project = $lang->projectCommon;
$lang->api->methodOptions = array(
'GET' => 'GET',
'POST' => 'POST',
@@ -169,6 +177,11 @@ $lang->api->requestTypeOptions['application/json'] = 'applicati
$lang->api->requestTypeOptions['application/x-www-form-urlencoded'] = 'application/x-www-form-urlencoded';
$lang->api->requestTypeOptions['multipart/form-data'] = 'multipart/form-data';
$lang->api->libTypeList = array();
$lang->api->libTypeList['product'] = $lang->productCommon . ' Api Library';
$lang->api->libTypeList['project'] = $lang->projectCommon . ' Api Library';
$lang->api->libTypeList['nolink'] = 'No Linked Api Library';
$lang->api->statusOptions = array(
'done' => 'Done',
'doing' => 'Doing',
+18 -5
View File
@@ -13,7 +13,7 @@ $lang->api->common = 'API';
$lang->api->getModel = 'Super Model API';
$lang->api->sql = 'SQL Query API';
$lang->api->index = 'Home';
$lang->api->index = 'API Space';
$lang->api->editLib = 'Edit';
$lang->api->releases = 'Release';
$lang->api->deleteRelease = 'Delete Release';
@@ -39,7 +39,6 @@ $lang->api->noModule = 'No directory in the API library. Please add the
$lang->api->post = 'Please refer to the page form for post debugging';
$lang->api->noUniqueName = 'The API library name exists.';
$lang->api->noUniqueVersion = 'The version exists.';
$lang->api->version = 'Version';
$lang->api->createStruct = 'Create Data Structure';
$lang->api->editStruct = 'Edit Data Structure';
$lang->api->deleteStruct = 'Delete Data Structure';
@@ -61,12 +60,16 @@ $lang->api->defaultVersion = "Current Version";
$lang->api->zentaoAPI = "Zentao API v1";
$lang->api->search = "Search";
$lang->api->allLibs = "AllLibs";
$lang->api->noLinked = "No Linked";
$lang->api->addCatalog = 'Add Catalog';
$lang->api->editCatalog = 'Edit Catalog';
$lang->api->deleteCatalog = 'Delete Catalog';
/* Common access control lang. */
$lang->api->whiteList = 'Whitelist';
$lang->api->aclList['open'] = 'Open';
$lang->api->aclList['private'] = 'Private';
$lang->api->aclList['custom'] = 'Custom';
$lang->api->aclList['open'] = "Public <span class='acl-tip'>(Users who can access doccan access it)</span>";
$lang->api->aclList['default'] = "Default <span class='acl-tip'>(Users who can access the selected %s can access it)</span>";
$lang->api->aclList['private'] = "Private <span class='acl-tip'> (Only the one who created it or users in the whiltelist can access it)</span>";
$lang->api->group = 'Group';
$lang->api->user = 'User';
@@ -87,6 +90,7 @@ $lang->struct->desc = 'Description';
$lang->struct->descPlaceholder = 'Parameter Description';
$lang->struct->action = 'Action';
$lang->struct->addSubField = 'Add Subfield';
$lang->struct->list = 'Data Structure List';
$lang->struct->typeOptions = array(
'formData' => 'FormData',
@@ -148,6 +152,10 @@ $lang->api->default = 'Default';
$lang->api->desc = 'Description';
$lang->api->customType = 'Custom Structure';
$lang->api->format = 'Format';
$lang->api->libType = 'Api Library Type';
$lang->api->product = $lang->productCommon;
$lang->api->project = $lang->projectCommon;
$lang->api->methodOptions = array(
'GET' => 'GET',
'POST' => 'POST',
@@ -169,6 +177,11 @@ $lang->api->requestTypeOptions['application/json'] = 'applicati
$lang->api->requestTypeOptions['application/x-www-form-urlencoded'] = 'application/x-www-form-urlencoded';
$lang->api->requestTypeOptions['multipart/form-data'] = 'multipart/form-data';
$lang->api->libTypeList = array();
$lang->api->libTypeList['product'] = $lang->productCommon . ' Api Library';
$lang->api->libTypeList['project'] = $lang->projectCommon . ' Api Library';
$lang->api->libTypeList['nolink'] = 'No Linked Api Library';
$lang->api->statusOptions = array(
'done' => 'Done',
'doing' => 'Doing',
+18 -5
View File
@@ -13,7 +13,7 @@ $lang->api->common = 'API';
$lang->api->getModel = 'Super Model API';
$lang->api->sql = 'SQL Query API';
$lang->api->index = 'Home';
$lang->api->index = 'API Space';
$lang->api->editLib = 'Edit';
$lang->api->releases = 'Release';
$lang->api->deleteRelease = 'Delete Release';
@@ -39,7 +39,6 @@ $lang->api->noModule = 'No directory in the API library. Please add the
$lang->api->post = 'Se référer à la liste si POST Debug';
$lang->api->noUniqueName = 'The API library name exists.';
$lang->api->noUniqueVersion = 'The version exists.';
$lang->api->version = 'Version';
$lang->api->createStruct = 'Create Data Structure';
$lang->api->editStruct = 'Edit Data Structure';
$lang->api->deleteStruct = 'Delete Data Structure';
@@ -61,12 +60,16 @@ $lang->api->defaultVersion = "Current Version";
$lang->api->zentaoAPI = "Zentao API v1";
$lang->api->search = "Search";
$lang->api->allLibs = "AllLibs";
$lang->api->noLinked = "No Linked";
$lang->api->addCatalog = 'Add Catalog';
$lang->api->editCatalog = 'Edit Catalog';
$lang->api->deleteCatalog = 'Delete Catalog';
/* Common access control lang. */
$lang->api->whiteList = 'Whitelist';
$lang->api->aclList['open'] = 'Open';
$lang->api->aclList['private'] = 'Private';
$lang->api->aclList['custom'] = 'Custom';
$lang->api->aclList['open'] = "Public <span class='acl-tip'>(Users who can access doccan access it)</span>";
$lang->api->aclList['default'] = "Default <span class='acl-tip'>(Users who can access the selected %s can access it)</span>";
$lang->api->aclList['private'] = "Private <span class='acl-tip'> (Only the one who created it or users in the whiltelist can access it)</span>";
$lang->api->group = 'Group';
$lang->api->user = 'User';
@@ -87,6 +90,7 @@ $lang->struct->desc = 'Description';
$lang->struct->descPlaceholder = 'Parameter Description';
$lang->struct->action = 'Action';
$lang->struct->addSubField = 'Add Subfield';
$lang->struct->list = 'Data Structure List';
$lang->struct->typeOptions = array(
'formData' => 'FormData',
@@ -148,6 +152,10 @@ $lang->api->default = 'Default';
$lang->api->desc = 'Description';
$lang->api->customType = 'Custom Structure';
$lang->api->format = 'Format';
$lang->api->libType = 'Api Library Type';
$lang->api->product = $lang->productCommon;
$lang->api->project = $lang->projectCommon;
$lang->api->methodOptions = array(
'GET' => 'GET',
'POST' => 'POST',
@@ -169,6 +177,11 @@ $lang->api->requestTypeOptions['application/json'] = 'applicati
$lang->api->requestTypeOptions['application/x-www-form-urlencoded'] = 'application/x-www-form-urlencoded';
$lang->api->requestTypeOptions['multipart/form-data'] = 'multipart/form-data';
$lang->api->libTypeList = array();
$lang->api->libTypeList['product'] = $lang->productCommon . ' Api Library';
$lang->api->libTypeList['project'] = $lang->projectCommon . ' Api Library';
$lang->api->libTypeList['nolink'] = 'No Linked Api Library';
$lang->api->statusOptions = array(
'done' => 'Done',
'doing' => 'Doing',
+36 -23
View File
@@ -13,13 +13,13 @@ $lang->api->common = 'API接口';
$lang->api->getModel = '超级model调用接口';
$lang->api->sql = 'SQL查询接口';
$lang->api->index = '接口库主页';
$lang->api->editLib = '编辑接口库';
$lang->api->index = '接口空间';
$lang->api->editLib = '编辑库';
$lang->api->releases = '版本管理';
$lang->api->deleteRelease = '删除版本';
$lang->api->deleteLib = '删除接口库';
$lang->api->deleteLib = '删除库';
$lang->api->createRelease = '发布接口';
$lang->api->createLib = '创建接口库';
$lang->api->createLib = '创建库';
$lang->api->createApi = '创建接口';
$lang->api->createAB = '创建';
$lang->api->createDemo = '导入禅道API';
@@ -35,17 +35,16 @@ $lang->api->result = '返回结果';
$lang->api->status = '状态';
$lang->api->data = '内容';
$lang->api->noParam = 'GET方式调试不需要输入参数,';
$lang->api->noModule = '接口库下没有目录,请先维护目录';
$lang->api->noModule = '库下没有目录,请先维护目录';
$lang->api->post = 'POST方式调试请参照页面表单';
$lang->api->noUniqueName = '接口库名已存在。';
$lang->api->noUniqueName = '库名已存在。';
$lang->api->noUniqueVersion = '版本已存在。';
$lang->api->version = '版本';
$lang->api->createStruct = '创建数据结构';
$lang->api->editStruct = '编辑数据结构';
$lang->api->deleteStruct = '删除数据结构';
$lang->api->create = '创建接口';
$lang->api->title = '接口名称';
$lang->api->pageTitle = '接口库';
$lang->api->pageTitle = '库';
$lang->api->module = '目录';
$lang->api->apiDoc = '接口';
$lang->api->manageType = '维护目录';
@@ -55,18 +54,22 @@ $lang->api->done = '开发完成';
$lang->api->basicInfo = '基本信息';
$lang->api->apiDesc = '接口说明';
$lang->api->confirmDelete = "您确定删除该接口吗?";
$lang->api->confirmDeleteLib = "您确定删除该接口库吗?";
$lang->api->confirmDeleteLib = "您确定删除该库吗?";
$lang->api->filterStruct = "使用数据结构填充";
$lang->api->defaultVersion = "当前版本";
$lang->api->zentaoAPI = "禅道API文档v1";
$lang->api->search = "搜索";
$lang->api->allLibs = "全部接口库";
$lang->api->allLibs = "全部库";
$lang->api->noLinked = "无关联";
$lang->api->addCatalog = '添加目录';
$lang->api->editCatalog = '编辑目录';
$lang->api->deleteCatalog = '删除目录';
/* Common access control lang. */
$lang->api->whiteList = '白名单';
$lang->api->aclList['open'] = '公开';
$lang->api->aclList['private'] = '私有';
$lang->api->aclList['custom'] = '自定义';
$lang->api->aclList['open'] = "公开 <span class='acl-tip'>(有文档视图权限即可访问)</span>";
$lang->api->aclList['default'] = "默认 <span class='acl-tip'>(有所选%s访问权限用户可以访问)</span>";
$lang->api->aclList['private'] = "私有 <span class='acl-tip'>(仅创建者和白名单用户可访问)</span>";
$lang->api->group = '分组';
$lang->api->user = '用户';
@@ -87,6 +90,7 @@ $lang->struct->desc = '描述';
$lang->struct->descPlaceholder = '参数说明';
$lang->struct->action = '操作';
$lang->struct->addSubField = '添加子字段';
$lang->struct->list = '数据结构列表';
$lang->struct->typeOptions = array(
'formData' => 'FormData',
@@ -102,15 +106,15 @@ $lang->api->structType = '类型';
$lang->api->structAttr = '属性';
$lang->api->structAddedBy = '创建人';
$lang->api->structAddedDate = '创建时间';
$lang->api->name = '接口库名称';
$lang->api->baseUrl = '请求基路径';
$lang->api->name = '库名称';
$lang->api->baseUrl = '请求基础路径';
$lang->api->baseUrlDesc = '网址或者路径,比如 test.zentao.net 或者 /v1';
$lang->api->desc = '描述';
$lang->api->control = '访问控制';
$lang->api->noLib = '暂时没有接口库。';
$lang->api->noLib = '暂时没有库。';
$lang->api->noApi = '暂时没有接口。';
$lang->api->noStruct = '暂时没有数据结构。';
$lang->api->lib = '所属接口库';
$lang->api->lib = '所属库';
$lang->api->apiList = '接口列表';
$lang->api->formTitle = '接口名称';
$lang->api->path = '请求路径';
@@ -125,11 +129,11 @@ $lang->api->query = '请求参数';
$lang->api->params = '请求体';
$lang->api->response = '请求响应';
$lang->api->responseExample = '响应示例';
$lang->api->id = '接口编号';
$lang->api->addedBy = '由谁添加';
$lang->api->addedDate = '添加时间';
$lang->api->editedBy = '由谁更新';
$lang->api->editedDate = '更新时间';
$lang->api->id = 'ID';
$lang->api->addedBy = '创建者';
$lang->api->addedDate = '创建时间';
$lang->api->editedBy = '修改者';
$lang->api->editedDate = '修改时间';
$lang->api->version = '版本号';
$lang->api->res = new stdClass();
$lang->api->res->name = '名称';
@@ -148,6 +152,10 @@ $lang->api->default = '默认值';
$lang->api->desc = '描述';
$lang->api->customType = '自定义结构';
$lang->api->format = '格式化';
$lang->api->libType = '接口库类型';
$lang->api->product = '所属' . $lang->productCommon;
$lang->api->project = '所属' . $lang->projectCommon;
$lang->api->methodOptions = array(
'GET' => 'GET',
'POST' => 'POST',
@@ -169,6 +177,11 @@ $lang->api->requestTypeOptions['application/json'] = 'applicati
$lang->api->requestTypeOptions['application/x-www-form-urlencoded'] = 'application/x-www-form-urlencoded';
$lang->api->requestTypeOptions['multipart/form-data'] = 'multipart/form-data';
$lang->api->libTypeList = array();
$lang->api->libTypeList['product'] = $lang->productCommon . '接口库';
$lang->api->libTypeList['project'] = $lang->projectCommon . '接口库';
$lang->api->libTypeList['nolink'] = '无关联接口库';
$lang->api->statusOptions = array(
'done' => '开发完成',
'doing' => '开发中',
@@ -210,7 +223,7 @@ $lang->apistruct = new stdClass();
$lang->apistruct->name = '结构名';
$lang->api_lib_release = new stdClass();
$lang->api_lib_release->version = '版本';
$lang->api_lib_release->version = '版本号';
$lang->api->error = new stdclass();
$lang->api->error->onlySelect = 'SQL查询接口只允许SELECT查询';
+125 -48
View File
@@ -168,6 +168,7 @@ class apiModel extends model
$now = helper::now();
$data = fixer::input('post')
->trim('name')
->skipSpecial('attribute')
->add('lib', $old->lib)
->add('editedBy', $this->app->user->account)
@@ -394,12 +395,13 @@ class apiModel extends model
/**
* Get api doc list by module id.
*
* @param int $libID
* @param int $moduleID
* @param int $release
* @param int $libID
* @param int $moduleID
* @param int $release
* @param object $pager
* @return array $list
*/
public function getListByModuleId($libID = 0, $moduleID = 0, $release = 0)
public function getListByModuleId($libID = 0, $moduleID = 0, $release = 0, $pager = null)
{
/* Get release info. */
if($release > 0)
@@ -413,10 +415,7 @@ class apiModel extends model
foreach($rel->snap['modules'] as $module)
{
$tmp = explode(',', $module['path']);
if(in_array($moduleID, $tmp))
{
$sub[] = $module['id'];
}
if(in_array($moduleID, $tmp)) $sub[] = $module['id'];
}
if($sub) $where .= 'and module in (' . implode(',', $sub) . ')';
}
@@ -433,10 +432,9 @@ class apiModel extends model
{
$where = 'lib = ' . $libID;
}
$list = $this->dao->select('*')
->from(TABLE_API)
->where($where)
$list = $this->dao->select('*')->from(TABLE_API)->where($where)
->andWhere('deleted')->eq(0)
->page($pager)
->fetchAll();
}
array_map(function ($item) {
@@ -528,7 +526,7 @@ class apiModel extends model
public function getReleaseByQuery($libID, $pager = '', $orderBy = '')
{
return $this->dao->select('*')->from(TABLE_API_LIB_RELEASE)
->where('lib')->eq($libID)
->where('lib')->in($libID)
->orderBy($orderBy)
->page($pager)
->fetchAll();
@@ -778,11 +776,13 @@ class apiModel extends model
/* Insert doclib. */
$lib = new stdclass();
$lib->type = 'api';
$lib->name = $name;
$lib->baseUrl = $baseUrl;
$lib->acl = 'open';
$lib->users = ',' . $currentAccount . ',';
$lib->type = 'api';
$lib->name = $name;
$lib->baseUrl = $baseUrl;
$lib->acl = 'open';
$lib->users = ',' . $currentAccount . ',';
$lib->addedBy = $currentAccount;
$lib->addedDate = helper::now();
$this->dao->insert(TABLE_DOCLIB)->data($lib)->autoCheck()
->batchCheck($this->config->api->createlib->requiredFields, 'notempty')
->check('name', 'unique', "`type` = 'api'")
@@ -887,10 +887,10 @@ class apiModel extends model
*
* @param string $table
* @param stirng $version
* @access private
* @access public
* @return array
*/
private function getDemoData($table, $version)
public function getDemoData($table, $version)
{
$file = $this->app->getAppRoot() . 'db' . DS . 'api' . DS . $version . DS . $table;
return unserialize(preg_replace_callback('#s:(\d+):"(.*?)";#s', function($match){return 's:'.strlen($match[2]).':"'.$match[2].'";';}, file_get_contents($file)));
@@ -902,15 +902,30 @@ class apiModel extends model
* @param object $lib
* @param string $queryID
* @param string $actionURL
* @param array $libs
* @param string $type product|project
* @access public
* @return void
*/
public function buildSearchForm($lib, $queryID, $actionURL)
public function buildSearchForm($lib, $queryID, $actionURL, $libs = array(), $type = '')
{
$this->config->api->search['module'] = 'api';
if(empty($lib)) return;
$libPairs = array('' => '', $lib->id => $lib->name);
$this->config->api->search['module'] = 'api';
if(!empty($libs))
{
foreach($libs as $lib)
{
if(empty($lib)) continue;
if($lib->type != 'api') continue;
$libPairs[$lib->id] = $lib->name;
}
$this->config->api->search['module'] = !empty($type) ? $type . 'apiDoc' : 'api';
}
$this->config->api->search['queryID'] = $queryID;
$this->config->api->search['actionURL'] = $actionURL;
$this->config->api->search['params']['lib']['values'] = (!empty($lib)) ? array($lib->id => $lib->name) + array('all' => $this->lang->api->allLibs) : array('all' => $this->lang->api->allLibs);
$this->config->api->search['params']['lib']['values'] = $libPairs + array('all' => $this->lang->api->allLibs);
$this->loadModel('search')->setSearchParams($this->config->api->search);
}
@@ -920,38 +935,100 @@ class apiModel extends model
*
* @param string $libID
* @param int $queryID
* @param string $objectType product|project
* @param array $libs
* @access public
* @return array
*/
public function getApiListBySearch($libID, $queryID)
public function getApiListBySearch($libID, $queryID, $objectType = '', $libs = array())
{
if($queryID)
{
$query = $this->loadModel('search')->getQuery($queryID);
if($query)
{
$this->session->set('apiQuery', $query->sql);
$this->session->set('apiForm', $query->form);
}
else
{
$this->session->set('apiQuery', ' 1 = 1');
}
}
else
{
if($this->session->apiQuery == false) $this->session->set('apiQuery', ' 1 = 1');
}
$queryName = $objectType ? $objectType . 'apiDocQuery' : 'apiQuery';
$queryForm = $objectType ? $objectType . 'apiDocForm' : 'apiForm';
if($queryID)
{
$query = $this->loadModel('search')->getQuery($queryID);
if($query)
{
$this->session->set($queryName, $query->sql);
$this->session->set($queryForm, $query->form);
}
else
{
$this->session->set($queryName, ' 1 = 1');
}
}
else
{
if($this->session->$queryName == false) $this->session->set($queryName, ' 1 = 1');
}
$apiQuery = $this->session->apiQuery;
$apiQuery = strpos($apiQuery, "`lib` = 'all'") === false ? "$apiQuery and lib = $libID" : str_replace("`lib` = 'all'", '1', $apiQuery);
$apiQuery = $this->session->$queryName;
if(strpos($apiQuery, "`lib` = 'all'") !== false) $apiQuery = str_replace("`lib` = 'all'", '1', $apiQuery);
$list = $this->dao->select('*')
->from(TABLE_API)
->where('deleted')->eq(0)
->andWhere($apiQuery)
->fetchAll();
$list = $this->dao->select('*')
->from(TABLE_API)
->where('deleted')->eq(0)
->andWhere($apiQuery)
->beginIF(!empty($libs))->andWhere('`lib`')->in($libs)->fi()
->fetchAll();
return $list;
return $list;
}
/**
* Get ordered objects for dic.
*
* @access public
* @return array
*/
public function getOrderedObjects()
{
$normalObjects = $closedObjects = array();
$libs = $this->loadModel('doc')->getApiLibs();
$products = $this->dao->select('t1.id, t1.name, t1.status')->from(TABLE_PRODUCT)->alias('t1')
->leftjoin(TABLE_DOCLIB)->alias('t2')->on('t2.product=t1.id')
->where('t2.id')->gt(0)
->andWhere('t1.vision')->eq($this->config->vision)
->andWhere('t1.deleted')->eq(0)
->andWhere('t2.id')->in(array_keys($libs))
->orderBy('id_desc')
->fetchAll('id');
foreach($products as $id => $product)
{
if($product->status == 'normal')
{
$normalObjects['product'][$id] = $product->name;
}
elseif($product->status == 'closed')
{
$closedObjects['product'][$id] = $product->name;
}
}
$projects = $this->dao->select('t1.id, t1.name, t1.status')->from(TABLE_PROJECT)->alias('t1')
->leftjoin(TABLE_DOCLIB)->alias('t2')->on('t2.project=t1.id')
->where('t2.id')->gt(0)
->andWhere('t1.vision')->eq($this->config->vision)
->andWhere('t1.deleted')->eq(0)
->beginIF(!$this->app->user->admin)->andWhere('t1.id')->in($this->app->user->view->projects)->fi()
->andWhere('t2.id')->in(array_keys($libs))
->orderBy('t1.hasProduct_asc, id_desc')
->fetchAll('id');
foreach($projects as $id => $project)
{
if($project->status != 'done' and $project->status != 'closed')
{
$normalObjects['project'][$id] = $project->name;
}
else if($project->status == 'done' or $project->status == 'closed')
{
$closedObjects['project'][$id] = $project->name;
}
}
return array($normalObjects, $closedObjects);
}
}
+157
View File
@@ -0,0 +1,157 @@
<style>
#tabContent {margin-top: 5px; max-width: 220px}
.objectTree ul {list-style: none; margin: 0}
.objectTree .objects>ul>li>div {display: flex; flex-flow: row nowrap; justify-content: flex-start; align-items: center;}
.objectTree li>a, div.hide-in-search>a {display: block; padding: 2px 10px 2px 5px; overflow: hidden; line-height: 20px; text-overflow: ellipsis; white-space: nowrap; border-radius: 4px;}
.objectTree .tree li>.list-toggle {line-height: 24px;}
.objectTree .tree li.has-list.open:before {content: unset;}
#swapper li>div.hide-in-search>a:focus, #swapper li>div.hide-in-search>a:hover {color: #838a9d; cursor: default;}
#swapper li > a {margin-top: 4px; margin-bottom: 4px;}
#swapper li {padding-top: 0; padding-bottom: 0;}
#swapper .tree li>.list-toggle {top: -1px;}
#closed {width: 90px; height: 25px; line-height: 25px; background-color: #ddd; color: #3c495c; text-align: center; margin-left: 15px; border-radius: 2px;}
#gray-line {width: 230px;height: 1px; margin-left: 10px; margin-bottom:2px; background-color: #ddd;}
#dropMenu.has-search-text .hide-in-search {display: flex;}
#swapper li>.selected {color: #0c64eb!important; background: #e9f2fb!important;}
.tree-product:last-child {border-bottom: 1px solid #eee;}
</style>
<?php
$normalObjectsHtml = '<ul class="tree noProgram">';
$closedObjectsHtml = '<ul class="tree noProgram">';
$link = $this->createLink('api', 'index');
$selected = $objectType == 'nolink' ? 'selected' : '';
$dataParams = 'data-type="nolink" data-id="0"';
if(!empty($nolinkLibs)) $normalObjectsHtml .= "<li>" . html::a($link, $lang->api->noLinked, '', "class='clickable $selected' title='{$lang->api->noLinked}' $dataParams data-key='" . zget($objectsPinYin, $lang->api->noLinked, '') . "'") . '</li>';
foreach(array('product', 'project') as $moduleType)
{
if(!empty($normalObjects[$moduleType]))
{
foreach($normalObjects[$moduleType] as $normalObjectID => $normalObjectName)
{
$dataParams = "data-type='$moduleType' data-id='$normalObjectID'";
$selected = $normalObjectID == $objectID ? 'selected' : '';
$normalObjectsHtml .= "<li>" . html::a($link, "<i class='icon icon-$moduleType'></i> $normalObjectName", '', "class='$selected clickable' title='{$normalObjectName}' $dataParams data-key='" . zget($objectsPinYin, $normalObjectName, '') . "'") . '</li>';
}
}
if(!empty($closedObjects[$moduleType]))
{
foreach($closedObjects[$moduleType] as $closedObjectID => $closedObjectName)
{
$dataParams = "data-type='$moduleType' data-id='$closedObjectID'";
$selected = $closedObjectID == $objectID ? 'selected' : '';
$closedObjectsHtml .= '<li>' . html::a($link, "<i class='icon icon-$moduleType'></i> $closedObjectName", '', "class='$selected clickable' title='{$closedObjectName}' $dataParams data-key='" . zget($objectsPinYin, $closedObjectName, '') . "'") . '</li>';
}
}
if($moduleType == 'product')
{
if(!empty($normalObjects['project']) and (!empty($nolinkLibs) or !empty($normalObjects['product']))) $normalObjectsHtml .= '<li class="divider"></li>';
if(!empty($closedObjects['project']) and !empty($normalObjects['product'])) $closedObjectsHtml .= '<li class="divider"></li>';
}
}
$normalObjectsHtml .= '</ul>';
$closedObjectsHtml .= '</ul>';
?>
<div class="table-row">
<div class="table-col <?php if(!empty($closedObjects['product']) or !empty($closedObjects['project'])) echo 'col-left'?>">
<div class='list-group'>
<div class="tab-content objectTree" id="tabContent">
<div class="tab-pane objects active">
<?php echo $normalObjectsHtml;?>
</div>
</div>
</div>
<?php if(!empty($closedObjects['product']) or !empty($closedObjects['project'])):?>
<div class="col-footer">
<a class='pull-right toggle-right-col not-list-item'><?php echo $lang->doc->closed?><i class='icon icon-angle-right'></i></a>
</div>
<?php endif;?>
</div>
<div id="gray-line" hidden></div>
<div id="closed" hidden><?php echo $lang->doc->closed?></div>
<div class="table-col col-right objectTree">
<div class='list-group objects'><?php echo $closedObjectsHtml;?></div>
</div>
</div>
<script>
$(function()
{
$('#swapper [data-ride="tree"]').tree('expand');
<?php if(isset($closedObjects[$objectID])):?>
$('.col-footer .toggle-right-col').click(function(){ scrollToSelected(); })
<?php else:?>
scrollToSelected();
<?php endif;?>
$('.nav-tabs li span').hide();
$('.nav-tabs li.active').find('span').show();
$('.nav-tabs>li a').click(function()
{
if($('#swapper input[type="search"]').val() == '')
{
$(this).siblings().show();
$(this).parent().siblings('li').find('span').hide();
}
})
$('#swapper #dropMenu .search-box').on('onSearchChange', function(event, value)
{
if(value != '')
{
$('div.hide-in-search').siblings('i').addClass('hide-in-search');
$('.nav-tabs li span').hide();
}
else
{
$('div.hide-in-search').siblings('i').removeClass('hide-in-search');
$('li.has-list div.hide-in-search').removeClass('hidden');
$('.nav-tabs li.active').find('span').show();
}
if($('.form-control.search-input').val().length > 0)
{
$('#closed').attr("hidden", false);
$('#gray-line').attr("hidden", false);
}
else
{
$('#closed').attr("hidden", true);
$('#gray-line').attr("hidden", true);
}
});
$('#swapper #dropMenu').on('onSearchComplete', function()
{
var listItem = $(this).find('.has-list');
listItem.each(function()
{
$(this).css('display','')
var $hidden = $(this).find('.hidden');
var $item = $(this).find('.search-list-item');
if($hidden.length == $item.length) $(this).css('display','none');
});
if($('.list-group.objects').height() == 0)
{
$('#closed').attr("hidden", true);
$('#gray-line').attr("hidden", true);
}
});
$('.objectTree a').on('click', function()
{
var objectType = $(this).data('type');
var objectID = $(this).data('id');
$.cookie('objectType', objectType, {expires: config.cookieLife, path: config.webRoot});
$.cookie('objectID', objectID, {expires: config.cookieLife, path: config.webRoot});
});
})
</script>
+130
View File
@@ -0,0 +1,130 @@
<style>
.base-url > p {margin: 0;}
.table-empty-tip > div {display: inline-block;}
.detail .list-group-item .heading.GET {
background-color: #e7f0f7;
}
.detail .list-group-item .heading.GET a {
color: #0f6ab4;
}
.detail .list-group {
height: calc(100vh - 215px);
overflow-y: auto;
}
.detail .list-group-item .heading.OPTIONS {
background-color: #e7f0f7;
}
.detail .list-group-item .heading.OPTIONS a {
color: #0f6ab4;
}
.detail .list-group-item .heading.POST {
background-color: #e7f6ec;
}
.detail .list-group-item .heading.POST a {
color: #10a54a;
}
.detail .list-group-item .heading.PUT {
background-color: #f9f2e9;
}
.detail .list-group-item .heading.PUT a {
color: #c5862b;
}
.detail .list-group-item .heading.PATCH {
background-color: #f9f2e9;
}
.detail .list-group-item .heading.PATCH a {
color: #c5862b;
}
.detail .list-group-item .heading.DELETE {
background-color: #f5e8e8;
border: 1px solid #e8c6c7;
}
.detail .list-group-item .heading.DELETE a {
color: #a41e22;
}
.detail .list-group-item a {
display: flex;
align-items: center;
}
.detail .list-group-item .path, .detail .list-group-item .desc {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.detail .list-group-item .path {
padding-left: 10px;
font-size: 14px;
color: black;
flex: 1;
}
.detail .list-group-item .desc {
width: auto;
font-size: 14px;
line-height: 38px;
float: right;
padding-right: 10px;
max-width: 200px;
}
.detail .list-group-item {list-style: none; font-size: 14px; margin-bottom: 10px; line-height: 30px}
.detail .list-group-item span {line-height: 30px; width: 65px;}
.detail .list-group-item .label+.label {margin-left: -4px;}
.detail .list-group-item .label {border-radius: 0;}
</style>
<?php if($apiID):?>
<?php include './content.html.php';?>
<?php else:?>
<?php if(empty($libs) || empty($apiList)):?>
<div class="cell apiList">
<div class="detail">
<li class="detail-title"><?php echo intval($libID) > 0 ? $lang->api->apiList : $lang->api->pageTitle;?></li>
</div>
<div class="table-empty-tip">
<div class="notice text-muted"><?php echo (empty($libs)) ? $lang->api->noLib : $lang->api->noApi;?></div>
<div class="no-content-button">
<?php
if($libID && common::hasPriv('api', 'create'))
{
if($app->rawModule == 'doc')
{
echo html::a($this->createLink('api', 'create', "libID=$libID&moduleID=$moduleID", '', true), '<i class="icon icon-plus"></i> ' . $lang->api->createApi, '', 'class="btn btn-info iframe" data-width="95%"');
}
else
{
echo html::a(helper::createLink('api', 'create', "libID={$libID}&moduleID=$moduleID"), '<i class="icon icon-plus"></i> ' . $lang->api->createApi, '', 'class="btn btn-info"');
}
}
?>
</div>
</div>
</div>
<?php else:?>
<div class="cell main-col" data-min-width="400">
<div class="detail base-url">
<?php $delimiter = strpos($app->clientLang, 'zh') === 0 ? ':' : ': ';?>
<p><?php echo $lang->api->baseUrl . $delimiter . $lib->baseUrl;?></p>
</div>
<div class="detail">
<ul class="list-group">
<?php foreach($apiList as $api):?>
<li class="list-group-item">
<div class="heading <?php echo $api->method;?>">
<a href="<?php echo helper::createLink('api', 'index', "libID={$api->lib}&moduleID=0&apiID={$api->id}&version=0&release=$release");?>" data-app="<?php echo $app->tab;?>">
<span class="label label-primary"><?php echo $api->method;?></span>
<span class="path" title="<?php echo $api->path;?>"><?php echo $api->path;?></span>
<span class="desc" title="<?php echo $api->title;?>"><?php echo $api->title;?></span>
</a>
</div>
</li>
<?php endforeach;?>
</ul>
</div>
</div>
<?php endif;?>
<?php endif;?>
+4 -7
View File
@@ -22,18 +22,15 @@
</div>
</div>
<div class="actions">
<?php echo html::a("javascript:fullScreen()", '<span class="icon-fullscreen"></span>', '', "title='{$lang->fullscreen}' class='btn btn-link fullscreen-btn'");?>
<?php
echo html::a("javascript:fullScreen()", '<i class="icon-fullscreen"></i>', '', "title='{$lang->fullscreen}' class='btn btn-link fullscreen-btn'");
if(!$isRelease)
{
if(common::hasPriv('api', 'edit')) echo html::a(inlink('edit', "apiID=$api->id"), '<i class="icon-edit"></i>', '', "title='{$lang->api->edit}' class='btn btn-link' data-app='{$this->app->tab}'");
if(common::hasPriv('api', 'delete'))
{
$deleteURL = $this->createLink('api', 'delete', "apiID=$api->id&confirm=yes");
echo html::a("javascript:ajaxDeleteApi(\"$deleteURL\", confirmDelete)", '<i class="icon-trash"></i>', '', "title='{$lang->api->delete}' class='btn btn-link'");
}
if(common::hasPriv('api', 'edit')) echo html::a(inlink('edit', "apiID=$api->id"), '<i class="icon-edit"></i>', '', "title='{$lang->api->edit}' class='btn btn-link' data-app='{$this->app->tab}'");
if(common::hasPriv('api', 'delete')) echo html::a(inLink('api', 'delete', "apiID=$api->id"), '<i class="icon-trash"></i>', '', "title='{$lang->api->delete}' class='btn btn-link' target='hiddenwin'");
}
?>
<a id="hisTrigger" href="###" class="btn btn-link" title=<?php echo $lang->history?>><span class="icon icon-clock"></span></a>
</div>
</div>
</div>
+11 -18
View File
@@ -38,12 +38,10 @@ js::set('struct_paramsType', $lang->struct->paramsType);
</div>
<div class='modal-body'>
<table class='table table-form'>
<tbody>
<tr>
<td><?php echo html::select('filter', $allStruct, '', "class='form-control chosen filterSelect'");?></td>
<td></td>
</tr>
</tbody>
<tr>
<td><?php echo html::select('filter', $allStruct, '', "class='form-control chosen filterSelect'");?></td>
<td></td>
</tr>
</table>
</div>
<div class="modal-footer">
@@ -62,7 +60,9 @@ js::set('struct_paramsType', $lang->struct->paramsType);
<tbody>
<tr>
<th class='w-110px'><?php echo $lang->api->lib;?></th>
<td> <?php echo html::select('lib', $libs, $libID, "class='form-control chosen' onchange=loadDocModule(this.value)");?> </td>
<td>
<?php echo $libName . html::hidden('lib', $libID);?>
</td>
<td></td>
</tr>
<tr>
@@ -103,9 +103,7 @@ js::set('struct_paramsType', $lang->struct->paramsType);
<td><?php echo html::radio('status', $lang->api->statusOptions, apiModel::STATUS_DONE);?></td>
</tr>
<tr>
<th>
<nobr><?php echo $lang->api->owner;?></nobr>
</th>
<th><?php echo $lang->api->owner;?></th>
<td>
<div class='input-group'>
<?php echo html::select('owner', $allUsers, $user, "class='form-control chosen'");?>
@@ -188,9 +186,7 @@ js::set('struct_paramsType', $lang->struct->paramsType);
</td>
</tr>
<tr>
<th>
<nobr><?php echo $lang->api->paramsExample;?></nobr>
</th>
<th><?php echo $lang->api->paramsExample;?></th>
<td>
<div class='input-group'>
<?php echo html::textarea('paramsExample', '', "style='width:100%;height:200px'");?>
@@ -205,9 +201,7 @@ js::set('struct_paramsType', $lang->struct->paramsType);
</td>
</tr>
<tr>
<th>
<nobr><?php echo $lang->api->responseExample;?></nobr>
</th>
<th><?php echo $lang->api->responseExample;?></th>
<td>
<div class='input-group'>
<?php echo html::textarea('responseExample', '', "style='width:100%;height:200px'");?>
@@ -223,8 +217,7 @@ js::set('struct_paramsType', $lang->struct->paramsType);
<tr>
<td colspan='3' class='text-center form-actions'>
<?php echo html::submitButton();?>
<?php if(empty($gobackLink)) echo html::backButton($lang->goback, "data-app='{$app->tab}'");?>
<?php if(!empty($gobackLink)) echo html::a($gobackLink, $lang->goback, '', "class='btn btn-back btn-wide'");?>
<?php echo html::backButton($lang->goback, "data-app='{$app->tab}' class='btn btn-back btn-wide'");?>
</td>
</tr>
</tbody>
+27 -14
View File
@@ -18,24 +18,40 @@
<div id='mainContent' class='main-content'>
<div class='center-block'>
<div class='main-header'>
<h2><?php echo $type == 'normal' ? $lang->api->createLib : $lang->api->createDemo;?></h2>
<h2><?php echo $lang->api->createLib;?></h2>
</div>
<form class='load-indicator main-form' id="apiForm" method='post' enctype='multipart/form-data'>
<table class='table table-form'>
<tr>
<th><?php echo $lang->api->libType;?></th>
<td>
<span><?php echo html::radio('libType', $lang->api->libTypeList, $type, "onchange='toggleLibType(this.value)'")?></span>
</td>
</tr>
<tr id='productBox' class="<?php if($type != 'product') echo 'hidden';?>">
<th><?php echo $lang->api->product;?></th>
<td class='required'>
<span><?php echo html::select('product', $products, $objectID, "class='form-control chosen'")?></span>
</td>
</tr>
<tr id='projectBox' class="<?php if($type != 'project') echo 'hidden';?>">
<th><?php echo $lang->api->project;?></th>
<td class='required'>
<span><?php echo html::select('project', $projects, $objectID, "class='form-control chosen'")?></span>
</td>
</tr>
<tr>
<th><?php echo $lang->api->name?></th>
<td style="width: 80%"><?php echo html::input('name', $type == 'demo' ? $lang->api->zentaoAPI : '', "class='form-control'")?></td>
<td style="width: 80%"><?php echo html::input('name', '', "class='form-control'")?></td>
</tr>
<tr>
<th><?php echo $lang->api->baseUrl?></th>
<td style="width: 80%"><?php echo html::input('baseUrl', $type == 'demo' ? ('http://' . $_SERVER['HTTP_HOST'] . $this->app->config->webRoot . 'api.php/v1') : '', "class='form-control' placeholder='" . $lang->api->baseUrlDesc . "'");?></td>
<td style="width: 80%"><?php echo html::input('baseUrl', '', "class='form-control' placeholder='" . $lang->api->baseUrlDesc . "'");?></td>
</tr>
<tr>
<tr id='aclBox'>
<th><?php echo $lang->api->control;?></th>
<td>
<?php $isDisabled = $type == 'demo' ? 'disabled' : '';?>
<span><?php echo html::radio('acl', $lang->api->aclList, 'open', "onchange='toggleAcl(this.value, \"lib\")' $isDisabled")?></span>
<span class='text-info' id='noticeAcl'><?php echo $lang->api->noticeAcl['open'];?></span>
<span><?php echo html::radio('acl', $lang->api->aclList, 'open', "onchange='toggleAcl(this.value, \"lib\")'", 'block');?></span>
</td>
</tr>
<tr id='whiteListBox' class='hidden'>
@@ -48,15 +64,10 @@
<div class='input-group'>
<span class='input-group-addon'><?php echo $lang->api->user?></span>
<?php echo html::select('users[]', $users, '', "class='form-control chosen' multiple")?>
<?php echo $this->fetch('my', 'buildContactLists', "dropdownName=users&attr=data-drop_direction='up'");?>
</div>
</td>
</tr>
<tr>
<th><?php echo $lang->api->desc;?></th>
<td colspan='2'>
<?php echo html::textarea('desc', '', "rows='8' class='form-control kindeditor' hidefocus='true' tabindex=''");?>
</td>
</tr>
<tr>
<td class='text-center form-actions' colspan='2'><?php echo html::submitButton();?></td>
</tr>
@@ -66,5 +77,7 @@
</div>
</div>
</div>
<?php js::set('noticeAcl', $lang->api->noticeAcl);?>
<?php js::set('productLang', $lang->productCommon);?>
<?php js::set('projectLang', $lang->projectCommon);?>
<?php js::set('libType', $type);?>
<?php include '../../common/view/footer.lite.html.php';?>
+20 -36
View File
@@ -1,12 +1,12 @@
<?php
/**
* The createlib view of doc module of ZenTaoPMS.
* The createlib view of api module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Jia Fu <fujia@cnezsoft.com>
* @package doc
* @version $Id: createlib.html.php 975 2010-07-29 03:30:25Z jajacn@126.com $
* @package api
* @version $Id: editlib.html.php 975 2010-07-29 03:30:25Z jajacn@126.com $
* @link http://www.zentao.net
*/
?>
@@ -22,42 +22,42 @@
</div>
<form class='load-indicator main-form form-ajax' id="apiForm" method='post' enctype='multipart/form-data'>
<table class='table table-form'>
<?php if(in_array($type, array('product', 'project'))):?>
<tr>
<th class='w-130px'><?php echo $lang->api->{$type};?></th>
<td><?php echo $object->name?></td>
</tr>
<?php endif;?>
<tr>
<th><?php echo $lang->api->name?></th>
<td style="width: 80%"><?php echo html::input('name', $doc->name, "class='form-control'");?></td>
<td style="width: 80%"><?php echo html::input('name', $lib->name, "class='form-control'");?></td>
</tr>
<tr>
<th><?php echo $lang->api->baseUrl?></th>
<td style="width: 80%"><?php echo html::input('baseUrl', $doc->baseUrl, "class='form-control'");?></td>
<td style="width: 80%"><?php echo html::input('baseUrl', $lib->baseUrl, "class='form-control'");?></td>
</tr>
<tr>
<tr id='aclBox'>
<th><?php echo $lang->api->control;?></th>
<td>
<span><?php echo html::radio('acl', $lang->api->aclList, $doc->acl, "onchange='toggleAcl(this.value, \"lib\")'")?></span>
<span class='text-info' id='noticeAcl'><?php echo $lang->api->noticeAcl['open'];?></span>
<span><?php echo html::radio('acl', $lang->api->aclList, $lib->acl, "onchange='toggleAcl(this.value, \"lib\")'", 'block')?></span>
</td>
</tr>
<tr id='whiteListBox' class='<?php echo $doc->acl == 'custom' ? '' : 'hidden';?>'>
<tr id='whiteListBox' class='<?php echo $lib->acl == 'private' ? '' : 'hidden';?>'>
<th><?php echo $lang->api->whiteList;?></th>
<td>
<div class='input-group'>
<span class='input-group-addon groups-addon'><?php echo $lang->api->group?></span>
<?php echo html::select('groups[]', $groups, $doc->groups, "class='form-control chosen' multiple");?>
<?php echo html::select('groups[]', $groups, $lib->groups, "class='form-control chosen' multiple");?>
</div>
<div class='input-group'>
<span class='input-group-addon'><?php echo $lang->api->user?></span>
<?php echo html::select('users[]', $users, $doc->users, "class='form-control chosen' multiple");?>
<?php echo html::select('users[]', $users, $lib->users, "class='form-control chosen' multiple");?>
<?php echo $this->fetch('my', 'buildContactLists', "dropdownName=users&attr=data-drop_direction='up'");?>
</div>
</td>
</tr>
<tr>
<th><?php echo $lang->api->desc;?></th>
<td colspan='2'>
<?php echo html::textarea('desc', $doc->desc, "rows='8' class='form-control kindeditor' hidefocus='true' tabindex=''");?>
</td>
</tr>
<tr>
<td class='text-center form-actions' colspan='2'><?php echo html::submitButton();?></td>
<td class='text-center form-actions' colspan='2'><?php echo html::hidden('type', $type) . html::submitButton();?></td>
</tr>
</table>
</form>
@@ -65,22 +65,6 @@
</div>
</div>
</div>
<div class='hidden'>
<table>
<tr id='aclBoxA'>
<th><?php echo $lang->api->control;?></th>
<td>
<?php echo html::radio('acl', $lang->api->aclListA, 'default', "onchange='toggleAcl(this.value, \"lib\")'");?>
</td>
</tr>
<tr id='aclBoxB'>
<th><?php echo $lang->api->control;?></th>
<td><?php echo html::radio('acl', $lang->api->aclListB, 'open', "onchange='toggleAcl(this.value, \"lib\")'");?></td>
</tr>
</table>
</div>
<?php js::set('noticeAcl', $lang->api->noticeAcl);?>
<script>
$(function(){toggleAcl($('form input[name="acl"]:checked').val(), 'lib');})
</script>
<?php js::set('productLang', $lang->productCommon);?>
<?php js::set('projectLang', $lang->projectCommon);?>
<?php include '../../common/view/footer.lite.html.php';?>
+72 -81
View File
@@ -12,89 +12,80 @@
?>
<?php include '../../common/view/header.html.php';?>
<?php js::set('confirmDelete', $lang->api->confirmDelete);?>
<div class="cell<?php if($browseType == 'bySearch') echo ' show';?>" id="queryBox" data-module=<?php echo 'api';?>></div>
<div class="fade main-row split-row" id="mainRow">
<?php if($libID):?>
<?php $sideWidth = common::checkNotCN() ? '270' : '238';?>
<div class="side-col" style="width:<?php echo $sideWidth;?>px" data-min-width="<?php echo $sideWidth;?>">
<div class="cell" style="min-height: 286px">
<div id='title'>
<li class='menu-title'><?php echo $this->lang->api->module;?></li>
<?php
$canTreeBrowse = common::hasPriv('tree', 'browse');
$canViewReleases = common::hasPriv('api', 'releases');
$canEditLib = common::hasPriv('api', 'editLib');
$canDeleteLib = common::hasPriv('api', 'deleteLib');
$haveMoreButton = ($canTreeBrowse or $canViewReleases or $canEditLib or $canDeleteLib);
if(!$isRelease and $haveMoreButton)
{
echo "<div class='menu-actions'>";
echo html::a('javascript:;', "<i class='icon icon-ellipsis-v'></i>", '', "data-toggle='dropdown' class='btn btn-link'");
echo "<ul class='dropdown-menu pull-right'>";
if($canTreeBrowse) echo '<li>' . html::a($this->createLink('tree', 'browse', "rootID=$libID&view=api", '', true), '<i class="icon-cog-outline"></i> ' . $this->lang->api->manageType, '', "class='iframe' data-width='1200px'") . '</li>';
if($canViewReleases) echo '<li>' . html::a($this->createLink('api', 'releases', "libID=$libID", '', true), '<i class="icon-version"></i> ' . $this->lang->api->managePublish, '', "class='iframe'") . '</li>';
echo "<li class='divider'></li>";
if($canEditLib) echo '<li>' . html::a($this->createLink('api', 'editLib', "rootID=$libID"), '<i class="icon-edit"></i> ' . $lang->api->editLib, '', "class='iframe'") . '</li>';
if($canDeleteLib) echo '<li>' . html::a($this->createLink('api', 'deleteLib', "rootID=$libID"), '<i class="icon-trash"></i> ' . $lang->api->deleteLib, 'hiddenwin') . '</li>';
echo '</ul></div>';
}
?>
</div>
<?php if(!$moduleTree):?>
<hr class="space">
<?php if(!$isRelease):?>
<div class="text-center text-muted tips"><?php echo $lang->api->noModule;?></div>
<?php endif;?>
<?php endif;?>
<?php echo $moduleTree;?>
</div>
<?php js::set('treeData', $libTree);?>
<div id="mainMenu" class="clearfix">
<div id="leftBar" class="btn-toolbar pull-left">
<?php echo $objectDropdown;?>
<?php if(!empty($libTree)):?>
<a class="btn btn-link querybox-toggle" id='bysearchTab'><i class="icon icon-search muted"></i> <?php echo $lang->doc->searchDoc;?></a>
<?php endif;?>
</div>
<?php endif;?>
<?php if($apiID):?>
<?php include './content.html.php';?>
<?php else:?>
<?php if(empty($libs) || empty($apiList)):?>
<div class="cell">
<div class="detail">
<li class="detail-title"><?php echo intval($libID) > 0 ? $lang->api->apiList : $lang->api->pageTitle;?></li>
</div>
<div class="detail">
<div class="no-content"><img src="<?php echo $config->webRoot . 'theme/default/images/main/no_content.png'?>"/></div>
<div class="notice text-muted"><?php echo (empty($libs)) ? $lang->api->noLib : $lang->api->noApi;?></div>
<div class="no-content-button">
<?php
if($libID && common::hasPriv('api', 'create'))
{
echo html::a(helper::createLink('api', 'create', "libID={$libID}"), '<i class="icon icon-plus"></i> ' . $lang->api->createApi, '', 'class="btn btn-info btn-wide"');
}
?>
</div>
</div>
<div class="btn-toolbar pull-right">
<?php
if($libTree and common::hasPriv('api', 'struct')) echo html::a($this->createLink('api', 'struct', "libID=$libID"), "<i class='icon-treemap muted'> </i>" . $lang->api->struct, '', "class='btn btn-link'");
if($libTree and common::hasPriv('api', 'releases')) echo html::a($this->createLink('api', 'releases', "libID=$libID", 'html', true), "<i class='icon-version muted'> </i>" . $lang->api->releases, '', "class='btn btn-link iframe' data-width='800px'");
if($libTree and common::hasPriv('api', 'createRelease')) echo html::a($this->createLink('api', 'createRelease', "libID=$libID"), "<i class='icon-publish muted'> </i>" . $lang->api->createRelease, '', "class='btn btn-link iframe' data-width='800px'");
if($libTree and common::hasPriv('api', 'export') and $config->edition != 'open') echo html::a($this->createLink('api', 'export', "libID=$libID&version=$version&release=$release", 'html', true), "<i class='icon-export muted'> </i>" . $lang->export, '', "class='btn btn-link export' data-width='480px' id='export'");
if(common::hasPriv('api', 'createLib')) echo html::a($this->createLink('api', 'createLib', "type=" . ($objectType ? $objectType : 'nolink') . "&objectID=$objectID"), '<i class="icon icon-plus"></i> ' . $lang->api->createLib, '', 'class="btn btn-secondary iframe" data-width="800px"');
if($libTree and common::hasPriv('api', 'create')) echo html::a($this->createLink('api', 'create', "libID=$libID&moduleID=$moduleID"), '<i class="icon icon-plus"></i> ' . $lang->api->createApi, '', 'class="btn btn-primary"');
?>
</div>
<?php else:?>
<div class="cell main-col" data-min-width="400">
<div class="detail base-url">
<p><?php echo $lang->api->baseUrl . ': ' . $lib->baseUrl;?></p>
</div>
<div class="detail">
<ul class="list-group">
<?php foreach($apiList as $api):?>
<li class="list-group-item">
<div class="heading <?php echo $api->method;?>">
<a href="<?php echo helper::createLink('api', 'index', "libID={$api->lib}&moduleID=0&apiID={$api->id}&version=0&release=$release");?>">
<span class="label label-primary"><?php echo $api->method;?></span>
<span class="path" title="<?php echo $api->path;?>"><?php echo $api->path;?></span>
<span class="desc" title="<?php echo $api->title;?>"><?php echo $api->title;?></span>
</a>
</div>
</li>
<?php endforeach;?>
</ul>
</div>
</div>
<div id='mainContent' class="fade <?php if(!empty($libTree)) echo 'flex';?>">
<?php if(empty($libTree)):?>
<div class="table-empty-tip">
<p>
<span class="text-muted"><?php echo $lang->doc->noLib;?></span>
<?php
if(common::hasPriv('api', 'createLib')) echo html::a(helper::createLink('api', 'createLib', "type=" . ($objectType ? $objectType : 'nolink')), '<i class="icon icon-plus"></i> ' . $lang->api->createLib, '', 'class="btn btn-info iframe" data-width="800px"');
?>
</p>
</div>
<?php endif;?>
<?php endif;?>
<?php else:?>
<div id='sideBar' class="panel side side-col col overflow-auto" data-min-width="150">
<?php include '../../doc/view/lefttree.html.php';?>
</div>
<div class="sidebar-toggle flex-center"><i class="icon icon-angle-left"></i></div>
<div class="main-col flex-full overflow-visible flex-auto overflow-visible" data-min-width="500">
<div class="cell<?php if($browseType == 'bySearch') echo ' show';?>" style="min-width: 400px" id="queryBox" data-module='api'></div>
<?php include 'apilist.html.php';?>
</div>
<?php endif;?>
</div>
<div class='hidden' id='dropDownData'>
<ul class='libDorpdown'>
<?php if(common::hasPriv('tree', 'browse')):?>
<li data-method="addCataLib" data-has-children='%hasChildren%' data-libid='%libID%' data-moduleid="%moduleID%" data-type="add"><a><i class="icon icon-icon-add-directory"></i><?php echo $lang->doc->libDropdown['addModule'];?></a></li>
<?php endif;?>
<?php if(common::hasPriv('api', 'editLib')):?>
<li data-method="editLib"><a href='<?php echo inlink('editLib', 'libID=%libID%');?>' data-toggle='modal' data-type='iframe'><i class="icon icon-edit"></i><?php echo $lang->doc->libDropdown['editLib'];?></a></li>
<?php endif;?>
<?php if(common::hasPriv('api', 'deleteLib')):?>
<li data-method="deleteLib"><a href='<?php echo inlink('deleteLib', 'libID=%libID%');?>' target='hiddenwin'><i class="icon icon-trash"></i><?php echo $lang->doc->libDropdown['deleteLib'];?></a></li>
<?php endif;?>
</ul>
<ul class='moduleDorpdown'>
<?php if(common::hasPriv('tree', 'browse')):?>
<li data-method="addCataBro" data-type="add" data-id="%moduleID%"><a><i class="icon icon-icon-add-directory"></i><?php echo $lang->doc->libDropdown['addSameModule'];?></a></li>
<li data-method="addCataChild" data-type="add" data-id="%moduleID%" data-has-children='%hasChildren%'><a><i class="icon icon-icon-add-directory"></i><?php echo $lang->doc->libDropdown['addSubModule'];?></a></li>
<li data-method="editCata" class='edit-module'><a data-href='<?php echo helper::createLink('tree', 'edit', 'moduleID=%moduleID%&type=doc');?>'><i class="icon icon-edit"></i><?php echo $lang->doc->libDropdown['editModule'];?></a></li>
<li data-method="deleteCata"><a href='<?php echo helper::createLink('tree', 'delete', 'rootID=%libID%&moduleID=%moduleID%');?>' target='hiddenwin'><i class="icon icon-trash"></i><?php echo $lang->doc->libDropdown['delModule'];?></a></li>
<?php endif;?>
</ul>
</div>
<div class='hidden' data-id="ulTreeModal">
<ul data-id="liTreeModal" class="menu-active-primary menu-hover-primary has-input">
<li data-id="insert" class="has-input">
<input data-target="%target%" class="form-control input-tree"></input>
</li>
</ul>
</div>
<div class="hidden" data-id="aTreeModal">
<a href="###" data-has-children="false" title="%name%" data-id="%id%">
<div class="text h-full w-full flex-between overflow-hidden" style="position: relative;">
<div>%name%</div>
<i class="icon icon-drop icon-ellipsis-v hidden file-drop-icon" data-iscatalogue="true"></i>
</div>
</a>
</div>
<?php include '../../common/view/footer.html.php';?>
+18 -7
View File
@@ -13,7 +13,6 @@
<?php include '../../common/view/header.html.php';?>
<div id='mainContent' class='main-row fade'>
<div class='main-col'>
<div class="cell" id="queryBox" data-module='user'></div>
<div id='mainMenu' class='clearfix'>
<div class='main-header'>
<h2><?php echo $lang->api->managePublish;?></h2>
@@ -24,11 +23,11 @@
<p><span class="text-muted"><?php echo $lang->noData;?></span></p>
</div>
<?php else:?>
<form class='main-table table-user' data-ride='table' method='post' data-checkable='false' id='userListForm'>
<table class='table has-sort-head' id='userList'>
<form class='main-table' method='post' id='releaseListForm'>
<table class='table has-sort-head' id='releaseList'>
<thead>
<tr>
<?php $vars = "libID={$libID}&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}";?>
<?php $vars = "libID={$libID}&orderBy=%s";?>
<th class='c-id'><?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
<th class='c-version'><?php common::printOrderLink('version', $orderBy, $vars, $lang->api->version);?></th>
<th class='c-name'><?php echo $lang->api->desc;?></th>
@@ -39,10 +38,10 @@
</thead>
<tbody>
<?php foreach($releases as $release):?>
<tr>
<tr data-id="<?php echo $release->id;?>">
<td><?php printf('%03d', $release->id);?></td>
<td><?php echo $release->version;?></td>
<td><?php echo $release->desc;?></td>
<td title=<?php echo $release->version;?>><?php echo $release->version;?></td>
<td title=<?php echo $release->desc;?>><?php echo $release->desc;?></td>
<td><?php echo zget($users, $release->addedBy, '');?></td>
<td class="c-date"><?php echo $release->addedDate;?></td>
<td class='c-actions'>
@@ -61,5 +60,17 @@ parent.$('#triggerModal .modal-content .modal-header .close').click(function()
{
parent.location.reload();
});
/**
* Remove release.
*
* @param int $releaseID
* @access public
* @return void
*/
function removeRelease(releaseID)
{
$('tr[data-id=' + releaseID + ']').remove()
}
</script>
<?php include '../../common/view/footer.html.php';?>
+14 -3
View File
@@ -15,6 +15,14 @@
<div class='main-col'>
<div class="cell" id="queryBox" data-module='user'></div>
<div id='mainMenu' class='clearfix'>
<div class='btn-toolbar pull-left leftBar'>
<?php $gobackLink = $this->session->structList ? $this->session->structList : inlink('struct', "libID=$libID");?>
<?php echo html::a($gobackLink, "<i class='icon-back'></i> " . $lang->goback, '', "class='btn btn-link'");?>
<div class='divider'></div>
<div class='page-title'>
<span class='text'><?php echo $lang->struct->list;?></span>
</div>
</div>
<div class='btn-toolbar pull-right'>
<?php common::printLink('api', 'createStruct', "libID=$libID", "<i class='icon icon-plus'></i> " . $lang->api->createStruct, '', "class='btn btn-primary create-user-btn'");?>
</div>
@@ -36,7 +44,7 @@
<th class='c-name'><?php echo $lang->api->structName;?></th>
<th class='c-user'><?php common::printOrderLink('addedBy', $orderBy, $vars, $lang->api->structAddedBy);?></th>
<th class='c-date'><?php common::printOrderLink('addedDate', $orderBy, $vars, $lang->api->structAddedDate);?></th>
<th class='c-actions'><?php echo $lang->actions;?></th>
<th class='c-actions-2'><?php echo $lang->actions;?></th>
</tr>
</thead>
<tbody>
@@ -44,9 +52,9 @@
<tr>
<td><?php printf('%03d', $struct->id);?></td>
<td><?php echo $struct->type;?></td>
<td><?php echo $struct->name;?></td>
<td class='c-name' title="<?php echo $struct->name;?>"><?php echo $struct->name;?></td>
<td><?php echo $struct->addedName;?></td>
<td class="c-date"><?php echo $struct->addedDate;?></td>
<td><?php echo formatTime($struct->addedDate, 'Y-m-d');?></td>
<td class='c-actions'>
<?php
if(common::hasPriv('api', 'editStruct')) echo html::a($this->createLink('api', 'editStruct', "libID=$libID&structID=$struct->id"), '<i class="icon-edit"></i>', '', "title='{$lang->api->editStruct}' class='btn'");
@@ -57,6 +65,9 @@
<?php endforeach;?>
</tbody>
</table>
<div class='table-footer'>
<?php $pager->show('right', 'pagerjs');?>
</div>
</form>
<?php endif;?>
</div>
+58
View File
@@ -0,0 +1,58 @@
<?php
/**
* The index view file of doc module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Yidong Wang <yidong@cnezsoft.com>
* @package doc
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/header.html.php';?>
<?php js::set('confirmDelete', $lang->api->confirmDelete);?>
<div class="cell<?php if($browseType == 'bySearch') echo ' show';?>" id="queryBox" data-module=<?php echo 'api';?>></div>
<div class="fade main-row split-row" id="mainRow">
<?php if($libID):?>
<?php $sideWidth = common::checkNotCN() ? '270' : '238';?>
<div class="side-col" style="width:<?php echo $sideWidth;?>px" data-min-width="<?php echo $sideWidth;?>">
<div class="cell" style="min-height: 286px; overflow: visible;">
<div id='title'>
<li class='menu-title'>
<div class="title"><?php echo $this->lang->api->module;?></div>
</li>
<?php
$canTreeBrowse = common::hasPriv('tree', 'browse');
$canViewReleases = common::hasPriv('api', 'releases');
$canEditLib = common::hasPriv('api', 'editLib');
$canDeleteLib = common::hasPriv('api', 'deleteLib');
$haveMoreButton = ($canTreeBrowse or $canViewReleases or $canEditLib or $canDeleteLib);
if(!$isRelease and $haveMoreButton)
{
echo "<div class='menu-actions'>";
echo html::a('javascript:;', "<i class='icon icon-ellipsis-v'></i>", '', "data-toggle='dropdown' class='btn btn-link'");
echo "<ul class='dropdown-menu pull-right'>";
if($canTreeBrowse) echo '<li>' . html::a($this->createLink('tree', 'browse', "rootID=$libID&view=api", '', true), '<i class="icon-cog-outline"></i> ' . $this->lang->api->manageType, '', "class='iframe' data-width='1200px'") . '</li>';
if($canViewReleases) echo '<li>' . html::a($this->createLink('api', 'releases', "libID=$libID", '', true), '<i class="icon-version"></i> ' . $this->lang->api->managePublish, '', "class='iframe'") . '</li>';
echo "<li class='divider'></li>";
if($canEditLib) echo '<li>' . html::a($this->createLink('api', 'editLib', "rootID=$libID"), '<i class="icon-edit"></i> ' . $lang->api->editLib, '', "class='iframe'") . '</li>';
if($canDeleteLib) echo '<li>' . html::a($this->createLink('api', 'deleteLib', "rootID=$libID"), '<i class="icon-trash"></i> ' . $lang->api->deleteLib, 'hiddenwin') . '</li>';
echo '</ul></div>';
}
?>
</div>
<?php if(!$moduleTree):?>
<hr class="space">
<?php if(!$isRelease):?>
<div class="text-center text-muted tips"><?php echo $lang->api->noModule;?></div>
<?php endif;?>
<?php endif;?>
<?php echo $moduleTree;?>
</div>
</div>
<?php endif;?>
<?php include 'apilist.html.php';?>
</div>
<?php include '../../common/view/footer.html.php';?>
+16 -11
View File
@@ -748,7 +748,7 @@ class block extends control
if(preg_match('/[^a-zA-Z0-9_]/', $this->params->type)) return;
$this->view->projects = $this->loadModel('project')->getPairsByProgram();
$this->view->testtasks = $this->dao->select('distinct t1.*,t2.name as productName,t2.shadow,t3.name as buildName,t4.name as projectName')->from(TABLE_TESTTASK)->alias('t1')
$this->view->testtasks = $this->dao->select('t1.*,t2.name as productName,t2.shadow,t3.name as buildName,t4.name as projectName')->from(TABLE_TESTTASK)->alias('t1')
->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product=t2.id')
->leftJoin(TABLE_BUILD)->alias('t3')->on('t1.build=t3.id')
->leftJoin(TABLE_PROJECT)->alias('t4')->on('t1.execution=t4.id')
@@ -1637,12 +1637,12 @@ class block extends control
$yesterday = date(DT_DATE1, strtotime('yesterday'));
$testtasks = $this->dao->select('*')->from(TABLE_TESTTASK)->where('product')->in($productIdList)->andWhere('project')->ne(0)->andWhere('deleted')->eq(0)->orderBy('id')->fetchAll('product');
$bugs = $this->dao->select("product, count(id) as total,
count(assignedTo = '{$this->app->user->account}' or null) as assignedToMe,
count(status != 'closed' or null) as unclosed,
count((status != 'closed' and status != 'resolved') or null) as unresolved,
count((confirmed = '0' and toStory = '0') or null) as unconfirmed,
count((resolvedDate >= '$yesterday' and resolvedDate < '$today') or null) as yesterdayResolved,
count((closedDate >= '$yesterday' and closedDate < '$today') or null) as yesterdayClosed")
count(IF(assignedTo = '{$this->app->user->account}', 1, null)) as assignedToMe,
count(IF(status != 'closed', 1, null)) as unclosed,
count(IF(status != 'closed' and status != 'resolved', 1, null)) as unresolved,
count(IF(confirmed = '0' and toStory = '0', 1, null)) as unconfirmed,
count(IF(resolvedDate >= '$yesterday' and resolvedDate < '$today', 1, null)) as yesterdayResolved,
count(IF(closedDate >= '$yesterday' and closedDate < '$today', 1, null)) as yesterdayClosed")
->from(TABLE_BUG)
->where('product')->in($productIdList)
->andWhere('execution')->in(array_keys($executions))
@@ -1650,13 +1650,18 @@ class block extends control
->groupBy('product')
->fetchAll('product');
$confirmedBugs = $this->dao->select('count(product) as product')->from(TABLE_ACTION)
$confirmedBugs = $this->dao->select('product')->from(TABLE_ACTION)
->where('objectType')->eq('bug')
->andWhere('action')->eq('bugconfirmed')
->andWhere('date')->ge($yesterday)
->andWhere('date')->lt($today)
->groupBy('product')
->fetchPairs('product', 'product');
->fetchAll();
$productConfirmedBugs = array();
foreach($confirmedBugs as $bug)
{
if(!isset($productConfirmedBugs[$bug->product])) $productConfirmedBugs[$bug->product] = 0;
$productConfirmedBugs[$bug->product]++;
}
foreach($products as $productID => $product)
{
@@ -1668,7 +1673,7 @@ class block extends control
$product->unconfirmed = empty($bug) ? 0 : $bug->unconfirmed;
$product->yesterdayResolved = empty($bug) ? 0 : $bug->yesterdayResolved;
$product->yesterdayClosed = empty($bug) ? 0 : $bug->yesterdayClosed;
$product->yesterdayConfirmed = empty($confirmedBugs[",$productID,"]) ? 0 : $confirmedBugs[",$productID,"];
$product->yesterdayConfirmed = empty($productConfirmedBugs[",$productID,"]) ? 0 : $productConfirmedBugs[",$productID,"];
$product->assignedRate = $product->total ? round($product->assignedToMe / $product->total * 100, 2) : 0;
$product->unresolvedRate = $product->total ? round($product->unresolved / $product->total * 100, 2) : 0;
+2 -2
View File
@@ -174,7 +174,7 @@ class bug extends control
$bugs = $this->bug->getBugs($productIDList, $executions, $branch, $browseType, $moduleID, $queryID, $sort, $pager, $this->projectID);
/* Process the sql, get the conditon partion, save it to session. */
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'bug', $browseType == 'needconfirm' ? false : true);
$this->loadModel('common')->saveQueryCondition($this->bug->dao->get(), 'bug', $browseType == 'needconfirm' ? false : true);
/* Process bug for check story changed. */
$bugs = $this->loadModel('story')->checkNeedConfirm($bugs);
@@ -919,7 +919,7 @@ class bug extends control
$projects = $this->loadModel('product')->getProjectPairsByProduct($productID, $bug->branch);
$this->session->set("project", key($projects), 'project');
$this->executeHooks($bugID);
/* Header and positon. */
+6
View File
@@ -633,6 +633,12 @@ function loadProjectBuilds(projectID)
$.get(createLink('bug', 'ajaxGetReleasedBuilds', 'productID=' + productID), function(data){releasedBuilds = data;}, 'json');
if($('#executionIdBox #execution').val() != 0)
{
$('#executionIdBox #execution').change();
return;
}
if(page == 'create')
{
var link = createLink('build', 'ajaxGetProjectBuilds', 'projectID=' + projectID + '&productID=' + productID + '&varName=openedBuild&build=&branch=' + branch);
+2 -1
View File
@@ -285,6 +285,7 @@ class buildModel extends model
$this->app->loadLang('branch');
foreach($allBuilds as $id => $build)
{
if($build->branch === '') $build->branch = 0;
if(empty($build->releaseID) and (strpos($params, 'nodone') !== false) and ($build->objectStatus === 'done')) continue;
if((strpos($params, 'noterminate') !== false) and ($build->releaseStatus === 'terminate')) continue;
if((strpos($params, 'withexecution') !== false) and $build->execution and isset($executions[$build->execution])) continue;
@@ -439,7 +440,7 @@ class buildModel extends model
if(!isset($relationBranch[$branch])) $relationBranch[$branch] = $branch;
}
}
$build->branch = implode(',', $relationBranch);
if($relationBranch) $build->branch = implode(',', $relationBranch);
}
$product = $this->loadModel('product')->getByID($build->product);
+9
View File
@@ -0,0 +1,9 @@
<?php
$config->chart->widthInput = 128;
$config->chart->widthDate = 248;
$config->chart->dateConvert = array();
$config->chart->dateConvert['year'] = 'YEAR';
$config->chart->dateConvert['month'] = 'MONTH';
$config->chart->dateConvert['week'] = 'YEARWEEK';
$config->chart->dateConvert['day'] = 'DATE';
+257
View File
@@ -0,0 +1,257 @@
<?php
/**
* The control file of chart module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
* @package chart
* @version $Id: model.php 5086 2013-07-10 02:25:22Z wyd621@gmail.com $
* @link http://www.zentao.net
*/
class chart extends control
{
/**
* Preview charts of a group.
*
* @param int $dimensionID
* @param int $groupID
* @access public
* @return void
*/
public function preview($dimensionID = 0, $groupID = 0)
{
$dimensionID = $this->loadModel('dimension')->setSwitcherMenu($dimensionID);
if(!$groupID) $groupID = $this->chart->getFirstChartGroupID($dimensionID);
list($chartTree, $charts) = $this->chart->getPreviewCharts($groupID);
if(!empty($_POST))
{
$charts = array();
foreach($this->post->charts as $value)
{
$chartID = explode('_', $value);
$group = $chartID[0];
$chartID = $chartID[1];
$chart = $this->chart->getByID($chartID);
$chart->currentGroup = $group;
$charts[] = $chart;
}
}
$this->view->title = $this->lang->chart->preview;
$this->view->dimensionID = $dimensionID;
$this->view->group = $this->loadModel('tree')->getByID($groupID);
$this->view->chartTree = $chartTree;
$this->view->charts = $charts;
$this->view->groups = $this->loadModel('tree')->getGroupPairs($dimensionID, 0, 1);
$this->display();
}
/**
* Ajax get filter form html.
*
* @param int $chartID
* @access public
* @return string
*/
public function ajaxGetFilterForm($chartID)
{
$fieldList = $this->post->fieldList;
$filters = $this->post->filters;
$fieldSettings = $this->post->fieldSettings;
$langs = $this->post->langs;
$clientLang = $this->app->getClientLang();
$fieldPairs = array();
foreach($fieldList as $field => $fieldName)
{
$fieldObject = $fieldSettings[$field]['object'];
$relatedField = $fieldSettings[$field]['field'];
$this->app->loadLang($fieldObject);
$fieldPairs[$field] = isset($this->lang->$fieldObject->$relatedField) ? $this->lang->$fieldObject->$relatedField : $field;
if(!isset($langs[$field])) continue;
if(!empty($langs[$field][$clientLang])) $fieldPairs[$field] = $langs[$field][$clientLang];
}
$htmls = array();
foreach($filters as $filter)
{
$field = $filter['field'];
$type = $filter['type'];
$default = isset($filter['default']) ? $filter['default'] : '';
$options = array();
if($type == 'select')
{
$fieldSetting = $fieldSettings[$field];
$options = $this->chart->getSysOptions(zget($fieldSetting, 'type', ''), zget($fieldSetting, 'object', ''), zget($fieldSetting, 'field', ''));
}
$filterHtml = array();
/* field html */
$filterHtml['field'] = html::select('field', $fieldPairs, $field, "class='form-control picker-select' onchange='initFilterForm(this, this.value)'");
/* default html */
$filterHtml['default'] = '';
if($type == 'input') $filterHtml['default'] .= html::input('default', $default, "class='form-control' onchange='changeDefault(this,this.value)'");
if($type == 'date' or $type == 'datetime')
{
if(empty($default)) $default = array('begin' => '', 'end' => '');
$class = $type == 'date' ? 'form-date' : 'form-datetime';
$filterHtml['default'] .= '<div class="input-group">';
$filterHtml['default'] .= html::input('default[begin]', $default['begin'], "class='form-control $class default-begin' placeholder='{$this->lang->chart->unlimited}' onchange='changeDefault(this,this.value)'");
$filterHtml['default'] .= "<span class='input-group-addon fix-border borderBox' style='border-radius: 0px;'>{$this->lang->chart->colon}</span>";
$filterHtml['default'] .= html::input('default[end]', $default['end'], "class='form-control $class default-end' placeholder='{$this->lang->chart->unlimited}' onchange='changeDefault(this,this.value)'");
$filterHtml['default'] .= '</div>';
}
if($type == 'select') $filterHtml['default'] = html::select('default[]', $options, $default, "class='form-control picker-select' onchange='changeDefault(this,this.value)' multiple");
if($type == 'condition')
{
$operator = isset($filter['operator']) ? $filter['operator'] : '';
$value = isset($filter['value']) ? $filter['value'] : '';
$hidden = strpos($operator, 'NULL') !== false ? 'hidden' : '';
$filterHtml['default'] = "<div class='conditionGroup' style='display:flex'>";
$filterHtml['default'] .= html::select('operator', $this->config->bi->conditionList, $operator, "class='form-control picker-select' onchange='changeCondition(this,this.value)'");
$filterHtml['default'] .= html::input('value', $value, "class='form-control $hidden' onchange='changeConditionValue(this,this.value)'");
$filterHtml['default'] .= "<div/>";
}
/* type html */
$filterHtml['type'] = html::select('type', $this->lang->chart->fieldTypeList, $type, "class='form-control picker-select' onchange='changeType(this, this.value)'");
/* filter item html */
$filterHtml['item'] = '';
if($type == 'input') $filterHtml['item'] .= html::input('default', $default, "class='form-control'");
if($type == 'date' or $type == 'datetime')
{
if(empty($default)) $default = array('begin' => '', 'end' => '');
$class = $type == 'date' ? 'form-date' : 'form-datetime';
$filterHtml['item'] .= '<div class="input-group">';
$filterHtml['item'] .= "<input type='text' name='default[begin]' id='default[begin]' value='{$default['begin']}' class='form-control $class default-begin' autocomplete='off' placeholder='{$this->lang->chart->unlimited}' onchange='changeDefault(this, this.value)'>";
$filterHtml['item'] .= '<span class="input-group-addon fix-border borderBox" style="border-radius: 0px;">' . $this->lang->chart->colon . '</span>';
$filterHtml['item'] .= "<input type='text' name='default[end]' id='default[end]' value='{$default['end']}' class='form-control $class default-end' autocomplete='off' placeholder='{$this->lang->chart->unlimited}' onchange='changeDefault(this, this.value)'>";
$filterHtml['item'] .= '</div>';
}
if($type == 'select') $filterHtml['item'] .= html::select('default', array('' => '') + $options, $default, "class='form-control picker-select' multiple");
if($type == 'condition')
{
$operator = isset($filter['operator']) ? $filter['operator'] : '';
$value = isset($filter['value']) ? $filter['value'] : '';
$hidden = strpos($operator, 'NULL') !== false ? 'hidden' : '';
$filterHtml['item'] = "<div class='conditionGroup' style='display:flex'>";
$filterHtml['item'] .= html::select('operator', $this->config->bi->conditionList, $operator, "class='form-control picker-select' onchange='changeCondition(this,this.value, true)'");
$filterHtml['item'] .= html::input('value', $value, "class='form-control $hidden'");
$filterHtml['item'] .= "<div/>";
}
$htmls[] = $filterHtml;
}
echo json_encode($htmls);
}
/**
* Ajax get chart.
*
* @access public
* @return void
*/
public function ajaxGetChart()
{
$post = fixer::input('post')->skipSpecial('settings,filters,sql,langs')->get();
$chartID = $post->id;
$settings = current($post->settings);
$type = $settings['type'];
$filters = isset($_POST['searchFilters']) ? $_POST['searchFilters'] : (isset($_POST['filters']) ? $post->filters : array());
$chart = $this->chart->getByID($chartID);
$filterFormat = array();
foreach($filters as $filter)
{
$field = $filter['field'];
if(!isset($filter['default'])) continue;
$default = $filter['default'];
switch($filter['type'])
{
case 'select':
if(empty($default)) break;
$default = array_filter($default, function($val){return !empty($val);});
$value = "('" . implode("', '", $default) . "')";
$filterFormat[$field] = array('operator' => 'IN', 'value' => $value);
break;
case 'input':
$filterFormat[$field] = array('operator' => 'like', 'value' => "'%$default%'");
break;
case 'date':
case 'datetime':
$begin = $default['begin'];
$end = $default['end'];
if(empty($begin) or empty($end)) break;
$value = "'$begin' and '$end'";
$filterFormat[$field] = array('operator' => 'BETWEEN', 'value' => $value);
break;
case 'condition':
$operator = $filter['operator'];
$value = $filter['value'];
if(in_array($operator, array('IN', 'NOT IN')))
{
$valueArr = explode(',', $value);
foreach($valueArr as $key => $val) $valueArr[$key] = '"' . $val . '"';
$value = '(' . implode(',', $valueArr) . ')';
}
elseif(in_array($operator, array('IS NOT NULL', 'IS NULL')))
{
$value = '';
}
$filterFormat[$field] = array('operator' => $operator, 'value' => $value);
break;
}
}
$sql = str_replace(';', '', "$post->sql");
$fields = $post->fieldSettings;
$langs = isset($post->langs) ? $post->langs : array();
switch($type)
{
case 'line':
$data = $this->chart->genLineChart($fields, $settings, $sql, $filterFormat, $langs);
break;
case 'cluBarX':
$data = $this->chart->genCluBar($fields, $settings, $sql, $filterFormat, '', $langs);
break;
case 'cluBarY':
$data = $this->chart->genCluBar($fields, $settings, $sql, $filterFormat, '', $langs);
break;
case 'pie':
$data = $this->chart->genPie($fields, $settings, $sql, $filterFormat);
break;
case 'radar':
$data = $this->chart->genRadar($fields, $settings, $sql, $filterFormat, $langs);
break;
case 'stackedBar':
$data = $this->chart->genCluBar($fields, $settings, $sql, $filterFormat, 'total', $langs);
break;
case 'stackedBarY':
$data = $this->chart->genCluBar($fields, $settings, $sql, $filterFormat, 'total', $langs);
break;
}
echo json_encode($data);
}
}
+7
View File
@@ -0,0 +1,7 @@
.table-panel {overflow-x: auto;}
.datatable {width: auto;}
.datatable th.header {line-height: 32px !important;}
.header-config {float: right; display: none;}
.header:hover .header-config {display: inline-block;}
.label-outline.label-info {border: unset; line-height: 14px;}
.border-bottom {border-bottom: 1px solid #f4f5f7;}
+53
View File
@@ -0,0 +1,53 @@
.m-chart-preview {color: rgb(49, 60, 82); background-color: rgb(244, 245, 247);}
.main-col .btn-toolbar {margin-bottom: 10px;}
.main-position {position: relative;}
.child-position {position: absolute; right: 0;}
.parent-position{padding-right: 180px;}
.biz-version {padding-top: 10px;}
.biz-version a {color: #81511C;}
#chartGroups li {overflow: hidden; white-space: nowrap;}
#chartGroups .checkbox-primary {margin-left: 8px; display: inline-block;}
#chartGroups .checkbox-primary + a {display: inline-block;}
#chartGroups .checkbox-primary > input[type=checkbox][name^=chart] + label {padding-left: 0px;}
.chart-item + .chart-item {margin-top: 10px;}
.chartbox {
height: 400px;
overflow: overlay;
border: 1px solid #ddd;
}
.ant-table-tbody>tr>td, .ant-table-thead>tr>th {
padding: 8px!important;
}
.table-title {
top: 10px;
right: auto;
bottom: auto;
left: 10px;
width: auto;
height: auto;
margin: 0px 0px 10px 10px;
font-size: 18px;
font-weight: bold;
text-align: left;
}
#subNavbar .nav li.active a {display: none;}
#mainContent .cell {padding: 11px;}
#mainContent .panel {border: 0;}
#mainContent .chart-item.main-row x-vue-echarts {max-height: 460px;}
#mainContent .chart-item.main-row .ant-table-wrapper {max-height: 398px; overflow-y: overlay !important;border: 1px solid #e8e8e8; border-right: 0;}
#mainContent .chart-item.main-row .ant-table-bordered .ant-table-body>table {border: 0;}
#mainContent .chart-item.main-row .ant-table-bordered .ant-table-body>table tr:last-child td {border-bottom: 0;}
.echart-content {width: 100%; min-height: 500px;}
.filterBox{display: flex; margin-bottom: 20px;}
.filter-items{display: flex; flex: 1; flex-wrap: wrap;}
.filter-item{padding: 0 16px 5px 0;}
.filter-item-grow{flex-grow: 1;}
.queryBtn{display: flex; align-items: center; padding-bottom: 5px;}
.filterBox .picker-selections{width: 128px; height: 32px; overflow: hidden; text-overflow: clip; white-space: nowrap;}
+56
View File
@@ -0,0 +1,56 @@
/**
* Ajax get chart data.
*
* @access public
* @return bool
*/
function ajaxGetChart(check = true, chart = DataStorage.chart, echart = window.echart)
{
var chartParams = JSON.parse(JSON.stringify(chart));
if(typeof DataStorage != 'undefined') chartParams.fieldSettings = JSON.parse(JSON.stringify(DataStorage.fieldSettings));
if(typeof DataStorage != 'undefined') chartParams.langs = JSON.parse(JSON.stringify(DataStorage.langs));
/* Redraw echart. */
/* 拿数据并重绘图表。*/
$.post(createLink('chart', 'ajaxGetChart'), chartParams, function(resp)
{
var data = JSON.parse(resp);
if(echart)
{
echart.clear();
echart.setOption(data, true);
$('.btn-export').removeClass('hidden');
}
});
}
/**
* Init picker.
*
* @access public
* @return void
*/
function initPicker($row, pickerName = 'picker-select')
{
$row.find('.' + pickerName).picker({'maxDropHeight': pickerHeight});
$row.find("." + pickerName).each(function(index)
{
if($(this).hasClass('required')) $(this).siblings("div .picker").addClass('required');
});
}
/**
* Init datepicker.
*
* @param object $obj
* @param function callback
* @access public
* @return void
*/
function initDatepicker($obj, callback)
{
$obj.find('.form-date').datepicker();
$obj.find('.form-datetime').datetimepicker();
if(typeof callback == 'function') callback($obj);
}
+215
View File
@@ -0,0 +1,215 @@
$(function()
{
initCheckBox();
initQueryBtn();
$('#exportchart').modalTrigger();
chartMap = new Map();
if(charts.length > 0)
{
charts.forEach(function(chart)
{
var echartDom = $('#chartDraw' + chart.currentGroup + chart.id).get(0);
var echart = echarts.init(echartDom);
ajaxGetChart(false, chart, echart);
renderFilters(chart);
chartMap.set(chart.currentGroup + chart.id, chart);
});
}
calcPreviewGrowFilter();
$('body').resize(() => {calcPreviewGrowFilter(true);});
$('[data-toggle="tooltip"]').tooltip();
})
/**
* Init check box.
*
* @access public
* @return void
*/
function initCheckBox()
{
/* Use parent checked prop set all child. */
$('input[data-type="parent"]').click(function()
{
$(this).parent().siblings('ul').find('input[data-type="child"]').prop('checked', $(this).prop('checked'));
});
$('input[data-type="child"]').click(function()
{
/* If child unchecked after click, set parent unchecked. */
if(!$(this).prop('checked'))
{
$(this).parentsUntil('#chartGroups', 'li').find('div').children('input[data-type="parent"]').prop('checked', false);
}
/* If child checked after click, if all child checked, set parent checked. */
else
{
if($(this).closest('ul').find('input[data-type="child"]').length >= 1)
{
var siblings_checked = $(this).closest('ul').find('input[data-type="child"]:checked').length;
var siblings_total = $(this).closest('ul').find('input[data-type="child"]').length;
if(siblings_checked == siblings_total)
{
$(this).parentsUntil('#chartGroups', 'li').find('div').children('input[data-type="parent"]').prop('checked', true);
}
}
}
});
/* Use click to trigger event. */
charts.forEach(function(item)
{
$("#chart_" + item.currentGroup + '_' + item.id).click();
});
}
/**
* Init query button.
*
* @access public
* @return void
*/
function initQueryBtn()
{
$('.btn-query').click(function()
{
var chartID = $(this).attr('data-chart');
var chartInfo = chartMap.get(chartID);
chartInfo.searchFilters = JSON.parse(JSON.stringify(chartInfo.filters));
// Foreach filters and set current value in searchFilters. */
$('#filterItems' + chartID + ' .filter-items').children().each(function(index)
{
var $child = $(this);
var filter = chartInfo.searchFilters[index];
var type = filter.type;
var value = null;
if(type == 'input' || type == 'select')
{
var value = $child.find('#default').val();
chartInfo.searchFilters[index].default = value;
}
else if(type == 'date' || type == 'datetime')
{
var begin = $child.find('input').first().val();
var end = $child.find('input').last().val();
var value = {"begin":begin, "end":end};
chartInfo.searchFilters[index].default = value;
}
else if(type == 'condition')
{
var operator = $child.find('#operator').data('zui.picker').getValue();
var value = $child.find('#value').val();
chartInfo.searchFilters[index].operator = operator;
chartInfo.searchFilters[index].value = value;
}
});
//* Reload echart. */
var echartDom = $('#chartDraw' + chartID).get(0);
var echartInfo = echarts.init(echartDom);
ajaxGetChart(false, chartInfo, echartInfo);
});
}
function calcPreviewGrowFilter(resize = false)
{
if(charts.length <= 0) return;
charts.forEach(function(chart)
{
/* When body resize, resize echarts. */
if(resize)
{
var echartDom = $('#chartDraw' + chart.currentGroup + chart.id).get(0);
var echart = echarts.init(echartDom);
echart.resize();
}
var $filterItems = $('#filterItems' + chart.currentGroup + chart.id + ' .filter-items');
/* When refreshing this page, ZenTao load this page twice, when the first load isn't complete, jump back to index and load the second time,
the first load can't calc filter width, can't get the element using jQuery at first load. */
var hasInit = true;
chart.filters.forEach(function(filter, index)
{
var nowItem = '.filter-item-' + index;
var $titleSpan = $filterItems.find(nowItem).find('.input-group-addon').first();
if(!$titleSpan.length) hasInit = false;
});
if(!hasInit) return;
var domWidth = $filterItems[0].getBoundingClientRect().width;
var nowWidth = domWidth;
var nowCount = 0;
var canGrowTotal = 0;
chart.filters.forEach(function(filter, index)
{
var nowItem = '.filter-item-' + index;
var leftPadding = parseInt($filterItems.find(nowItem).css('padding-left'));
var rightPadding = parseInt($filterItems.find(nowItem).css('padding-right'));
var spanWidth = $filterItems.find(nowItem).find('.input-group-addon').first()[0].getBoundingClientRect().width;
var filterWidth = ((filter.type == 'input' || filter.type == 'select') ? WIDTH_INPUT : WIDTH_DATE) + (spanWidth + leftPadding + rightPadding);
/* Clear the flex-basis and set flex-basic again. */
$filterItems.find(nowItem).css('flex-basis', '');
$filterItems.find(nowItem).css('flex-basis', filterWidth);
if(nowWidth - filterWidth >= 0)
{
nowWidth -= filterWidth;
nowCount ++;
}
else
{
canGrowTotal += nowCount;
nowWidth = domWidth - filterWidth;
nowCount = 1;
}
});
/* Clear all filter filter-item-grow and add class to support grow element. */
$filterItems.children().removeClass('filter-item-grow');
chart.filters.forEach(function(filter, index)
{
var nowItem = '.filter-item-' + index;
if(canGrowTotal >= index + 1) $filterItems.find(nowItem).addClass('filter-item-grow');
});
});
}
function renderFilters(chart)
{
if(chart.filters.length == 0) return;
var fieldNames = {};
Object.keys(chart.fieldSettings).forEach(function(key){fieldNames[key] = chart.fieldSettings[key].name;});
$.post(createLink('chart', 'ajaxGetFilterForm', 'chartID=' + chart.id), {fieldList: fieldNames, fieldSettings: chart.fieldSettings, filters: chart.filters, langs: chart.langs}, function(resp)
{
resp = JSON.parse(resp);
chart.filters.forEach(function(filter, index)
{
var $filterItems = $('#filterItems' + chart.currentGroup + chart.id + ' .filter-items');
$filterItems.append(renderFilterItem(filter, resp, index));
});
});
}
function renderFilterItem(filter, resp, index, step)
{
var tpl = $('#filterItemTpl').html();
var data =
{
index: index,
name: filter.name,
search: resp[index].item
};
var html = $($.zui.formatString(tpl, data))
initPicker(html);
initDatepicker(html);
return html;
}
+33
View File
@@ -0,0 +1,33 @@
<?php
$lang->chart->preview = 'View Chart';
$lang->chart->query = 'Query';
$lang->chart->toDesign = 'To Design';
$lang->chart->group = 'Group';
$lang->chart->field = 'Field';
$lang->chart->agg = 'Aggregate';
$lang->chart->chooseField = 'Choose field';
$lang->chart->aggType = 'Aggregate type';
$lang->chart->other = 'Other';
$lang->chart->unlimited = 'Unlimited';
$lang->chart->colon = 'To';
$lang->chart->fieldTypeList = array();
$lang->chart->fieldTypeList['input'] = 'Text';
$lang->chart->fieldTypeList['date'] = 'Date';
$lang->chart->fieldTypeList['datetime'] = 'Time';
$lang->chart->fieldTypeList['select'] = 'Dropdown';
//$lang->chart->fieldTypeList['condition'] = 'Condition';
$lang->chart->groupWeek = 'Week %s,%s';
$lang->chart->noChart = 'No Chart';
$lang->chart->noChartSelected = 'Please select one chart.';
$lang->chart->aggList = array();
$lang->chart->aggList['count'] = 'Count';
$lang->chart->aggList['distinct'] = 'Count after distinct';
$lang->chart->aggList['avg'] = 'AVG';
$lang->chart->aggList['sum'] = 'SUM';
$lang->chart->aggList['max'] = 'MAX';
$lang->chart->aggList['min'] = 'MIN';
+33
View File
@@ -0,0 +1,33 @@
<?php
$lang->chart->preview = 'View Chart';
$lang->chart->query = 'Query';
$lang->chart->toDesign = 'To Design';
$lang->chart->group = 'Group';
$lang->chart->field = 'Field';
$lang->chart->agg = 'Aggregate';
$lang->chart->chooseField = 'Choose field';
$lang->chart->aggType = 'Aggregate type';
$lang->chart->other = 'Other';
$lang->chart->unlimited = 'Unlimited';
$lang->chart->colon = 'To';
$lang->chart->fieldTypeList = array();
$lang->chart->fieldTypeList['input'] = 'Text';
$lang->chart->fieldTypeList['date'] = 'Date';
$lang->chart->fieldTypeList['datetime'] = 'Time';
$lang->chart->fieldTypeList['select'] = 'Dropdown';
//$lang->chart->fieldTypeList['condition'] = 'Condition';
$lang->chart->groupWeek = 'Week %s,%s';
$lang->chart->noChart = 'No Chart';
$lang->chart->noChartSelected = 'Please select one chart.';
$lang->chart->aggList = array();
$lang->chart->aggList['count'] = 'Count';
$lang->chart->aggList['distinct'] = 'Count after distinct';
$lang->chart->aggList['avg'] = 'AVG';
$lang->chart->aggList['sum'] = 'SUM';
$lang->chart->aggList['max'] = 'MAX';
$lang->chart->aggList['min'] = 'MIN';
+33
View File
@@ -0,0 +1,33 @@
<?php
$lang->chart->preview = 'View Chart';
$lang->chart->query = 'Query';
$lang->chart->toDesign = 'To Design';
$lang->chart->group = 'Group';
$lang->chart->field = 'Field';
$lang->chart->agg = 'Aggregate';
$lang->chart->chooseField = 'Choose field';
$lang->chart->aggType = 'Aggregate type';
$lang->chart->other = 'Other';
$lang->chart->unlimited = 'Unlimited';
$lang->chart->colon = 'To';
$lang->chart->fieldTypeList = array();
$lang->chart->fieldTypeList['input'] = 'Text';
$lang->chart->fieldTypeList['date'] = 'Date';
$lang->chart->fieldTypeList['datetime'] = 'Time';
$lang->chart->fieldTypeList['select'] = 'Dropdown';
//$lang->chart->fieldTypeList['condition'] = 'Condition';
$lang->chart->groupWeek = 'Week %s,%s';
$lang->chart->noChart = 'No Chart';
$lang->chart->noChartSelected = 'Please select one chart.';
$lang->chart->aggList = array();
$lang->chart->aggList['count'] = 'Count';
$lang->chart->aggList['distinct'] = 'Count after distinct';
$lang->chart->aggList['avg'] = 'AVG';
$lang->chart->aggList['sum'] = 'SUM';
$lang->chart->aggList['max'] = 'MAX';
$lang->chart->aggList['min'] = 'MIN';
+33
View File
@@ -0,0 +1,33 @@
<?php
$lang->chart->preview = '查看图表';
$lang->chart->query = '查询';
$lang->chart->toDesign = '进入设计';
$lang->chart->group = '所属分组';
$lang->chart->field = '关联字段';
$lang->chart->agg = '汇总';
$lang->chart->chooseField = '选择字段';
$lang->chart->aggType = '统计方式';
$lang->chart->other = '其他';
$lang->chart->unlimited = '不限';
$lang->chart->colon = '至';
$lang->chart->fieldTypeList = array();
$lang->chart->fieldTypeList['input'] = '文本框';
$lang->chart->fieldTypeList['date'] = '日期';
$lang->chart->fieldTypeList['datetime'] = '时间';
$lang->chart->fieldTypeList['select'] = '下拉菜单';
//$lang->chart->fieldTypeList['condition'] = '条件筛选';
$lang->chart->groupWeek = '%s年第%s周';
$lang->chart->noChart = '暂时没有图表';
$lang->chart->noChartSelected = '请选择至少一个图表。';
$lang->chart->aggList = array();
$lang->chart->aggList['count'] = '计数';
$lang->chart->aggList['distinct'] = '去重后计数';
$lang->chart->aggList['avg'] = '平均值';
$lang->chart->aggList['sum'] = '求和';
$lang->chart->aggList['max'] = '最大值';
$lang->chart->aggList['min'] = '最小值';
+630
View File
@@ -0,0 +1,630 @@
<?php
/**
* The model file of chart module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
* @package chart
* @version $Id: model.php 5086 2013-07-10 02:25:22Z wyd621@gmail.com $
* @link http://www.zentao.net
*/
class chartModel extends model
{
/**
* Get first chart group id.
*
* @param int $dimensionID
* @access public
* @return int
*/
public function getFirstChartGroupID($dimensionID)
{
return $this->dao->select('id')->from(TABLE_MODULE)
->where('deleted')->eq('0')
->andWhere('type')->eq('chart')
->andWhere('root')->eq($dimensionID)
->andWhere('grade')->eq(1)
->orderBy('`order`')
->limit(1)
->fetch('id');
}
/**
* Get chart.
*
* @param int $chartID
* @access public
* @return object
*/
public function getByID($chartID)
{
$chart = $this->dao->select('*')->from(TABLE_CHART)->where('id')->eq($chartID)->fetch();
if(!$chart) return false;
if(!empty($chart->fields) and $chart->fields != 'null')
{
$chart->fieldSettings = json_decode($chart->fields);
$chart->fields = array();
foreach($chart->fieldSettings as $field => $settings) $chart->fields[] = $field;
}
else
{
$chart->fieldSettings = array();
}
if($chart->sql == null) $chart->sql = '';
if(!empty($chart->filters)) $chart->filters = json_decode($chart->filters, true);
return $this->processChart($chart);
}
/**
* Process sql and correct type.
*
* @param object $chart
* @access public
* @return object
*/
public function processChart($chart)
{
if(!empty($chart->sql)) $chart->sql = trim(str_replace(';', '', $chart->sql));
if(!empty($chart->settings)) $chart->settings = json_decode($chart->settings, true);
if(!empty($chart->settings) and is_array($chart->settings))
{
$firstSetting = current($chart->settings);
if(isset($firstSetting['type'])) $chart->type = $firstSetting['type'];
}
return $chart;
}
/**
* Get tree of charts and groups.
*
* @param int $groupID
* @param string $orderBy
* @access public
* @return array
*/
public function getPreviewCharts($groupID, $orderBy = 'id_desc')
{
if(!$groupID) return array('', array());
$currentGroup = $this->loadModel('tree')->getByID($groupID);
if(empty($currentGroup) || $currentGroup->grade != 1) return array('', array());
$groups = $this->dao->select('id, grade, name')->from(TABLE_MODULE)->where('deleted')->eq('0')->andWhere('path')->like("{$currentGroup->path}%")->orderBy('`order`')->fetchAll();
if(!$groups) return array('', array());
$chartGroups = array();
foreach($groups as $group)
{
$chartGroups[$group->id] = $this->dao->select('*')->from(TABLE_CHART)
->where('deleted')->eq(0)
->andWhere("FIND_IN_SET($group->id, `group`)")
->andWhere('stage')->ne('draft')
->orderBy($orderBy)
->fetchAll();
}
if(!$chartGroups) return array('', array());
$readyCharts = array();
foreach($chartGroups as $groupID => $chartGroup)
{
$charts = array();
foreach($chartGroup as $chart)
{
if($chart->stage != 'published') continue;
$charts[] = $chart;
}
if(!empty($charts)) $readyCharts[$groupID] = $charts;
}
$index = 1;
$chartTree = '';
$firstChart = null;
foreach($groups as $group)
{
if(!isset($readyCharts[$group->id])) continue;
if($group->grade == 2)
{
$class = $index == 1 ? 'open' : 'closed';
$chartTree .= "<li class='$class'><div class='checkbox-primary'><input type='checkbox' data-type='parent' name='groups[]' id='group{$group->id}' value='{$group->id}' title='{$group->name}'><label>{$group->name}</label></div><ul>";
}
$charts = $readyCharts[$group->id];
foreach($charts as $chart)
{
$chart->currentGroup = $group->id;
if(!$firstChart) $firstChart = $chart;
$chartTree .= "<li title='{$chart->name}'><div class='checkbox-primary checkbox-inline'><input type='checkbox' data-type='child' name='charts[]' id='chart_{$group->id}_{$chart->id}' value='{$group->id}_{$chart->id}' title='{$chart->name}' data-group='{$group->id}'><label for='chart_{$group->id}_{$chart->id}'></label></div><a>{$chart->name}</a></li>";
}
if($group->grade == 2) $chartTree .= '</ul></li>';
$index++;
}
if($chartTree) $chartTree = "<ul id='chartGroups' class='tree' data-ride='tree'>" . $chartTree . '</ul>';
$charts = array();
if($firstChart)
{
if(!empty($firstChart->settings)) $firstChart->settings = json_decode($firstChart->settings, true);
if(!empty($firstChart->filters)) $firstChart->filters = json_decode($firstChart->filters, true);
if(!empty($firstChart->fields) and $firstChart->fields != 'null')
{
$firstChart->fieldSettings = json_decode($firstChart->fields);
$firstChart->fields = array_keys(json_decode($firstChart->fields, true));
}
$charts[] = $firstChart;
}
return array($chartTree, $charts);
}
/**
* Gen radar.
*
* @param int $fields
* @param int $settings
* @param int $defaultSql
* @param int $filters
* @param array $langs
* @access public
* @return void
*/
public function genRadar($fields, $settings, $defaultSql, $filters, $langs = array())
{
list($group, $metrics, $aggs, $xLabels, $yStats) = $this->getMultiData($settings, $defaultSql, $filters);
$yDatas = array();
$max = 0;
foreach($yStats as $yStat)
{
$data = array();
foreach($xLabels as $xLabel)
{
$yStatXLabel = isset($yStat[$xLabel]) ? $yStat[$xLabel] : 0;
$data[] = $yStatXLabel;
}
if(max($yStat) > $max) $max = max($yStat);
$yDatas[] = $data;
}
$series = array();
$legend = new stdclass();
$series['type'] = 'radar';
$clientLang = $this->app->getClientLang();
foreach($yDatas as $index => $yData)
{
$fieldName = $fields[$metrics[$index]]['name'];
if(!empty($fields[$metrics[$index]]['object']) and !empty($fields[$metrics[$index]]['field']))
{
$relatedObject = $fields[$metrics[$index]]['object'];
$relatedField = $fields[$metrics[$index]]['field'];
$this->app->loadLang($relatedObject);
$fieldName = isset($this->lang->$relatedObject->$relatedField) ? $this->lang->$relatedObject->$relatedField : $fieldName;
}
if(isset($langs[$metrics[$index]]) and !empty($langs[$metrics[$index]][$clientLang])) $fieldName = $langs[$metrics[$index]][$clientLang];
$seriesName = $fieldName . '(' . $this->lang->chart->aggList[$aggs[$index]] . ')';
$series['data'][] = array('name' => $seriesName, 'value' => $yData);
}
$indicator = array();
$optionList = $this->getSysOptions($fields[$group]['type'], $fields[$group]['object'], $fields[$group]['field']);
foreach($xLabels as $xLabel)
{
$labelName = isset($optionList[$xLabel]) ? $optionList[$xLabel] : $xLabel;
$indicator[] = array('name' => $labelName, 'max' => $max);
}
$options = array('series' => $series, 'legend' => $legend, 'radar' => array('indicator' => $indicator), 'tooltip' => array('trigger' => 'item'));
return $options;
}
/**
* Gen pie.
*
* @param string $schema
* @param object $settings
* @param string $sql
* @param array $filters
* @access public
* @return array
*/
public function genPie($fields, $settings, $sql, $filters)
{
$group = isset($settings['group'][0]['field']) ? $settings['group'][0]['field'] : '';
$date = isset($settings['group'][0]['group']) ? zget($this->config->chart->dateConvert, $settings['group'][0]['group']) : '';
$metric = isset($settings['metric'][0]['field']) ? $settings['metric'][0]['field'] : '';
$agg = isset($settings['metric'][0]['valOrAgg']) ? $settings['metric'][0]['valOrAgg'] : '';
$defaultSql = str_replace(';', '', $sql);
$groupSql = $groupBySql = "tt.`$group`";
if(!empty($date))
{
$groupSql = $date == 'MONTH' ? "YEAR(tt.`$group`) as ttyear, $date(tt.`$group`) as ttgroup" : "$date(tt.`$group`) as $group";
$groupBySql = $date == 'MONTH' ? "YEAR(tt.`$group`), $date(tt.`$group`)" : "$date(tt.`$group`)";
}
if($agg == 'distinct')
{
$aggSQL = "count($agg tt.`$metric`) as `$metric`";
}
else
{
$aggSQL = "$agg(tt.`$metric`) as `$metric`";
}
$sql = "select $groupSql,$aggSQL from ($defaultSql) tt";
if(!empty($filters))
{
$wheres = array();
foreach($filters as $field => $filter)
{
$wheres[] = "$field {$filter['operator']} {$filter['value']}";
}
$whereStr = implode(' and ', $wheres);
$sql .= " where $whereStr";
}
$sql .= " group by $groupBySql";
$rows = $this->dao->query($sql)->fetchAll();
$stat = $this->processRows($rows, $date, $group, $metric);
$maxCount = 50;
if(empty($date)) arsort($stat);
$copyStat = $stat;
$other = array_sum(array_splice($copyStat, $maxCount));
$stat[$this->lang->chart->other] = $other;
if(empty($date)) arsort($stat);
$optionList = $this->getSysOptions($fields[$group]['type'], $fields[$group]['object'], $fields[$group]['field']);
$data = array();
foreach($stat as $name => $value)
{
if($value == 0) continue;
$value = round($value, 2);
$labelName = isset($optionList[$name]) ? $optionList[$name] : $name;
$data[] = array('name' => $labelName, 'value' => $value);
}
$label = array('show' => true, 'position' => 'outside', 'formatter' => '{b} {d}%');
$legend = new stdclass();
$legend->type = 'scroll';
$legend->orient = 'vertical';
$legend->right = 0;
$series[] = array('data' => $data, 'type' => 'pie', 'label' => $label);
$options = array('series' => $series, 'legend' => $legend, 'tooltip' => array('trigger' => 'item', 'formatter' => "{b}<br/> {c} ({d}%)"));
return $options;
}
/**
* Process rows.
*
* @param array $rows
* @param string $date
* @param string $group
* @param string $metric
* @access public
* @return array
*/
public function processRows($rows, $date, $group, $metric)
{
$stat = array();
foreach($rows as $row)
{
if(!empty($date) and $date == 'MONTH')
{
$stat[sprintf("%04d", $row->ttyear) . '-' . sprintf("%02d", $row->ttgroup)] = $row->$metric;
}
elseif(!empty($date) and $date == 'YEARWEEK')
{
$yearweek = sprintf("%06d", $row->$group);
$year = substr($yearweek, 0, strlen($yearweek) - 2);
$week = substr($yearweek, -2);
$weekIndex = in_array($this->app->getClientLang(), array('zh-cn', 'zh-tw')) ? sprintf($this->lang->chart->groupWeek, $year, $week) : sprintf($this->lang->chart->groupWeek, $week, $year);
$stat[$weekIndex] = $row->$metric;
}
elseif(!empty($date) and $date == 'YEAR')
{
$stat[sprintf("%04d", $row->$group)] = $row->$metric;
}
else
{
$stat[$row->$group] = $row->$metric;
}
}
return $stat;
}
/**
* Gen line.
*
* @param string $schema
* @param object $settings
* @param string $sql
* @param array $filters
* @param array $langs
* @access public
* @return array
*/
public function genLineChart($fields, $settings, $defaultSql, $filters, $langs = array())
{
list($group, $metrics, $aggs, $xLabels, $yStats) = $this->getMultiData($settings, $defaultSql, $filters);
$fieldType = $fields[$settings['xaxis'][0]['field']]['type'];
if($fieldType == 'date') sort($xLabels);
$yDatas = array();
foreach($xLabels as $xLabel)
{
foreach($yStats as $index => $yStat)
{
if(!isset($yDatas[$index])) $yDatas[$index] = array();
$yDatas[$index][] = isset($yStat[$xLabel]) ? $yStat[$xLabel] : 0;
}
}
$optionList = $this->getSysOptions($fields[$group]['type'], $fields[$group]['object'], $fields[$group]['field']);
foreach($xLabels as $index => $xLabel) $xLabels[$index] = isset($optionList[$xLabel]) ? $optionList[$xLabel] : $xLabel;
$xaxis = array('type' => 'category', 'data' => $xLabels);
$yaxis = array('type' => 'value');
$legend = new stdclass();
$series = array();
$clientLang = $this->app->getClientLang();
foreach($yDatas as $index => $yData)
{
$fieldName = $fields[$metrics[$index]]['name'];
if(!empty($fields[$metrics[$index]]['object']) and !empty($fields[$metrics[$index]]['field']))
{
$relatedObject = $fields[$metrics[$index]]['object'];
$relatedField = $fields[$metrics[$index]]['field'];
$this->app->loadLang($relatedObject);
$fieldName = isset($this->lang->$relatedObject->$relatedField) ? $this->lang->$relatedObject->$relatedField : $fieldName;
}
if(isset($langs[$metrics[$index]]) and !empty($langs[$metrics[$index]][$clientLang])) $fieldName = $langs[$metrics[$index]][$clientLang];
$seriesName = $fieldName . '(' . $this->lang->chart->aggList[$aggs[$index]] . ')';
$series[] = array('name' => $seriesName, 'data' => $yData, 'type' => 'line');
}
$options = array('series' => $series, 'legend' => $legend, 'xAxis' => $xaxis, 'yAxis' => $yaxis, 'tooltip' => array('trigger' => 'axis'));
return $options;
}
/**
* Gen cluBar.
*
* @param int $fields
* @param int $settings
* @param int $defaultSql
* @param int $filters
* @param int $stack
* @param array $langs
* @access public
* @return void
*/
public function genCluBar($fields, $settings, $defaultSql, $filters, $stack = '', $langs = array())
{
list($group, $metrics, $aggs, $xLabels, $yStats) = $this->getMultiData($settings, $defaultSql, $filters);
$yDatas = array();
foreach($yStats as $yStat)
{
$data = array();
foreach($xLabels as $xLabel)
{
$data[] = isset($yStat[$xLabel]) ? $yStat[$xLabel] : 0;
}
$yDatas[] = $data;
}
$optionList = $this->getSysOptions($fields[$group]['type'], $fields[$group]['object'], $fields[$group]['field']);
foreach($xLabels as $index => $xLabel) $xLabels[$index] = isset($optionList[$xLabel]) ? $optionList[$xLabel] : $xLabel;
$xaxis = array('type' => 'category', 'data' => $xLabels, 'axisLabel' => array('interval' => 0));
$yaxis = array('type' => 'value');
$legend = new stdclass();
/* Cluster bar X graphs and cluster bar Y graphs are really just x and y axes switched, so cluster bar Y $xaixs and $yaxis are swapped so that the method can be reused. */
/* 簇状柱形图和簇状条形图其实只是x轴和y轴换了换,所以交换一下簇状条形图 xAxis和yAxis即可,这样方法就可以复用了。*/
if(in_array($settings['type'], array('cluBarY', 'stackedBarY'))) list($xaxis, $yaxis) = array($yaxis, $xaxis);
$series = array();
$clientLang = $this->app->getClientLang();
foreach($yDatas as $index => $yData)
{
$fieldName = $fields[$metrics[$index]]['name'];
if(!empty($fields[$metrics[$index]]['object']) and !empty($fields[$metrics[$index]]['field']))
{
$relatedObject = $fields[$metrics[$index]]['object'];
$relatedField = $fields[$metrics[$index]]['field'];
$this->app->loadLang($relatedObject);
$fieldName = isset($this->lang->$relatedObject->$relatedField) ? $this->lang->$relatedObject->$relatedField : $fieldName;
}
if(isset($langs[$metrics[$index]]) and !empty($langs[$metrics[$index]][$clientLang])) $fieldName = $langs[$metrics[$index]][$clientLang];
$seriesName = $fieldName . '(' . $this->lang->chart->aggList[$aggs[$index]] . ')';
$series[] = array('name' => $seriesName, 'data' => $yData, 'type' => 'bar', 'stack' => $stack);
}
$options = array('series' => $series, 'legend' => $legend, 'xAxis' => $xaxis, 'yAxis' => $yaxis, 'tooltip' => array('trigger' => 'axis'));
return $options;
}
/**
* Get multi data.
*
* @param int $settings
* @param int $defaultSql
* @param int $filters
* @access public
* @return void
*/
public function getMultiData($settings, $defaultSql, $filters, $sort = false)
{
$group = isset($settings['xaxis'][0]['field']) ? $settings['xaxis'][0]['field'] : '';
$date = isset($settings['xaxis'][0]['group']) ? zget($this->config->chart->dateConvert, $settings['xaxis'][0]['group']) : '';
$metrics = array();
$aggs = array();
foreach($settings['yaxis'] as $yaxis)
{
$metrics[] = $yaxis['field'];
$aggs[] = $yaxis['valOrAgg'];
}
$yCount = count($metrics);
$xLabels = array();
$yStats = array();
for($i = 0; $i < $yCount; $i ++)
{
$metric = $metrics[$i];
$agg = $aggs[$i];
$groupSql = $groupBySql = "tt.`$group`";
if(!empty($date))
{
$groupSql = $date == 'MONTH' ? "YEAR(tt.`$group`) as ttyear, $date(tt.`$group`) as ttgroup" : "$date(tt.`$group`) as $group";
$groupBySql = $date == 'MONTH' ? "YEAR(tt.`$group`), $date(tt.`$group`)" : "$date(tt.`$group`)";
}
if($agg == 'distinct')
{
$aggSQL = "count($agg tt.`$metric`) as `$metric`";
}
else
{
$aggSQL = "$agg(tt.`$metric`) as `$metric`";
}
$sql = "select $groupSql,$aggSQL from ($defaultSql) tt";
if(!empty($filters))
{
$wheres = array();
foreach($filters as $field => $filter)
{
$wheres[] = "$field {$filter['operator']} {$filter['value']}";
}
$whereStr = implode(' and ', $wheres);
$sql .= " where $whereStr";
}
$sql .= " group by $groupBySql";
$rows = $this->dao->query($sql)->fetchAll();
$stat = $this->processRows($rows, $date, $group, $metric);
$maxCount = 50;
if($sort) arsort($stat);
$yStats[] = $stat;
$xLabels = array_merge($xLabels, array_keys($stat));
$xLabels = array_unique($xLabels);
}
return array($group, $metrics, $aggs, $xLabels, $yStats);
}
/**
* Adjust the action is clickable.
*
* @param object $chart
* @param string $action
* @static
* @access public
* @return bool
*/
public static function isClickable($chart, $action)
{
return true;
}
/**
* Get sys options.
*
* @param string $type
* @access public
* @return array
*/
public function getSysOptions($type, $object = '', $field = '', $sql = '')
{
$options = array('' => '');
switch($type)
{
case 'user':
$options = $this->loadModel('user')->getPairs();
break;
case 'product':
$options = $this->loadModel('product')->getPairs();
break;
case 'project':
$options = $this->loadModel('project')->getPairsByProgram();
break;
case 'execution':
$options = $this->loadModel('execution')->getPairs();
break;
case 'dept':
$options = $this->loadModel('dept')->getOptionMenu(0);
break;
case 'option':
if($field)
{
$path = $this->app->getModuleRoot() . 'dataview' . DS . 'table' . DS . "$object.php";
include $path;
$options = $schema->fields[$field]['options'];
}
break;
case 'object':
if($field)
{
$table = zget($this->config->objectTables, $object);
$options = $this->dao->select("id, {$field}")->from($table)->fetchPairs();
}
break;
case 'string':
if($field and $sql)
{
$cols = $this->dbh->query($sql)->fetchAll();
foreach($cols as $col)
{
$data = $col->$field;
$options[$data] = $data;
}
}
break;
}
return $options;
}
}
+118
View File
@@ -0,0 +1,118 @@
<?php
/**
* The preview view file of chart module of ZenTaoPMS.
*
* @copyright Copyright 2009-2022 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Gang Liu <liugang@easycorp.ltd>
* @package chart
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include $app->getModuleRoot() . 'common/view/header.html.php';?>
<?php js::import($jsRoot . 'moment/moment.min.js');?>
<?php js::import($jsRoot . 'echarts/echarts.common.min.js');?>
<?php js::set('groupID', isset($group->id) ? $group->id : 0);?>
<?php js::set('charts', $charts);?>
<?php js::set('noChartSelected', $lang->chart->noChartSelected);?>
<?php js::set('chartLang', $lang->chart);?>
<?php js::set('WIDTH_INPUT', $config->chart->widthInput);?>
<?php js::set('WIDTH_DATE', $config->chart->widthDate);?>
<?php js::set('pickerHeight', $config->bi->pickerHeight);?>
<div id='mainMenu' class='clearfix main-position'>
<div class='btn-toolBar pull-left parent-position'>
<?php
foreach($groups as $groupID => $groupName)
{
if(!$groupID) continue;
$activeClass = $groupID == $group->id ? 'btn-active-text' : '';
echo html::a(inlink('preview', "dimensionID={$dimensionID}&groupID={$groupID}"), $groupName, '', "class='btn btn-link {$activeClass}' id='{$groupID}Tab'");
}
?>
</div>
<?php if($this->config->edition == 'biz' or $this->config->edition == 'max'):?>
<div class='btn-toolbar pull-right child-position'>
<?php common::printLink('chart', 'exportChart', '', "<i class='icon icon-export muted'> </i> " . $lang->export, '', "class='btn btn-link btn-export' id='exportchart'");?>
<?php common::printLink('chart', 'browse', '', $lang->chart->toDesign, '', "class='btn btn-primary '");?>
</div>
<?php endif;?>
</div>
<div id="mainContent" class='main-row'>
<div class='side-col col-lg'>
<div class='panel'>
<div class='panel-heading'>
<div class='panel-title'><?php echo isset($group->name) ? $group->name : '';?></div>
</div>
<div class='panel-body'>
<?php if(!$chartTree):?>
<hr class="space">
<div class="text-center text-muted">
<?php echo $lang->chart->noChart;?>
</div>
<hr class="space">
<?php elseif($chartTree):?>
<form method='post'>
<?php echo $chartTree;?>
<div class='btn-toolbar'>
<?php echo html::selectAll();?>
<?php echo html::submitButton($lang->chart->preview, '', 'btn btn-primary');?>
</div>
</form>
<?php endif;?>
<?php if($this->config->edition == 'open'):?>
<div class='text biz-version'>
<span class='text-important'><?php echo (!empty($config->isINT)) ? $lang->bizVersionINT : $lang->bizVersion;?></span>
</div>
<?php endif;?>
</div>
</div>
</div>
<div class='main-col'>
<div class='cell'>
<?php if(!$chartTree):?>
<hr class="space">
<div class="text-center text-muted">
<?php echo $lang->chart->noChart;?>
</div>
<hr class="space">
<?php else:?>
<div class='btn-toolbar pull-right'>
</div>
<?php foreach($charts as $chart):?>
<div class='panel'>
<div class='panel-heading'>
<div class='panel-title'>
<?php echo $chart->name;?>
<?php if(!empty($chart->desc)):?>
<a data-toggle='tooltip' data-placement='auto' title='<?php echo $chart->desc;?>'><i class='icon-help'></i></a>
<?php endif;?>
</div>
</div>
<div class='panel-body'>
<div id="filterItems<?php echo $chart->currentGroup;?><?php echo $chart->id;?>" class='filterBox'>
<div class='filter-items'></div>
<?php if(!empty($chart->filters)):?>
<div class='queryBtn'><?php echo html::submitButton($lang->chart->query, "data-chart={$chart->currentGroup}{$chart->id}", 'btn btn-primary btn-query');?></div>
<?php endif;?>
</div>
<div id="chartDraw<?php echo $chart->currentGroup;?><?php echo $chart->id;?>" data-group="<?php echo $chart->currentGroup;?>" data-id="<?php echo $chart->id;?>" class='echart-content'></div>
</div>
</div>
<?php endforeach;?>
<?php endif;?>
</div>
</div>
</div>
<?php include $app->getModuleRoot() . 'common/view/footer.html.php';?>
<template id='filterItemTpl'>
<div class='filter-item filter-item-{index}'>
<div class='input-group'>
<span class='input-group-addon field-name'>{name}</span>
{search}
</div>
</div>
</template>
+2
View File
@@ -44,6 +44,7 @@ $lang->user = new stdclass();
$lang->screen = new stdclass();
$lang->report = new stdclass();
$lang->pivot = new stdclass();
$lang->chart = new stdclass();
$lang->repo = new stdclass();
$lang->jenkins = new stdclass();
$lang->gitlab = new stdclass();
@@ -91,6 +92,7 @@ $lang->app = new stdclass();
$lang->zahost = new stdclass();
$lang->zanode = new stdclass();
$lang->holiday = new stdclass();
$lang->dimension = new stdclass();
$lang->projectbuild = new stdclass();
$lang->projectrelease = new stdclass();
+20 -12
View File
@@ -48,6 +48,8 @@ $lang->tutorialAB = 'Tutorial';
$lang->runInfo = "<div class='row'><div class='u-1 a-center' id='debugbar'>Time %s MS, Memory %s KB, Query %s. </div></div>";
$lang->agreement = "I have read and agreed to the terms and conditions of <a href='http://zpl.pub/page/zplv12.html' target='_blank'> Z PUBLIC LICENSE 1.2 </a>. <span class='text-danger'>Without authorization, I should not remove, hide or cover any logos/links of ZenTao.</span>";
$lang->designedByAIUX = "<a href='https://api.zentao.net/goto.php?item=aiux' class='link-aiux' target='_blank'><i class='icon icon-aiux'></i> AIUX</a>";
$lang->bizVersion = '<a href="https://www.zentao.net/page/enterprise.html" target="_blank">Testen Sie ZenTao Biz für mehr Informationen!</a>';
$lang->bizVersionINT = '<a href="https://www.zentao.pm/page/vs.html" etarget="_blank">Testen Sie ZenTao Biz für mehr Informationen!</a>';
$lang->reset = 'Zurücksetzen';
$lang->cancel = 'Abbrechen';
@@ -177,6 +179,7 @@ $lang->repo->codeRepo = 'Code Repo';
$lang->screen->common = 'Screen';
$lang->report->common = 'BI';
$lang->pivot->common = 'Pivot Table';
$lang->chart->common = 'Chart';
$lang->system->common = 'System';
$lang->admin->common = 'Admin';
$lang->story->common = 'Story';
@@ -219,6 +222,7 @@ $lang->app->serverLink = 'Server Link';
$lang->review->common = 'Review';
$lang->zahost->common = 'ZAhost';
$lang->zanode->common = 'ZAnode';
$lang->dimension->common = 'Dimension';
$lang->personnel->common = 'Member';
$lang->personnel->invest = 'Investment';
@@ -276,17 +280,22 @@ $lang->project->kanban = $lang->projectCommon . ' Kanban';
$lang->execution->executionKanban = "{$lang->execution->common} Kanban";
$lang->execution->all = "{$lang->execution->common} List";
$lang->doc->recent = 'Recent';
$lang->doc->my = 'My';
$lang->doc->favorite = 'Favorite';
$lang->doc->product = $lang->productCommon;
$lang->doc->project = $lang->projectCommon;
$lang->doc->api = 'API';
$lang->doc->execution = $lang->execution->common;
$lang->doc->custom = 'Custom';
$lang->doc->wiki = 'WIKI';
$lang->doc->apiDoc = 'API Docuemnt';
$lang->doc->apiStruct = 'Data Structure';
$lang->doc->recent = 'Recent';
$lang->doc->my = 'My';
$lang->doc->favorite = 'Favorite';
$lang->doc->product = $lang->productCommon;
$lang->doc->project = $lang->projectCommon;
$lang->doc->api = 'API';
$lang->doc->execution = $lang->execution->common;
$lang->doc->custom = 'Custom';
$lang->doc->wiki = 'WIKI';
$lang->doc->apiDoc = 'API Docuemnt';
$lang->doc->apiStruct = 'Data Structure';
$lang->doc->mySpace = 'My Space';
$lang->doc->productSpace = "{$lang->productCommon} Space";
$lang->doc->projectSpace = "{$lang->projectCommon} Space";
$lang->doc->apiSpace = 'API Space';
$lang->doc->teamSpace = 'Team Space';
$lang->product->list = $lang->productCommon . ' List';
$lang->product->kanban = $lang->productCommon . ' Kanban';
@@ -294,7 +303,6 @@ $lang->product->kanban = $lang->productCommon . ' Kanban';
$lang->project->report = 'Report';
$lang->report->weekly = 'Weekly';
$lang->report->annual = 'Annual Summary';
$lang->report->notice = new stdclass();
$lang->report->notice->help = 'Hinweis: Berichte wurde auf Basis der Suche generiert. Bitte suchen Sie in der Liste bevor Sie einen Bericht generieren.';
+20 -12
View File
@@ -48,6 +48,8 @@ $lang->tutorialAB = 'Tutorial';
$lang->runInfo = "<div class='row'><div class='u-1 a-center' id='debugbar'>Time %s MS, Memory %s KB, Query %s. </div></div>";
$lang->agreement = "I have read and agreed to the terms and conditions. <span class='text-danger'>Without authorization, I should not remove, hide or cover any logos/links of ZenTao.</span>";
$lang->designedByAIUX = "<a href='https://api.zentao.net/goto.php?item=aiux' class='link-aiux' target='_blank'><i class='icon icon-aiux'></i> AIUX</a>";
$lang->bizVersion = '<a href="https://www.zentao.net/page/enterprise.html" target="_blank">Try ZenTao Biz for more!</a>';
$lang->bizVersionINT = '<a href="https://www.zentao.pm/page/vs.html" target="_blank">Try ZenTao Biz for more!</a>';
$lang->reset = 'Reset';
$lang->cancel = 'Cancel';
@@ -177,6 +179,7 @@ $lang->repo->codeRepo = 'Code Repo';
$lang->screen->common = 'Screen';
$lang->report->common = 'BI';
$lang->pivot->common = 'Pivot Table';
$lang->chart->common = 'Chart';
$lang->system->common = 'System';
$lang->admin->common = 'Admin';
$lang->story->common = 'Story';
@@ -219,6 +222,7 @@ $lang->app->serverLink = 'Server Link';
$lang->review->common = 'Review';
$lang->zahost->common = 'ZAhost';
$lang->zanode->common = 'ZAnode';
$lang->dimension->common = 'Dimension';
$lang->personnel->common = 'Member';
$lang->personnel->invest = 'Investment';
@@ -276,17 +280,22 @@ $lang->project->kanban = $lang->projectCommon . ' Kanban';
$lang->execution->executionKanban = "{$lang->execution->common} Kanban";
$lang->execution->all = "{$lang->execution->common} List";
$lang->doc->recent = 'Recent';
$lang->doc->my = 'My';
$lang->doc->favorite = 'Favorite';
$lang->doc->product = $lang->productCommon;
$lang->doc->project = $lang->projectCommon;
$lang->doc->api = 'API';
$lang->doc->execution = $lang->execution->common;
$lang->doc->custom = 'Custom';
$lang->doc->wiki = 'WIKI';
$lang->doc->apiDoc = 'API Docuemnt';
$lang->doc->apiStruct = 'Data Structure';
$lang->doc->recent = 'Recent';
$lang->doc->my = 'My';
$lang->doc->favorite = 'Favorite';
$lang->doc->product = $lang->productCommon;
$lang->doc->project = $lang->projectCommon;
$lang->doc->api = 'API';
$lang->doc->execution = $lang->execution->common;
$lang->doc->custom = 'Custom';
$lang->doc->wiki = 'WIKI';
$lang->doc->apiDoc = 'API Docuemnt';
$lang->doc->apiStruct = 'Data Structure';
$lang->doc->mySpace = 'My Space';
$lang->doc->productSpace = "{$lang->productCommon} Space";
$lang->doc->projectSpace = "{$lang->projectCommon} Space";
$lang->doc->apiSpace = 'API Space';
$lang->doc->teamSpace = 'Team Space';
$lang->product->list = $lang->productCommon . ' List';
$lang->product->kanban = $lang->productCommon . ' Kanban';
@@ -294,7 +303,6 @@ $lang->product->kanban = $lang->productCommon . ' Kanban';
$lang->project->report = 'Report';
$lang->report->weekly = 'Weekly';
$lang->report->annual = 'Annual Summary';
$lang->report->notice = new stdclass();
$lang->report->notice->help = 'Note: The report is generated on the results of browsing the list. Click, e.g. AssignedToMe, then click Create Report to generate a report based on AssignedToMe list.';
+20 -12
View File
@@ -48,6 +48,8 @@ $lang->tutorialAB = 'Tutorial';
$lang->runInfo = "<div class='row'><div class='u-1 a-center' id='debugbar'>Time %s MS, Memory %s KB, Query %s. </div></div>";
$lang->agreement = "J'ai lu et j'accepte les termes et conditions de la <a href='http://zpl.pub/page/zplv12.html' target='_blank'> Z PUBLIC LICENSE 1.2 </a>. <span class='text-danger'>Sans autorisation, je ne dois pas supprimer, masquer ou couvrir les logos / liens de ZenTao.</span>";
$lang->designedByAIUX = "<a href='https://api.zentao.net/goto.php?item=aiux' class='link-aiux' target='_blank'><i class='icon icon-aiux'></i> AIUX</a>";
$lang->bizVersion = '<a href="https://www.zentao.net/page/enterprise.html" target="_blank">Essayez ZenTao Biz pour en savoir plus!</a>';
$lang->bizVersionINT = '<a href="https://www.zentao.pm/page/vs.html" target="_blank">Essayez ZenTao Biz pour en savoir plus!</a>';
$lang->reset = 'Réinitialiser';
$lang->cancel = 'Annuler';
@@ -177,6 +179,7 @@ $lang->repo->codeRepo = 'Code Repo';
$lang->screen->common = 'Screen';
$lang->report->common = 'BI';
$lang->pivot->common = 'Pivot Table';
$lang->chart->common = 'Chart';
$lang->system->common = 'System';
$lang->admin->common = 'Admin';
$lang->story->common = 'Story';
@@ -219,6 +222,7 @@ $lang->app->serverLink = 'Server Link';
$lang->review->common = 'Review';
$lang->zahost->common = 'ZAhost';
$lang->zanode->common = 'ZAnode';
$lang->dimension->common = 'Dimension';
$lang->personnel->common = 'Member';
$lang->personnel->invest = 'Investment';
@@ -276,17 +280,22 @@ $lang->project->kanban = $lang->projectCommon . ' Kanban';
$lang->execution->executionKanban = "{$lang->execution->common} Kanban";
$lang->execution->all = "{$lang->execution->common} List";
$lang->doc->recent = 'Recent';
$lang->doc->my = 'My';
$lang->doc->favorite = 'Favorite';
$lang->doc->product = $lang->productCommon;
$lang->doc->project = $lang->projectCommon;
$lang->doc->api = 'API';
$lang->doc->execution = $lang->execution->common;
$lang->doc->custom = 'Custom';
$lang->doc->wiki = 'WIKI';
$lang->doc->apiDoc = 'API Docuemnt';
$lang->doc->apiStruct = 'Data Structure';
$lang->doc->recent = 'Recent';
$lang->doc->my = 'My';
$lang->doc->favorite = 'Favorite';
$lang->doc->product = $lang->productCommon;
$lang->doc->project = $lang->projectCommon;
$lang->doc->api = 'API';
$lang->doc->execution = $lang->execution->common;
$lang->doc->custom = 'Custom';
$lang->doc->wiki = 'WIKI';
$lang->doc->apiDoc = 'API Docuemnt';
$lang->doc->apiStruct = 'Data Structure';
$lang->doc->mySpace = 'My Space';
$lang->doc->productSpace = "{$lang->productCommon} Space";
$lang->doc->projectSpace = "{$lang->projectCommon} Space";
$lang->doc->apiSpace = 'API Space';
$lang->doc->teamSpace = 'Team Space';
$lang->product->list = $lang->productCommon . ' List';
$lang->product->kanban = $lang->productCommon . ' Kanban';
@@ -294,7 +303,6 @@ $lang->product->kanban = $lang->productCommon . ' Kanban';
$lang->project->report = 'Report';
$lang->report->weekly = 'Weekly';
$lang->report->annual = 'Annual Summary';
$lang->report->notice = new stdclass();
$lang->report->notice->help = 'Note : Le rapport est généré à partir des résultats de la liste consultée. Par exemple, cliquez sur AssignedToMe, puis Générer Rapport pour obtenir un rapport basé sur la liste de ce qui vous est assigné.';
+17 -37
View File
@@ -48,7 +48,7 @@ $lang->mainNav->admin = "{$lang->navIcons['admin']} {$lang->admin->common}|a
$lang->dividerMenu = ',kanban,oa,admin,';
$lang->mainNav->menuOrder[5] = 'my';
$lang->mainNav->menuOrder[5] = 'my';
$lang->mainNav->menuOrder[10] = 'program';
$lang->mainNav->menuOrder[15] = 'product';
$lang->mainNav->menuOrder[20] = 'project';
@@ -168,7 +168,7 @@ $lang->product->menu->release = array('link' => "{$lang->release->common}|re
$lang->product->menu->roadmap = array('link' => "{$lang->roadmap}|product|roadmap|productID=%s");
$lang->product->menu->requirement = array('link' => "{$lang->URCommon}|product|browse|productID=%s&branch=&browseType=unclosed&param=0&storyType=requirement", 'alias' => 'batchedit', 'subModule' => 'story');
$lang->product->menu->track = array('link' => "{$lang->track}|product|track|productID=%s");
$lang->product->menu->doc = array('link' => "{$lang->doc->common}|doc|tableContents|type=product&objectID=%s", 'subModule' => 'doc');
$lang->product->menu->doc = array('link' => "{$lang->doc->common}|doc|productSpace|objectID=%s", 'subModule' => 'doc,api');
$lang->product->menu->dynamic = array('link' => "{$lang->dynamic}|product|dynamic|productID=%s");
$lang->product->menu->settings = array('link' => "{$lang->settings}|product|view|productID=%s", 'subModule' => 'tree,branch', 'alias' => 'edit,whitelist,addwhitelist');
@@ -187,8 +187,6 @@ $lang->product->menuOrder[55] = 'settings';
$lang->product->menuOrder[60] = 'create';
$lang->product->menuOrder[65] = 'all';
$lang->product->menu->doc['subMenu'] = new stdclass();
$lang->product->menu->settings['subMenu'] = new stdclass();
$lang->product->menu->settings['subMenu']->view = array('link' => "{$lang->overview}|product|view|productID=%s", 'alias' => 'edit');
$lang->product->menu->settings['subMenu']->module = array('link' => "{$lang->module}|tree|browse|product=%s&view=story", 'subModule' => 'tree');
@@ -209,7 +207,7 @@ $lang->scrum->menu->execution = array('link' => "$lang->executionCommon|projec
$lang->scrum->menu->storyGroup = array('link' => "{$lang->common->story}|projectstory|story|projectID=%s&product=%s",'class' => 'dropdown dropdown-hover', 'exclude' => 'tree-browse');
$lang->scrum->menu->story = array('link' => "$lang->SRCommon|projectstory|story|projectID=%s", 'subModule' => 'projectstory,tree', 'alias' => 'story,track');
$lang->scrum->menu->projectplan = array('link' => "{$lang->productplan->shortCommon}|projectplan|browse|productID=%s", 'subModule' => 'productplan');
$lang->scrum->menu->doc = array('link' => "{$lang->doc->common}|doc|tableContents|type=project&objectID=%s", 'subModule' => 'doc');
$lang->scrum->menu->doc = array('link' => "{$lang->doc->common}|doc|projectSpace|objectID=%s", 'subModule' => 'doc,api');
$lang->scrum->menu->qa = array('link' => "{$lang->qa->common}|project|bug|projectID=%s", 'subModule' => 'testcase,testtask,bug,testreport', 'alias' => 'bug,testtask,testcase,testreport', 'exclude' => 'execution-create,execution-batchedit');
$lang->scrum->menu->devops = array('link' => "{$lang->repo->common}|repo|browse|repoID=0&branchID=&objectID=%s", 'subModule' => 'repo');
$lang->scrum->menu->build = array('link' => "{$lang->build->common}|project|build|project=%s", 'subModule' => 'projectbuild');
@@ -237,8 +235,6 @@ $lang->scrum->menuOrder[40] = 'release';
$lang->scrum->menuOrder[45] = 'dynamic';
$lang->scrum->menuOrder[55] = 'settings';
$lang->scrum->menu->doc['subMenu'] = new stdclass();
$lang->scrum->menu->qa['subMenu'] = new stdclass();
//$lang->scrum->menu->qa['subMenu']->index = array('link' => "$lang->dashboard|project|qa|projectID=%s");
$lang->scrum->menu->qa['subMenu']->bug = array('link' => "{$lang->bug->common}|project|bug|projectID=%s", 'subModule' => 'bug');
@@ -264,7 +260,7 @@ $lang->waterfall->menu->storyGroup = array('link' => "{$lang->common->story}|pro
$lang->waterfall->menu->story = array('link' => "$lang->SRCommon|projectstory|story|projectID=%s", 'subModule' => 'projectstory,tree', 'alias' => 'story', 'exclude' => 'projectstory-track');
$lang->waterfall->menu->design = array('link' => "{$lang->design->common}|design|browse|project=%s");
$lang->waterfall->menu->qa = array('link' => "{$lang->qa->common}|project|bug|projectID=%s", 'subModule' => 'testcase,testtask,bug,testreport', 'alias' => 'bug,testtask,testcase,testreport');
$lang->waterfall->menu->doc = array('link' => "{$lang->doc->common}|doc|tableContents|type=project&objectID=%s");
$lang->waterfall->menu->doc = array('link' => "{$lang->doc->common}|doc|projectSpace|objectID=%s");
$lang->waterfall->menu->devops = array('link' => "{$lang->repo->common}|repo|browse|repoID=0&branchID=&objectID=%s", 'subModule' => 'repo');
$lang->waterfall->menu->build = array('link' => "{$lang->build->common}|project|build|project=%s", 'subModule' => 'projectbuild');
$lang->waterfall->menu->release = array('link' => "{$lang->release->common}|projectrelease|browse|project=%s", 'subModule' => 'projectrelease');
@@ -289,8 +285,6 @@ $lang->waterfall->menuOrder[65] = 'build';
$lang->waterfall->menuOrder[70] = 'release';
$lang->waterfall->menuOrder[80] = 'dynamic';
$lang->waterfall->menu->doc['subMenu'] = new stdclass();
$lang->waterfall->menu->programplan['subMenu'] = new stdclass();
$lang->waterfall->menu->programplan['subMenu']->lists = array('link' => "{$lang->stage->list}|programplan|browse|projectID=%s&productID=0&type=lists", 'alias' => 'create');
@@ -372,8 +366,6 @@ $lang->execution->menuOrder[60] = 'release';
$lang->execution->menuOrder[65] = 'action';
$lang->execution->menuOrder[70] = 'settings';
$lang->execution->menu->doc['subMenu'] = new stdclass();
$lang->execution->menu->view['subMenu'] = new stdclass();
$lang->execution->menu->view['subMenu']->groupTask = "$lang->groupView|execution|grouptask|executionID=%s";
$lang->execution->menu->view['subMenu']->tree = "$lang->treeView|execution|tree|executionID=%s";
@@ -507,45 +499,32 @@ $lang->kanban->menu = new stdclass();
/* Doc menu. */
$lang->doc->menu = new stdclass();
$lang->doc->menu->dashboard = array('link' => "{$lang->dashboard}|doc|index");
$lang->doc->menu->recent = array('link' => "{$lang->doc->recent}|doc|browse|browseTyp=byediteddate", 'alias' => 'recent');
$lang->doc->menu->my = array('link' => "{$lang->doc->my}|doc|browse|browseTyp=openedbyme", 'alias' => 'my');
$lang->doc->menu->collect = array('link' => "{$lang->doc->favorite}|doc|browse|browseTyp=collectedbyme", 'alias' => 'collect');
$lang->doc->menu->product = array('link' => "{$lang->doc->product}|doc|tableContents|type=product", 'alias' => 'showfiles,product');
$lang->doc->menu->api = array('link' => "{$lang->doc->api}|api|index", 'alias' => 'api');
$lang->doc->menu->project = array('link' => "{$lang->doc->project}|doc|tableContents|type=project", 'alias' => 'showfiles,project');
$lang->doc->menu->execution = array('link' => "{$lang->doc->execution}|doc|tableContents|type=execution", 'alias' => 'showfiles,execution');
$lang->doc->menu->custom = array('link' => "{$lang->doc->custom}|doc|tableContents|type=custom", 'alias' => 'custom');
$lang->doc->menu->my = array('link' => "{$lang->doc->mySpace}|doc|mySpace|type=mine", 'alias' => 'myspace');
$lang->doc->menu->product = array('link' => "{$lang->doc->productSpace}|doc|productSpace|", 'alias' => 'productspace');
$lang->doc->menu->project = array('link' => "{$lang->doc->projectSpace}|doc|projectSpace|", 'alias' => 'projectspace');
$lang->doc->menu->api = array('link' => "{$lang->doc->apiSpace}|api|index", 'alias' => 'api');
$lang->doc->menu->custom = array('link' => "{$lang->doc->teamSpace}|doc|tableContents|type=custom", 'alias' => 'tablecontents');
$lang->doc->dividerMenu = ',product,';
/* Doc menu order. */
$lang->doc->menuOrder[5] = 'dashboard';
$lang->doc->menuOrder[10] = 'recent';
$lang->doc->menuOrder[15] = 'my';
$lang->doc->menuOrder[20] = 'collect';
$lang->doc->menuOrder[25] = 'product';
$lang->doc->menuOrder[30] = 'project';
$lang->doc->menuOrder[35] = 'execution';
$lang->doc->menuOrder[36] = 'api';
$lang->doc->menuOrder[40] = 'custom';
$lang->doc->menu->product['subMenu'] = new stdclass();
$lang->doc->menu->project['subMenu'] = new stdclass();
$lang->doc->menu->execution['subMenu'] = new stdclass();
$lang->doc->menu->custom['subMenu'] = new stdclass();
$lang->doc->menu->api['subMenu'] = new stdclass();
$lang->doc->menu->api['subMenu']->index = array('link' => "{$lang->doc->apiDoc}|api|index|libID=%s", 'alias' => 'create,edit');
$lang->doc->menu->api['subMenu']->struct = array('link' => "{$lang->doc->apiStruct}|api|struct|libID=%s", 'alias' => 'createstruct,editstruct');
$lang->doc->menuOrder[10] = 'my';
$lang->doc->menuOrder[15] = 'product';
$lang->doc->menuOrder[20] = 'project';
$lang->doc->menuOrder[25] = 'api';
$lang->doc->menuOrder[30] = 'custom';
/* Report menu.*/
$lang->report->menu = new stdclass();
$lang->report->menu->screen = array('link' => "{$lang->screen->common}|screen|browse");
$lang->report->menu->pivot = array('link' => "{$lang->pivot->common}|pivot|preview");
$lang->report->menu->chart = array('link' => "{$lang->chart->common}|chart|preview");
/* Report menu order. */
$lang->report->menuOrder[5] = 'screen';
$lang->report->menuOrder[10] = 'pivot';
$lang->report->menuOrder[15] = 'chart';
/* Company menu.*/
$lang->company->menu = new stdclass();
@@ -634,6 +613,7 @@ $lang->navGroup->api = 'doc';
$lang->navGroup->screen = 'report';
$lang->navGroup->pivot = 'report';
$lang->navGroup->chart = 'report';
$lang->navGroup->qa = 'qa';
$lang->navGroup->bug = 'qa';
+20 -12
View File
@@ -48,6 +48,8 @@ $lang->tutorialAB = '新手引导';
$lang->runInfo = "<div class='row'><div class='u-1 a-center' id='debugbar'>时间: %s 毫秒, 内存: %s KB, 查询: %s. </div></div>";
$lang->agreement = "已阅读并同意。<span class='text-danger'>未经许可,不得去除、隐藏或遮掩禅道软件的任何标志及链接。</span>";
$lang->designedByAIUX = "<a href='https://api.zentao.net/goto.php?item=aiux' class='link-aiux' target='_blank'><i class='icon icon-aiux'></i> 艾体验设计</a>";
$lang->bizVersion = '<a href="https://www.zentao.net/page/enterprise.html" target="_blank">更多精彩,尽在企业版!</a>';
$lang->bizVersionINT = '<a href="https://www.zentao.pm/page/vs.html" target="_blank">更多精彩,尽在企业版!</a>';
$lang->reset = '重填';
$lang->cancel = '取消';
@@ -177,6 +179,7 @@ $lang->repo->codeRepo = '代码库';
$lang->screen->common = '大屏';
$lang->report->common = 'BI';
$lang->pivot->common = '透视表';
$lang->chart->common = '图表';
$lang->system->common = '组织';
$lang->admin->common = '后台';
$lang->story->common = $lang->SRCommon;
@@ -219,6 +222,7 @@ $lang->app->serverLink = '服务器链接';
$lang->review->common = '审批';
$lang->zahost->common = '宿主机';
$lang->zanode->common = '执行节点';
$lang->dimension->common = '维度';
$lang->personnel->common = '人员';
$lang->personnel->invest = '投入人员';
@@ -276,17 +280,22 @@ $lang->project->kanban = $lang->projectCommon . '看板';
$lang->execution->executionKanban = "{$lang->execution->common}看板";
$lang->execution->all = "{$lang->execution->common}列表";
$lang->doc->recent = '最近文档';
$lang->doc->my = '我的文档';
$lang->doc->favorite = '我的收藏';
$lang->doc->product = $lang->productCommon . '库';
$lang->doc->project = $lang->projectCommon . '库';
$lang->doc->api = '接口库';
$lang->doc->execution = "{$lang->execution->common}库";
$lang->doc->custom = '自定义库';
$lang->doc->wiki = 'WIKI';
$lang->doc->apiDoc = '文档';
$lang->doc->apiStruct = '数据结构';
$lang->doc->recent = '最近文档';
$lang->doc->my = '我的文档';
$lang->doc->favorite = '我的收藏';
$lang->doc->product = $lang->productCommon . '库';
$lang->doc->project = $lang->projectCommon . '库';
$lang->doc->api = '接口库';
$lang->doc->execution = "{$lang->execution->common}库";
$lang->doc->custom = '自定义库';
$lang->doc->wiki = 'WIKI';
$lang->doc->apiDoc = '文档';
$lang->doc->apiStruct = '数据结构';
$lang->doc->mySpace = '我的空间';
$lang->doc->productSpace = "{$lang->productCommon}空间";
$lang->doc->projectSpace = "{$lang->projectCommon}空间";
$lang->doc->apiSpace = '接口空间';
$lang->doc->teamSpace = '团队空间';
$lang->product->list = $lang->productCommon . '列表';
$lang->product->kanban = $lang->productCommon . '看板';
@@ -294,7 +303,6 @@ $lang->product->kanban = $lang->productCommon . '看板';
$lang->project->report = '报告';
$lang->report->weekly = '周报';
$lang->report->annual = '年度总结';
$lang->report->notice = new stdclass();
$lang->report->notice->help = '注:统计报表的数据来源于列表页面的检索结果,生成统计报表前请先在列表页面进行检索。比如列表页面我们检索的是%tab%,那么报表就是基于之前检索的%tab%的结果集进行统计。';
+1 -2
View File
@@ -153,7 +153,7 @@ $lang->devops->common = 'DevOps';
$lang->doc->common = '文檔';
$lang->repo->common = '代碼';
$lang->repo->codeRepo = '代碼庫';
$lang->report->common = '統計';
$lang->report->common = 'BI';
$lang->system->common = '組織';
$lang->admin->common = '後台';
$lang->task->common = '任務';
@@ -258,7 +258,6 @@ $lang->product->kanban = $lang->productCommon . '看板';
$lang->project->report = '報告';
$lang->report->weekly = '周報';
$lang->report->annual = '年度總結';
$lang->report->notice = new stdclass();
$lang->report->notice->help = '註:統計報表的數據來源於列表頁面的檢索結果,生成統計報表前請先在列表頁面進行檢索。比如列表頁面我們檢索的是%tab%,那麼報表就是基于之前檢索的%tab%的結果集進行統計。';
+106 -90
View File
@@ -596,7 +596,6 @@ class commonModel extends model
if($config->systemMode == 'light') unset($lang->createIcons['program']);
/* Check whether the creation permission is available, and print create buttons. */
foreach($lang->createIcons as $objectType => $objectIcon)
{
$createMethod = 'create';
@@ -605,102 +604,98 @@ class commonModel extends model
if($objectType == 'kanbanspace') $createMethod = 'createSpace';
if(strpos('|bug|execution|kanbanspace|', "|$objectType|") !== false) $needPrintDivider = true;
if(common::hasPriv($module, $createMethod))
$hasPriv = common::hasPriv($module, $createMethod);
if($hasPriv and $objectType == 'doc' and !common::hasPriv('doc', 'tableContents')) $hasPriv = false;
if(!$hasPriv and $objectType == 'doc' and common::hasPriv('api', 'create')) $hasPriv = true;
if(!$hasPriv) continue;
/* Determines whether to print a divider. */
if($needPrintDivider and $showCreateList)
{
if($objectType == 'doc' and !common::hasPriv('doc', 'tableContents')) continue;
$html .= '<li class="divider"></li>';
$needPrintDivider = false;
}
/* Determines whether to print a divider. */
if($needPrintDivider and $showCreateList)
{
$html .= '<li class="divider"></li>';
$needPrintDivider = false;
}
$showCreateList = true;
$isOnlyBody = false;
$attr = '';
$showCreateList = true;
$isOnlyBody = false;
$attr = '';
$params = '';
switch($objectType)
{
case 'doc':
$params = "objectType=&objectID=0&libID=0";
$createMethod = 'selectLibType';
$isOnlyBody = true;
$attr = "class='iframe' data-width='700px'";
break;
case 'project':
$params = '';
switch($objectType)
{
case 'doc':
$params = "objectType=&objectID=0&libID=0";
$createMethod = 'selectLibType';
$isOnlyBody = true;
$attr = "class='iframe' data-width='700px'";
break;
case 'project':
$params = "model=scrum&programID=0&copyProjectID=0&extra=from=global";
if($config->vision == 'lite')
{
$params = "model=kanban";
}
elseif(!defined('TUTORIAL'))
{
$params = "programID=0&from=global";
$createMethod = 'createGuide';
$attr = 'data-toggle="modal"';
}
break;
case 'bug':
$params = "productID=$productID&branch=&extras=from=global";
break;
case 'story':
if(!$productID and $config->vision == 'lite')
{
$module = 'project';
$params = "model=kanban";
}
else
{
$params = "productID=$productID&branch=0&moduleID=0&storyID=0&objectID=0&bugID=0&planID=0&todoID=0&extra=from=global";
if($config->vision == 'lite')
{
$params = "model=kanban";
}
else if(!defined('TUTORIAL'))
{
$params = "programID=0&from=global";
$createMethod = 'createGuide';
$attr = 'data-toggle="modal"';
}
else
{
$params = "model=scrum&programID=0&copyProjectID=0&extra=from=global";
}
$projectID = isset($_SESSION['project']) ? $_SESSION['project'] : 0;
$projects = $app->dbh->query("SELECT t2.id FROM " . TABLE_PROJECTPRODUCT . " AS t1 LEFT JOIN " . TABLE_PROJECT . " AS t2 ON t1.project = t2.id WHERE t1.`product` = '{$productID}' and t2.`type` = 'project' and t2.id " . helper::dbIN($app->user->view->projects) . " ORDER BY `order` desc")->fetchAll();
break;
case 'bug':
$params = "productID=$productID&branch=&extras=from=global";
break;
case 'story':
if(!$productID and $config->vision == 'lite')
{
$module = 'project';
$params = "model=kanban";
$projectIdList = array();
foreach($projects as $project) $projectIdList[$project->id] = $project->id;
if($projectID and !isset($projectIdList[$projectID])) $projectID = 0;
if(empty($projectID)) $projectID = key($projectIdList);
$params = "productID={$productID}&branch=0&moduleID=0&storyID=0&objectID={$projectID}&bugID=0&planID=0&todoID=0&extra=from=global";
}
else
{
$params = "productID=$productID&branch=0&moduleID=0&storyID=0&objectID=0&bugID=0&planID=0&todoID=0&extra=from=global";
if($config->vision == 'lite')
{
$projectID = isset($_SESSION['project']) ? $_SESSION['project'] : 0;
$projects = $app->dbh->query("SELECT t2.id FROM " . TABLE_PROJECTPRODUCT . " AS t1 LEFT JOIN " . TABLE_PROJECT . " AS t2 ON t1.project = t2.id WHERE t1.`product` = '{$productID}' and t2.`type` = 'project' and t2.id " . helper::dbIN($app->user->view->projects) . " ORDER BY `order` desc")->fetchAll();
}
$projectIdList = array();
foreach($projects as $project) $projectIdList[$project->id] = $project->id;
if($projectID and !isset($projectIdList[$projectID])) $projectID = 0;
if(empty($projectID)) $projectID = key($projectIdList);
$params = "productID={$productID}&branch=0&moduleID=0&storyID=0&objectID={$projectID}&bugID=0&planID=0&todoID=0&extra=from=global";
}
}
break;
case 'task':
$params = "executionID=0&storyID=0&moduleID=0&taskID=0&todoID=0&extra=from=global";
break;
case 'testcase':
$params = "productID=$productID&branch=&moduleID=0&from=&param=0&storyID=0&extras=from=global";
break;
case 'execution':
$projectID = isset($_SESSION['project']) ? $_SESSION['project'] : 0;
$params = "projectID={$projectID}&executionID=0&copyExecutionID=0&planID=0&confirm=no&productID=0&extra=from=global";
break;
case 'product':
$params = "programID=&extra=from=global";
break;
case 'program':
$params = "parentProgramID=0&extra=from=global";
break;
case 'kanbanspace':
$isOnlyBody = true;
$attr = "class='iframe' data-width='75%'";
break;
case 'kanban':
$isOnlyBody = true;
$attr = "class='iframe' data-width='75%'";
break;
}
$html .= '<li>' . html::a(helper::createLink($module, $createMethod, $params, '', $isOnlyBody), "<i class='icon icon-$objectIcon'></i> " . $lang->createObjects[$objectType], '', "$attr data-app=''") . '</li>';
break;
case 'task':
$params = "executionID=0&storyID=0&moduleID=0&taskID=0&todoID=0&extra=from=global";
break;
case 'testcase':
$params = "productID=$productID&branch=&moduleID=0&from=&param=0&storyID=0&extras=from=global";
break;
case 'execution':
$projectID = isset($_SESSION['project']) ? $_SESSION['project'] : 0;
$params = "projectID={$projectID}&executionID=0&copyExecutionID=0&planID=0&confirm=no&productID=0&extra=from=global";
break;
case 'product':
$params = "programID=&extra=from=global";
break;
case 'program':
$params = "parentProgramID=0&extra=from=global";
break;
case 'kanbanspace':
$isOnlyBody = true;
$attr = "class='iframe' data-width='75%'";
break;
case 'kanban':
$isOnlyBody = true;
$attr = "class='iframe' data-width='75%'";
break;
}
$html .= '<li>' . html::a(helper::createLink($module, $createMethod, $params, '', $isOnlyBody), "<i class='icon icon-$objectIcon'></i> " . $lang->createObjects[$objectType], '', "$attr data-app=''") . '</li>';
}
if(!$showCreateList) return '';
@@ -1054,6 +1049,27 @@ class commonModel extends model
}
}
/* Check whether the menu of this group have permissions. If yes, point to them. */
if($display == false and isset($lang->$group->menu))
{
foreach($lang->$group->menu as $menu)
{
if(!isset($menu['link'])) continue;
$linkPart = explode('|', $menu['link']);
if(count($linkPart) < 3) continue;
list($label, $module, $method) = $linkPart;
if(common::hasPriv($module, $method))
{
$display = true;
$currentModule = $module;
$currentMethod = $method;
if(!isset($menu['target'])) break; // Try to jump to the method without opening a new window.
}
}
}
if(!$display) continue;
/* Assign vars. */
@@ -1792,7 +1808,7 @@ EOF;
global $lang, $app;
$object = $app->dbh->query('SELECT project,type FROM ' . TABLE_EXECUTION . " WHERE `id` = '$executionID'")->fetch();
$object = $app->dbh->query('SELECT project,`type` FROM ' . TABLE_EXECUTION . " WHERE `id` = '$executionID'")->fetch();
if(empty($object)) return;
$executionPairs = array();
@@ -2376,7 +2392,7 @@ EOF;
*/
public function checkField($table, $field)
{
$fields = $this->dao->query("DESC $table")->fetchAll();
$fields = $this->dao->descTable($table);
$hasField = false;
foreach($fields as $fieldObj)
{
+5 -1
View File
@@ -35,6 +35,10 @@ class cronModel extends model
return $this->dao->select('*')->from(TABLE_CRON)
->where('1=1')
->beginIF(strpos($params, 'nostop') !== false)->andWhere('status')->ne('stop')->fi()
->beginIF($this->config->edition != 'max')
->andWhere('command')->ne('moduleName=measurement&methodName=initCrontabQueue')
->andWhere('command')->ne('moduleName=measurement&methodName=execCrontabQueue')
->fi()
->fetchAll('id');
}
@@ -138,7 +142,7 @@ class cronModel extends model
public function getLastTime()
{
$cron = $this->dao->select('*')->from(TABLE_CRON)->orderBy('lastTime desc')->limit(1)->fetch();
return isset($cron->lastTime) ? $cron->lastTime : $cron->lasttime;
return isset($cron->lastTime) ? $cron->lastTime : '0000-00-00 00:00:00';
}
/**
+1
View File
@@ -285,6 +285,7 @@ class customModel extends model
foreach($item['subMenu'] as $subMenu)
{
if(!isset($subMenu['link']) or strpos($subMenu['link'], '|') === false) continue;
if(strpos("|program|product|project|execution|qa|", "|{$app->tab}|") === false and strpos($subMenu['link'], '%s') !== false) continue;
list($subLabel, $module, $method) = explode('|', $subMenu['link']);
if(count(explode('|', $subMenu['link'])) > 3) list($subLabel, $module, $method, $vars) = explode('|', $subMenu['link']);
+3
View File
@@ -0,0 +1,3 @@
<?php
$lang->dataview->id = 'ID';
$lang->dataview->name = 'Name';
+3
View File
@@ -0,0 +1,3 @@
<?php
$lang->dataview->id = 'ID';
$lang->dataview->name = 'Name';
+3
View File
@@ -0,0 +1,3 @@
<?php
$lang->dataview->id = 'ID';
$lang->dataview->name = 'Name';
+3
View File
@@ -0,0 +1,3 @@
<?php
$lang->dataview->id = '编号';
$lang->dataview->name = '名称';
+63
View File
@@ -0,0 +1,63 @@
<?php
$this->app->loadLang('bug');
$this->app->loadLang('product');
$this->app->loadLang('story');
$this->app->loadLang('project');
$this->app->loadLang('tree');
$schema = new stdclass();
$schema->primaryTable = 'bug';
$schema->tables = array();
$schema->tables['bug'] = 'zt_bug';
$schema->tables['product'] = 'zt_product';
$schema->tables['story'] = 'zt_story';
$schema->tables['productline'] = 'zt_module';
$schema->tables['program'] = 'zt_project';
$schema->tables['project'] = 'zt_project';
$schema->tables['bugmodule'] = 'zt_module';
$schema->joins = array();
$schema->joins['product'] = 'product.id = bug.product';
$schema->joins['story'] = 'story.id = bug.story';
$schema->joins['productline'] = 'productline.id = product.line';
$schema->joins['program'] = 'program.id = product.program';
$schema->joins['project'] = 'project.id = bug.project';
$schema->joins['bugmodule'] = 'bugmodule.id = bug.module';
$schema->fields = array();
$schema->fields['id'] = array('type' => 'number', 'name' => $this->lang->bug->id);
$schema->fields['title'] = array('type' => 'string', 'name' => $this->lang->bug->title);
$schema->fields['steps'] = array('type' => 'text', 'name' => $this->lang->bug->steps);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->bug->status, 'options' => $this->lang->bug->statusList);
$schema->fields['confirmed'] = array('type' => 'option', 'name' => $this->lang->bug->confirmed, 'options' => $this->lang->bug->confirmedList);
$schema->fields['severity'] = array('type' => 'option', 'name' => $this->lang->bug->severity, 'options' => $this->lang->bug->severityList);
$schema->fields['product'] = array('type' => 'object', 'name' => $this->lang->bug->product, 'object' => 'product', 'show' => 'product.name');
$schema->fields['project'] = array('type' => 'object', 'name' => $this->lang->bug->project, 'object' => 'project', 'show' => 'project.name');
$schema->fields['bugmodule'] = array('type' => 'object', 'name' => $this->lang->bug->module, 'object' => 'bugmodule', 'show' => 'bugmodule.name');
$schema->fields['story'] = array('type' => 'object', 'name' => $this->lang->story->common, 'object' => 'story', 'show' => 'story.title');
$schema->fields['pri'] = array('type' => 'option', 'name' => $this->lang->bug->pri, 'options' => $this->lang->bug->priList);
$schema->fields['openedBy'] = array('type' => 'user', 'name' => $this->lang->bug->openedBy);
$schema->fields['openedDate'] = array('type' => 'date', 'name' => $this->lang->bug->openedDate);
$schema->fields['resolvedBy'] = array('type' => 'user', 'name' => $this->lang->bug->resolvedBy);
$schema->fields['resolution'] = array('type' => 'option', 'name' => $this->lang->bug->resolution, 'options' => $this->lang->bug->resolutionList);
$schema->fields['resolvedDate'] = array('type' => 'date', 'name' => $this->lang->bug->resolvedDate);
$schema->objects = array();
$schema->objects['story'] = array();
$schema->objects['story']['id'] = array('type' => 'number', 'name' => $this->lang->story->id);
$schema->objects['story']['title'] = array('type' => 'string', 'name' => $this->lang->story->common);
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->common);
$schema->objects['project'] = array();
$schema->objects['project']['id'] = array('type' => 'number', 'name' => $this->lang->project->id);
$schema->objects['project']['name'] = array('type' => 'string', 'name' => $this->lang->project->common);
$schema->objects['bugmodule'] = array();
$schema->objects['bugmodule']['id'] = array('type' => 'number', 'name' => $this->lang->bug->id);
$schema->objects['bugmodule']['name'] = array('type' => 'string', 'name' => $this->lang->tree->module);
+92
View File
@@ -0,0 +1,92 @@
<?php
$this->app->loadLang('bug');
$this->app->loadLang('product');
$this->app->loadLang('testtask');
$this->app->loadLang('build');
$this->app->loadLang('execution');
$this->app->loadLang('project');
$this->app->loadLang('tree');
$this->app->loadLang('dataview');
$schema = new stdclass();
$schema->primaryTable = 'bug';
$schema->tables = array();
$schema->tables['bug'] = 'zt_bug';
$schema->tables['product'] = 'zt_product';
$schema->tables['testtask'] = 'zt_testtask';
$schema->tables['testcase'] = 'zt_case';
$schema->tables['build'] = 'zt_build';
$schema->tables['execution'] = 'zt_project';
$schema->tables['project'] = 'zt_project';
$schema->tables['module'] = 'zt_module';
$schema->tables['casemodule'] = 'zt_module';
$schema->joins = array();
$schema->joins['product'] = 'product.id = bug.product';
$schema->joins['testtask'] = 'testtask.id = bug.testtask';
$schema->joins['build'] = 'build.id = testtask.build';
$schema->joins['execution'] = 'execution.id = build.execution';
$schema->joins['project'] = 'project.id = build.project';
$schema->joins['module'] = 'module.id = bug.module';
$schema->joins['testcase'] = 'testcase.id = bug.case';
$schema->joins['casemodule'] = 'casemodule.id = testcase.module';
$schema->fields = array();
$schema->fields['id'] = array('type' => 'number', 'name' => $this->lang->bug->id);
$schema->fields['title'] = array('type' => 'string', 'name' => $this->lang->bug->title);
$schema->fields['steps'] = array('type' => 'text', 'name' => $this->lang->bug->steps);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->bug->status, 'options' => $this->lang->bug->statusList);
$schema->fields['confirmed'] = array('type' => 'option', 'name' => $this->lang->bug->confirmed, 'options' => $this->lang->bug->confirmedList);
$schema->fields['severity'] = array('type' => 'option', 'name' => $this->lang->bug->severity, 'options' => $this->lang->bug->severityList);
$schema->fields['product'] = array('type' => 'object', 'name' => $this->lang->bug->product, 'object' => 'product', 'show' => 'product.name');
$schema->fields['project'] = array('type' => 'object', 'name' => $this->lang->bug->project, 'object' => 'project', 'show' => 'project.name');
$schema->fields['build'] = array('type' => 'object', 'name' => $this->lang->build->common, 'object' => 'build', 'show' => 'build.name');
$schema->fields['module'] = array('type' => 'object', 'name' => $this->lang->bug->module, 'object' => 'module', 'show' => 'module.name');
$schema->fields['testtask'] = array('type' => 'object', 'name' => $this->lang->testtask->common, 'object' => 'testtask', 'show' => 'testtask.name');
$schema->fields['pri'] = array('type' => 'option', 'name' => $this->lang->bug->pri, 'options' => $this->lang->bug->priList);
$schema->fields['openedBy'] = array('type' => 'user', 'name' => $this->lang->bug->openedBy);
$schema->fields['openedDate'] = array('type' => 'datetime', 'name' => $this->lang->bug->openedDate);
$schema->fields['resolvedBy'] = array('type' => 'user', 'name' => $this->lang->bug->resolvedBy);
$schema->fields['resolution'] = array('type' => 'option', 'name' => $this->lang->bug->resolution, 'options' => $this->lang->bug->resolutionList);
$schema->fields['resolvedDate'] = array('type' => 'datetime', 'name' => $this->lang->bug->resolvedDate);
$schema->fields['casemodule'] = array('type' => 'object', 'name' => $this->lang->tree->module, 'object' => 'casemodule', 'show' => 'casemodule.name');
$schema->objects = array();
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->common);
$schema->objects['testtask'] = array();
$schema->objects['testtask']['id'] = array('type' => 'number', 'name' => $this->lang->testtask->id);
$schema->objects['testtask']['name'] = array('type' => 'string', 'name' => $this->lang->testtask->common);
$schema->objects['build'] = array();
$schema->objects['build']['id'] = array('type' => 'number', 'name' => $this->lang->build->id);
$schema->objects['build']['name'] = array('type' => 'string', 'name' => $this->lang->build->common);
$schema->objects['execution'] = array();
$schema->objects['execution']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['execution']['name'] = array('type' => 'string', 'name' => $this->lang->execution->common);
$schema->objects['project'] = array();
$schema->objects['project']['id'] = array('type' => 'number', 'name' => $this->lang->project->id);
$schema->objects['project']['name'] = array('type' => 'string', 'name' => $this->lang->project->common);
$schema->objects['build'] = array();
$schema->objects['build']['id'] = array('type' => 'number', 'name' => $this->lang->build->id);
$schema->objects['build']['name'] = array('type' => 'string', 'name' => $this->lang->build->common);
$schema->objects['module'] = array();
$schema->objects['module']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['module']['name'] = array('type' => 'string', 'name' => $this->lang->tree->module);
$schema->objects['testcase'] = array();
$schema->objects['testcase']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['testcase']['title'] = array('type' => 'string', 'name' => $this->lang->testcase->common);
$schema->objects['casemodule'] = array();
$schema->objects['casemodule']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['casemodule']['name'] = array('type' => 'string', 'name' => $this->lang->dataview->name);
+45
View File
@@ -0,0 +1,45 @@
<?php
$this->app->loadLang('product');
$this->app->loadLang('project');
$this->app->loadLang('execution');
$this->app->loadLang('build');
$schema = new stdclass();
$schema->primaryTable = 'build';
$schema->tables = array();
$schema->tables['product'] = 'zt_product';
$schema->tables['project'] = 'zt_project';
$schema->tables['execution'] = 'zt_project';
$schema->tables['build'] = 'zt_build';
$schema->joins = array();
$schema->joins['product'] = 'product.id = build.product';
$schema->joins['project'] = 'project.id = build.project';
$schema->joins['execution'] = 'execution.id = build.execution';
$schema->fields = array();
$schema->fields['product'] = array('type' => 'object', 'name' => $this->lang->build->product, 'object' => 'product', 'show' => 'product.name');
$schema->fields['project'] = array('type' => 'object', 'name' => $this->lang->build->project, 'object' => 'project', 'show' => 'project.name');
$schema->fields['execution'] = array('type' => 'object', 'name' => $this->lang->build->execution, 'object' => 'execution', 'show' => 'execution.name');
$schema->fields['name'] = array('type' => 'string', 'name' => $this->lang->build->name);
$schema->fields['builder'] = array('type' => 'user', 'name' => $this->lang->build->builder);
$schema->fields['stories'] = array('type' => 'string', 'name' => $this->lang->build->stories);
$schema->fields['bugs'] = array('type' => 'string', 'name' => $this->lang->build->bugs);
$schema->fields['date'] = array('type' => 'date', 'name' => $this->lang->build->date);
$schema->fields['desc'] = array('type' => 'string', 'name' => $this->lang->build->desc);
$schema->objects = array();
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->name);
$schema->objects['project'] = array();
$schema->objects['project']['id'] = array('type' => 'number', 'name' => $this->lang->project->id);
$schema->objects['project']['name'] = array('type' => 'string', 'name' => $this->lang->project->name);
$schema->objects['execution'] = array();
$schema->objects['execution']['id'] = array('type' => 'number', 'name' => $this->lang->execution->id);
$schema->objects['execution']['name'] = array('type' => 'string', 'name' => $this->lang->execution->name);
+18
View File
@@ -0,0 +1,18 @@
<?php
$this->app->loadLang('tree');
$this->app->loadLang('dataview');
$schema = new stdclass();
$schema->primaryTable = 'casemodule';
$schema->tables = array();
$schema->tables['casemodule'] = 'zt_module';
$schema->joins = array();
$schema->fields = array();
$schema->fields['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->fields['name'] = array('type' => 'string', 'name' => $this->lang->tree->module);
$schema->objects = array();
+30
View File
@@ -0,0 +1,30 @@
<?php
$this->app->loadLang('testcase');
$casestepLang = new stdclass();
$casestepLang->type = '步骤类型';
$casestepLang->typeList['step'] = '步骤';
$casestepLang->typeList['group'] = '分组';
$schema = new stdclass();
$schema->primaryTable = 'casestep';
$schema->tables = array();
$schema->tables['casestep'] = 'zt_casestep';
$schema->tables['testcase'] = 'zt_case';
$schema->joins = array();
$schema->joins['testcase'] = 'testcase.id = casestep.`case`';
$schema->fields = array();
$schema->fields['case'] = array('type' => 'object', 'name' => $this->lang->testcase->common, 'object' => 'testcase', 'show' => 'testcase.title');
$schema->fields['type'] = array('type' => 'option', 'name' => $casestepLang->type, 'options' => $casestepLang->typeList);
$schema->fields['desc'] = array('type' => 'string', 'name' => $this->lang->testcase->desc);
$schema->fields['expect'] = array('type' => 'string', 'name' => $this->lang->testcase->expect);
$schema->fields['version'] = array('type' => 'number', 'name' => $this->lang->testcase->version);
$schema->objects = array();
$schema->objects['testcase'] = array();
$schema->objects['testcase']['id'] = array('type' => 'number', 'name' => $this->lang->testcase->id);
$schema->objects['testcase']['title'] = array('type' => 'string', 'name' => $this->lang->testcase->title);
+37
View File
@@ -0,0 +1,37 @@
<?php
$this->app->loadLang('execution');
$this->app->loadLang('project');
$this->app->loadLang('product');
$schema = new stdclass();
$schema->primaryTable = 'execution';
$schema->tables = array();
$schema->tables['project'] = 'zt_project';
$schema->tables['execution'] = 'zt_project';
$schema->joins = array();
$schema->joins['project'] = 'execution.project = project.id';
$schema->fields = array();
$schema->fields['project'] = array('type' => 'object', 'name' => $this->lang->project->name, 'object' => 'project', 'show' => 'project.name');
$schema->fields['name'] = array('type' => 'string', 'name' => $this->lang->execution->name);
$schema->fields['code'] = array('type' => 'string', 'name' => $this->lang->execution->code);
$schema->fields['type'] = array('type' => 'option', 'name' => $this->lang->execution->type, 'options' => $this->lang->execution->typeList);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->execution->status, 'options' => $this->lang->execution->statusList);
$schema->fields['desc'] = array('type' => 'string', 'name' => $this->lang->execution->desc);
$schema->fields['begin'] = array('type' => 'date', 'name' => $this->lang->execution->begin);
$schema->fields['end'] = array('type' => 'date', 'name' => $this->lang->execution->end);
$schema->fields['PO'] = array('type' => 'user', 'name' => $this->lang->product->PO);
$schema->fields['PM'] = array('type' => 'user', 'name' => $this->lang->execution->PM);
$schema->fields['QD'] = array('type' => 'user', 'name' => $this->lang->execution->QD);
$schema->fields['RD'] = array('type' => 'user', 'name' => $this->lang->execution->RD);
$schema->fields['openedBy'] = array('type' => 'user', 'name' => $this->lang->execution->openedBy);
$schema->fields['openedDate'] = array('type' => 'date', 'name' => $this->lang->execution->openedDate);
$schema->objects = array();
$schema->objects['project'] = array();
$schema->objects['project']['id'] = array('type' => 'number', 'name' => $this->lang->project->id);
$schema->objects['project']['name'] = array('type' => 'string', 'name' => $this->lang->project->name);
+41
View File
@@ -0,0 +1,41 @@
<?php
$this->app->loadLang('product');
$this->app->loadLang('program');
$this->app->loadLang('tree');
$schema = new stdclass();
$schema->primaryTable = 'product';
$schema->tables = array();
$schema->tables['product'] = 'zt_product';
$schema->tables['program'] = 'zt_project';
$schema->tables['line'] = 'zt_module';
$schema->joins = array();
$schema->joins['program'] = 'product.program = program.id';
$schema->joins['line'] = 'product.line = line.id';
$schema->fields = array();
$schema->fields['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->fields['program'] = array('type' => 'object', 'name' => $this->lang->product->program, 'object' => 'program', 'show' => 'program.name');
$schema->fields['line'] = array('type' => 'object', 'name' => $this->lang->product->line, 'object' => 'line', 'show' => 'line.name');
$schema->fields['name'] = array('type' => 'string', 'name' => $this->lang->product->name);
$schema->fields['code'] = array('type' => 'string', 'name' => $this->lang->product->code);
$schema->fields['type'] = array('type' => 'option', 'name' => $this->lang->product->type, 'options' => $this->lang->product->typeList);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->product->status, 'options' => $this->lang->product->statusList);
$schema->fields['desc'] = array('type' => 'string', 'name' => $this->lang->product->desc);
$schema->fields['PO'] = array('type' => 'user', 'name' => $this->lang->product->PO);
$schema->fields['QD'] = array('type' => 'user', 'name' => $this->lang->product->QD);
$schema->fields['RD'] = array('type' => 'user', 'name' => $this->lang->product->RD);
$schema->fields['createdBy'] = array('type' => 'user', 'name' => $this->lang->product->createdBy);
$schema->fields['createdDate'] = array('type' => 'date', 'name' => $this->lang->product->createdDate);
$schema->objects = array();
$schema->objects['program'] = array();
$schema->objects['program']['id'] = array('type' => 'number', 'name' => $this->lang->program->id);
$schema->objects['program']['name'] = array('type' => 'string', 'name' => $this->lang->program->name);
$schema->objects['line'] = array();
$schema->objects['line']['name'] = array('type' => 'string', 'name' => $this->lang->product->line);
+28
View File
@@ -0,0 +1,28 @@
<?php
$this->app->loadLang('productplan');
$this->app->loadLang('product');
$schema = new stdclass();
$schema->primaryTable = 'productplan';
$schema->tables = array();
$schema->tables['productplan'] = 'zt_productplan';
$schema->tables['product'] = 'zt_product';
$schema->joins = array();
$schema->joins['product'] = 'productplan.product = product.id';
$schema->fields = array();
$schema->fields['product'] = array('type' => 'object', 'name' => $this->lang->productplan->product, 'object' => 'product', 'show' => 'product.name');
$schema->fields['title'] = array('type' => 'string', 'name' => $this->lang->productplan->title);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->productplan->status, 'options' => $this->lang->productplan->statusList);
$schema->fields['desc'] = array('type' => 'string', 'name' => $this->lang->productplan->desc);
$schema->fields['begin'] = array('type' => 'date', 'name' => $this->lang->productplan->begin);
$schema->fields['end'] = array('type' => 'date', 'name' => $this->lang->productplan->end);
$schema->objects = array();
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->name);
+30
View File
@@ -0,0 +1,30 @@
<?php
$this->app->loadLang('project');
$this->app->loadLang('product');
$schema = new stdclass();
$schema->primaryTable = 'project';
$schema->tables = array();
$schema->tables['project'] = 'zt_project';
$schema->joins = array();
$schema->fields = array();
$schema->fields['name'] = array('type' => 'string', 'name' => $this->lang->project->name);
$schema->fields['code'] = array('type' => 'string', 'name' => $this->lang->project->code);
$schema->fields['model'] = array('type' => 'option', 'name' => $this->lang->project->model, 'options' => $this->lang->project->modelList);
$schema->fields['type'] = array('type' => 'option', 'name' => $this->lang->project->type, 'options' => $this->lang->project->typeList);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->project->status, 'options' => $this->lang->project->statusList);
$schema->fields['desc'] = array('type' => 'string', 'name' => $this->lang->project->desc);
$schema->fields['begin'] = array('type' => 'date', 'name' => $this->lang->project->begin);
$schema->fields['end'] = array('type' => 'date', 'name' => $this->lang->project->end);
$schema->fields['PO'] = array('type' => 'user', 'name' => $this->lang->product->PO);
$schema->fields['PM'] = array('type' => 'user', 'name' => $this->lang->project->common . $this->lang->project->PM);
$schema->fields['QD'] = array('type' => 'user', 'name' => $this->lang->project->QD);
$schema->fields['RD'] = array('type' => 'user', 'name' => $this->lang->project->RD);
$schema->fields['openedBy'] = array('type' => 'user', 'name' => $this->lang->project->openedBy);
$schema->fields['openedDate'] = array('type' => 'date', 'name' => $this->lang->project->openedDate);
$schema->objects = array();
+46
View File
@@ -0,0 +1,46 @@
<?php
$this->app->loadLang('release');
$this->app->loadLang('product');
$this->app->loadLang('project');
$this->app->loadLang('build');
$schema = new stdclass();
$schema->primaryTable = 'release';
$schema->tables = array();
$schema->tables['release'] = 'zt_release';
$schema->tables['product'] = 'zt_product';
$schema->tables['project'] = 'zt_project';
$schema->tables['build'] = 'zt_build';
$schema->joins = array();
$schema->joins['product'] = 'release.product = product.id';
$schema->joins['project'] = 'release.project = project.id';
$schema->joins['build'] = 'release.build = build.id';
$schema->fields = array();
$schema->fields['product'] = array('type' => 'object', 'name' => $this->lang->release->product, 'object' => 'product', 'show' => 'product.name');
$schema->fields['project'] = array('type' => 'object', 'name' => $this->lang->release->project, 'object' => 'project', 'show' => 'project.name');
$schema->fields['build'] = array('type' => 'object', 'name' => $this->lang->release->build, 'object' => 'build', 'show' => 'build.name');
$schema->fields['name'] = array('type' => 'string', 'name' => $this->lang->release->name);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->release->status, 'options' => $this->lang->release->statusList);
$schema->fields['desc'] = array('type' => 'string', 'name' => $this->lang->release->desc);
$schema->fields['date'] = array('type' => 'date', 'name' => $this->lang->release->date);
$schema->fields['stories'] = array('type' => 'string', 'name' => $this->lang->release->stories);
$schema->fields['bugs'] = array('type' => 'string', 'name' => $this->lang->release->bugs);
$schema->fields['leftBugs'] = array('type' => 'string', 'name' => $this->lang->release->leftBugs);
$schema->objects = array();
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->name);
$schema->objects['project'] = array();
$schema->objects['project']['id'] = array('type' => 'number', 'name' => $this->lang->project->id);
$schema->objects['project']['name'] = array('type' => 'string', 'name' => $this->lang->project->name);
$schema->objects['build'] = array();
$schema->objects['build']['id'] = array('type' => 'number', 'name' => $this->lang->build->id);
$schema->objects['build']['name'] = array('type' => 'string', 'name' => $this->lang->build->common);
+49
View File
@@ -0,0 +1,49 @@
<?php
$this->app->loadLang('product');
$this->app->loadLang('productplan');
$this->app->loadLang('story');
$this->app->loadLang('project');
$this->app->loadLang('tree');
$this->app->loadLang('dataview');
$schema = new stdclass();
$schema->primaryTable = 'story';
$schema->tables = array();
$schema->tables['story'] = 'zt_story';
$schema->tables['product'] = 'zt_product';
$schema->tables['productline'] = 'zt_module';
$schema->tables['productplan'] = 'zt_productplan';
$schema->tables['program'] = 'zt_project';
$schema->tables['project'] = 'zt_project';
$schema->tables['storymodule'] = 'zt_module';
$schema->tables['storyspec'] = 'zt_storyspec';
$schema->joins = array();
$schema->joins['product'] = 'product.id = story.product';
$schema->joins['storymodule'] = 'storymodule.id = story.module';
$schema->joins['storyspec'] = 'storyspec.story = story.id';
$schema->fields = array();
$schema->fields['id'] = array('type' => 'number', 'name' => $this->lang->story->id);
$schema->fields['title'] = array('type' => 'string', 'name' => $this->lang->story->title);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->story->status, 'options' => $this->lang->story->statusList);
$schema->fields['stage'] = array('type' => 'option', 'name' => $this->lang->story->stage, 'options' => $this->lang->story->stageList);
$schema->fields['pri'] = array('type' => 'option', 'name' => $this->lang->story->pri, 'options' => $this->lang->story->priList);
$schema->fields['product'] = array('type' => 'object', 'name' => $this->lang->story->product, 'object' => 'product', 'show' => 'product.name');
$schema->fields['storymodule'] = array('type' => 'object', 'name' => $this->lang->story->module, 'object' => 'storymodule', 'show' => 'storymodule.name');
$schema->fields['closedDate'] = array('type' => 'date', 'name' => $this->lang->story->closedDate);
$schema->fields['closedReason'] = array('type' => 'option', 'name' => $this->lang->story->closedReason, 'options' => $this->lang->story->reasonList);
$schema->fields['openedBy'] = array('type' => 'user', 'name' => $this->lang->story->openedBy);
$schema->fields['openedDate'] = array('type' => 'date', 'name' => $this->lang->story->openedDate);
$schema->objects = array();
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->common);
$schema->objects['storymodule'] = array();
$schema->objects['storymodule']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['storymodule']['name'] = array('type' => 'string', 'name' => $this->lang->tree->name);
+63
View File
@@ -0,0 +1,63 @@
<?php
$this->app->loadLang('task');
$this->app->loadLang('project');
$this->app->loadLang('execution');
$this->app->loadLang('story');
$this->app->loadLang('tree');
$this->app->loadLang('dataview');
$schema = new stdclass();
$schema->primaryTable = 'task';
$schema->tables = array();
$schema->tables['task'] = 'zt_task';
$schema->tables['project'] = 'zt_project';
$schema->tables['execution'] = 'zt_project';
$schema->tables['story'] = 'zt_story';
$schema->tables['taskmodule'] = 'zt_module';
$schema->joins = array();
$schema->joins['execution'] = 'task.execution = execution.id';
$schema->joins['project'] = 'task.project = project.id';
$schema->joins['story'] = 'task.story = story.id';
$schema->joins['taskmodule'] = 'task.module = taskmodule.id';
$schema->fields = array();
$schema->fields['project'] = array('type' => 'object', 'name' => $this->lang->task->project, 'object' => 'project', 'show' => 'project.name');
$schema->fields['execution'] = array('type' => 'object', 'name' => $this->lang->task->execution, 'object' => 'execution', 'show' => 'execution.name');
$schema->fields['story'] = array('type' => 'object', 'name' => $this->lang->task->story, 'object' => 'story', 'show' => 'story.title');
$schema->fields['taskmodule'] = array('type' => 'object', 'name' => $this->lang->task->module, 'object' => 'taskmodule', 'show' => 'taskmodule.name');
$schema->fields['name'] = array('type' => 'string', 'name' => $this->lang->task->name);
$schema->fields['pri'] = array('type' => 'option', 'name' => $this->lang->task->pri, 'options' => $this->lang->task->priList);
$schema->fields['type'] = array('type' => 'option', 'name' => $this->lang->task->type, 'options' => $this->lang->task->typeList);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->task->status, 'options' => $this->lang->task->statusList);
$schema->fields['desc'] = array('type' => 'string', 'name' => $this->lang->task->desc);
$schema->fields['estimate'] = array('type' => 'string', 'name' => $this->lang->task->estimate);
$schema->fields['consumed'] = array('type' => 'string', 'name' => $this->lang->task->consumed);
$schema->fields['left'] = array('type' => 'string', 'name' => $this->lang->task->left);
$schema->fields['estStarted'] = array('type' => 'date', 'name' => $this->lang->task->estStarted);
$schema->fields['deadline'] = array('type' => 'date', 'name' => $this->lang->task->deadline);
$schema->fields['assignedTo'] = array('type' => 'user', 'name' => $this->lang->task->assignedTo);
$schema->fields['finishedBy'] = array('type' => 'user', 'name' => $this->lang->task->finishedBy);
$schema->fields['closedBy'] = array('type' => 'user', 'name' => $this->lang->task->closedBy);
$schema->fields['openedBy'] = array('type' => 'user', 'name' => $this->lang->task->openedBy);
$schema->fields['openedDate'] = array('type' => 'date', 'name' => $this->lang->task->openedDate);
$schema->objects = array();
$schema->objects['project'] = array();
$schema->objects['project']['id'] = array('type' => 'number', 'name' => $this->lang->project->id);
$schema->objects['project']['name'] = array('type' => 'string', 'name' => $this->lang->project->name);
$schema->objects['execution'] = array();
$schema->objects['execution']['id'] = array('type' => 'number', 'name' => $this->lang->execution->id);
$schema->objects['execution']['name'] = array('type' => 'string', 'name' => $this->lang->execution->name);
$schema->objects['story'] = array();
$schema->objects['story']['id'] = array('type' => 'number', 'name' => $this->lang->story->id);
$schema->objects['story']['title'] = array('type' => 'string', 'name' => $this->lang->story->title);
$schema->objects['taskmodule'] = array();
$schema->objects['taskmodule']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['taskmodule']['name'] = array('type' => 'string', 'name' => $this->lang->tree->name);
+36
View File
@@ -0,0 +1,36 @@
<?php
$this->app->loadLang('task');
$this->app->loadLang('project');
$this->app->loadLang('execution');
$teamLang = new stdclass();
$teamLang->type = '对象类型';
$teamLang->typeList['task'] = '任务';
$teamLang->typeList['execution'] = '执行';
$teamLang->typeList['project'] = '项目';
$schema = new stdclass();
$schema->primaryTable = 'team';
$schema->tables = array();
$schema->tables['team'] = 'zt_team';
$schema->tables['project'] = 'zt_project';
$schema->tables['execution'] = 'zt_project';
$schema->tables['task'] = 'zt_task';
$schema->joins = array();
$schema->joins['execution'] = 'team.root = execution.id';
$schema->joins['project'] = 'team.root = project.id';
$schema->joins['task'] = 'team.root = task.id';
$schema->fields = array();
$schema->fields['root'] = array('type' => 'object', 'name' => $this->lang->execution->common, 'object' => 'execution', 'show' => 'execution.name');
$schema->fields['account'] = array('type' => 'user', 'name' => $this->lang->team->account);
$schema->fields['type'] = array('type' => 'option', 'name' => $teamLang->type, 'options' => $teamLang->typeList);
$schema->objects = array();
$schema->objects['execution'] = array();
$schema->objects['execution']['id'] = array('type' => 'number', 'name' => $this->lang->execution->id);
$schema->objects['execution']['name'] = array('type' => 'string', 'name' => $this->lang->execution->name);
+52
View File
@@ -0,0 +1,52 @@
<?php
$this->app->loadLang('product');
$this->app->loadLang('testcase');
$this->app->loadLang('testtask');
$this->app->loadLang('tree');
$this->app->loadLang('story');
$this->app->loadLang('dataview');
$schema = new stdclass();
$schema->primaryTable = 'testcase';
$schema->tables = array();
$schema->tables['testcase'] = 'zt_case';
$schema->tables['product'] = 'zt_product';
$schema->tables['casemodule'] = 'zt_module';
$schema->tables['story'] = 'zt_story';
$schema->tables['casestep'] = 'zt_casestep';
$schema->joins = array();
$schema->joins['product'] = 'product.id = testcase.product';
$schema->joins['casemodule'] = 'casemodule.id = testcase.module';
$schema->joins['story'] = 'story.id = testcase.story';
$schema->joins['casestep'] = 'casestep.case = testcase.id';
$schema->fields = array();
$schema->fields['id'] = array('type' => 'number', 'name' => $this->lang->testcase->id);
$schema->fields['title'] = array('type' => 'string', 'name' => $this->lang->testcase->title);
$schema->fields['pri'] = array('type' => 'option', 'name' => $this->lang->testcase->pri, 'options' => $this->lang->testcase->priList);
$schema->fields['type'] = array('type' => 'option', 'name' => $this->lang->testcase->type, 'options' => $this->lang->testcase->typeList);
$schema->fields['stage'] = array('type' => 'option', 'name' => $this->lang->testcase->stage, 'options' => $this->lang->testcase->stageList);
$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->testcase->status, 'options' => $this->lang->testcase->statusList);
$schema->fields['version'] = array('type' => 'number', 'name' => $this->lang->testcase->version);
$schema->fields['product'] = array('type' => 'object', 'name' => $this->lang->testcase->product, 'object' => 'product', 'show' => 'product.name');
$schema->fields['story'] = array('type' => 'object', 'name' => $this->lang->testcase->story, 'object' => 'story', 'show' => 'story.title');
$schema->fields['casemodule'] = array('type' => 'object', 'name' => $this->lang->testcase->module, 'object' => 'casemodule', 'show' => 'casemodule.name');
$schema->fields['openedBy'] = array('type' => 'user', 'name' => $this->lang->testcase->openedBy);
$schema->fields['openedDate'] = array('type' => 'date', 'name' => $this->lang->testcase->openedDate);
$schema->objects = array();
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->common);
$schema->objects['casemodule'] = array();
$schema->objects['casemodule']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['casemodule']['name'] = array('type' => 'string', 'name' => $this->lang->tree->name);
$schema->objects['story'] = array();
$schema->objects['story']['id'] = array('type' => 'number', 'name' => $this->lang->story->id);
$schema->objects['story']['title'] = array('type' => 'string', 'name' => $this->lang->story->title);
+84
View File
@@ -0,0 +1,84 @@
<?php
$this->app->loadLang('testcase');
$this->app->loadLang('testtask');
$this->app->loadLang('project');
$this->app->loadLang('execution');
$this->app->loadLang('tree');
$this->app->loadLang('build');
$this->app->loadLang('caselib');
$this->app->loadLang('product');
$this->app->loadLang('dataview');
$schema = new stdclass();
$schema->primaryTable = 'testresult';
$schema->tables = array();
$schema->tables['testcase'] = 'zt_case';
$schema->tables['testrun'] = 'zt_testrun';
$schema->tables['testresult'] = 'zt_testresult';
$schema->tables['testtask'] = 'zt_testtask';
$schema->tables['project'] = 'zt_project';
$schema->tables['execution'] = 'zt_project';
$schema->tables['casemodule'] = 'zt_module';
$schema->tables['build'] = 'zt_build';
$schema->tables['caselib'] = 'zt_testsuite';
$schema->tables['product'] = 'zt_product';
$schema->joins = array();
$schema->joins['testcase'] = 'testcase.id = testresult.case';
$schema->joins['testrun'] = 'testrun.id = testresult.run';
$schema->joins['testtask'] = 'testrun.task = testtask.id';
$schema->joins['project'] = 'project.id = testtask.project';
$schema->joins['execution'] = 'execution.id = testtask.execution';
$schema->joins['casemodule'] = 'casemodule.id = testcase.module';
$schema->joins['build'] = 'build.id = testtask.build';
$schema->joins['caselib'] = 'caselib.id = testcase.lib';
$schema->joins['product'] = 'product.id = testcase.product';
$schema->fields = array();
$schema->fields['caseResult'] = array('type' => 'option', 'name' => $this->lang->testtask->caseResult, 'options' => $this->lang->testcase->resultList);
$schema->fields['stepResults'] = array('type' => 'json', 'name' => $this->lang->testtask->stepResults);
$schema->fields['lastRunner'] = array('type' => 'user', 'name' => $this->lang->testtask->lastRunner);
$schema->fields['date'] = array('type' => 'date', 'name' => $this->lang->testtask->date);
$schema->fields['testcase'] = array('type' => 'object', 'name' => $this->lang->testcase->common, 'object' => 'testcase', 'show' => 'testcase.title');
$schema->fields['testtask'] = array('type' => 'object', 'name' => $this->lang->testtask->common, 'object' => 'testtask', 'show' => 'testtask.name');
$schema->fields['execution'] = array('type' => 'object', 'name' => $this->lang->execution->common, 'object' => 'execution', 'show' => 'execution.name');
$schema->fields['project'] = array('type' => 'object', 'name' => $this->lang->project->common, 'object' => 'project', 'show' => 'execution.name');
$schema->fields['casemodule'] = array('type' => 'object', 'name' => $this->lang->tree->common, 'object' => 'casemodule', 'show' => 'casemodule.name');
$schema->fields['build'] = array('type' => 'object', 'name' => $this->lang->build->common, 'object' => 'build', 'show' => 'build.name');
$schema->fields['caselib'] = array('type' => 'object', 'name' => $this->lang->caselib->common, 'object' => 'caselib', 'show' => 'caselib.name');
$schema->objects = array();
$schema->objects['testcase'] = array();
$schema->objects['testcase']['id'] = array('type' => 'number', 'name' => $this->lang->testcase->id);
$schema->objects['testcase']['title'] = array('type' => 'string', 'name' => $this->lang->testcase->title);
$schema->objects['testtask'] = array();
$schema->objects['testtask']['id'] = array('type' => 'number', 'name' => $this->lang->testtask->id);
$schema->objects['testtask']['name'] = array('type' => 'string', 'name' => $this->lang->testtask->name);
$schema->objects['build'] = array();
$schema->objects['build']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['build']['name'] = array('type' => 'string', 'name' => $this->lang->build->name);
$schema->objects['project'] = array();
$schema->objects['project']['id'] = array('type' => 'number', 'name' => $this->lang->project->id);
$schema->objects['project']['name'] = array('type' => 'string', 'name' => $this->lang->project->name);
$schema->objects['execution'] = array();
$schema->objects['execution']['id'] = array('type' => 'number', 'name' => $this->lang->execution->id);
$schema->objects['execution']['name'] = array('type' => 'string', 'name' => $this->lang->execution->name);
$schema->objects['casemodule'] = array();
$schema->objects['casemodule']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['casemodule']['name'] = array('type' => 'string', 'name' => $this->lang->dataview->name);
$schema->objects['caselib'] = array();
$schema->objects['caselib']['id'] = array('type' => 'number', 'name' => $this->lang->dataview->id);
$schema->objects['caselib']['name'] = array('type' => 'string', 'name' => $this->lang->caselib->name);
$schema->objects['product'] = array();
$schema->objects['product']['id'] = array('type' => 'number', 'name' => $this->lang->product->id);
$schema->objects['product']['name'] = array('type' => 'string', 'name' => $this->lang->product->name);

Some files were not shown because too many files have changed in this diff Show More