diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000..46cded4c0d --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +./.git +./build +./Jenkinsfile +./Makefile diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 391f318220..0000000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,68 +0,0 @@ -stages: - - sonarqube - - unit-test - - ui-test - - package - - cleanup-packages - - notify - -program-static-analysis: - stage: sonarqube - image: - name: sonarsource/sonar-scanner-cli:latest - entrypoint: [""] - variables: - SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" # Defines the location of the analysis task cache - GIT_DEPTH: "0" # Tells git to fetch all the branches of the project, required by the analysis task - cache: - key: "${CI_JOB_NAME}" - paths: - - .sonar/cache - script: - - sonar-scanner -Dsonar.inclusions=$(git diff --name-only HEAD~1|tr '\n' ',') -Dsonar.analysis.user=${GITLAB_USER_LOGIN} - allow_failure: true - only: - - master # or the name of your main branch - -unit-test: - stage: unit-test - script: - - "/home/gitlab-runner/bin/zentao-unittest.sh ${CI_PROJECT_DIR}" - allow_failure: true - only: - - master - - merge_requests - -ui-test: - stage: ui-test - script: - - "/home/gitlab-runner/bin/zentao-uitest.sh ${CI_PROJECT_DIR}" - allow_failure: true - only: - - master - - merge_requests - -package: - stage: package - script: - - make cizip - allow_failure: true - only: - - master - -cleanup-packages: - stage: cleanup-packages - script: - - make clean - when: on_failure - only: - - master - -notify: - stage: notify - script: - - "/home/gitlab-runner/bin/ci-notify.php" - when: on_success - only: - - master - - merge_requests diff --git a/Dockerfile.test b/Dockerfile.test new file mode 100644 index 0000000000..5dc0041958 --- /dev/null +++ b/Dockerfile.test @@ -0,0 +1,15 @@ +FROM hub.qucheng.com/ci/zentao-ztf:latest + +# Install zentao +ARG VERSION +ENV ZENTAO_VER=${VERSION} +ENV EASYSOFT_APP_NAME="ZenTao $ZENTAO_VER" + +ARG MYSQL_HOST +ARG MYSQL_PASSWORD +ENV MYSQL_HOST=${MYSQL_HOST} +ENV MYSQL_PASSWORD=${MYSQL_PASSWORD} + +SHELL ["/bin/bash", "-c"] +# Copy ZenTao +COPY --chown=33:33 . /apps/zentao/ diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100755 index 0000000000..1d3a2d1538 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,300 @@ +pipeline { + agent { + kubernetes { + inheritFrom "build-docker code-scan xuanim mysql-server" + } + } + + environment { + ZENTAO_VERSION = """${sh( + returnStdout: true, + script: 'cat VERSION' + ).trim()}""" + MYSQL_SERVER_HOST = """${sh( + returnStdout: true, + script: 'hostname -I' + ).trim()}""" + MYSQL_ROOT_PASSWORD = 'pass4ci' + + MIDDLE_IMAGE_REPO = "hub.qc.oop.cc/zentao-ztf" + MIDDLE_IMAGE_TAG = """${sh( + returnStdout: true, + script: 'echo $BUILD_ID' + ).trim()}""" + } + + stages { + stage("checkout code") { + steps { + echo "checkout code success" + } + } + + stage('Sonar Scanner') { + parallel { + stage('SonarQube') { + steps { + container('sonar') { + withSonarQubeEnv('sonarqube') { + sh 'git config --global --add safe.directory $(pwd)' + sh 'sonar-scanner -Dsonar.inclusions=$(git diff --name-only HEAD~1|tr "\\n" ",") -Dsonar.analysis.user=$(git show -s --format=%an)' + } + } + } + post { + success { + container('xuanimbot') { + sh 'git config --global --add safe.directory $(pwd)' + sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%cn)" --title "sonar scanner" --url "https://sonar.qc.oop.cc/dashboard?id=zentaopms&branch=${GIT_BRANCH}" --content "sonar scanner success" --debug --custom' + } + } + failure { + container('xuanimbot') { + sh 'git config --global --add safe.directory $(pwd)' + sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%cn)" --title "sonar scanner" --url "https://sonar.qc.oop.cc/dashboard?id=zentaopms&branch=${GIT_BRANCH}" --content "sonar scanner failure" --debug --custom' + } + } + } + } + + stage('Build Image') { + steps { + container('docker') { + sh 'docker build --pull . -f Dockerfile.test --build-arg VERSION=${ZENTAO_VERSION} --build-arg MIRROR=true --build-arg MYSQL_HOST=${MYSQL_SERVER_HOST} --build-arg MYSQL_PASSWORD=${MYSQL_ROOT_PASSWORD} -t ${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}' + sh 'docker push ${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}' + } + } + post { + success { + echo 'build image success' + } + failure { + container('xuanimbot') { + sh 'git config --global --add safe.directory $(pwd)' + sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%cn)" --title "build image" --url "${RUN_DISPLAY_URL}" --content "Build unit test image failure" --debug --custom' + } + } + } + } + } + } + + stage('Unit Test'){ + stages{ + stage('Init') { + agent { + kubernetes { + inheritFrom "xuanim" + containerTemplate { + name "zentao" + image "${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}" + command "sleep" + args "99d" + } + } + } + options { skipDefaultCheckout() } + + steps { + container('zentao') { + sh 'initdb.php ; /apps/zentao/test/ztest init' + } + } + post { + success { + sh 'echo "stage unit init success"' + } + failure { + container('xuanimbot') { + sh 'git config --global --add safe.directory $(pwd)' + sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%cn)" --title "unittest init" --url "${RUN_DISPLAY_URL}" --content "Unit test database initialization failed" --debug --custom' + } + } + } + } + + stage('Run') { + parallel { + stage('UnitTest P1') { + agent { + kubernetes { + inheritFrom "xuanim" + containerTemplate { + name "zentao1" + image "${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}" + command "sleep" + args "99d" + } + } + } + options { skipDefaultCheckout() } + + steps { + container('zentao1') { + sh 'initdb.php config' + sh '/apps/zentao/test/ztest extract ; /apps/zentao/test/ztest P1 | tee /apps/zentao/test/p1.log' + sh 'pipeline-unittest.sh /apps/zentao/test/p1.log' + } + } + } + + stage('UnitTest P2') { + agent { + kubernetes { + inheritFrom "xuanim" + containerTemplate { + name "zentao2" + image "${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}" + command "sleep" + args "99d" + } + } + } + options { skipDefaultCheckout() } + + steps { + container('zentao2') { + sh 'initdb.php config' + sh '/apps/zentao/test/ztest extract ; /apps/zentao/test/ztest P2 | tee /apps/zentao/test/p2.log' + sh 'pipeline-unittest.sh /apps/zentao/test/p2.log' + } + } + + } + + stage('UnitTest P3') { + agent { + kubernetes { + inheritFrom "xuanim" + containerTemplate { + name "zentao3" + image "${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}" + command "sleep" + args "99d" + } + } + } + options { skipDefaultCheckout() } + + steps { + container('zentao3') { + sh 'initdb.php config' + sh '/apps/zentao/test/ztest extract ; /apps/zentao/test/ztest P3 | tee /apps/zentao/test/p3.log' + sh 'pipeline-unittest.sh /apps/zentao/test/p3.log' + } + } + } + + stage('UnitTest P4') { + agent { + kubernetes { + inheritFrom "xuanim" + containerTemplate { + name "zentao4" + image "${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}" + command "sleep" + args "99d" + } + } + } + options { skipDefaultCheckout() } + + steps { + container('zentao4') { + sh 'initdb.php config' + sh '/apps/zentao/test/ztest extract ; /apps/zentao/test/ztest P4 | tee /apps/zentao/test/p4.log ' + sh 'pipeline-unittest.sh /apps/zentao/test/p4.log' + } + } + + } + + stage('UnitTest P5') { + agent { + kubernetes { + inheritFrom "xuanim" + containerTemplate { + name "zentao5" + image "${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}" + command "sleep" + args "99d" + } + } + } + options { skipDefaultCheckout() } + + steps { + container('zentao5') { + sh 'initdb.php config' + sh '/apps/zentao/test/ztest extract ; /apps/zentao/test/ztest P5 | tee /apps/zentao/test/p5.log' + sh 'pipeline-unittest.sh /apps/zentao/test/p5.log' + } + } + } + + stage('UnitTest P6') { + agent { + kubernetes { + inheritFrom "xuanim" + containerTemplate { + name "zentao6" + image "${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}" + command "sleep" + args "99d" + } + } + } + options { skipDefaultCheckout() } + + steps { + container('zentao6') { + sh 'initdb.php config' + sh '/apps/zentao/test/ztest extract ; /apps/zentao/test/ztest P6 | tee /apps/zentao/test/p6.log' + sh 'pipeline-unittest.sh /apps/zentao/test/p6.log' + } + } + } + + stage('UnitTest P7') { + agent { + kubernetes { + inheritFrom "xuanim" + containerTemplate { + name "zentao7" + image "${MIDDLE_IMAGE_REPO}:${MIDDLE_IMAGE_TAG}" + command "sleep" + args "99d" + } + } + } + options { skipDefaultCheckout() } + + steps { + container('zentao7') { + sh 'initdb.php config' + sh '/apps/zentao/test/ztest extract ; /apps/zentao/test/ztest P7 | tee /apps/zentao/test/p7.log' + sh 'pipeline-unittest.sh /apps/zentao/test/p7.log' + } + } + } + } // End Parallel + } + } + post{ + success{ + container('xuanimbot') { + sh 'git config --global --add safe.directory /home/jenkins/agent/workspace/pangu_pangu_xuanimbot_master' + sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%cn)" --title "unittest" --url "${RUN_DISPLAY_URL}" --content "Unit test passed" --debug --custom' + } + } + failure{ + container('xuanimbot') { + sh 'git config --global --add safe.directory $(pwd)' + sh '/usr/local/bin/xuanimbot --users "$(git show -s --format=%cn)" --title "unittest" --url "${RUN_DISPLAY_URL}" --content "Unit test failed" --debug --custom' + } + } + } + }//End unittest + + } // End Root Stages +} // End pipeline diff --git a/Makefile b/Makefile index 399e35d52f..4db7860f8a 100644 --- a/Makefile +++ b/Makefile @@ -102,10 +102,10 @@ zentaoxx: mkdir zentaoxx/db/ cp zentaoxx/db_bak/upgradexuanxuan*.sql zentaoxx/db_bak/xuanxuan.sql zentaoxx/db/ rm -rf zentaoxx/db_bak/ - sed -i "s/\$$accountAdmin = \$$this->dao->select('account, admin')->from(TABLE_USER)->where('id')->eq(\$$userID)->fetch();/\$$accountAdmin = \$$this->dao->select('account')->from(TABLE_USER)->where('id')->eq(\$$userID)->fetch();\n\$$admins = \$$this->dao->select('admins')->from(TABLE_COMPANY)->where('id')->eq(\$$this->app->company->id)->fetch('admins');\n\$$adminArray = explode(',', \$$admins);\n\$$accountAdmin->admin = in_array(\$$accountAdmin->account, \$$adminArray) ? 'super' : '';\n/" zentaoxx/extension/xuan/im/model/chat.php + sed -i "s/\$$accountAdmin = \$$this->dao->select('account, admin')->from(TABLE_USER)->where('id')->eq(\$$userID)->fetch();/\$$accountAdmin = \$$this->dao->select('account')->from(TABLE_USER)->where('id')->eq(\$$userID)->fetch();\n\$$sysAdmins = \$$this->dao->select('admins')->from(TABLE_COMPANY)->where('id')->eq(\$$this->app->company->id)->fetch('admins');\n\$$sysAdminArray = explode(',', \$$sysAdmins);\n\$$accountAdmin->admin = in_array(\$$accountAdmin->account, \$$sysAdminArray) ? 'super' : '';\n/" zentaoxx/extension/xuan/im/model/chat.php sed -i "s/\$$sysAdmins = \$$this->dao->select('id')->from(TABLE_USER)->where('admin')->eq('super')->fetchPairs();/\$$account = \$$this->loadModel('user')->getById(\$$userID);\n\$$admins = \$$this->dao->select('admins')->from(TABLE_COMPANY)->where('id')->eq(\$$this->app->company->id)->fetch('admins');\n\$$adminArray = explode(',', \$$admins);\nreturn in_array(\$$account, \$$adminArray);\n/" zentaoxx/extension/xuan/im/model/chat.php sed -i "/->on('tc.ownedBy=tu.account')/{ N ; s/type/tc.type/}" zentaoxx/extension/xuan/im/model/chat.php - sed -i "s/\$$super = \$$this->dao->select('admin')->from(TABLE_USER)->where('id')->eq(\$$userID)->fetch('admin');/\$$account = \$$this->dao->select('account')->from(TABLE_USER)->where('id')->eq(\$$userID)->fetch('account');\n\$$admins = \$$this->dao->select('admins')->from(TABLE_COMPANY)->where('id')->eq(\$$this->app->company->id)->fetch('admins');\n\$$adminArray = explode(',', \$$admins);\n\$$super = in_array(\$$account, \$$adminArray) ? 'super' : '';/g" zentaoxx/extension/xuan/im/control.php + sed -i "s/\$$super = \$$this->dao->select('admin')->from(TABLE_USER)->where('id')->eq(\$$userID)->fetch('admin');/\$$account = \$$this->dao->select('account')->from(TABLE_USER)->where('id')->eq(\$$userID)->fetch('account');\n\$$sysAdmins = \$$this->dao->select('admins')->from(TABLE_COMPANY)->where('id')->eq(\$$this->app->company->id)->fetch('admins');\n\$$sysAdminArray = explode(',', \$$sysAdmins);\n\$$super = in_array(\$$account, \$$sysAdminArray) ? 'super' : '';/g" zentaoxx/extension/xuan/im/control.php sed -i "/foreach(\$$users as \$$user)/i \$$admins = \$$this->dao->select('admins')->from(TABLE_COMPANY)->where('id')->eq(\$$this->app->company->id)->fetch('admins');\$$adminArray = explode(',', \$$admins);" zentaoxx/extension/xuan/im/model/user.php sed -i "/if(\!isset(\$$user->signed)) \$$user->signed = 0;/a \$$user->admin = in_array(\$$user->account, \$$adminArray) ? 'super' : '';" zentaoxx/extension/xuan/im/model/user.php sed -i "/updateUser->ping/d" zentaoxx/extension/xuan/im/model/user.php diff --git a/api/v1/entries/hostsubmit.php b/api/v1/entries/hostsubmit.php index 07bb56112c..00945ca704 100644 --- a/api/v1/entries/hostsubmit.php +++ b/api/v1/entries/hostsubmit.php @@ -50,7 +50,7 @@ class hostSubmitEntry extends baseEntry { if(in_array($image->status, array('failed', 'completed'))) $image->status = $image->status == 'completed' ? 'restore_completed' : 'restore_failed'; } - else if($imageInfo->from == 'snapshot' && $imageInfo->status == 'creating') + else if($imageInfo->from == 'snapshot') { if($image->status == 'failed') { diff --git a/db/standard/zentao18.3.sql b/db/standard/zentao18.3.sql index 868994d561..f5f48c81f1 100644 --- a/db/standard/zentao18.3.sql +++ b/db/standard/zentao18.3.sql @@ -857,19 +857,6 @@ CREATE TABLE `zt_designspec` ( `files` varchar(255) NOT NULL, UNIQUE KEY `design` (`design`,`version`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -CREATE TABLE `zt_dimension` ( - `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, - `name` varchar(90) NOT NULL, - `code` varchar(45) NOT NULL, - `desc` text NOT NULL, - `createdBy` varchar(30) NOT NULL, - `createdDate` datetime NOT NULL, - `editedBy` varchar(30) NOT NULL, - `editedDate` datetime NOT NULL, - `deleted` enum('0','1') NOT NULL DEFAULT '0', - PRIMARY KEY (`id`), - KEY `code` (`code`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `zt_doc` ( `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, `vision` varchar(10) NOT NULL DEFAULT 'rnd', diff --git a/db/update17.8.sql b/db/update17.8.sql index 62dd3545a3..edb113421d 100644 --- a/db/update17.8.sql +++ b/db/update17.8.sql @@ -31,7 +31,7 @@ REPLACE INTO `zt_report` (`code`, `name`, `module`, `sql`, `vars`, `langs`, `par ('product-quality', '{\"zh-cn\":\"\\u4ea7\\u54c1\\u8d28\\u91cf\\u8868\",\"zh-tw\":\"\\u7522\\u54c1\\u8cea\\u91cf\\u8868\",\"en\":\"Product Quality\",\"de\":\"Product Quality\",\"fr\":\"Product Quality\"}', ',product', 'select t1.id,t1.name,t2.stories,(t2.stories-t2.undone) as doneStory,t3.bugs,t3.resolutions,round(t3.bugs/(t2.stories-t2.undone),2) as bugthanstory,t3.seriousBugs from TABLE_PRODUCT as t1 \r\nleft join ztv_productstories as t2 on t1.id=t2.product \r\nleft join ztv_productbugs as t3 on t1.id=t3.product \r\nleft join TABLE_PROGRAM as t4 on t1.program=t4.id \r\nwhere t1.deleted=\'0\'\r\norder by t4.`order` asc, t1.line desc, t1.`order` asc', '', '{\"stories\":{\"zh-cn\":\"\\u9700\\u6c42\\u603b\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u603b\\u6570\",\"en\":\"Stories\"},\"doneStory\":{\"zh-cn\":\"\\u5b8c\\u6210\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u9700\\u6c42\\u6570\",\"en\":\"Finished Stories\"},\"bugs\":{\"zh-cn\":\"Bug\\u6570\",\"zh-tw\":\"Bug\\u6570\",\"en\":\"Bugs\"},\"resolutions\":{\"zh-cn\":\"\\u89e3\\u51b3Bug\\u6570\",\"zh-tw\":\"\\u89e3\\u51b3Bug\\u6570\",\"en\":\"Solved Bugs\"},\"bugthanstory\":{\"zh-cn\":\"Bug\\/\\u5b8c\\u6210\\u9700\\u6c42\",\"zh-tw\":\"Bug\\/\\u5b8c\\u6210\\u9700\\u6c42\",\"en\":\"Bug\\/Finished Story\"},\"seriousBugs\":{\"zh-cn\":\"\\u91cd\\u8981Bug\\u6570\",\"zh-tw\":\"\\u91cd\\u8981Bug\\u6570\",\"en\":\"Serious Bugs\"},\"seriousBugsPercent\":{\"zh-cn\":\"\\u4e25\\u91cdbug\\u6bd4\\u7387\",\"zh-tw\":\"\\u4e25\\u91cdbug\\u6bd4\\u7387\",\"en\":\"Serious Bugs %\"}}', '{\"group1\":\"name\",\"group2\":\"\",\"reportField\":[\"stories\",\"doneStory\",\"bugs\",\"resolutions\",\"bugthanstory\",\"seriousBugs\"],\"reportType\":[\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\"],\"sumAppend\":[\"stories\",\"doneStory\",\"bugs\",\"resolutions\",\"bugthanstory\",\"seriousBugs\"],\"percent\":{\"5\":\"1\"},\"contrast\":{\"5\":\"bugs\"},\"showAlone\":{\"5\":\"1\"}}', 2, '{\"zh-cn\":\"\\u5217\\u51fa\\u4ea7\\u54c1\\u7684\\u9700\\u6c42\\u6570\\uff0c\\u5b8c\\u6210\\u7684\\u9700\\u6c42\\u603b\\u6570\\uff0cBug\\u6570\\uff0c\\u89e3\\u51b3\\u7684Bug\\u603b\\u6570\\uff0cBug\\/\\u9700\\u6c42\\uff0c\\u91cd\\u8981Bug\\u6570\\u91cf(\\u4e25\\u91cd\\u7a0b\\u5ea6\\u4e0d\\u5927\\u4e8e3)\\u3002\",\"zh-tw\":\"\\u5217\\u51fa\\u7522\\u54c1\\u7684\\u9700\\u6c42\\u6578\\uff0c\\u5b8c\\u6210\\u7684\\u9700\\u6c42\\u7e3d\\u6578\\uff0cBug\\u6578\\uff0c\\u89e3\\u6c7a\\u7684Bug\\u7e3d\\u6578\\uff0cBug\\/\\u9700\\u6c42\\uff0c\\u91cd\\u8981Bug\\u6578\\u91cf(\\u56b4\\u91cd\\u7a0b\\u5ea6\\u4e0d\\u5927\\u65bc3)\\u3002\",\"en\":\"Serious Bug (severity is less than 3).\",\"de\":\"Serious Bug (severity is less than 3).\",\"fr\":\"Serious Bug (severity is less than 3).\"}', 'admin', '2015-07-23 17:17:40'), ('user-login', '{\"zh-cn\":\"\\u5458\\u5de5\\u767b\\u5f55\\u6b21\\u6570\\u7edf\\u8ba1\\u8868\",\"zh-tw\":\"\\u54e1\\u5de5\\u767b\\u9304\\u6b21\\u6578\\u7d71\\u8a08\\u8868\",\"en\":\"Login Times\",\"de\":\"Login Times\",\"fr\":\"Login Times\"}', ',staff', 'select actor,LEFT(`date`,10) as `day` from TABLE_ACTION where `action`=\'login\' and if($startDate=\'\',1,`date`>=$startDate) and if($endDate=\'\',1,`date`<=$endDate) order by `date` asc, actor asc', '{\"varName\":[\"startDate\",\"endDate\"],\"showName\":[\"\\u8d77\\u59cb\\u65f6\\u95f4\",\"\\u7ed3\\u675f\\u65f6\\u95f4\"],\"requestType\":[\"date\",\"date\"],\"selectList\":[\"user\",\"user\"],\"default\":[\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"count\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"done\":{\"zh-cn\":\"\\u5b8c\\u6210\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u6570\",\"en\":\"Done\"}}', '{\"group1\":\"actor\",\"isUser\":{\"group1\":[\"1\"]},\"group2\":\"\",\"reportField\":[\"day\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u5b9e\\u73b0\\u5458\\u5de5\\u767b\\u5f55\\u6b21\\u6570\\u7edf\\u8ba1\\u62a5\\u8868\\uff0c\\u6309\\u7167\\u5929\\u7edf\\u8ba1\\u6bcf\\u5929\\u6bcf\\u4e2a\\u4eba\\u7684\\u767b\\u5f55\\u6b21\\u6570\\uff0c\\u4ee5\\u53ca\\u603b\\u6570\\u3002\",\"zh-tw\":\"\\u5be6\\u73fe\\u54e1\\u5de5\\u767b\\u9304\\u6b21\\u6578\\u7d71\\u8a08\\u5831\\u8868\\uff0c\\u6309\\u7167\\u5929\\u7d71\\u8a08\\u6bcf\\u5929\\u6bcf\\u500b\\u4eba\\u7684\\u767b\\u9304\\u6b21\\u6578\\uff0c\\u4ee5\\u53ca\\u7e3d\\u6578\\u3002\",\"en\":\"The summary of user login times.\",\"de\":\"The summary of user login times.\",\"fr\":\"The summary of user login times.\"}', 'admin', '2015-07-24 14:28:11'), ('effort', '{\"zh-cn\":\"\\u65e5\\u5fd7\\u6c47\\u603b\\u8868\",\"zh-tw\":\"\\u65e5\\u8a8c\\u532f\\u7e3d\\u8868\",\"en\":\"Effort Summary\",\"de\":\"Effort Summary\",\"fr\":\"Effort Summary\"}', ',staff', 'select t1.account,t1.consumed,t1.`date`,if($dept=\'0\',0,t2.dept) as dept from TABLE_EFFORT as t1 left join TABLE_USER as t2 on t1.account=t2.account where t1.`deleted`=\'0\' and if($startDate=\'\',1,t1.`date`>=$startDate) and if($endDate=\'\',1,t1.`date`<=$endDate) having dept=$dept order by `date` asc', '{\"varName\":[\"dept\",\"startDate\",\"endDate\"],\"showName\":[\"\\u90e8\\u95e8\",\"\\u8d77\\u59cb\\u65f6\\u95f4\",\"\\u7ed3\\u675f\\u65f6\\u95f4\"],\"requestType\":[\"select\",\"date\",\"date\"],\"selectList\":[\"dept\",\"user\",\"user\"],\"default\":[\"\",\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"date\":{\"zh-cn\":\"\\u65e5\\u671f\",\"zh-tw\":\"\\u65e5\\u671f\",\"en\":\"Date\"},\"consumed\":{\"zh-cn\":\"\\u6d88\\u8017\\u5de5\\u65f6\",\"zh-tw\":\"\\u6d88\\u8017\\u5de5\\u65f6\",\"en\":\"Cost\"}}', '{\"group1\":\"account\",\"isUser\":{\"group1\":[\"1\"]},\"group2\":\"\",\"reportField\":[\"date\"],\"reportType\":[\"sum\"],\"sumAppend\":[\"consumed\"]}', 2, '{\"zh-cn\":\"\\u67e5\\u770b\\u67d0\\u4e2a\\u65f6\\u95f4\\u6bb5\\u5185\\u7684\\u65e5\\u5fd7\\u60c5\\u51b5\\uff0c\\u53ef\\u4ee5\\u6309\\u7167\\u90e8\\u95e8\\u9009\\u62e9\\u3002\",\"zh-tw\":\"\\u67e5\\u770b\\u67d0\\u500b\\u6642\\u9593\\u6bb5\\u5167\\u7684\\u65e5\\u8a8c\\u60c5\\u6cc1\\uff0c\\u53ef\\u4ee5\\u6309\\u7167\\u90e8\\u9580\\u9078\\u64c7\\u3002\",\"en\":\"Effort summary of users.\",\"de\":\"Effort summary of users\",\"fr\":\"Effort summary of users\"}', 'admin', '2015-07-27 13:53:32'), -('company-dynamic', '{\"zh-cn\":\"\\u516c\\u53f8\\u52a8\\u6001\\u6c47\\u603b\\u8868\",\"zh-tw\":\"\\u516c\\u53f8\\u52d5\\u614b\\u532f\\u7e3d\\u8868\",\"en\":\"Company Dynamics\",\"de\":\"Company Dynamics\",\"fr\":\"Company Dynamics\"}', ',staff', 'select t1.day,t2.userlogin,t3.consumed,t4.storyopen,t5.storyclose,t6.taskopen,t7.taskfinish,t8.bugopen,t9.bugresolve,t1.actions from ztv_dayactions as t1 left join ztv_dayuserlogin as t2 on t1.day=t2.day left join ztv_dayeffort as t3 on t1.day=t3.date left join ztv_daystoryopen as t4 on t1.day=t4.day left join ztv_daystoryclose as t5 on t1.day=t5.day left join ztv_daytaskopen as t6 on t1.day=t6.day left join ztv_daytaskfinish as t7 on t1.day=t7.day left join ztv_daybugopen as t8 on t1.day=t8.day left join ztv_daybugresolve as t9 on t1.day=t9.day where if($startDate=\'\',1,t1.day>=$startDate) and if($endDate=\'\',1,t1.day<=$endDate)', '{\"varName\":[\"startDate\",\"endDate\"],\"showName\":[\"\\u8d77\\u59cb\\u65f6\\u95f4\",\"\\u7ed3\\u675f\\u65f6\\u95f4\"],\"requestType\":[\"date\",\"date\"],\"selectList\":[\"user\",\"user\"],\"default\":[\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"day\":{\"zh-cn\":\"\\u65e5\\u671f\",\"zh-tw\":\"\\u65e5\\u671f\",\"en\":\"Date\"},\"userlogin\":{\"zh-cn\":\"\\u767b\\u5f55\\u6b21\\u6570\",\"zh-tw\":\"\\u767b\\u9304\\u6b21\\u6578\",\"en\":\"Login\"},\"consumed\":{\"zh-cn\":\"\\u65e5\\u5fd7\\u5de5\\u65f6\",\"zh-tw\":\"\\u65e5\\u8a8c\\u5de5\\u6642\",\"en\":\"Cost(h)\"},\"storyopen\":{\"zh-cn\":\"\\u65b0\\u589e\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u65b0\\u589e\\u9700\\u6c42\\u6578\",\"en\":\"Open Story\"},\"storyclose\":{\"zh-cn\":\"\\u5173\\u95ed\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u95dc\\u9589\\u9700\\u6c42\\u6578\",\"en\":\"Closed Story\"},\"taskopen\":{\"zh-cn\":\"\\u65b0\\u589e\\u4efb\\u52a1\\u6570\",\"zh-tw\":\"\\u65b0\\u589e\\u4efb\\u52d9\\u6578\",\"en\":\"Open Task\"},\"taskfinish\":{\"zh-cn\":\"\\u5b8c\\u6210\\u4efb\\u52a1\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u4efb\\u52d9\\u6578\",\"en\":\"Finished Task\"},\"bugopen\":{\"zh-cn\":\"\\u65b0\\u589eBug\\u6570\",\"zh-tw\":\"\\u65b0\\u589eBug\\u6578\",\"en\":\"Open Bug\"},\"bugresolve\":{\"zh-cn\":\"\\u89e3\\u51b3Bug\\u6570\",\"zh-tw\":\"\\u89e3\\u51b3Bug\\u6578\",\"en\":\"Resolved bug\"},\"actions\":{\"zh-cn\":\"\\u52a8\\u6001\\u6570\",\"zh-tw\":\"\\u52d5\\u614b\\u6578\",\"en\":\"Dynamics\"}}', '{\"group1\":\"day\",\"isUser\":{\"group1\":[\"1\"]},\"group2\":\"\",\"reportField\":[\"userlogin\",\"consumed\",\"storyopen\",\"storyclose\",\"taskopen\",\"taskfinish\",\"bugopen\",\"bugresolve\",\"actions\"],\"reportType\":[\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\"],\"sumAppend\":[\"userlogin\",\"consumed\",\"storyopen\",\"storyclose\",\"taskopen\",\"taskfinish\",\"bugopen\",\"bugresolve\",\"actions\"]}', 2, '{\"zh-cn\":\"\\u53ef\\u4ee5\\u6307\\u5b9a\\u4e00\\u4e2a\\u65f6\\u671f\\uff0c\\u5217\\u51fa\\u76f8\\u5e94\\u7684\\u6570\\u636e\\uff1a1. \\u6bcf\\u5929\\u7684\\u767b\\u5f55\\u6b21\\u6570\\u30022. \\u6bcf\\u5929\\u7684\\u65e5\\u5fd7\\u5de5\\u65f6\\u91cf\\u30023. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u9700\\u6c42\\u6570\\u30024. \\u6bcf\\u5929\\u5173\\u95ed\\u7684\\u9700\\u6c42\\u6570\\u30025. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u4efb\\u52a1\\u6570\\u30026. \\u6bcf\\u5929\\u5b8c\\u6210\\u7684\\u4efb\\u52a1\\u6570\\u30027. \\u6bcf\\u5929\\u65b0\\u589e\\u7684Bug\\u6570\\u30028. \\u6bcf\\u5929\\u89e3\\u51b3\\u7684Bug\\u6570\\u30029. \\u6bcf\\u5929\\u7684\\u52a8\\u6001\\u6570\\u3002\",\"zh-tw\":\"\\u53ef\\u4ee5\\u6307\\u5b9a\\u4e00\\u500b\\u6642\\u671f\\uff0c\\u5217\\u51fa\\u76f8\\u61c9\\u7684\\u6578\\u64da\\uff1a1. \\u6bcf\\u5929\\u7684\\u767b\\u9304\\u6b21\\u6578\\u30022. \\u6bcf\\u5929\\u7684\\u65e5\\u8a8c\\u5de5\\u6642\\u91cf\\u30023. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u9700\\u6c42\\u6578\\u30024. \\u6bcf\\u5929\\u95dc\\u9589\\u7684\\u9700\\u6c42\\u6578\\u30025. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u4efb\\u52d9\\u6578\\u30026. \\u6bcf\\u5929\\u5b8c\\u6210\\u7684\\u4efb\\u52d9\\u6578\\u30027. \\u6bcf\\u5929\\u65b0\\u589e\\u7684Bug\\u6578\\u30028. \\u6bcf\\u5929\\u89e3\\u6c7a\\u7684Bug\\u6578\\u30029. \\u6bcf\\u5929\\u7684\\u52d5\\u614b\\u6578\\u3002\",\"en\":\"The summary of company dynamics\",\"de\":\"The summary of company dynamics\",\"fr\":\"The summary of company dynamics\"}', 'admin', '2015-07-27 15:09:42'), +('company-dynamic', '{\"zh-cn\":\"\\u516c\\u53f8\\u52a8\\u6001\\u6c47\\u603b\\u8868\",\"zh-tw\":\"\\u516c\\u53f8\\u52d5\\u614b\\u532f\\u7e3d\\u8868\",\"en\":\"Company Dynamics\",\"de\":\"Company Dynamics\",\"fr\":\"Company Dynamics\"}', ',staff', 'select t1.day,t2.userlogin,t3.consumed,t4.storyopen,t5.storyclose,t6.taskopen,t7.taskfinish,t8.bugopen,t9.bugresolve,t1.actions from ztv_dayactions as t1 left join ztv_dayuserlogin as t2 on t1.day=t2.day left join ztv_dayeffort as t3 on t1.day=t3.date left join ztv_daystoryopen as t4 on t1.day=t4.day left join ztv_daystoryclose as t5 on t1.day=t5.day left join ztv_daytaskopen as t6 on t1.day=t6.day left join ztv_daytaskfinish as t7 on t1.day=t7.day left join ztv_daybugopen as t8 on t1.day=t8.day left join ztv_daybugresolve as t9 on t1.day=t9.day where if($startDate=\'\',1,t1.day>=$startDate) and if($endDate=\'\',1,t1.day<=$endDate)', '{\"varName\":[\"startDate\",\"endDate\"],\"showName\":[\"\\u8d77\\u59cb\\u65f6\\u95f4\",\"\\u7ed3\\u675f\\u65f6\\u95f4\"],\"requestType\":[\"date\",\"date\"],\"selectList\":[\"user\",\"user\"],\"default\":[\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"day\":{\"zh-cn\":\"\\u65e5\\u671f\",\"zh-tw\":\"\\u65e5\\u671f\",\"en\":\"Date\"},\"userlogin\":{\"zh-cn\":\"\\u767b\\u5f55\\u6b21\\u6570\",\"zh-tw\":\"\\u767b\\u9304\\u6b21\\u6578\",\"en\":\"Login\"},\"consumed\":{\"zh-cn\":\"\\u65e5\\u5fd7\\u5de5\\u65f6\",\"zh-tw\":\"\\u65e5\\u8a8c\\u5de5\\u6642\",\"en\":\"Cost(h)\"},\"storyopen\":{\"zh-cn\":\"\\u65b0\\u589e\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u65b0\\u589e\\u9700\\u6c42\\u6578\",\"en\":\"Open Story\"},\"storyclose\":{\"zh-cn\":\"\\u5173\\u95ed\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u95dc\\u9589\\u9700\\u6c42\\u6578\",\"en\":\"Closed Story\"},\"taskopen\":{\"zh-cn\":\"\\u65b0\\u589e\\u4efb\\u52a1\\u6570\",\"zh-tw\":\"\\u65b0\\u589e\\u4efb\\u52d9\\u6578\",\"en\":\"Open Task\"},\"taskfinish\":{\"zh-cn\":\"\\u5b8c\\u6210\\u4efb\\u52a1\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u4efb\\u52d9\\u6578\",\"en\":\"Finished Task\"},\"bugopen\":{\"zh-cn\":\"\\u65b0\\u589eBug\\u6570\",\"zh-tw\":\"\\u65b0\\u589eBug\\u6578\",\"en\":\"Open Bug\"},\"bugresolve\":{\"zh-cn\":\"\\u89e3\\u51b3Bug\\u6570\",\"zh-tw\":\"\\u89e3\\u51b3Bug\\u6578\",\"en\":\"Resolved bug\"},\"actions\":{\"zh-cn\":\"\\u52a8\\u6001\\u6570\",\"zh-tw\":\"\\u52d5\\u614b\\u6578\",\"en\":\"Dynamics\"}}', '{\"group1\":\"day\",\"isUser\":{\"group1\":[\"1\"]},\"group2\":\"\",\"reportField\":[\"userlogin\",\"consumed\",\"storyopen\",\"storyclose\",\"taskopen\",\"taskfinish\",\"bugopen\",\"bugresolve\",\"actions\"],\"reportType\":[\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\"],\"sumAppend\":[\"userlogin\",\"consumed\",\"storyopen\",\"storyclose\",\"taskopen\",\"taskfinish\",\"bugopen\",\"bugresolve\",\"actions\"]}', 2, '{\"zh-cn\":\"\\u53ef\\u4ee5\\u6307\\u5b9a\\u4e00\\u4e2a\\u65f6\\u671f\\uff0c\\u5217\\u51fa\\u76f8\\u5e94\\u7684\\u6570\\u636e\\uff1a1. \\u6bcf\\u5929\\u7684\\u767b\\u5f55\\u6b21\\u6570\\u30022. \\u6bcf\\u5929\\u7684\\u65e5\\u5fd7\\u5de5\\u65f6\\u91cf\\u30023. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u9700\\u6c42\\u6570\\u30024. \\u6bcf\\u5929\\u5173\\u95ed\\u7684\\u9700\\u6c42\\u6570\\u30025. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u4efb\\u52a1\\u6570\\u30026. \\u6bcf\\u5929\\u5b8c\\u6210\\u7684\\u4efb\\u52a1\\u6570\\u30027. \\u6bcf\\u5929\\u65b0\\u589e\\u7684Bug\\u6570\\u30028. \\u6bcf\\u5929\\u89e3\\u51b3\\u7684Bug\\u6570\\u30029. \\u6bcf\\u5929\\u7684\\u52a8\\u6001\\u6570\\u3002\",\"zh-tw\":\"\\u53ef\\u4ee5\\u6307\\u5b9a\\u4e00\\u500b\\u6642\\u671f\\uff0c\\u5217\\u51fa\\u76f8\\u61c9\\u7684\\u6578\\u64da\\uff1a1. \\u6bcf\\u5929\\u7684\\u767b\\u9304\\u6b21\\u6578\\u30022. \\u6bcf\\u5929\\u7684\\u65e5\\u8a8c\\u5de5\\u6642\\u91cf\\u30023. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u9700\\u6c42\\u6578\\u30024. \\u6bcf\\u5929\\u95dc\\u9589\\u7684\\u9700\\u6c42\\u6578\\u30025. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u4efb\\u52d9\\u6578\\u30026. \\u6bcf\\u5929\\u5b8c\\u6210\\u7684\\u4efb\\u52d9\\u6578\\u30027. \\u6bcf\\u5929\\u65b0\\u589e\\u7684Bug\\u6578\\u30028. \\u6bcf\\u5929\\u89e3\\u6c7a\\u7684Bug\\u6578\\u30029. \\u6bcf\\u5929\\u7684\\u52d5\\u614b\\u6578\\u3002\",\"en\":\"The summary of company dynamics\",\"de\":\"The summary of company dynamics\",\"fr\":\"The summary of company dynamics\"}', 'admin', '2015-07-27 15:09:42'), ('bug-resolve', '{\"zh-cn\":\"Bug\\u89e3\\u51b3\\u8868\",\"zh-tw\":\"Bug\\u89e3\\u6c7a\\u8868\",\"en\":\"Solved Bugs\",\"de\":\"Solved Bugs\",\"fr\":\"Solved Bugs\"}', ',test', 'select *,if($product=\'\',0,product) as customproduct from TABLE_BUG where deleted=\'0\' and resolution!=\'\' and if($startDate=\'\',1,resolvedDate>=$startDate) and if($endDate=\'\',1,resolvedDate<=$endDate) having customproduct=$product', '{\"varName\":[\"product\",\"startDate\",\"endDate\"],\"showName\":[\"\\u4ea7\\u54c1\",\"\\u89e3\\u51b3\\u65e5\\u671f\\u5f00\\u59cb\",\"\\u89e3\\u51b3\\u65e5\\u671f\\u7ed3\\u675f\"],\"requestType\":[\"select\",\"date\",\"date\"],\"selectList\":[\"product\",\"user\",\"user\"],\"default\":[\"\",\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"count\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"done\":{\"zh-cn\":\"\\u5b8c\\u6210\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u6570\",\"en\":\"Done\"}}', '{\"group1\":\"resolvedBy\",\"isUser\":{\"group1\":[\"1\"]},\"group2\":\"\",\"reportField\":[\"resolution\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"],\"reportTotal\":[\"1\"],\"percent\":[\"1\"],\"contrast\":[\"crystalTotal\"],\"showAlone\":[\"1\"]}', 2, '{\"zh-cn\":\"\\u5217\\u51fa\\u89e3\\u51b3\\u7684Bug\\u603b\\u6570\\uff0c\\u89e3\\u51b3\\u65b9\\u6848\\u7684\\u5206\\u5e03\\uff0c\\u5360\\u7684\\u6bd4\\u4f8b\\uff08\\u8be5\\u7528\\u6237\\u89e3\\u51b3\\u7684Bug\\u7684\\u6570\\u91cf\\u5360\\u6240\\u6709\\u7684\\u89e3\\u51b3\\u7684Bug\\u7684\\u6570\\u91cf)\\u3002\",\"zh-tw\":\"\\u5217\\u51fa\\u89e3\\u6c7a\\u7684Bug\\u7e3d\\u6578\\uff0c\\u89e3\\u6c7a\\u65b9\\u6848\\u7684\\u5206\\u5e03\\uff0c\\u5360\\u7684\\u6bd4\\u4f8b\\uff08\\u8a72\\u7528\\u6236\\u89e3\\u6c7a\\u7684Bug\\u7684\\u6578\\u91cf\\u5360\\u6240\\u6709\\u7684\\u89e3\\u6c7a\\u7684Bug\\u7684\\u6578\\u91cf)\\u3002\",\"en\":\"percentage:self resolved \\/ all resolved\",\"de\":\"percentage:self resolved \\/ all resolved\",\"fr\":\"percentage:self resolved \\/ all resolved\"}', 'admin', '2015-07-24 13:44:25'), ('project-progress', '{\"zh-cn\":\"\\u9879\\u76ee\\u8fdb\\u5c55\\u8868\",\"zh-tw\":\"\\u9805\\u76ee\\u9032\\u5c55\\u8868\",\"en\":\"Project Progress Report\",\"de\":\"Project Progress Report\",\"fr\":\"Project Progress Report\",\"vi\":\"Project Progress Report\",\"ja\":\"Project Progress Report\"}', ',project', 'select t1.id,t4.name as project,t4.id,IF(t4.multiple="1",t1.name,"") as execution,t1.status,t2.number as tasks,round(t2.consumed,2) as consumed,round(t2.`left`,2) as `left`,t3.stories,t2.undone as undoneTask,t3.undone as undoneStory,t2.totalReal from TABLE_EXECUTION as t1 \r\nleft join ztv_executionsummary as t2 on t1.id=t2.execution\r\nleft join ztv_projectstories as t3 on t1.id=t3.execution\r\nleft join TABLE_PROJECT as t4 on t4.id=t1.project\r\nwhere t1.deleted=\'0\' and t1.type in (\'sprint\',\'stage\') and if($project=\'\',1,t4.id=$project) and if($execution=\'\',1,t1.id=$execution) and if($status=\'\',1,t1.status=$status)', '{\"varName\":[\"project\",\"execution\",\"status\"],\"showName\":[\"\\u9879\\u76ee\\u5217\\u8868\",\"\\u6267\\u884c\\u5217\\u8868\",\"\\u6267\\u884c\\u72b6\\u6001\"],\"requestType\":[\"select\",\"select\",\"select\"],\"selectList\":[\"project\",\"execution\",\"project.status\"],\"default\":[\"\",\"\",\"\"]}', '{\"stories\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"tasks\":{\"zh-cn\":\"\\u4efb\\u52a1\\u6570\",\"zh-tw\":\"\\u4efb\\u52a1\\u6570\",\"en\":\"Tasks\"},\"undoneStory\":{\"zh-cn\":\"\\u5269\\u4f59\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u5269\\u4f59\\u9700\\u6c42\\u6570\",\"en\":\"Undone Story\"},\"undoneTask\":{\"zh-cn\":\"\\u5269\\u4f59\\u4efb\\u52a1\\u6570\",\"zh-tw\":\"\\u5269\\u4f59\\u4efb\\u52a1\\u6570\",\"en\":\"Undone Task\"},\"consumed\":{\"zh-cn\":\"\\u5df2\\u6d88\\u8017\\u5de5\\u65f6\",\"zh-tw\":\"\\u5df2\\u6d88\\u8017\\u5de5\\u65f6\",\"en\":\"Cost(h)\"},\"left\":{\"zh-cn\":\"\\u5269\\u4f59\\u5de5\\u65f6\",\"zh-tw\":\"\\u5269\\u4f59\\u5de5\\u65f6\",\"en\":\"Left(h)\"},\"consumedPercent\":{\"zh-cn\":\"\\u8fdb\\u5ea6\",\"zh-tw\":\"\\u8fdb\\u5ea6\",\"en\":\"Process\"},\"execution\":{\"zh-cn\":\"\\u6267\\u884c\\u540d\\u79f0\"}}', '{\"group1\":\"project\",\"group2\":\"execution\",\"reportField\":[\"stories\",\"undoneStory\",\"tasks\",\"undoneTask\",\"left\",\"consumed\"],\"reportType\":[\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\"],\"sumAppend\":[\"stories\",\"undoneStory\",\"tasks\",\"undoneTask\",\"left\",\"consumed\"],\"percent\":{\"5\":\"1\"},\"contrast\":{\"5\":\"totalReal\"},\"showAlone\":{\"5\":\"1\"}}', 2, '{\"zh-cn\":\"\\u9879\\u76ee\\u7684\\u9700\\u6c42\\u6570\\uff0c\\u4efb\\u52a1\\u6570\\uff0c\\u5df2\\u6d88\\u8017\\u5de5\\u65f6\\uff0c\\u5269\\u4f59\\u5de5\\u65f6\\uff0c\\u5269\\u4f59\\u9700\\u6c42\\u6570\\uff0c\\u5269\\u4f59\\u4efb\\u52a1\\u6570\\uff0c\\u8fdb\\u5ea6\\u3002\",\"zh-tw\":\"\\u9805\\u76ee\\u7684\\u9700\\u6c42\\u6578\\uff0c\\u4efb\\u52d9\\u6578\\uff0c\\u5df2\\u6d88\\u8017\\u5de5\\u6642\\uff0c\\u5269\\u9918\\u5de5\\u6642\\uff0c\\u5269\\u9918\\u9700\\u6c42\\u6578\\uff0c\\u5269\\u9918\\u4efb\\u52d9\\u6578\\uff0c\\u9032\\u5ea6\\u3002\",\"en\":\"\",\"de\":\"\",\"fr\":\"\",\"vi\":\"\",\"ja\":\"\"}', 'admin', '2015-07-23 14:03:06'), ('projectbug-type', '{\"zh-cn\":\"\\u9879\\u76eeBug\\u7c7b\\u578b\\u7edf\\u8ba1\\u8868\",\"zh-tw\":\"\\u9805\\u76eeBug\\u985e\\u578b\\u7d71\\u8a08\\u8868\",\"en\":\"Project Bug Type\",\"de\":\"Project Bug Type\",\"fr\":\"Project Bug Type\",\"vi\":\"Project Bug Type\",\"ja\":\"Project Bug Type\"}', ',project,test', 'select t1.id,t3.name as project,t3.id,IF(t3.multiple="1",t1.name,"") as execution,t2.id as bugID,t2.type from TABLE_EXECUTION as t1 \r\nleft join TABLE_BUG as t2 on t1.id=t2.execution\r\nleft join TABLE_PROJECT as t3 on t3.id=t1.project\r\nwhere t1.deleted=\'0\' and t2.deleted=\'0\' and if($project=\'\',1,t3.id=$project) and if($execution=\'\',1,t1.id=$execution)', '{\"varName\":[\"project\",\"execution\"],\"showName\":[\"\\u9879\\u76ee\\u5217\\u8868\",\"\\u6267\\u884c\\u5217\\u8868\"],\"requestType\":[\"select\",\"select\"],\"selectList\":[\"project\",\"execution\"],\"default\":[\"\",\"\"]}', '{\"stories\":{\"zh-cn\":\"\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u9700\\u6c42\\u6570\",\"en\":\"Stories\"},\"tasks\":{\"zh-cn\":\"\\u4efb\\u52a1\\u6570\",\"zh-tw\":\"\\u4efb\\u52a1\\u6570\",\"en\":\"Tasks\"},\"undoneStory\":{\"zh-cn\":\"\\u5269\\u4f59\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u5269\\u4f59\\u9700\\u6c42\\u6570\",\"en\":\"Undone Story\"},\"undoneTask\":{\"zh-cn\":\"\\u5269\\u4f59\\u4efb\\u52a1\\u6570\",\"zh-tw\":\"\\u5269\\u4f59\\u4efb\\u52a1\\u6570\",\"en\":\"Undone Task\"},\"consumed\":{\"zh-cn\":\"\\u5df2\\u6d88\\u8017\\u5de5\\u65f6\",\"zh-tw\":\"\\u5df2\\u6d88\\u8017\\u5de5\\u65f6\",\"en\":\"Cost(h)\"},\"left\":{\"zh-cn\":\"\\u5269\\u4f59\\u5de5\\u65f6\",\"zh-tw\":\"\\u5269\\u4f59\\u5de5\\u65f6\",\"en\":\"Left(h)\"},\"consumedPercent\":{\"zh-cn\":\"\\u8fdb\\u5ea6\",\"zh-tw\":\"\\u8fdb\\u5ea6\",\"en\":\"Process\"},\"execution\":{\"zh-cn\":\"\\u6267\\u884c\\u540d\\u79f0\"}}', '{\"group1\":\"project\",\"group2\":\"execution\",\"reportField\":[\"type\"],\"reportType\":[\"count\"],\"sumAppend\":[\"\"]}', 2, '{\"zh-cn\":\"\\u6309\\u7167\\u9879\\u76ee\\u7edf\\u8ba1Bug\\u7684\\u7c7b\\u578b\\u5206\\u5e03\\u60c5\\u51b5\\u3002\",\"zh-tw\":\"\\u6309\\u7167\\u9805\\u76ee\\u7d71\\u8a08Bug\\u7684\\u985e\\u578b\\u5206\\u5e03\\u60c5\\u6cc1\\u3002\",\"en\":\"\",\"de\":\"\",\"fr\":\"\",\"vi\":\"\",\"ja\":\"\"}', 'admin', '2015-08-04 13:54:22'); diff --git a/db/update18.2.sql b/db/update18.2.sql index 4feb914dcc..a3086c913c 100644 --- a/db/update18.2.sql +++ b/db/update18.2.sql @@ -1,3 +1,18 @@ ALTER TABLE `zt_lang` MODIFY COLUMN `section` varchar(50) NOT NULL; DELETE FROM `zt_grouppriv` WHERE `module` = 'dev' AND `method` = 'editor'; REPLACE INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system','common','','setPercent','1'); +DROP TABLE IF EXISTS `zt_dimension`; + +REPLACE INTO `zt_lang` (`lang`, `module`, `section`, `key`, `value`, `system`) VALUES +('zh-tw', 'custom', 'URSRList', '1', '{"SRName":"\\u8edf\\u4ef6\\u9700\\u6c42","URName":"\\u7528\\u6236\\u9700\\u6c42"}', '0'), +('zh-tw', 'custom', 'URSRList', '2', '{"SRName":"\\u7814\\u767c\\u9700\\u6c42","URName":"\\u7528\\u6236\\u9700\\u6c42"}', '0'), +('zh-tw', 'custom', 'URSRList', '3', '{"SRName":"\\u8edf\\u9700","URName":"\\u7528\\u9700"}', '0'), +('zh-tw', 'custom', 'URSRList', '4', '{"SRName":"\\u6545\\u4e8b","URName":"\\u53f2\\u8a69"}', '0'), +('zh-tw', 'custom', 'URSRList', '5', '{"SRName":"\\u9700\\u6c42","URName":"\\u7528\\u6236\\u9700\\u6c42"}', '0'), +('fr', 'custom', 'URSRList', '1', '{\"SRName\":\"Story\",\"URName\":\"Epic\"}', '0'), +('fr', 'custom', 'URSRList', '2', '{\"SRName\":\"Software Requirement\",\"URName\":\"User Requirement\"}', '0'), +('de', 'custom', 'URSRList', '1', '{\"SRName\":\"Story\",\"URName\":\"Epic\"}', '0'), +('de', 'custom', 'URSRList', '2', '{\"SRName\":\"Software Requirement\",\"URName\":\"User Requirement\"}', '0'); + +REPLACE INTO `zt_report` (`code`, `name`, `module`, `sql`, `vars`, `langs`, `params`, `step`, `desc`, `addedBy`, `addedDate`) VALUES +('company-dynamic', '{\"zh-cn\":\"\\u516c\\u53f8\\u52a8\\u6001\\u6c47\\u603b\\u8868\",\"zh-tw\":\"\\u516c\\u53f8\\u52d5\\u614b\\u532f\\u7e3d\\u8868\",\"en\":\"Company Dynamics\",\"de\":\"Company Dynamics\",\"fr\":\"Company Dynamics\"}', ',staff', 'select t1.day,t2.userlogin,t3.consumed,t4.storyopen,t5.storyclose,t6.taskopen,t7.taskfinish,t8.bugopen,t9.bugresolve,t1.actions from ztv_dayactions as t1 left join ztv_dayuserlogin as t2 on t1.day=t2.day left join ztv_dayeffort as t3 on t1.day=t3.date left join ztv_daystoryopen as t4 on t1.day=t4.day left join ztv_daystoryclose as t5 on t1.day=t5.day left join ztv_daytaskopen as t6 on t1.day=t6.day left join ztv_daytaskfinish as t7 on t1.day=t7.day left join ztv_daybugopen as t8 on t1.day=t8.day left join ztv_daybugresolve as t9 on t1.day=t9.day where if($startDate=\'\',1,t1.day>=$startDate) and if($endDate=\'\',1,t1.day<=$endDate)', '{\"varName\":[\"startDate\",\"endDate\"],\"showName\":[\"\\u8d77\\u59cb\\u65f6\\u95f4\",\"\\u7ed3\\u675f\\u65f6\\u95f4\"],\"requestType\":[\"date\",\"date\"],\"selectList\":[\"user\",\"user\"],\"default\":[\"$MONTHBEGIN\",\"$MONTHEND\"]}', '{\"day\":{\"zh-cn\":\"\\u65e5\\u671f\",\"zh-tw\":\"\\u65e5\\u671f\",\"en\":\"Date\"},\"userlogin\":{\"zh-cn\":\"\\u767b\\u5f55\\u6b21\\u6570\",\"zh-tw\":\"\\u767b\\u9304\\u6b21\\u6578\",\"en\":\"Login\"},\"consumed\":{\"zh-cn\":\"\\u65e5\\u5fd7\\u5de5\\u65f6\",\"zh-tw\":\"\\u65e5\\u8a8c\\u5de5\\u6642\",\"en\":\"Cost(h)\"},\"storyopen\":{\"zh-cn\":\"\\u65b0\\u589e\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u65b0\\u589e\\u9700\\u6c42\\u6578\",\"en\":\"Open Story\"},\"storyclose\":{\"zh-cn\":\"\\u5173\\u95ed\\u9700\\u6c42\\u6570\",\"zh-tw\":\"\\u95dc\\u9589\\u9700\\u6c42\\u6578\",\"en\":\"Closed Story\"},\"taskopen\":{\"zh-cn\":\"\\u65b0\\u589e\\u4efb\\u52a1\\u6570\",\"zh-tw\":\"\\u65b0\\u589e\\u4efb\\u52d9\\u6578\",\"en\":\"Open Task\"},\"taskfinish\":{\"zh-cn\":\"\\u5b8c\\u6210\\u4efb\\u52a1\\u6570\",\"zh-tw\":\"\\u5b8c\\u6210\\u4efb\\u52d9\\u6578\",\"en\":\"Finished Task\"},\"bugopen\":{\"zh-cn\":\"\\u65b0\\u589eBug\\u6570\",\"zh-tw\":\"\\u65b0\\u589eBug\\u6578\",\"en\":\"Open Bug\"},\"bugresolve\":{\"zh-cn\":\"\\u89e3\\u51b3Bug\\u6570\",\"zh-tw\":\"\\u89e3\\u51b3Bug\\u6578\",\"en\":\"Resolved bug\"},\"actions\":{\"zh-cn\":\"\\u52a8\\u6001\\u6570\",\"zh-tw\":\"\\u52d5\\u614b\\u6578\",\"en\":\"Dynamics\"}}', '{\"group1\":\"day\",\"isUser\":{\"group1\":[\"1\"]},\"group2\":\"\",\"reportField\":[\"userlogin\",\"consumed\",\"storyopen\",\"storyclose\",\"taskopen\",\"taskfinish\",\"bugopen\",\"bugresolve\",\"actions\"],\"reportType\":[\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\",\"sum\"],\"sumAppend\":[\"userlogin\",\"consumed\",\"storyopen\",\"storyclose\",\"taskopen\",\"taskfinish\",\"bugopen\",\"bugresolve\",\"actions\"]}', 2, '{\"zh-cn\":\"\\u53ef\\u4ee5\\u6307\\u5b9a\\u4e00\\u4e2a\\u65f6\\u671f\\uff0c\\u5217\\u51fa\\u76f8\\u5e94\\u7684\\u6570\\u636e\\uff1a1. \\u6bcf\\u5929\\u7684\\u767b\\u5f55\\u6b21\\u6570\\u30022. \\u6bcf\\u5929\\u7684\\u65e5\\u5fd7\\u5de5\\u65f6\\u91cf\\u30023. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u9700\\u6c42\\u6570\\u30024. \\u6bcf\\u5929\\u5173\\u95ed\\u7684\\u9700\\u6c42\\u6570\\u30025. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u4efb\\u52a1\\u6570\\u30026. \\u6bcf\\u5929\\u5b8c\\u6210\\u7684\\u4efb\\u52a1\\u6570\\u30027. \\u6bcf\\u5929\\u65b0\\u589e\\u7684Bug\\u6570\\u30028. \\u6bcf\\u5929\\u89e3\\u51b3\\u7684Bug\\u6570\\u30029. \\u6bcf\\u5929\\u7684\\u52a8\\u6001\\u6570\\u3002\",\"zh-tw\":\"\\u53ef\\u4ee5\\u6307\\u5b9a\\u4e00\\u500b\\u6642\\u671f\\uff0c\\u5217\\u51fa\\u76f8\\u61c9\\u7684\\u6578\\u64da\\uff1a1. \\u6bcf\\u5929\\u7684\\u767b\\u9304\\u6b21\\u6578\\u30022. \\u6bcf\\u5929\\u7684\\u65e5\\u8a8c\\u5de5\\u6642\\u91cf\\u30023. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u9700\\u6c42\\u6578\\u30024. \\u6bcf\\u5929\\u95dc\\u9589\\u7684\\u9700\\u6c42\\u6578\\u30025. \\u6bcf\\u5929\\u65b0\\u589e\\u7684\\u4efb\\u52d9\\u6578\\u30026. \\u6bcf\\u5929\\u5b8c\\u6210\\u7684\\u4efb\\u52d9\\u6578\\u30027. \\u6bcf\\u5929\\u65b0\\u589e\\u7684Bug\\u6578\\u30028. \\u6bcf\\u5929\\u89e3\\u6c7a\\u7684Bug\\u6578\\u30029. \\u6bcf\\u5929\\u7684\\u52d5\\u614b\\u6578\\u3002\",\"en\":\"The summary of company dynamics\",\"de\":\"The summary of company dynamics\",\"fr\":\"The summary of company dynamics\"}', 'admin', '2015-07-27 15:09:42'); diff --git a/db/zentao.sql b/db/zentao.sql index 047ef4fa39..df4487c829 100755 --- a/db/zentao.sql +++ b/db/zentao.sql @@ -6381,11 +6381,22 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES (12,'my','limited'); REPLACE INTO `zt_lang` (`lang`, `module`, `section`, `key`, `value`, `system`) VALUES -('zh-cn', 'custom', 'URSRList', '1', '{\"SRName\":\"\\u8f6f\\u4ef6\\u9700\\u6c42\",\"URName\":\"\\u7528\\u6237\\u9700\\u6c42\"}', '1'),('zh-cn', 'custom', 'URSRList', '2', '{\"SRName\":\"\\u7814\\u53d1\\u9700\\u6c42\",\"URName\":\"\\u7528\\u6237\\u9700\\u6c42\"}', '1'), -('zh-cn', 'custom', 'URSRList', '3', '{\"SRName\":\"\\u8f6f\\u9700\",\"URName\":\"\\u7528\\u9700\"}', '1'),('zh-cn', 'custom', 'URSRList', '4', '{\"SRName\":\"\\u6545\\u4e8b\",\"URName\":\"\\u53f2\\u8bd7\"}', '1'), +('zh-cn', 'custom', 'URSRList', '1', '{\"SRName\":\"\\u8f6f\\u4ef6\\u9700\\u6c42\",\"URName\":\"\\u7528\\u6237\\u9700\\u6c42\"}', '1'), +('zh-cn', 'custom', 'URSRList', '2', '{\"SRName\":\"\\u7814\\u53d1\\u9700\\u6c42\",\"URName\":\"\\u7528\\u6237\\u9700\\u6c42\"}', '1'), +('zh-cn', 'custom', 'URSRList', '3', '{\"SRName\":\"\\u8f6f\\u9700\",\"URName\":\"\\u7528\\u9700\"}', '1'), +('zh-cn', 'custom', 'URSRList', '4', '{\"SRName\":\"\\u6545\\u4e8b\",\"URName\":\"\\u53f2\\u8bd7\"}', '1'), ('zh-cn', 'custom', 'URSRList', '5', '{\"SRName\":\"\\u9700\\u6c42\",\"URName\":\"\\u7528\\u6237\\u9700\\u6c42\"}', '1'), +('zh-tw', 'custom', 'URSRList', '1', '{"SRName":"\\u8edf\\u4ef6\\u9700\\u6c42","URName":"\\u7528\\u6236\\u9700\\u6c42"}', '0'), +('zh-tw', 'custom', 'URSRList', '2', '{"SRName":"\\u7814\\u767c\\u9700\\u6c42","URName":"\\u7528\\u6236\\u9700\\u6c42"}', '0'), +('zh-tw', 'custom', 'URSRList', '3', '{"SRName":"\\u8edf\\u9700","URName":"\\u7528\\u9700"}', '0'), +('zh-tw', 'custom', 'URSRList', '4', '{"SRName":"\\u6545\\u4e8b","URName":"\\u53f2\\u8a69"}', '0'), +('zh-tw', 'custom', 'URSRList', '5', '{"SRName":"\\u9700\\u6c42","URName":"\\u7528\\u6236\\u9700\\u6c42"}', '0'), ('en', 'custom', 'URSRList', '1', '{\"SRName\":\"Story\",\"URName\":\"Epic\"}', '0'), -('en', 'custom', 'URSRList', '2', '{\"SRName\":\"Software Requirement\",\"URName\":\"User Requirement\"}', '0'); +('en', 'custom', 'URSRList', '2', '{\"SRName\":\"Software Requirement\",\"URName\":\"User Requirement\"}', '0'), +('fr', 'custom', 'URSRList', '1', '{\"SRName\":\"Story\",\"URName\":\"Epic\"}', '0'), +('fr', 'custom', 'URSRList', '2', '{\"SRName\":\"Software Requirement\",\"URName\":\"User Requirement\"}', '0'), +('de', 'custom', 'URSRList', '1', '{\"SRName\":\"Story\",\"URName\":\"Epic\"}', '0'), +('de', 'custom', 'URSRList', '2', '{\"SRName\":\"Software Requirement\",\"URName\":\"User Requirement\"}', '0'); REPLACE INTO `zt_stage` (`name`,`percent`,`type`,`projectType`,`createdBy`,`createdDate`,`editedBy`,`editedDate`,`deleted`) VALUES ('需求','10','request','waterfall','admin','2020-02-08 21:08:30','admin','2020-02-12 13:50:27','0'), diff --git a/extension/lite/task/ext/config/lite.php b/extension/lite/task/ext/config/lite.php index aeb63bd17a..81dede0b76 100644 --- a/extension/lite/task/ext/config/lite.php +++ b/extension/lite/task/ext/config/lite.php @@ -1,5 +1,4 @@ task->customBatchCreateFields .= ',lane,region'; $config->task->custom->batchCreateFields .= ',lane,region'; $config->task->datatable->defaultField = array('id', 'pri', 'name', 'status', 'assignedTo', 'lane', 'finishedBy', 'estimate', 'consumed', 'left', 'progress', 'deadline', 'actions'); diff --git a/extension/lite/task/ext/view/batchcreate.html.php b/extension/lite/task/ext/view/batchcreate.html.php index ffb7675296..88b8029a41 100644 --- a/extension/lite/task/ext/view/batchcreate.html.php +++ b/extension/lite/task/ext/view/batchcreate.html.php @@ -16,6 +16,7 @@ task->addChildTask);?> +task->create->requiredFields);?>
@@ -48,11 +49,7 @@ } foreach(explode(',', $config->task->create->requiredFields) as $field) { - if($field) - { - $requiredFields[$field] = ''; - if(strpos(",{$config->task->customBatchCreateFields},", ",{$field},") !== false) $visibleFields[$field] = ''; - } + if($field) $requiredFields[$field] = ''; } $colspan = count($visibleFields) + 3; ?> @@ -62,20 +59,20 @@ idAB;?> - '>task->module?> + moduleBox'>task->module?> type != 'ops'):?> - '>task->story;?> + storyBox'>task->story;?> task->name;?> - '>task->region;?> - '>task->lane;?> + regionBox'>task->region;?> + laneBox'>task->lane;?> typeAB;?> '>task->assignedTo;?> - '>task->estimateAB;?> - '>task->estStarted;?> - '>task->deadline;?> - '>task->desc;?> - '>task->pri;?> + estimateBox'>task->estimateAB;?> + estStartedBox'>task->estStarted;?> + deadlineBox'>task->deadline;?> + descBox'>task->desc;?> + priBox'>task->pri;?> task->getFlowExtendFields(); foreach($extendFields as $extendField) echo "{$extendField->name}"; @@ -106,12 +103,12 @@ - style='overflow:visible'> + id, $i)'")?> type != 'ops'):?> - style='overflow: visible'> +
@@ -134,12 +131,12 @@
- style='overflow:visible'> - style='overflow:visible'> + + task->typeList, $type, "class='form-control chosen'");?> - style='overflow:visible'> - > - > + + +
- > +
- > - >task->priList, $pri, 'class=form-control');?> + + task->priList, $pri, 'class=form-control');?> control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->loadModel('flow')->getFieldControl($extendField, '', $extendField->field . "[$i]") . "";?> @@ -177,11 +174,11 @@ %s - style='overflow:visible'> + id, \"%s\")'")?> - style='overflow: visible'> +
@@ -203,12 +200,12 @@
- style='overflow:visible'> - style='overflow:visible'> + + task->typeList, $type, 'class="form-control"');?> - style='overflow:visible'> - > - > + + +
- > +
{$lang->task->ditto}"; ?>
- > - >task->priList, $pri, 'class=form-control');?> + + task->priList, $pri, 'class=form-control');?> control == 'select' or $extendField->control == 'multi-select') ? " style='overflow:visible'" : '') . ">" . $this->loadModel('flow')->getFieldControl($extendField, '', $extendField->field . "[%s]") . "";?> diff --git a/framework/router.class.php b/framework/router.class.php index 289e477a8c..edfc99616f 100755 --- a/framework/router.class.php +++ b/framework/router.class.php @@ -101,8 +101,6 @@ class router extends baseRouter global $lang; if(!is_object($lang)) $lang = new language(); - $appName = ''; - /* Set productCommon and projectCommon for flow. */ if($moduleName == 'common') $this->setCommonLang(); @@ -111,7 +109,13 @@ class router extends baseRouter /* Replace main nav lang. */ if($moduleName == 'common' and $this->dbh and !empty($this->config->db->name)) { - $customMenus = $this->dbh->query('SELECT * FROM' . TABLE_LANG . "WHERE `module`='common' AND `section`='mainNav' AND `lang`='{$this->clientLang}' AND `vision`='{$this->config->vision}'")->fetchAll(); + $customMenus = array(); + try + { + $customMenus = $this->dbh->query('SELECT * FROM' . TABLE_LANG . "WHERE `module`='common' AND `section`='mainNav' AND `lang`='{$this->clientLang}' AND `vision`='{$this->config->vision}'")->fetchAll(); + } + catch(PDOException $exception){} + foreach($customMenus as $menu) { $menuKey = $menu->key; @@ -317,7 +321,12 @@ class router extends baseRouter } /* Replace common lang. */ - $customMenus = $this->dbh->query('SELECT * FROM' . TABLE_LANG . "WHERE `module`='common' AND `lang`='{$this->clientLang}' AND `section`='' AND `vision`='{$config->vision}'")->fetchAll(); + $customMenus = array(); + try + { + $customMenus = $this->dbh->query('SELECT * FROM' . TABLE_LANG . "WHERE `module`='common' AND `lang`='{$this->clientLang}' AND `section`='' AND `vision`='{$config->vision}'")->fetchAll(); + } + catch(PDOException $exception){} foreach($customMenus as $menu) if(isset($lang->{$menu->key})) $lang->{$menu->key} = $menu->value; } } @@ -356,9 +365,6 @@ class router extends baseRouter public function loadModuleConfig($moduleName, $appName = '') { global $config; - - $appName = ''; - if($config and (!isset($config->$moduleName) or !is_object($config->$moduleName))) $config->$moduleName = new stdclass(); /* 初始化数组。Init the variables. */ diff --git a/module/action/config.php b/module/action/config.php index 77eaec4b92..d7e9abdb8f 100755 --- a/module/action/config.php +++ b/module/action/config.php @@ -65,7 +65,7 @@ $config->action->majorList['project'] = array('opened', 'edited'); $config->action->majorList['execution'] = array('opened', 'edited'); $config->action->needGetProjectType = 'build,task,bug,case,testcase,caselib,testtask,testsuite,testreport,doc,issue,release,risk,design,opportunity,trainplan,gapanalysis,researchplan,researchreport,'; -$config->action->needGetRelateField = ',story,productplan,release,task,build,bug,testcase,case,testtask,testreport,doc,doclib,issue,risk,opportunity,trainplan,gapanalysis,team,whitelist,researchplan,researchreport,meeting,kanbanlane,kanbancolumn,module,review,'; +$config->action->needGetRelateField = ',branch,story,productplan,release,task,build,bug,testcase,case,testtask,testreport,doc,doclib,issue,risk,opportunity,trainplan,gapanalysis,team,whitelist,researchplan,researchreport,meeting,kanbanlane,kanbancolumn,module,review,'; $config->action->noLinkModules = ',doclib,module,webhook,gitlab,gitea,gogs,sonarqube,pipeline,jenkins,kanban,kanbanspace,kanbancolumn,kanbanlane,kanbanregion,kanbancard,execution,project,traincategory,apistruct,program,product,user,entry,repo,'; $config->action->ignoreObjectType4Dynamic = 'kanbanregion,kanbanlane,kanbancolumn'; diff --git a/module/action/model.php b/module/action/model.php index d0133ef7fd..8dc16c0131 100755 --- a/module/action/model.php +++ b/module/action/model.php @@ -453,7 +453,7 @@ class actionModel extends model elseif($actionName == 'unlinkedfromexecution') { $name = $this->dao->select('name')->from(TABLE_PROJECT)->where('id')->eq($action->extra)->fetch('name'); - if($name) $action->extra = common::hasPriv('project', 'story') ? html::a(helper::createLink('project', 'story', "projectID=$action->extra"), "#$action->extra " . $name) : "#$action->extra " . $name; + if($name) $action->extra = common::hasPriv('execution', 'view') ? html::a(helper::createLink('execution', 'view', "executionID=$action->extra"), "#$action->extra " . $name) : "#$action->extra " . $name; } elseif($actionName == 'unlinkedfromproject') { @@ -949,7 +949,7 @@ class actionModel extends model else { if($actionType == 'restoredsnapshot' && in_array($action->objectType, array('vm', 'zanode')) && $value == 'defaultSnap') $value = $this->lang->$objectType->snapshot->defaultSnapName; - + $desc = str_replace('$' . $key, $value, $desc); } } diff --git a/module/admin/lang/de.php b/module/admin/lang/de.php index 9829c02c0e..ac0302561d 100755 --- a/module/admin/lang/de.php +++ b/module/admin/lang/de.php @@ -106,7 +106,7 @@ $lang->admin->setModule->auditplan = 'QA'; $lang->admin->setModule->meeting = 'Meeting'; $lang->admin->setModule->roadmap = 'Roadmap'; $lang->admin->setModule->track = 'Track'; -$lang->admin->setModule->UR = 'URStroy'; +$lang->admin->setModule->UR = $lang->URCommon; $lang->admin->setModule->researchplan = 'Researchplan'; $lang->admin->setModule->gapanalysis = 'Gapanalysis'; $lang->admin->setModule->storylib = 'Story Lib'; diff --git a/module/admin/lang/en.php b/module/admin/lang/en.php index 989d926c26..9094d6a330 100755 --- a/module/admin/lang/en.php +++ b/module/admin/lang/en.php @@ -106,7 +106,7 @@ $lang->admin->setModule->auditplan = 'QA'; $lang->admin->setModule->meeting = 'Meeting'; $lang->admin->setModule->roadmap = 'Roadmap'; $lang->admin->setModule->track = 'Track'; -$lang->admin->setModule->UR = 'URStroy'; +$lang->admin->setModule->UR = $lang->URCommon; $lang->admin->setModule->researchplan = 'Researchplan'; $lang->admin->setModule->gapanalysis = 'Gapanalysis'; $lang->admin->setModule->storylib = 'Story Lib'; diff --git a/module/admin/lang/fr.php b/module/admin/lang/fr.php index 3c6b0b8179..99ae83495c 100755 --- a/module/admin/lang/fr.php +++ b/module/admin/lang/fr.php @@ -106,7 +106,7 @@ $lang->admin->setModule->auditplan = 'QA'; $lang->admin->setModule->meeting = 'Meeting'; $lang->admin->setModule->roadmap = 'Roadmap'; $lang->admin->setModule->track = 'Track'; -$lang->admin->setModule->UR = 'URStroy'; +$lang->admin->setModule->UR = $lang->URCommon; $lang->admin->setModule->researchplan = 'Researchplan'; $lang->admin->setModule->gapanalysis = 'Gapanalysis'; $lang->admin->setModule->storylib = 'Story Lib'; diff --git a/module/admin/lang/menu.php b/module/admin/lang/menu.php index a9580b0a4f..c154fd9f32 100644 --- a/module/admin/lang/menu.php +++ b/module/admin/lang/menu.php @@ -121,7 +121,7 @@ $lang->admin->menuList->feature['tabMenu']['product']['productplan'] = array('li $lang->admin->menuList->feature['tabMenu']['product']['release'] = array('link' => "{$lang->release->common}|custom|required|module=release", 'exclude' => 'custom-required'); $lang->admin->menuList->feature['tabMenu']['execution']['execution'] = array('link' => "{$lang->execution->common}|custom|required|module=execution", 'links' => array("custom|execution|"), 'alias' => 'execution', 'exclude' => 'custom-required'); -$lang->admin->menuList->feature['tabMenu']['execution']['task'] = array('link' => "{$lang->task->common}|custom|required|module=task", 'links' => array('custom|set|module=task&field=priList', 'custom|limittaskdate'), 'alias' => 'limittaskdate','exclude' => 'custom-required'); +$lang->admin->menuList->feature['tabMenu']['execution']['task'] = array('link' => "{$lang->task->common}|custom|required|module=task", 'links' => array('custom|set|module=task&field=priList', 'custom|limittaskdate|'), 'alias' => 'limittaskdate','exclude' => 'custom-required'); $lang->admin->menuList->feature['tabMenu']['qa']['bug'] = array('link' => "{$lang->bug->common}|custom|required|module=bug", 'links' => array("custom|set|module=bug&field=priList"), 'exclude' => 'custom-required,custom-set'); $lang->admin->menuList->feature['tabMenu']['qa']['testcase'] = array('link' => "{$lang->testcase->common}|custom|required|module=testcase", 'links' => array("custom|set|module=testcase&field=priList"), 'exclude' => 'custom-required,custom-set'); diff --git a/module/admin/lang/zh-cn.php b/module/admin/lang/zh-cn.php index bc4a35220a..2e8af2b073 100755 --- a/module/admin/lang/zh-cn.php +++ b/module/admin/lang/zh-cn.php @@ -106,7 +106,7 @@ $lang->admin->setModule->auditplan = 'QA'; $lang->admin->setModule->meeting = '会议'; $lang->admin->setModule->roadmap = '路线图'; $lang->admin->setModule->track = '矩阵'; -$lang->admin->setModule->UR = '用户需求'; +$lang->admin->setModule->UR = $lang->URCommon; $lang->admin->setModule->researchplan = '调研'; $lang->admin->setModule->gapanalysis = '培训'; $lang->admin->setModule->storylib = '需求库'; diff --git a/module/admin/model.php b/module/admin/model.php index 7253ab5c88..81209b5347 100755 --- a/module/admin/model.php +++ b/module/admin/model.php @@ -666,6 +666,7 @@ class adminModel extends model ->limit('1') ->fetch('date'); + if($firstUseDate) $firstUseDate = substr($firstUseDate, 0, 10); return helper::getDateInterval($firstUseDate); } diff --git a/module/api/control.php b/module/api/control.php index 6826f47564..d6d1f6a578 100755 --- a/module/api/control.php +++ b/module/api/control.php @@ -803,15 +803,15 @@ EOT; { $result = $this->api->request($method->className, $method->methodName, $action); $content = json_decode($result['content']); - $status = $content->status; - $data = json_decode($content->data); + $status = zget($content, 'status', ''); + $data = isset($content->data) ? json_decode($content->data) : ''; $data = '' . print_r($data, true) . ''; $response['result'] = 'success'; $response['status'] = $status; $response['url'] = $result['url']; $response['data'] = $data; - $this->send($response); + return print(json_encode($response)); } $this->view->method = $method; diff --git a/module/api/js/debug.js b/module/api/js/debug.js index 705eaa0830..fbcfa67d39 100644 --- a/module/api/js/debug.js +++ b/module/api/js/debug.js @@ -1,6 +1,6 @@ $(document).ready(function() { - var options = + var options = { target : null, timeout : 30000, diff --git a/module/block/view/scrumlistblock.html.php b/module/block/view/scrumlistblock.html.php index f583c20b12..8d08bf51c3 100644 --- a/module/block/view/scrumlistblock.html.php +++ b/module/block/view/scrumlistblock.html.php @@ -45,7 +45,7 @@ $viewLink = $this->createLink('execution', 'task', 'executionID=' . $execution->id); ?> > - name, '', "title='$execution->name'");?> + name, '', "title='$execution->name' class='text-primary'");?> end;?> diff --git a/module/bug/config.php b/module/bug/config.php index d9c707e2f2..16921034e9 100755 --- a/module/bug/config.php +++ b/module/bug/config.php @@ -217,7 +217,7 @@ $config->bug->datatable->fieldList['project']['fixed'] = 'no'; $config->bug->datatable->fieldList['project']['width'] = '120'; $config->bug->datatable->fieldList['project']['required'] = 'no'; $config->bug->datatable->fieldList['project']['control'] = 'hidden'; -$config->bug->datatable->fieldList['project']['dataSource'] = array('module' => 'product', 'method' => 'getProjectPairsByProduct', 'params' => '$productID'); +$config->bug->datatable->fieldList['project']['dataSource'] = array('module' => 'product', 'method' => 'getProjectPairsByProduct', 'params' => '$productID&'); $config->bug->datatable->fieldList['execution']['title'] = 'execution'; $config->bug->datatable->fieldList['execution']['fixed'] = 'no'; diff --git a/module/bug/css/browse.css b/module/bug/css/browse.css index 260ea0ab1d..557dba00db 100644 --- a/module/bug/css/browse.css +++ b/module/bug/css/browse.css @@ -22,6 +22,7 @@ th.c-confirmed {text-align: center;} .c-severity {overflow: hidden; white-space: nowrap;} .c-keywords {overflow: hidden; white-space: nowrap;} .c-id {text-overflow: ellipsis; white-space: nowrap;} +.c-toTask {overflow: hidden; white-space: nowrap;} .body-modal #mainMenu>.btn-toolbar {width: auto;} diff --git a/module/bug/view/edit.html.php b/module/bug/view/edit.html.php index 2a0e86dc51..6aa2684235 100644 --- a/module/bug/view/edit.html.php +++ b/module/bug/view/edit.html.php @@ -125,7 +125,7 @@ if($this->app->tab == 'project') js::set('objectID', $bug->project); - '> + '> bug->productplan;?> plan, "class='form-control chosen'");?> diff --git a/module/bug/view/view.html.php b/module/bug/view/view.html.php index 1ef74093c0..0d38c5d2a4 100644 --- a/module/bug/view/view.html.php +++ b/module/bug/view/view.html.php @@ -161,7 +161,7 @@ bug->fromCase;?> case) echo html::a(helper::createLink('testcase', 'view', "caseID=$bug->case&version=$bug->caseVersion", '', true), " {$lang->bug->fromCase}$lang->colon$bug->case", '', isonlybody() ? '' : "data-toggle='modal' data-type='iframe' data-width='80%'");?> - '> + '> bug->productplan;?> plan or !common::printLink('productplan', 'view', "planID=$bug->plan&type=bug", $bug->planName)) echo $bug->planName;?> diff --git a/module/caselib/view/create.html.php b/module/caselib/view/create.html.php index 81db56d2c2..2c8ee99723 100644 --- a/module/caselib/view/create.html.php +++ b/module/caselib/view/create.html.php @@ -25,7 +25,7 @@ caselib->desc;?> - + printExtendFields('', 'table');?> diff --git a/module/common/lang/de.php b/module/common/lang/de.php index 94980fb14c..0c916d800e 100644 --- a/module/common/lang/de.php +++ b/module/common/lang/de.php @@ -90,7 +90,7 @@ $lang->viewDetails = 'View Details'; $lang->actions = 'Aktionen'; $lang->restore = 'Wiederherstellen'; -$lang->confirmDraft = 'There are unsaved form of %name%. Do you want to restore them?'; +$lang->confirmDraft = 'Unsaved form is found. Do you want to restore it?'; $lang->resume = 'resume'; $lang->comment = 'Notiz'; $lang->history = 'Historie'; diff --git a/module/common/lang/en.php b/module/common/lang/en.php index c041725072..715782f579 100644 --- a/module/common/lang/en.php +++ b/module/common/lang/en.php @@ -90,7 +90,7 @@ $lang->viewDetails = 'View Details'; $lang->actions = 'Action'; $lang->restore = 'Reset'; -$lang->confirmDraft = 'There are unsaved form of %name%. Do you want to restore them?'; +$lang->confirmDraft = 'Unsaved form is found. Do you want to restore it?'; $lang->resume = 'resume'; $lang->comment = 'Note'; $lang->history = 'History'; diff --git a/module/common/lang/fr.php b/module/common/lang/fr.php index e7496a09a8..502a64a84c 100644 --- a/module/common/lang/fr.php +++ b/module/common/lang/fr.php @@ -90,7 +90,7 @@ $lang->viewDetails = 'View Details'; $lang->actions = 'Action'; $lang->restore = 'Réinitialiser'; -$lang->confirmDraft = 'There are unsaved form of %name%. Do you want to restore them?'; +$lang->confirmDraft = 'Unsaved form is found. Do you want to restore it?'; $lang->resume = 'resume'; $lang->comment = 'Note'; $lang->history = 'Historique'; diff --git a/module/common/view/kindeditor.html.php b/module/common/view/kindeditor.html.php index 74626a21db..5da89fc62c 100755 --- a/module/common/view/kindeditor.html.php +++ b/module/common/view/kindeditor.html.php @@ -109,6 +109,10 @@ $uid = uniqid(''); items: editorTool, placeholder: $editor.attr('placeholder') || options.placeholder || '', pasteImage: {postUrl: createLink('file', 'ajaxPasteImg', 'uid=' + kuid), placeholder: $editor.attr('placeholder') || noticePasteImg);?>}, + afterChange: function() + { + $editor.closest('.main-form').trigger('change'); + } }); try diff --git a/module/custom/lang/de.php b/module/custom/lang/de.php index b9eb95d85b..e35a1c5dbb 100644 --- a/module/custom/lang/de.php +++ b/module/custom/lang/de.php @@ -236,8 +236,8 @@ $lang->custom->restDayList[6] = 'Saturday rest'; $lang->custom->restDayList[0] = 'Sunday rest'; global $config; -$lang->custom->sprintConceptList[0] = 'Program Product Iteration'; -$lang->custom->sprintConceptList[1] = 'Program Product Sprint'; +$lang->custom->sprintConceptList[0] = 'Project Product Iteration'; +$lang->custom->sprintConceptList[1] = 'Project Product Sprint'; $lang->custom->workingList['full'] = 'Full Management of Dev'; diff --git a/module/custom/lang/en.php b/module/custom/lang/en.php index b083c164af..268fbab554 100644 --- a/module/custom/lang/en.php +++ b/module/custom/lang/en.php @@ -236,8 +236,8 @@ $lang->custom->restDayList[6] = 'Saturday rest'; $lang->custom->restDayList[0] = 'Sunday rest'; global $config; -$lang->custom->sprintConceptList[0] = 'Program Product Iteration'; -$lang->custom->sprintConceptList[1] = 'Program Product Sprint'; +$lang->custom->sprintConceptList[0] = 'Project Product Iteration'; +$lang->custom->sprintConceptList[1] = 'Project Product Sprint'; $lang->custom->workingList['full'] = 'Application Lifecycle Management'; diff --git a/module/custom/lang/fr.php b/module/custom/lang/fr.php index b13c6cb8cb..fb3c6f4552 100644 --- a/module/custom/lang/fr.php +++ b/module/custom/lang/fr.php @@ -236,8 +236,8 @@ $lang->custom->restDayList[6] = 'Saturday rest'; $lang->custom->restDayList[0] = 'Sunday rest'; global $config; -$lang->custom->sprintConceptList[0] = 'Program Product Iteration'; -$lang->custom->sprintConceptList[1] = 'Program Product Sprint'; +$lang->custom->sprintConceptList[0] = 'Project Product Iteration'; +$lang->custom->sprintConceptList[1] = 'Project Product Sprint'; $lang->custom->workingList['full'] = 'Application Lifecycle Management'; diff --git a/module/custom/lang/zh-cn.php b/module/custom/lang/zh-cn.php index 37575fbd92..b677dd0d0b 100644 --- a/module/custom/lang/zh-cn.php +++ b/module/custom/lang/zh-cn.php @@ -236,8 +236,8 @@ $lang->custom->restDayList[6] = '周六休息'; $lang->custom->restDayList[0] = '周天休息'; global $config; -$lang->custom->sprintConceptList[0] = "{$lang->projectCommon} 产品 迭代"; -$lang->custom->sprintConceptList[1] = "{$lang->projectCommon} 产品 冲刺"; +$lang->custom->sprintConceptList[0] = "项目 产品 迭代"; +$lang->custom->sprintConceptList[1] = "项目 产品 冲刺"; $lang->custom->workingList['full'] = '完整研发管理工具'; diff --git a/module/custom/model.php b/module/custom/model.php index b091e14b71..a390f12f77 100644 --- a/module/custom/model.php +++ b/module/custom/model.php @@ -577,7 +577,6 @@ class customModel extends model public function getURSRPairs() { $lang = $this->app->getClientLang(); - $lang = $lang == 'zh-tw' ? 'zh-cn' : $lang; $langData = $this->dao->select('`key`, `value`, `system`')->from(TABLE_LANG) ->where('lang')->eq($lang) ->andWhere('module')->eq('custom') @@ -659,7 +658,6 @@ class customModel extends model { $this->app->loadLang('custom'); $lang = $this->app->getClientLang(); - $lang = $lang == 'zh-tw' ? 'zh-cn' : $lang; $langData = $this->dao->select('`key`, `value`, `system`')->from(TABLE_LANG) ->where('lang')->eq($lang) diff --git a/module/dev/lang/de.php b/module/dev/lang/de.php index e815c1b72d..e648dff8e1 100644 --- a/module/dev/lang/de.php +++ b/module/dev/lang/de.php @@ -1,7 +1,7 @@ dev->common = 'Entwicklung'; -$lang->dev->api = 'API'; -$lang->dev->db = 'Datenbank'; +$lang->dev->api = 'API Document'; +$lang->dev->db = 'Data Dictionary'; $lang->dev->editor = 'Bearbeiter'; $lang->dev->translate = 'Translate'; $lang->dev->dbList = 'Datenbank'; @@ -18,7 +18,7 @@ $lang->dev->paramRange = 'Parameter Range: %s'; $lang->dev->paramDate = 'Date format: YY-mm-dd, e.g 2019-01-01'; $lang->dev->paramColor = 'Color format: #RGB, e.g. #3da7f5'; $lang->dev->paramMailto = "User account. Separate accounts by ','."; -$lang->dev->noteEditor = "The editor is disabled for security reasons. To use this feature, please go to the official website to download and install the plugin of the editor."; +$lang->dev->noteEditor = "The editor is disabled for security reasons. To use this feature, Please turn on."; $lang->dev->noteTranslate = "The translation is disabled for security reasons. To use this feature, please go to the official website to download and install the plugin of translation."; $lang->dev->confirmRestore = 'Do you want to reset?'; diff --git a/module/dev/lang/en.php b/module/dev/lang/en.php index ac7deabf7e..95bff27d80 100644 --- a/module/dev/lang/en.php +++ b/module/dev/lang/en.php @@ -1,7 +1,7 @@ dev->common = 'Develop'; -$lang->dev->api = 'API'; -$lang->dev->db = 'Database'; +$lang->dev->api = 'API Document'; +$lang->dev->db = 'Data Dictionary'; $lang->dev->editor = 'Editor'; $lang->dev->translate = 'Translate'; $lang->dev->dbList = 'Database'; @@ -18,7 +18,7 @@ $lang->dev->paramRange = 'Parameter Range: %s'; $lang->dev->paramDate = 'Date format: YY-mm-dd, e.g 2019-01-01'; $lang->dev->paramColor = 'Color format: #RGB, e.g. #3da7f5'; $lang->dev->paramMailto = "User account. Separate accounts by ','."; -$lang->dev->noteEditor = "The editor is disabled for security reasons. To use this feature, please go to the official website to download and install the plugin of the editor."; +$lang->dev->noteEditor = "The editor is disabled for security reasons. To use this feature, Please turn on."; $lang->dev->noteTranslate = "The translation is disabled for security reasons. To use this feature, please go to the official website to download and install the plugin of translation."; $lang->dev->confirmRestore = 'Do you want to reset?'; diff --git a/module/dev/lang/fr.php b/module/dev/lang/fr.php index ac7deabf7e..95bff27d80 100644 --- a/module/dev/lang/fr.php +++ b/module/dev/lang/fr.php @@ -1,7 +1,7 @@ dev->common = 'Develop'; -$lang->dev->api = 'API'; -$lang->dev->db = 'Database'; +$lang->dev->api = 'API Document'; +$lang->dev->db = 'Data Dictionary'; $lang->dev->editor = 'Editor'; $lang->dev->translate = 'Translate'; $lang->dev->dbList = 'Database'; @@ -18,7 +18,7 @@ $lang->dev->paramRange = 'Parameter Range: %s'; $lang->dev->paramDate = 'Date format: YY-mm-dd, e.g 2019-01-01'; $lang->dev->paramColor = 'Color format: #RGB, e.g. #3da7f5'; $lang->dev->paramMailto = "User account. Separate accounts by ','."; -$lang->dev->noteEditor = "The editor is disabled for security reasons. To use this feature, please go to the official website to download and install the plugin of the editor."; +$lang->dev->noteEditor = "The editor is disabled for security reasons. To use this feature, Please turn on."; $lang->dev->noteTranslate = "The translation is disabled for security reasons. To use this feature, please go to the official website to download and install the plugin of translation."; $lang->dev->confirmRestore = 'Do you want to reset?'; diff --git a/module/dev/lang/zh-cn.php b/module/dev/lang/zh-cn.php index 0e5e117fd5..c01ab55b44 100644 --- a/module/dev/lang/zh-cn.php +++ b/module/dev/lang/zh-cn.php @@ -1,7 +1,7 @@ dev->common = '二次开发'; -$lang->dev->api = 'API'; -$lang->dev->db = '数据库'; +$lang->dev->api = '接口文档'; +$lang->dev->db = '数据字典'; $lang->dev->editor = '编辑器'; $lang->dev->translate = '翻译'; $lang->dev->dbList = '数据库'; diff --git a/module/dev/model.php b/module/dev/model.php index e2706de62f..47e14f5198 100644 --- a/module/dev/model.php +++ b/module/dev/model.php @@ -418,6 +418,7 @@ class devModel extends model $originalLangs['SRCommon'] = $this->lang->dev->SR; $URSRList = $this->loadModel('custom')->getItems("lang={$language}&module=custom§ion=URSRList&key={$this->config->custom->URSR}&vision={$this->config->vision}"); + if(empty($URSRList)) $URSRList = $this->custom->getItems("lang={$language}&module=custom§ion=URSRList&vision={$this->config->vision}"); $URSRList = array_shift($URSRList); if($URSRList) { @@ -505,6 +506,7 @@ class devModel extends model $customedLangs['URCommon'] = $this->lang->dev->UR == $this->lang->URCommon ? '' : $this->lang->URCommon; $customedLangs['SRCommon'] = $this->lang->dev->SR == $this->lang->SRCommon ? '' : $this->lang->SRCommon; $URSRList = $this->custom->getItems("lang={$language}&module=custom§ion=URSRList&key={$this->config->custom->URSR}&vision={$this->config->vision}"); + if(empty($URSRList)) $URSRList = $this->custom->getItems("lang={$language}&module=custom§ion=URSRList&vision={$this->config->vision}"); $URSRList = array_shift($URSRList); if($URSRList) { @@ -1040,7 +1042,12 @@ class devModel extends model $_POST = array(); $oldValue = $this->dao->select('*')->from(TABLE_LANG)->where('`key`')->eq($this->config->custom->URSR)->andWhere('section')->eq('URSRList')->andWhere('lang')->eq($language)->andWhere('module')->eq('custom')->fetch('value'); - $oldValue = json_decode($oldValue); + $URSRList = $this->loadModel('custom')->getItems("lang={$language}&module=custom§ion=URSRList&key={$this->config->custom->URSR}&vision={$this->config->vision}"); + if(empty($URSRList)) $URSRList = $this->custom->getItems("lang={$language}&module=custom§ion=URSRList&vision={$this->config->vision}"); + $URSRList = array_shift($URSRList); + + $this->config->custom->URSR = $URSRList->key; + $oldValue = json_decode($URSRList->value); $_POST['SRName'] = !empty($post['common_SRCommon']) ? $post['common_SRCommon'] : zget($oldValue, 'defaultSRName', $oldValue->SRName); $_POST['URName'] = !empty($post['common_URCommon']) ? $post['common_URCommon'] : zget($oldValue, 'defaultURName', $oldValue->URName); @@ -1099,10 +1106,11 @@ class devModel extends model $module->children = array(); foreach($objects[$moduleKey] as $objectKey => $objectName) { - $defaultValue = $type == 'module' ? $objectName : ''; + if($type == 'table' and !isset($this->lang->dev->tableList[$objectKey])) continue; + $object = new stdclass(); $object->key = $objectName; - $object->title = zget($this->lang->dev->tableList, $objectKey, $defaultValue); + $object->title = zget($this->lang->dev->tableList, $objectKey, $objectName); $object->active = $objectName == $currentObject ? 1 : 0; if($object->active) $module->active = 1; diff --git a/module/dev/view/langitem.html.php b/module/dev/view/langitem.html.php index a6f24dad43..a5f36abaa7 100644 --- a/module/dev/view/langitem.html.php +++ b/module/dev/view/langitem.html.php @@ -47,7 +47,7 @@ -
+
app->getClientLang()) != $language):?> diff --git a/module/doc/control.php b/module/doc/control.php index 62a201ffee..336439b4e8 100755 --- a/module/doc/control.php +++ b/module/doc/control.php @@ -236,8 +236,7 @@ class doc extends control $response['message'] = $this->lang->saveSuccess; $response['result'] = 'success'; - $response['closeModal'] = true; - $response['callback'] = "redirectParentWindow($hasLibPriv, $libID, $objectID)"; + $response['locate'] = 'parent'; return $this->send($response); } diff --git a/module/editor/control.php b/module/editor/control.php index a03432e552..da2b0ba95c 100644 --- a/module/editor/control.php +++ b/module/editor/control.php @@ -160,9 +160,16 @@ class editor extends control { $filePath = helper::safe64Decode($filePath); if(strpos(strtolower($filePath), strtolower($this->app->getBasePath())) !== 0) return print($this->lang->editor->editFileError); + + $fileName = empty($_POST['fileName']) ? '' : trim($this->post->fileName); + if(empty($fileName)) return print(js::error($this->lang->editor->emptyFileName)); + if($action != 'edit' and $action != 'newPage') $filePath = $this->editor->getSavePath($filePath, $action); if($action != 'edit' and $action != 'newPage' and file_exists($filePath) and !$this->post->override) return print(js::error($this->lang->editor->repeatFile)); - if(!$this->editor->save($filePath)) return; + + $result = $this->editor->save($filePath); + if(is_string($result)) return print(js::alert($result)); + echo js::reload('parent.parent.extendWin'); return print(js::locate(inlink('edit', "filePath=" . helper::safe64Encode($filePath) . "&action=edit"), 'parent')); } diff --git a/module/editor/css/extend.css b/module/editor/css/extend.css index cb5051802c..68dc6d394b 100644 --- a/module/editor/css/extend.css +++ b/module/editor/css/extend.css @@ -12,3 +12,4 @@ .m-editor-extend .main-header {padding: 10px 20px; } .m-editor-extend .main-content {padding: 0px; padding-top: 10px; box-shadow: none;} #extendTree li a {white-space: nowrap;} +#extendTree span {padding: 0 4px;} diff --git a/module/editor/js/index.js b/module/editor/js/index.js index 161b430f51..a5a5fedfef 100644 --- a/module/editor/js/index.js +++ b/module/editor/js/index.js @@ -47,4 +47,12 @@ function initModuleTree() $(this).parent().addClass('active'); $(this).parent().parent().parent().addClass('active'); }) + + $firstModule = $('#moduleTree li a:not([data-has-children="true"])'); + if($firstModule.length) + { + $firstModule = $firstModule.eq(0); + $firstModule.closest('li.has-list').addClass('open in'); + $firstModule.trigger('click'); + } } diff --git a/module/editor/lang/de.php b/module/editor/lang/de.php index cdca827ca2..159fa032f5 100644 --- a/module/editor/lang/de.php +++ b/module/editor/lang/de.php @@ -34,7 +34,8 @@ $lang->editor->noticeOkFile = 'Aus Sicherheitsgründen muss Ihr Adminkonto best $lang->editor->editFileError = 'Sie können nur ZenTao Dateien verändern!'; $lang->editor->turnOff = "If you don't use the editor function, you can turn it off here."; -$lang->editor->notWritable = "Nicht beschreibbar. Berechtigung erforderlich. Bitte versuchen Sie chmod 777 -R "; +$lang->editor->notExists = "Not exists. Please create it. Try mkdir -p %s"; +$lang->editor->notWritable = "Nicht beschreibbar. Berechtigung erforderlich. Bitte versuchen Sie chmod 777 -R %s"; $lang->editor->notDelete = 'Kann nicht gelöscht werden. Bitte prüfen Sie Ihre Berechtigungen!'; $lang->editor->emptyFileName = 'Bitte geben Sie einen Dateinamen an!'; $lang->editor->onlyLocalVisit = "This feature only works when the IP is 127.0.0.1. Help"; diff --git a/module/editor/lang/en.php b/module/editor/lang/en.php index 2d3a1bfd2d..d9052c4cc2 100644 --- a/module/editor/lang/en.php +++ b/module/editor/lang/en.php @@ -34,7 +34,8 @@ $lang->editor->noticeOkFile = 'For security reasons, your Admin account has to $lang->editor->editFileError = 'You can only modify ZenTao files!'; $lang->editor->turnOff = "If you don't use the editor function, you can turn it off here."; -$lang->editor->notWritable = "Not wirtable. Permission is required. Please try chmod 777 -R "; +$lang->editor->notExists = "Not exists. Please create it. Try mkdir -p %s"; +$lang->editor->notWritable = "Not wirtable. Permission is required. Please try chmod 777 -R %s"; $lang->editor->notDelete = 'Cannot be deleted. Please check your permissions!'; $lang->editor->emptyFileName = 'Please enter a File Name!'; $lang->editor->onlyLocalVisit = "This feature only works when the IP is 127.0.0.1 for security. Help"; diff --git a/module/editor/lang/fr.php b/module/editor/lang/fr.php index 3c4db8b0e5..7ab003a543 100644 --- a/module/editor/lang/fr.php +++ b/module/editor/lang/fr.php @@ -34,7 +34,8 @@ $lang->editor->noticeOkFile = 'Pour des raisons de s?curit?, votre compte admin $lang->editor->editFileError = 'Vous pouvez seulement modifier les fichiers ZenTao !'; $lang->editor->turnOff = "If you don't use the editor function, you can turn it off here."; -$lang->editor->notWritable = "Non inscriptible. Permission requise. Essayez chmod 777 -R "; +$lang->editor->notExists = "Not exists. Please create it. Try mkdir -p %s"; +$lang->editor->notWritable = "Non inscriptible. Permission requise. Essayez chmod 777 -R %s"; $lang->editor->notDelete = 'Ne peut pas ?tre supprim?. V?rifiez les permissions !'; $lang->editor->emptyFileName = 'Entrez un nom de fichier !'; $lang->editor->onlyLocalVisit = "Cette fonctionnalit? ne fonctionne que pour une IP 127.0.0.1. Aide"; diff --git a/module/editor/lang/zh-cn.php b/module/editor/lang/zh-cn.php index 6936539032..2d2d06d868 100644 --- a/module/editor/lang/zh-cn.php +++ b/module/editor/lang/zh-cn.php @@ -34,7 +34,8 @@ $lang->editor->noticeOkFile = '为了安全起见,系统需要确认您的管 $lang->editor->editFileError = '只能修改禅道文件!'; $lang->editor->turnOff = '如不使用编辑器功能,可在此关闭。'; -$lang->editor->notWritable = "无法写入,可能没有权限。请尝试执行 chmod 777 -R "; +$lang->editor->notExists = "不存在该目录,请先创建。请尝试执行 mkdir -p %s"; +$lang->editor->notWritable = "无法写入,可能没有权限。请尝试执行 chmod 777 -R %s"; $lang->editor->notDelete = '无法删除,请检查权限!'; $lang->editor->emptyFileName = '请写入一个文件名!'; $lang->editor->onlyLocalVisit = "该功能只能在IP:127.0.0.1下访问。说明文档"; diff --git a/module/editor/model.php b/module/editor/model.php index bf0a9eb96a..8feb42f355 100644 --- a/module/editor/model.php +++ b/module/editor/model.php @@ -320,24 +320,21 @@ class editorModel extends model * * @param string $filePath * @access public - * @return bool + * @return string */ public function save($filePath) { /* Reduce expiration time for check safe file. */ $this->config->safeFileTimeout = 15 * 60; $statusFile = $this->loadModel('common')->checkSafeFile(); - if($statusFile) - { - print(js::alert(sprintf($this->lang->editor->noticeOkFile, str_replace('\\', '/', $statusFile)))); - return false; - } + if($statusFile) return sprintf($this->lang->editor->noticeOkFile, str_replace('\\', '/', $statusFile)); $dirPath = dirname($filePath); $extFilePath = substr($filePath, 0, strpos($filePath, DS . 'ext' . DS) + 4); if(!is_dir($dirPath) and is_writable($extFilePath)) mkdir($dirPath, 0777, true); - if(!is_dir($dirPath) or !is_writable($dirPath)) return print(js::alert($this->lang->editor->notWritable . $extFilePath)); - if(strpos(strtolower(realpath($dirPath)), strtolower($this->app->getBasePath())) !== 0) return print(js::alert($this->lang->editor->editFileError)); + if(!is_dir($dirPath)) return sprintf($this->lang->editor->notExists, $extFilePath); + if(!is_writable($dirPath)) return sprintf($this->lang->editor->notWritable, $extFilePath); + if(strpos(strtolower(realpath($dirPath)), strtolower($this->app->getBasePath())) !== 0) return $this->lang->editor->editFileError; $fileContent = $this->post->fileContent; $evils = array('eval', 'exec', 'passthru', 'proc_open', 'shell_exec', 'system', '$$', 'include', 'require', 'assert', 'javascript', 'onclick'); diff --git a/module/editor/view/extend.html.php b/module/editor/view/extend.html.php index 08381d2bfa..5717a1a4fa 100644 --- a/module/editor/view/extend.html.php +++ b/module/editor/view/extend.html.php @@ -51,6 +51,14 @@ $(function() { if(!$(this).hasClass('active')) $(this).removeClass('text-primary'); }); + + var $firstBtn = $('a[target="editWin"]'); + if($firstBtn.length) + { + $firstBtn = $firstBtn.eq(0); + $firstBtn.trigger('click'); + $(parent.document).find('#editWin').attr('src', $firstBtn.attr('href')); + } }); diff --git a/module/execution/control.php b/module/execution/control.php index a08edbe0f2..b693088674 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -2177,6 +2177,7 @@ class execution extends control $allProjects = $this->project->getPairsByModel($project->model, 0, 'noclosed', isset($projectID) ? $projectID : 0); $this->project->setMenu($projectID); $this->view->project = $project; + if($project->model == 'waterfall' or $project->model == 'waterfallplus') $this->lang->execution->common = $this->lang->execution->stage; } else { diff --git a/module/execution/css/view.css b/module/execution/css/view.css index ade5431e42..5be4918dab 100644 --- a/module/execution/css/view.css +++ b/module/execution/css/view.css @@ -27,5 +27,5 @@ #cfdChart {margin-top: -20px;} -#triggerModal .modal-dialog {top: 15% !important; overflow-y: auto; max-height: 80%;} +#triggerModal .modal-dialog {top: 15% !important; max-height: 80%;} #triggerModal .modal-dialog::-webkit-scrollbar-track {background-color: white;} diff --git a/module/execution/lang/zh-cn.php b/module/execution/lang/zh-cn.php index b5fc440213..276bcda25b 100644 --- a/module/execution/lang/zh-cn.php +++ b/module/execution/lang/zh-cn.php @@ -654,8 +654,8 @@ $lang->execution->gantt->exportFail = '导出失败。'; $lang->execution->boardColorList = array('#32C5FF', '#006AF1', '#9D28B2', '#FF8F26', '#7FBB00', '#424BAC', '#66c5f8', '#EC2761'); -$lang->execution->linkBranchStoryByPlanTips = "执行按计划关联需求时,只导入本执行所关联%s的激活状态的需求。"; -$lang->execution->linkNormalStoryByPlanTips = "执行按计划关联需求时,只导入激活状态的需求。"; +$lang->execution->linkBranchStoryByPlanTips = "{$lang->execution->common}按计划关联需求时,只导入本{$lang->execution->common}所关联%s的激活状态的需求。"; +$lang->execution->linkNormalStoryByPlanTips = "{$lang->execution->common}按计划关联需求时,只导入激活状态的需求。"; $lang->execution->featureBar['dynamic']['all'] = '全部'; $lang->execution->featureBar['dynamic']['today'] = '今天'; diff --git a/module/execution/model.php b/module/execution/model.php index b27463f5d3..6acd189014 100755 --- a/module/execution/model.php +++ b/module/execution/model.php @@ -390,11 +390,11 @@ class executionModel extends model $type = 'sprint'; if($project) $type = zget($this->config->execution->modelList, $project->model, 'sprint'); - if(($project->model == 'waterfall' or $project->model == 'waterfallplus') and isset($this->config->setPercent) and $this->config->setPercent == 1) + if($project->model == 'waterfall' or $project->model == 'waterfallplus') { $_POST['products'] = array_filter($_POST['products']); if(empty($_POST['products'])) dao::$errors['products0'] = $this->lang->project->errorNoProducts; - $this->checkWorkload('create', $_POST['percent'], $project); + if(isset($this->config->setPercent) and $this->config->setPercent == 1) $this->checkWorkload('create', $_POST['percent'], $project); if(dao::isError()) return false; } @@ -1311,6 +1311,27 @@ class executionModel extends model unset($execution->end); } + if($this->post->readjustTime && $oldExecution->grade > 1) + { + $parent = $this->getByID($oldExecution->parent); + $begin = $execution->begin; + $end = $execution->end; + $parentBegin = $parent->begin; + $parentEnd = $parent->end; + + if($begin < $parentBegin) + { + dao::$errors["message"][] = sprintf($this->lang->execution->errorLetterParent, $parentBegin); + } + + if($end > $parentEnd) + { + dao::$errors["message"][] = sprintf($this->lang->execution->errorGreaterParent, $parentEnd); + } + } + + if(dao::isError()) return false; + $execution = $this->loadModel('file')->processImgURL($execution, $this->config->execution->editor->activate['id'], $this->post->uid); $this->dao->update(TABLE_EXECUTION)->data($execution) ->autoCheck() @@ -5684,12 +5705,13 @@ class executionModel extends model */ public function generateRow($executions, $users, $productID) { - $rows = array(); + $today = helper::today(); + $rows = array(); foreach($executions as $id => $execution) { $label = $execution->type == 'stage' ? 'label-warning' : 'label-info'; $link = $execution->type == 'kanban' ? helper::createLink('execution', 'kanban', "id=$execution->id") : helper::createLink('execution', 'task', "id=$execution->id"); - $execution->name = "{$this->lang->execution->typeList[$execution->type]} " . (empty($execution->children) ? html::a($link, $execution->name) : $execution->name); + $execution->name = "{$this->lang->execution->typeList[$execution->type]} " . (empty($execution->children) ? html::a($link, $execution->name, '_self', 'class="text-primary"') : $execution->name) . (strtotime($today) > strtotime($execution->end) ? '' . $this->lang->execution->delayed . '' : '');; $execution->project = $execution->projectName; $execution->parent = ($execution->parent and $execution->grade > 1) ? $execution->parent : ''; $execution->asParent = !empty($execution->children); diff --git a/module/execution/view/story.html.php b/module/execution/view/story.html.php index 54cc115c73..8412190f4c 100644 --- a/module/execution/view/story.html.php +++ b/module/execution/view/story.html.php @@ -271,6 +271,7 @@ $story):?> estimate; + $story->from = $this->app->tab; ?> $value) @@ -286,7 +287,7 @@ children)):?> children as $key => $child):?> - from = 'execution';?> + from = $this->app->tab;?> children)) ? ' table-child-bottom' : '';?> @@ -404,7 +405,7 @@ execution->linkBranchStoryByPlanTips, $lang->project->branch) : $lang->execution->linkNormalStoryByPlanTips; - $linkStoryByPlanTips = $execution->multiple ? $linkStoryByPlanTips : str_replace($lang->executionCommon, $lang->projectCommon, $linkStoryByPlanTips); + $linkStoryByPlanTips = $execution->multiple ? $linkStoryByPlanTips : str_replace($lang->execution->common, $lang->projectCommon, $linkStoryByPlanTips); ?>
diff --git a/module/file/model.php b/module/file/model.php index a11d334653..ecfbad3811 100755 --- a/module/file/model.php +++ b/module/file/model.php @@ -733,7 +733,7 @@ class fileModel extends model $line = str_replace('""', '"', $line); /* if only one column then line is the data. */ - if(strpos($line, ',') === false and $line[0] != '"' and $col == -1) + if(strpos($line, ',') === false and isset($line[0]) and $line[0] != '"' and $col == -1) { $data[$row][0] = trim($line, '"'); } diff --git a/module/index/control.php b/module/index/control.php index 664eb2c5d8..b4f6cef1e2 100644 --- a/module/index/control.php +++ b/module/index/control.php @@ -62,17 +62,6 @@ class index extends control $this->display(); } - /** - * Just test the extension engine. - * - * @access public - * @return void - */ - public function testext() - { - echo $this->fetch('misc', 'getsid'); - } - /** * ajaxClearObjectSession * diff --git a/module/mr/control.php b/module/mr/control.php index 7d2e34b035..503fd7c6cc 100644 --- a/module/mr/control.php +++ b/module/mr/control.php @@ -39,7 +39,7 @@ class mr extends control ->andWhere('synced')->eq(1) ->orderBy('id') ->count(); - if($repoCount == 0) $this->locate($this->repo->createLink('create')); + if($repoCount == 0) $this->locate($this->loadModel('repo')->createLink('create')); $repoID = $this->loadModel('repo')->saveState($repoID, $objectID); $repo = $this->repo->getRepoByID($repoID); diff --git a/module/my/model.php b/module/my/model.php index 9b462d72f1..06456510bc 100644 --- a/module/my/model.php +++ b/module/my/model.php @@ -1112,11 +1112,12 @@ class myModel extends model { if($checkExists) return true; $story = new stdclass(); - $story->id = $data->id; - $story->title = $data->title; - $story->type = 'story'; - $story->time = $data->openedDate; - $story->status = $data->status; + $story->id = $data->id; + $story->title = $data->title; + $story->type = 'story'; + $story->storyType = $data->type; + $story->time = $data->openedDate; + $story->status = $data->status; $stories[$story->id] = $story; } @@ -1435,6 +1436,7 @@ class myModel extends model $review->status = $objectType == 'attend' ? $object->reviewStatus : ((isset($object->status) and !isset($flows[$objectType])) ? $object->status : 'done'); if(strpos($review->result, ',') !== false) list($review->result) = explode(',', $review->result); + if($objectType == 'story') $review->storyType = $object->type; if($review->type == 'review') $review->type = 'projectreview'; if($review->type == 'case') $review->type = 'testcase'; $review->title = ''; diff --git a/module/my/view/audit.html.php b/module/my/view/audit.html.php index 20b6198d42..d6e7345166 100644 --- a/module/my/view/audit.html.php +++ b/module/my/view/audit.html.php @@ -57,7 +57,7 @@ $typeName = ''; if(isset($lang->{$review->type}->common)) $typeName = $lang->{$review->type}->common; - if($type == 'story') $typeName = $lang->SRCommon; + if($type == 'story') $typeName = $review->storyType == 'story' ? $lang->SRCommon : $lang->URCommon; if($review->type == 'projectreview') $typeName = $lang->project->common; if(isset($flows[$review->type])) $typeName = $flows[$review->type]; diff --git a/module/product/model.php b/module/product/model.php index 7268ae8977..27cda70cf3 100755 --- a/module/product/model.php +++ b/module/product/model.php @@ -1275,6 +1275,7 @@ class productModel extends model public function getProjectPairsByProduct($productID, $branch = 0, $appendProject = 0, $status = '', $param = '') { $product = $this->getById($productID); + if(empty($product)) return array(); return $this->dao->select('t2.id, t2.name')->from(TABLE_PROJECTPRODUCT)->alias('t1') ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id') diff --git a/module/product/view/ajaxgetdropmenu.html.php b/module/product/view/ajaxgetdropmenu.html.php index 22e5ef33f6..6e8f6d3d16 100644 --- a/module/product/view/ajaxgetdropmenu.html.php +++ b/module/product/view/ajaxgetdropmenu.html.php @@ -4,26 +4,27 @@