From f0ca6dc4d96e3cc2168a249f9c24635365eb58a9 Mon Sep 17 00:00:00 2001 From: zenggang Date: Thu, 24 Aug 2023 09:32:06 +0000 Subject: [PATCH] * Finish tasks. --- config/zentaopms.php | 4 +- db/update18.6.sql | 18 +++ db/zentao.sql | 18 +++ module/action/config.php | 3 +- module/action/lang/en.php | 2 + module/action/lang/zh-cn.php | 3 +- module/artifactrepo/config/dtable.php | 38 ++++++ module/artifactrepo/config/form.php | 17 +++ module/artifactrepo/control.php | 161 +++++++++++++++++++++++++ module/artifactrepo/js/browse.ui.js | 15 +++ module/artifactrepo/js/create.ui.js | 66 ++++++++++ module/artifactrepo/lang/de.php | 16 +++ module/artifactrepo/lang/en.php | 16 +++ module/artifactrepo/lang/fr.php | 16 +++ module/artifactrepo/lang/zh-cn.php | 16 +++ module/artifactrepo/model.php | 134 ++++++++++++++++++++ module/artifactrepo/ui/browse.html.php | 59 +++++++++ module/artifactrepo/ui/create.html.php | 77 ++++++++++++ module/artifactrepo/ui/edit.html.php | 71 +++++++++++ module/artifactrepo/zen.php | 30 +++++ module/common/lang/en.php | 42 +++---- module/common/lang/menu.php | 2 +- module/common/lang/zh-cn.php | 42 +++---- module/repo/view/setrules.html.php | 1 - 24 files changed, 818 insertions(+), 49 deletions(-) create mode 100644 module/artifactrepo/config/dtable.php create mode 100644 module/artifactrepo/config/form.php create mode 100644 module/artifactrepo/control.php create mode 100644 module/artifactrepo/js/browse.ui.js create mode 100644 module/artifactrepo/js/create.ui.js create mode 100644 module/artifactrepo/lang/de.php create mode 100644 module/artifactrepo/lang/en.php create mode 100644 module/artifactrepo/lang/fr.php create mode 100644 module/artifactrepo/lang/zh-cn.php create mode 100644 module/artifactrepo/model.php create mode 100644 module/artifactrepo/ui/browse.html.php create mode 100644 module/artifactrepo/ui/create.html.php create mode 100644 module/artifactrepo/ui/edit.html.php create mode 100644 module/artifactrepo/zen.php diff --git a/config/zentaopms.php b/config/zentaopms.php index 51e229b026..be91050137 100644 --- a/config/zentaopms.php +++ b/config/zentaopms.php @@ -388,6 +388,7 @@ define('TABLE_PRIVRELATION', '`' . $config->db->prefix . 'privrelation`'); define('TABLE_SPACE', '`' . $config->db->prefix . 'space`'); define('TABLE_INSTANCE', '`' . $config->db->prefix . 'instance`'); define('TABLE_SOLUTION', '`' . $config->db->prefix . 'solution`'); +define('TABLE_ARTIFACTREPO', '`' . $config->db->prefix . 'artifactrepo`'); $config->objectTables['product'] = TABLE_PRODUCT; $config->objectTables['productplan'] = TABLE_PRODUCTPLAN; @@ -453,6 +454,7 @@ $config->objectTables['host'] = TABLE_ZAHOST; $config->objectTables['instance'] = TABLE_INSTANCE; $config->objectTables['space'] = TABLE_SPACE; $config->objectTables['solution'] = TABLE_SOLUTION; +$config->objectTables['artifactrepo'] = TABLE_ARTIFACTREPO; $config->newFeatures = array('introduction', 'tutorial', 'youngBlueTheme', 'visions'); $config->disabledFeatures = ''; @@ -490,4 +492,4 @@ $config->bi = new stdclass(); $config->bi->pickerHeight = 150; $config->hasDropmenuApps = array('program', 'project', 'product', 'execution', 'qa', 'admin'); -$config->excludeDropmenuList = array('program-browse', 'product-all', 'product-index', 'execution-all', 'project-browse', 'product-batchedit', 'admin-index', 'product-create', 'project-create', 'execution-create', 'program-create'); \ No newline at end of file +$config->excludeDropmenuList = array('program-browse', 'product-all', 'product-index', 'execution-all', 'project-browse', 'product-batchedit', 'admin-index', 'product-create', 'project-create', 'execution-create', 'program-create'); diff --git a/db/update18.6.sql b/db/update18.6.sql index cc645610b7..4b2388e3bc 100644 --- a/db/update18.6.sql +++ b/db/update18.6.sql @@ -70,6 +70,24 @@ CREATE TABLE IF NOT EXISTS `zt_solution` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +-- DROP TABLE IF EXISTS `zt_artifactrepo`; +CREATE TABLE `zt_artifactrepo` ( + `id` smallint(8) UNSIGNED NOT NULL AUTO_INCREMENT, + `name` varchar(45) CHARACTER SET utf8 NOT NULL, + `products` varchar(1000) CHARACTER SET utf8 NOT NULL, + `serverID` smallint(8) NOT NULL, + `repoName` varchar(45) CHARACTER SET utf8 NOT NULL, + `format` varchar(10) CHARACTER SET utf8 NOT NULL, + `type` char(7) CHARACTER SET utf8 NOT NULL, + `status` varchar(10) CHARACTER SET utf8 NOT NULL, + `createdBy` varchar(30) CHARACTER SET utf8 NOT NULL, + `createdDate` datetime DEFAULT CURRENT_TIMESTAMP, + `editedBy` varchar(30) CHARACTER SET utf8 NOT NULL, + `editedDate` datetime DEFAULT CURRENT_TIMESTAMP, + `deleted` tinyint(4) UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + INSERT INTO `zt_privmanager` (`parent`, `code`, `type`, `edition`, `vision`, `order`) VALUES (515, 'application', 'package', ',open,biz,max,ipd,', ',rnd,', 5); INSERT INTO `zt_priv` (`module`, `method`, `parent`, `edition`, `vision`, `system`, `order`) VALUES ('space', 'browse', 651, ',open,biz,max,ipd,', ',rnd,', '1', 10),('instance', 'view', 651, ',open,biz,max,ipd,', ',rnd,', '1', 20),('space', 'getStoreAppInfo', 651, ',open,biz,max,ipd,', ',rnd,', '1', 30),('instance', 'install', 651, ',open,biz,max,ipd,', ',rnd,', '1', 40),('instance', 'visit', 651, ',open,biz,max,ipd,', ',rnd,', '1', 50),('instance', 'ajaxStatus', 651, ',open,biz,max,ipd,', ',rnd,', '1', 60),('instance', 'ajaxStart', 651, ',open,biz,max,ipd,', ',rnd,', '1', 70),('instance', 'ajaxStop', 651, ',open,biz,max,ipd,', ',rnd,', '1', 80),('instance', 'ajaxUninstall', 651, ',open,biz,max,ipd,', ',rnd,', '1', 90),('instance', 'upgrade', 651, ',open,biz,max,ipd,', ',rnd,', '1', 100); diff --git a/db/zentao.sql b/db/zentao.sql index 9c0408d3cb..837a907543 100755 --- a/db/zentao.sql +++ b/db/zentao.sql @@ -13324,6 +13324,24 @@ CREATE TABLE IF NOT EXISTS `zt_solutions` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +-- DROP TABLE IF EXISTS `zt_artifactrepo`; +CREATE TABLE `zt_artifactrepo` ( + `id` smallint(8) UNSIGNED NOT NULL AUTO_INCREMENT, + `name` varchar(45) CHARACTER SET utf8 NOT NULL, + `products` varchar(1000) CHARACTER SET utf8 NOT NULL, + `serverID` smallint(8) NOT NULL, + `repoName` varchar(45) CHARACTER SET utf8 NOT NULL, + `format` varchar(10) CHARACTER SET utf8 NOT NULL, + `type` char(7) CHARACTER SET utf8 NOT NULL, + `status` varchar(10) CHARACTER SET utf8 NOT NULL, + `createdBy` varchar(30) CHARACTER SET utf8 NOT NULL, + `createdDate` datetime DEFAULT CURRENT_TIMESTAMP, + `editedBy` varchar(30) CHARACTER SET utf8 NOT NULL, + `editedDate` datetime DEFAULT CURRENT_TIMESTAMP, + `deleted` tinyint(4) UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + -- DROP TABLE IF EXISTS `zt_measqueue`; CREATE TABLE IF NOT EXISTS `zt_measqueue` ( `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, diff --git a/module/action/config.php b/module/action/config.php index b323a79878..d74ec50577 100755 --- a/module/action/config.php +++ b/module/action/config.php @@ -59,6 +59,7 @@ $config->action->objectNameFields['host'] = 'name'; $config->action->objectNameFields['instance'] = 'name'; $config->action->objectNameFields['space'] = 'name'; $config->action->objectNameFields['solution'] = 'name'; +$config->action->objectNameFields['artifactrepo'] = 'name'; $config->action->commonImgSize = 870; @@ -99,4 +100,4 @@ $config->trash->search['params']['objectID'] = array('operator' => 'include', $config->trash->search['params']['actor'] = array('operator' => '=', 'control' => 'select', 'values' => 'users'); $config->trash->search['params']['date'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date'); -$config->action->newPageModule = array('repo', 'mr', 'host', 'account', 'serverroom', 'instance', 'store', 'space', 'host'); \ No newline at end of file +$config->action->newPageModule = array('repo', 'mr', 'host', 'account', 'serverroom', 'instance', 'store', 'space', 'host'); diff --git a/module/action/lang/en.php b/module/action/lang/en.php index 7b4fd36e88..ad307b28f8 100755 --- a/module/action/lang/en.php +++ b/module/action/lang/en.php @@ -168,6 +168,7 @@ $lang->action->objectTypes['host'] = 'Host'; $lang->action->objectTypes['deploy'] = 'Deploy'; $lang->action->objectTypes['service'] = 'Service'; $lang->action->objectTypes['domain'] = 'Domain'; +$lang->action->objectTypes['artifactrepo'] = 'Artifact Repo'; /* Used to describe operation history. */ @@ -848,6 +849,7 @@ $lang->action->label->instance = 'Application|instance|view|id=%s'; $lang->action->label->deploy = 'Deploy|deploy|view|id=%s'; $lang->action->label->domian = 'Domain|domian|view|id=%s'; $lang->action->label->service = 'Service|service|view|id=%s'; +$lang->action->label->artifactrepo = 'Artifact Repo|artifactrepo|browse|'; /* Object type. */ $lang->action->search = new stdclass(); diff --git a/module/action/lang/zh-cn.php b/module/action/lang/zh-cn.php index 7efb24a29c..ae81795a4f 100755 --- a/module/action/lang/zh-cn.php +++ b/module/action/lang/zh-cn.php @@ -168,7 +168,7 @@ $lang->action->objectTypes['host'] = '主机'; $lang->action->objectTypes['deploy'] = '发布'; $lang->action->objectTypes['service'] = '服务'; $lang->action->objectTypes['domain'] = '域名'; - +$lang->action->objectTypes['artifactrepo'] = '制品库'; /* 用来描述操作历史记录。*/ $lang->action->desc = new stdclass(); @@ -844,6 +844,7 @@ $lang->action->label->instance = '应用|instance|view|id=%s'; $lang->action->label->deploy = '上线|deploy|view|id=%s'; $lang->action->label->domian = '域名|domian|view|id=%s'; $lang->action->label->service = '服务|service|view|id=%s'; +$lang->action->label->artifactrepo = '制品库|artifactrepo|browse|'; /* Object type. */ $lang->action->search = new stdclass(); diff --git a/module/artifactrepo/config/dtable.php b/module/artifactrepo/config/dtable.php new file mode 100644 index 0000000000..1420c94a94 --- /dev/null +++ b/module/artifactrepo/config/dtable.php @@ -0,0 +1,38 @@ +loadLang('repo'); + +$config->artifactrepo->dtable = new stdclass(); + +$config->artifactrepo->dtable->fieldList['name']['title'] = $lang->artifactrepo->name; +$config->artifactrepo->dtable->fieldList['name']['type'] = 'title'; +$config->artifactrepo->dtable->fieldList['name']['width'] = '300'; + +$config->artifactrepo->dtable->fieldList['format']['title'] = $lang->artifactrepo->format; +$config->artifactrepo->dtable->fieldList['format']['sortType'] = true; + +$config->artifactrepo->dtable->fieldList['products']['title'] = $lang->repo->product; +$config->artifactrepo->dtable->fieldList['products']['name'] = 'productNames'; +$config->artifactrepo->dtable->fieldList['products']['width'] = '300'; + +$config->artifactrepo->dtable->fieldList['type']['title'] = $lang->artifactrepo->type; +$config->artifactrepo->dtable->fieldList['type']['sortType'] = true; + +$config->artifactrepo->dtable->fieldList['status']['title'] = $lang->artifactrepo->status; +$config->artifactrepo->dtable->fieldList['status']['sortType'] = true; + +$config->artifactrepo->dtable->fieldList['url']['title'] = $lang->artifactrepo->url; +$config->artifactrepo->dtable->fieldList['url']['width'] = '400'; + +$config->artifactrepo->dtable->fieldList['actions']['type'] = 'actions'; +$config->artifactrepo->dtable->fieldList['actions']['menu'] = array('edit', 'delete'); + +$config->artifactrepo->dtable->fieldList['actions']['list']['edit']['icon'] = 'edit'; +$config->artifactrepo->dtable->fieldList['actions']['list']['edit']['hint'] = $lang->edit; +$config->artifactrepo->dtable->fieldList['actions']['list']['edit']['url'] = array('module' => 'artifactrepo', 'method' => 'edit', 'params' => 'id={id}'); + +$config->artifactrepo->dtable->fieldList['actions']['list']['delete']['icon'] = 'trash'; +$config->artifactrepo->dtable->fieldList['actions']['list']['delete']['hint'] = $lang->artifactrepo->delete; +$config->artifactrepo->dtable->fieldList['actions']['list']['delete']['className'] = 'ajax-submit'; +$config->artifactrepo->dtable->fieldList['actions']['list']['delete']['data-confirm'] = $lang->artifactrepo->confirmDelete; +$config->artifactrepo->dtable->fieldList['actions']['list']['delete']['url'] = array('module' => 'artifactrepo', 'method' => 'delete', 'params' => 'id={id}&confirm=yes'); diff --git a/module/artifactrepo/config/form.php b/module/artifactrepo/config/form.php new file mode 100644 index 0000000000..7d52177103 --- /dev/null +++ b/module/artifactrepo/config/form.php @@ -0,0 +1,17 @@ +artifactrepo->form = new stdclass(); + +$config->artifactrepo->form->create = common::formConfig('artifactrepo', 'create'); +$config->artifactrepo->form->create['name'] = array('required' => true, 'type' => 'string'); +$config->artifactrepo->form->create['products'] = array('required' => false, 'type' => 'array', 'default' => array()); +$config->artifactrepo->form->create['serverID'] = array('required' => true, 'type' => 'int'); +$config->artifactrepo->form->create['repoName'] = array('required' => true, 'type' => 'string'); +$config->artifactrepo->form->create['type'] = array('required' => true, 'type' => 'string'); +$config->artifactrepo->form->create['format'] = array('required' => false, 'type' => 'string', 'default' => ''); +$config->artifactrepo->form->create['status'] = array('required' => true, 'type' => 'string'); + +$config->artifactrepo->form->edit = common::formConfig('artifactrepo', 'edit'); +$config->artifactrepo->form->edit['name'] = array('required' => true, 'type' => 'string'); +$config->artifactrepo->form->edit['products'] = array('required' => false, 'type' => 'array', 'default' => array()); diff --git a/module/artifactrepo/control.php b/module/artifactrepo/control.php new file mode 100644 index 0000000000..a8506b45d5 --- /dev/null +++ b/module/artifactrepo/control.php @@ -0,0 +1,161 @@ + + * @package artifactrepo + * @version $Id$ + * @link https://www.qucheng.com + */ +class artifactrepo extends control +{ + /** + * Browse artifactrepo. + * + * @param int $param + * @param string $type + * @param string $orderBy + * @param int $recTotal + * @param int $recPerPage + * @param int $pageID + @access public + * @return void + */ + public function browse($browseType = 'all', $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 24, $pageID = 1) + { + /* Load pager. */ + $this->app->loadClass('pager', true); + $pager = new pager($recTotal, $recPerPage, $pageID); + + $artifactRepos = $this->artifactrepo->getList($orderBy, $pager); + + $this->view->title = $this->lang->artifactrepo->common; + $this->view->orderBy = $orderBy; + $this->view->pager = $pager; + $this->view->browseType = $browseType; + $this->view->artifactRepos = $artifactRepos; + $this->view->products = $this->loadModel('product')->getPairs('', 0, '', 'all'); + $this->view->pageLink = $this->createLink('artifactrepo', 'browse', "browseType={$browseType}&orderBy={$orderBy}&recTotal={$recTotal}&recPerPage={$recPerPage}&pageID={$pageID}"); + + $this->display(); + } + + /** + * 创建一个制品库。 + * Create a artifactrepo. + * + * @access public + * @return void + */ + public function create() + { + if($_POST) + { + $repo = form::data($this->config->artifactrepo->form->create) + ->join('products', ',') + ->add('createdBy', $this->app->user->account) + ->add('createdDate', helper::now()) + ->get(); + $repoID = $this->artifactrepo->create($repo); + if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); + + $this->loadModel('action')->create('artifactRepo', $repoID, 'created'); + return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browse'))); + } + + $nexusList = $this->loadModel('pipeline')->getPairs('nexus'); + + $this->view->title = $this->lang->artifactrepo->create; + $this->view->nexusList = $nexusList; + $this->view->products = $this->loadModel('product')->getPairs('', 0, '', 'all'); + + $this->display(); + } + + /** + * 编辑一个制品库。 + * Edit a artifact repo. + * + * @param int $artifactRepoID + * @access public + * @return viod + */ + public function edit(int $artifactRepoID) + { + if($_POST) + { + $repo = form::data($this->config->artifactrepo->form->edit) + ->join('products', ',') + ->add('editedBy', $this->app->user->account) + ->add('editedDate', helper::now()) + ->get(); + + $changes = $this->artifactrepo->update($repo, $artifactRepoID); + if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); + return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browse'))); + } + + $artifactRepo = $this->artifactrepo->getByID($artifactRepoID); + + $this->view->title = $this->lang->artifactrepo->edit; + $this->view->artifactRepo = $artifactRepo; + $this->view->products = $this->loadModel('product')->getPairs('', 0, '', 'all'); + + $this->display(); + } + + public function delete(int $artifactRepoID, string $confirm = 'no') + { + if($confirm == 'yes') + { + $this->artifactrepo->delete(TABLE_ARTIFACTREPO, $artifactRepoID); + if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); + + return $this->send(array('result' => 'success', 'load' => true)); + } + + } + + /** + * ajax方式获取版本库列表。 + * Get artifact repos by ajax. + * + * @param int $serverID + * @access public + * @return void + */ + public function ajaxGetArtifactRepos(int $serverID) + { + $repos = $this->artifactrepo->getServerRepos($serverID); + + return print(json_encode($repos)); + } + + public function ajaxUpdateArtifactRepos() + { + $artifactRepos = $this->artifactrepo->getList(); + $serverRepos = array(); + foreach($artifactRepos as $repo) + { + if(!isset($serverRepos[$repo->serverID])) $serverRepos[$repo->serverID] = $this->artifactrepo->getServerRepos($repo->serverID); + } + + $hasUpdate = false; + foreach($artifactRepos as $repo) + { + foreach($serverRepos[$repo->serverID] as $serverRepo) + { + $serverRepo->onlineStatus = $serverRepo->online ? 'online' : 'offline'; + if($serverRepo->name == $repo->repoName && $serverRepo->onlineStatus != $repo->status) + { + $this->artifactrepoZen->updateStatus($repo->id, $serverRepo->onlineStatus); + $hasUpdate = true; + } + } + } + + return print(json_encode(array('hasUpdate' => $hasUpdate))); + } +} diff --git a/module/artifactrepo/js/browse.ui.js b/module/artifactrepo/js/browse.ui.js new file mode 100644 index 0000000000..f6e9e98ca3 --- /dev/null +++ b/module/artifactrepo/js/browse.ui.js @@ -0,0 +1,15 @@ +$(function() +{ + $.get($.createLink('artifactrepo', 'ajaxUpdateArtifactRepos'), function(response) + { + data = JSON.parse(response); + if(data.hasUpdate) loadTable(pageLink); + }); +}); + +window.createSortLink = function(col) +{ + var sort = col.name + '_asc'; + if(sort == orderBy) sort = col.name + '_desc'; + return sortLink.replace('{orderBy}', sort); +} diff --git a/module/artifactrepo/js/create.ui.js b/module/artifactrepo/js/create.ui.js new file mode 100644 index 0000000000..8ce9d80e57 --- /dev/null +++ b/module/artifactrepo/js/create.ui.js @@ -0,0 +1,66 @@ +var repoData; + +/** + * Get artifactreos. + * + * @param event $event + * @access public + * @return viod + */ +function getArtifactRepo(event) +{ + const server = $(event.target).val(); + const url = $.createLink('artifactrepo', 'ajaxGetArtifactRepos', 'serverID=' + server); + + toggleLoading('#repoName', true); + $.get(url, function(response) + { + repoData = JSON.parse(response); + + var repoItems = []; + for(i in repoData) + { + repoItems.push({'text': repoData[i].name, 'value': repoData[i].name}); + } + $artifactRepo = $('#repoName').zui('picker'); + $artifactRepo.render({items: repoItems}); + $artifactRepo.$.clear(); + toggleLoading('#repoName', false); + }); +} + +/** + * Repo change event. + * + * @access public + * @return viod + */ +function onRepoChange() +{ + var repoName = $('[name=repoName]').val(); + if(!repoName) + { + $('#type').val(''); + $('#format').val(''); + $('#status').val(''); + $('#url').val(''); + return; + } + + for(i in repoData) + { + if(repoData[i].name == repoName) + { + $('#type').val(repoData[i].type); + $('#format').val(repoData[i].format); + $('#status').val(repoData[i].online ? 'online' : 'offline'); + $('#url').val(repoData[i].url); + } + } +} + +$(function() +{ + $('div.servers .form-label').addClass('required'); +}); + diff --git a/module/artifactrepo/lang/de.php b/module/artifactrepo/lang/de.php new file mode 100644 index 0000000000..50a10e3071 --- /dev/null +++ b/module/artifactrepo/lang/de.php @@ -0,0 +1,16 @@ +artifactrepo = new stdclass(); +$lang->artifactrepo->common = 'Browse artifact repo'; +$lang->artifactrepo->create = 'Add artifact repo'; +$lang->artifactrepo->edit = 'Edit artifact repo'; +$lang->artifactrepo->delete = 'Del artifact repo'; + +$lang->artifactrepo->name = 'Name'; +$lang->artifactrepo->serverID = 'Server'; +$lang->artifactrepo->repoName = 'Artifact Repo'; +$lang->artifactrepo->format = 'Artifact Type'; +$lang->artifactrepo->type = 'Type'; +$lang->artifactrepo->status = 'Status'; +$lang->artifactrepo->url = 'Repo Address'; + +$lang->artifactrepo->confirmDelete = 'Are you sure you want to delete this aritfact repo?'; diff --git a/module/artifactrepo/lang/en.php b/module/artifactrepo/lang/en.php new file mode 100644 index 0000000000..50a10e3071 --- /dev/null +++ b/module/artifactrepo/lang/en.php @@ -0,0 +1,16 @@ +artifactrepo = new stdclass(); +$lang->artifactrepo->common = 'Browse artifact repo'; +$lang->artifactrepo->create = 'Add artifact repo'; +$lang->artifactrepo->edit = 'Edit artifact repo'; +$lang->artifactrepo->delete = 'Del artifact repo'; + +$lang->artifactrepo->name = 'Name'; +$lang->artifactrepo->serverID = 'Server'; +$lang->artifactrepo->repoName = 'Artifact Repo'; +$lang->artifactrepo->format = 'Artifact Type'; +$lang->artifactrepo->type = 'Type'; +$lang->artifactrepo->status = 'Status'; +$lang->artifactrepo->url = 'Repo Address'; + +$lang->artifactrepo->confirmDelete = 'Are you sure you want to delete this aritfact repo?'; diff --git a/module/artifactrepo/lang/fr.php b/module/artifactrepo/lang/fr.php new file mode 100644 index 0000000000..50a10e3071 --- /dev/null +++ b/module/artifactrepo/lang/fr.php @@ -0,0 +1,16 @@ +artifactrepo = new stdclass(); +$lang->artifactrepo->common = 'Browse artifact repo'; +$lang->artifactrepo->create = 'Add artifact repo'; +$lang->artifactrepo->edit = 'Edit artifact repo'; +$lang->artifactrepo->delete = 'Del artifact repo'; + +$lang->artifactrepo->name = 'Name'; +$lang->artifactrepo->serverID = 'Server'; +$lang->artifactrepo->repoName = 'Artifact Repo'; +$lang->artifactrepo->format = 'Artifact Type'; +$lang->artifactrepo->type = 'Type'; +$lang->artifactrepo->status = 'Status'; +$lang->artifactrepo->url = 'Repo Address'; + +$lang->artifactrepo->confirmDelete = 'Are you sure you want to delete this aritfact repo?'; diff --git a/module/artifactrepo/lang/zh-cn.php b/module/artifactrepo/lang/zh-cn.php new file mode 100644 index 0000000000..7a9efa66ba --- /dev/null +++ b/module/artifactrepo/lang/zh-cn.php @@ -0,0 +1,16 @@ +artifactrepo = new stdclass(); +$lang->artifactrepo->common = '浏览制品库'; +$lang->artifactrepo->create = '添加制品库'; +$lang->artifactrepo->edit = '编辑制品库'; +$lang->artifactrepo->delete = '删除制品库'; + +$lang->artifactrepo->name = '名称'; +$lang->artifactrepo->serverID = '服务器'; +$lang->artifactrepo->repoName = '制品库'; +$lang->artifactrepo->format = '制品类型'; +$lang->artifactrepo->type = '类型'; +$lang->artifactrepo->status = '状态'; +$lang->artifactrepo->url = '库地址'; + +$lang->artifactrepo->confirmDelete = '您确认要删除该制品库吗?'; diff --git a/module/artifactrepo/model.php b/module/artifactrepo/model.php new file mode 100644 index 0000000000..190e534fee --- /dev/null +++ b/module/artifactrepo/model.php @@ -0,0 +1,134 @@ + + * @package artifactrepo + * @version $Id$ + * @link https://www.qucheng.com + */ +class artifactrepoModel extends model +{ + /** + * 根据id获取制品库。 + * Get artifactrepo by id. + * + * @param int $artifactRepoID + * @access public + * @return object + */ + public function getByID(int $artifactRepoID) + { + $artifactRepo = $this->dao->select('t1.*, t2.url, t2.name as serverName')->from(TABLE_ARTIFACTREPO)->alias('t1') + ->leftJoin(TABLE_PIPELINE)->alias('t2')->on('t1.serverID = t2.id') + ->where('t1.deleted')->eq(0) + ->andWhere('t1.id')->eq($artifactRepoID) + ->fetch(); + $artifactRepo->url .= 'repository/' . $artifactRepo->repoName; + + return $artifactRepo; + } + + /** + * 获取制品库列表。 + * Get artifactrepo repo list. + * + * @param string $orderBy + * @param object $pager + * @access public + * @return array + */ + public function getList($orderBy = 'id_desc', $pager = null) + { + $artifactRepos = $this->dao->select('t1.*, t2.id AS pipelineID, t2.url')->from(TABLE_ARTIFACTREPO)->alias('t1') + ->leftJoin(TABLE_PIPELINE)->alias('t2')->on('t1.serverID = t2.id') + ->where('t1.deleted')->eq(0) + ->orderBy($orderBy) + ->page($pager) + ->fetchAll('id'); + foreach($artifactRepos as $repo) + { + $repo->url .= 'repository/' . $repo->repoName; + } + + return $artifactRepos; + } + + /** + * 获取服务器上仓库列表。 + * Get server repos. + * + * @param int $serverID + * @access public + * @return array + */ + public function getServerRepos(int $serverID): array + { + $server = $this->loadModel('pipeline')->getByID($serverID); + if(!$server) return array(); + + if($server->type == 'nexus') + { + $url = $server->url . 'service/rest/v1/repositorySettings'; + $auth = "{$server->account}:{$server->password}"; + + $response = common::http($url, '', array(CURLOPT_USERPWD => $auth)); + $data = json_decode($response); + return $data; + } + + return array(); + } + + /** + * 创建一个制品库。 + * Create a artifact repo. + * + * @param object $repo + * @access public + * @return false|int + */ + public function create(object $artifactRepo): false|int + { + if(substr($artifactRepo->url, -1) != '/') $artifactRepo->url .= '/'; + $this->dao->insert(TABLE_ARTIFACTREPO)->data($artifactRepo) + ->check('repoName', 'unique', "serverID = {$artifactRepo->serverID} and repoName = '{$artifactRepo->repoName}'") + ->autoCheck() + ->exec(); + + if(dao::isError()) return false; + return $this->dao->lastInsertID(); + } + + /** + * 更新一个制品库。 + * Update a artifact repo. + * + * @param object $artifactRepo + * @param int $artifactRepoID + * @access public + * @return viod + */ + public function update(object $artifactRepo, $artifactRepoID): array|false + { + $oldArtifactRepo = $this->getByID($artifactRepoID); + + $this->dao->update(TABLE_ARTIFACTREPO)->data($artifactRepo) + ->autoCheck() + ->check('name', 'unique', "name = '{$artifactRepo->name}' and id != {$artifactRepoID}") + ->where('id')->eq($artifactRepoID) + ->exec(); + if(dao::isError()) return false; + + $changes = common::createChanges($oldArtifactRepo, $artifactRepo); + if($changes) + { + $actionID = $this->loadModel('action')->create('artifactRepo', $artifactRepoID, 'edited'); + $this->action->logHistory($actionID, $changes); + } + + return $changes; + } +} diff --git a/module/artifactrepo/ui/browse.html.php b/module/artifactrepo/ui/browse.html.php new file mode 100644 index 0000000000..2bf93ea6fe --- /dev/null +++ b/module/artifactrepo/ui/browse.html.php @@ -0,0 +1,59 @@ + + * @package artifact + * @link https://www.zentao.net + */ +namespace zin; + +jsVar('pageLink', $pageLink); +jsVar('orderBy', $orderBy); +jsVar('sortLink', $this->createLink('artifactrepo', 'browse', "browseType={$browseType}&orderBy={orderBy}&recTotal={$recTotal}&recPerPage={$recPerPage}")); + +$statusMap = array(); +$canCreate = hasPriv('artifactrepo', 'create'); + +foreach($artifactRepos as $repo) +{ + $repo->productNames = ''; + $productList = explode(',', str_replace(' ', '', $repo->products)); + if($productList) + { + foreach($productList as $productID) + { + if(!isset($products[$productID])) continue; + $repo->productNames .= ' ' . zget($products, $productID, $productID); + } + } +} +$artifactRepos = initTableData($artifactRepos, $config->artifactrepo->dtable->fieldList, $this->artifactrepo); + +featureBar +( +); + +toolBar +( + $canCreate ? item(set(array + ( + 'text' => $lang->artifactrepo->create, + 'icon' => 'plus', + 'class' => 'btn primary', + 'url' => createLink('artifactrepo', 'create'), + ))) : null, +); + +dtable +( + set::cols($config->artifactrepo->dtable->fieldList), + set::data($artifactRepos), + set::sortLink(jsRaw('createSortLink')), + set::footPager(usePager()), +); + +render(); + diff --git a/module/artifactrepo/ui/create.html.php b/module/artifactrepo/ui/create.html.php new file mode 100644 index 0000000000..5240ffd2ac --- /dev/null +++ b/module/artifactrepo/ui/create.html.php @@ -0,0 +1,77 @@ + + * @package artifactrepo + * @link https://www.zentao.net + */ +namespace zin; + +formPanel +( + set::title($lang->artifactrepo->create), + formGroup + ( + set::width('2/3'), + set::name('name'), + set::required(true), + set::label($lang->artifactrepo->name), + ), + formGroup + ( + set::name('products[]'), + set::label($lang->repo->product), + set::control(array('type' => 'picker', 'multiple' => true)), + set::items($products), + ), + formGroup + ( + set::width('2/3'), + setClass('servers'), + set::name('serverID'), + set::label($lang->artifactrepo->serverID), + set::items($nexusList), + on::change('getArtifactRepo'), + ), + formGroup + ( + set::width('2/3'), + set::name('repoName'), + set::required(true), + set::label($lang->devops->artifact), + set::items(array()), + on::change('onRepoChange'), + ), + formGroup + ( + set::width('2/3'), + set::name('type'), + set::label($lang->artifactrepo->type), + set::readonly(true), + input + ( + set::type('hidden'), + set::name('format'), + ), + ), + formGroup + ( + set::width('2/3'), + set::name('status'), + set::label($lang->artifactrepo->status), + set::readonly(true), + ), + formGroup + ( + set::width('2/3'), + set::name('url'), + set::label($lang->artifactrepo->url), + set::readonly(true), + ), +); + +render(); + diff --git a/module/artifactrepo/ui/edit.html.php b/module/artifactrepo/ui/edit.html.php new file mode 100644 index 0000000000..bf90713373 --- /dev/null +++ b/module/artifactrepo/ui/edit.html.php @@ -0,0 +1,71 @@ + + * @package artifactrepo + * @link https://www.zentao.net + */ +namespace zin; + +formPanel +( + set::title($lang->artifactrepo->edit), + formGroup + ( + set::width('2/3'), + set::name('name'), + set::required(true), + set::label($lang->artifactrepo->name), + set::value($artifactRepo->name), + ), + formGroup + ( + set::name('products[]'), + set::label($lang->repo->product), + set::control(array('type' => 'picker', 'multiple' => true)), + set::items($products), + set::value($artifactRepo->products), + ), + formGroup + ( + set::width('2/3'), + setClass('servers'), + set::label($lang->artifactrepo->serverID), + set::control('static'), + set::value($artifactRepo->serverName), + ), + formGroup + ( + set::width('2/3'), + set::label($lang->devops->artifact), + set::control('static'), + set::value($artifactRepo->repoName), + ), + formGroup + ( + set::width('2/3'), + set::label($lang->artifactrepo->type), + set::control('static'), + set::value($artifactRepo->type), + ), + formGroup + ( + set::width('2/3'), + set::label($lang->artifactrepo->status), + set::control('static'), + set::value($artifactRepo->status), + ), + formGroup + ( + set::width('2/3'), + set::label($lang->artifactrepo->url), + set::control('static'), + set::value($artifactRepo->url), + ), +); + +render(); + diff --git a/module/artifactrepo/zen.php b/module/artifactrepo/zen.php new file mode 100644 index 0000000000..20340888d3 --- /dev/null +++ b/module/artifactrepo/zen.php @@ -0,0 +1,30 @@ + + * @package artifactrepo + * @link https://www.zentao.net + */ +class artifactrepoZen extends artifactrepo +{ + /** + * 更新版本库状态。 + * Update artifact repo status. + * + * @param int $artifactRepoID + * @param string $status + * @access protected + * @return bool + */ + protected function updateStatus(int $artifactRepoID, string $status): bool + { + $this->dao->update(TABLE_ARTIFACTREPO)->set('status')->eq($status)->where('id')->eq($artifactRepoID)->exec(); + + return !dao::isError(); + } +} + diff --git a/module/common/lang/en.php b/module/common/lang/en.php index 28ec35f717..f498d23cc2 100644 --- a/module/common/lang/en.php +++ b/module/common/lang/en.php @@ -360,28 +360,26 @@ $lang->testcase->case = 'Test Case'; $lang->testcase->testsuite = 'Test Suite'; $lang->testcase->caselib = 'Case Library'; -$lang->devops->compile = 'Pipelines'; -$lang->devops->mr = 'Merge Request'; -$lang->devops->repo = 'Repo'; -$lang->devops->rules = 'Rule'; -$lang->devops->settings = 'Setting Merge Request'; -$lang->devops->platform = 'Platform'; -$lang->devops->set = 'Set'; -$lang->devops->artifact = 'Artifact'; -$lang->devops->environment = 'Environment'; -$lang->devops->resource = 'Resource'; -$lang->devops->dblist = 'Database'; -$lang->devops->domain = 'Domain'; -$lang->devops->oss = 'Oss'; -$lang->devops->host = 'Host'; -$lang->devops->account = 'Account'; -$lang->devops->serverroom = 'IDC'; -$lang->devops->deploy = 'Deploy'; -$lang->devops->service = 'Service'; -$lang->devops->provider = 'IDC Provider'; -$lang->devops->cpuBrand = 'CPU Brand'; -$lang->devops->city = 'IDC Location'; -$lang->devops->os = 'OS Version'; +$lang->devops->compile = 'Pipelines'; +$lang->devops->mr = 'Merge Request'; +$lang->devops->repo = 'Repo'; +$lang->devops->rules = 'Rule'; +$lang->devops->settings = 'Setting Merge Request'; +$lang->devops->platform = 'Platform'; +$lang->devops->set = 'Set'; +$lang->devops->artifactrepo = 'Artifact Repo'; +$lang->devops->environment = 'Environment'; +$lang->devops->resource = 'Resource'; +$lang->devops->dblist = 'Database'; +$lang->devops->domain = 'Domain'; +$lang->devops->oss = 'Oss'; +$lang->devops->host = 'Host'; +$lang->devops->account = 'Account'; +$lang->devops->serverroom = 'IDC'; +$lang->devops->provider = 'IDC Provider'; +$lang->devops->cpuBrand = 'CPU Brand'; +$lang->devops->city = 'IDC Location'; +$lang->devops->os = 'OS Version'; $lang->admin->module = 'Module'; $lang->admin->system = 'System'; diff --git a/module/common/lang/menu.php b/module/common/lang/menu.php index c942ee87a7..83603bedeb 100644 --- a/module/common/lang/menu.php +++ b/module/common/lang/menu.php @@ -486,7 +486,7 @@ $lang->devops->homeMenu = new stdclass(); //$lang->devops->homeMenu->dashboard = array('link' => "{$lang->dashboard}|system|dashboard"); $lang->devops->homeMenu->repos = array('link' => "{$lang->devops->repo}|repo|maintain", 'alias' => 'create,edit,import'); $lang->devops->homeMenu->compile = array('link' => "{$lang->devops->compile}|job|browse", 'subModule' => 'compile,job'); -$lang->devops->homeMenu->artifact = array('link' => "{$lang->devops->artifact}|artifact|browse"); +$lang->devops->homeMenu->artifactrepo = array('link' => "{$lang->devops->artifactrepo}|artifactrepo|browse", 'alias' => 'create'); if($config->edition != 'open') $lang->devops->homeMenu->deploy = array('link' => "{$lang->devops->deploy}|deploy|browse", 'subModule' => 'create,edit,browse,view'); diff --git a/module/common/lang/zh-cn.php b/module/common/lang/zh-cn.php index bb4bbda0f3..e50f8f993f 100644 --- a/module/common/lang/zh-cn.php +++ b/module/common/lang/zh-cn.php @@ -360,28 +360,26 @@ $lang->testcase->case = '用例'; $lang->testcase->testsuite = '套件'; $lang->testcase->caselib = '用例库'; -$lang->devops->compile = '流水线'; -$lang->devops->mr = '合并请求'; -$lang->devops->repo = '代码库'; -$lang->devops->rules = '指令'; -$lang->devops->settings = '合并请求设置'; -$lang->devops->platform = '平台'; -$lang->devops->set = '设置'; -$lang->devops->artifact = '制品库'; -$lang->devops->environment = '环境'; -$lang->devops->resource = '资源'; -$lang->devops->dblist = '数据库'; -$lang->devops->domain = '域名'; -$lang->devops->oss = '对象存储'; -$lang->devops->host = '主机'; -$lang->devops->account = '账号'; -$lang->devops->serverroom = '机房'; -$lang->devops->deploy = '上线'; -$lang->devops->service = '服务'; -$lang->devops->provider = '服务商'; -$lang->devops->cpuBrand = 'CPU品牌'; -$lang->devops->city = '城市'; -$lang->devops->os = '系统版本'; +$lang->devops->compile = '流水线'; +$lang->devops->mr = '合并请求'; +$lang->devops->repo = '代码库'; +$lang->devops->rules = '指令'; +$lang->devops->settings = '合并请求设置'; +$lang->devops->platform = '平台'; +$lang->devops->set = '设置'; +$lang->devops->artifactrepo = '制品库'; +$lang->devops->environment = '环境'; +$lang->devops->resource = '资源'; +$lang->devops->dblist = '数据库'; +$lang->devops->domain = '域名'; +$lang->devops->oss = '对象存储'; +$lang->devops->host = '主机'; +$lang->devops->account = '账号'; +$lang->devops->serverroom = '机房'; +$lang->devops->provider = '服务商'; +$lang->devops->cpuBrand = 'CPU品牌'; +$lang->devops->city = '城市'; +$lang->devops->os = '系统版本'; $lang->admin->module = '功能配置'; $lang->admin->system = '系统'; diff --git a/module/repo/view/setrules.html.php b/module/repo/view/setrules.html.php index c723577d34..67203a5cab 100644 --- a/module/repo/view/setrules.html.php +++ b/module/repo/view/setrules.html.php @@ -93,7 +93,6 @@ - goback, '', 'class="btn btn-wide"');?>