Merge branch '18.x' into zentaoipd
This commit is contained in:
Vendored
+279
-61
@@ -18,6 +18,8 @@ pipeline {
|
||||
SRC_ZDOOEXT_PATH = "${WORKSPACE}/zdooext"
|
||||
|
||||
SRC_ZENTAOEXT_PATH = "${WORKSPACE}/zentaoext"
|
||||
|
||||
MIRROR = "true"
|
||||
}
|
||||
|
||||
stages {
|
||||
@@ -48,6 +50,7 @@ pipeline {
|
||||
stage("Pull") {
|
||||
steps {
|
||||
checkout scm
|
||||
sh 'env'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,24 +105,13 @@ pipeline {
|
||||
}
|
||||
|
||||
stage("Build") {
|
||||
environment {
|
||||
GIT_TAG_BUILD_TYPE = """${sh(
|
||||
returnStdout: true,
|
||||
script: 'misc/parse_tag.sh $TAG_NAME type'
|
||||
).trim()}"""
|
||||
|
||||
GIT_TAG_BUILD_GROUP = """${sh(
|
||||
returnStdout: true,
|
||||
script: 'misc/parse_tag.sh $TAG_NAME group'
|
||||
).trim()}"""
|
||||
}
|
||||
|
||||
stages {
|
||||
stage("make ciCommon") {
|
||||
steps {
|
||||
|
||||
sh "echo $GIT_TAG_BUILD_TYPE/abc"
|
||||
sh "echo $GIT_TAG_BUILD_GROUP/def"
|
||||
container('xuanimbot') {
|
||||
sh 'git config --global --add safe.directory $(pwd)'
|
||||
sh '/usr/local/bin/xuanimbot --groups 84be4c6e-02e3-4fdc-b081-318c0c1eca02 --groups 31a0008b-6e3e-4b7f-9b7b-396a46b1f8f4 --title "Start build zentaopms" --url "${BUILD_URL}" --content "Build by Tag ${TAG_NAME}" --debug --custom'
|
||||
}
|
||||
withCredentials([gitUsernamePassword(credentialsId: 'git-zcorp-cc-jenkins-bot-http',gitToolName: 'git-tool')]) {
|
||||
container('package') {
|
||||
sh 'mkdir ${ZENTAO_RELEASE_PATH} && chown 1000:1000 ${ZENTAO_RELEASE_PATH}'
|
||||
@@ -162,6 +154,11 @@ pipeline {
|
||||
script: 'cat ${SRC_ZENTAOEXT_PATH}/MAXVERSION'
|
||||
).trim()}"""
|
||||
|
||||
GIT_COMMIT = """${sh(
|
||||
returnStdout: true,
|
||||
script: 'git rev-parse HEAD'
|
||||
).trim()}"""
|
||||
|
||||
GIT_TAG_BUILD_TYPE = """${sh(
|
||||
returnStdout: true,
|
||||
script: 'misc/parse_tag.sh $TAG_NAME type'
|
||||
@@ -172,11 +169,16 @@ pipeline {
|
||||
script: 'misc/parse_tag.sh $TAG_NAME group'
|
||||
).trim()}"""
|
||||
|
||||
GIT_TAGGER_NAME = """${sh(
|
||||
returnStdout: true,
|
||||
script: 'git for-each-ref --format="%(taggername)" refs/tags/$(git tag --points-at HEAD)'
|
||||
).trim()}"""
|
||||
|
||||
OUTPUT_PKG_PATH = "${ZENTAO_RELEASE_PATH}/output"
|
||||
|
||||
ARTIFACT_REPOSITORY = """${sh(
|
||||
returnStdout: true,
|
||||
script: 'echo easycorp-snapshot'
|
||||
script: 'misc/parse_tag.sh $TAG_NAME type | grep release >/dev/null && echo easycorp || echo easycorp-snapshot'
|
||||
).trim()}"""
|
||||
ARTIFACT_HOST = "nexus.qc.oop.cc"
|
||||
ARTIFACT_PROTOCOL = "https"
|
||||
@@ -185,6 +187,7 @@ pipeline {
|
||||
|
||||
stages {
|
||||
stage("Merge and Upload") {
|
||||
|
||||
matrix {
|
||||
agent {
|
||||
kubernetes {
|
||||
@@ -194,10 +197,11 @@ pipeline {
|
||||
command "sleep"
|
||||
args "99d"
|
||||
}
|
||||
inheritFrom "publish-qiniu"
|
||||
}
|
||||
}
|
||||
options { skipDefaultCheckout() }
|
||||
options {
|
||||
skipDefaultCheckout()
|
||||
}
|
||||
|
||||
axes {
|
||||
axis {
|
||||
@@ -223,11 +227,15 @@ pipeline {
|
||||
}
|
||||
stages {
|
||||
|
||||
stage("frame") {
|
||||
stage("ZIP") {
|
||||
environment {
|
||||
ARTIFACT_NAME = """${sh(
|
||||
returnStdout: true,
|
||||
script: 'test ${ZLANG} = cn && echo -n zentaopms || echo -n zentaoalm'
|
||||
script: 'test ${ZLANG} = cn && echo -n ZenTaoPMS || echo -n ZenTaoALM'
|
||||
).trim()}"""
|
||||
INT_FLAG = """${sh(
|
||||
returnStdout: true,
|
||||
script: 'test ${ZLANG} = cn && echo -n "int." || echo -n ""'
|
||||
).trim()}"""
|
||||
}
|
||||
|
||||
@@ -239,7 +247,6 @@ pipeline {
|
||||
sh 'mkdir $ZENTAO_RELEASE_PATH'
|
||||
sh '${ZENTAO_BUILD_PATH}/package.sh zip'
|
||||
sh 'mkdir $OUTPUT_PKG_PATH'
|
||||
sh 'env | grep GIT_TAG'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -250,7 +257,7 @@ pipeline {
|
||||
nexusVersion: 'nexus3',
|
||||
protocol: env.ARTIFACT_PROTOCOL,
|
||||
nexusUrl: env.ARTIFACT_HOST,
|
||||
groupId: 'zentao.base' + '.' + env.GIT_TAG_BUILD_GROUP,
|
||||
groupId: 'zentao.pmsPack' + '.' + env.GIT_TAG_BUILD_GROUP,
|
||||
version: env.PMS_VERSION,
|
||||
repository: env.ARTIFACT_REPOSITORY,
|
||||
credentialsId: env.ARTIFACT_CRED_ID,
|
||||
@@ -265,7 +272,7 @@ pipeline {
|
||||
nexusVersion: 'nexus3',
|
||||
protocol: env.ARTIFACT_PROTOCOL,
|
||||
nexusUrl: env.ARTIFACT_HOST,
|
||||
groupId: 'zentao.biz' + '.' + env.GIT_TAG_BUILD_GROUP,
|
||||
groupId: 'zentao.bizPack' + '.' + env.GIT_TAG_BUILD_GROUP,
|
||||
version: env.BIZ_VERSION,
|
||||
repository: env.ARTIFACT_REPOSITORY,
|
||||
credentialsId: env.ARTIFACT_CRED_ID,
|
||||
@@ -284,7 +291,7 @@ pipeline {
|
||||
nexusVersion: 'nexus3',
|
||||
protocol: env.ARTIFACT_PROTOCOL,
|
||||
nexusUrl: env.ARTIFACT_HOST,
|
||||
groupId: 'zentao.max' + '.' + env.GIT_TAG_BUILD_GROUP,
|
||||
groupId: 'zentao.maxPack' + '.' + env.GIT_TAG_BUILD_GROUP,
|
||||
version: env.MAX_VERSION,
|
||||
repository: env.ARTIFACT_REPOSITORY,
|
||||
credentialsId: env.ARTIFACT_CRED_ID,
|
||||
@@ -301,18 +308,18 @@ pipeline {
|
||||
)
|
||||
|
||||
sh 'mkdir ${OUTPUT_PKG_PATH}/${PMS_VERSION} ${OUTPUT_PKG_PATH}/${BIZ_VERSION} ${OUTPUT_PKG_PATH}/${MAX_VERSION}'
|
||||
sh 'cp ${ZENTAO_RELEASE_PATH}/base.zip ${OUTPUT_PKG_PATH}/${PMS_VERSION}/${ARTIFACT_NAME}-${PMS_VERSION}-${PHPVERSION}.zip'
|
||||
sh 'mv ${ZENTAO_RELEASE_PATH}/biz.zip ${OUTPUT_PKG_PATH}/${BIZ_VERSION}/${ARTIFACT_NAME}-${BIZ_VERSION}-${PHPVERSION}.zip'
|
||||
sh 'mv ${ZENTAO_RELEASE_PATH}/biz.update.zip ${OUTPUT_PKG_PATH}/${BIZ_VERSION}/${ARTIFACT_NAME}.update-${BIZ_VERSION}-${PHPVERSION}.zip'
|
||||
sh 'mv ${ZENTAO_RELEASE_PATH}/max.zip ${OUTPUT_PKG_PATH}/${MAX_VERSION}/${ARTIFACT_NAME}-${MAX_VERSION}-${PHPVERSION}.zip'
|
||||
sh 'mv ${ZENTAO_RELEASE_PATH}/max.update.zip ${OUTPUT_PKG_PATH}/${MAX_VERSION}/${ARTIFACT_NAME}.update-${MAX_VERSION}-${PHPVERSION}.zip'
|
||||
sh 'cp ${ZENTAO_RELEASE_PATH}/base.zip ${OUTPUT_PKG_PATH}/${PMS_VERSION}/${ARTIFACT_NAME}.${PMS_VERSION}.${INT_FLAG}${PHPVERSION}.zip'
|
||||
sh 'mv ${ZENTAO_RELEASE_PATH}/biz.zip ${OUTPUT_PKG_PATH}/${BIZ_VERSION}/${ARTIFACT_NAME}.${BIZ_VERSION}.${INT_FLAG}${PHPVERSION}.zip'
|
||||
sh 'mv ${ZENTAO_RELEASE_PATH}/biz.update.zip ${OUTPUT_PKG_PATH}/${BIZ_VERSION}/${ARTIFACT_NAME}.${BIZ_VERSION}.${INT_FLAG}update.${PHPVERSION}.zip'
|
||||
sh 'mv ${ZENTAO_RELEASE_PATH}/max.zip ${OUTPUT_PKG_PATH}/${MAX_VERSION}/${ARTIFACT_NAME}.${MAX_VERSION}.${INT_FLAG}${PHPVERSION}.zip'
|
||||
sh 'mv ${ZENTAO_RELEASE_PATH}/max.update.zip ${OUTPUT_PKG_PATH}/${MAX_VERSION}/${ARTIFACT_NAME}.${MAX_VERSION}.${INT_FLAG}update.${PHPVERSION}.zip'
|
||||
}
|
||||
} // End upload zip
|
||||
|
||||
stage("syspack") {
|
||||
when {
|
||||
buildingTag()
|
||||
// environment name: 'GIT_TAG_BUILD_TYPE', value: 'release'
|
||||
// buildingTag()
|
||||
environment name: 'GIT_TAG_BUILD_TYPE', value: 'release'
|
||||
}
|
||||
steps{
|
||||
sh 'env | grep GIT_TAG'
|
||||
@@ -329,28 +336,8 @@ pipeline {
|
||||
}
|
||||
|
||||
steps {
|
||||
nexusArtifactUploader(
|
||||
nexusVersion: 'nexus3',
|
||||
protocol: env.ARTIFACT_PROTOCOL,
|
||||
nexusUrl: env.ARTIFACT_HOST,
|
||||
groupId: 'zentao.pms' + '.' + env.GIT_TAG_BUILD_GROUP,
|
||||
version: env.PMS_VERSION,
|
||||
repository: env.ARTIFACT_REPOSITORY,
|
||||
credentialsId: env.ARTIFACT_CRED_ID,
|
||||
artifacts: [
|
||||
[artifactId: env.ARTIFACT_NAME,
|
||||
classifier: env.PHPVERSION + '-1.noarch',
|
||||
file: env.ZENTAO_RELEASE_PATH + '/zentao.rpm',
|
||||
type: 'rpm'],
|
||||
[artifactId: env.ARTIFACT_NAME,
|
||||
classifier: env.PHPVERSION + '.1.all',
|
||||
file: env.ZENTAO_RELEASE_PATH + '/zentao.deb',
|
||||
type: 'deb']
|
||||
]
|
||||
)
|
||||
|
||||
sh 'mv ${ZENTAO_RELEASE_PATH}/zentao.rpm ${OUTPUT_PKG_PATH}/${PMS_VERSION}/${ARTIFACT_NAME}-${PMS_VERSION}-${PHPVERSION}-1.noarch.rpm'
|
||||
sh 'mv ${ZENTAO_RELEASE_PATH}/zentao.deb ${OUTPUT_PKG_PATH}/${PMS_VERSION}/${ARTIFACT_NAME}-${PMS_VERSION}-${PHPVERSION}.1.all.deb'
|
||||
sh 'mv ${ZENTAO_RELEASE_PATH}/zentao.rpm ${OUTPUT_PKG_PATH}/${PMS_VERSION}/${ARTIFACT_NAME}.${PMS_VERSION}.${PHPVERSION}.1.noarch.rpm'
|
||||
sh 'mv ${ZENTAO_RELEASE_PATH}/zentao.deb ${OUTPUT_PKG_PATH}/${PMS_VERSION}/${ARTIFACT_NAME}.${PMS_VERSION}.${PHPVERSION}.1.all.deb'
|
||||
}
|
||||
} // End upload syspack cn
|
||||
|
||||
@@ -360,7 +347,7 @@ pipeline {
|
||||
}
|
||||
|
||||
environment {
|
||||
QINIU_BUCKET = "qisytest"
|
||||
QINIU_BUCKET = "download"
|
||||
OBJECT_KEY_PREFIX = "zentao/"
|
||||
QINIU_ACCESS_KEY = credentials('qiniu-upload-ak')
|
||||
QINIU_SECRET_KEY = credentials('qiniu-upload-sk')
|
||||
@@ -368,10 +355,10 @@ pipeline {
|
||||
|
||||
steps {
|
||||
sh 'ls -l ${OUTPUT_PKG_PATH}'
|
||||
container('qiniu') {
|
||||
sh "qshell account $QINIU_ACCESS_KEY $QINIU_SECRET_KEY uploader"
|
||||
sh "qshell qupload2 --bucket ${QINIU_BUCKET} --overwrite --src-dir ${OUTPUT_PKG_PATH} --key-prefix ${OBJECT_KEY_PREFIX}"
|
||||
}
|
||||
container('jnlp') {
|
||||
sh 'qshell account $QINIU_ACCESS_KEY $QINIU_SECRET_KEY uploader'
|
||||
sh 'qshell qupload2 --bucket $QINIU_BUCKET --overwrite --src-dir $OUTPUT_PKG_PATH --key-prefix $OBJECT_KEY_PREFIX'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -383,15 +370,246 @@ pipeline {
|
||||
|
||||
} // End Merge and Upload Max
|
||||
|
||||
stage("Notice") {
|
||||
stage("Notice ZIP") {
|
||||
steps {
|
||||
container('xuanimbot') {
|
||||
sh 'env | grep GIT'
|
||||
sh 'git config --global --add safe.directory $(pwd)'
|
||||
//sh '/usr/local/bin/xuanimbot --users "qishiyao" --title "zentao build with tag ${TAG_NAME} success" --url ""${ARTIFACT_PROTOCOL}://${ARTIFACT_HOST}/#browse/browse:${ARTIFACT_REPOSITORY}:zentao"" --content "zentaopms build success, click buttom below for browse artifacts" --debug --custom'
|
||||
sh '/usr/local/bin/xuanimbot --users "qishiyao" --groups "fced7fb3-0d48-449f-b408-ecae52a50f89" --title "zentao build with tag ${TAG_NAME} success" --url ""${ARTIFACT_PROTOCOL}://${ARTIFACT_HOST}/#browse/browse:${ARTIFACT_REPOSITORY}:zentao"" --content "zentaopms build success, click buttom below for browse artifacts" --debug --custom'
|
||||
sh './misc/gen_build_report.sh > /tmp/success.md'
|
||||
sh '/usr/local/bin/xuanimbot --groups 84be4c6e-02e3-4fdc-b081-318c0c1eca02 --groups 31a0008b-6e3e-4b7f-9b7b-396a46b1f8f4 --title "zentaopms package success" --url "${RUN_DISPLAY_URL}" --content-file /tmp/success.md --debug --custom'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage("Docker Image") {
|
||||
agent {
|
||||
kubernetes {
|
||||
inheritFrom "dind xuanim"
|
||||
}
|
||||
}
|
||||
stages() {
|
||||
stage("prepare") {
|
||||
steps {
|
||||
checkout scmGit(branches: [[name: "master"]],
|
||||
extensions: [cloneOption(depth: 2, noTags: false, reference: '', shallow: true)],
|
||||
userRemoteConfigs: [[credentialsId: 'git-zcorp-cc-jenkins-bot-http', url: 'https://git.zcorp.cc/app/zentao.git']]
|
||||
)
|
||||
container('docker') {
|
||||
sh "sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories"
|
||||
sh "apk --no-cache add make bash jq git"
|
||||
sh "docker run --privileged --rm tonistiigi/binfmt --install all"
|
||||
sh "docker buildx create --name mybuilder --driver docker-container --bootstrap"
|
||||
sh "docker buildx use mybuilder"
|
||||
sh "make markdown-init"
|
||||
}
|
||||
}
|
||||
}
|
||||
stage("docker pms") {
|
||||
environment {
|
||||
ZENTAO_URL = """${sh(
|
||||
returnStdout: true,
|
||||
script: "echo ${ARTIFACT_PROTOCOL}://${ARTIFACT_HOST}/repository/${ARTIFACT_REPOSITORY}/zentao/pmsPack/`echo ${GIT_TAG_BUILD_GROUP} | tr . /`/ZenTaoPMS"
|
||||
).trim()}"""
|
||||
}
|
||||
steps {
|
||||
container('docker') {
|
||||
sh 'env | grep ZENTAO'
|
||||
sh 'make build'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage("docker biz") {
|
||||
environment {
|
||||
ZENTAO_URL = """${sh(
|
||||
returnStdout: true,
|
||||
script: "echo ${ARTIFACT_PROTOCOL}://${ARTIFACT_HOST}/repository/${ARTIFACT_REPOSITORY}/zentao/bizPack/`echo ${GIT_TAG_BUILD_GROUP} | tr . /`/ZenTaoPMS"
|
||||
).trim()}"""
|
||||
}
|
||||
steps {
|
||||
container('docker') {
|
||||
sh 'make build-biz'
|
||||
sh 'make build-biz-k8s'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage("docker max") {
|
||||
environment {
|
||||
ZENTAO_URL = """${sh(
|
||||
returnStdout: true,
|
||||
script: "echo ${ARTIFACT_PROTOCOL}://${ARTIFACT_HOST}/repository/${ARTIFACT_REPOSITORY}/zentao/maxPack/`echo ${GIT_TAG_BUILD_GROUP} | tr . /`/ZenTaoPMS"
|
||||
).trim()}"""
|
||||
}
|
||||
steps {
|
||||
container('docker') {
|
||||
sh 'make build-max'
|
||||
sh 'make build-max-k8s'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage("Image Notice") {
|
||||
steps {
|
||||
container('docker') {
|
||||
sh 'make markdown-render > ./report.md'
|
||||
}
|
||||
container('xuanimbot') {
|
||||
sh 'git config --global --add safe.directory $(pwd)'
|
||||
sh '/usr/local/bin/xuanimbot --groups 84be4c6e-02e3-4fdc-b081-318c0c1eca02 --groups 31a0008b-6e3e-4b7f-9b7b-396a46b1f8f4 --title "zentaopms build image success" --url "${RUN_DISPLAY_URL}" --content-file ./report.md --debug --custom'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
} // End Docker Image
|
||||
|
||||
stage("Zbox") {
|
||||
agent {
|
||||
kubernetes {
|
||||
containerTemplate {
|
||||
name "docker"
|
||||
image "docker:23.0.6-dind-alpine3.17"
|
||||
command "sleep"
|
||||
args "99d"
|
||||
}
|
||||
inheritFrom "dind xuanim"
|
||||
}
|
||||
}
|
||||
|
||||
stages() {
|
||||
stage("Prepare") {
|
||||
steps {
|
||||
checkout scmGit(branches: [[name: "main"]],
|
||||
extensions: [cloneOption(depth: 2, noTags: false, reference: '', shallow: true)],
|
||||
userRemoteConfigs: [[credentialsId: 'git-zcorp-cc-jenkins-bot-http', url: 'https://git.zcorp.cc/devops/zbox-builder.git']]
|
||||
)
|
||||
container('docker') {
|
||||
sh "sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories"
|
||||
sh "apk --no-cache add make bash jq git curl wget libarchive-tools p7zip mariadb-client"
|
||||
sh "docker run --privileged --rm tonistiigi/binfmt --install all"
|
||||
sh "docker buildx create --name mybuilder --driver docker-container --bootstrap"
|
||||
sh "docker buildx use mybuilder"
|
||||
sh 'curl https://pkg.qucheng.com/files/stacksmith/render-template-1.0.1-10-debian-11-amd64.tar.gz | tar zxf - -C /'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage("Build Zbox") {
|
||||
environment {
|
||||
// printf "$PKG_URL_FORMATTER" pmsPack ZenTaoPMS 18.5 ZenTaoPMS-18.5-php8.1.zip
|
||||
PKG_URL_FORMATTER = """${sh(
|
||||
returnStdout: true,
|
||||
script: "echo ${ARTIFACT_PROTOCOL}://${ARTIFACT_HOST}/repository/${ARTIFACT_REPOSITORY}/zentao/%s/`echo ${GIT_TAG_BUILD_GROUP} | tr . /`/%s/%s/%s"
|
||||
).trim()}"""
|
||||
}
|
||||
steps {
|
||||
container('docker') {
|
||||
sh 'bash build-zbox.sh zh-cn linux $PMS_VERSION $BIZ_VERSION $MAX_VERSION ipd1.0'
|
||||
sh 'bash build-zbox.sh en linux $PMS_VERSION $BIZ_VERSION $MAX_VERSION ipd1.0'
|
||||
sh 'ls -l release'
|
||||
}
|
||||
|
||||
nexusArtifactUploader(
|
||||
nexusVersion: 'nexus3',
|
||||
protocol: env.ARTIFACT_PROTOCOL,
|
||||
nexusUrl: env.ARTIFACT_HOST,
|
||||
groupId: 'zentao.pmsPack' + '.' + env.GIT_TAG_BUILD_GROUP,
|
||||
version: env.PMS_VERSION,
|
||||
repository: env.ARTIFACT_REPOSITORY,
|
||||
credentialsId: env.ARTIFACT_CRED_ID,
|
||||
artifacts: [
|
||||
[artifactId: 'ZenTaoPMS',
|
||||
classifier: 'zbox_64',
|
||||
file: './release/zh-cn/' + PMS_VERSION + '/ZenTaoPMS.' + PMS_VERSION + '.zbox_64.tar.gz',
|
||||
type: 'tar.gz'],
|
||||
[artifactId: 'ZenTaoALM',
|
||||
classifier: 'zbox_64',
|
||||
file: './release/en/' + PMS_VERSION + '/ZenTaoALM.' + PMS_VERSION + '.int.zbox_64.tar.gz',
|
||||
type: 'tar.gz']
|
||||
]
|
||||
)
|
||||
|
||||
nexusArtifactUploader(
|
||||
nexusVersion: 'nexus3',
|
||||
protocol: env.ARTIFACT_PROTOCOL,
|
||||
nexusUrl: env.ARTIFACT_HOST,
|
||||
groupId: 'zentao.bizPack' + '.' + env.GIT_TAG_BUILD_GROUP,
|
||||
version: env.BIZ_VERSION,
|
||||
repository: env.ARTIFACT_REPOSITORY,
|
||||
credentialsId: env.ARTIFACT_CRED_ID,
|
||||
artifacts: [
|
||||
[artifactId: 'ZenTaoPMS',
|
||||
classifier: 'zbox_64',
|
||||
file: './release/zh-cn/' + BIZ_VERSION + '/ZenTaoPMS.' + BIZ_VERSION + '.zbox_64.tar.gz',
|
||||
type: 'tar.gz'],
|
||||
[artifactId: 'ZenTaoALM',
|
||||
classifier: 'zbox_64',
|
||||
file: './release/en/' + BIZ_VERSION + '/ZenTaoALM.' + BIZ_VERSION + '.int.zbox_64.tar.gz',
|
||||
type: 'tar.gz']
|
||||
]
|
||||
)
|
||||
|
||||
nexusArtifactUploader(
|
||||
nexusVersion: 'nexus3',
|
||||
protocol: env.ARTIFACT_PROTOCOL,
|
||||
nexusUrl: env.ARTIFACT_HOST,
|
||||
groupId: 'zentao.maxPack' + '.' + env.GIT_TAG_BUILD_GROUP,
|
||||
version: env.MAX_VERSION,
|
||||
repository: env.ARTIFACT_REPOSITORY,
|
||||
credentialsId: env.ARTIFACT_CRED_ID,
|
||||
artifacts: [
|
||||
[artifactId: 'ZenTaoPMS',
|
||||
classifier: 'zbox_64',
|
||||
file: './release/zh-cn/' + MAX_VERSION + '/ZenTaoPMS.' + MAX_VERSION + '.zbox_64.tar.gz',
|
||||
type: 'tar.gz'],
|
||||
[artifactId: 'ZenTaoALM',
|
||||
classifier: 'zbox_64',
|
||||
file: './release/en/' + MAX_VERSION + '/ZenTaoALM.' + MAX_VERSION + '.int.zbox_64.tar.gz',
|
||||
type: 'tar.gz']
|
||||
]
|
||||
)
|
||||
|
||||
sh 'script/lib/gen_report.sh > zbox-success.md'
|
||||
container('xuanimbot') {
|
||||
sh 'git config --global --add safe.directory $(pwd)'
|
||||
sh '/usr/local/bin/xuanimbot --groups 84be4c6e-02e3-4fdc-b081-318c0c1eca02 --groups 31a0008b-6e3e-4b7f-9b7b-396a46b1f8f4 --title "zentaopms build zbox success" --url "${RUN_DISPLAY_URL}" --content-file zbox-success.md --debug --custom'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage("Upload Zbox to Qiniu") {
|
||||
when {
|
||||
environment name: 'GIT_TAG_BUILD_TYPE', value: 'release'
|
||||
}
|
||||
|
||||
environment {
|
||||
QINIU_BUCKET = "download"
|
||||
OBJECT_KEY_PREFIX = "zentao/"
|
||||
QINIU_ACCESS_KEY = credentials('qiniu-upload-ak')
|
||||
QINIU_SECRET_KEY = credentials('qiniu-upload-sk')
|
||||
}
|
||||
|
||||
steps {
|
||||
container('jnlp') {
|
||||
sh 'qshell account $QINIU_ACCESS_KEY $QINIU_SECRET_KEY uploader'
|
||||
sh 'qshell qupload2 --bucket $QINIU_BUCKET --overwrite --src-dir ./release/zh-cn --key-prefix $OBJECT_KEY_PREFIX'
|
||||
sh 'qshell qupload2 --bucket $QINIU_BUCKET --overwrite --src-dir ./release/en --key-prefix $OBJECT_KEY_PREFIX'
|
||||
}
|
||||
}
|
||||
} // End Upload Zbox to Qiniu
|
||||
}
|
||||
} // End Zbox
|
||||
|
||||
}
|
||||
|
||||
post {
|
||||
failure {
|
||||
container('xuanimbot') {
|
||||
sh 'git config --global --add safe.directory $(pwd)'
|
||||
sh '/usr/local/bin/xuanimbot --users "${GIT_TAGGER_NAME}" --groups 31a0008b-6e3e-4b7f-9b7b-396a46b1f8f4 --title "zentaopms build failed" --url "${BUILD_URL}" --content "" --debug --custom'
|
||||
}
|
||||
}
|
||||
}
|
||||
} // end publish
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@ class buildsEntry extends entry
|
||||
if(empty($projectID)) $projectID = $this->param('project', 0);
|
||||
if(empty($projectID)) return $this->sendError(400, "Need project id.");
|
||||
|
||||
$control = $this->loadController('project', 'build');
|
||||
$control->build($projectID, $this->param('type', 'all'), $this->param('param', 0), $this->param('order', 't1.date_desc,t1.id_desc'));
|
||||
$control = $this->loadController('projectbuild', 'browse');
|
||||
$control->browse($projectID, $this->param('type', 'all'), $this->param('param', 0), $this->param('order', 't1.date_desc,t1.id_desc'));
|
||||
$data = $this->getData();
|
||||
|
||||
if(!isset($data->status)) return $this->sendError(400, 'error');
|
||||
|
||||
@@ -64,6 +64,24 @@ class ztfSubmitEntry extends baseEntry
|
||||
->set('ZTFResult')->eq(json_encode($post))
|
||||
->where('id')->eq($post->task)
|
||||
->exec();
|
||||
|
||||
$result = $this->dao->select('*')->from(TABLE_TESTRESULT)
|
||||
->where('id')->eq($post->task)
|
||||
->fetch();
|
||||
|
||||
if($result->run)
|
||||
{
|
||||
$runStatus = $result->caseResult == 'blocked' ? 'blocked' : 'normal';
|
||||
$this->dao->update(TABLE_TESTRUN)
|
||||
->set('lastRunResult')->eq($result->caseResult)
|
||||
->set('status')->eq($runStatus)
|
||||
->set('lastRunner')->eq($result->lastRunner)
|
||||
->set('lastRunDate')->eq($result->date)
|
||||
->where('id')->eq($result->run)
|
||||
->exec();
|
||||
}
|
||||
|
||||
$this->dao->update(TABLE_CASE)->set('lastRunner')->eq($result->lastRunner)->set('lastRunDate')->eq($result->date)->set('lastRunResult')->eq($result->caseResult)->where('id')->eq($result->case)->exec();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ if(!class_exists('config')){class config{}}
|
||||
if(!function_exists('getWebRoot')){function getWebRoot(){}}
|
||||
|
||||
/* 基本设置。Basic settings. */
|
||||
$config->version = '18.5'; // ZenTaoPHP的版本。 The version of ZenTaoPHP. Don't change it.
|
||||
$config->version = '18.6'; // ZenTaoPHP的版本。 The version of ZenTaoPHP. Don't change it.
|
||||
$config->liteVersion = '1.2'; // 迅捷版版本。 The version of Lite.
|
||||
$config->charset = 'UTF-8'; // ZenTaoPHP的编码。 The encoding of ZenTaoPHP.
|
||||
$config->cookieLife = time() + 2592000; // Cookie的生存时间。The cookie life time.
|
||||
|
||||
@@ -34,6 +34,7 @@ $routes['/configurations/:name'] = 'config';
|
||||
$routes['/programs/:id/products'] = 'products';
|
||||
$routes['/products'] = 'products';
|
||||
$routes['/products/:id'] = 'product';
|
||||
$routes['/product/:id'] = 'product';
|
||||
|
||||
$routes['/productlines'] = 'productLines';
|
||||
$routes['/productlines/:id'] = 'productLine';
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
UPDATE `zt_chart` SET `sql` = 'SELECT IF(t3.id IS NOT NULL, t3.`name`, \"空\") AS deptName,count(1) as count, \r\nIF(t3.id IS NOT NULL, t3.`order`, 9999) AS deptOrder \r\nFROM zt_user AS t1 \r\nLEFT JOIN zt_dept AS t2 ON t1.dept = t2.id\r\nLEFT JOIN zt_dept AS t3 ON FIND_IN_SET(TRIM(\',\' FROM t3.path), TRIM(\',\' FROM t2.path)) AND t3.grade = \'1\'\r\nWHERE t1.deleted = \'0\'\r\nGROUP BY deptName, deptOrder \r\nORDER BY deptOrder ASC'
|
||||
WHERE `id` = 1049;
|
||||
+7
-7
File diff suppressed because one or more lines are too long
+2
-2
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"pkg": {
|
||||
"xuanxuan": {
|
||||
"gitVersion": "4786a9a7555ef5cdc6f8b84049d44e2add643a23",
|
||||
"version": "7.1"
|
||||
"gitVersion": "v7.2.1-rc.4",
|
||||
"version": "7.2.1"
|
||||
},
|
||||
"zentaoext": {
|
||||
"gitVersion": "18.x"
|
||||
|
||||
Executable
+61
@@ -0,0 +1,61 @@
|
||||
#!/bin/bash
|
||||
|
||||
finishTime=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
|
||||
blankLine() {
|
||||
echo
|
||||
}
|
||||
|
||||
outputFrame() {
|
||||
printf "$1"
|
||||
}
|
||||
|
||||
outputLine() {
|
||||
echo "$1"
|
||||
}
|
||||
|
||||
outputLine "构建日期 **$finishTime**"
|
||||
blankLine
|
||||
|
||||
outputLine "#### Git 信息"
|
||||
|
||||
outputLine "* 触发 Tag: $TAG_NAME"
|
||||
|
||||
outputLine "* CommitId: ${GIT_COMMIT:0:7}"
|
||||
|
||||
outputLine "* 触发人: ${GIT_TAGGER_NAME}"
|
||||
|
||||
blankLine
|
||||
|
||||
|
||||
# 触发人: qishiyao
|
||||
subGroupPath=`echo $GIT_TAG_BUILD_GROUP | sed 's/\./\//'`
|
||||
|
||||
outputLine "#### 下载地址"
|
||||
outputLine "##### 开源版"
|
||||
outputFrame "[${PMS_VERSION} (中文)](${ARTIFACT_PROTOCOL}://${ARTIFACT_HOST}/service/rest/repository/browse/${ARTIFACT_REPOSITORY}/zentao/pmsPack/$subGroupPath/ZenTaoPMS/${PMS_VERSION}/)"
|
||||
outputFrame "\t\t"
|
||||
outputLine "[${PMS_VERSION} (English)](${ARTIFACT_PROTOCOL}://${ARTIFACT_HOST}/service/rest/repository/browse/${ARTIFACT_REPOSITORY}/zentao/pmsPack/$subGroupPath/ZenTaoALM/${PMS_VERSION}/)"
|
||||
|
||||
outputLine "##### 企业版"
|
||||
|
||||
outputFrame "[${BIZ_VERSION:3} (中文)](${ARTIFACT_PROTOCOL}://${ARTIFACT_HOST}/service/rest/repository/browse/${ARTIFACT_REPOSITORY}/zentao/bizPack/$subGroupPath/ZenTaoPMS/${BIZ_VERSION}/)"
|
||||
outputFrame "\t\t"
|
||||
outputLine "[${BIZ_VERSION:3} 升级包 (中文)](${ARTIFACT_PROTOCOL}://${ARTIFACT_HOST}/service/rest/repository/browse/${ARTIFACT_REPOSITORY}/zentao/bizPack/$subGroupPath/ZenTaoPMS.update/${BIZ_VERSION}/)"
|
||||
|
||||
outputFrame "[${BIZ_VERSION:3} (English)](${ARTIFACT_PROTOCOL}://${ARTIFACT_HOST}/service/rest/repository/browse/${ARTIFACT_REPOSITORY}/zentao/bizPack/$subGroupPath/ZenTaoALM/${BIZ_VERSION}/)"
|
||||
outputFrame "\t"
|
||||
outputLine "[${BIZ_VERSION:3} 升级包 (English)](${ARTIFACT_PROTOCOL}://${ARTIFACT_HOST}/service/rest/repository/browse/${ARTIFACT_REPOSITORY}/zentao/bizPack/$subGroupPath/ZenTaoALM.update/${BIZ_VERSION}/)"
|
||||
|
||||
outputLine "##### 旗舰版"
|
||||
|
||||
outputFrame "[${MAX_VERSION:3} (中文)](${ARTIFACT_PROTOCOL}://${ARTIFACT_HOST}/service/rest/repository/browse/${ARTIFACT_REPOSITORY}/zentao/maxPack/$subGroupPath/ZenTaoPMS/${MAX_VERSION}/)"
|
||||
outputFrame "\t\t"
|
||||
outputLine "[${MAX_VERSION:3} 升级包 (中文)](${ARTIFACT_PROTOCOL}://${ARTIFACT_HOST}/service/rest/repository/browse/${ARTIFACT_REPOSITORY}/zentao/maxPack/$subGroupPath/ZenTaoPMS.update/${MAX_VERSION}/)"
|
||||
|
||||
outputFrame "[${MAX_VERSION:3} (English)](${ARTIFACT_PROTOCOL}://${ARTIFACT_HOST}/service/rest/repository/browse/${ARTIFACT_REPOSITORY}/zentao/maxPack/$subGroupPath/ZenTaoALM/${MAX_VERSION}/)"
|
||||
outputFrame "\t"
|
||||
outputLine "[${MAX_VERSION:3} 升级包 (English)](${ARTIFACT_PROTOCOL}://${ARTIFACT_HOST}/service/rest/repository/browse/${ARTIFACT_REPOSITORY}/zentao/maxPack/$subGroupPath/ZenTaoALM.update/${MAX_VERSION}/)"
|
||||
|
||||
outputLine "##### 历史版本"
|
||||
outputLine "[查看历史版本](${ARTIFACT_PROTOCOL}://${ARTIFACT_HOST}/#browse/browse:easycorp-snapshot)"
|
||||
@@ -812,7 +812,7 @@ class actionModel extends model
|
||||
$trashQuery = $this->session->trashQuery;
|
||||
$trashQuery = str_replace(array('`objectID`', '`actor`', '`date`'), array('t1.`objectID`', 't1.`actor`', 't1.`date`'), $trashQuery);
|
||||
$table = $this->config->objectTables[$objectType];
|
||||
$nameField = isset($this->config->action->objectNameFields[$objectType]) ? 't2.' . "`{$this->config->action->objectNameFields[$objectType]}`" : '';
|
||||
$nameField = isset($this->config->action->objectNameFields[$objectType]) ? 't2.' . '`' . $this->config->action->objectNameFields[$objectType] . '`' : '';
|
||||
|
||||
if($nameField) $trashQuery = preg_replace("/`objectName`/", $nameField, $trashQuery);
|
||||
|
||||
@@ -1513,7 +1513,7 @@ class actionModel extends model
|
||||
elseif($objectType == 'stakeholder')
|
||||
{
|
||||
$objectName = $this->dao->select("t1.id, t2.realname")->from($table)->alias('t1')
|
||||
->leftJoin(TABLE_USER)->alias('t2')->on("t1.`{$field}` = t2.account")
|
||||
->leftJoin(TABLE_USER)->alias('t2')->on("t1.`$field` = t2.account")
|
||||
->where('t1.id')->in($objectIdList)
|
||||
->fetchPairs();
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
.side-col {width: 240px;}
|
||||
#sidebar> .cell {width: 220px;}
|
||||
|
||||
#data {overflow: scroll;}
|
||||
#datas {overflow: scroll;}
|
||||
#data th, #data td, #schema td, #modules li > strong {overflow: hidden; text-overflow: unset; white-space: nowrap;}
|
||||
#dataContent {margin: 0px; padding: 0px;}
|
||||
#dataContent .detail {margin: 0px; padding: 0px;}
|
||||
|
||||
@@ -17,6 +17,22 @@ $(function()
|
||||
if(dataview.used) result = confirm(warningDesign);
|
||||
if(result) window.location.href = url;
|
||||
});
|
||||
|
||||
initPager(pageID, recPerPage, recTotal, fieldCount);
|
||||
|
||||
$('.first-page,.left-page,.last-page,.right-page').click(function()
|
||||
{
|
||||
pageID = $(this).data('page');
|
||||
queryTableData();
|
||||
});
|
||||
|
||||
$('.dropup li a').click(function()
|
||||
{
|
||||
pageID = 1;
|
||||
recPerPage = $(this).data('size');
|
||||
queryTableData();
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -33,3 +49,118 @@ function locate(module, method, params)
|
||||
var link = createLink(module, method, params);
|
||||
window.location.href = link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query table data.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function queryTableData()
|
||||
{
|
||||
var params = {};
|
||||
params.pageID = pageID;
|
||||
params.recPerPage = recPerPage;
|
||||
params.recTotal = recTotal;
|
||||
params.table = table;
|
||||
params.type = type;
|
||||
$.post(createLink('dataview', 'ajaxGetTableData'), params,function(resp)
|
||||
{
|
||||
resp = JSON.parse(resp);
|
||||
buildTable(resp);
|
||||
|
||||
recTotal = resp.recTotal;
|
||||
fieldCount = resp.fieldCount;
|
||||
initPager(pageID, recPerPage, recTotal, fieldCount);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Build dataview data table.
|
||||
*
|
||||
* @param object resp
|
||||
* @return void
|
||||
*/
|
||||
function buildTable(resp)
|
||||
{
|
||||
var dataview = resp.dataview;
|
||||
var clientLang = resp.clientLang;
|
||||
var minWidth = resp.fieldCount * 100 + 'px';
|
||||
|
||||
var html = "<table class='table table-bordered' style='min-width:" + minWidth + "'>";
|
||||
html += "<thead><tr>";
|
||||
for(var field in resp.fields)
|
||||
{
|
||||
var fieldName = dataview?.fieldSettings?.[field]?.name ? dataview.fieldSettings[field].name : field;
|
||||
if(dataview?.langs)
|
||||
{
|
||||
var langs = JSON.parse(dataview.langs);
|
||||
if(langs) fieldName = langs?.[field]?.[clientLang] ? langs[field][clientLang] : fieldName;
|
||||
}
|
||||
|
||||
html += "<th>" + fieldName + "</th>";
|
||||
}
|
||||
html += "</tr></thead>";
|
||||
html += "<tbody>";
|
||||
|
||||
for(var index in resp.datas)
|
||||
{
|
||||
var data = resp.datas[index];
|
||||
|
||||
html += '<tr>';
|
||||
for(var field in resp.fields)
|
||||
{
|
||||
var tdValue = data?.[field] ? data[field] : 'null';
|
||||
html += "<td title='" + tdValue + "'>" + tdValue + "</td>";
|
||||
}
|
||||
html += '</tr>';
|
||||
}
|
||||
html += '</tbody>';
|
||||
html += '</table>';
|
||||
|
||||
$('#datas').empty();
|
||||
$('#datas').append(html);
|
||||
}
|
||||
|
||||
/**
|
||||
* Init pager.
|
||||
*
|
||||
* @param int pageID
|
||||
* @param int recPerPage
|
||||
* @param int recTotal
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function initPager(pageID, recPerPage, recTotal, fieldCount)
|
||||
{
|
||||
var pageID = parseInt(pageID);
|
||||
var recPerPage = parseInt(recPerPage);
|
||||
var recTotal = parseInt(recTotal);
|
||||
var pageTotal = parseInt(Math.ceil(recTotal / recPerPage));
|
||||
|
||||
$('.recTotal').html(recTotalTip.replace('%s', recTotal));
|
||||
$('.recPerPage').html(recPerPageTip.replace('%s', recPerPage));
|
||||
|
||||
$('.dropup li').removeClass('active');
|
||||
$('.dropup li a').each(function()
|
||||
{
|
||||
if($(this).data('size') == recPerPage)
|
||||
{
|
||||
$(this).parent().addClass('active');
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
$('.page-number').html('<strong>' + pageID + '</strong>/<strong>' + pageTotal + '</strong>');
|
||||
|
||||
$('.first-page').data('page', 1);
|
||||
$('.left-page').data('page', pageID - 1);
|
||||
$('.right-page').data('page', pageID + 1);
|
||||
$('.last-page').data('page', pageTotal);
|
||||
|
||||
$('.first-page,.left-page,.last-page,.right-page').removeClass('disabled');
|
||||
if(pageID == 1) $('.first-page,.left-page').addClass('disabled');
|
||||
if(pageID == pageTotal) $('.last-page,.right-page').addClass('disabled');
|
||||
|
||||
$('#queryResult').html(viewResult.replace('%s', recTotal).replace('%s', fieldCount));
|
||||
}
|
||||
|
||||
|
||||
@@ -140,6 +140,7 @@ function saveSettings()
|
||||
{
|
||||
var fieldSettings = DataStorage.clone('fieldSettings');
|
||||
var relatedObject = DataStorage.relatedObject;
|
||||
var objectFields = DataStorage.objectFields;
|
||||
for(let index in DataStorage.fields)
|
||||
{
|
||||
var relatedTable = $('#relatedTable' + index).val();
|
||||
@@ -147,7 +148,11 @@ function saveSettings()
|
||||
fieldSettings[index].object = relatedTable;
|
||||
fieldSettings[index].field = relatedField;
|
||||
|
||||
if(relatedTable != relatedObject[index]) fieldSettings[index].type = 'object';
|
||||
if(relatedTable != relatedObject[index])
|
||||
{
|
||||
fieldSettings[index].type = 'object';
|
||||
if(typeof(objectFields) != 'undefined' && typeof(objectFields[relatedTable]) != 'undefined' && typeof(objectFields[relatedTable][index]) != 'undefined') fieldSettings[index].type = objectFields[relatedTable][index].type == 'object' ? 'string' : objectFields[relatedTable][index].type;
|
||||
}
|
||||
if(relatedTable == relatedObject[index] && fieldSettings[index].type == 'object') fieldSettings[index].type = 'string';
|
||||
}
|
||||
|
||||
|
||||
@@ -158,6 +158,7 @@ $lang->dataview->error->warningDelete = 'The custom table has been referenced. D
|
||||
|
||||
$lang->dataview->querying = 'Querying, please wait...';
|
||||
$lang->dataview->queryResult = 'Query data in row %s x %s column';
|
||||
$lang->dataview->viewResult = '%s x %s rows of data';
|
||||
$lang->dataview->recTotalTip = '<strong> %s </strong> items in total';
|
||||
$lang->dataview->recPerPageTip = "<strong> %s </strong> items per page <span class='caret'></span>";
|
||||
|
||||
|
||||
@@ -158,6 +158,7 @@ $lang->dataview->error->warningDelete = 'The custom table has been referenced. D
|
||||
|
||||
$lang->dataview->querying = 'Querying, please wait...';
|
||||
$lang->dataview->queryResult = 'Query data in row %s x %s column';
|
||||
$lang->dataview->viewResult = '%s x %s rows of data';
|
||||
$lang->dataview->recTotalTip = '<strong> %s </strong> items in total';
|
||||
$lang->dataview->recPerPageTip = "<strong> %s </strong> items per page <span class='caret'></span>";
|
||||
|
||||
|
||||
@@ -158,6 +158,7 @@ $lang->dataview->error->warningDelete = 'The custom table has been referenced. D
|
||||
|
||||
$lang->dataview->querying = 'Querying, please wait...';
|
||||
$lang->dataview->queryResult = 'Query data in row %s x %s column';
|
||||
$lang->dataview->viewResult = '%s x %s rows of data';
|
||||
$lang->dataview->recTotalTip = '<strong> %s </strong> items in total';
|
||||
$lang->dataview->recPerPageTip = "<strong> %s </strong> items per page <span class='caret'></span>";
|
||||
|
||||
|
||||
@@ -158,6 +158,7 @@ $lang->dataview->error->warningDelete = '中间表已被引用,删除会导致
|
||||
|
||||
$lang->dataview->querying = '正在查询,请稍后...';
|
||||
$lang->dataview->queryResult = '查询到 %s行 x %s列数据';
|
||||
$lang->dataview->viewResult = '共 %s行 x %s列数据';
|
||||
$lang->dataview->recTotalTip = '共 <strong> %s </strong> 项';
|
||||
$lang->dataview->recPerPageTip = "每页 <strong> %s </strong> 项 <span class='caret'></span>";
|
||||
|
||||
|
||||
@@ -61,16 +61,52 @@ class dataviewModel extends model
|
||||
return $moduleNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get alias names.
|
||||
*
|
||||
* @param object $statement
|
||||
* @param array $moduleNames
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getAliasNames($statement, $moduleNames)
|
||||
{
|
||||
$aliasNames = array();
|
||||
if(isset($statement->from))
|
||||
{
|
||||
foreach($statement->from as $from)
|
||||
{
|
||||
if(isset($moduleNames[$from->table]))
|
||||
{
|
||||
$aliasNames[$from->alias] = $from->table;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(isset($statement->join))
|
||||
{
|
||||
foreach($statement->join as $join)
|
||||
{
|
||||
if(isset($moduleNames[$join->expr->table]))
|
||||
{
|
||||
$aliasNames[$join->expr->alias] = $join->expr->table;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $aliasNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge fields.
|
||||
*
|
||||
* @param int $dataFields
|
||||
* @param int $sqlFields
|
||||
* @param int $moduleNames
|
||||
* @param array $dataFields
|
||||
* @param array $sqlFields
|
||||
* @param array $moduleNames
|
||||
* @param array $aliasNames
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function mergeFields($dataFields, $sqlFields, $moduleNames)
|
||||
public function mergeFields($dataFields, $sqlFields, $moduleNames, $aliasNames = array())
|
||||
{
|
||||
$mergeFields = array();
|
||||
$relatedObject = array();
|
||||
@@ -94,6 +130,14 @@ class dataviewModel extends model
|
||||
$relatedObject[$field] = $moduleName;
|
||||
continue;
|
||||
}
|
||||
elseif(isset($aliasNames[$table]))
|
||||
{
|
||||
$moduleName = $aliasNames[$table];
|
||||
if(strpos($moduleName, 'flow_') !== false) $moduleName = substr($moduleName, 5);
|
||||
$mergeFields[$field] = isset($this->lang->$moduleName->$fieldName) ? $this->lang->$moduleName->$fieldName : $field;
|
||||
$relatedObject[$field] = $moduleName;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(strpos(join(',', $sqlFields), '.*') !== false)
|
||||
|
||||
@@ -12,8 +12,18 @@
|
||||
?>
|
||||
<?php include $app->getModuleRoot() . 'common/view/header.html.php';?>
|
||||
<?php js::set('table', $selectedTable);?>
|
||||
<?php js::set('type', $type);?>
|
||||
<?php js::set('dataview', $dataview);?>
|
||||
<?php js::set('fieldCount', count($fields));?>
|
||||
<?php js::set('warningDesign', $lang->dataview->error->warningDesign);?>
|
||||
<?php js::set('viewResult', $lang->dataview->viewResult);?>
|
||||
|
||||
<?php js::set('pageID', $pageID);?>
|
||||
<?php js::set('recPerPage', $recPerPage);?>
|
||||
<?php js::set('recTotal', $recTotal);?>
|
||||
<?php js::set('recTotalTip', $lang->dataview->recTotalTip);?>
|
||||
<?php js::set('recPerPageTip', $lang->dataview->recPerPageTip);?>
|
||||
|
||||
<div id='mainMenu' class='clearfix'>
|
||||
<div class='btn-toolbar pull-left'><?php // common::printAdminSubMenu('dev');?></div>
|
||||
<div class="btn-toolbar pull-right">
|
||||
@@ -83,32 +93,77 @@
|
||||
<div class='tab-content '>
|
||||
<div class='tab-pane active' id='data'>
|
||||
<?php if(!empty($fields)):?>
|
||||
<table class="table table-bordered" style="min-width: <?php echo count($fields)*100;?>px">
|
||||
<thead>
|
||||
<tr>
|
||||
<?php foreach($fields as $key => $field):?>
|
||||
<?php
|
||||
$fieldName = isset($dataview->fieldSettings->$key->name) ? $dataview->fieldSettings->$key->name : $key;
|
||||
if(!empty($dataview->langs))
|
||||
{
|
||||
$langs = json_decode($dataview->langs, true);
|
||||
if(!empty($langs)) $fieldName = $langs[$key][$clientLang] ? $langs[$key][$clientLang] : $fieldName;
|
||||
}
|
||||
?>
|
||||
<th><?php echo $fieldName;?></th>
|
||||
<?php endforeach;?>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<div id='datas'>
|
||||
<table class="table table-bordered" style="min-width: <?php echo count($fields)*100;?>px">
|
||||
<thead>
|
||||
<tr>
|
||||
<?php foreach($fields as $key => $field):?>
|
||||
<?php
|
||||
$fieldName = isset($dataview->fieldSettings->$key->name) ? $dataview->fieldSettings->$key->name : $key;
|
||||
if(!empty($dataview->langs))
|
||||
{
|
||||
$langs = json_decode($dataview->langs, true);
|
||||
if(!empty($langs)) $fieldName = $langs[$key][$clientLang] ? $langs[$key][$clientLang] : $fieldName;
|
||||
}
|
||||
?>
|
||||
<th><?php echo $fieldName;?></th>
|
||||
<?php endforeach;?>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach($data as $value):?>
|
||||
<?php echo '<tr>';?>
|
||||
<?php foreach($fields as $key => $field):?>
|
||||
<td title='<?php echo isset($value->$key) ? $value->$key : 'null';?>'><?php echo isset($value->$key) ? $value->$key : 'null';?></td>
|
||||
<?php $tdValue = isset($value->$key) ? $value->$key : 'null';?>
|
||||
<td title='<?php echo $tdValue;?>'><?php echo $tdValue;?></td>
|
||||
<?php endforeach;?>
|
||||
<?php echo '</tr>';?>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
</table>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class='table-footer'>
|
||||
<ul class="pager">
|
||||
<li><div class="pager-label recTotal"></div></li>
|
||||
<li>
|
||||
<div class="btn-group pager-size-menu dropup">
|
||||
<button type="button" class="btn dropdown-toggle recPerPage" data-toggle="dropdown" style="border-radius: 4px;"></button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="javascript:;" data-size="5">5</a></li>
|
||||
<li><a href="javascript:;" data-size="10">10</a></li>
|
||||
<li><a href="javascript:;" data-size="15">15</a></li>
|
||||
<li><a href="javascript:;" data-size="20">20</a></li>
|
||||
<li><a href="javascript:;" data-size="25">25</a></li>
|
||||
<li><a href="javascript:;" data-size="30">30</a></li>
|
||||
<li><a href="javascript:;" data-size="35">35</a></li>
|
||||
<li><a href="javascript:;" data-size="40">40</a></li>
|
||||
<li><a href="javascript:;" data-size="45">45</a></li>
|
||||
<li><a href="javascript:;" data-size="50">50</a></li>
|
||||
<li><a href="javascript:;" data-size="100">100</a></li>
|
||||
<li><a href="javascript:;" data-size="200">200</a></li>
|
||||
<li><a href="javascript:;" data-size="500">500</a></li>
|
||||
<li><a href="javascript:;" data-size="1000">1000</a></li>
|
||||
<li><a href="javascript:;" data-size="2000">2000</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
<li class='pager-item-left first-page'>
|
||||
<a class='pager-item' data-page='1' href='javascript:;'><i class='icon icon-first-page'></i></a>
|
||||
</li>
|
||||
<li class='pager-item-left left-page'>
|
||||
<a class='pager-item' data-page='1' href='javascript:;'><i class='icon icon-angle-left'></i></a>
|
||||
</li>
|
||||
<li><div class='pager-label page-number'></div></li>
|
||||
<li class='pager-item-right right-page'>
|
||||
<a class='pager-item' data-page='1' href='javascript:;'><i class='icon icon-angle-right'></i></a>
|
||||
</li>
|
||||
<li class='pager-item-right last-page'>
|
||||
<a class='pager-item' data-page='1' href='javascript:;'><i class='icon icon-last-page'></i></a>
|
||||
</li>
|
||||
</ul>
|
||||
<span style="float:left;line-height:28px" id="queryResult"></span>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
<div class='tab-pane' id='schema'>
|
||||
|
||||
@@ -72,7 +72,14 @@ class pivot extends control
|
||||
$processSqlData = $this->loadModel('chart')->getTables($sql);
|
||||
$sql = $processSqlData['sql'];
|
||||
|
||||
list($data, $configs) = $this->pivot->genSheet(json_decode(json_encode($pivot->fieldSettings), true), $pivot->settings, $sql, $filterFormat, json_decode($pivot->langs, true));
|
||||
if(isset($pivot->settings['summary']) and $pivot->settings['summary'] =='notuse')
|
||||
{
|
||||
list($data, $configs) = $this->pivot->genOriginSheet(json_decode(json_encode($pivot->fieldSettings), true), $pivot->settings, $sql, $filterFormat, json_decode($pivot->langs, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
list($data, $configs) = $this->pivot->genSheet(json_decode(json_encode($pivot->fieldSettings), true), $pivot->settings, $sql, $filterFormat, json_decode($pivot->langs, true));
|
||||
}
|
||||
$this->view->data = $data;
|
||||
$this->view->configs = $configs;
|
||||
}
|
||||
@@ -298,7 +305,14 @@ class pivot extends control
|
||||
$processSqlData = $this->loadModel('chart')->getTables($sql);
|
||||
$sql = $processSqlData['sql'];
|
||||
|
||||
list($data, $configs) = $this->pivot->genSheet($fields, $settings, $sql, $filterFormat, $langs);
|
||||
if(isset($settings['summary']) and $settings['summary'] == 'notuse')
|
||||
{
|
||||
list($data, $configs) = $this->pivot->genOriginSheet($fields, $settings, $sql, $filterFormat, $langs);
|
||||
}
|
||||
else
|
||||
{
|
||||
list($data, $configs) = $this->pivot->genSheet($fields, $settings, $sql, $filterFormat, $langs);
|
||||
}
|
||||
|
||||
$this->pivot->buildPivotTable($data, $configs, $fields, $sql);
|
||||
}
|
||||
|
||||
@@ -5,10 +5,11 @@
|
||||
.parent-position {padding-right: 160px;}
|
||||
.datagrid {overflow: auto;}
|
||||
.heading-padding, .datagrid-padding {padding-left: 6px; padding-right: 6px;}
|
||||
.datagrid-padding {padding-top: 2px;}
|
||||
|
||||
.filter-items > .table-row{display: table!important;}
|
||||
.filter-items .filter-item:first-child {padding-left: 0!important;}
|
||||
.filterBox {display: flex; margin-bottom: 20px; margin-left: 6px; margin-right: 6px;}
|
||||
.filterBox {display: flex; margin-bottom: 5px; margin-left: 6px; margin-right: 6px; margin-top: 8px;}
|
||||
.filter-items {display: flex; flex: 1; flex-wrap: wrap;}
|
||||
.filter-item {padding: 0 16px 5px 0;}
|
||||
.filter-item-grow {flex-grow: 1;}
|
||||
@@ -17,3 +18,15 @@
|
||||
#filterItems .picker-selections {overflow: hidden; text-overflow: clip; white-space: nowrap;}
|
||||
|
||||
#filterItems .picker .picker-selections {width: auto !important;}
|
||||
.content-border {padding-top: 16px; padding-bottom: 16px; border-bottom: 1px solid #F1F5F9;}
|
||||
.flex-between {display:flex; justify-content: space-between;}
|
||||
.flex-start {display:flex; justify-content: flex-start;}
|
||||
|
||||
.query-after {padding-right: 8px; padding-top: 1px;}
|
||||
.query-pseudo {position: relative; padding-right: 24px; padding-top: 1px;}
|
||||
.query-pseudo::after {content: ""; position: absolute; top: 0; right: 0; bottom: 0; width: 1px; background-color: #F1F5F9;}
|
||||
|
||||
#filterMargin {padding-top: 8px; padding-bottom: 5px;}
|
||||
.pivot-design {padding-left: 24px; padding-right: 12px;}
|
||||
.pivot-edit {padding-left: 12px; padding-right: 12px;}
|
||||
.pivot-delete {padding-left: 12px; padding-right: 8px;}
|
||||
|
||||
@@ -139,10 +139,15 @@ function checkFormSetting()
|
||||
*/
|
||||
function validate(showError = false)
|
||||
{
|
||||
var pivot = DataStorage.pivot;
|
||||
var pivot = DataStorage.pivot;
|
||||
var formSettings = pivot.settings;
|
||||
/* Code for temporary */
|
||||
var isReady = true;
|
||||
var isReady = true;
|
||||
|
||||
if("summary" in formSettings && formSettings.summary == 'notuse')
|
||||
{
|
||||
if(isReady) $('#datagrid-tip').addClass('hidden');
|
||||
return true;
|
||||
}
|
||||
|
||||
/* check group settings. */
|
||||
var exist = false;
|
||||
|
||||
+58
-17
@@ -5,6 +5,7 @@ $(function()
|
||||
expandTree();
|
||||
renderFilters(pivot);
|
||||
initQueryBtn();
|
||||
initOriginQueryBtn();
|
||||
|
||||
$('body').resize(() => {calcPreviewGrowFilter();});
|
||||
|
||||
@@ -20,17 +21,14 @@ function expandTree()
|
||||
tree.expand($('.pivot-' + pivotID).parents('li'));
|
||||
}
|
||||
|
||||
/*$('.btn-export').click(function()
|
||||
{
|
||||
if(typeof pivotID == 'undefined' || !pivotID) return;
|
||||
pivot = getQueryInfo();
|
||||
});
|
||||
*/
|
||||
|
||||
function getQueryInfo()
|
||||
{
|
||||
var pivotInfo = pivot;
|
||||
// if not use JSON.parse(JSON.stringify()), edit pivotInfo also affects pivot. If click btn-query-origin, pivot setting also have summary field.
|
||||
var pivotInfo = JSON.parse(JSON.stringify(pivot));
|
||||
pivotInfo.searchFilters = JSON.parse(JSON.stringify(pivotInfo.filters));
|
||||
pivotInfo.step = 4;
|
||||
|
||||
if(!pivotInfo.searchFilters) return pivotInfo;
|
||||
|
||||
if(isQueryFilter(pivotInfo.filters))
|
||||
{
|
||||
@@ -70,7 +68,6 @@ function getQueryInfo()
|
||||
});
|
||||
}
|
||||
|
||||
pivotInfo.step = 4;
|
||||
return pivotInfo;
|
||||
}
|
||||
|
||||
@@ -84,17 +81,55 @@ function initQueryBtn()
|
||||
{
|
||||
$('.btn-query').click(function()
|
||||
{
|
||||
pivotInfo = getQueryInfo();
|
||||
$.post(createLink('pivot', 'ajaxGetPivot'), pivotInfo,function(resp)
|
||||
{
|
||||
var myDatagrid = $('#datagirdInfo');
|
||||
myDatagrid.find('.reportData').remove();
|
||||
myDatagrid.append(resp);
|
||||
});
|
||||
|
||||
var pivotInfo = getQueryInfo();
|
||||
refreshPivot(pivotInfo);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Init origin query button.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function initOriginQueryBtn()
|
||||
{
|
||||
$('.btn-query-origin').click(function()
|
||||
{
|
||||
var pivotInfo = getQueryInfo();
|
||||
pivotInfo.settings['summary'] = 'notuse';
|
||||
refreshPivot(pivotInfo, true);
|
||||
});
|
||||
}
|
||||
|
||||
function refreshPivot(pivotInfo, isOrigin = false)
|
||||
{
|
||||
$.post(createLink('pivot', 'ajaxGetPivot'), pivotInfo,function(resp)
|
||||
{
|
||||
var myDatagrid = $('#datagirdInfo');
|
||||
myDatagrid.find('.reportData').remove();
|
||||
myDatagrid.append(resp);
|
||||
|
||||
if(isOrigin)
|
||||
{
|
||||
$('#filterItems').addClass('hidden');
|
||||
$('#filterMargin').removeClass('hidden');
|
||||
|
||||
$('#pivot-query').removeClass('hidden');
|
||||
$('#origin-query').addClass('hidden');
|
||||
}
|
||||
else
|
||||
{
|
||||
$('#filterItems').removeClass('hidden');
|
||||
$('#filterMargin').addClass('hidden');
|
||||
|
||||
$('#pivot-query').addClass('hidden');
|
||||
$('#origin-query').removeClass('hidden');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function calcPreviewGrowFilter()
|
||||
{
|
||||
if(pivot.filters.length <= 0) return;
|
||||
@@ -280,3 +315,9 @@ function isQueryFilter(filters)
|
||||
{
|
||||
return filters.length > 0 && filters[0].from == 'query';
|
||||
}
|
||||
|
||||
function locate(module, method, params)
|
||||
{
|
||||
var link = createLink(module, method, params);
|
||||
window.location.href = link;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ $lang->pivot->design = 'Design pivot';
|
||||
$lang->pivot->export = 'Export pivot';
|
||||
$lang->pivot->query = 'Query';
|
||||
$lang->pivot->browseAction = 'Design in Pivot Table';
|
||||
$lang->pivot->designAB = 'Design';
|
||||
|
||||
$lang->pivot->id = 'ID';
|
||||
$lang->pivot->name = 'Name';
|
||||
@@ -71,6 +72,8 @@ $lang->pivot->percent = '%';
|
||||
$lang->pivot->undefined = 'Undefiniert';
|
||||
$lang->pivot->project = $lang->projectCommon;
|
||||
$lang->pivot->PO = 'PO';
|
||||
$lang->pivot->showPivot = 'Show Pivot';
|
||||
$lang->pivot->showOrigin = 'Show Origin Data';
|
||||
|
||||
$lang->pivot->colors[] = 'AFD8F8';
|
||||
$lang->pivot->colors[] = 'AFD8F8';
|
||||
@@ -261,7 +264,7 @@ $lang->pivot->noChartSelected = 'Please select one pivot.';
|
||||
$lang->pivot->beginGtEnd = 'Begin time should not be >= end time.';
|
||||
$lang->pivot->resetSettings = 'The configuration of the query data has been modified, requiring redesign of the pivot, whether to continue.';
|
||||
$lang->pivot->clearSettings = 'The configuration of the query data has been modified, whether to clear the pivot and save.';
|
||||
$lang->pivot->draftSave = 'Released content is edited, will be overwritten, whether to continue?';
|
||||
$lang->pivot->draftSave = 'The pivot table has been published and will be in draft state. Do you want to continue?';
|
||||
$lang->pivot->cannotAddQuery = 'Result filter has been added, query filter cannot be added.';
|
||||
$lang->pivot->cannotAddResult = 'Query filter has been added, result filter cannot be added.';
|
||||
|
||||
@@ -332,6 +335,7 @@ $lang->pivot->typeOptions['dept'] = 'Dept';
|
||||
|
||||
$lang->pivot->step2 = new stdclass();
|
||||
$lang->pivot->step2->group = 'Row Grouping';
|
||||
$lang->pivot->step2->summary = 'Summary Setting';
|
||||
$lang->pivot->step2->column = 'Column Settings';
|
||||
$lang->pivot->step2->groupTip = 'Select Field';
|
||||
$lang->pivot->step2->groupNum = array('One', 'Two', 'Three');
|
||||
@@ -344,6 +348,7 @@ $lang->pivot->step2->columnField = 'Field';
|
||||
$lang->pivot->step2->calcMode = 'Calc Mode';
|
||||
|
||||
$lang->pivot->step2->moreThanOne = 'Select at least one group field.';
|
||||
$lang->pivot->step2->summaryTip = 'After this parameter is selected, you can configure Row Grouping, Column Settings, and Show column totals';
|
||||
$lang->pivot->step2->groupsTip = 'By selecting a grouping field, the data of the SQL query is grouped and displayed hierarchically in the pivot table.';
|
||||
$lang->pivot->step2->columnsTip = 'Add 1 column to the pivot table and set it.';
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ $lang->pivot->design = 'Design pivot';
|
||||
$lang->pivot->export = 'Export pivot';
|
||||
$lang->pivot->query = 'Query';
|
||||
$lang->pivot->browseAction = 'Design in Pivot Table';
|
||||
$lang->pivot->designAB = 'Design';
|
||||
|
||||
$lang->pivot->id = 'ID';
|
||||
$lang->pivot->name = 'Name';
|
||||
@@ -71,6 +72,8 @@ $lang->pivot->percent = '%';
|
||||
$lang->pivot->undefined = 'Undefiniert';
|
||||
$lang->pivot->project = $lang->projectCommon;
|
||||
$lang->pivot->PO = 'PO';
|
||||
$lang->pivot->showPivot = 'Show Pivot';
|
||||
$lang->pivot->showOrigin = 'Show Origin Data';
|
||||
|
||||
$lang->pivot->colors[] = 'AFD8F8';
|
||||
$lang->pivot->colors[] = 'AFD8F8';
|
||||
@@ -261,7 +264,7 @@ $lang->pivot->noChartSelected = 'Please select one pivot.';
|
||||
$lang->pivot->beginGtEnd = 'Begin time should not be >= end time.';
|
||||
$lang->pivot->resetSettings = 'The configuration of the query data has been modified, requiring redesign of the pivot, whether to continue.';
|
||||
$lang->pivot->clearSettings = 'The configuration of the query data has been modified, whether to clear the pivot and save.';
|
||||
$lang->pivot->draftSave = 'Released content is edited, will be overwritten, whether to continue?';
|
||||
$lang->pivot->draftSave = 'The pivot table has been published and will be in draft state. Do you want to continue?';
|
||||
$lang->pivot->cannotAddQuery = 'Result filter has been added, query filter cannot be added.';
|
||||
$lang->pivot->cannotAddResult = 'Query filter has been added, result filter cannot be added.';
|
||||
|
||||
@@ -332,6 +335,7 @@ $lang->pivot->typeOptions['dept'] = 'Dept';
|
||||
|
||||
$lang->pivot->step2 = new stdclass();
|
||||
$lang->pivot->step2->group = 'Row Grouping';
|
||||
$lang->pivot->step2->summary = 'Summary Setting';
|
||||
$lang->pivot->step2->column = 'Column Settings';
|
||||
$lang->pivot->step2->groupTip = 'Select Field';
|
||||
$lang->pivot->step2->groupNum = array('One', 'Two', 'Three');
|
||||
@@ -344,6 +348,7 @@ $lang->pivot->step2->columnField = 'Field';
|
||||
$lang->pivot->step2->calcMode = 'Calc Mode';
|
||||
|
||||
$lang->pivot->step2->moreThanOne = 'Select at least one group field.';
|
||||
$lang->pivot->step2->summaryTip = 'After this parameter is selected, you can configure Row Grouping, Column Settings, and Show column totals';
|
||||
$lang->pivot->step2->groupsTip = 'By selecting a grouping field, the data of the SQL query is grouped and displayed hierarchically in the pivot table.';
|
||||
$lang->pivot->step2->columnsTip = 'Add 1 column to the pivot table and set it.';
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ $lang->pivot->design = 'Design pivot';
|
||||
$lang->pivot->export = 'Export pivot';
|
||||
$lang->pivot->query = 'Query';
|
||||
$lang->pivot->browseAction = 'Design in Pivot Table';
|
||||
$lang->pivot->designAB = 'Design';
|
||||
|
||||
$lang->pivot->id = 'ID';
|
||||
$lang->pivot->name = 'Name';
|
||||
@@ -71,6 +72,8 @@ $lang->pivot->percent = '%';
|
||||
$lang->pivot->undefined = 'Undefiniert';
|
||||
$lang->pivot->project = $lang->projectCommon;
|
||||
$lang->pivot->PO = 'PO';
|
||||
$lang->pivot->showPivot = 'Show Pivot';
|
||||
$lang->pivot->showOrigin = 'Show Origin Data';
|
||||
|
||||
$lang->pivot->colors[] = 'AFD8F8';
|
||||
$lang->pivot->colors[] = 'AFD8F8';
|
||||
@@ -261,7 +264,7 @@ $lang->pivot->noChartSelected = 'Please select one pivot.';
|
||||
$lang->pivot->beginGtEnd = 'Begin time should not be >= end time.';
|
||||
$lang->pivot->resetSettings = 'The configuration of the query data has been modified, requiring redesign of the pivot, whether to continue.';
|
||||
$lang->pivot->clearSettings = 'The configuration of the query data has been modified, whether to clear the pivot and save.';
|
||||
$lang->pivot->draftSave = 'Released content is edited, will be overwritten, whether to continue?';
|
||||
$lang->pivot->draftSave = 'The pivot table has been published and will be in draft state. Do you want to continue?';
|
||||
$lang->pivot->cannotAddQuery = 'Result filter has been added, query filter cannot be added.';
|
||||
$lang->pivot->cannotAddResult = 'Query filter has been added, result filter cannot be added.';
|
||||
|
||||
@@ -332,6 +335,7 @@ $lang->pivot->typeOptions['dept'] = 'Dept';
|
||||
|
||||
$lang->pivot->step2 = new stdclass();
|
||||
$lang->pivot->step2->group = 'Row Grouping';
|
||||
$lang->pivot->step2->summary = 'Summary Setting';
|
||||
$lang->pivot->step2->column = 'Column Settings';
|
||||
$lang->pivot->step2->groupTip = 'Select Field';
|
||||
$lang->pivot->step2->groupNum = array('One', 'Two', 'Three');
|
||||
@@ -344,6 +348,7 @@ $lang->pivot->step2->columnField = 'Field';
|
||||
$lang->pivot->step2->calcMode = 'Calc Mode';
|
||||
|
||||
$lang->pivot->step2->moreThanOne = 'Select at least one group field.';
|
||||
$lang->pivot->step2->summaryTip = 'After this parameter is selected, you can configure Row Grouping, Column Settings, and Show column totals';
|
||||
$lang->pivot->step2->groupsTip = 'By selecting a grouping field, the data of the SQL query is grouped and displayed hierarchically in the pivot table.';
|
||||
$lang->pivot->step2->columnsTip = 'Add 1 column to the pivot table and set it.';
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ $lang->pivot->design = 'Design pivot';
|
||||
$lang->pivot->export = 'Export pivot';
|
||||
$lang->pivot->query = 'Query';
|
||||
$lang->pivot->browseAction = 'Design in Pivot Table';
|
||||
$lang->pivot->designAB = 'Design';
|
||||
|
||||
$lang->pivot->id = 'ID';
|
||||
$lang->pivot->name = 'Name';
|
||||
@@ -61,6 +62,8 @@ $lang->pivot->percent = '%';
|
||||
$lang->pivot->undefined = 'Undefiniert';
|
||||
$lang->pivot->project = $lang->projectCommon;
|
||||
$lang->pivot->PO = 'PO';
|
||||
$lang->pivot->showPivot = 'Show Pivot';
|
||||
$lang->pivot->showOrigin = 'Show Origin Data';
|
||||
|
||||
$lang->pivot->colors[] = 'AFD8F8';
|
||||
$lang->pivot->colors[] = 'AFD8F8';
|
||||
@@ -251,7 +254,7 @@ $lang->pivot->noChartSelected = 'Please select one pivot.';
|
||||
$lang->pivot->beginGtEnd = 'Begin time should not be >= end time.';
|
||||
$lang->pivot->resetSettings = 'The configuration of the query data has been modified, requiring redesign of the pivot, whether to continue.';
|
||||
$lang->pivot->clearSettings = 'The configuration of the query data has been modified, whether to clear the pivot and save.';
|
||||
$lang->pivot->draftSave = 'Released content is edited, will be overwritten, whether to continue?';
|
||||
$lang->pivot->draftSave = 'The pivot table has been published and will be in draft state. Do you want to continue?';
|
||||
$lang->pivot->cannotAddQuery = 'Result filter has been added, query filter cannot be added.';
|
||||
$lang->pivot->cannotAddResult = 'Query filter has been added, result filter cannot be added.';
|
||||
|
||||
@@ -322,6 +325,7 @@ $lang->pivot->typeOptions['dept'] = 'Dept';
|
||||
|
||||
$lang->pivot->step2 = new stdclass();
|
||||
$lang->pivot->step2->group = 'Row Grouping';
|
||||
$lang->pivot->step2->summary = 'Summary Setting';
|
||||
$lang->pivot->step2->column = 'Column Settings';
|
||||
$lang->pivot->step2->groupTip = 'Select Field';
|
||||
$lang->pivot->step2->groupNum = array('One', 'Two', 'Three');
|
||||
@@ -334,6 +338,7 @@ $lang->pivot->step2->columnField = 'Field';
|
||||
$lang->pivot->step2->calcMode = 'Calc Mode';
|
||||
|
||||
$lang->pivot->step2->moreThanOne = 'Select at least one group field.';
|
||||
$lang->pivot->step2->summaryTip = 'After this parameter is selected, you can configure Row Grouping, Column Settings, and Show column totals';
|
||||
$lang->pivot->step2->groupsTip = 'By selecting a grouping field, the data of the SQL query is grouped and displayed hierarchically in the pivot table.';
|
||||
$lang->pivot->step2->columnsTip = 'Add 1 column to the pivot table and set it.';
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ $lang->pivot->design = '设计透视表';
|
||||
$lang->pivot->export = '导出透视表';
|
||||
$lang->pivot->query = '查询';
|
||||
$lang->pivot->browseAction = '进入透视表设计';
|
||||
$lang->pivot->designAB = '设计';
|
||||
|
||||
$lang->pivot->id = 'ID';
|
||||
$lang->pivot->name = '名称';
|
||||
@@ -71,6 +72,8 @@ $lang->pivot->percent = '百分比';
|
||||
$lang->pivot->undefined = '未设定';
|
||||
$lang->pivot->project = $lang->projectCommon;
|
||||
$lang->pivot->PO = 'PO';
|
||||
$lang->pivot->showPivot = '查看透视表';
|
||||
$lang->pivot->showOrigin = '查看原始数据';
|
||||
|
||||
$lang->pivot->colors[] = 'AFD8F8';
|
||||
$lang->pivot->colors[] = 'F6BD0F';
|
||||
@@ -261,7 +264,7 @@ $lang->pivot->noChartSelected = '请选择至少一个图表。';
|
||||
$lang->pivot->beginGtEnd = '开始时间不得大于结束时间。';
|
||||
$lang->pivot->resetSettings = '查询数据的配置已修改,是否清空透视表设计,并重新设计。';
|
||||
$lang->pivot->clearSettings = '查询数据的配置已修改,是否清空透视表设计并保存。';
|
||||
$lang->pivot->draftSave = '已发布的内容被编辑,将覆盖,是否继续?';
|
||||
$lang->pivot->draftSave = '该透视表已发布,将变为草稿态,是否继续?';
|
||||
$lang->pivot->cannotAddQuery = '已添加结果筛选器,无法添加查询筛选器';
|
||||
$lang->pivot->cannotAddResult = '已添加查询筛选器,无法添加结果筛选器';
|
||||
|
||||
@@ -332,6 +335,7 @@ $lang->pivot->typeOptions['dept'] = '部门';
|
||||
|
||||
$lang->pivot->step2 = new stdclass();
|
||||
$lang->pivot->step2->group = '行分组';
|
||||
$lang->pivot->step2->summary = '汇总设置';
|
||||
$lang->pivot->step2->column = '列设置';
|
||||
$lang->pivot->step2->groupTip = '选择字段';
|
||||
$lang->pivot->step2->groupNum = array('一', '二', '三');
|
||||
@@ -344,6 +348,7 @@ $lang->pivot->step2->columnField = '字段';
|
||||
$lang->pivot->step2->calcMode = '计算方式';
|
||||
|
||||
$lang->pivot->step2->moreThanOne = '至少选择一个分组字段。';
|
||||
$lang->pivot->step2->summaryTip = '勾选后,可配置行分组、列设置、显示列的汇总。';
|
||||
$lang->pivot->step2->groupsTip = '通过选择分组字段,对SQL查询的数据进行分组,并分层级显示在透视表中。';
|
||||
$lang->pivot->step2->columnsTip = '在透视表中添加1列并对其进行设置。';
|
||||
|
||||
|
||||
+72
-2
@@ -2162,8 +2162,7 @@ class pivotModel extends model
|
||||
*/
|
||||
public function buildPivotTable($data, $configs, $fields = array(), $sql = '')
|
||||
{
|
||||
$clientLang = $this->app->getClientLang();
|
||||
$width = 128;
|
||||
$width = 128;
|
||||
|
||||
/* Init table. */
|
||||
$table = "<table class='reportData table table-condensed table-striped table-bordered table-fixed datatable' style='width: auto; min-width: 100%' data-fixed-left-width='400'>";
|
||||
@@ -2259,6 +2258,77 @@ class pivotModel extends model
|
||||
return $sql;
|
||||
}
|
||||
|
||||
/**
|
||||
* replace defined table names.
|
||||
*
|
||||
* @param string $sql
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function genOriginSheet($fields, $settings, $sql, $filters, $langs = array())
|
||||
{
|
||||
$sql = $this->initVarFilter($filters, $sql);
|
||||
|
||||
/* Create sql. */
|
||||
$sql = str_replace(';', '', $sql);
|
||||
|
||||
if(preg_match_all("/[\$]+[a-zA-Z0-9]+/", $sql, $out))
|
||||
{
|
||||
foreach($out[0] as $match) $sql = str_replace($match, "''", $sql);
|
||||
}
|
||||
|
||||
/* Process rows. */
|
||||
$connectSQL = '';
|
||||
if(!empty($filters) && !isset($filters[0]['from']))
|
||||
{
|
||||
$wheres = array();
|
||||
foreach($filters as $field => $filter)
|
||||
{
|
||||
$wheres[] = "tt.`$field` {$filter['operator']} {$filter['value']}";
|
||||
}
|
||||
|
||||
$whereStr = implode(' and ', $wheres);
|
||||
$connectSQL .= " where $whereStr";
|
||||
}
|
||||
|
||||
$columnSQL = "select * from ($sql) tt" . $connectSQL;
|
||||
$rows = $this->dao->query($columnSQL)->fetchAll();
|
||||
|
||||
$cols = array();
|
||||
$clientLang = $this->app->getClientLang();
|
||||
/* Build cols. */
|
||||
foreach($fields as $field)
|
||||
{
|
||||
$key = $field['field'];
|
||||
|
||||
$col = new stdclass();
|
||||
$col->name = $key;
|
||||
$col->isGroup = true;
|
||||
|
||||
$fieldObject = $field['object'];
|
||||
$relatedField = $field['field'];
|
||||
|
||||
$colLabel = $key;
|
||||
if($fieldObject)
|
||||
{
|
||||
$this->app->loadLang($fieldObject);
|
||||
if(isset($this->lang->$fieldObject->$relatedField)) $colLabel = $this->lang->$fieldObject->$relatedField;
|
||||
}
|
||||
|
||||
if(isset($langs[$key]) and !empty($langs[$key][$clientLang])) $colLabel = $langs[$key][$clientLang];
|
||||
$col->label = $colLabel;
|
||||
|
||||
$cols[0][] = $col;
|
||||
}
|
||||
|
||||
$data = new stdclass();
|
||||
$data->cols = $cols;
|
||||
$data->array = json_decode(json_encode($rows), true);
|
||||
|
||||
$configs = array_fill(0, count($rows), array_fill(0, count($fields), 1));
|
||||
|
||||
return array($data, $configs);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
<?php js::set('WIDTH_DATE', $config->pivot->widthDate);?>
|
||||
<?php js::set('pickerHeight', $config->bi->pickerHeight);?>
|
||||
<?php js::set('datepickerText', $this->lang->datepicker->dpText);?>
|
||||
<?php js::set('confirmDesign', $lang->pivot->confirm->design);?>
|
||||
<?php $queryDom = "<div class='queryBtn query-inside hidden'> <button type='submit' id='submit' class='btn btn-primary btn-query' data-loading='Loading...'>{$lang->pivot->query}</button></div>";?>
|
||||
<?php js::set('queryDom', $queryDom);?>
|
||||
|
||||
@@ -30,21 +31,37 @@
|
||||
</div>
|
||||
<hr class="space">
|
||||
<?php else:?>
|
||||
<div class='panel-heading heading-padding'>
|
||||
<div class='panel-heading heading-padding content-border flex-between'>
|
||||
<div class='panel-title'>
|
||||
<?php echo $pivot->name;?>
|
||||
<?php if(!empty($pivot->desc)):?>
|
||||
<a data-toggle='tooltip' data-placement='auto' title='<?php echo $pivot->desc;?>'><i class='icon-help'></i></a>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
<div class='flex-start'>
|
||||
<?php $clickable = $this->pivot->isClickable($pivot, 'design');?>
|
||||
<?php $showLine = ($clickable and (common::hasPriv('pivot', 'design') or common::hasPriv('pivot', 'edit') or common::hasPriv('pivot', 'delete'))) ? 'query-pseudo' : 'query-after';?>
|
||||
<?php echo html::a('#', "{$lang->pivot->showOrigin}", '', "id='origin-query' class='$showLine btn-query-origin' title='{$lang->pivot->showOrigin}'");?>
|
||||
<?php echo html::a('#', "{$lang->pivot->showPivot}", '', "id='pivot-query' class='$showLine btn-query hidden' title='{$lang->pivot->showPivot}'");?>
|
||||
|
||||
<?php
|
||||
$params = helper::safe64Encode("dimensionID=$pivot->dimension&groupID=$pivot->group&pivotID=$pivot->id");
|
||||
$class = !empty($pivot->used) ? "btn-design" : '';
|
||||
|
||||
if(common::hasPriv('pivot', 'design') and $clickable) echo html::a($this->createLink('pivot', 'design', "id=$pivot->id&from=preview¶m=$params"), "<i class='icon icon-design'></i> {$lang->pivot->designAB}", '', "class='pivot-design $class' title='{$lang->pivot->designAB}'");
|
||||
if(common::hasPriv('pivot', 'edit') and $clickable) echo html::a($this->createLink('pivot', 'edit', "id=$pivot->id&from=preview¶ms=$params", '', true), "<i class='icon icon-edit'></i> {$lang->edit}", '', "class='iframe pivot-edit' title='{$lang->edit}' data-width='600'");
|
||||
if(common::hasPriv('pivot', 'delete') and $clickable) echo html::a($this->createLink('pivot', 'delete', "id=$pivot->id&confirm=no&from=preview"), "<i class='icon icon-trash'></i> {$lang->delete}", 'hiddenwin', "class='pivot-delete' title='{$lang->delete}'");
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<div class='panel-body' style='padding:0px;'>
|
||||
<div id="filterItems" class='filterBox'>
|
||||
<div class='filter-items'></div>
|
||||
<?php if(!empty($pivot->filters)):?>
|
||||
<div class='queryBtn query-outside'><?php echo html::submitButton($lang->pivot->query, "", 'btn btn-primary btn-query');?></div>
|
||||
<div class='queryBtn query-outside visibility-hidden'><?php echo html::submitButton($lang->pivot->query, "", 'btn btn-primary btn-query');?></div>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
<div id="filterMargin" class='hidden'></div>
|
||||
<div id='datagirdInfo' class='datagrid datagrid-padding'>
|
||||
<?php $sql = $this->loadModel('chart')->parseSqlVars($pivot->sql, $pivot->filters);?>
|
||||
<?php $this->pivot->buildPivotTable($data, $configs, json_decode(json_encode($pivot->fieldSettings), true), $sql);?>
|
||||
@@ -84,3 +101,13 @@
|
||||
<div class="default-block hidden"><?php echo html::select('default', '', '', "class='form-control form-select multiple'");?></div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
$(function()
|
||||
{
|
||||
$('.btn-design').click(function()
|
||||
{
|
||||
var result = confirm(confirmDesign);
|
||||
if(!result) return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -31,6 +31,10 @@ class pivotZen extends pivot
|
||||
$this->view->method = $method;
|
||||
$this->view->params = $params;
|
||||
|
||||
/* This session is used to pivot-preview page, when design edit or delete a pivot in pivot-preview, use session to back current dimension and group. */
|
||||
$this->session->set('backDimension', $dimension);
|
||||
$this->session->set('backGroup', $groupID);
|
||||
|
||||
if(empty($this->view->title)) $this->view->title = $this->lang->pivot->list;
|
||||
}
|
||||
|
||||
|
||||
@@ -1778,7 +1778,7 @@ class productModel extends model
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function refreshStats()
|
||||
public function refreshStats($refreshAll = false)
|
||||
{
|
||||
$updateTime = zget($this->app->config->global, 'productStatsTime', '');
|
||||
$now = helper::now();
|
||||
@@ -1788,21 +1788,25 @@ class productModel extends model
|
||||
* Else only refresh the latest products in action table.
|
||||
*/
|
||||
$productActions = array();
|
||||
if($updateTime > date('Y-m-d', strtotime('-14 days')))
|
||||
$products = array();
|
||||
if($updateTime < date('Y-m-d', strtotime('-14 days')) or $refreshAll)
|
||||
{
|
||||
$products = $this->dao->select('id')->from(TABLE_PRODUCT)->fetchPairs('id');
|
||||
}
|
||||
else
|
||||
{
|
||||
$productActions = $this->dao->select('distinct product')->from(TABLE_ACTION)
|
||||
->where('date')->ge($updateTime)
|
||||
->andWhere('product')->notin(array(',0,', ',,'))
|
||||
->fetchPairs('product');
|
||||
if(empty($productActions)) return;
|
||||
}
|
||||
|
||||
$products = array();
|
||||
foreach($productActions as $productAction)
|
||||
{
|
||||
foreach(explode(',', trim($productAction, ',')) as $product)
|
||||
foreach($productActions as $productAction)
|
||||
{
|
||||
$products[$product] = $product;
|
||||
foreach(explode(',', trim($productAction, ',')) as $product)
|
||||
{
|
||||
$products[$product] = $product;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1301,7 +1301,7 @@ class programModel extends model
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function refreshStats()
|
||||
public function refreshStats($refreshAll = false)
|
||||
{
|
||||
$updateTime = zget($this->app->config->global, 'projectStatsTime', '');
|
||||
$now = helper::now();
|
||||
@@ -1311,7 +1311,11 @@ class programModel extends model
|
||||
* Else only refresh the latest executions in action table.
|
||||
*/
|
||||
$projects = array();
|
||||
if($updateTime > date('Y-m-d', strtotime('-14 days')))
|
||||
if($updateTime < date('Y-m-d', strtotime('-14 days')) or $refreshAll)
|
||||
{
|
||||
$projects = $this->dao->select('id,project,model')->from(TABLE_PROJECT)->fetchAll('id');
|
||||
}
|
||||
else
|
||||
{
|
||||
$projects = $this->dao->select('distinct t1.project,t2.model')->from(TABLE_ACTION)->alias('t1')
|
||||
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project=t2.id')
|
||||
@@ -1324,6 +1328,7 @@ class programModel extends model
|
||||
$summary = $this->dao->select('execution, SUM(t1.estimate) AS totalEstimate, SUM(t1.consumed) AS totalConsumed, SUM(t1.`left`) AS totalLeft')->from(TABLE_TASK)->alias('t1')
|
||||
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project=t2.id')
|
||||
->where('t1.deleted')->eq(0)
|
||||
->andWhere('t1.parent')->le(0) // Ignore child task.
|
||||
->beginIF(!empty($projects))->andWhere('t1.project')->in(array_keys($projects))->fi()
|
||||
->groupBy('execution')
|
||||
->fetchAll();
|
||||
|
||||
+10
-2
@@ -564,10 +564,18 @@ class screenModel extends model
|
||||
$settings = json_decode($chart->settings, true);
|
||||
$fields = json_decode($chart->fields, true);
|
||||
$langs = json_decode($chart->langs, true);
|
||||
list($options, $config) = $this->loadModel('pivot')->genSheet($fields, $settings, $chart->sql, $filters, $langs);
|
||||
|
||||
if(isset($settings['summary']) and $settings['summary'] == 'notuse')
|
||||
{
|
||||
list($options, $config) = $this->loadModel('pivot')->genOriginSheet($fields, $settings, $chart->sql, $filters, $langs);
|
||||
}
|
||||
else
|
||||
{
|
||||
list($options, $config) = $this->loadModel('pivot')->genSheet($fields, $settings, $chart->sql, $filters, $langs);
|
||||
}
|
||||
|
||||
$colspan = array();
|
||||
if($options->columnTotal and $options->columnTotal == 'sum' and !empty($options->array))
|
||||
if(isset($options->columnTotal) and $options->columnTotal == 'sum' and !empty($options->array))
|
||||
{
|
||||
$optionsData = $options->array;
|
||||
$count = count($optionsData);
|
||||
|
||||
@@ -428,7 +428,7 @@ class searchModel extends model
|
||||
->skipSpecial('sql,form')
|
||||
->remove('onMenuBar')
|
||||
->get();
|
||||
if($this->post->onMenuBar) $query->shortcut = 1;
|
||||
if($this->post->onMenuBar) $query->shortcut = '1';
|
||||
$this->dao->insert(TABLE_USERQUERY)->data($query)->autoCheck()->check('title', 'notempty')->exec();
|
||||
|
||||
if(!dao::isError())
|
||||
|
||||
@@ -578,7 +578,7 @@ class storyModel extends model
|
||||
{
|
||||
if(empty($title)) continue;
|
||||
|
||||
$stories->reviewer[$i] = array_filter($stories->reviewer[$i]);
|
||||
$stories->reviewer[$i] = is_array($stories->reviewer[$i]) ? array_filter($stories->reviewer[$i]) : array();
|
||||
if(empty($stories->reviewer[$i]) and empty($stories->reviewerDitto[$i])) $stories->reviewer[$i] = array();
|
||||
$reviewers = (isset($stories->reviewDitto[$i])) ? $reviewers : $stories->reviewer[$i];
|
||||
$stories->reviewer[$i] = $reviewers;
|
||||
|
||||
+32
-25
@@ -1341,7 +1341,7 @@ class testtaskModel extends model
|
||||
$postReals = $postData->reals[$caseID];
|
||||
|
||||
$caseResult = $result ? $result : 'pass';
|
||||
if($postData->node) $caseResult = '';
|
||||
if(!empty($postData->node)) $caseResult = '';
|
||||
$stepResults = array();
|
||||
if($dbSteps)
|
||||
{
|
||||
@@ -2230,17 +2230,21 @@ class testtaskModel extends model
|
||||
|
||||
$case = new stdclass();
|
||||
if(!empty($caseResult->id)) $case->id = $caseResult->id;
|
||||
$case->product = $productID;
|
||||
if(empty($caseResult->id)) $case->title = $caseResult->title;
|
||||
$case->pri = 3;
|
||||
$case->type = 'unit';
|
||||
$case->stage = 'unittest';
|
||||
$case->status = 'normal';
|
||||
$case->openedBy = $this->app->user->account;
|
||||
$case->openedDate = $now;
|
||||
$case->version = 1;
|
||||
if(empty($caseResult->id)) $case->auto = 'unit';
|
||||
$case->frame = $frame;
|
||||
$case->status = 'normal';
|
||||
$case->frame = $frame;
|
||||
|
||||
if(empty($caseResult->id))
|
||||
{
|
||||
$case->type = 'unit';
|
||||
$case->stage = 'unittest';
|
||||
$case->product = $productID;
|
||||
$case->title = $caseResult->title;
|
||||
$case->pri = 3;
|
||||
$case->openedBy = $this->app->user->account;
|
||||
$case->openedDate = $now;
|
||||
$case->version = 1;
|
||||
$case->auto = 'unit';
|
||||
}
|
||||
|
||||
$result = new stdclass();
|
||||
$result->case = 0;
|
||||
@@ -2298,19 +2302,22 @@ class testtaskModel extends model
|
||||
if(!isset($suites[$suiteIndex])) $suites[$suiteIndex] = $suite;
|
||||
|
||||
$case = new stdclass();
|
||||
if(isset($caseResult->id)) $case->id = $caseResult->id;
|
||||
if(!isset($caseResult->id)) $case->product = $productID;
|
||||
$case->title = $caseResult->title;
|
||||
$case->pri = 3;
|
||||
$case->type = 'feature';
|
||||
$case->stage = 'feature';
|
||||
$case->status = 'normal';
|
||||
$case->openedBy = $this->app->user->account;
|
||||
$case->openedDate = $now;
|
||||
$case->version = 1;
|
||||
$case->auto = 'func';
|
||||
$case->frame = $frame;
|
||||
$case->steps = array();
|
||||
if(!empty($caseResult->id)) $case->id = $caseResult->id;
|
||||
$case->title = $caseResult->title;
|
||||
$case->frame = $frame;
|
||||
$case->status = 'normal';
|
||||
$case->steps = array();
|
||||
$case->auto = 'func';
|
||||
if(empty($caseResult->id))
|
||||
{
|
||||
$case->product = $productID;
|
||||
$case->pri = 3;
|
||||
$case->type = 'feature';
|
||||
$case->stage = 'feature';
|
||||
$case->openedBy = $this->app->user->account;
|
||||
$case->openedDate = $now;
|
||||
$case->version = 1;
|
||||
}
|
||||
|
||||
$result = new stdclass();
|
||||
$result->case = 0;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
<?php js::set('browseType', $browseType);?>
|
||||
<?php js::set('moduleID', $moduleID);?>
|
||||
<?php js::set('case2RunMap', $case2RunMap);?>
|
||||
<?php js::set('taskID', $taskID);?>
|
||||
<?php js::set('automation', !empty($automation) ? $automation->id : 0);?>
|
||||
<?php $this->app->loadLang('zanode');?>
|
||||
<?php js::set('runCaseConfirm', $lang->zanode->runCaseConfirm);?>
|
||||
@@ -177,7 +178,7 @@ function runAutocase()
|
||||
runIDList.push(case2RunMap[$(this).val()]);
|
||||
});
|
||||
|
||||
var url = createLink('zanode', 'ajaxRunZTFScript', 'scriptID=' + automation)
|
||||
var url = createLink('zanode', 'ajaxRunZTFScript', 'scriptID=' + automation + "&taskID=" + taskID)
|
||||
|
||||
var postData = {'caseIDList' : caseIDList.join(','), 'runIDList' : runIDList.join(',')};
|
||||
|
||||
|
||||
@@ -38,7 +38,8 @@ $config->upgrade->maxVersion['max4_3'] = '18_3';
|
||||
$config->upgrade->maxVersion['max4_4_alpha1'] = '18_4_alpha1';
|
||||
$config->upgrade->maxVersion['max4_4_beta1'] = '18_4_beta1';
|
||||
$config->upgrade->maxVersion['max4_4'] = '18_4';
|
||||
$config->upgrade->maxVersion['max4_5'] = '18_5'; // max insert position.
|
||||
$config->upgrade->maxVersion['max4_5'] = '18_5';
|
||||
$config->upgrade->maxVersion['max4_6'] = '18_6'; // max insert position.
|
||||
|
||||
$config->upgrade->bizVersion = array();
|
||||
$config->upgrade->bizVersion['biz1_0'] = '9_5_1';
|
||||
@@ -115,7 +116,8 @@ $config->upgrade->bizVersion['biz8_3'] = '18_3';
|
||||
$config->upgrade->bizVersion['biz8_4_alpha1'] = '18_4_alpha1';
|
||||
$config->upgrade->bizVersion['biz8_4_beta1'] = '18_4_beta1';
|
||||
$config->upgrade->bizVersion['biz8_4'] = '18_4';
|
||||
$config->upgrade->bizVersion['biz8_5'] = '18_5'; // biz insert position.
|
||||
$config->upgrade->bizVersion['biz8_5'] = '18_5';
|
||||
$config->upgrade->bizVersion['biz8_6'] = '18_6'; // biz insert position.
|
||||
|
||||
$config->upgrade->proVersion = array();
|
||||
$config->upgrade->proVersion['pro1_0'] = '3_1';
|
||||
|
||||
@@ -179,7 +179,8 @@ $lang->upgrade->fromVersions['18_3'] = '18.3';
|
||||
$lang->upgrade->fromVersions['18_4_alpha1'] = '18.4.alpha1';
|
||||
$lang->upgrade->fromVersions['18_4_beta1'] = '18.4.beta1';
|
||||
$lang->upgrade->fromVersions['18_4'] = '18.4';
|
||||
$lang->upgrade->fromVersions['18_5'] = '18.5'; // pms insert position.
|
||||
$lang->upgrade->fromVersions['18_5'] = '18.5';
|
||||
$lang->upgrade->fromVersions['18_6'] = '18.6'; // pms insert position.
|
||||
|
||||
global $config;
|
||||
/* Lite. */
|
||||
@@ -363,7 +364,8 @@ $lang->upgrade->fromVersions['biz8_3'] = 'Biz8.3';
|
||||
$lang->upgrade->fromVersions['biz8_4_alpha1'] = 'Biz8.4.alpha1';
|
||||
$lang->upgrade->fromVersions['biz8_4_beta1'] = 'Biz8.4.beta1';
|
||||
$lang->upgrade->fromVersions['biz8_4'] = 'Biz8.4';
|
||||
$lang->upgrade->fromVersions['biz8_5'] = 'Biz8.5'; // biz insert position.
|
||||
$lang->upgrade->fromVersions['biz8_5'] = 'Biz8.5';
|
||||
$lang->upgrade->fromVersions['biz8_6'] = 'Biz8.6'; // biz insert position.
|
||||
|
||||
/* Max. */
|
||||
$lang->upgrade->fromVersions['max2_0_beta4'] = 'Max2.0.beta4';
|
||||
@@ -408,4 +410,4 @@ $lang->upgrade->fromVersions['max4_4'] = 'Max4.4';
|
||||
$lang->upgrade->fromVersions['max4_5'] = 'Max4.5'; // max insert position.
|
||||
|
||||
/* Ipd */
|
||||
$lang->upgrade->fromVersions['ipd1_0_beta1'] = 'Ipd1.0.beta1';
|
||||
$lang->upgrade->fromVersions['ipd1_0_beta1'] = 'Ipd1.0.beta1'; // ipd insert position.
|
||||
|
||||
@@ -676,6 +676,11 @@ class upgradeModel extends model
|
||||
if(strpos($fromVersion, 'ipd') === false) $this->execSQL($this->getUpgradeFile('ipdinstall'));
|
||||
if($fromVersion == 'ipd1.0.beta1') $this->execSQL($this->getUpgradeFile('ipd1.0.beta1'));
|
||||
if($this->config->edition == 'ipd' and strpos($fromVersion, 'ipd') === false) $this->addORPriv();
|
||||
|
||||
$this->loadModel('product')->refreshStats(true);
|
||||
$this->loadModel('program')->refreshStats(true);
|
||||
$this->updatePivotFieldsType();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1488,7 +1493,7 @@ class upgradeModel extends model
|
||||
try
|
||||
{
|
||||
$tableExists = true;
|
||||
$stmt = $this->dbh->query("show fields from `{$table}`");
|
||||
$stmt = $this->dbh->query("show fields from `$table`");
|
||||
while($row = $stmt->fetch()) $fields[$row->Field] = $row->Field;
|
||||
}
|
||||
catch(PDOException $e)
|
||||
@@ -1514,11 +1519,11 @@ class upgradeModel extends model
|
||||
if(stripos($line, 'auto_increment') !== false) $line .= ' primary key';
|
||||
try
|
||||
{
|
||||
$this->dbh->exec("ALTER TABLE `{$table}` ADD $line");
|
||||
$this->dbh->exec("ALTER TABLE `$table` ADD $line");
|
||||
}
|
||||
catch(PDOException $e)
|
||||
{
|
||||
$alterSQL .= "ALTER TABLE `{$table}` ADD $line;\n";
|
||||
$alterSQL .= "ALTER TABLE `$table` ADD $line;\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9263,8 +9268,18 @@ class upgradeModel extends model
|
||||
|
||||
$columns[] = $column;
|
||||
|
||||
$data->stage = 'draft';
|
||||
$data->step = 1;
|
||||
$this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
|
||||
$stmt = $this->dbh->query($data->sql);
|
||||
|
||||
if(!$stmt)
|
||||
{
|
||||
$data->stage = 'draft';
|
||||
$data->step = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$settings->summary = 'notuse';
|
||||
}
|
||||
}
|
||||
|
||||
$settings->columns = $columns;
|
||||
@@ -9603,4 +9618,47 @@ class upgradeModel extends model
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Update pivot fields type, pivotID maybe is 1008,1012,1013,1015,1020,1027.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function updatePivotFieldsType()
|
||||
{
|
||||
$fieldsPairs = array();
|
||||
$fieldsPairs[] = array('maybeID' => 1008, 'beforefields' => '"execution":{"object":"project","field":"execution","type":"string"},"type":{"object":"project","field":"type","type":"string"}',
|
||||
'fields' => '{"id":{"object":"project","field":"id","type":"string"},"project":{"object":"project","field":"project","type":"string"},"execution":{"object":"project","field":"execution","type":"string"},"type":{"object":"task","field":"type","type":"option"},"taskID":{"object":"task","field":"taskID","type":"string"},"projectstatus":{"object":"task","field":"projectstatus","type":"string"}}',
|
||||
'langs' => '{"project":{"zh-cn":"\\u9879\\u76ee\\u540d\\u79f0","zh-tw":"","en":"","de":"","fr":""},"execution":{"zh-cn":"\\u6267\\u884c\\u540d\\u79f0","zh-tw":"","en":"","de":"","fr":""},"id":{"zh-cn":"\\u9879\\u76eeID","zh-tw":"","en":"","de":"","fr":""},"type":{"zh-cn":"\\u4efb\\u52a1\\u7c7b\\u578b","zh-tw":"","en":"","de":"","fr":""},"taskID":{"zh-cn":"taskID","zh-tw":"","en":"","de":"","fr":""},"projectstatus":{"zh-cn":"projectstatus","zh-tw":"","en":"","de":"","fr":""}}');
|
||||
$fieldsPairs[] = array('maybeID' => 1012, 'beforefields' => '"project":{"object":"projectstory","field":"project","type":"string"},"execution":{"object":"project","field":"execution","type":"string"},"status":{"object":"project","field":"status","type":"string"}',
|
||||
'fields' => '{"id":{"object":"project","field":"id","type":"string"},"project":{"object":"projectstory","field":"project","type":"string"},"execution":{"object":"project","field":"execution","type":"string"},"status":{"object":"story","field":"status","type":"option"}}',
|
||||
);
|
||||
$fieldsPairs[] = array('maybeID' => 1013, 'beforefields' => '"execution":{"object":"project","field":"execution","type":"string"},"stage":{"object":"project","field":"stage","type":"string"}}',
|
||||
'fields' => '{"id":{"object":"project","field":"id","type":"string"},"project":{"object":"projectstory","field":"project","type":"string"},"execution":{"object":"project","field":"execution","type":"string"},"stage":{"object":"story","field":"stage","type":"option"}}',
|
||||
'langs' => '{"project":{"zh-cn":"\\u9879\\u76ee\\u540d\\u79f0","zh-tw":"","en":"","de":"","fr":""},"execution":{"zh-cn":"\\u6267\\u884c\\u540d\\u79f0","zh-tw":"","en":"","de":"","fr":""},"id":{"zh-cn":"\\u9879\\u76eeID","zh-tw":"","en":"","de":"","fr":""},"stage":{"zh-cn":"\\u9636\\u6bb5","zh-tw":"","en":"","de":"","fr":""}}');
|
||||
$fieldsPairs[] = array('maybeID' => 1015, 'beforefields' => '"bugID":{"object":"bug","field":"bugID","type":"string"},"status":{"object":"project","field":"status","type":"string"}',
|
||||
'fields' => '{"id":{"object":"project","field":"id","type":"string"},"project":{"object":"project","field":"project","type":"string"},"t3id":{"object":"project","field":"t3id","type":"string"},"execution":{"object":"project","field":"execution","type":"string"},"bugID":{"object":"bug","field":"bugID","type":"string"},"status":{"object":"bug","field":"status","type":"option"}}',
|
||||
);
|
||||
$fieldsPairs[] = array('maybeID' => 1020, 'beforefields' => '"bugID":{"object":"project","field":"bugID","type":"string"},"type":{"object":"product","field":"type","type":"string"}',
|
||||
'fields' => '{"id":{"object":"product","field":"id","type":"string"},"name":{"object":"product","field":"name","type":"string"},"bugID":{"object":"project","field":"bugID","type":"string"},"type":{"object":"bug","field":"type","type":"option"}}',
|
||||
'langs' => '{"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"},"id":{"zh-cn":"\\u7f16\\u53f7","zh-tw":"","en":"","de":"","fr":""},"name":{"zh-cn":"\\u4ea7\\u54c1\\u540d\\u79f0","zh-tw":"","en":"","de":"","fr":""},"bugID":{"zh-cn":"bugID","zh-tw":"","en":"","de":"","fr":""},"type":{"zh-cn":"Bug\\u7c7b\\u578b","zh-tw":"","en":"","de":"","fr":""}}');
|
||||
$fieldsPairs[] = array('maybeID' => 1027, 'beforefields' => '"bugID":{"object":"bug","field":"bugID","type":"string"},"type":{"object":"project","field":"type","type":"string"}',
|
||||
'fields' => '{"id":{"object":"project","field":"id","type":"string"},"project":{"object":"project","field":"project","type":"string"},"t3id":{"object":"project","field":"t3id","type":"string"},"execution":{"object":"project","field":"execution","type":"string"},"bugID":{"object":"bug","field":"bugID","type":"string"},"type":{"object":"bug","field":"type","type":"option"}}',
|
||||
'langs' => '{"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","zh-tw":"","en":"","de":"","fr":""},"id":{"zh-cn":"\\u9879\\u76eeID","zh-tw":"","en":"","de":"","fr":""},"project":{"zh-cn":"\\u9879\\u76ee\\u540d\\u79f0","zh-tw":"","en":"","de":"","fr":""},"bugID":{"zh-cn":"bugID","zh-tw":"","en":"","de":"","fr":""},"type":{"zh-cn":"Bug\\u7c7b\\u578b","zh-tw":"","en":"","de":"","fr":""}}');
|
||||
|
||||
foreach($fieldsPairs as $field)
|
||||
{
|
||||
$pivot = $this->dao->select('*')->from(TABLE_PIVOT)->where('fields')->like("%{$field['beforefields']}%")->fetchAll();
|
||||
if(count($pivot) > 1 or count($pivot) == 0) continue;
|
||||
|
||||
$pivot = reset($pivot);
|
||||
|
||||
$data = new stdclass();
|
||||
if(isset($field['fields'])) $data->fields = $field['fields'];
|
||||
if(isset($field['langs'])) $data->langs = $field['langs'];
|
||||
|
||||
$this->dao->update(TABLE_PIVOT)->data($data)->where('id')->eq($pivot->id)->exec();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -609,23 +609,33 @@ class zanode extends control
|
||||
* Ajax: run ZTF script.
|
||||
*
|
||||
* @param int $scriptID
|
||||
* @param string $taskID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function ajaxRunZTFScript($scriptID = 0)
|
||||
public function ajaxRunZTFScript($scriptID = 0, $taskID = 0)
|
||||
{
|
||||
if($_POST)
|
||||
{
|
||||
$caseIDList = $_POST['caseIDList'];
|
||||
$runIDList = $_POST['runIDList'];
|
||||
$runIDList = empty($_POST['runIDList']) ? array() : $_POST['runIDList'];
|
||||
$script = $this->zanode->getAutomationByID($scriptID);
|
||||
$cases = $this->loadModel('testcase')->getByList($caseIDList);
|
||||
$cases = $this->loadModel('testcase')->getByList($caseIDList);
|
||||
|
||||
$runs = array();
|
||||
if($taskID)
|
||||
{
|
||||
$runs = $this->dao->select('id, `case`')->from(TABLE_TESTRUN)
|
||||
->where('`case`')->in($caseIDList)
|
||||
->andWhere('task')->eq($taskID)->fi()
|
||||
->fetchPairs('case', 'id');
|
||||
}
|
||||
|
||||
$caseIDListArray = explode(',', $caseIDList);
|
||||
$runIDListArray = explode(',', $runIDList);
|
||||
$case2RunMap = array();
|
||||
|
||||
foreach($caseIDListArray as $index => $caseID) $case2RunMap[$caseID] = $runIDListArray[$index];
|
||||
foreach($caseIDListArray as $index => $caseID) $case2RunMap[$caseID] = empty($runIDListArray[$index]) ? 0 : $runIDListArray[$index];
|
||||
|
||||
foreach($cases as $id => $case)
|
||||
{
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
v7.2.1-rc.4
|
||||
@@ -1 +0,0 @@
|
||||
7.2.1
|
||||
Reference in New Issue
Block a user