diff --git a/config/zentaopms.php b/config/zentaopms.php index 4fb7395455..4992f080bf 100644 --- a/config/zentaopms.php +++ b/config/zentaopms.php @@ -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`'); @@ -452,3 +453,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; diff --git a/db/demo.sql b/db/demo.sql index e0eb401c6d..03a27580ff 100644 --- a/db/demo.sql +++ b/db/demo.sql @@ -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', '', '', '', '', '

[步骤]进入首页

\r\n

[结果]出现乱码    

\r\n

[期望]正常显示

', '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', '', '', '', '', '

[步骤]进入新闻中心

\r\n

[结果]页面出现乱码

\r\n

[期望]正常显示

', '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', '', '', '', '', '

[步骤]进入成果展示    

\r\n

[结果]乱码

\r\n

[期望]正常显示

', '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', '', '', '', '', '

[步骤]进入售后服务

\r\n

[结果]乱码

\r\n

[期望]正常显示

', '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', '', '', '', '', '

[步骤]进入首页

\r\n

[结果]出现乱码    

\r\n

[期望]正常显示

', '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', '', '', '', '', '

[步骤]进入新闻中心

\r\n

[结果]页面出现乱码

\r\n

[期望]正常显示

', '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', '', '', '', '', '

[步骤]进入成果展示    

\r\n

[结果]乱码

\r\n

[期望]正常显示

', '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', '', '', '', '', '

[步骤]进入售后服务

\r\n

[结果]乱码

\r\n

[期望]正常显示

', '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', ' 作为一名本公司的用户,我希望可以在成果展示看到该公司网站的企业新闻,这样可以方便我进行了解该公司的产品并进行购买。 
', ' 作为一名本公司的用户,我希望可以在成果展示看到该公司网站的吹产品,这样可以方便我进行了解该公司的产品并进行购买。 
', '001- 作为一名本公司的用户,我希望可以在成果展示看到该公司网站的企业新闻,这样可以方便我进行了解该公司的产品并进行购买。
\n001+ 作为一名本公司的用户,我希望可以在成果展示看到该公司网站的吹产品,这样可以方便我进行了解该公司的产品并进行购买。
'), @@ -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', '', '建立公司企业网站,可以更好对外展示。
', '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版本。
', '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版本。
', '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', '开发企业网站的基本雏形。
', 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, '首页设计和开发', '作为一名本公司的用户,我希望可以在首页看到该公司网站的基本内容,例如最新动态、部分成果展示、联系信息、工商信息等。
', '开发并通过验收
'), -(2, 1, '新闻中心的设计和开发。', '作为一名本公司的用户,我希望可以在新闻中心看到该公司网站的企业新闻,这样可以通过新闻了解企业的最新动态。
', ''), -(3, 1, '成果展示的设计和开发', ' 作为一名本公司的用户,我希望可以在成果展示看到该公司网站的企业新闻,这样可以方便我进行了解该公司的产品并进行购买。 
', ''), -(3, 2, '成果展示的设计和开发', ' 作为一名本公司的用户,我希望可以在成果展示看到该公司网站的吹产品,这样可以方便我进行了解该公司的产品并进行购买。 
', ''), -(4, 1, '售后服务的设计和开发', '作为一名本公司的用户,我希望可以在售后服务看到该公司网站的售后服务,这样可以方便我联系该公司来解决我的问题。 
', ''), -(5, 1, '诚聘英才的设计和开发', '作为一名求职者,我希望可以在诚聘英才里看到该公司的招聘信息,这样可以方便我应聘该公司。 
', ''), -(6, 1, '合作洽谈的设计和开发', '作为一名合作商,我希望可以在合作洽谈里看到该公司对外的合作内容,这样可以方便我和该公司进行合作洽谈。 
', ''), -(7, 1, '关于我们的设计和开发', '我希望可以在关于我们里看到该公司的基本信息,这样可以方便我了解该公司。
', ''); -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, '首页设计和开发', '作为一名本公司的用户,我希望可以在首页看到该公司网站的基本内容,例如最新动态、部分成果展示、联系信息、工商信息等。
', '开发并通过验收
', ''), +(2, 1, '新闻中心的设计和开发。', '作为一名本公司的用户,我希望可以在新闻中心看到该公司网站的企业新闻,这样可以通过新闻了解企业的最新动态。
', '', ''), +(3, 1, '成果展示的设计和开发', ' 作为一名本公司的用户,我希望可以在成果展示看到该公司网站的企业新闻,这样可以方便我进行了解该公司的产品并进行购买。 
', '', ''), +(3, 2, '成果展示的设计和开发', ' 作为一名本公司的用户,我希望可以在成果展示看到该公司网站的吹产品,这样可以方便我进行了解该公司的产品并进行购买。 
', '', ''), +(4, 1, '售后服务的设计和开发', '作为一名本公司的用户,我希望可以在售后服务看到该公司网站的售后服务,这样可以方便我联系该公司来解决我的问题。 
', '', ''), +(5, 1, '诚聘英才的设计和开发', '作为一名求职者,我希望可以在诚聘英才里看到该公司的招聘信息,这样可以方便我应聘该公司。 
', '', ''), +(6, 1, '合作洽谈的设计和开发', '作为一名合作商,我希望可以在合作洽谈里看到该公司对外的合作内容,这样可以方便我和该公司进行合作洽谈。 
', '', ''), +(7, 1, '关于我们的设计和开发', '我希望可以在关于我们里看到该公司的基本信息,这样可以方便我了解该公司。
', '', ''); +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'), diff --git a/db/endemo.sql b/db/endemo.sql index 2277a6a1d4..c913530a40 100644 --- a/db/endemo.sql +++ b/db/endemo.sql @@ -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', '', '', '', '', '

[步骤]进入首页

\r\n

[结果]出现乱码    

\r\n

[期望]正常显示

', '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', '', '', '', '', '

[步骤]进入新闻中心

\r\n

[结果]页面出现乱码

\r\n

[期望]正常显示

', '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', '', '', '', '', '

[步骤]进入成果展示    

\r\n

[结果]乱码

\r\n

[期望]正常显示

', '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', '', '', '', '', '

[步骤]进入售后服务

\r\n

[结果]乱码

\r\n

[期望]正常显示

', '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', '', '', '', '', '

[步骤]进入首页

\r\n

[结果]出现乱码    

\r\n

[期望]正常显示

', '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', '', '', '', '', '

[步骤]进入新闻中心

\r\n

[结果]页面出现乱码

\r\n

[期望]正常显示

', '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', '', '', '', '', '

[步骤]进入成果展示    

\r\n

[结果]乱码

\r\n

[期望]正常显示

', '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', '', '', '', '', '

[步骤]进入售后服务

\r\n

[结果]乱码

\r\n

[期望]正常显示

', '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', ' 作为一名本公司的用户,我希望可以在成果展示看到该公司网站的企业新闻,这样可以方便我进行了解该公司的产品并进行购买。 
', ' 作为一名本公司的用户,我希望可以在成果展示看到该公司网站的吹产品,这样可以方便我进行了解该公司的产品并进行购买。 
', '001- 作为一名本公司的用户,我希望可以在成果展示看到该公司网站的企业新闻,这样可以方便我进行了解该公司的产品并进行购买。
\n001+ 作为一名本公司的用户,我希望可以在成果展示看到该公司网站的吹产品,这样可以方便我进行了解该公司的产品并进行购买。
'), @@ -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', '', '建立公司企业网站,可以更好对外展示。
', '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版本。
', '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版本。
', '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', '开发企业网站的基本雏形。
', 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, '首页设计和开发', '作为一名本公司的用户,我希望可以在首页看到该公司网站的基本内容,例如最新动态、部分成果展示、联系信息、工商信息等。
', '开发并通过验收
'), -(2, 1, '新闻中心的设计和开发。', '作为一名本公司的用户,我希望可以在新闻中心看到该公司网站的企业新闻,这样可以通过新闻了解企业的最新动态。
', ''), -(3, 1, '成果展示的设计和开发', ' 作为一名本公司的用户,我希望可以在成果展示看到该公司网站的企业新闻,这样可以方便我进行了解该公司的产品并进行购买。 
', ''), -(3, 2, '成果展示的设计和开发', ' 作为一名本公司的用户,我希望可以在成果展示看到该公司网站的吹产品,这样可以方便我进行了解该公司的产品并进行购买。 
', ''), -(4, 1, '售后服务的设计和开发', '作为一名本公司的用户,我希望可以在售后服务看到该公司网站的售后服务,这样可以方便我联系该公司来解决我的问题。 
', ''), -(5, 1, '诚聘英才的设计和开发', '作为一名求职者,我希望可以在诚聘英才里看到该公司的招聘信息,这样可以方便我应聘该公司。 
', ''), -(6, 1, '合作洽谈的设计和开发', '作为一名合作商,我希望可以在合作洽谈里看到该公司对外的合作内容,这样可以方便我和该公司进行合作洽谈。 
', ''), -(7, 1, '关于我们的设计和开发', '我希望可以在关于我们里看到该公司的基本信息,这样可以方便我了解该公司。
', ''); -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, '首页设计和开发', '作为一名本公司的用户,我希望可以在首页看到该公司网站的基本内容,例如最新动态、部分成果展示、联系信息、工商信息等。
', '开发并通过验收
', ''), +(2, 1, '新闻中心的设计和开发。', '作为一名本公司的用户,我希望可以在新闻中心看到该公司网站的企业新闻,这样可以通过新闻了解企业的最新动态。
', '', ''), +(3, 1, '成果展示的设计和开发', ' 作为一名本公司的用户,我希望可以在成果展示看到该公司网站的企业新闻,这样可以方便我进行了解该公司的产品并进行购买。 
', '', ''), +(3, 2, '成果展示的设计和开发', ' 作为一名本公司的用户,我希望可以在成果展示看到该公司网站的吹产品,这样可以方便我进行了解该公司的产品并进行购买。 
', '', ''), +(4, 1, '售后服务的设计和开发', '作为一名本公司的用户,我希望可以在售后服务看到该公司网站的售后服务,这样可以方便我联系该公司来解决我的问题。 
', '', ''), +(5, 1, '诚聘英才的设计和开发', '作为一名求职者,我希望可以在诚聘英才里看到该公司的招聘信息,这样可以方便我应聘该公司。 
', '', ''), +(6, 1, '合作洽谈的设计和开发', '作为一名合作商,我希望可以在合作洽谈里看到该公司对外的合作内容,这样可以方便我和该公司进行合作洽谈。 
', '', ''), +(7, 1, '关于我们的设计和开发', '我希望可以在关于我们里看到该公司的基本信息,这样可以方便我了解该公司。
', '', ''); +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'), diff --git a/db/update18.3.sql b/db/update18.3.sql index 7fcdc51318..aadaf5e657 100644 --- a/db/update18.3.sql +++ b/db/update18.3.sql @@ -20,13 +20,13 @@ CREATE TABLE IF NOT EXISTS `zt_pivot` ( `name` text NOT NULL, `desc` text NOT NULL, `sql` mediumtext NOT NULL, - `fields` mediumtext NOT NULL, - `langs` mediumtext NOT NULL, + `fields` mediumtext NULL, + `langs` mediumtext NULL, `vars` mediumtext NOT NULL, `objects` mediumtext NULL, `settings` mediumtext NOT NULL, `filters` mediumtext NOT NULL, - `step` tinyint(1) unsigned NOT NULL, + `step` tinyint(1) unsigned NOT NULL DEFAULT '', `stage` enum('draft','published') NOT NULL DEFAULT 'draft', `builtin` enum('0', '1') NOT NULL DEFAULT '0', `createdBy` varchar(30) NOT NULL, @@ -35,19 +35,20 @@ CREATE TABLE IF NOT EXISTS `zt_pivot` ( `editedDate` datetime NULL, `deleted` enum('0', '1') NOT NULL DEFAULT '0', PRIMARY KEY (`id`), - KEY(`dimension`), - KEY(`group`) + KEY `dimension` (`dimension`), + KEY `group` (`group`) ) ENGINE = InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `zt_chart_back` SELECT * FROM `zt_chart`; -ALTER TABLE `zt_chart` MODIFY `fields` mediumtext NOT NULL; +ALTER TABLE `zt_chart` MODIFY `fields` mediumtext NULL; ALTER TABLE `zt_chart` MODIFY `group` varchar(255) NOT NULL; ALTER TABLE `zt_chart` ADD `stage` enum('draft','published') NOT NULL DEFAULT 'draft' AFTER `sql`; -ALTER TABLE `zt_chart` ADD `langs` text NOT NULL AFTER `fields`; -ALTER TABLE `zt_chart` ADD `step` tinyint(1) unsigned NOT NULL AFTER `filters`; +ALTER TABLE `zt_chart` ADD `langs` text NULL AFTER `fields`; +ALTER TABLE `zt_chart` ADD `step` tinyint(1) unsigned NOT NULL DEFAULT '0' AFTER `filters`; +ALTER TABLE `zt_chart` DROP `dataset`; -ALTER TABLE `zt_dataview` ADD `langs` text NOT NULL AFTER `fields`; +ALTER TABLE `zt_dataview` ADD `langs` text NULL AFTER `fields`; ALTER TABLE `zt_screen` ADD `status` enum('draft','published') NOT NULL DEFAULT 'draft' AFTER `scheme`; ALTER TABLE `zt_screen` ADD `builtin` enum('0', '1') NOT NULL DEFAULT '0' AFTER `status`; @@ -151,6 +152,15 @@ SELECT t1.`group`, t1.`module`, 'editCatalog' FROM `zt_grouppriv` AS t1 WHERE t1 INSERT IGNORE INTO `zt_grouppriv` (`group`, `module`, `method`) SELECT t1.`group`, t1.`module`, 'deleteCatalog' FROM `zt_grouppriv` AS t1 WHERE t1.`module` = 'doc' AND t1.`method` = 'catalog'; +INSERT IGNORE INTO `zt_grouppriv` (`group`, `module`, `method`) +SELECT t1.`group`, 'api', 'addCatalog' FROM `zt_grouppriv` AS t1 WHERE t1.`module` = 'doc' AND t1.`method` = 'catalog'; + +INSERT IGNORE INTO `zt_grouppriv` (`group`, `module`, `method`) +SELECT t1.`group`, 'api', 'editCatalog' FROM `zt_grouppriv` AS t1 WHERE t1.`module` = 'doc' AND t1.`method` = 'catalog'; + +INSERT IGNORE INTO `zt_grouppriv` (`group`, `module`, `method`) +SELECT t1.`group`, 'api', 'deleteCatalog' FROM `zt_grouppriv` AS t1 WHERE t1.`module` = 'doc' AND t1.`method` = 'catalog'; + UPDATE `zt_grouppriv` SET `method` = 'mySpace' WHERE `module` = 'doc' AND `method` = 'browse'; ALTER TABLE `zt_account` @@ -173,8 +183,7 @@ CHANGE `editedDate` `editedDate` datetime NULL; ALTER TABLE `zt_assetlib` CHANGE `editedBy` `editedBy` varchar(30) NOT NULL DEFAULT '', -CHANGE `editedDate` `editedDate` datetime NULL, -CHANGE `registerDate` `registerDate` datetime NULL; +CHANGE `editedDate` `editedDate` datetime NULL; ALTER TABLE `zt_attend` CHANGE `reviewedBy` `reviewedBy` char(30) NULL DEFAULT '', @@ -206,6 +215,17 @@ CHANGE `lastEditedBy` `lastEditedBy` char(30) NOT NULL DEFAULT '', CHANGE `lastEditedDate` `lastEditedDate` date NULL; ALTER TABLE `zt_bug` +CHANGE `hardware` `hardware` varchar(30) NOT NULL DEFAULT '', +CHANGE `injection` `injection` mediumint unsigned NOT NULL DEFAULT '0', +CHANGE `repo` `repo` mediumint unsigned NOT NULL DEFAULT '0', +CHANGE `mr` `mr` mediumint unsigned NOT NULL DEFAULT '0', +CHANGE `entry` `entry` text COLLATE 'utf8mb3_general_ci' NULL, +CHANGE `lines` `lines` varchar(10) COLLATE 'utf8mb3_general_ci' NOT NULL DEFAULT '', +CHANGE `v1` `v1` varchar(40) COLLATE 'utf8mb3_general_ci' NOT NULL DEFAULT '', +CHANGE `v2` `v2` varchar(40) COLLATE 'utf8mb3_general_ci' NOT NULL DEFAULT '', +CHANGE `identify` `identify` mediumint unsigned NOT NULL DEFAULT '0', +CHANGE `activatedCount` `activatedCount` smallint NOT NULL DEFAULT '0', +CHANGE `activatedDate` `activatedDate` datetime NULL, CHANGE `assignedDate` `assignedDate` datetime NULL, CHANGE `resolvedDate` `resolvedDate` datetime NULL, CHANGE `closedDate` `closedDate` datetime NULL, @@ -598,7 +618,8 @@ CHANGE `editedDate` `editedDate` datetime NULL; ALTER TABLE `zt_stakeholder` CHANGE `editedBy` `editedBy` char(30) NOT NULL DEFAULT '', -CHANGE `editedDate` `editedDate` date NULL; +CHANGE `editedDate` `editedDate` date NULL, +CHANGE `deleted` `deleted` enum('0','1') NOT NULL DEFAULT '0'; ALTER TABLE `zt_story` CHANGE `assignedDate` `assignedDate` datetime NULL, @@ -612,12 +633,14 @@ CHANGE `closedDate` `closedDate` datetime NULL, CHANGE `closedReason` `closedReason` varchar(30) NOT NULL DEFAULT '', CHANGE `activatedDate` `activatedDate` datetime NULL, CHANGE `feedbackBy` `feedbackBy` varchar(100) NOT NULL DEFAULT '', +CHANGE `stagedBy` `stagedBy` char(30) NOT NULL DEFAULT '', CHANGE `notifyEmail` `notifyEmail` varchar(100) NOT NULL DEFAULT ''; ALTER TABLE `zt_storyreview` CHANGE `reviewDate` `reviewDate` datetime NULL; ALTER TABLE `zt_task` +CHANGE `design` `design` mediumint unsigned NOT NULL DEFAULT '0', CHANGE `estStarted` `estStarted` date NULL, CHANGE `realStarted` `realStarted` datetime NULL, CHANGE `finishedBy` `finishedBy` varchar(30) NOT NULL DEFAULT '', @@ -739,3 +762,14 @@ CHANGE `editedDate` `editedDate` datetime NULL; ALTER TABLE `zt_zoutput` CHANGE `editedBy` `editedBy` varchar(30) NOT NULL DEFAULT '', CHANGE `editedDate` `editedDate` datetime NULL; + +CREATE TABLE IF NOT EXISTS `zt_docaction` ( + `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, + `doc` mediumint(8) unsigned NOT NULL, + `action` varchar(80) NOT NULL, + `actor` char(30) NOT NULL, + `date` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `doc` (`doc`), + KEY `actor` (`actor`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/db/zentao.sql b/db/zentao.sql index 24edb643a0..bb2c6db173 100755 --- a/db/zentao.sql +++ b/db/zentao.sql @@ -249,8 +249,8 @@ CREATE TABLE IF NOT EXISTS `zt_bug` ( `id` mediumint(8) NOT NULL AUTO_INCREMENT, `project` mediumint(8) unsigned NOT NULL, `product` mediumint(8) unsigned NOT NULL DEFAULT '0', - `injection` mediumint(8) unsigned NOT NULL, - `identify` mediumint(8) unsigned NOT NULL, + `injection` mediumint(8) unsigned NOT NULL DEFAULT '0', + `identify` mediumint(8) unsigned NOT NULL DEFAULT '0', `branch` mediumint(8) unsigned NOT NULL DEFAULT '0', `module` mediumint(8) unsigned NOT NULL DEFAULT '0', `execution` mediumint(8) unsigned NOT NULL DEFAULT '0', @@ -267,15 +267,15 @@ CREATE TABLE IF NOT EXISTS `zt_bug` ( `type` varchar(30) NOT NULL DEFAULT '', `os` varchar(255) NOT NULL DEFAULT '', `browser` varchar(255) NOT NULL DEFAULT '', - `hardware` varchar(30) NOT NULL, + `hardware` varchar(30) NOT NULL DEFAULT '', `found` varchar(30) NOT NULL DEFAULT '', `steps` mediumtext NOT NULL, `status` enum('active','resolved','closed') NOT NULL DEFAULT 'active', `subStatus` varchar(30) NOT NULL DEFAULT '', `color` char(7) NOT NULL, `confirmed` tinyint(1) NOT NULL DEFAULT '0', - `activatedCount` smallint(6) NOT NULL, - `activatedDate` datetime NOT NULL, + `activatedCount` smallint(6) NOT NULL DEFAULT '0', + `activatedDate` datetime NULL, `feedbackBy` varchar(100) NOT NULL, `notifyEmail` varchar(100) NOT NULL, `mailto` text, @@ -297,12 +297,12 @@ CREATE TABLE IF NOT EXISTS `zt_bug` ( `caseVersion` smallint(6) NOT NULL DEFAULT '1', `feedback` mediumint(8) unsigned NOT NULL DEFAULT '0', `result` mediumint(8) unsigned NOT NULL, - `repo` mediumint(8) unsigned NOT NULL, - `mr` mediumint(8) unsigned NOT NULL, - `entry` text NOT NULL, - `lines` varchar(10) NOT NULL, - `v1` varchar(40) NOT NULL, - `v2` varchar(40) NOT NULL, + `repo` mediumint(8) unsigned NOT NULL DEFAULT '0', + `mr` mediumint(8) unsigned NOT NULL DEFAULT '0', + `entry` text NULL, + `lines` varchar(10) NOT NULL DEFAULT '', + `v1` varchar(40) NOT NULL DEFAULT '', + `v2` varchar(40) NOT NULL DEFAULT '', `repoType` varchar(30) NOT NULL DEFAULT '', `issueKey` varchar(50) NOT NULL DEFAULT '', `testtask` mediumint(8) unsigned NOT NULL, @@ -442,9 +442,9 @@ CREATE TABLE IF NOT EXISTS `zt_chart` ( `desc` text NOT NULL, `settings` mediumtext NOT NULL, `filters` mediumtext NOT NULL, - `step` tinyint(1) unsigned NOT NULL, - `fields` mediumtext NOT NULL, - `langs` text NOT NULL, + `step` tinyint(1) unsigned NOT NULL DEFAULT '0', + `fields` mediumtext NULL, + `langs` text NULL, `sql` mediumtext, `stage` enum('draft','published') NOT NULL DEFAULT 'draft', `builtin` tinyint(1) unsigned NOT NULL, @@ -481,8 +481,8 @@ CREATE TABLE IF NOT EXISTS `zt_dimension` ( `desc` text NOT NULL, `createdBy` varchar(30) NOT NULL, `createdDate` datetime NOT NULL, - `editedBy` varchar(30) NOT NULL, - `editedDate` datetime NOT NULL, + `editedBy` varchar(30) NOT NULL DEFAULT '', + `editedDate` datetime NULL, `deleted` enum('0','1') NOT NULL default '0', PRIMARY KEY (`id`), KEY `code` (`code`) @@ -584,7 +584,7 @@ CREATE TABLE IF NOT EXISTS `zt_dataview` ( `view` varchar(57) NOT NULL, `sql` text NOT NULL, `fields` mediumtext NOT NULL, - `langs` text NOT NULL, + `langs` text NULL, `objects` mediumtext NOT NULL, `createdBy` varchar(30) NOT NULL, `createdDate` datetime NOT NULL, @@ -686,6 +686,17 @@ CREATE TABLE IF NOT EXISTS `zt_doc` ( KEY `execution` (`execution`), KEY `lib` (`lib`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +-- DROP TABLE IF EXISTS `zt_docaction`; +CREATE TABLE IF NOT EXISTS `zt_docaction` ( + `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, + `doc` mediumint(8) unsigned NOT NULL, + `action` varchar(80) NOT NULL, + `actor` char(30) NOT NULL, + `date` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY `doc` (`doc`), + KEY `actor` (`actor`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- DROP TABLE IF EXISTS `zt_doccontent`; CREATE TABLE IF NOT EXISTS `zt_doccontent` ( `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, @@ -991,8 +1002,8 @@ CREATE TABLE IF NOT EXISTS `zt_kanbanregion` ( `order` mediumint(8) NOT NULL DEFAULT '0', `createdBy` char(30) NOT NULL, `createdDate` datetime NOT NULL, - `lastEditedBy` char(30) NOT NULL, - `lastEditedDate` datetime NOT NULL, + `lastEditedBy` char(30) NOT NULL DEFAULT '', + `lastEditedDate` datetime NULL, `deleted` enum('0', '1') NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -1569,7 +1580,7 @@ CREATE TABLE IF NOT EXISTS `zt_stakeholder` ( `createdDate` date NOT NULL, `editedBy` char(30) NOT NULL DEFAULT '', `editedDate` date NULL, - `deleted` enum('0','1') NOT NULL, + `deleted` enum('0','1') NOT NULL DEFAULT '0', PRIMARY KEY (`id`), KEY `objectID` (`objectID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -1596,7 +1607,7 @@ CREATE TABLE IF NOT EXISTS `zt_story` ( `subStatus` varchar(30) NOT NULL DEFAULT '', `color` char(7) NOT NULL, `stage` enum('','wait','planned','projected','developing','developed','testing','tested','verified','released','closed') NOT NULL DEFAULT 'wait', - `stagedBy` char(30) NOT NULL, + `stagedBy` char(30) NOT NULL DEFAULT '', `mailto` text, `lib` mediumint(8) unsigned NOT NULL DEFAULT '0', `fromStory` mediumint(8) unsigned NOT NULL DEFAULT '0', @@ -1686,7 +1697,7 @@ CREATE TABLE IF NOT EXISTS `zt_task` ( `parent` mediumint(8) NOT NULL DEFAULT '0', `execution` mediumint(8) unsigned NOT NULL DEFAULT '0', `module` mediumint(8) unsigned NOT NULL DEFAULT '0', - `design` mediumint(8) unsigned NOT NULL, + `design` mediumint(8) unsigned NOT NULL DEFAULT '0', `story` mediumint(8) unsigned NOT NULL DEFAULT '0', `storyVersion` smallint(6) NOT NULL DEFAULT '1', `designVersion` smallint(6) unsigned NOT NULL, @@ -9705,7 +9716,6 @@ CREATE TABLE IF NOT EXISTS `zt_assetlib` ( `createdDate` datetime NOT NULL, `editedBy` varchar(30) NOT NULL DEFAULT '', `editedDate` datetime NULL, - `registerDate` datetime NULL, `deleted` enum('0','1') NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB CHARSET=utf8; @@ -14044,13 +14054,13 @@ CREATE TABLE IF NOT EXISTS `zt_pivot` ( `name` text NOT NULL, `desc` text NOT NULL, `sql` mediumtext NOT NULL, - `fields` mediumtext NOT NULL, - `langs` mediumtext NOT NULL, + `fields` mediumtext NULL, + `langs` mediumtext NULL, `vars` mediumtext NOT NULL, `objects` mediumtext NULL, `settings` mediumtext NOT NULL, `filters` mediumtext NOT NULL, - `step` tinyint(1) unsigned NOT NULL, + `step` tinyint(1) unsigned NOT NULL DEFAULT '0', `stage` enum('draft','published') NOT NULL DEFAULT 'draft', `builtin` enum('0', '1') NOT NULL DEFAULT '0', `createdBy` varchar(30) NOT NULL, @@ -14059,8 +14069,8 @@ CREATE TABLE IF NOT EXISTS `zt_pivot` ( `editedDate` datetime NOT NULL, `deleted` enum('0', '1') NOT NULL DEFAULT '0', PRIMARY KEY (`id`), - KEY(`dimension`), - KEY(`group`) + KEY `dimension` (`dimension`), + KEY `group` (`group`) ) ENGINE = InnoDB DEFAULT CHARSET=utf8; -- DROP TABLE IF EXISTS `zt_sqlview`; diff --git a/extension/lite/common/ext/lang/zh-cn/lite.php b/extension/lite/common/ext/lang/zh-cn/lite.php index ca7c09e4fc..12e65fbfed 100644 --- a/extension/lite/common/ext/lang/zh-cn/lite.php +++ b/extension/lite/common/ext/lang/zh-cn/lite.php @@ -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'); @@ -117,8 +117,8 @@ $lang->SRCommon = '目标'; /* Doc menu. */ $lang->doc->menu = new stdclass(); $lang->doc->menu->dashboard = array('link' => "{$lang->dashboard}|doc|index"); -$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->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,'; diff --git a/extension/lite/group/ext/lang/resource.php b/extension/lite/group/ext/lang/resource.php index 7cb8bd18cf..a3f32b1f6b 100644 --- a/extension/lite/group/ext/lang/resource.php +++ b/extension/lite/group/ext/lang/resource.php @@ -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,12 @@ 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->doc->mine2export = 'mine2export'; + $lang->resource->doc->product2export = 'product2export'; + $lang->resource->doc->project2export = 'project2export'; + $lang->resource->doc->custom2export = 'custom2export'; + $lang->resource->doc->execution2export = 'execution2export'; $lang->resource->my->review = 'review'; diff --git a/framework/base/helper.class.php b/framework/base/helper.class.php index fb5286f377..3e5694036e 100644 --- a/framework/base/helper.class.php +++ b/framework/base/helper.class.php @@ -595,7 +595,7 @@ class baseHelper */ static public function isZeroDate($date) { - return (empty($date) or substr($date, 0, 4) == '0000'); + return (empty($date) or substr($date, 0, 4) <= '1970'); } /** @@ -1008,7 +1008,7 @@ if (!function_exists('getallheaders')) { function getallheaders() { $headers = array(); - foreach ($_SERVER as $name => $value) + foreach ($_SERVER as $name => $value) { if (substr($name, 0, 5) == 'HTTP_') { diff --git a/lib/base/dao/dao.class.php b/lib/base/dao/dao.class.php index e993b05e49..4a073f393d 100644 --- a/lib/base/dao/dao.class.php +++ b/lib/base/dao/dao.class.php @@ -1703,6 +1703,8 @@ class baseSQL continue; } if(strpos($this->skipFields, ",$field,") !== false) continue; + if($field == 'id' and $this->method == 'update') continue; // primary key not allowed in dmdb. + $this->sql .= "`$field` = " . $this->quote($value) . ','; } } @@ -1874,10 +1876,14 @@ class baseSQL * @access public * @return static|sql the sql object. */ - public function where($arg1, $arg2 = null, $arg3 = null) + public function where($arg1 = '', $arg2 = null, $arg3 = null) { if($this->inCondition and !$this->conditionIsTrue) return $this; - if($arg3 !== null) + if(!$arg1) + { + $condition = ''; + } + elseif($arg3 !== null) { $value = $this->quote($arg3); $condition = "`$arg1` $arg2 " . $this->quote($arg3); @@ -2105,6 +2111,34 @@ class baseSQL return $this; } + /** + * 不为空日期 + * Create not zero date. + * + * @access public + * @return static|sql the sql object. + */ + public function notZeroDate() + { + if($this->inCondition and !$this->conditionIsTrue) return $this; + $this->sql .= " > '1970-01-01' "; + return $this; + } + + /** + * 不为空时间 + * Create not zero datetime. + * + * @access public + * @return static|sql the sql object. + */ + public function notZeroDatetime() + { + if($this->inCondition and !$this->conditionIsTrue) return $this; + $this->sql .= " > '1970-01-01 00:00:01' "; + return $this; + } + /** * 创建ORDER BY部分。 * Create the order by part. diff --git a/lib/dao/dm.class.php b/lib/dao/dm.class.php index 43a991b677..80904a01ae 100644 --- a/lib/dao/dm.class.php +++ b/lib/dao/dm.class.php @@ -19,6 +19,19 @@ */ class dm extends dao { + /** + * 设置$table属性。 + * Set the $table property. + * + * @param string $table + * @access public + * @return void + */ + public function setTable($table) + { + $this->table = trim($table, '`'); + } + /** * 类MySQL的DESC语法。 * Desc table, show fields. @@ -36,7 +49,7 @@ class dm extends dao foreach($rawFields as $rawField) { $field = new stdClass(); - $field->Field = $rawField->field; + $field->Field = $rawField->COLUMN_NAME; $fields[] = $field; } return $fields; @@ -123,12 +136,17 @@ class dm extends dao 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); } + + /* fix sum(if(..., 1, 0)) , count(if(..., 1, 0)) */ + if(substr($if, strlen($if)-2) == '))' and (stripos($field, 'sum(') == 0 or stripos($field, 'count(') == 0)) $if = substr($if, 0, strlen($if)-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); @@ -146,7 +164,7 @@ class dm extends dao * @access public * @return static|sql the sql object. */ - public function where($arg1, $arg2 = null, $arg3 = null) + public function where($arg1 = '', $arg2 = null, $arg3 = null) { $arg1 = $this->formatWhere($arg1); return parent::where($arg1, $arg2, $arg3); @@ -217,6 +235,20 @@ class dm extends dao 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. @@ -236,7 +268,7 @@ class dm extends dao 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;"; + $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->name}' 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; @@ -265,7 +297,7 @@ class dm extends dao if($this->method == 'replace' && !empty($this->sqlobj->data)) { - $insertSql = "INSERT INTO {$this->table} "; + $insertSql = "INSERT INTO \"{$this->table}\" "; $fields = '('; $values = 'VALUES('; foreach($this->sqlobj->data as $field => $value) @@ -281,10 +313,19 @@ class dm extends dao $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}}'"; + $pks = $this->getPKColumns(); + if(!empty($pks)) + { + $pks = explode(',', $pks); + $conditions = array(); + foreach($pks as $pk) + { + if(isset($this->sqlobj->data->{$pk})) $conditions[] = " \"{$pk}\" = '{$this->sqlobj->data->{$pk}}'"; + } + if(!empty($conditions)) $updateSql .= ' WHERE ' . implode(' AND ', $conditions); + } - $deleteSql = "DELETE FROM {$this->table} WHERE "; + $deleteSql = "DELETE FROM \"{$this->table}\" WHERE "; $ingore = array(); $ingore['`zt_config`'] = array('value'); foreach($this->sqlobj->data as $field => $value) @@ -389,7 +430,7 @@ EOT; foreach($rawFields as $rawField) { $firstPOS = strpos($rawField->data_type, '('); - $type = substr($rawField->data_type, 0, $firstPOS > 0 ? $firstPOS : strlen($rawField->type)); + $type = substr($rawField->data_type, 0, $firstPOS > 0 ? $firstPOS : strlen($rawField->data_type)); $type = str_replace(array('big', 'small', 'medium', 'tiny', 'var'), '', $type); $field = array(); @@ -420,7 +461,7 @@ EOT; { $field['rule'] = 'skip'; } - $fields[$rawField->field] = $field; + $fields[$rawField->column_name] = $field; } return $fields; } diff --git a/lib/dbh/dbh.class.php b/lib/dbh/dbh.class.php index 28e91aca97..e9cf2d9b73 100644 --- a/lib/dbh/dbh.class.php +++ b/lib/dbh/dbh.class.php @@ -256,6 +256,7 @@ class dbh 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; @@ -398,4 +399,37 @@ class dbh { 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(); + } } diff --git a/module/action/model.php b/module/action/model.php index 0a73f2c237..0ff7312044 100755 --- a/module/action/model.php +++ b/module/action/model.php @@ -1306,9 +1306,13 @@ class actionModel extends model $shadowProducts = $this->dao->select('id')->from(TABLE_PRODUCT)->where('shadow')->eq(1)->fetchPairs(); $projectMultiples = $this->dao->select('id,type,multiple')->from(TABLE_PROJECT)->where('id')->in($projectIdList)->fetchAll('id'); + $docList = $this->loadModel('doc')->getPrivDocs(); + $docLibList = $this->doc->getLibs(); foreach($actions as $i => $action) { + if($action->objectType == 'doc' and !isset($docList[$action->objectID])) unset($actions[$i]); + if($action->objectType == 'doclib' and !isset($docLibList[$action->objectID])) unset($actions[$i]); if($action->objectType == 'product' AND isset($shadowProducts[$action->objectID])) { unset($actions[$i]); @@ -1548,6 +1552,8 @@ class actionModel extends model */ public function setObjectLink($action, $deptUsers, $shadowProducts, $project = null) { + $this->app->loadConfig('doc'); + $action->objectLink = ''; $action->objectLabel = zget($this->lang->action->objectTypes, $action->objectLabel); @@ -1677,9 +1683,10 @@ class actionModel extends model else { $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}"; + if(isset($this->config->doc->spaceMethod[$docLib->type])) $method = $this->config->doc->spaceMethod[$docLib->type]; + if($method == 'myspace') $params = "type=mine&libID={$action->objectID}"; + if($method == 'tablecontents') $params = sprintf($vars, $docLib->type, $docLib->objectID, $action->objectID, $appendLib); + if(!in_array($method, array('myspace', 'tablecontents'))) $params = "objectID={$docLib->objectID}&libID={$action->objectID}"; $action->objectLink = helper::createLink('doc', $method, $params); } } diff --git a/module/api/control.php b/module/api/control.php index b6b7e883ec..95a78e9109 100755 --- a/module/api/control.php +++ b/module/api/control.php @@ -49,6 +49,12 @@ class api extends control $objectID = $this->objectID; $isFirstLoad = $libID ? false : true; + if($release) + { + $browseType = 'byrelease'; + $param = $release; + } + /* Get all api doc libraries. */ $libs = $this->doc->getApiLibs($appendLib, $objectType, $objectID); if(empty($libs) and $objectType != 'nolink') @@ -125,7 +131,7 @@ class api extends control $this->view->objectID = $objectID; $this->view->moduleID = $moduleID; $this->view->version = $version; - $this->view->libTree = $this->doc->getLibTree($libID, $libs, 'api', $moduleID, $objectID, $browseType); + $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) : ''; @@ -163,12 +169,32 @@ class api extends control $this->view->actions = $apiID ? $this->action->getList('api', $apiID) : array(); } + /* Crumbs links array. */ + $lib = zget($libs, $libID); + $type = $lib->product ? 'product' : ($lib->project ? 'project' : 'unlink'); + + $methodName = $type != 'unlink' ? $type . 'Space' : 'index'; + if($this->app->tab == 'doc') $methodName = 'index'; + + $linkObject = zget($lib, $type, 0); + $linkParams = "libID=$lib->id"; + if($methodName != 'index') $linkParams = "objectID=$linkObject&$linkParams"; + + $crumbs[] = html::a(inLink($methodName, $linkParams), html::image("static/svg/interface.svg") . $lib->name); + $moduleList = $this->loadModel('tree')->getParents($api->module); + foreach($moduleList as $module) + { + $linkParams .= "&moduleID=$module->id"; + $crumbs[] = html::a(inLink($methodName, $linkParams), $module->name); + } + $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->crumbs = $crumbs; $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); @@ -178,24 +204,22 @@ class api extends control /** * 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); - /* 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; @@ -218,7 +242,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)")); } } @@ -236,6 +260,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()) @@ -316,6 +341,7 @@ class api extends control $now = helper::now(); $userId = $this->app->user->account; $data = fixer::input('post') + ->trim('name') ->add('lib', $libID) ->skipSpecial('attribute') ->add('addedBy', $userId) @@ -414,8 +440,6 @@ class api extends control */ public function createLib($type = 'product', $objectID = 0) { - if(!in_array($type, array('product', 'project'))) $type = 'product'; - if(!empty($_POST)) { $libID = $this->doc->createApiLib(); @@ -433,7 +457,8 @@ class api extends control return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->createLink('api', 'index', "libID=$libID"))); } - $this->lang->api->aclList['default'] = sprintf($this->lang->api->aclList['default'], $this->lang->{$type}->common); + $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; @@ -512,7 +537,7 @@ class api extends control return print(js::locate($this->createLink('api', 'index'), 'parent.parent')); } - return print(js::locate($this->createLink('api', 'index'), 'parent')); + return print(js::reload('parent')); } } @@ -525,6 +550,7 @@ class api extends control */ public function edit($apiID) { + $api = $this->api->getLibById($apiID); if(helper::isAjaxRequest() && !empty($_POST)) { $changes = $this->api->update($apiID); @@ -536,10 +562,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; @@ -931,4 +956,31 @@ class api extends control $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"); + } } diff --git a/module/api/css/common.css b/module/api/css/common.css index 5cbde1de73..d72371dec4 100644 --- a/module/api/css/common.css +++ b/module/api/css/common.css @@ -159,3 +159,7 @@ form .table-data, #content .table-data {border: 1px solid #e2e2e3;} .paramsTable th {text-align: left!important; font-size: 14px;} .paramsTable td {text-align: left;} + +.info .version, .info .crumbs {float: left;} +.info .crumbs {font-size: 13px; margin-top: 5px; font-weight: normal;} +.info .crumbs img {margin-right: 3px;} diff --git a/module/api/css/createlib.css b/module/api/css/createlib.css index 4b4ded1749..6d28a95d3c 100644 --- a/module/api/css/createlib.css +++ b/module/api/css/createlib.css @@ -3,3 +3,4 @@ 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;} diff --git a/module/api/css/releases.css b/module/api/css/releases.css index 2d9d871192..c9bcc1d090 100644 --- a/module/api/css/releases.css +++ b/module/api/css/releases.css @@ -2,3 +2,5 @@ .c-actions {width: 60px;} tbody tr td {white-space: nowrap; overflow: hidden; text-overflow: clip;} +#mainContent {max-height: 400px;} +#releaseListForm {margin-bottom: 20px;} diff --git a/module/api/js/common.js b/module/api/js/common.js index cc7543ab4e..9680e4b9f8 100644 --- a/module/api/js/common.js +++ b/module/api/js/common.js @@ -200,8 +200,7 @@ $(document).ready(function() */ function redirectParentWindow(libID) { - var link = createLink('api', 'index', 'libID=' + libID); - parent.location.href = link; + parent.location.reload(); } try { diff --git a/module/api/js/createlib.js b/module/api/js/createlib.js index 02a964d4fa..bdc608f4cb 100644 --- a/module/api/js/createlib.js +++ b/module/api/js/createlib.js @@ -1,4 +1,4 @@ -$(document).ready(function() +$(function() { $('#apiForm').ajaxForm({ success: (data) => { @@ -10,4 +10,6 @@ $(document).ready(function() } } }) + + toggleLibType(libType); }); diff --git a/module/api/js/view.js b/module/api/js/view.js new file mode 100644 index 0000000000..f32c457b49 --- /dev/null +++ b/module/api/js/view.js @@ -0,0 +1,121 @@ +/** + * Display the document in full screen. + * + * @access public + * @return void + */ +function fullScreen() +{ + var element = document.getElementById('content'); + var requestMethod = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || element.msRequestFullscreen; + if(requestMethod) + { + var afterEnterFullscreen = function() + { + $('#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); + }; + + var whenFailEnterFullscreen = function(error) + { + $.cookie('isFullScreen', 0); + }; + + try + { + var result = requestMethod.call(element); + if(result && (typeof result.then === 'function' || result instanceof window.Promise)) + { + result.then(afterEnterFullscreen).catch(whenFailEnterFullscreen); + } + else + { + afterEnterFullscreen(); + } + } + catch (error) + { + whenFailEnterFullscreen(error); + } + } + + $('.main-col iframe').css('min-height', $(window).height() + 'px'); +} + +/** + * Exit full screen. + * + * @access public + * @return void + */ +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(); +}); + +document.addEventListener('webkitfullscreenchange', function (e) +{ + if(!document.webkitFullscreenElement) exitFullScreen(); +}); + +document.addEventListener('mozfullscreenchange', function (e) +{ + if(!document.mozFullScreenElement) exitFullScreen(); +}); + +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 = $('
'); + $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(); + }); + }); +}); diff --git a/module/api/lang/de.php b/module/api/lang/de.php index 3a88082d06..8843f01349 100644 --- a/module/api/lang/de.php +++ b/module/api/lang/de.php @@ -61,6 +61,9 @@ $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'; diff --git a/module/api/lang/en.php b/module/api/lang/en.php index b73d0e5656..d635929153 100644 --- a/module/api/lang/en.php +++ b/module/api/lang/en.php @@ -61,6 +61,9 @@ $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'; diff --git a/module/api/lang/fr.php b/module/api/lang/fr.php index a0425ca703..2ef819831d 100644 --- a/module/api/lang/fr.php +++ b/module/api/lang/fr.php @@ -61,6 +61,9 @@ $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'; diff --git a/module/api/lang/zh-cn.php b/module/api/lang/zh-cn.php index a4eeef8b26..bea818e109 100755 --- a/module/api/lang/zh-cn.php +++ b/module/api/lang/zh-cn.php @@ -61,6 +61,9 @@ $lang->api->zentaoAPI = "禅道API文档v1"; $lang->api->search = "搜索"; $lang->api->allLibs = "全部库"; $lang->api->noLinked = "无关联"; +$lang->api->addCatalog = '添加目录'; +$lang->api->editCatalog = '编辑目录'; +$lang->api->deleteCatalog = '删除目录'; /* Common access control lang. */ $lang->api->whiteList = '白名单'; diff --git a/module/api/model.php b/module/api/model.php index 513e95076e..db6c44d62b 100644 --- a/module/api/model.php +++ b/module/api/model.php @@ -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) @@ -414,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) . ')'; } @@ -434,9 +432,7 @@ 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(); @@ -780,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'") diff --git a/module/api/view/content.html.php b/module/api/view/content.html.php index d62e2d3e37..ec29ce4c2b 100644 --- a/module/api/view/content.html.php +++ b/module/api/view/content.html.php @@ -20,19 +20,18 @@
+
', $crumbs);?>
+ ', '', "title='{$lang->fullscreen}' class='btn btn-link fullscreen-btn'");?> id"), '', '', "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"); - echo html::a($deleteURL, '', '', "title='{$lang->api->delete}' class='btn btn-link' target='hiddenwin'"); - } + if(common::hasPriv('api', 'edit')) echo html::a(inlink('edit', "apiID=$api->id"), '', '', "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"), '', '', "title='{$lang->api->delete}' class='btn btn-link' target='hiddenwin'"); } ?> + history?>>
diff --git a/module/api/view/createlib.html.php b/module/api/view/createlib.html.php index 1f90647228..d73e1e5428 100644 --- a/module/api/view/createlib.html.php +++ b/module/api/view/createlib.html.php @@ -79,4 +79,5 @@ productCommon);?> projectCommon);?> + diff --git a/module/api/view/index.html.php b/module/api/view/index.html.php index fd5a30f46c..2b24026b20 100644 --- a/module/api/view/index.html.php +++ b/module/api/view/index.html.php @@ -26,7 +26,7 @@ if($libTree and common::hasPriv('api', 'releases')) echo html::a($this->createLink('api', 'releases', "libID=$libID", 'html', true), " " . $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"), " " . $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), " " . $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 == 'project' ? 'project' : 'product') . "&objectID=$objectID"), ' ' . $lang->api->createLib, '', 'class="btn btn-secondary iframe" data-width="800px"'); + if(common::hasPriv('api', 'createLib')) echo html::a($this->createLink('api', 'createLib', "type=" . ($objectType ? $objectType : 'nolink') . "&objectID=$objectID"), ' ' . $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"), ' ' . $lang->api->createApi, '', 'class="btn btn-primary"'); ?> @@ -37,7 +37,7 @@

doc->noLib;?> ' . $lang->api->createLib, '', 'class="btn btn-info iframe" data-width="800px"'); + if(common::hasPriv('api', 'createLib')) echo html::a(helper::createLink('api', 'createLib', "type=" . ($objectType ? $objectType : 'nolink')), ' ' . $lang->api->createLib, '', 'class="btn btn-info iframe" data-width="800px"'); ?>

diff --git a/module/api/view/releases.html.php b/module/api/view/releases.html.php index 54e394dd5e..3798ff0272 100644 --- a/module/api/view/releases.html.php +++ b/module/api/view/releases.html.php @@ -13,7 +13,6 @@
-
@@ -62,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() +} diff --git a/module/block/control.php b/module/block/control.php index 229c6fefc8..76415e75ec 100755 --- a/module/block/control.php +++ b/module/block/control.php @@ -42,6 +42,7 @@ class block extends control if($module == 'my') { $modules = $this->lang->block->moduleList; + unset($modules['doc']); list($programModule, $programMethod) = explode('-', $this->config->programLink); list($productModule, $productMethod) = explode('-', $this->config->productLink); @@ -748,7 +749,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('t1.id,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') @@ -2033,6 +2034,86 @@ class block extends control $this->view->projects = $this->loadModel('project')->getOverviewList('byStatus', $status, $orderBy, $count); } + /** + * Print document statistic block. + * + * @access public + * @return void + */ + public function printDocStatisticBlock() + { + } + + /** + * Print document dynamic block. + * + * @access public + * @return void + */ + public function printDocDynamicBlock() + { + } + + /** + * Print my collection of documents block. + * + * @access public + * @return void + */ + public function printMyCollectionBlock() + { + } + + /** + * Print recent update block. + * + * @access public + * @return void + */ + public function printRecentUpdateBlock() + { + } + + /** + * Print view list block. + * + * @access public + * @return void + */ + public function printViewListBlock() + { + } + + /** + * Print collect list block. + * + * @access public + * @return void + */ + public function printCollectListBlock() + { + } + + /** + * Print product's document block. + * + * @access public + * @return void + */ + public function printProductDocBlock() + { + } + + /** + * Print project's document block. + * + * @access public + * @return void + */ + public function printProjectDocBlock() + { + } + /** * Print guide block * diff --git a/module/block/lang/de.php b/module/block/lang/de.php index 978f144d63..a113c81711 100644 --- a/module/block/lang/de.php +++ b/module/block/lang/de.php @@ -332,6 +332,42 @@ $lang->block->default['full']['my']['10']['grid'] = 8; $lang->block->default['full']['my']['10']['params']['orderBy'] = 'id_desc'; $lang->block->default['full']['my']['10']['params']['count'] = '15'; +/* Doc module block. */ +$lang->block->default['doc']['1']['title'] = 'Statistic'; +$lang->block->default['doc']['1']['block'] = 'statistic'; +$lang->block->default['doc']['1']['grid'] = 8; + +$lang->block->default['doc']['2']['title'] = 'Dynamic'; +$lang->block->default['doc']['2']['block'] = 'docdynamic'; +$lang->block->default['doc']['2']['grid'] = 4; + +$lang->block->default['doc']['3']['title'] = 'My Collection'; +$lang->block->default['doc']['3']['block'] = 'mycollection'; +$lang->block->default['doc']['3']['grid'] = 8; + +$lang->block->default['doc']['4']['title'] = 'Recently Update'; +$lang->block->default['doc']['4']['block'] = 'recentupdate'; +$lang->block->default['doc']['4']['grid'] = 8; + +$lang->block->default['doc']['5']['title'] = 'Browse Leaderboard'; +$lang->block->default['doc']['5']['block'] = 'viewlist'; +$lang->block->default['doc']['5']['grid'] = 4; + +if($config->vision == 'rnd') +{ + $lang->block->default['doc']['6']['title'] = $lang->productCommon . 'Document'; + $lang->block->default['doc']['6']['block'] = 'productdoc'; + $lang->block->default['doc']['6']['grid'] = 8; +} + +$lang->block->default['doc']['7']['title'] = 'Favorite Leaderboard'; +$lang->block->default['doc']['7']['block'] = 'collectlist'; +$lang->block->default['doc']['7']['grid'] = 4; + +$lang->block->default['doc']['8']['title'] = $lang->projectCommon . 'Document'; +$lang->block->default['doc']['8']['block'] = 'projectdoc'; +$lang->block->default['doc']['8']['grid'] = 8; + $lang->block->count = 'Count'; $lang->block->type = 'Type'; $lang->block->orderBy = 'Order by'; @@ -360,6 +396,7 @@ $lang->block->moduleList['project'] = $lang->projectCommon; $lang->block->moduleList['execution'] = $lang->execution->common; $lang->block->moduleList['qa'] = 'QA'; $lang->block->moduleList['todo'] = 'Todos'; +$lang->block->moduleList['doc'] = 'Doc'; $lang->block->modules['project'] = new stdclass(); $lang->block->modules['project']->availableBlocks = new stdclass(); @@ -414,6 +451,17 @@ $lang->block->modules['todo'] = new stdclass(); $lang->block->modules['todo']->availableBlocks = new stdclass(); $lang->block->modules['todo']->availableBlocks->list = 'Todos'; +$lang->block->modules['doc'] = new stdclass(); +$lang->block->modules['doc']->availableBlocks = new stdclass(); +$lang->block->modules['doc']->availableBlocks->statistic = 'Statistic'; +$lang->block->modules['doc']->availableBlocks->docdynamic = 'Dynamic'; +$lang->block->modules['doc']->availableBlocks->mycollection = 'My Collection'; +$lang->block->modules['doc']->availableBlocks->recentupdate = 'Recently Update'; +$lang->block->modules['doc']->availableBlocks->viewlist = 'Browse Leaderboard'; +$lang->block->modules['doc']->availableBlocks->productdoc = $lang->productCommon . 'Document'; +$lang->block->modules['doc']->availableBlocks->collectlist = 'Favorite Leaderboard'; +$lang->block->modules['doc']->availableBlocks->projectdoc = $lang->projectCommon . 'Document'; + $lang->block->orderByList = new stdclass(); $lang->block->orderByList->product = array(); diff --git a/module/block/lang/en.php b/module/block/lang/en.php index 2a19a3bcec..0a614422fc 100644 --- a/module/block/lang/en.php +++ b/module/block/lang/en.php @@ -332,6 +332,42 @@ $lang->block->default['full']['my']['10']['grid'] = 8; $lang->block->default['full']['my']['10']['params']['orderBy'] = 'id_desc'; $lang->block->default['full']['my']['10']['params']['count'] = '15'; +/* Doc module block. */ +$lang->block->default['doc']['1']['title'] = 'Statistic'; +$lang->block->default['doc']['1']['block'] = 'statistic'; +$lang->block->default['doc']['1']['grid'] = 8; + +$lang->block->default['doc']['2']['title'] = 'Dynamic'; +$lang->block->default['doc']['2']['block'] = 'docdynamic'; +$lang->block->default['doc']['2']['grid'] = 4; + +$lang->block->default['doc']['3']['title'] = 'My Collection'; +$lang->block->default['doc']['3']['block'] = 'mycollection'; +$lang->block->default['doc']['3']['grid'] = 8; + +$lang->block->default['doc']['4']['title'] = 'Recently update'; +$lang->block->default['doc']['4']['block'] = 'recentupdate'; +$lang->block->default['doc']['4']['grid'] = 8; + +$lang->block->default['doc']['5']['title'] = 'Browse Leaderboard'; +$lang->block->default['doc']['5']['block'] = 'viewlist'; +$lang->block->default['doc']['5']['grid'] = 4; + +if($config->vision == 'rnd') +{ + $lang->block->default['doc']['6']['title'] = $lang->productCommon . 'Document'; + $lang->block->default['doc']['6']['block'] = 'productdoc'; + $lang->block->default['doc']['6']['grid'] = 8; +} + +$lang->block->default['doc']['7']['title'] = 'Favorite Leaderboard'; +$lang->block->default['doc']['7']['block'] = 'collectlist'; +$lang->block->default['doc']['7']['grid'] = 4; + +$lang->block->default['doc']['8']['title'] = $lang->projectCommon . 'Document'; +$lang->block->default['doc']['8']['block'] = 'projectdoc'; +$lang->block->default['doc']['8']['grid'] = 8; + $lang->block->count = 'Count'; $lang->block->type = 'Type'; $lang->block->orderBy = 'Order by'; @@ -360,6 +396,7 @@ $lang->block->moduleList['project'] = $lang->projectCommon; $lang->block->moduleList['execution'] = $lang->execution->common; $lang->block->moduleList['qa'] = 'Test'; $lang->block->moduleList['todo'] = 'Todo'; +$lang->block->moduleList['doc'] = 'Doc'; $lang->block->modules['project'] = new stdclass(); $lang->block->modules['project']->availableBlocks = new stdclass(); @@ -414,6 +451,17 @@ $lang->block->modules['todo'] = new stdclass(); $lang->block->modules['todo']->availableBlocks = new stdclass(); $lang->block->modules['todo']->availableBlocks->list = 'Todo'; +$lang->block->modules['doc'] = new stdclass(); +$lang->block->modules['doc']->availableBlocks = new stdclass(); +$lang->block->modules['doc']->availableBlocks->statistic = 'Statistic'; +$lang->block->modules['doc']->availableBlocks->docdynamic = 'Dynamic'; +$lang->block->modules['doc']->availableBlocks->mycollection = 'My Collection'; +$lang->block->modules['doc']->availableBlocks->recentupdate = 'Recently Update'; +$lang->block->modules['doc']->availableBlocks->viewlist = 'Browse Leaderboard'; +$lang->block->modules['doc']->availableBlocks->productdoc = $lang->productCommon . 'Document'; +$lang->block->modules['doc']->availableBlocks->collectlist = 'Favorite Leaderboard'; +$lang->block->modules['doc']->availableBlocks->projectdoc = $lang->projectCommon . 'Document'; + $lang->block->orderByList = new stdclass(); $lang->block->orderByList->product = array(); diff --git a/module/block/lang/fr.php b/module/block/lang/fr.php index 0485e43e45..406b27cb53 100644 --- a/module/block/lang/fr.php +++ b/module/block/lang/fr.php @@ -332,6 +332,42 @@ $lang->block->default['full']['my']['10']['grid'] = 8; $lang->block->default['full']['my']['10']['params']['orderBy'] = 'id_desc'; $lang->block->default['full']['my']['10']['params']['count'] = '15'; +/* Doc module block. */ +$lang->block->default['doc']['1']['title'] = 'Statistic'; +$lang->block->default['doc']['1']['block'] = 'statistic'; +$lang->block->default['doc']['1']['grid'] = 8; + +$lang->block->default['doc']['2']['title'] = 'Dynamic'; +$lang->block->default['doc']['2']['block'] = 'docdynamic'; +$lang->block->default['doc']['2']['grid'] = 4; + +$lang->block->default['doc']['3']['title'] = 'My Collection'; +$lang->block->default['doc']['3']['block'] = 'mycollection'; +$lang->block->default['doc']['3']['grid'] = 8; + +$lang->block->default['doc']['4']['title'] = 'Recently Update'; +$lang->block->default['doc']['4']['block'] = 'recentupdate'; +$lang->block->default['doc']['4']['grid'] = 8; + +$lang->block->default['doc']['5']['title'] = 'Browse Leaderboard'; +$lang->block->default['doc']['5']['block'] = 'viewlist'; +$lang->block->default['doc']['5']['grid'] = 4; + +if($config->vision == 'rnd') +{ + $lang->block->default['doc']['6']['title'] = $lang->productCommon . 'Document'; + $lang->block->default['doc']['6']['block'] = 'productdoc'; + $lang->block->default['doc']['6']['grid'] = 8; +} + +$lang->block->default['doc']['7']['title'] = 'Favorite Leaderboard'; +$lang->block->default['doc']['7']['block'] = 'collectlist'; +$lang->block->default['doc']['7']['grid'] = 4; + +$lang->block->default['doc']['8']['title'] = $lang->projectCommon . 'Document'; +$lang->block->default['doc']['8']['block'] = 'projectdoc'; +$lang->block->default['doc']['8']['grid'] = 8; + $lang->block->count = 'Numéro'; $lang->block->type = 'Type'; $lang->block->orderBy = 'Trié par'; @@ -360,6 +396,7 @@ $lang->block->moduleList['project'] = $lang->projectCommon; $lang->block->moduleList['execution'] = $lang->execution->common; $lang->block->moduleList['qa'] = 'Test'; $lang->block->moduleList['todo'] = 'Todo'; +$lang->block->moduleList['doc'] = 'Doc'; $lang->block->modules['project'] = new stdclass(); $lang->block->modules['project']->availableBlocks = new stdclass(); @@ -414,6 +451,17 @@ $lang->block->modules['todo'] = new stdclass(); $lang->block->modules['todo']->availableBlocks = new stdclass(); $lang->block->modules['todo']->availableBlocks->list = 'Todo'; +$lang->block->modules['doc'] = new stdclass(); +$lang->block->modules['doc']->availableBlocks = new stdclass(); +$lang->block->modules['doc']->availableBlocks->statistic = 'Statistic'; +$lang->block->modules['doc']->availableBlocks->docdynamic = 'Dynamic'; +$lang->block->modules['doc']->availableBlocks->mycollection = 'My Collection'; +$lang->block->modules['doc']->availableBlocks->recentupdate = 'Recently Update'; +$lang->block->modules['doc']->availableBlocks->viewlist = 'Browse Leaderboard'; +$lang->block->modules['doc']->availableBlocks->productdoc = $lang->productCommon . 'Document'; +$lang->block->modules['doc']->availableBlocks->collectlist = 'Favorite Leaderboard'; +$lang->block->modules['doc']->availableBlocks->projectdoc = $lang->projectCommon . 'Document'; + $lang->block->orderByList = new stdclass(); $lang->block->orderByList->product = array(); diff --git a/module/block/lang/zh-cn.php b/module/block/lang/zh-cn.php index 0af3f1887a..ea8a382d39 100644 --- a/module/block/lang/zh-cn.php +++ b/module/block/lang/zh-cn.php @@ -332,6 +332,42 @@ $lang->block->default['full']['my']['10']['grid'] = 8; $lang->block->default['full']['my']['10']['params']['orderBy'] = 'id_desc'; $lang->block->default['full']['my']['10']['params']['count'] = '15'; +/* Doc module block. */ +$lang->block->default['doc']['1']['title'] = '文档统计'; +$lang->block->default['doc']['1']['block'] = 'statistic'; +$lang->block->default['doc']['1']['grid'] = 8; + +$lang->block->default['doc']['2']['title'] = '文档动态'; +$lang->block->default['doc']['2']['block'] = 'docdynamic'; +$lang->block->default['doc']['2']['grid'] = 4; + +$lang->block->default['doc']['3']['title'] = '我的收藏'; +$lang->block->default['doc']['3']['block'] = 'mycollection'; +$lang->block->default['doc']['3']['grid'] = 8; + +$lang->block->default['doc']['4']['title'] = '最近更新'; +$lang->block->default['doc']['4']['block'] = 'recentupdate'; +$lang->block->default['doc']['4']['grid'] = 8; + +$lang->block->default['doc']['5']['title'] = '浏览排行榜'; +$lang->block->default['doc']['5']['block'] = 'viewlist'; +$lang->block->default['doc']['5']['grid'] = 4; + +if($config->vision == 'rnd') +{ + $lang->block->default['doc']['6']['title'] = $lang->productCommon . '文档'; + $lang->block->default['doc']['6']['block'] = 'productdoc'; + $lang->block->default['doc']['6']['grid'] = 8; +} + +$lang->block->default['doc']['7']['title'] = '收藏排行榜'; +$lang->block->default['doc']['7']['block'] = 'collectlist'; +$lang->block->default['doc']['7']['grid'] = 4; + +$lang->block->default['doc']['8']['title'] = $lang->projectCommon . '文档'; +$lang->block->default['doc']['8']['block'] = 'projectdoc'; +$lang->block->default['doc']['8']['grid'] = 8; + $lang->block->count = '数量'; $lang->block->type = '类型'; $lang->block->orderBy = '排序'; @@ -360,6 +396,7 @@ $lang->block->moduleList['project'] = $lang->projectCommon; $lang->block->moduleList['execution'] = $lang->execution->common; $lang->block->moduleList['qa'] = '测试'; $lang->block->moduleList['todo'] = '待办'; +$lang->block->moduleList['doc'] = '文档'; $lang->block->modules['project'] = new stdclass(); $lang->block->modules['project']->availableBlocks = new stdclass(); @@ -414,6 +451,17 @@ $lang->block->modules['todo'] = new stdclass(); $lang->block->modules['todo']->availableBlocks = new stdclass(); $lang->block->modules['todo']->availableBlocks->list = '待办列表'; +$lang->block->modules['doc'] = new stdclass(); +$lang->block->modules['doc']->availableBlocks = new stdclass(); +$lang->block->modules['doc']->availableBlocks->statistic = '文档统计'; +$lang->block->modules['doc']->availableBlocks->docdynamic = '文档动态'; +$lang->block->modules['doc']->availableBlocks->mycollection = '我的收藏'; +$lang->block->modules['doc']->availableBlocks->recentupdate = '最近更新'; +$lang->block->modules['doc']->availableBlocks->viewlist = '浏览排行榜'; +$lang->block->modules['doc']->availableBlocks->productdoc = $lang->productCommon . '文档'; +$lang->block->modules['doc']->availableBlocks->collectlist = '收藏排行榜'; +$lang->block->modules['doc']->availableBlocks->projectdoc = $lang->projectCommon . '文档'; + $lang->block->orderByList = new stdclass(); $lang->block->orderByList->product = array(); diff --git a/module/block/model.php b/module/block/model.php index fcb3d99bab..21be92da64 100644 --- a/module/block/model.php +++ b/module/block/model.php @@ -558,6 +558,7 @@ class blockModel extends model if($module == 'project') return $this->getProjectStatisticParams(); if($module == 'execution') return $this->getExecutionStatisticParams(); if($module == 'qa') return $this->getQaStatisticParams(); + if($module == 'doc') return $this->getDocStatisticParams(); $params = new stdclass(); $params = $this->appendCountParams($params); @@ -628,6 +629,17 @@ class blockModel extends model return json_encode($params); } + /** + * Get document statistic params. + * + * @access public + * @return bool + */ + public function getDocStatisticParams() + { + return false; + } + /** * Get recent project pararms. * @@ -718,7 +730,7 @@ class blockModel extends model $params = $this->appendCountParams(); $params->type['name'] = $this->lang->block->type; - $params->type['options'] = $this->lang->issue->labelList; + $params->type['options'] = $this->lang->issue->featureBar['browse']; $params->type['control'] = 'select'; $params->orderBy['name'] = $this->lang->block->orderBy; @@ -1061,6 +1073,83 @@ class blockModel extends model return false; } + /** + * Get document dynamic params. + * + * @access public + * @return bool + */ + public function getDocDynamicParams() + { + return false; + } + + /** + * Get my collection params. + * + * @access public + * @return bool + */ + public function getMyCollectionParams() + { + return false; + } + + /** + * Get recent update params. + * + * @access public + * @return bool + */ + public function getRecentUpdateParams() + { + return false; + } + + /** + * Get view list params. + * + * @access public + * @return bool + */ + public function getViewlistParams() + { + return false; + } + + /** + * Get product document params. + * + * @access public + * @return bool + */ + public function getProductDocParams() + { + return false; + } + + /** + * Get collect list params. + * + * @access public + * @return bool + */ + public function getCollectListParams() + { + return false; + } + + /** + * Get project document params. + * + * @access public + * @return bool + */ + public function getProjectDocParams() + { + return false; + } + /** * Get the total estimated man hours required. * diff --git a/module/report/js/bugassign.js b/module/block/view/collectlistblock.html.php similarity index 100% rename from module/report/js/bugassign.js rename to module/block/view/collectlistblock.html.php diff --git a/module/block/view/docdynamicblock.html.php b/module/block/view/docdynamicblock.html.php new file mode 100644 index 0000000000..e69de29bb2 diff --git a/module/block/view/docstatisticblock.html.php b/module/block/view/docstatisticblock.html.php new file mode 100644 index 0000000000..e69de29bb2 diff --git a/module/block/view/mycollectionblock.html.php b/module/block/view/mycollectionblock.html.php new file mode 100644 index 0000000000..e69de29bb2 diff --git a/module/block/view/productdocblock.html.php b/module/block/view/productdocblock.html.php new file mode 100644 index 0000000000..e69de29bb2 diff --git a/module/block/view/projectdocblock.html.php b/module/block/view/projectdocblock.html.php new file mode 100644 index 0000000000..e69de29bb2 diff --git a/module/block/view/recentupdateblock.html.php b/module/block/view/recentupdateblock.html.php new file mode 100644 index 0000000000..e69de29bb2 diff --git a/module/block/view/viewlistblock.html.php b/module/block/view/viewlistblock.html.php new file mode 100644 index 0000000000..e69de29bb2 diff --git a/module/branch/model.php b/module/branch/model.php index 51f70c7fb0..e7983045fa 100644 --- a/module/branch/model.php +++ b/module/branch/model.php @@ -105,6 +105,8 @@ class branchModel extends model */ public function getPairs($productID, $params = '', $executionID = 0, $mergedBranches = '') { + if(!$productID) $productID = 0; + $executionBranches = array(); if($executionID) { diff --git a/module/bug/control.php b/module/bug/control.php index e6a755bd70..77e404814d 100755 --- a/module/bug/control.php +++ b/module/bug/control.php @@ -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. */ diff --git a/module/bug/js/common.js b/module/bug/js/common.js index e50f5bf3ed..88af3d0079 100644 --- a/module/bug/js/common.js +++ b/module/bug/js/common.js @@ -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); diff --git a/module/bug/model.php b/module/bug/model.php index 119d5e1bb7..6327665556 100644 --- a/module/bug/model.php +++ b/module/bug/model.php @@ -62,7 +62,7 @@ class bugModel extends model $bug = fixer::input('post') ->setDefault('openedBy', $this->app->user->account) ->setDefault('openedDate', $now) - ->setDefault('project,execution,story,task', 0) + ->setDefault('project,execution,story,task,duplicateBug,linkBug', 0) ->setDefault('openedBuild', '') ->setDefault('notifyEmail', '') ->setDefault('deadline', '0000-00-00') diff --git a/module/chart/config.php b/module/chart/config.php new file mode 100644 index 0000000000..a10083cf02 --- /dev/null +++ b/module/chart/config.php @@ -0,0 +1,9 @@ +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'; diff --git a/module/chart/control.php b/module/chart/control.php new file mode 100644 index 0000000000..71e3d63bf9 --- /dev/null +++ b/module/chart/control.php @@ -0,0 +1,212 @@ + + * @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'] .= '
'; + $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'] .= "{$this->lang->chart->colon}"; + $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'] .= '
'; + } + 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'] = "
"; + $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'] .= "
"; + } + + /* 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'] .= '
'; + $filterHtml['item'] .= ""; + $filterHtml['item'] .= '' . $this->lang->chart->colon . ''; + $filterHtml['item'] .= ""; + $filterHtml['item'] .= '
'; + } + 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'] = "
"; + $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'] .= "
"; + } + + $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 = $this->chart->getFilterFormat($filters); + + $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); + } +} diff --git a/module/chart/css/common.css b/module/chart/css/common.css new file mode 100644 index 0000000000..daca1be13f --- /dev/null +++ b/module/chart/css/common.css @@ -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;} diff --git a/module/chart/css/preview.css b/module/chart/css/preview.css new file mode 100644 index 0000000000..bcb34a8496 --- /dev/null +++ b/module/chart/css/preview.css @@ -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;} diff --git a/module/chart/js/common.js b/module/chart/js/common.js new file mode 100644 index 0000000000..9e727b3bcb --- /dev/null +++ b/module/chart/js/common.js @@ -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); +} diff --git a/module/chart/js/preview.js b/module/chart/js/preview.js new file mode 100644 index 0000000000..44eb412c0e --- /dev/null +++ b/module/chart/js/preview.js @@ -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; +} diff --git a/module/chart/lang/de.php b/module/chart/lang/de.php new file mode 100644 index 0000000000..ef7fc798b9 --- /dev/null +++ b/module/chart/lang/de.php @@ -0,0 +1,33 @@ +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'; diff --git a/module/chart/lang/en.php b/module/chart/lang/en.php new file mode 100644 index 0000000000..ef7fc798b9 --- /dev/null +++ b/module/chart/lang/en.php @@ -0,0 +1,33 @@ +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'; diff --git a/module/chart/lang/fr.php b/module/chart/lang/fr.php new file mode 100644 index 0000000000..ef7fc798b9 --- /dev/null +++ b/module/chart/lang/fr.php @@ -0,0 +1,33 @@ +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'; diff --git a/module/chart/lang/zh-cn.php b/module/chart/lang/zh-cn.php new file mode 100644 index 0000000000..f3cdbe9097 --- /dev/null +++ b/module/chart/lang/zh-cn.php @@ -0,0 +1,33 @@ +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'] = '最小值'; diff --git a/module/chart/model.php b/module/chart/model.php new file mode 100644 index 0000000000..a0b3d342b9 --- /dev/null +++ b/module/chart/model.php @@ -0,0 +1,683 @@ + + * @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 .= "
    • "; + } + + $charts = $readyCharts[$group->id]; + foreach($charts as $chart) + { + $chart->currentGroup = $group->id; + if(!$firstChart) $firstChart = $chart; + + $chartTree .= "
    • {$chart->name}
    • "; + } + if($group->grade == 2) $chartTree .= '
  • '; + + $index++; + } + + if($chartTree) $chartTree = "
      " . $chartTree . '
    '; + + $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}
    {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; + } + + public function getFilterFormat($filters) + { + $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; + if(!is_array($default)) $default = array($default); + $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; + } + } + + return $filterFormat; + } +} + diff --git a/module/chart/view/preview.html.php b/module/chart/view/preview.html.php new file mode 100644 index 0000000000..e1fc3d1fb1 --- /dev/null +++ b/module/chart/view/preview.html.php @@ -0,0 +1,118 @@ + + * @package chart + * @version $Id$ + * @link http://www.zentao.net + */ +?> +getModuleRoot() . 'common/view/header.html.php';?> + + +id) ? $group->id : 0);?> + +chart->noChartSelected);?> +chart);?> +chart->widthInput);?> +chart->widthDate);?> +bi->pickerHeight);?> + + + +
    +
    +
    +
    +
    name) ? $group->name : '';?>
    +
    +
    + +
    +
    + chart->noChart;?> +
    +
    + +
    + +
    + + chart->preview, '', 'btn btn-primary');?> +
    +
    + + config->edition == 'open'):?> +
    + isINT)) ? $lang->bizVersionINT : $lang->bizVersion;?> +
    + +
    +
    +
    +
    +
    + +
    +
    + chart->noChart;?> +
    +
    + +
    +
    + +
    +
    +
    + name;?> + desc)):?> + + +
    +
    +
    +
    +
    + filters)):?> +
    chart->query, "data-chart={$chart->currentGroup}{$chart->id}", 'btn btn-primary btn-query');?>
    + +
    +
    +
    +
    + + +
    +
    +
    +getModuleRoot() . 'common/view/footer.html.php';?> + + diff --git a/module/common/lang/common.php b/module/common/lang/common.php index 3d6f838585..3f8d0a07e2 100644 --- a/module/common/lang/common.php +++ b/module/common/lang/common.php @@ -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(); diff --git a/module/common/lang/de.php b/module/common/lang/de.php index 885b478670..e4980a1b5e 100644 --- a/module/common/lang/de.php +++ b/module/common/lang/de.php @@ -48,6 +48,8 @@ $lang->tutorialAB = 'Tutorial'; $lang->runInfo = "
    Time %s MS, Memory %s KB, Query %s.
    "; $lang->agreement = "I have read and agreed to the terms and conditions of Z PUBLIC LICENSE 1.2 . Without authorization, I should not remove, hide or cover any logos/links of ZenTao."; $lang->designedByAIUX = " AIUX"; +$lang->bizVersion = 'Testen Sie ZenTao Biz für mehr Informationen!'; +$lang->bizVersionINT = 'Testen Sie ZenTao Biz für mehr Informationen!'; $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'; @@ -344,7 +347,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.'; diff --git a/module/common/lang/en.php b/module/common/lang/en.php index 678605b17f..162fae5866 100644 --- a/module/common/lang/en.php +++ b/module/common/lang/en.php @@ -48,6 +48,8 @@ $lang->tutorialAB = 'Tutorial'; $lang->runInfo = "
    Time %s MS, Memory %s KB, Query %s.
    "; $lang->agreement = "I have read and agreed to the terms and conditions. Without authorization, I should not remove, hide or cover any logos/links of ZenTao."; $lang->designedByAIUX = " AIUX"; +$lang->bizVersion = 'Try ZenTao Biz for more!'; +$lang->bizVersionINT = 'Try ZenTao Biz for more!'; $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'; @@ -341,7 +344,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.'; diff --git a/module/common/lang/fr.php b/module/common/lang/fr.php index 96e345af52..73d8d8447c 100644 --- a/module/common/lang/fr.php +++ b/module/common/lang/fr.php @@ -48,6 +48,8 @@ $lang->tutorialAB = 'Tutorial'; $lang->runInfo = "
    Time %s MS, Memory %s KB, Query %s.
    "; $lang->agreement = "J'ai lu et j'accepte les termes et conditions de la Z PUBLIC LICENSE 1.2 . Sans autorisation, je ne dois pas supprimer, masquer ou couvrir les logos / liens de ZenTao."; $lang->designedByAIUX = " AIUX"; +$lang->bizVersion = 'Essayez ZenTao Biz pour en savoir plus!'; +$lang->bizVersionINT = 'Essayez ZenTao Biz pour en savoir plus!'; $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'; @@ -341,7 +344,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é.'; diff --git a/module/common/lang/menu.php b/module/common/lang/menu.php index cb72edae29..3ca59f44a8 100644 --- a/module/common/lang/menu.php +++ b/module/common/lang/menu.php @@ -519,10 +519,12 @@ $lang->doc->menuOrder[30] = 'custom'; $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(); @@ -631,6 +633,7 @@ $lang->navGroup->api = 'doc'; $lang->navGroup->screen = 'report'; $lang->navGroup->pivot = 'report'; +$lang->navGroup->chart = 'report'; $lang->navGroup->bidesign = 'report'; $lang->navGroup->qa = 'qa'; diff --git a/module/common/lang/zh-cn.php b/module/common/lang/zh-cn.php index 8b9d926aed..723940b1b7 100644 --- a/module/common/lang/zh-cn.php +++ b/module/common/lang/zh-cn.php @@ -48,6 +48,8 @@ $lang->tutorialAB = '新手引导'; $lang->runInfo = "
    时间: %s 毫秒, 内存: %s KB, 查询: %s.
    "; $lang->agreement = "已阅读并同意。未经许可,不得去除、隐藏或遮掩禅道软件的任何标志及链接。"; $lang->designedByAIUX = " 艾体验设计"; +$lang->bizVersion = '更多精彩,尽在企业版!'; +$lang->bizVersionINT = '更多精彩,尽在企业版!'; $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; @@ -341,7 +344,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%的结果集进行统计。'; diff --git a/module/common/lang/zh-tw.php b/module/common/lang/zh-tw.php index 7e3744a38f..bd85fa53b2 100644 --- a/module/common/lang/zh-tw.php +++ b/module/common/lang/zh-tw.php @@ -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%的結果集進行統計。'; diff --git a/module/common/model.php b/module/common/model.php index 927402fc84..345099e229 100644 --- a/module/common/model.php +++ b/module/common/model.php @@ -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,10 +604,9 @@ class commonModel extends model if($objectType == 'kanbanspace') $createMethod = 'createSpace'; if(strpos('|bug|execution|kanbanspace|', "|$objectType|") !== false) $needPrintDivider = true; - if($objectType == 'doc' and !common::hasPriv('doc', 'tableContents')) continue; - $hasPriv = common::hasPriv($module, $createMethod); - if($objectType == 'doc' and !$hasPriv and common::hasPriv('api', 'create')) $hasPriv = true; + 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. */ diff --git a/module/company/control.php b/module/company/control.php index 9952b5f9df..6a84f863e0 100755 --- a/module/company/control.php +++ b/module/company/control.php @@ -74,7 +74,7 @@ class company extends control $users = $this->company->getUsers($browseType, $type, $queryID, $deptID, $sort, $pager); /* Process the sql, get the conditon partion, save it to session. */ - $this->loadModel('common')->saveQueryCondition($this->company->user->dao->get(), 'user', true); + $this->loadModel('common')->saveQueryCondition($this->dao->get(), 'user', true); /* Remove passwd. */ foreach($users as $user) unset($user->password); diff --git a/module/dataview/lang/de.php b/module/dataview/lang/de.php new file mode 100644 index 0000000000..e5dce9a094 --- /dev/null +++ b/module/dataview/lang/de.php @@ -0,0 +1,3 @@ +dataview->id = 'ID'; +$lang->dataview->name = 'Name'; diff --git a/module/dataview/lang/en.php b/module/dataview/lang/en.php new file mode 100644 index 0000000000..e5dce9a094 --- /dev/null +++ b/module/dataview/lang/en.php @@ -0,0 +1,3 @@ +dataview->id = 'ID'; +$lang->dataview->name = 'Name'; diff --git a/module/dataview/lang/fr.php b/module/dataview/lang/fr.php new file mode 100644 index 0000000000..e5dce9a094 --- /dev/null +++ b/module/dataview/lang/fr.php @@ -0,0 +1,3 @@ +dataview->id = 'ID'; +$lang->dataview->name = 'Name'; diff --git a/module/dataview/lang/zh-cn.php b/module/dataview/lang/zh-cn.php new file mode 100644 index 0000000000..f4e3a0a39f --- /dev/null +++ b/module/dataview/lang/zh-cn.php @@ -0,0 +1,3 @@ +dataview->id = '编号'; +$lang->dataview->name = '名称'; diff --git a/module/dataview/table/bug.php b/module/dataview/table/bug.php new file mode 100644 index 0000000000..53cc4f8d55 --- /dev/null +++ b/module/dataview/table/bug.php @@ -0,0 +1,63 @@ +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); diff --git a/module/dataview/table/bugbuild.php b/module/dataview/table/bugbuild.php new file mode 100644 index 0000000000..84d8f87008 --- /dev/null +++ b/module/dataview/table/bugbuild.php @@ -0,0 +1,92 @@ +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); diff --git a/module/dataview/table/build.php b/module/dataview/table/build.php new file mode 100644 index 0000000000..82de562429 --- /dev/null +++ b/module/dataview/table/build.php @@ -0,0 +1,45 @@ +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); diff --git a/module/dataview/table/casemodule.php b/module/dataview/table/casemodule.php new file mode 100644 index 0000000000..71c4d5f7bb --- /dev/null +++ b/module/dataview/table/casemodule.php @@ -0,0 +1,18 @@ +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(); diff --git a/module/dataview/table/casestep.php b/module/dataview/table/casestep.php new file mode 100644 index 0000000000..009c3d7447 --- /dev/null +++ b/module/dataview/table/casestep.php @@ -0,0 +1,30 @@ +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); diff --git a/module/dataview/table/execution.php b/module/dataview/table/execution.php new file mode 100644 index 0000000000..6868b5cf16 --- /dev/null +++ b/module/dataview/table/execution.php @@ -0,0 +1,37 @@ +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); diff --git a/module/dataview/table/product.php b/module/dataview/table/product.php new file mode 100644 index 0000000000..13689982db --- /dev/null +++ b/module/dataview/table/product.php @@ -0,0 +1,41 @@ +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); diff --git a/module/dataview/table/productplan.php b/module/dataview/table/productplan.php new file mode 100644 index 0000000000..4130e5c2fc --- /dev/null +++ b/module/dataview/table/productplan.php @@ -0,0 +1,28 @@ +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); diff --git a/module/dataview/table/project.php b/module/dataview/table/project.php new file mode 100644 index 0000000000..2f2def927f --- /dev/null +++ b/module/dataview/table/project.php @@ -0,0 +1,30 @@ +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(); diff --git a/module/dataview/table/release.php b/module/dataview/table/release.php new file mode 100644 index 0000000000..a0c74459d5 --- /dev/null +++ b/module/dataview/table/release.php @@ -0,0 +1,46 @@ +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); diff --git a/module/dataview/table/story.php b/module/dataview/table/story.php new file mode 100644 index 0000000000..022c4225b6 --- /dev/null +++ b/module/dataview/table/story.php @@ -0,0 +1,49 @@ +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); diff --git a/module/dataview/table/task.php b/module/dataview/table/task.php new file mode 100644 index 0000000000..d5d1a562d1 --- /dev/null +++ b/module/dataview/table/task.php @@ -0,0 +1,63 @@ +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); diff --git a/module/dataview/table/team.php b/module/dataview/table/team.php new file mode 100644 index 0000000000..ef28e65a4e --- /dev/null +++ b/module/dataview/table/team.php @@ -0,0 +1,36 @@ +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); diff --git a/module/dataview/table/testcase.php b/module/dataview/table/testcase.php new file mode 100644 index 0000000000..53d99060df --- /dev/null +++ b/module/dataview/table/testcase.php @@ -0,0 +1,52 @@ +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); diff --git a/module/dataview/table/testresult.php b/module/dataview/table/testresult.php new file mode 100644 index 0000000000..6b951aef68 --- /dev/null +++ b/module/dataview/table/testresult.php @@ -0,0 +1,84 @@ +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); diff --git a/module/dataview/table/testrun.php b/module/dataview/table/testrun.php new file mode 100644 index 0000000000..a5a5e191d2 --- /dev/null +++ b/module/dataview/table/testrun.php @@ -0,0 +1,78 @@ +app->loadLang('testcase'); +$this->app->loadLang('testtask'); +$this->app->loadLang('tree'); +$this->app->loadLang('project'); +$this->app->loadLang('execution'); +$this->app->loadLang('build'); +$this->app->loadLang('product'); +$this->app->loadLang('dataview'); + +$schema = new stdclass(); + +$schema->primaryTable = 'testrun'; + +$schema->tables = array(); +$schema->tables['testrun'] = 'zt_testrun'; +$schema->tables['testcase'] = 'zt_case'; +$schema->tables['testtask'] = 'zt_testtask'; +$schema->tables['casemodule'] = 'zt_module'; +$schema->tables['project'] = 'zt_project'; +$schema->tables['execution'] = 'zt_project'; +$schema->tables['build'] = 'zt_build'; +$schema->tables['product'] = 'zt_product'; + +$schema->joins = array(); +$schema->joins['testcase'] = 'testcase.id = testrun.case'; +$schema->joins['product'] = 'product.id = testcase.product'; +$schema->joins['testtask'] = 'testtask.id = testrun.task'; +$schema->joins['casemodule'] = 'casemodule.id = testcase.module'; +$schema->joins['project'] = 'project.id = testtask.project'; +$schema->joins['execution'] = 'execution.id = testtask.execution'; +$schema->joins['build'] = 'build.id = testtask.build'; + +$schema->fields = array(); +$schema->fields['testtask'] = array('type' => 'object', 'name' => $this->lang->testtask->common, 'object' => 'testtask', 'show' => 'testtask.name'); +$schema->fields['testcase'] = array('type' => 'object', 'name' => $this->lang->testcase->common, 'object' => 'testcase', 'show' => 'testcase.title'); +$schema->fields['assignedTo'] = array('type' => 'user', 'name' => $this->lang->testcase->assignedTo); +$schema->fields['project'] = array('type' => 'object', 'name' => $this->lang->project->common, 'object' => 'project', 'show' => 'execution.name'); +$schema->fields['build'] = array('type' => 'object', 'name' => $this->lang->build->common, 'object' => 'build', 'show' => 'build.name'); +$schema->fields['execution'] = array('type' => 'object', 'name' => $this->lang->execution->common, 'object' => 'execution', 'show' => 'execution.name'); +$schema->fields['casemodule'] = array('type' => 'object', 'name' => $this->lang->tree->common, 'object' => 'casemodule', 'show' => 'casemodule.name'); +$schema->fields['lastRunner'] = array('type' => 'user', 'name' => $this->lang->testtask->lastRunner); +$schema->fields['lastRunDate'] = array('type' => 'user', 'name' => $this->lang->testtask->lastRunDate); +$schema->fields['lastRunResult'] = array('type' => 'option', 'name' => $this->lang->testtask->lastRunResult, 'options' => $this->lang->testcase->resultList); + +$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['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['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['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); diff --git a/module/dataview/table/testtask.php b/module/dataview/table/testtask.php new file mode 100644 index 0000000000..04194e6432 --- /dev/null +++ b/module/dataview/table/testtask.php @@ -0,0 +1,56 @@ +app->loadLang('product'); +$this->app->loadLang('project'); +$this->app->loadLang('execution'); +$this->app->loadLang('build'); +$this->app->loadLang('testtask'); + +$schema = new stdclass(); + +$schema->primaryTable = 'testtask'; + +$schema->tables = array(); +$schema->tables['product'] = 'zt_product'; +$schema->tables['project'] = 'zt_project'; +$schema->tables['execution'] = 'zt_project'; +$schema->tables['build'] = 'zt_build'; +$schema->tables['testtask'] = 'zt_testtask'; + +$schema->joins = array(); +$schema->joins['product'] = 'product.id = testtask.product'; +$schema->joins['project'] = 'project.id = testtask.project'; +$schema->joins['execution'] = 'execution.id = testtask.execution'; +$schema->joins['build'] = 'build.id = testtask.build'; + +$schema->fields = array(); +$schema->fields['product'] = array('type' => 'object', 'name' => $this->lang->testtask->product, 'object' => 'product', 'show' => 'product.name'); +$schema->fields['project'] = array('type' => 'object', 'name' => $this->lang->testtask->project, 'object' => 'project', 'show' => 'project.name'); +$schema->fields['execution'] = array('type' => 'object', 'name' => $this->lang->testtask->execution, 'object' => 'execution', 'show' => 'execution.name'); +$schema->fields['build'] = array('type' => 'object', 'name' => $this->lang->testtask->build, 'object' => 'build', 'show' => 'build.name'); + +$schema->fields['id'] = array('type' => 'number', 'name' => $this->lang->testtask->id); +$schema->fields['name'] = array('type' => 'string', 'name' => $this->lang->testtask->name); +$schema->fields['type'] = array('type' => 'option', 'name' => $this->lang->testtask->type, 'options' => $this->lang->testtask->typeList); +$schema->fields['owner'] = array('type' => 'user', 'name' => $this->lang->testtask->owner); +$schema->fields['pri'] = array('type' => 'option', 'name' => $this->lang->testtask->pri, 'options' => $this->lang->testtask->priList); +$schema->fields['begin'] = array('type' => 'date', 'name' => $this->lang->testtask->begin); +$schema->fields['end'] = array('type' => 'date', 'name' => $this->lang->testtask->end); +$schema->fields['status'] = array('type' => 'option', 'name' => $this->lang->testtask->status, 'options' => $this->lang->testtask->statusList); + +$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); + +$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->name); diff --git a/module/dimension/lang/de.php b/module/dimension/lang/de.php index bfa2812263..70196212cb 100644 --- a/module/dimension/lang/de.php +++ b/module/dimension/lang/de.php @@ -1,3 +1,10 @@ dimension->common = 'Dimension'; -$lang->dimension->default = 'Efficiency'; +$lang->dimension->common = 'Dimension'; +$lang->dimension->efficiency = 'Efficiency'; +$lang->dimension->quality = 'Quality'; + +$lang->dimension->moduleList[''] = ''; +$lang->dimension->moduleList['product'] = $lang->productCommon; +$lang->dimension->moduleList['project'] = $lang->projectCommon; +$lang->dimension->moduleList['test'] = 'QA'; +$lang->dimension->moduleList['staff'] = 'Company'; diff --git a/module/dimension/lang/en.php b/module/dimension/lang/en.php index bfa2812263..70196212cb 100644 --- a/module/dimension/lang/en.php +++ b/module/dimension/lang/en.php @@ -1,3 +1,10 @@ dimension->common = 'Dimension'; -$lang->dimension->default = 'Efficiency'; +$lang->dimension->common = 'Dimension'; +$lang->dimension->efficiency = 'Efficiency'; +$lang->dimension->quality = 'Quality'; + +$lang->dimension->moduleList[''] = ''; +$lang->dimension->moduleList['product'] = $lang->productCommon; +$lang->dimension->moduleList['project'] = $lang->projectCommon; +$lang->dimension->moduleList['test'] = 'QA'; +$lang->dimension->moduleList['staff'] = 'Company'; diff --git a/module/dimension/lang/fr.php b/module/dimension/lang/fr.php index bfa2812263..70196212cb 100644 --- a/module/dimension/lang/fr.php +++ b/module/dimension/lang/fr.php @@ -1,3 +1,10 @@ dimension->common = 'Dimension'; -$lang->dimension->default = 'Efficiency'; +$lang->dimension->common = 'Dimension'; +$lang->dimension->efficiency = 'Efficiency'; +$lang->dimension->quality = 'Quality'; + +$lang->dimension->moduleList[''] = ''; +$lang->dimension->moduleList['product'] = $lang->productCommon; +$lang->dimension->moduleList['project'] = $lang->projectCommon; +$lang->dimension->moduleList['test'] = 'QA'; +$lang->dimension->moduleList['staff'] = 'Company'; diff --git a/module/dimension/lang/zh-cn.php b/module/dimension/lang/zh-cn.php index 6c6b30b58b..9cf2974d3a 100644 --- a/module/dimension/lang/zh-cn.php +++ b/module/dimension/lang/zh-cn.php @@ -1,3 +1,10 @@ dimension->common = '维度'; -$lang->dimension->default = '效能'; +$lang->dimension->common = '维度'; +$lang->dimension->efficiency = '效能'; +$lang->dimension->quality = '质量'; + +$lang->dimension->moduleList[''] = ''; +$lang->dimension->moduleList['product'] = $lang->productCommon; +$lang->dimension->moduleList['project'] = $lang->projectCommon; +$lang->dimension->moduleList['test'] = '测试'; +$lang->dimension->moduleList['staff'] = '组织'; diff --git a/module/doc/config.php b/module/doc/config.php index f16bf98786..2a640cbce6 100644 --- a/module/doc/config.php +++ b/module/doc/config.php @@ -37,6 +37,18 @@ $config->doc->iconList['word'] = 'word'; $config->doc->iconList['ppt'] = 'ppt'; $config->doc->iconList['excel'] = 'excel'; +$config->doc->objectIconList['product'] = 'icon-product'; +$config->doc->objectIconList['project'] = 'icon-project'; +$config->doc->objectIconList['execution'] = 'icon-run'; +$config->doc->objectIconList['mine'] = 'icon-contacts'; +$config->doc->objectIconList['custom'] = 'icon-groups'; + +$config->doc->spaceMethod['mine'] = 'myspace'; +$config->doc->spaceMethod['product'] = 'productspace'; +$config->doc->spaceMethod['project'] = 'projectspace'; +$config->doc->spaceMethod['execution'] = 'projectspace'; +$config->doc->spaceMethod['custom'] = 'tablecontents'; + $config->doc->search['module'] = 'doc'; $config->doc->search['fields']['title'] = $lang->doc->title; $config->doc->search['fields']['id'] = $lang->doc->id; diff --git a/module/doc/control.php b/module/doc/control.php index 603d4fee04..f82610933d 100755 --- a/module/doc/control.php +++ b/module/doc/control.php @@ -36,26 +36,14 @@ class doc extends control */ public function index() { - $this->session->set('docList', $this->app->getURI(true), 'doc'); - $this->app->loadClass('pager', $static = true); - $pager = new pager(0, 5, 1); - - $this->view->title = $this->lang->doc->common . $this->lang->colon . $this->lang->doc->index; - $this->view->position[] = $this->lang->doc->index; - - $this->view->latestEditedDocs = $this->doc->getDocsByBrowseType('byediteddate', 0, 0, 'editedDate_desc, id_desc', $pager); - $this->view->myDocs = $this->doc->getDocsByBrowseType('openedbyme', 0, 0, 'addedDate_desc', $pager); - $this->view->collectedDocs = $this->doc->getDocsByBrowseType('collectedbyme', 0, 0, 'addedDate_desc', $pager); - $this->view->statisticInfo = $this->doc->getStatisticInfo(); - $this->view->users = $this->user->getPairs('noletter'); - + $this->view->title = $this->lang->doc->common . $this->lang->colon . $this->lang->doc->index; $this->display(); } /** * My space. * - * @param string $type mine + * @param string $type mine|view|collect|createdBy * @param int $libID * @param int $moduleID * @param string $browseType all|draft|bysearch @@ -67,7 +55,7 @@ class doc extends control * @access public * @return void */ - public function mySpace($type = 'mine', $libID = 0, $moduleID = 0, $browseType = 'all', $param = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1) + public function mySpace($type = 'mine', $libID = 0, $moduleID = 0, $browseType = 'all', $param = 0, $orderBy = 'status,id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1) { /* Save session, load module. */ $uri = $this->app->getURI(true); @@ -75,42 +63,52 @@ class doc extends control $this->session->set('productList', $uri, 'product'); $this->session->set('executionList', $uri, 'execution'); $this->session->set('projectList', $uri, 'project'); + $this->session->set('objectName', '', 'doc'); + $this->session->set('spaceType', 'mine', 'doc'); $this->loadModel('search'); list($libs, $libID, $object, $objectID, $objectDropdown) = $this->doc->setMenuByType('mine', 0, $libID); /* Build the search form. */ $browseType = strtolower($browseType); + $type = strtolower($type); $queryID = $browseType == 'bysearch' ? (int)$param : 0; $params = "libID=$libID&moduleID=$moduleID&browseType=bySearch¶m=myQueryID&orderBy=$orderBy"; - if($this->app->rawMethod == 'mySpace') $param = "type=$type&" . $params; + if($this->app->rawMethod == 'myspace') $params = "type=$type&" . $params; $actionURL = $this->createLink('doc', $this->app->rawMethod, $params); $this->doc->buildSearchForm($libID, $libs, $queryID, $actionURL, $type); - /* Set header and position. */ - $this->view->title = $this->lang->doc->common; - /* Load pager. */ $this->app->loadClass('pager', $static = true); $pager = new pager($recTotal, $recPerPage, $pageID); /* Append id for secend sort. */ $sort = common::appendOrder($orderBy); + $docs = array(); + if($type == 'mine') + { + $docs = $browseType == 'bysearch' ? $this->doc->getDocsBySearch('mine', 0, $libID, $queryID, $orderBy, $pager) : $this->doc->getDocs($libID, $moduleID, $browseType, $orderBy, $pager); + } + elseif($type == 'view' or $type == 'collect' or $type == 'createdby') + { + $docs = $this->doc->getMineList($type, $browseType, $orderBy, $pager, $queryID); + } + $this->view->title = $this->lang->doc->common; $this->view->moduleID = $moduleID; - $this->view->docs = $this->doc->getDocsByBrowseType($browseType, $queryID, $moduleID, $sort, $pager); + $this->view->docs = $docs; $this->view->users = $this->user->getPairs('noletter'); $this->view->orderBy = $orderBy; $this->view->browseType = $browseType; $this->view->param = $param; $this->view->libID = $libID; $this->view->lib = $this->doc->getLibById($libID); - $this->view->libTree = $this->doc->getLibTree($libID, $libs, 'mine', 0); + $this->view->libTree = $this->doc->getLibTree($type != 'mine' ? 0 : $libID, $libs, 'mine', $moduleID, 0, $browseType); $this->view->pager = $pager; $this->view->type = $type; $this->view->objectID = 0; - $this->view->canExport = 0; + $this->view->canExport = ($this->config->edition != 'open' and common::hasPriv('doc', 'mine2export') and $type == 'mine'); $this->view->libType = 'lib'; $this->display(); @@ -155,7 +153,8 @@ class doc extends control if($type == 'product') $objects = $this->product->getPairs(); if($type == 'project') { - $objects = $this->project->getPairsByProgram('', 'all', false, 'order_asc', 'kanban'); + $excludedModel = $this->config->vision == 'lite' ? '' : 'kanban'; + $objects = $this->project->getPairsByProgram('', 'all', false, 'order_asc', $excludedModel); if($this->app->tab == 'doc') { $this->view->executionPairs = array(0 => '') + $this->execution->getPairs($objectID, 'all', 'multiple,leaf,noprefix'); @@ -163,10 +162,10 @@ class doc extends control } } - if($type == 'execution') $objects = $this->execution->getPairs(0, 'all', 'multiple,leaf,noprefix'); if($type == 'execution') { + $objects = $this->execution->getPairs(0, 'sprint,stage', 'multiple,leaf,noprefix'); $execution = $this->execution->getByID($objectID); if($execution->type == 'stage') $this->lang->doc->execution = str_replace($this->lang->executionCommon, $this->lang->project->stage, $this->lang->doc->execution); } @@ -180,8 +179,6 @@ class doc extends control elseif($type == 'mine') { $acl = 'private'; - unset($this->lang->doclib->aclList['open']); - unset($this->lang->doclib->aclList['default']); $this->lang->doclib->aclList = $this->lang->doclib->mySpaceAclList['private']; } @@ -266,20 +263,28 @@ class doc extends control $this->view->object = $execution; } - if($lib->type == 'custom') unset($this->lang->doclib->aclList['default']); - if($lib->type == 'api') + if($lib->type == 'custom') + { + unset($this->lang->doclib->aclList['default']); + } + elseif($lib->type == 'api') { $this->app->loadLang('api'); $type = !empty($lib->product) ? 'product' : 'project'; $this->lang->api->aclList['default'] = sprintf($this->lang->api->aclList['default'], $this->lang->{$type}->common); } - if($lib->type != 'custom') + elseif($lib->type == 'mine') + { + $this->lang->doclib->aclList = $this->lang->doclib->mySpaceAclList['private']; + } + elseif($lib->type != 'custom') { $type = isset($type) ? $type : $lib->type; $this->lang->doclib->aclList['default'] = sprintf($this->lang->doclib->aclList['default'], $this->lang->{$type}->common); $this->lang->doclib->aclList['private'] = sprintf($this->lang->doclib->privateACL, $this->lang->{$type}->common); unset($this->lang->doclib->aclList['open']); } + if(!empty($lib->main)) unset($this->lang->doclib->aclList['private'], $this->lang->doclib->aclList['open']); $this->view->lib = $lib; @@ -409,7 +414,8 @@ class doc extends control $objects = array(); if($objectType == 'project') { - $objects = $this->project->getPairsByProgram('', 'all', false, 'order_asc', 'kanban'); + $excludedModel = $this->config->vision == 'lite' ? '' : 'kanban'; + $objects = $this->project->getPairsByProgram('', 'all', false, 'order_asc', $excludedModel); if($lib->type == 'execution') { $execution = $this->loadModel('execution')->getById($lib->execution); @@ -428,6 +434,10 @@ class doc extends control { $objects = $this->loadModel('product')->getPairs(); } + elseif($objectType == 'mine') + { + $this->lang->doc->aclList = $this->lang->doclib->mySpaceAclList; + } $moduleOptionMenu = $this->doc->getLibsOptionMenu($libs); $moduleID = $moduleID ? (int)$moduleID : (int)$this->cookie->lastDocModule; @@ -588,6 +598,10 @@ class doc extends control { $objects = $this->loadModel('product')->getPairs(); } + elseif($objectType == 'mine') + { + $this->lang->doc->aclList = $this->lang->doclib->mySpaceAclList['private']; + } $moduleOptionMenu = $this->doc->getLibsOptionMenu($libs); $this->config->showMainMenu = strpos(',html,markdown,text,', ",{$doc->type},") === false; @@ -730,28 +744,21 @@ class doc extends control */ public function collect($objectID, $objectType) { + $table = ''; if($objectType == 'doc') $table = TABLE_DOC; - if($objectType == 'doclib') $table = TABLE_DOCLIB; - if($objectType == 'module') $table = TABLE_MODULE; - $collectors = $this->dao->select('collector')->from($table)->where('id')->eq($objectID)->fetch('collector'); + if(empty($table)) return; - $hasCollect = strpos($collectors, ",{$this->app->user->account},") !== false; - if($hasCollect) + $action = $this->doc->getActionByObject($objectID, 'collect'); + if($action) { - $collectors = str_replace(",{$this->app->user->account},", ',', $collectors); + $this->doc->deleteAction($action->id); } else { - $collectors = explode(',', $collectors); - $collectors[] = $this->app->user->account; - $collectors = implode(',', $collectors); + $this->doc->createAction($objectID, 'collect'); } - $collectors = trim($collectors, ',') ? ',' . trim($collectors, ',') . ',' : ''; - - $this->dao->update($table)->set('collector')->eq($collectors)->where('id')->eq($objectID)->exec(); - - return $this->send(array('status' => $hasCollect ? 'no' : 'yes')); + return $this->send(array('status' => $action ? 'no' : 'yes')); } /** @@ -810,6 +817,8 @@ class doc extends control */ public function ajaxGetModules($objectType, $objectID, $docType = 'doc') { + if(empty($objectID)) return print(html::select('module', array(), '', "class='form-control'")); + if($docType == 'doc') { $unclosed = strpos($this->config->doc->custom->showLibs, 'unclosed') !== false ? 'unclosedProject' : ''; @@ -1118,10 +1127,11 @@ class doc extends control $lib = $this->doc->getLibById($doc->lib); if(!empty($lib) and $lib->deleted == '1') $appendLib = $doc->id; + $objectType = isset($lib->type) ? $lib->type : 'custom'; $type = $objectType == 'execution' && $this->app->tab != 'execution' ? 'project' : $objectType; - $objectID = isset($doc->{$type}) ? $doc->{$type} : 0; - list($libs, $libID, $object, $objectID) = $this->doc->setMenuByType($type, $objectID, $doc->lib, $appendLib); + $objectID = zget($doc, $type, 0); + list($libs, $libID, $object, $objectID, $objectDropdown) = $this->doc->setMenuByType($type, $objectID, $doc->lib, $appendLib); $moduleTree = $this->doc->getTreeMenu($type, $objectID, $libID, 0, $docID); @@ -1131,6 +1141,7 @@ class doc extends control $doc = $this->doc->getById($docID, $version, true); if(!$doc) return print(js::error($this->lang->notFound)); + $this->doc->createAction($docID, 'view'); if($doc->keywords) { $doc->keywords = str_replace(",", ',', $doc->keywords); @@ -1202,26 +1213,54 @@ class doc extends control } } - $doc = $docID ? $doc : ''; - $spaceType = $objectType . 'Space'; + $doc = $docID ? $doc : ''; - $this->view->title = isset($this->lang->doc->{$spaceType}) ? $this->lang->doc->{$spaceType} : $this->lang->doc->common; - $this->view->docID = $docID; - $this->view->doc = $doc; - $this->view->version = $version; - $this->view->object = $object; - $this->view->objectID = $objectID; - $this->view->objectType = $objectType; - $this->view->type = $type; - $this->view->libID = $libID; - $this->view->lib = isset($libs[$libID]) ? $libs[$libID] : new stdclass(); - $this->view->libs = $this->doc->getLibsByObject($type, $objectID); - $this->view->canBeChanged = common::canModify($type, $object); // Determines whether an object is editable. - $this->view->actions = $docID ? $this->action->getList('doc', $docID) : array(); - $this->view->users = $this->user->getPairs('noclosed,noletter'); - $this->view->autoloadPage = $this->doc->checkAutoloadPage($doc); - $this->view->libTree = $this->doc->getLibTree($libID, $libs, $type, $doc->module, $objectID); - $this->view->preAndNext = $this->loadModel('common')->getPreAndNextObject('doc', $docID); + /* Crumbs links array. */ + $methodName = in_array($type, array('product', 'project')) ? $objectType . 'Space' : 'tableContents'; + $linkParams = "objectID={$objectID}&libID={$lib->id}"; + if($this->app->tab == 'execution' or $objectType == 'custom') + { + $linkParams = "objectType=$objectType&$linkParams"; + $methodName = 'tableContents'; + } + if($type == 'mine') + { + $linkParams = "type=mine&libID={$lib->id}"; + $methodName = 'mySpace'; + } + + $crumbs[] = html::a(inLink($methodName, $linkParams), html::image("static/svg/wiki-file-lib.svg") . $lib->name); + + $moduleList = $this->loadModel('tree')->getParents($doc->module); + foreach($moduleList as $module) + { + $withModuleParams = $linkParams . "&moduleID=$module->id"; + $crumbs[] = html::a(inLink($methodName, $withModuleParams), $module->name); + } + + $spaceType = $objectType . 'Space'; + $this->view->title = isset($this->lang->doc->{$spaceType}) ? $this->lang->doc->{$spaceType} : $this->lang->doc->common; + $this->view->docID = $docID; + $this->view->doc = $doc; + $this->view->version = $version; + $this->view->object = $object; + $this->view->objectID = $objectID; + $this->view->objectType = $objectType; + $this->view->type = $type; + $this->view->libID = $libID; + $this->view->crumbs = $crumbs; + $this->view->lib = isset($libs[$libID]) ? $libs[$libID] : new stdclass(); + $this->view->libs = $this->doc->getLibsByObject($type, $objectID); + $this->view->canBeChanged = common::canModify($type, $object); // Determines whether an object is editable. + $this->view->actions = $docID ? $this->action->getList('doc', $docID) : array(); + $this->view->users = $this->user->getPairs('noclosed,noletter'); + $this->view->autoloadPage = $this->doc->checkAutoloadPage($doc); + $this->view->libTree = $this->doc->getLibTree($libID, $libs, $type, $doc->module, $objectID); + $this->view->preAndNext = $this->loadModel('common')->getPreAndNextObject('doc', $docID); + $this->view->moduleID = $doc->module; + $this->view->objectDropdown = $objectDropdown; + $this->view->canExport = ($this->config->edition != 'open' && common::hasPriv('doc', $type . '2export')); + $this->view->exportMethod = $type . '2export'; $this->display(); } @@ -1296,6 +1335,9 @@ class doc extends control $apiObjectID = $apiObjectType ? $objectID : 0; $apiLibs = $apiObjectType ? $this->doc->getApiLibs(0, $apiObjectType, $apiObjectID) : array(); + $canExport = $libType == 'api' ? common::hasPriv('api', 'export') : common::hasPriv('doc', $type . '2export'); + if($this->config->edition == 'open') $canExport = false; + $this->view->title = $title; $this->view->type = $type; $this->view->objectType = $type; @@ -1303,7 +1345,7 @@ class doc extends control $this->view->isFirstLoad = $isFirstLoad; $this->view->param = $queryID; $this->view->users = $this->user->getPairs('noletter'); - $this->view->libTree = $this->doc->getLibTree($libID, $libs, $type, $moduleID, $objectID, $browseType); + $this->view->libTree = $this->doc->getLibTree($libID, $libs, $type, $moduleID, $objectID, $browseType, $param); $this->view->libID = $libID; $this->view->moduleID = $moduleID; $this->view->objectDropdown = $objectDropdown; @@ -1312,11 +1354,11 @@ class doc extends control $this->view->pager = $pager; $this->view->objectID = $objectID; $this->view->orderBy = $orderBy; - $this->view->canExport = $libType == 'api' ? common::hasPriv('api', 'export') : common::hasPriv('doc', $type . '2export'); + $this->view->release = $browseType == 'byrelease' ? $param : 0; + $this->view->canExport = $canExport; $this->view->exportMethod = $libType == 'api' ? 'export' : $type . '2export'; $this->view->apiLibID = key($apiLibs); - $this->display(); } @@ -1388,8 +1430,13 @@ class doc extends control $spaceList = $this->lang->doc->spaceList; $typeList = $this->lang->doc->types; - if(!common::hasPriv('doc', 'create')) unset($spaceList['mine'], $spaceList['custom'], $typeList['doc']); - if(!common::hasPriv('api', 'create')) unset($spaceList['api'], $typeList['api']); + if(!common::hasPriv('doc', 'create')) unset($spaceList['mine'], $spaceList['custom'], $typeList['doc']); + if(!common::hasPriv('doc', 'mySpace')) unset($spaceList['mine']); + if(!common::hasPriv('doc', 'productSpace')) unset($spaceList['product']); + if(!common::hasPriv('doc', 'projectSpace')) unset($spaceList['project']); + if(!common::hasPriv('doc', 'tableContents')) unset($spaceList['custom']); + if(!common::hasPriv('api', 'index')) unset($spaceList['api']); + if(!common::hasPriv('api', 'create')) unset($spaceList['api'], $typeList['api']); $products = $this->loadModel('product')->getPairs(); $projects = $this->project->getPairsByProgram('', 'all', false, 'order_asc', 'kanban'); @@ -1419,7 +1466,7 @@ class doc extends control $this->view->objectType = $objectType; $this->view->objectID = $objectID; $this->view->module = $module; - $this->view->method = $method; + $this->view->method = $method =='view' ? $objectType.'space' : $method; $this->view->normalObjects = $myObjects + $normalObjects; $this->view->closedObjects = $closedObjects; $this->view->objectsPinYin = common::convert2Pinyin($myObjects + $normalObjects + $closedObjects); diff --git a/module/doc/css/common.css b/module/doc/css/common.css index 8f07a8858b..c8f86deaed 100644 --- a/module/doc/css/common.css +++ b/module/doc/css/common.css @@ -12,7 +12,6 @@ .col-spliter:hover:after, .row-spliting .col-spliter:before, .row-spliting .col-spliter:after {opacity: 1;} - @media (max-width: 720px) { .split-row > .side-col, diff --git a/module/doc/css/create.css b/module/doc/css/create.css index 53c246b110..e19e12a218 100644 --- a/module/doc/css/create.css +++ b/module/doc/css/create.css @@ -1,3 +1,4 @@ +body {overflow: hidden;} .doc-title {width:400px;} .doc-title input {border: unset; font-size: 18px; font-weight: bold; color: #3c4353; padding-left: 16px;} .doc-title .form-control:focus {border: unset; box-shadow: unset;} diff --git a/module/doc/css/edit.css b/module/doc/css/edit.css index 8c7f6a87c8..fe41bdb93b 100644 --- a/module/doc/css/edit.css +++ b/module/doc/css/edit.css @@ -1,3 +1,4 @@ +body {overflow: hidden;} .doc-title {width:400px;} .doc-title input {border: unset; font-size: 18px; font-weight: bold; color: #3c4353; padding-left: 16px;} .doc-title .form-control:focus {border: unset; box-shadow: unset;} diff --git a/module/doc/css/index.css b/module/doc/css/index.css deleted file mode 100644 index f45675040c..0000000000 --- a/module/doc/css/index.css +++ /dev/null @@ -1,4 +0,0 @@ -#pageActions ul.dropdown-menu {left: 67px;} -#mainRow .main-col .row .col-sm-7 {width: 55% !important;} -#mainRow .main-col .row .col-sm-5 {width: 45% !important;} -#mainRow .c-num {text-overflow: ellipsis; white-space: nowrap;} diff --git a/module/doc/css/myspace.css b/module/doc/css/myspace.css index 80cea2d24b..44a6627b45 100644 --- a/module/doc/css/myspace.css +++ b/module/doc/css/myspace.css @@ -1 +1,14 @@ -#mainContent .c-id > a {color: #0c60e1;} +.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;} +#mainContent > .panel {margin-bottom: 0; height: calc(100vh - 130px); overflow-y: auto;} +#bysearchTab::before {display: none;} +#queryBox #groupAndOr {min-width: 60px;} diff --git a/module/doc/css/selectlibtype.css b/module/doc/css/selectlibtype.css index cbffff4aec..61649d1aea 100644 --- a/module/doc/css/selectlibtype.css +++ b/module/doc/css/selectlibtype.css @@ -1 +1,3 @@ #lib_chosen.chosen-container .chosen-results {max-height: 100px;} +.radio-inline+.radio-inline { margin-top: 0; margin-left: 0px;} +.radio-inline {margin-right: 10px;} diff --git a/module/doc/css/showfiles.css b/module/doc/css/showfiles.css index 2c732fce6d..5747a53ebb 100644 --- a/module/doc/css/showfiles.css +++ b/module/doc/css/showfiles.css @@ -19,7 +19,7 @@ #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 > .panel {margin-bottom: 0; height: calc(100vh - 130px); overflow-y: auto;} #mainContent > .main-col {padding-left: 0;} .no-content {width: 100px; height: 100px; margin: 0 auto;} diff --git a/module/doc/css/tablecontents.css b/module/doc/css/tablecontents.css index ed62b56ae8..b7196e25cc 100644 --- a/module/doc/css/tablecontents.css +++ b/module/doc/css/tablecontents.css @@ -9,14 +9,15 @@ .overflow-auto {overflow: auto;} .overflow-visible {overflow: visible;} .overflow-hidden {overflow: hidden;} -#main {padding-bottom: 0;} .img-lib {width: 14px; height: 14px; margin-bottom: 2px; flex: 0 0 14px;} +#main {padding-bottom: 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 > .panel {margin-bottom: 0; height: calc(100vh - 130px); overflow-y: auto;} #mainContent > .main-col {padding-left: 0;} +#swapper {margin-right: 15px;} .no-content {width: 100px; height: 100px; margin: 0 auto;} .notice {text-align: center; padding-left: 15px; padding-top: 20px;} @@ -31,7 +32,6 @@ 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: clip; overflow: hidden;} #modules i.icon-file-text {color: #D0D2D6; font-size: 14px;} .sortable-sorting .module-name > a {cursor: move;} @@ -46,7 +46,8 @@ span.dotted-line+a {display: block;} .is-sorting > li ul {display: none!important;} li.drag-shadow ul {display: none!important;} -.table .c-name > .doc-title {display: inline-block; max-width: 90%; overflow: hidden; background: transparent; padding-right:0px;} +.table .c-name > .doc-title {display: inline-block; max-width: calc(100% - 80px); overflow: hidden; background: transparent; padding-right:0px;} +.table .c-name > span.doc-title {line-height: 0; vertical-align: inherit;} .table .c-name > .draft {background-color:rgba(129, 102, 238, 0.12); color:#8166EE;} .table .c-name > .ajaxCollect {float: right; position: relative; right: 10px; top: 0px;} table.table > thead > tr {height: 32px;} diff --git a/module/doc/css/view.css b/module/doc/css/view.css index 510a575687..4f44ea039d 100644 --- a/module/doc/css/view.css +++ b/module/doc/css/view.css @@ -1,3 +1,4 @@ +.h-full-adjust {overflow-y: auto; height: calc(100vh - 120px);} .main-col .block-files .panel-heading {padding-right: 20px;} .main-col .block-files .panel-heading .panel-title {height: 35px; line-height: 30px;} .main-col .doc-title {display: flex; font-size: 16px; margin-bottom: 15px;} @@ -5,7 +6,7 @@ .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 a + a {margin-left: 8px;} +.main-col .doc-title .actions a + a {margin-left: 0px;} .main-col .doc-title .actions i {font-size: 15px; color: #8c8c8c;} #content .title {max-width: 54%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;} #content .detail-content {padding-left: 10px;} @@ -32,6 +33,7 @@ .outline-content li.text-ellipsis.active>a {font-weight: 700; color: #0c64eb;} #outline li.has-list.open:before {content: unset;} #fileTree {margin-bottom: 40px; max-height: calc(100vh - 180px); overflow: auto;} +#closeBtn {position: absolute; right: 10px; top: 10px;} .title {font-size: 20px !important;} .article-content.comment {width: 100% !important;} @@ -47,5 +49,20 @@ .overflow-auto {overflow: auto;} .overflow-visible {overflow: visible;} .overflow-hidden {overflow: hidden;} -#mainContent > .panel {margin-bottom: 0; height: calc(100vh - 125px); overflow-y: auto;} .detail-title .actions .ajaxCollect > img {width: 20px;} +.actions > .text {color: #8c8c8c; font-size: 14px;} +.flex-content {display: flex; width: 100%; height: 100%;} +.flex-content > #content {flex: auto; overflow-y: auto;} +.flex-content > #history {flex: 0 0 302px; position: relative;} +.flex-content > #history > #closeIcon {position: absolute; right: 10px; top: 10px;} +.panel {margin-bottom: 0;} +.detail {margin: 0 4px;} +#mainContent > .panel {margin-bottom: 0; overflow-y: auto;} + +.info .version, .info .crumbs {float: left;} +.crumbs img {margin-right: 3px; margin-bottom: 4px;} +.crumbs {float: left; display: flex;height: 32px; width: 670px; align-items: center; overflow: hidden;} +.crumbs a {padding: 6px 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;} +.crumbs .separator {flex: 0 0 15px; display: flex; justify-content: center; align-items: center;} +.crumbs :last-child {flex: none;} + diff --git a/module/doc/js/common.js b/module/doc/js/common.js index 6ccf395459..60edba596e 100644 --- a/module/doc/js/common.js +++ b/module/doc/js/common.js @@ -10,6 +10,7 @@ function loadObjectModules(objectType, objectID, docType) { if(typeof docType == 'undefined') docType = 'doc'; var link = createLink('doc', 'ajaxGetModules', 'objectType=' + objectType + '&objectID=' + objectID + '&type=' + docType); + if(objectType == 'execution' && objectID == 0) var link = createLink('doc', 'ajaxGetModules', 'objectType=project&objectID=' + $('#project').val() + '&type=' + docType); $('#moduleBox').load(link, function(){$('#moduleBox').find('select').picker(); $('#moduleLabel').remove();}); } @@ -22,7 +23,7 @@ function loadObjectModules(objectType, objectID, docType) */ function loadExecutions(projectID) { - var link = createLink('project', 'ajaxGetExecutions', "projectID=" + projectID + "&executionID=0&mode=multiple,leaf,noprefix"); + var link = createLink('project', 'ajaxGetExecutions', "projectID=" + projectID + "&executionID=0&mode=multiple,leaf,noprefix&type=sprint,stage"); $('#executionBox').load(link, function(){$('#executionBox').find('select').attr('data-placeholder', holders.execution).attr('onchange', "loadObjectModules('execution', this.value)").picker()}); loadObjectModules('project', projectID); } @@ -274,6 +275,7 @@ $(document).ready(function() $(function() { $('.split-row').splitRow(); + updateCrumbs(); }); var $pageSetting = $('#pageSetting'); @@ -342,25 +344,35 @@ function locateNewLib(type, objectID, libID) */ function setSavePath() { + var getSubPath = function($obj) + { + var $td = $obj.parent(); + var usePicker = $td.find('.picker').length == 1; + var subPath = $obj.find('option:checked').text(); + if(usePicker) subPath = $td.find('.picker .picker-selection-text').text(); + return subPath; + } + savePath = defaultSave; if($('#modalBasicInfo #product').length == 1) { - savePath += $('#modalBasicInfo #product option:checked').text() + '/'; + savePath += getSubPath($('#modalBasicInfo #product')) + '/'; } else if($('#modalBasicInfo #project').length == 1 && $('#modalBasicInfo #execution').length == 0) { - savePath += $('#modalBasicInfo #project option:checked').text() + '/'; + savePath += getSubPath($('#modalBasicInfo #project')) + '/'; } else if($('#modalBasicInfo #project').length == 1 && $('#modalBasicInfo #execution').length == 1) { - if($('#modalBasicInfo #execution').val() == '') savePath += $('#modalBasicInfo #project option:checked').text() + '/'; - if($('#modalBasicInfo #execution').val() != '') savePath += $('#modalBasicInfo #execution option:checked').text() + '/'; + var executionID = $('#modalBasicInfo #execution').val(); + if(executionID == '0' || executionID == '') savePath += getSubPath($('#modalBasicInfo #project')) + '/'; + if(executionID != '0' && executionID != '') savePath += getSubPath($('#modalBasicInfo #execution')) + '/'; } else if($('#modalBasicInfo #execution').length == 1) { - savePath += $('#modalBasicInfo #execution option:checked').text() + '/'; + savePath += getSubPath($('#modalBasicInfo #execution')) + '/'; } - savePath += $('#modalBasicInfo #module option:checked').text(); + savePath += getSubPath($('#modalBasicInfo #module')); $('#savePath').html(savePath).attr('title', savePath); } @@ -378,3 +390,30 @@ function submit(object) $('#dataform').submit(); setTimeout(function(){$(object).attr('type', 'button').removeAttr('disabled')}, 2000); } + +/** + * Update crumbs. + * + * @access public + * @return void + */ +function updateCrumbs() +{ + var $crumbs = $('#crumbs'); + var $crumbItems = $('#crumbs > a'); + var crumbMaxWidth = 660; + if($crumbs.width < crumbMaxWidth || $crumbItems.length == 1) return; + + /* last crumbItem width major */ + var $lastChild = $($crumbItems[$crumbItems.length -1]); + var $separator = "
    >
    " + var $ellipsis = "
    ...
    " + if($lastChild.width() > $crumbs.width()) + { + var $appendChild = $lastChild[0]; + $crumbs.empty(); + $crumbs.append($appendChild); + $crumbs.prepend($separator); + $crumbs.prepend($ellipsis); + } +} diff --git a/module/doc/js/view.js b/module/doc/js/view.js index 7f8d8f5f36..38d17e3efe 100644 --- a/module/doc/js/view.js +++ b/module/doc/js/view.js @@ -187,8 +187,9 @@ $(function() simplemde.value(String($('#markdownContent').val())); simplemde.togglePreview(); } + $('#docExport').attr('href', createLink('doc', exportMethod, 'libID=' + libID + '&docID=' + docID + '&version=' + $('#content .doc-title .version').data('version'))); }); - }); + }) $('#sidebar .icon.icon-angle-right').click(function() { @@ -199,4 +200,28 @@ $(function() }) $('.outline .outline-toggle i.icon-angle-right').trigger("click"); + $('#history').append(''); + $('#hisTrigger').on('click', function() + { + var $history = $('#history'); + var $icon = $(this); + if($history.hasClass('hidden')) + { + $history.removeClass('hidden'); + $icon.addClass('text-primary'); + } + else + { + $history.addClass('hidden'); + $icon.removeClass('text-primary'); + } + }) + + $('#history').find('.btn.pull-right').removeClass('pull-right') + $('#closeBtn').on('click', function() + { + $('#history').addClass('hidden'); + $('#hisTrigger').removeClass('text-primary'); + }) + $('#history').find('.btn.pull-right').removeClass('pull-right'); }) diff --git a/module/doc/lang/de.php b/module/doc/lang/de.php index 64f72e1c3d..4b509ad6d0 100644 --- a/module/doc/lang/de.php +++ b/module/doc/lang/de.php @@ -36,7 +36,7 @@ $lang->doclib->aclListB['open'] = 'Public'; $lang->doclib->aclListB['custom'] = 'Custom'; $lang->doclib->aclListB['private'] = 'Private'; -$lang->doclib->mySpaceAclList['private'] = "Private (Only creators can access it)"; +$lang->doclib->mySpaceAclList['private'] = "Private (Only creators can access it)"; $lang->doclib->aclList = array(); $lang->doclib->aclList['open'] = "Public (Users who can access doccan access it)"; @@ -70,14 +70,14 @@ $lang->doc->project = $lang->projectCommon; $lang->doc->execution = $lang->execution->common; $lang->doc->lib = 'Bibliothek'; $lang->doc->module = 'Modul'; -$lang->doc->libAndModule = 'Bibliothek & Modul'; +$lang->doc->libAndModule = 'Bibliothek&Modul'; $lang->doc->object = 'Object'; $lang->doc->title = 'Titel'; $lang->doc->digest = 'Zusammenfassung'; $lang->doc->comment = 'Bemerkung'; $lang->doc->type = 'Typ'; $lang->doc->content = 'Text'; -$lang->doc->keywords = 'Tags'; +$lang->doc->keywords = 'Keywords'; $lang->doc->status = 'Status'; $lang->doc->url = 'URL'; $lang->doc->files = 'Datei'; @@ -121,6 +121,9 @@ $lang->doc->nextStep = 'Next'; $lang->doc->closed = 'Closed'; $lang->doc->saveDraft = 'Save Draft'; $lang->doc->defaultSave = 'Default Save: '; +$lang->doc->position = 'Position'; +$lang->doc->person = 'Person'; +$lang->doc->team = 'Team'; $lang->doc->moduleDoc = 'Nach Modulen'; $lang->doc->searchDoc = 'Suche'; @@ -137,13 +140,14 @@ $lang->doc->myDoc = 'Meine Dokumente'; $lang->doc->myView = 'Recently Viewed'; $lang->doc->myCollection = 'Meine Favoriten'; $lang->doc->myCreation = 'Created By'; +$lang->doc->myLib = 'My Library'; $lang->doc->tableContents = 'Catalog'; $lang->doc->addCatalog = 'Add Catalog'; $lang->doc->editCatalog = 'Edit Catalog'; $lang->doc->deleteCatalog = 'Delete Catalog'; /* Methods list */ -$lang->doc->index = 'Home'; +$lang->doc->index = 'Dashboard'; $lang->doc->createAB = 'Create'; $lang->doc->create = 'Dokument hinzufügen'; $lang->doc->edit = 'Bearbeiten'; @@ -194,7 +198,7 @@ $lang->doc->showDoc = 'Whether to display documents'; global $config; /* Query condition list. */ $lang->doc->allProduct = 'Alle' . $lang->productCommon; -$lang->doc->allExecutions = 'Alle' . $lang->executionCommon; +$lang->doc->allExecutions = 'Alle' . $lang->execution->common; $lang->doc->allProjects = 'All' . $lang->projectCommon . 's'; $lang->doc->libTypeList['product'] = $lang->productCommon . ' Bibliothek'; diff --git a/module/doc/lang/en.php b/module/doc/lang/en.php index b71dbc2647..9d2e64c92a 100644 --- a/module/doc/lang/en.php +++ b/module/doc/lang/en.php @@ -36,7 +36,7 @@ $lang->doclib->aclListB['open'] = 'Public'; $lang->doclib->aclListB['custom'] = 'Custom'; $lang->doclib->aclListB['private'] = 'Private'; -$lang->doclib->mySpaceAclList['private'] = "Private (Only creators can access it)"; +$lang->doclib->mySpaceAclList['private'] = "Private (Only creators can access it)"; $lang->doclib->aclList = array(); $lang->doclib->aclList['open'] = "Public (Users who can access doccan access it)"; @@ -70,14 +70,14 @@ $lang->doc->project = $lang->projectCommon; $lang->doc->execution = $lang->execution->common; $lang->doc->lib = 'Library'; $lang->doc->module = 'Catalog'; -$lang->doc->libAndModule = 'Library & Catalog'; +$lang->doc->libAndModule = 'Library&Catalog'; $lang->doc->object = 'Object'; $lang->doc->title = 'Name'; $lang->doc->digest = 'Summary'; $lang->doc->comment = 'Comment'; $lang->doc->type = 'Type'; $lang->doc->content = 'Text'; -$lang->doc->keywords = 'Tags'; +$lang->doc->keywords = 'Keywords'; $lang->doc->status = 'Status'; $lang->doc->url = 'URL'; $lang->doc->files = 'Files'; @@ -121,6 +121,9 @@ $lang->doc->nextStep = 'Next'; $lang->doc->closed = 'Closed'; $lang->doc->saveDraft = 'Save Draft'; $lang->doc->defaultSave = 'Default Save: '; +$lang->doc->position = 'Position'; +$lang->doc->person = 'Person'; +$lang->doc->team = 'Team'; $lang->doc->moduleDoc = 'By Module'; $lang->doc->searchDoc = 'Search'; @@ -137,13 +140,14 @@ $lang->doc->myDoc = 'My Documents'; $lang->doc->myView = 'Recently Viewed'; $lang->doc->myCollection = 'My Favorites'; $lang->doc->myCreation = 'Created By'; +$lang->doc->myLib = 'My Library'; $lang->doc->tableContents = 'Directory'; $lang->doc->addCatalog = 'Add Catalog'; $lang->doc->editCatalog = 'Edit Catalog'; $lang->doc->deleteCatalog = 'Delete Catalog'; /* Methods list */ -$lang->doc->index = 'Document Home'; +$lang->doc->index = 'Dashboard'; $lang->doc->createAB = 'Create'; $lang->doc->create = 'Create Document'; $lang->doc->edit = 'Edit Document'; @@ -194,7 +198,7 @@ $lang->doc->showDoc = 'Whether to display documents'; global $config; /* Query condition list. */ $lang->doc->allProduct = 'All' . $lang->productCommon . 's'; -$lang->doc->allExecutions = 'All' . $lang->executionCommon . 's'; +$lang->doc->allExecutions = 'All' . $lang->execution->common . 's'; $lang->doc->allProjects = 'All' . $lang->projectCommon . 's'; $lang->doc->libTypeList['product'] = $lang->productCommon . ' Library'; diff --git a/module/doc/lang/fr.php b/module/doc/lang/fr.php index 41026a545f..004dfe78da 100644 --- a/module/doc/lang/fr.php +++ b/module/doc/lang/fr.php @@ -36,7 +36,7 @@ $lang->doclib->aclListB['open'] = 'Public'; $lang->doclib->aclListB['custom'] = 'Person.'; $lang->doclib->aclListB['private'] = 'Privée'; -$lang->doclib->mySpaceAclList['private'] = "Private (Only creators can access it)"; +$lang->doclib->mySpaceAclList['private'] = "Private (Only creators can access it)"; $lang->doclib->aclList = array(); $lang->doclib->aclList['open'] = "Public (Users who can access doccan access it)"; @@ -70,14 +70,14 @@ $lang->doc->project = $lang->projectCommon; $lang->doc->execution = $lang->execution->common; $lang->doc->lib = 'Bibliothèque'; $lang->doc->module = 'Catégorie'; -$lang->doc->libAndModule = 'Library & Catalog'; +$lang->doc->libAndModule = 'Library&Catalog'; $lang->doc->object = 'Object'; $lang->doc->title = 'Nom'; $lang->doc->digest = 'Résumé'; $lang->doc->comment = 'Commentaire'; $lang->doc->type = 'Type'; $lang->doc->content = 'Texte'; -$lang->doc->keywords = 'Tags'; +$lang->doc->keywords = 'Keywords'; $lang->doc->status = 'Status'; $lang->doc->url = 'URL'; $lang->doc->files = 'Fichiers'; @@ -121,6 +121,9 @@ $lang->doc->nextStep = 'Next'; $lang->doc->closed = 'Closed'; $lang->doc->saveDraft = 'Save Draft'; $lang->doc->defaultSave = 'Default Save: '; +$lang->doc->position = 'Position'; +$lang->doc->person = 'Person'; +$lang->doc->team = 'Team'; $lang->doc->moduleDoc = 'Par Module'; $lang->doc->searchDoc = 'Rechercher'; @@ -137,13 +140,14 @@ $lang->doc->myDoc = 'Mes Documents'; $lang->doc->myView = 'Recently Viewed'; $lang->doc->myCollection = 'Mes Favoris'; $lang->doc->myCreation = 'Created By'; +$lang->doc->myLib = 'My Library'; $lang->doc->tableContents = 'Catalog'; $lang->doc->addCatalog = 'Add Catalog'; $lang->doc->editCatalog = 'Edit Catalog'; $lang->doc->deleteCatalog = 'Delete Catalog'; /* Methods list */ -$lang->doc->index = 'Accueil Documents'; +$lang->doc->index = 'Dashboard'; $lang->doc->createAB = 'Create'; $lang->doc->create = 'Ajouter Document'; $lang->doc->edit = 'Editer Document'; @@ -194,7 +198,7 @@ $lang->doc->showDoc = 'Whether to display documents'; global $config; /* Query condition list. */ $lang->doc->allProduct = 'Tous les' . $lang->productCommon . 's'; -$lang->doc->allExecutions = 'Tous les' . $lang->executionCommon . 's'; +$lang->doc->allExecutions = 'Tous les' . $lang->execution->common . 's'; $lang->doc->allProjects = 'All' . $lang->projectCommon . 's'; $lang->doc->libTypeList['product'] = $lang->productCommon . ' Library'; diff --git a/module/doc/lang/zh-cn.php b/module/doc/lang/zh-cn.php index 4632983eef..3e9ec2fa10 100644 --- a/module/doc/lang/zh-cn.php +++ b/module/doc/lang/zh-cn.php @@ -36,7 +36,7 @@ $lang->doclib->aclListB['open'] = '公开'; $lang->doclib->aclListB['custom'] = '自定义'; $lang->doclib->aclListB['private'] = '私有'; -$lang->doclib->mySpaceAclList['private'] = "私有 (仅创建者可访问)"; +$lang->doclib->mySpaceAclList['private'] = "私有(仅创建者可访问)"; $lang->doclib->aclList = array(); $lang->doclib->aclList['open'] = "公开 (有文档视图权限即可访问)"; @@ -83,7 +83,7 @@ $lang->doc->url = '文档URL'; $lang->doc->files = '附件'; $lang->doc->addedBy = '由谁添加'; $lang->doc->addedByAB = '创建者'; -$lang->doc->addedDate = '创建时间'; +$lang->doc->addedDate = '创建日期'; $lang->doc->editedBy = '修改者'; $lang->doc->editedDate = '修改日期'; $lang->doc->lastEditedBy = '最后更新者'; @@ -121,6 +121,9 @@ $lang->doc->nextStep = '下一步'; $lang->doc->closed = '已关闭'; $lang->doc->saveDraft = '存为草稿'; $lang->doc->defaultSave = '默认存入:'; +$lang->doc->position = '所在位置'; +$lang->doc->person = '个人'; +$lang->doc->team = '团队'; $lang->doc->moduleDoc = '按模块浏览'; $lang->doc->searchDoc = '搜索'; @@ -137,13 +140,14 @@ $lang->doc->myDoc = '我的文档'; $lang->doc->myView = '最近浏览'; $lang->doc->myCollection = '我的收藏'; $lang->doc->myCreation = '我创建的'; +$lang->doc->myLib = '我的个人库'; $lang->doc->tableContents = '目录'; $lang->doc->addCatalog = '添加目录'; $lang->doc->editCatalog = '编辑目录'; $lang->doc->deleteCatalog = '删除目录'; /* 方法列表。*/ -$lang->doc->index = '文档主页'; +$lang->doc->index = '仪表盘'; $lang->doc->createAB = '创建'; $lang->doc->create = '创建文档'; $lang->doc->edit = '编辑文档'; @@ -194,7 +198,7 @@ $lang->doc->showDoc = '是否显示文档'; global $config; /* 查询条件列表 */ $lang->doc->allProduct = '所有' . $lang->productCommon; -$lang->doc->allExecutions = '所有' . $lang->executionCommon; +$lang->doc->allExecutions = '所有' . $lang->execution->common; $lang->doc->allProjects = '所有' . $lang->projectCommon; $lang->doc->libTypeList['product'] = $lang->productCommon . '文档库'; diff --git a/module/doc/model.php b/module/doc/model.php index a414b800a1..8980aef732 100644 --- a/module/doc/model.php +++ b/module/doc/model.php @@ -82,7 +82,7 @@ class docModel extends model ->beginIF($type == 'all')->andWhere('deleted')->eq(0)->fi() ->beginIF($excludeType)->andWhere('type')->notin($excludeType)->fi() ->andWhere('vision')->eq($this->config->vision) - ->orderBy('`order`_asc, id_asc') + ->orderBy('id_asc') ->query(); } else @@ -93,12 +93,13 @@ class docModel extends model ->beginIF($type)->andWhere('type')->eq($type)->fi() ->beginIF(!$type)->andWhere('type')->ne('api')->fi() ->beginIF($objectID and strpos(',product,project,execution,', ",$type,") !== false)->andWhere($type)->eq($objectID)->fi() - ->orderBy("`order`_asc, id_asc")->query(); + ->orderBy('id_asc') + ->query(); } $products = $this->loadModel('product')->getPairs(); - $projects = $this->loadModel('project')->getPairsByProgram(); - $executions = $this->loadModel('execution')->getPairs(0, 'all', 'multiple,leaf'); + $projects = $this->loadModel('project')->getPairsByProgram('', 'all', false, 'order_asc', 'kanban'); + $executions = $this->loadModel('execution')->getPairs(0, 'sprint,stage', 'multiple,leaf'); $waterfalls = array(); if(empty($objectID) and $type != 'product' and $type != 'project' and $type != 'custom') { @@ -123,14 +124,18 @@ class docModel extends model { if(strpos($extra, 'withObject') !== false) { + if($lib->product != 0) $lib->name = zget($products, $lib->product, '') . ' / ' . $lib->name; if($lib->execution != 0) { $lib->name = zget($executions, $lib->execution, '') . ' / ' . $lib->name; + $lib->name = ltrim($lib->name, '/'); if(!empty($waterfalls[$lib->execution])) $lib->name = $waterfalls[$lib->execution] . ' / ' . $lib->name; $lib->name = trim($lib->name, '/'); } - if($lib->product != 0) $lib->name = zget($products, $lib->product, '') . ' / ' . $lib->name; - if($lib->project != 0) $lib->name = zget($projects, $lib->project, '') . ' / ' . $lib->name; + + if($lib->project != 0) $lib->name = zget($projects, $lib->project, '') . ' / ' . $lib->name; + if($lib->type == 'mine') $lib->name = $this->lang->doc->person . ' / ' . $lib->name; + if($lib->type == 'custom') $lib->name = $this->lang->doc->team . ' / ' . $lib->name; } $libPairs[$lib->id] = $lib->name; @@ -377,8 +382,9 @@ class docModel extends model */ public function getDocsByBrowseType($browseType, $queryID, $moduleID, $sort, $pager) { - $allLibs = array_keys($this->getLibs('all')); - $docIdList = $this->getPrivDocs(0, $moduleID); + $allLibs = $this->getLibs('all'); + $allLibIDList = array_keys($allLibs); + $docIdList = $this->getPrivDocs(0, $moduleID); $files = $this->dao->select('*')->from(TABLE_FILE) ->where('objectType')->eq('doc') @@ -418,7 +424,7 @@ class docModel extends model $docs = $this->dao->select('*')->from(TABLE_DOC) ->where('deleted')->eq(0) ->andWhere($query) - ->andWhere('lib')->in($allLibs) + ->andWhere('lib')->in($allLibIDList) ->beginIF($this->config->doc->notArticleType)->andWhere('type')->notIN($this->config->doc->notArticleType)->fi() ->andWhere('addedBy', 1)->eq($this->app->user->account) ->orWhere('id')->in(array_keys($docIDList)) @@ -431,7 +437,7 @@ class docModel extends model { $docs = $this->dao->select('*')->from(TABLE_DOC) ->where('deleted')->eq(0) - ->andWhere('lib')->in($allLibs) + ->andWhere('lib')->in($allLibIDList) ->beginIF($this->config->doc->notArticleType)->andWhere('type')->notIN($this->config->doc->notArticleType)->fi() ->andWhere('addedBy')->eq($this->app->user->account) ->orderBy($sort) @@ -448,7 +454,7 @@ class docModel extends model $docs = $this->dao->select('*')->from(TABLE_DOC) ->where('deleted')->eq(0) ->andWhere('id')->in(array_keys($docIDList)) - ->andWhere('lib')->in($allLibs) + ->andWhere('lib')->in($allLibIDList) ->beginIF($this->config->doc->notArticleType)->andWhere('type')->notIN($this->config->doc->notArticleType)->fi() ->orderBy($sort) ->page($pager) @@ -460,18 +466,19 @@ class docModel extends model ->where('deleted')->eq(0) ->andWhere('id')->in($docIdList) ->beginIF($this->config->doc->notArticleType)->andWhere('type')->notIN($this->config->doc->notArticleType)->fi() - ->andWhere('lib')->in($allLibs) + ->andWhere('lib')->in($allLibIDList) ->orderBy('editedDate_desc') ->page($pager) ->fetchAll('id'); } elseif($browseType == "collectedbyme") { - $docs = $this->dao->select('*')->from(TABLE_DOC) - ->where('deleted')->eq(0) - ->andWhere('lib')->in($allLibs) - ->beginIF($this->config->doc->notArticleType)->andWhere('type')->notIN($this->config->doc->notArticleType)->fi() - ->andWhere('collector')->like("%,{$this->app->user->account},%") + $docs = $this->dao->select('t1.*')->from(TABLE_DOC)->alias('t1') + ->leftJoin(TABLE_DOCACTION)->alias('t2')->on("t1.id=t2.doc && t2.action='collect'") + ->where('t1.deleted')->eq(0) + ->andWhere('t1.lib')->in($allLibIDList) + ->beginIF($this->config->doc->notArticleType)->andWhere('t1.type')->notIN($this->config->doc->notArticleType)->fi() + ->andWhere('t2.actor')->eq($this->app->user->account) ->orderBy($sort) ->page($pager) ->fetchAll('id'); @@ -480,24 +487,9 @@ class docModel extends model if(empty($docs)) return array(); /* Get projects, executions and products by docIdList. */ - list($projects, $executions, $products) = $this->getObjectsByDoc(array_keys($docs)); - $docContents = $this->dao->select('*')->from(TABLE_DOCCONTENT)->where('doc')->in(array_keys($docs))->orderBy('version,doc')->fetchAll('doc'); - - $objects = array('product' => 'products', 'execution' => 'executions', 'project' => 'projects'); foreach($docs as $index => $doc) { - foreach($objects as $type => $object) - { - if(!empty($doc->{$type})) - { - $doc->objectID = $doc->{$type}; - $doc->objectName = ${$object}[$doc->{$type}]; - $doc->objectType = $type; - break; - } - } - $docs[$index]->fileSize = 0; if(isset($files[$index])) { @@ -530,6 +522,7 @@ class docModel extends model } } + $docs = $this->processCollector($docs); return $docs; } @@ -587,7 +580,8 @@ class docModel extends model */ public function getObjectsByDoc($docIdList = array()) { - if(empty($docIdList)) return array(); + $projects = $executions = $products = array(); + if(empty($docIdList)) return array($projects, $executions, $products); $projects = $this->dao->select('t1.id, t1.name')->from(TABLE_PROJECT)->alias('t1') ->leftJoin(TABLE_DOC)->alias('t2')->on('t1.id=t2.project') @@ -616,20 +610,104 @@ class docModel extends model * @param string $orderBy * @param object $pager * @access public - * @return void + * @return array */ public function getDocs($libID, $module, $browseType, $orderBy, $pager = null) { $docIdList = $this->getPrivDocs($libID, $module, 'children'); - return $this->dao->select('*')->from(TABLE_DOC) + $docs = $this->dao->select('*')->from(TABLE_DOC) ->where('deleted')->eq(0) ->andWhere('vision')->eq($this->config->vision) ->andWhere('id')->in($docIdList) ->beginIF($browseType == 'all')->andWhere("(status = 'normal' or (status = 'draft' and addedBy='{$this->app->user->account}'))")->fi() - ->beginIF($browseType == 'draft')->andWhere('status')->eq('draft')->fi() + ->beginIF($browseType == 'draft')->andWhere('status')->eq('draft')->andWhere('addedBy')->eq($this->app->user->account)->fi() ->orderBy($orderBy) ->page($pager) ->fetchAll('id'); + $docs = $this->processCollector($docs); + return $docs; + } + + /** + * Get mine list. + * + * @param string $type view|collect|createdBy + * @param string $browseType all|draft + * @param string $orderBy + * @param object $pager + * @access public + * @return array + */ + public function getMineList($type, $browseType, $orderBy, $pager = null, $queryID = 0) + { + $query = ''; + if($browseType == 'bysearch') + { + $query = $this->buildQuery($type, $queryID); + $query = preg_replace('/(`\w+`)/', 't1.$1', $query); + } + + $libs = $this->getLibs(); + $docIDList = $this->getPrivDocs(array_keys($libs)); + if($type == 'view' or $type == 'collect') + { + $docs = $this->dao->select('DISTINCT t1.*,t3.name as libName,t3.type as objectType')->from(TABLE_DOC)->alias('t1') + ->leftJoin(TABLE_DOCACTION)->alias('t2')->on("t1.id=t2.doc") + ->leftJoin(TABLE_DOCLIB)->alias('t3')->on("t1.lib=t3.id") + ->where('t1.deleted')->eq(0) + ->andWhere('t1.lib')->ne('') + ->andWhere('t1.vision')->eq($this->config->vision) + ->andWhere('t1.id')->in(array_keys($docIDList)) + ->andWhere('t2.action')->eq($type) + ->andWhere('t2.actor')->eq($this->app->user->account) + ->beginIF($browseType == 'all' or $browseType == 'bysearch')->andWhere("(t1.status = 'normal' or (t1.status = 'draft' and t1.addedBy='{$this->app->user->account}'))")->fi() + ->beginIF($browseType == 'draft')->andWhere('t1.status')->eq('draft')->andWhere('t1.addedBy')->eq($this->app->user->account)->fi() + ->beginIF($browseType == 'bysearch')->andWhere($query)->fi() + ->orderBy($orderBy) + ->page($pager, 't1.id') + ->fetchAll('id'); + } + elseif($type == 'createdby') + { + $docs = $this->dao->select('DISTINCT t1.*,t2.name as libName,t2.type as objectType')->from(TABLE_DOC)->alias('t1') + ->leftJoin(TABLE_DOCLIB)->alias('t2')->on("t1.lib=t2.id") + ->where('t1.deleted')->eq(0) + ->andWhere('t1.lib')->ne('') + ->andWhere('t1.id')->in(array_keys($docIDList)) + ->andWhere('t1.vision')->eq($this->config->vision) + ->andWhere('t1.addedBy')->eq($this->app->user->account) + ->beginIF($browseType == 'draft')->andWhere('t1.status')->eq('draft')->andWhere('t1.addedBy')->eq($this->app->user->account)->fi() + ->beginIF($browseType == 'bysearch')->andWhere($query)->fi() + ->orderBy($orderBy) + ->page($pager) + ->fetchAll('id'); + } + + $this->loadModel('tree'); + $objects = array(); + $modules = array(); + list($objects['project'], $objects['execution'], $objects['product']) = $this->getObjectsByDoc(array_keys($docs)); + foreach($docs as $docID => $doc) + { + if(!isset($modules[$doc->lib])) $modules[$doc->lib] = $this->tree->getOptionMenu($doc->lib, 'doc', 0, 0, 'nodeleted', 'all', ' > '); + $doc->moduleName = zget($modules[$doc->lib], $doc->module); + $doc->moduleName = ltrim($doc->moduleName, '/'); + + $doc->objectID = zget($doc, $doc->objectType, 0); + $doc->objectName = ''; + if(isset($objects[$doc->objectType])) + { + $doc->objectName = $objects[$doc->objectType][$doc->objectID]; + } + else + { + if($doc->objectType == 'mine') $doc->objectName = $this->lang->doc->person; + if($doc->objectType == 'custom') $doc->objectName = $this->lang->doc->team; + } + } + + $docs = $this->processCollector($docs); + return $docs; } /** @@ -684,6 +762,10 @@ class docModel extends model if(strpos($this->server->http_referer, $loginLink) !== false) return print(js::locate(inlink('index'))); return print(js::locate('back')); } + + $docs = $this->processCollector(array($doc->id => $doc)); + $doc = $docs[$doc->id]; + $version = $version ? $version : $doc->version; $docContent = $this->dao->select('*')->from(TABLE_DOCCONTENT)->where('doc')->eq($doc->id)->andWhere('version')->eq($version)->fetch(); @@ -811,7 +893,8 @@ class docModel extends model if(empty($docContent->content)) return dao::$errors['content'] = sprintf($this->lang->error->notempty, $this->lang->doc->content); } - $doc->draft = $docContent->content; + $doc->draft = $docContent->content; + $doc->vision = $this->config->vision; $this->dao->insert(TABLE_DOC)->data($doc, 'content')->autoCheck() ->batchCheck($requiredFields, 'notempty') ->exec(); @@ -921,7 +1004,7 @@ class docModel extends model if($files) $docContent->files .= ',' . join(',', array_keys($files)); $docContent->files = trim($docContent->files, ','); if(isset($doc->digest)) $docContent->digest = $doc->digest; - if($doc->status == 'draft') + if($oldDoc->status == 'draft') { $this->dao->update(TABLE_DOCCONTENT)->data($docContent)->where('id')->eq($oldDocContent->id)->exec(); } @@ -994,7 +1077,7 @@ class docModel extends model unset($this->config->doc->search['fields']['module']); } - elseif(in_array($type, array('product', 'project', 'execution', 'custom', 'mine'))) + else { if(!isset($libs[$libID])) $libs[$libID] = $this->getLibById($libID); @@ -1013,36 +1096,61 @@ class docModel extends model } else { + if($type == 'mine' or $type == 'createdby') + { + unset($this->config->doc->search['fields']['addedBy']); + if($type == 'mine') unset($this->config->doc->search['fields']['editedBy']); + } unset($this->config->doc->search['fields']['execution']); } + if(in_array($type, array('view', 'collect', 'createdby'))) $libPairs = array('' => '') + $this->getLibs('all', 'withObject'); $this->config->doc->search['module'] = $queryName; $this->config->doc->search['params']['lib']['values'] = $libPairs + array('all' => $this->lang->doclib->all); unset($this->config->doc->search['fields']['product']); unset($this->config->doc->search['fields']['module']); } - else - { - $products = $this->product->getPairs('nocode', $this->session->project); - $this->config->doc->search['params']['execution']['values'] = array('' => '') + $this->loadModel('execution')->getPairs($this->session->project, 'sprint,stage', 'multiple,leaf,noprefix') + array('all' => $this->lang->doc->allExecutions); - $this->config->doc->search['params']['lib']['values'] = array('' => '', $libID => ($libID ? $libs[$libID] : 0), 'all' => $this->lang->doclib->all); - $this->config->doc->search['params']['product']['values'] = array('' => '') + $products + array('all' => $this->lang->doc->allProduct); - } $this->config->doc->search['actionURL'] = $actionURL; $this->config->doc->search['queryID'] = $queryID; - /* Get the modules. */ - $this->config->doc->search['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($libID, 'doc', $startModuleID = 0); + $this->loadModel('search')->setSearchParams($this->config->doc->search); + } - if($type == 'index' || $type == 'view' || ($this->app->rawMethod != 'contribute' and $libID == 0)) + /** + * Build search query. + * + * @param string $type + * @param int $queryID + * @access public + * @return string + */ + public function buildQuery($type, $queryID = 0) + { + $queryName = $type . 'libDocQuery'; + $queryForm = $type . 'libDocForm'; + if($queryID) { - unset($this->config->doc->search['fields']['module']); - unset($this->config->doc->search['fields']['lib']); + $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'); } - $this->loadModel('search')->setSearchParams($this->config->doc->search); + $query = $this->session->$queryName; + if(strpos($query, "`lib` = 'all'") !== false) $query = str_replace("`lib` = 'all'", '1', $query); + return $query; } /** @@ -1197,7 +1305,8 @@ class docModel extends model */ public function checkPrivDoc($object) { - if($this->app->user->admin) return true; + $libType = $this->dao->select('type')->from(TABLE_DOCLIB)->where('id')->eq($object->lib)->fetch('type'); + if($this->app->user->admin and $libType != 'mine') return true; static $extraDocLibs; if($extraDocLibs === null) $extraDocLibs = $this->getPrivLibsByDoc(); @@ -1587,7 +1696,7 @@ class docModel extends model ->leftjoin(TABLE_DOCLIB)->alias('t2')->on('t2.project=t1.id') ->where("CONCAT(',', t2.users, ',')")->like("%,{$this->app->user->account},%") ->andWhere('t1.vision')->eq($this->config->vision) - ->andWhere('t1.model')->ne('kanban') + ->beginIF($this->config->vision == 'rnd')->andWhere('model')->ne('kanban')->fi() ->andWhere('t1.deleted')->eq(0) ->beginIF(!$this->app->user->admin)->andWhere('t1.id')->in($this->app->user->view->projects)->fi() ->fetchPairs(); @@ -1597,7 +1706,7 @@ class docModel extends model ->where('type')->eq('project') ->andWhere('vision')->eq($this->config->vision) ->andWhere('deleted')->eq(0) - ->andWhere('model')->ne('kanban') + ->beginIF($this->config->vision == 'rnd')->andWhere('model')->ne('kanban')->fi() ->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->projects)->fi() ->orderBy('order_asc') ->fetchAll('id'); @@ -2032,11 +2141,16 @@ class docModel extends model $lately = date('Y-m-d', strtotime('-3 day')); $statisticInfo = $this->dao->select("count(id) as totalDocs, count(IF(editedDate like '{$today}%', 1, null)) as todayEditedDocs, count(IF(editedDate > '{$lately}', 1, null)) as lastEditedDocs, count(IF(addedDate > '{$lately}', 1, null)) as lastAddedDocs, - count(IF(collector like '%,{$this->app->user->account},%', 1, null)) as myCollection, count(IF(addedBy = '{$this->app->user->account}', 1, null)) as myDocs")->from(TABLE_DOC) + count(IF(addedBy = '{$this->app->user->account}', 1, null)) as myDocs")->from(TABLE_DOC) ->where('deleted')->eq(0) ->andWhere('vision')->eq($this->config->vision) ->andWhere('id')->in($docIdList) ->fetch(); + $statisticInfo->myCollection = $this->dao->select('count(*) as count')->from(TABLE_DOCACTION) + ->where('doc')->in($docIdList) + ->andWhere('action')->eq('collect') + ->andWhere('actor')->eq($this->app->user->account) + ->fetch('count'); $statisticInfo->pastEditedDocs = $statisticInfo->totalDocs - $statisticInfo->todayEditedDocs; $statisticInfo->lastEditedProgress = $statisticInfo->totalDocs ? round($statisticInfo->lastEditedDocs / $statisticInfo->totalDocs, 2) * 100 : 0; @@ -2316,7 +2430,6 @@ class docModel extends model } } - if(isset($moduleDocs[0])) { if(!isset($treeMenu[0])) $treeMenu[0] = ''; @@ -2717,41 +2830,22 @@ class docModel extends model */ public function getDocsBySearch($type, $objectID, $libID, $queryID, $orderBy = 'id_desc', $pager = null) { - $queryName = $type . 'libDocQuery'; - $queryForm = $type . 'libDocForm'; - 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'); - } - - $libs = $this->getLibsByObject($type, $objectID); - $query = $this->session->$queryName; - if(strpos($query, "`lib` = 'all'") !== false) $query = str_replace("`lib` = 'all'", '1', $query); - + $query = $this->buildQuery($type, $queryID); + $libs = $this->getLibsByObject($type, $objectID); $docIdList = $this->getPrivDocs(array_keys($libs)); - return $this->dao->select('*')->from(TABLE_DOC) + $docs = $this->dao->select('*')->from(TABLE_DOC) ->where('deleted')->eq(0) ->andWhere($query) ->andWhere('lib')->in(array_keys($libs)) ->andWhere('vision')->eq($this->config->vision) ->beginIF($this->config->doc->notArticleType)->andWhere('type')->notIN($this->config->doc->notArticleType)->fi() ->beginIF(!empty($docIdList))->andWhere('id')->in($docIdList)->fi() + ->andWhere("(status = 'normal' or (status = 'draft' and addedBy='{$this->app->user->account}'))") ->orderBy($orderBy) ->page($pager) ->fetchAll('id'); + $docs = $this->processCollector($docs); + return $docs; } /** @@ -2787,9 +2881,9 @@ class docModel extends model * @access public * @return array */ - public function getModuleTree($rootID, $moduleID = 0, $type = 'doc', $parent = 0, &$modules = array()) + public function getModuleTree($rootID, $moduleID = 0, $type = 'doc', $parent = 0, $modules = array()) { - if(empty($modules)) + if(is_array($modules) and empty($modules)) { $modules = $this->dao->select('*')->from(TABLE_MODULE) ->where('root')->eq((int)$rootID) @@ -2843,10 +2937,11 @@ class docModel extends model * @param int $objectID * @param int $executionID * @param string $browseType bySearch + * @param int $param * @access public * @return array */ - public function getLibTree($libID, $libs, $type, $moduleID, $objectID = 0, $browseType = '') + public function getLibTree($libID, $libs, $type, $moduleID, $objectID = 0, $browseType = '', $param = 0) { if($type == 'project') { @@ -2857,24 +2952,32 @@ class docModel extends model $executionLibs[$lib->execution][$lib->id] = $lib; } - $executionPairs = $this->dao->select('id,name')->from(TABLE_EXECUTION) - ->where('id')->in(array_keys($executionLibs)) - ->fetchPairs(); + $executionPairs = $this->dao->select('id,name')->from(TABLE_EXECUTION)->where('id')->in(array_keys($executionLibs))->fetchPairs(); } + $release = null; + if($browseType == 'byrelease' and $param) $release = $this->loadModel('api')->getRelease(0, 'byId', $param); + + $browseType = strtolower($browseType); $libTree = array($type => array()); $apiLibs = array(); $apiLibIDList = array(); foreach($libs as $lib) { + $releaseModule = array(); + if($release and $release->lib == $lib->id) + { + foreach($release->snap['modules'] as $module) $releaseModule[$module['id']] = (object)$module; + } + $item = new stdclass(); $item->id = $lib->id; $item->type = $lib->type == 'api' ? 'api' : 'lib'; $item->name = $lib->name; $item->objectType = $type; $item->objectID = $objectID; - $item->active = $lib->id == $libID && $browseType != 'bySearch' ? 1 : 0; - $item->children = $this->getModuleTree($lib->id, $moduleID, $lib->type == 'api' ? 'api' : 'doc'); + $item->active = $lib->id == $libID && $browseType != 'bysearch' ? 1 : 0; + $item->children = $this->getModuleTree($lib->id, $moduleID, $lib->type == 'api' ? 'api' : 'doc', 0, $releaseModule); $showDoc = $this->loadModel('setting')->getItem('owner=' . $this->app->user->account . '&module=doc&key=showDoc'); $showDoc = $showDoc === '0' ? 0 : 1; if($this->app->rawMethod == 'view' and $lib->type != 'api' and $showDoc) @@ -2975,6 +3078,52 @@ class docModel extends model } if($type != 'project') $libTree = array_values($libTree[$type]); + if($type == 'mine') + { + $myLib = new stdclass(); + $myLib->id = 0; + $myLib->name = $this->lang->doc->myLib; + $myLib->type = 'min'; + $myLib->objectType = 'doc'; + $myLib->objectID = 0; + $myLib->active = 0; + $myLib->hasAction = false; + $myLib->active = zget($this->app->rawParams, 'type', '') == 'mine' ? 1 : 0; + $myLib->children = $libTree; + + $myView = new stdclass(); + $myView->id = 0; + $myView->name = $this->lang->doc->myView; + $myView->type = 'view'; + $myView->objectType = 'doc'; + $myView->objectID = 0; + $myView->hasAction = false; + $myView->active = zget($this->app->rawParams, 'type', '') == 'view' ? 1 : 0; + + $myCollection = new stdclass(); + $myCollection->id = 0; + $myCollection->name = $this->lang->doc->myCollection; + $myCollection->type = 'collect'; + $myCollection->objectType = 'doc'; + $myCollection->objectID = 0; + $myCollection->hasAction = false; + $myCollection->active = zget($this->app->rawParams, 'type', '') == 'collect' ? 1 : 0; + + $myCreation = new stdclass(); + $myCreation->id = 0; + $myCreation->name = $this->lang->doc->myCreation; + $myCreation->type = 'createdBy'; + $myCreation->objectType = 'doc'; + $myCreation->objectID = 0; + $myCreation->hasAction = false; + $myCreation->active = zget($this->app->rawParams, 'type', '') == 'createdby' ? 1 : 0; + + $libTree = array(); + $libTree[] = $myLib; + if(common::hasPriv('doc', 'myView')) $libTree[] = $myView; + if(common::hasPriv('doc', 'myCollection')) $libTree[] = $myCollection; + if(common::hasPriv('doc', 'myCreation')) $libTree[] = $myCreation; + } return $libTree; } @@ -3072,4 +3221,92 @@ class docModel extends model if(count($sameNames) > 0 and $libType == 'project') dao::$errors['name'] = $this->lang->doclib->apiNameUnique[$libType] . sprintf($this->lang->error->unique, $this->lang->doclib->name, $lib->name); if(count($sameNames) > 0 and $libType == 'nolink') dao::$errors['name'] = $this->lang->doclib->apiNameUnique[$libType] . sprintf($this->lang->error->unique, $this->lang->doclib->name, $lib->name); } + + /** + * Create action. + * + * @param int $docID + * @param string $action view|collect + * @param string $account + * @access public + * @return int|bool + */ + public function createAction($docID, $action, $account = '') + { + $docID = (int)$docID; + if(empty($docID)) return false; + + if(empty($account))$account = $this->app->user->account; + if($action == 'collect') $this->dao->delete()->from(TABLE_DOCACTION)->where('doc')->eq($docID)->andWhere('action')->eq('collect')->andWhere('actor')->eq($account)->exec(); + + $data = new stdclass(); + $data->doc = $docID; + $data->action = $action; + $data->actor = $account; + $data->date = helper::now(); + $this->dao->insert(TABLE_DOCACTION)->data($data)->autoCheck()->exec(); + if(!dao::isError()) + { + $actionID = $this->dao->lastInsertID(); + if($action == 'view') $this->dao->update(TABLE_DOC)->set('views = views + 1')->where('id')->eq($docID)->exec(); + if($action == 'collect') + { + $collectCount = $this->dao->select('count(*) as count')->from(TABLE_DOCACTION)->where('doc')->eq($docID)->andWhere('action')->eq('collect')->fetch('count'); + $this->dao->update(TABLE_DOC)->set('collector')->eq($collectCount)->where('id')->eq($docID)->exec(); + } + + return $actionID; + } + } + + /** + * Get action by object. + * + * @param int $docID + * @param string $action view|collect + * @param string $account + * @access public + * @return object + */ + public function getActionByObject($docID, $action, $account = '') + { + if(empty($account)) $account = $this->app->user->account; + return $this->dao->select('*')->from(TABLE_DOCACTION)->where('doc')->eq((int)$docID)->andWhere('action')->eq($action)->andWhere('actor')->eq($account)->fetch(); + } + + /** + * Delete action. + * + * @param int $actionID + * @access public + * @return void + */ + public function deleteAction($actionID) + { + $action = $this->dao->select('*')->from(TABLE_DOCACTION)->where('id')->eq($actionID)->fetch(); + $this->dao->delete()->from(TABLE_DOCACTION)->where('id')->eq($actionID)->exec(); + if($action->action == 'collect') + { + $collectCount = $this->dao->select('count(*) as count')->from(TABLE_DOCACTION)->where('doc')->eq($action->doc)->andWhere('action')->eq('collect')->fetch('count'); + $this->dao->update(TABLE_DOC)->set('collector')->eq($collectCount)->where('id')->eq($action->doc)->exec(); + } + } + + /** + * Process collector to account. + * + * @param array $docs + * @access public + * @return array + */ + public function processCollector($docs) + { + $actionGroup = $this->dao->select('*')->from(TABLE_DOCACTION)->where('doc')->in(array_keys($docs))->andWhere('action')->eq('collect')->fetchGroup('doc', 'actor'); + foreach($docs as $docID => $doc) + { + $doc->collector = ''; + if(isset($actionGroup[$docID])) $doc->collector = ',' . implode(',', array_keys($actionGroup[$docID])) . ','; + } + return $docs; + } } diff --git a/module/doc/view/content.html.php b/module/doc/view/content.html.php index de873d0a55..8ab4482625 100644 --- a/module/doc/view/content.html.php +++ b/module/doc/view/content.html.php @@ -1,7 +1,7 @@ doc->confirmDelete);?> -
    -
    +
    +
    @@ -30,8 +30,13 @@
    + doc->diff?> + ', '', "title='{$lang->fullscreen}' class='btn btn-link fullscreen-btn'");?> + + collector, ',' . $this->app->user->account . ',') !== false ? 'star' : 'star-empty';?> + id&objectType=doc");?>" title="doc->collect;?>" class='ajaxCollect btn btn-link'> + ', '', "title='{$lang->fullscreen}' class='btn btn-link fullscreen-btn'"); if(common::hasPriv('doc', 'edit')) { $iframe = ''; @@ -41,20 +46,16 @@ $iframe = 'iframe'; $onlybody = 'true'; } - echo html::a(inlink('edit', "docID=$doc->id&comment=false&objectType=$objectType&objectID=$object->id&libID=$libID", '', $onlybody), '', '', "title='{$lang->doc->edit}' class='btn btn-link $iframe' data-app='{$this->app->tab}'"); + echo html::a(inlink('edit', "docID=$doc->id&comment=false&objectType=$objectType&objectID=$object->id&libID=$libID", '', $onlybody), '', '', "title='{$lang->doc->edit}' class='btn btn-link $iframe' data-app='{$this->app->tab}'"); } if(common::hasPriv('doc', 'delete')) { $deleteURL = $this->createLink('doc', 'delete', "docID=$doc->id&confirm=yes&from=lib"); - echo html::a("javascript:ajaxDeleteDoc(\"$deleteURL\", \"docList\", confirmDelete)", '', '', "title='{$lang->doc->delete}' class='btn btn-link'"); - } - ?> - - collector, ',' . $this->app->user->account . ',') !== false ? 'star' : 'star-empty';?> - id&objectType=doc");?>" title="doc->collect;?>" class='ajaxCollect btn btn-link'> - + echo html::a("javascript:ajaxDeleteDoc(\"$deleteURL\", \"docList\", confirmDelete)", '', '', "title='{$lang->doc->delete}' class='btn btn-link'"); + }?> + history?>> - config->edition == 'max' and $this->app->tab == 'project'):?> + vision == 'rnd' and $config->edition == 'max' and $app->tab == 'project'):?> import}'>"; - echo html::a('javascript:;', "", '', "data-toggle='dropdown' class='btn btn-link'"); + echo html::a('javascript:;', "", '', "data-toggle='dropdown' class='btn btn-link'"); echo "
    -
    +
    -
    config->edition == 'max'):?> diff --git a/module/doc/view/createtexttype.html.php b/module/doc/view/createtexttype.html.php index 29fef3b581..225d86f946 100644 --- a/module/doc/view/createtexttype.html.php +++ b/module/doc/view/createtexttype.html.php @@ -60,7 +60,7 @@ - + @@ -68,8 +68,8 @@ - - app->tab == 'doc'):?> + + app->tab == 'doc' and $config->vision == 'rnd'):?> @@ -77,17 +77,17 @@ - + - + - - + + @@ -111,7 +111,7 @@ diff --git a/module/doc/view/doclist.html.php b/module/doc/view/doclist.html.php index 05c88973bb..62719df5f6 100644 --- a/module/doc/view/doclist.html.php +++ b/module/doc/view/doclist.html.php @@ -16,6 +16,7 @@ body {margin-bottom: 25px;} #docListForm th.c-user {width: 80px;} #docListForm th.c-actions {width: 84px; padding-left: 15px;} #docListForm .checkbox-primary {line-height: 16px;} +#docListForm table .checkbox-primary {top: -2px;} #docListForm .checkbox-primary > label {height: 16px; line-height: 16px; padding-left: 16px;} #docListForm .checkbox-primary > label:before {left: -1px; font-size: 10px;} #docListForm .checkbox-primary > label:after {width: 12px; height: 12px;} diff --git a/module/doc/view/editothertype.html.php b/module/doc/view/editothertype.html.php index 0928aff2a6..983e8586d1 100644 --- a/module/doc/view/editothertype.html.php +++ b/module/doc/view/editothertype.html.php @@ -35,7 +35,7 @@ - + diff --git a/module/doc/view/edittexttype.html.php b/module/doc/view/edittexttype.html.php index fe019995e1..cc6e1f388a 100644 --- a/module/doc/view/edittexttype.html.php +++ b/module/doc/view/edittexttype.html.php @@ -70,12 +70,12 @@ - + - - + + diff --git a/module/doc/view/index.html.php b/module/doc/view/index.html.php index c664665280..90e969ab9e 100644 --- a/module/doc/view/index.html.php +++ b/module/doc/view/index.html.php @@ -11,197 +11,5 @@ */ ?> -
    -
    -
    -
    -
    -
    -
    -
    doc->orderByEdit;?>
    - -
    - -
    -

    doc->noDoc;?>

    -
    - -
    -
    doc->title?>
    doc->project;?>project : $objectID, "class='form-control chosen' onchange=loadExecutions(this.value)");?>project : $objectID, "class='form-control picker-select' onchange=loadExecutions(this.value)");?>doc->execution?> doc->placeholder->execution}' onchange='loadObjectModules(\"execution\", this.value)'")?>
    doc->execution;?>
    doc->product;?>
    doc->libAndModule?>doc->libAndModule?>
    doc->keywords;?>
    doclib->control;?> - doc->aclList, 'open', "onchange='toggleAcl(this.value, \"doc\")'");?> + doc->aclList, $objectType == 'mine' ? 'private' : 'open', "onchange='toggleAcl(this.value, \"doc\")'");?>
    doc->libAndModule?>doc->libAndModule?> lib . '_' . $doc->module, "class='form-control chosen'");?>
    doc->project;?>
    doc->libAndModule?>lib . '_' . $doc->module, "class='form-control chosen'");?>doc->libAndModule?>lib . '_' . $doc->module, "class='form-control picker-select'");?>
    doc->keywords;?>
    - - - - - - - - - - - - - - - - - - -
    doc->title;?>doc->size;?>doc->addedBy;?>doc->editedDate;?>
    createLink('doc', 'view', "docID={$doc->id}", '', true), $doc->title, '', "data-toggle='modal' data-type='iframe' data-width='90%' title='{$doc->title}'")?>fileSize ? $doc->fileSize : '-';?>addedBy);?>editedDate) ? formatTime($doc->addedDate, 'Y-m-d') : formatTime($doc->editedDate, 'Y-m-d');?>
    -
    - -
    -
    -
    -
    -
    -
    doc->allDoc . ' ' . $statisticInfo->totalDocs;?>
    -
    - -
    -
    -
    -
    -
    -
    doc->myDoc;?>
    - -
    - -
    -

    doc->noDoc;?>

    -
    - -
    - - - - - - - - - - - - - - - - - - - -
    doc->title;?>doc->size;?>doc->addedBy;?>doc->editedDate;?>
    createLink('doc', 'view', "docID={$doc->id}", '', true), $doc->title, '', "data-toggle='modal' data-type='iframe' data-width='90%' title='{$doc->title}'")?>fileSize ? $doc->fileSize : '-';?>addedBy);?>editedDate) ? formatTime($doc->editedDate, 'Y-m-d') : formatTime($doc->addedDate, 'y-m-d');?>
    -
    - -
    -
    -
    -
    -
    -
    doc->myCollection;?>
    - -
    - -
    -

    doc->noDoc;?>

    -
    - -
    - - - - - - - - - - - - - - - - - -
    doc->title;?>doc->addedBy;?>doc->editedDate;?>
    createLink('doc', 'view', "docID={$doc->id}", '', true), $doc->title, '', "data-toggle='modal' data-type='iframe' data-width='90%' title='{$doc->title}'")?>addedBy);?>editedDate) ? formatTime($doc->editedDate, 'Y-m-d') : formatTime($doc->addedDate, 'y-m-d');?>
    -
    - -
    -
    -
    -
    -
    +fetch('block', 'dashboard', 'module=doc');?> diff --git a/module/doc/view/lefttree.html.php b/module/doc/view/lefttree.html.php index 5b101f17f4..0da8f7e00b 100644 --- a/module/doc/view/lefttree.html.php +++ b/module/doc/view/lefttree.html.php @@ -23,13 +23,13 @@ .input-tree {width: 120px;} .tree-icon {position: absolute; right: 0;} .tree li.has-input {overflow: hidden;} +.tree li.has-input > input {margin-left: 15px;} .img-lib {flex: 0 0 14px; height: 14px; margin-right: 5px;} .tree-icon {position: absolute; right: 0;} .tree li > a {max-width: 100%; padding: 2px;} .file-tree a.show-icon > div, .file-tree a.hover > div {padding-right: 15px;} -.tree li.has-input {overflow: hidden;} -.tree-text {overflow: hidden;} +.tree-text {overflow: hidden; min-width: 50px;} i.btn-info, i.btn-info:hover {border: none; background: #fff; box-shadow: unset;} .tree-version-trigger {padding: 0 10px; width: 54px; border-radius: 5px; background: #F9F9F9; display: flex; align-items: center;} .tree-version-trigger > .text {overflow: hidden; flex: 0 0 30px;} @@ -39,7 +39,7 @@ i.btn-info, i.btn-info:hover {border: none; background: #fff; box-shadow: unset; /* css for sidebar */ .sidebar-toggle {flex: 0 0 16px;} .sidebar-toggle > .icon {width: 12px; height: 30px; margin-top: -10px; line-height: 30px; color: #fff; text-align: center; background: #7dcdfe; border-radius: 6px; cursor: pointer; padding-left: 0; padding-top: 0;} -.bottom-btn-tree {position: fixed; bottom: 66px; left: 48px;} +.bottom-btn-tree {position: absolute; bottom: 15px; left: 25px;} .spliter {flex: 0 0 12px;} .spliter-btn {height: 28px; width: 10px; background: #fff; position: absolute; top: 30%; left: -1px; border: 1px solid #D9D9D9; border-radius: 2px;} @@ -92,39 +92,54 @@ js::set('canViewFiles', common::hasPriv('doc', 'showfiles')); - - - - - - - - -rawModule, 'editLib') || common::hasPriv($app->rawModule, 'deleteLib'));?> + '; $item += ''; if(item.versions) versionsData[item.id] = item.versions; @@ -268,8 +288,8 @@ $(function() if(isFirstLoad) ele.data('zui.tree').collapse(); - var $leaf = ele.find('li.active'); - if($leaf.length) $leaf[$leaf.length - 1].scrollIntoView(false); + var $leaf = ele.find('li.active > a'); + if($leaf.length && $('#fileTree').height() >= $('#sideBar').height()) $('#sideBar')[0].scrollTop = $($leaf[$leaf.length - 1]).offset().top - 100; ele.on('click', '.icon-drop', function(e) { @@ -329,8 +349,9 @@ $(function() if($(this).data('type') == 'annex') return; if(!$(this).data('action')) return; - var libClass = '.libDorpdown'; - if(!$(this).hasClass('lib')) libClass = '.moduleDorpdown'; + var moduleType = $(this).data('type') == 'api' ? 'api' : 'doc'; + var libClass = '.' + moduleType + 'LibDorpdown'; + if(!$(this).hasClass('lib')) libClass = '.' + moduleType + 'ModuleDorpdown'; $(this).find('.icon').removeClass('hidden'); $(this).addClass('show-icon'); @@ -360,7 +381,7 @@ $(function() libID = $(this).closest('.lib').data('id'); } - return lcatePage(libID, moduleID, $(this).data('type')); + return locatePage(libID, moduleID, $(this).data('type')); }).on('click', '.tree-version-trigger', function(e) { $('.dropdown-in-tree').remove(); @@ -408,8 +429,10 @@ $(function() * @access public * @return void */ - function lcatePage(libID, moduleID, type) + function locatePage(libID, moduleID, type) { + if(!libID) libID = 0; + if(!moduleID) moduleID = 0; linkParams = linkParams.replace('%s', 'libID=' + libID + '&moduleID=' + moduleID); var methodName = ''; if(config.currentModule == 'api') @@ -422,10 +445,13 @@ $(function() methodName = 'showFiles'; linkParams = 'type=' + objectType + '&objectID=' + objectID; } - else if(objectType == 'mine') + else if(objectType == 'mine' || objectType == 'view' || objectType == 'collect' || objectType == 'createdby') { + var mySpaceType = 'mine'; + if(type == 'view' || type == 'collect' || type == 'createdBy') mySpaceType = type; + methodName = 'mySpace'; - linkParams = 'type=mine&libID=' + libID; + linkParams = 'type='+ mySpaceType + '&libID=' + libID + '&moduleID=' + moduleID; } else if(['text', 'word', 'ppt', 'excel'].indexOf(type) !== -1) { @@ -509,7 +535,7 @@ $(function() else { var $input = $('[data-id=ulTreeModal]').html(); - var $rootDom = $('[data-id=' + item.libid + ']a'); + var $rootDom = $('[data-id=' + item.libid + ']a.lib'); var $li = $rootDom.parent(); moduleData.isUpdate = true; $rootDom.after($input); @@ -548,9 +574,16 @@ $(function() } }).on('click', '#versionSwitcher a', function() { - var $item = $(this); - linkParams = linkParams.replace('%s', 'libID=' + $item.closest('ul').data('libId') + '&moduleID=0&apiID=0&version=0&release=' + $item.data('id')); - location.href = createLink(config.currentModule, 'index', linkParams); + var libID = $(this).closest('#versionSwitcher').data('lib'); + var moduleID = $(this).data('id'); + var params = 'libID=' + libID + '&moduleID=0&apiID=0&version=0&release=' + moduleID; + var methodName = config.currentMethod; + if(config.currentModule == 'doc') + { + params = linkParams.replace('%s', 'libID=' + libID + '&moduleID=' + moduleID).replace('browseType=&', 'browseType=byrelease&').replace('param=0', 'param=' + moduleID); + methodName = objectType + 'Space'; + } + location.href = createLink(config.currentModule, methodName, params); }).on('blur', '.file-tree input.input-tree', function() { var $input = $(this); @@ -583,7 +616,7 @@ $(function() } var module = result.module; - return lcatePage(module.root, module.id, 'doc'); + return locatePage(module.root, module.id, 'doc'); }); }).on('keydown', '.file-tree input.input-tree', function(e) { diff --git a/module/doc/view/mydoclist.html.php b/module/doc/view/mydoclist.html.php index b877953a20..b551996f7e 100644 --- a/module/doc/view/mydoclist.html.php +++ b/module/doc/view/mydoclist.html.php @@ -15,10 +15,18 @@ body {margin-bottom: 25px;} #docListForm th.c-id {width: 72px;} #docListForm th.c-user {width: 80px;} #docListForm th.c-actions {width: 84px; padding-left: 15px;} +#docListForm .c-module, #docListForm .c-object {width: 120px; overflow: hidden; white-space: nowrap; text-overflow: clip;} +#docListForm .table .c-name > .doc-title {display: inline-block; max-width: calc(100% - 80px); overflow: hidden; background: transparent; padding-right:0px;} +#docListForm .table .c-name > span.doc-title {line-height: 0; vertical-align: inherit;} +#docListForm .table .c-name > .draft {background-color:rgba(129, 102, 238, 0.12); color:#8166EE;} +#docListForm .table .c-name > .ajaxCollect {float: right; position: relative; right: 10px; top: 0px;} +#docListForm table.table > thead > tr {height: 32px;} #docListForm .checkbox-primary {line-height: 16px;} +#docListForm table .checkbox-primary {top: -2px;} #docListForm .checkbox-primary > label {height: 16px; line-height: 16px; padding-left: 16px;} #docListForm .checkbox-primary > label:before {left: -1px; font-size: 10px;} #docListForm .checkbox-primary > label:after {width: 12px; height: 12px;} +.table-files .btn {padding: 0 2px;} +