From 1d2734393870fff55123d650396f0f43d2bd01bc Mon Sep 17 00:00:00 2001 From: zhaoke Date: Tue, 19 Sep 2023 15:28:45 +0800 Subject: [PATCH 001/120] * Fix bug #38379. --- module/account/config/dtable.php | 1 + module/account/ui/browse.html.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/module/account/config/dtable.php b/module/account/config/dtable.php index 6609838678..696c01de3e 100644 --- a/module/account/config/dtable.php +++ b/module/account/config/dtable.php @@ -50,6 +50,7 @@ $config->account->actionList['edit']['icon'] = 'edit'; $config->account->actionList['edit']['text'] = $lang->edit; $config->account->actionList['edit']['hint'] = $lang->edit; $config->account->actionList['edit']['data-toggle'] = 'modal'; +$config->account->actionList['edit']['data-size'] = 'sm'; $config->account->actionList['edit']['showText'] = true; $config->account->actionList['edit']['url'] = array('module' => 'account', 'method' => 'edit', 'params' => 'id={id}'); diff --git a/module/account/ui/browse.html.php b/module/account/ui/browse.html.php index b7b295921f..e9262a5a19 100644 --- a/module/account/ui/browse.html.php +++ b/module/account/ui/browse.html.php @@ -22,7 +22,7 @@ featureBar /* zin: Define the toolbar on main menu. */ $canCreate = hasPriv('account', 'create'); $createLink = $this->createLink('account', 'create'); -$createItem = array('text' => $lang->account->create, 'url' => $createLink, 'class' => 'primary', 'icon' => 'plus', 'data-toggle' => 'modal'); +$createItem = array('text' => $lang->account->create, 'url' => $createLink, 'class' => 'primary', 'icon' => 'plus', 'data-toggle' => 'modal', 'data-size' => 'sm'); $tableData = initTableData($accountList, $config->account->dtable->fieldList, $this->account); From 5e4826ba4b9f61172ca42f3fe984d8f77c95aa4b Mon Sep 17 00:00:00 2001 From: liugang Date: Tue, 19 Sep 2023 16:19:32 +0800 Subject: [PATCH 002/120] * bug: fix that user can't sort the bugs in browse page by click table header, fix bug #38766. --- module/bug/view/browse.html.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/bug/view/browse.html.php b/module/bug/view/browse.html.php index eaa1a700db..c5f940bb2b 100644 --- a/module/bug/view/browse.html.php +++ b/module/bug/view/browse.html.php @@ -16,7 +16,7 @@ bug->generateCol($orderBy); $rows = $this->bug->generateRow($bugs, $branchOption, $modulePairs, $projectPairs, $plans, $executions, $stories, $tasks, $users); -$sortLink = $this->createLink('bug', 'browse', "productID=$productID&branch=$branch&browseType=$browseType¶m=$param&orderBy=$orderBy&recTotal=$pager->recTotal&recPerPage=$pager->recPerPage&pageID=$pager->pageID"); +$sortLink = $this->createLink('bug', 'browse', "productID=$productID&branch=$branch&browseType=$browseType¶m=$param&orderBy={orderBy}&recTotal=$pager->recTotal&recPerPage=$pager->recPerPage&pageID=$pager->pageID"); js::set('cols', json_encode($cols)); js::set('data', json_encode($rows)); From 3e11bab27c6b16a85426262b3b76f6a76d9f21e9 Mon Sep 17 00:00:00 2001 From: zhaoke Date: Tue, 19 Sep 2023 16:26:37 +0800 Subject: [PATCH 003/120] * Fix bug #102949. --- module/gitlab/control.php | 7 ++++++- module/gitlab/lang/de.php | 3 +++ module/gitlab/lang/en.php | 3 +++ module/gitlab/lang/fr.php | 3 +++ module/gitlab/lang/vi.php | 3 +++ module/gitlab/lang/zh-cn.php | 3 +++ module/gitlab/lang/zh-tw.php | 3 +++ 7 files changed, 24 insertions(+), 1 deletion(-) diff --git a/module/gitlab/control.php b/module/gitlab/control.php index a15892711d..f62b242719 100644 --- a/module/gitlab/control.php +++ b/module/gitlab/control.php @@ -626,7 +626,12 @@ class gitlab extends control { $this->gitlab->createUser($gitlabID); - if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); + if(dao::isError()) + { + $message = dao::getError(); + foreach($message as &$msg) if(is_string($msg)) $msg = zget($this->lang->gitlab->errorResonse, $msg, $msg); + return $this->send(array('result' => 'fail', 'message' => $message)); + } return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => inlink('browseUser', "gitlabID=$gitlabID"))); } diff --git a/module/gitlab/lang/de.php b/module/gitlab/lang/de.php index 0b370758e6..368a44f3af 100644 --- a/module/gitlab/lang/de.php +++ b/module/gitlab/lang/de.php @@ -118,6 +118,9 @@ $lang->gitlab->errorLang[4] = 'Branch already exists.'; $lang->gitlab->errorLang[5] = 'Failed to save group, path has already been taken.'; $lang->gitlab->errorLang[6] = $lang->gitlab->noAccess; +$lang->gitlab->errorResonse['Email has already been taken'] = 'Email has already been taken'; +$lang->gitlab->errorResonse['Username has already been taken'] = 'Username has already been taken'; + $lang->gitlab->project = new stdclass; $lang->gitlab->project->id = "Project ID"; $lang->gitlab->project->name = "Project name"; diff --git a/module/gitlab/lang/en.php b/module/gitlab/lang/en.php index 0b370758e6..368a44f3af 100644 --- a/module/gitlab/lang/en.php +++ b/module/gitlab/lang/en.php @@ -118,6 +118,9 @@ $lang->gitlab->errorLang[4] = 'Branch already exists.'; $lang->gitlab->errorLang[5] = 'Failed to save group, path has already been taken.'; $lang->gitlab->errorLang[6] = $lang->gitlab->noAccess; +$lang->gitlab->errorResonse['Email has already been taken'] = 'Email has already been taken'; +$lang->gitlab->errorResonse['Username has already been taken'] = 'Username has already been taken'; + $lang->gitlab->project = new stdclass; $lang->gitlab->project->id = "Project ID"; $lang->gitlab->project->name = "Project name"; diff --git a/module/gitlab/lang/fr.php b/module/gitlab/lang/fr.php index 9c21823d8a..77813e53ab 100644 --- a/module/gitlab/lang/fr.php +++ b/module/gitlab/lang/fr.php @@ -118,6 +118,9 @@ $lang->gitlab->errorLang[4] = 'Branch already exists.'; $lang->gitlab->errorLang[5] = 'Failed to save group, path has already been taken.'; $lang->gitlab->errorLang[6] = $lang->gitlab->noAccess; +$lang->gitlab->errorResonse['Email has already been taken'] = 'Email has already been taken'; +$lang->gitlab->errorResonse['Username has already been taken'] = 'Username has already been taken'; + $lang->gitlab->project = new stdclass; $lang->gitlab->project->id = "Project ID"; $lang->gitlab->project->name = "Project name"; diff --git a/module/gitlab/lang/vi.php b/module/gitlab/lang/vi.php index afddbeef4e..f36e3bc532 100644 --- a/module/gitlab/lang/vi.php +++ b/module/gitlab/lang/vi.php @@ -115,6 +115,9 @@ $lang->gitlab->errorLang[4] = 'Branch already exists.'; $lang->gitlab->errorLang[5] = 'Failed to save group, path has already been taken.'; $lang->gitlab->errorLang[6] = $lang->gitlab->noAccess; +$lang->gitlab->errorResonse['Email has already been taken'] = 'Email has already been taken'; +$lang->gitlab->errorResonse['Username has already been taken'] = 'Username has already been taken'; + $lang->gitlab->project = new stdclass; $lang->gitlab->project->id = "Project ID"; $lang->gitlab->project->name = "Project name"; diff --git a/module/gitlab/lang/zh-cn.php b/module/gitlab/lang/zh-cn.php index 46096a3737..d2585040ed 100644 --- a/module/gitlab/lang/zh-cn.php +++ b/module/gitlab/lang/zh-cn.php @@ -118,6 +118,9 @@ $lang->gitlab->errorLang[4] = '分支名已存在。'; $lang->gitlab->errorLang[5] = '保存失败,群组URL路径已经被使用。'; $lang->gitlab->errorLang[6] = $lang->gitlab->noAccess; +$lang->gitlab->errorResonse['Email has already been taken'] = '邮箱已存在'; +$lang->gitlab->errorResonse['Username has already been taken'] = '用户名已存在'; + $lang->gitlab->project = new stdclass; $lang->gitlab->project->id = "项目ID"; $lang->gitlab->project->name = "项目名称"; diff --git a/module/gitlab/lang/zh-tw.php b/module/gitlab/lang/zh-tw.php index 464a7c9401..84ea0371a8 100644 --- a/module/gitlab/lang/zh-tw.php +++ b/module/gitlab/lang/zh-tw.php @@ -106,6 +106,9 @@ $lang->gitlab->errorLang[3] = "只能包含字母、數字、'.'-'和'.'。不 $lang->gitlab->errorLang[4] = '分支名已存在。'; $lang->gitlab->errorLang[5] = '保存失敗,群組URL路徑已經被使用。'; +$lang->gitlab->errorResonse['Email has already been taken'] = '邮箱已存在'; +$lang->gitlab->errorResonse['Username has already been taken'] = '用户名已存在'; + $lang->gitlab->project = new stdclass; $lang->gitlab->project->id = "項目ID"; $lang->gitlab->project->name = "項目名稱"; From 41b4fb13948f8fbb62e20651e95bc550b42cc1f5 Mon Sep 17 00:00:00 2001 From: sunhao Date: Tue, 19 Sep 2023 16:55:33 +0800 Subject: [PATCH 004/120] * zui: update tree and fix sortable in tree not work. --- www/js/zui/min.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/js/zui/min.js b/www/js/zui/min.js index d20bb76bab..b890b45377 100644 --- a/www/js/zui/min.js +++ b/www/js/zui/min.js @@ -1,5 +1,5 @@ /*! - * ZUI: ZUI for Zentao - v1.10.0 - 2023-09-12 + * ZUI: ZUI for Zentao - v1.10.0 - 2023-09-19 * http://openzui.com * GitHub: https://github.com/easysoft/zui.git * Copyright (c) 2023 cnezsoft.com; Licensed MIT @@ -74,7 +74,7 @@ function(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"= * Original idea by: * Binny V A, http://www.openjs.com/scripts/events/keyboard_shortcuts/ */ -function(t){function e(e){if("string"==typeof e.data){var i=e.handler,n=e.data.toLowerCase().split(" ");e.handler=function(e){if(this===e.target||!/textarea|select/i.test(e.target.nodeName)&&"text"!==e.target.type){var o="keypress"!==e.type&&t.hotkeys.specialKeys[e.which],a=String.fromCharCode(e.which).toLowerCase(),s="",r={};e.altKey&&"alt"!==o&&(s+="alt+"),e.ctrlKey&&"ctrl"!==o&&(s+="ctrl+"),e.metaKey&&!e.ctrlKey&&"meta"!==o&&(s+="meta+"),e.shiftKey&&"shift"!==o&&(s+="shift+"),o?r[s+o]=!0:(r[s+a]=!0,r[s+t.hotkeys.shiftNums[a]]=!0,"shift+"===s&&(r[t.hotkeys.shiftNums[a]]=!0));for(var l=0,c=n.length;l","/":"?","\\":"|"}},t.each(["keydown","keyup","keypress"],function(){t.event.special[this]={add:e}})}(jQuery),function(t,e,i){"use strict";var n="zui.picker",o={},a={lang:null,remote:null,remoteConverter:null,remoteOnly:!1,onRemoteError:null,disableEmptySearch:!1,textKey:"text",valueKey:"value",keysKey:"keys",multi:"auto",formItem:"auto",list:null,allowSingleDeselect:null,autoSelectFirst:!1,maxSelectedCount:0,maxListCount:100,hideEmptyTextOption:!0,searchValueKey:!0,emptyResultHint:null,hideOnScroll:!0,inheritFormItemClasses:!1,emptySearchResultHint:null,accurateSearchHint:null,remoteErrorHint:null,deleteByBackspace:!0,disableScrollOnShow:!0,maxDropHeight:250,dropDirection:"auto",dropWidth:"100%",maxAutoDropWidth:450,minAutoDropWidth:100,multiValueSplitter:",",multiSelectActions:5,searchDelay:200,autoClearDrop:6e4,fixLabelFor:!0,hotkey:!0,onSelect:null,onDeselect:null,onBeforeChange:null,onChange:null,onReady:null,onNoResults:null,onShowingDrop:null,onHidingDrop:null,onShowedDrop:null,onHiddenDrop:null,valueMustInList:!0},s={zh_cn:{emptyResultHint:"没有可选项",emptySearchResultHint:"没有找到 “{0}”",accurateSearchHint:"请提供更多关键词缩小匹配范围",remoteErrorHint:"无法从服务器获取结果 - {0}",selectAll:"全选",deselectAll:"取消选择"},zh_tw:{emptyResultHint:"沒有可選項",emptySearchResultHint:"沒有找到 “{0}”",accurateSearchHint:"請提供更多關鍵詞縮小匹配範圍",remoteErrorHint:"無法從服務器獲取結果 - {0}",selectAll:"全選",deselectAll:"取消選擇"},en:{emptyResultHint:"No options",emptySearchResultHint:'Cannot found "{0}"',accurateSearchHint:"Suggest to provide more keywords",remoteErrorHint:"Unable to get result from server: {0}",selectAll:"Select all",deselectAll:"Deselect all"}},r=function(o,a){var l=this;l.name=n,l.$=t(o),l.id="pk_"+(l.$.attr("id")||t.zui.uuid()),a=l.options=t.extend({},r.DEFAULTS,this.$.data(),a),void 0!==a.hideOnWindowScroll&&(a.hideOnScroll=a.hideOnWindowScroll);var c=t.zui.clientLang?t.zui.clientLang():"en",h=a.lang||c;l.lang=t.zui.getLangData?t.zui.getLangData(n,h,s):s[h]||s[c];var d,u,p=a.formItem,f='.form-item,input[type="hidden"],select,input[type="text"]';if(d="self"===p?l.$:"auto"!==p&&p?l.$.find(p):l.$.is(f)?l.$:l.$.find(f).first(),!d.length)return console.error&&console.error("Cannot found form item for picker.");if(d.is('input[type="hidden"]'))u="hidden";else if(d.is("select"))u="select";else{if(!d.is('input[type="text"]'))return console.error&&console.error("Unknown form type for picker.");u="text"}a.inheritFormItemClasses&&v.addClass(d.attr("class")),l.formType=u,l.$formItem=d.removeClass("picker").hide(),l.selfFormItem=d.is(l.$);var g=a.multi;g&&"auto"!==g||(g="select"===u&&"multiple"===d.attr("multiple")),g=!!g,l.multi=g,g||(l.options.checkable=!1);var m=a.list;m?l.setList("function"==typeof m?m({search:l.search,limit:a.maxListCount}):m,!0):"select"===u?l.updateFromSelect():l.setList([],!0);var v;v=!l.selfFormItem&&l.$.hasClass("picker")?l.$:t('
').insertAfter(l.$),v.addClass("picker").toggleClass("picker-multi",g).toggleClass("picker-single",!g);var y=v.children(".picker-selections");y.length?y.empty():y=t('
');var b=l.id+"-search",w=t('').appendTo(y);if(!g){var x=t('
');a.allowSingleDeselect&&x.append(''),x.appendTo(y),l.$singleSelection=x}v.toggleClass("picker-input-empty",!w.val().length).append(y),l.$container=v,l.$selections=y,l.$search=w,l.search="";var C=a.placeholder;if(void 0===C&&(C=d.attr("placeholder")),"string"==typeof C&&C.length&&y.append(t('
').text(C)),a.placeholder=C,a.fixLabelFor){var k=d.attr("id");k&&t('label[for="'+k+'"]').attr("for",b)}var _=void 0!==a.defaultValue?a.defaultValue:d.val();if(null===_&&(_=""),l.setValue(_,!0),l.setDisabled(),w.on("focus",function(){l.disabled||(l._blurTimer&&(clearTimeout(l._blurTimer),l._blurTimer=0),v.addClass("picker-focus"),l.options.disableEmptySearch&&"string"==typeof l.search&&!l.search.length||l.showDropList())}).on("blur",function(){l.disabled||(l._blurTimer&&clearTimeout(l._blurTimer),l._blurTimer=setTimeout(function(){l._blurTimer=0,w.is(":focus")||v.removeClass("picker-focus")},100))}).on("input change",function(){if(!l.disabled){var t=w.val();if(g&&w.width(14*t.length),v.toggleClass("picker-input-empty",!t.length),l.tryUpdateList(t),a.disableEmptySearch){const e="string"!=typeof t||t.length;!l.dropListShowed&&e?l.showDropList():l.dropListShowed&&!e&&l.hideDropList()}}}),a.hotkey&&w.on("keydown",function(t){if(!l.disabled){var e=t.key||t.which;if(l.dropListShowed){var i=l.activeValue,n="string"==typeof i;if("Enter"===e||13===e)n&&(l.select(i,g),g?(l.$search.val(""),l.tryUpdateList("")):w.blur(),t.preventDefault(),t.stopPropagation());else if("ArrowDown"===e||40===e){var o,s=l.$activeOption;if(s&&(o=s.next(".picker-option"),g))for(;o.length&&o.hasClass("picker-option-selected");)o=o.next(".picker-option");o&&o.length||(o=l.$optionsList.children(g?".picker-option:not(.picker-option-selected)":".picker-option").first()),o.length&&l.activeOption(o),t.preventDefault(),t.stopPropagation()}else if("ArrowUp"===e||30===e){var r,s=l.$activeOption;if(s&&(r=s.prev(".picker-option"),g))for(;r.length&&r.hasClass("picker-option-selected");)r=r.prev(".picker-option");r&&r.length||(r=l.$optionsList.children(g?".picker-option:not(.picker-option-selected)":".picker-option").last()),r.length&&l.activeOption(r),t.preventDefault(),t.stopPropagation()}else"Escape"===e||27===e?l.hideDropList(!0):a.deleteByBackspace&&g&&("Backspace"===e||8===e)&&l.value&&l.value.length&&!w.val().length&&l.deselect(l.value[l.value.length-1])}}}),g){y.on("mousedown",function(t){if(!l.disabled)return l.dropListShowed&&!a.checkable?(t.preventDefault(),void t.stopPropagation()):void 0}).on("mouseup",function(e){l.disabled||y.hasClass("sortable-sorting")||t(e.target).closest(".picker-selection-remove").length||l.dropListShowed&&!a.checkable||l.focus()});var T=a.sortValuesByDnd;if(T&&t.fn.sortable){v.addClass("picker-sortable");var S={selector:".picker-selection",stopPropagation:!0,start:function(){l.hideDropList(!0)},finish:function(e){var i=[];t.each(e.list,function(t,e){i.push(e.item.data("value"))}),l.setValue(i.slice(),!1,!0)}};"object"==typeof T&&t.extend(S,T),y.sortable(S)}}if(y.on("click",".picker-selection-remove",function(e){if(!l.disabled){if(l.multi){var i=t(this).closest(".picker-selection");l.deselect(i.data("value"))}else l.deselect();e.stopPropagation()}}),d.on("chosen:updated",function(){l.updateFromSelect(!1),l.setValue(d.val(),!0),l.setDisabled(),l.updateList()}).on("chosen:activate",l.focus).on("chosen:open",l.showDropList).on("chosen:close",l.hideDropList),v.addClass("picker-ready"),t.zui.asap(function(){l.triggerEvent("ready",{picker:l},"","chosen:ready")}),!a.disableScrollOnShow){var D=a.hideOnScroll;D&&![e,i,!0].includes(D)&&t(D).on("scroll",this.handleParentScroll.bind(this))}};r.prototype.destroy=function(){var e=this,i=e.options;e.hideDropList(!0);var o=e.$search;o.off("focus blur input change"),i.hotkey&&o.off("keydown"),o.remove();var a=e.$selections;a.off("click"),e.multi&&a.off("mousedown mouseup"),a.remove();var s=e.$formItem;e.selectOptionsBackup&&(s.empty(),t.each(e.selectOptionsBackup,function(e,n){var o={value:n[i.valueKey]},a=n[i.keysKey];void 0!==a&&(o["data-"+i.keysKey]=a),s.append(t("
diff --git a/module/install/view/progress.html.php b/module/install/view/progress.html.php new file mode 100644 index 0000000000..ebef4affa9 --- /dev/null +++ b/module/install/view/progress.html.php @@ -0,0 +1,60 @@ + + * @package install + * @link http://www.zentao.net + */ +?> + + + +id);?> +status, array('installing', 'installed', 'finish')));?> +solution->notices);?> +solution->errors);?> +solution->install);?> +solution->config);?> + + +
+ +
+ +app->getModuleRoot() . '/common/view/footer.html.php';?> diff --git a/module/install/view/step5.html.php b/module/install/view/step5.html.php index 5a25294b58..01eb3e9874 100644 --- a/module/install/view/step5.html.php +++ b/module/install/view/step5.html.php @@ -67,7 +67,7 @@ install->importDemoData);?> - + inQuickon ? $lang->install->next : $lang->save);?> diff --git a/module/solution/config.php b/module/solution/config.php new file mode 100644 index 0000000000..8e88853748 --- /dev/null +++ b/module/solution/config.php @@ -0,0 +1,5 @@ +solution = new stdclass(); + +$config->solution->gitlab = new stdclass(); +$config->solution->gitlab->minCompatibleVersion = '9.0'; diff --git a/module/solution/lang/zh-cn.php b/module/solution/lang/zh-cn.php new file mode 100644 index 0000000000..1220e55343 --- /dev/null +++ b/module/solution/lang/zh-cn.php @@ -0,0 +1,63 @@ +solution->market = new stdclass; +$lang->solution->market->browse = '解决方案市场'; +$lang->solution->market->view = '解决方案详情'; + +$lang->solution->name = '名称'; + +$lang->solution->browse = '已安装'; +$lang->solution->view = '解决方案详情'; +$lang->solution->detail = '查看'; +$lang->solution->progress = '安装进度'; +$lang->solution->install = '安装'; +$lang->solution->cancelInstall = '取消安装'; +$lang->solution->uninstall = '卸载'; +$lang->solution->retryInstall = '重试'; +$lang->solution->nextStep = '下一步'; +$lang->solution->config = '配置'; + +$lang->solution->introduction = '基本介绍'; +$lang->solution->scenes = '适用场景'; +$lang->solution->diagram = '架构图'; +$lang->solution->includedApp = '包含应用'; +$lang->solution->features = '方案亮点'; +$lang->solution->relatedLinks = '相关链接'; +$lang->solution->customers = '典型客户'; +$lang->solution->apps = '安装的应用'; +$lang->solution->externalApps = '外部应用'; +$lang->solution->resources = '资源占用'; + +$lang->solution->editName = '修改名称'; + +$lang->solution->chooseApp = '请选择要安装的应用'; +$lang->solution->noInstalledSolution = '还没有安装解决方案'; +$lang->solution->toInstall = '去安装'; + +$lang->solution->notices = new stdclass; +$lang->solution->notices->fail = '失败'; +$lang->solution->notices->success = '成功'; +$lang->solution->notices->creatingSolution = '正在创建解决方案。'; +$lang->solution->notices->uninstallingSolution = '正在卸载解决方案'; +$lang->solution->notices->installingApp = '正在安装:'; +$lang->solution->notices->installationSuccess = '解决方案安装成功!'; +$lang->solution->notices->cancelInstall = '确定要取消安装吗?'; +$lang->solution->notices->confirmToUninstall = '确定要卸载吗?'; +$lang->solution->notices->confirmReinstall = '确定要重试安装吗?'; + +$lang->solution->errors = new stdclass; +$lang->solution->errors->error = '错误'; +$lang->solution->errors->notFound = '找不到相关数据'; +$lang->solution->errors->failToInstallApp = '安装%s应用失败'; +$lang->solution->errors->timeout = '安装超时'; +$lang->solution->errors->failToUninstallApp = '卸载%s应用失败'; +$lang->solution->errors->hasInstallationError = '安装过程中发生错误'; +$lang->solution->errors->notFoundAppByVersion = '找不到%s版本的%s应用'; +$lang->solution->errors->notEnoughResource = '资源不足, 请增加配置或释放其它资源后重试。'; + +$lang->solution->installationErrors = array(); +$lang->solution->installationErrors['waiting'] = '安装未开始。'; +$lang->solution->installationErrors['uninstalling'] = '安装已取消。'; +$lang->solution->installationErrors['cneError'] = '安装失败。'; +$lang->solution->installationErrors['timeout'] = '安装超时。'; +$lang->solution->installationErrors['notFoundApp'] = '找不到待安装的应用。'; +$lang->solution->installationErrors['notEnoughResource'] = '资源不足, 请增加配置或释放其它资源后重试。'; diff --git a/module/solution/model.php b/module/solution/model.php new file mode 100644 index 0000000000..2e29475a30 --- /dev/null +++ b/module/solution/model.php @@ -0,0 +1,517 @@ + + * @package solution + * @version $Id$ + * @link https://www.qucheng.com + */ +class solutionModel extends model +{ + /** + * Get solution by id. + * + * @param int $id + * @access public + * @return object|null + */ + public function getByID($id) + { + $solution = $this->dao->select('*')->from(TABLE_SOLUTION)->where('id')->eq($id)->fetch(); + if(!$solution) return null; + + $instanceIDList = $this->dao->select('id')->from(TABLE_INSTANCE)->where('solution')->eq($id)->fetchAll('id'); + + $solution->instances = array(); + if($instanceIDList) $solution->instances = $this->loadModel('instance')->getByIDList(array_keys($instanceIDList)); + + return $solution; + } + + /** + * Search + * + * @param string $keyword + * @access public + * @return array + */ + public function search($keyword = '') + { + return $this->dao->select('*')->from(TABLE_SOLUTION) + ->where('deleted')->eq(0) + ->beginIF($keyword)->andWhere('name')->like($keyword)->fi() + ->orderBy('createdAt desc')->fetchAll(); + } + + /** + * Update solution name. + * + * @param int $solutionID + * @access public + * @return int + */ + public function updateName($solutionID) + { + $newSolution = fixer::input('post')->trim('name')->get(); + + return $this->dao->update(TABLE_SOLUTION)->data($newSolution)->autoCheck()->where('id')->eq($solutionID)->exec(); + } + + /** + * Create by solution of cloud market. + * + * @param object $cloudSolution + * @access public + * @return object + */ + public function create($cloudSolution, $components) + { + $postedCharts = $this->session->solutionCharts == '' ? fixer::input('post')->get() : $this->session->solutionCharts; + + /* Sort selected apps. */ + $orderedCategories = $components->order; + $selectedApps = array(); + foreach($orderedCategories as $category) + { + $chart = zget($postedCharts, $category); + + $selectedApps[$category] = $this->pickAppFromSchema($components, $category, $chart, $cloudSolution); + if(empty($selectedApps[$category])) unset($selectedApps[$category]); + } + + /* Create solution. */ + $solution = new stdclass; + $solution->name = $cloudSolution->title; + $solution->appID = $cloudSolution->id; + $solution->appName = $cloudSolution->name; + $solution->appVersion = $cloudSolution->app_version; + $solution->version = $cloudSolution->version; + $solution->chart = $cloudSolution->chart; + $solution->cover = $cloudSolution->background_url; + $solution->introduction = $cloudSolution->introduction; + $solution->desc = $cloudSolution->description; + $solution->status = 'waiting'; + $solution->source = 'cloud'; + $solution->components = json_encode($selectedApps); + $solution->createdBy = $this->app->user->account; + $solution->createdAt = date('Y-m-d H:i:s'); + + $channel = $this->app->session->cloudChannel ? $this->app->session->cloudChannel : $this->config->cloud->api->channel; + + $solution->channel = $channel; + + $this->dao->insert(TABLE_SOLUTION)->data($solution)->exec(); + + if(dao::isError()) return null; + + return $this->getByID($this->dao->lastInsertID()); + } + + /** + * Pick App from schema info by category and chart. + * + * @param object $schema + * @param string $category + * @param string $chart + * @param object $cloudSolution + * @access public + * @return object|null + */ + public function pickAppFromSchema($schema, $category, $chart, $cloudSolution) + { + $categoryList = helper::arrayColumn($schema->category, null, 'name'); + $appGroup = zget($categoryList, $category, array()); + + foreach($appGroup->choices as $appInSchema) + { + + if($appInSchema->name != $chart) continue; + + $appInfo = zget($cloudSolution->apps, $chart); + + $appInfo->version = $appInSchema->version; + $appInfo->app_version = $appInSchema->app_version; + $appInfo->status = 'waiting'; + + return $appInfo; + } + + return; + } + + /** + * Install solution. + * + * @param int $solutionID + * @access public + * @return bool + */ + public function install($solutionID) + { + set_time_limit(0); + session_write_close(); + + $solution = $this->getByID($solutionID); + if(!$solution) + { + dao::$errors[] = $this->lang->solution->errors->notFound; + return false; + } + if(in_array($solution->status, array('installing', 'installed', 'uninstalled'))) return false; + $this->saveStatus($solutionID, 'installing'); + + $this->loadModel('cne'); + $this->loadModel('instance'); + $this->loadModel('store'); + $this->loadModel('common'); + $allMappings = array(); + $solutionSchema = $this->loadModel('store')->solutionConfig('id', $solution->appID); + $channel = $this->app->session->cloudChannel ? $this->app->session->cloudChannel : $this->config->cloud->api->channel; + $components = json_decode($solution->components); + foreach($components as $categorty => $componentApp) + { + $solutionStatus = $this->dao->select('status')->from(TABLE_SOLUTION)->where('id')->eq($solutionID)->fetch(); + if($solutionStatus->status !='installing') + { + /* If status is not installing, should abort installation. Becaust installation was canceled or error happened. */ + dao::$errors[] = $this->lang->solution->errors->hasInstallationError; + return false; + } + + $instance = $this->instance->instanceOfSolution($solution, $componentApp->chart); + /* If not install. */ + if(!$instance) + { + $cloudApp = $this->store->getAppInfo($componentApp->id, false, '', $componentApp->version, $channel); + if(!$cloudApp) + { + $this->saveStatus($solutionID, 'notFoundApp'); + dao::$errors[] = sprintf($this->lang->solution->errors->notFoundAppByVersion, $componentApp->version, $componentApp->alias); + return false; + } + /* Must install the defineded version in solution schema. */ + $cloudApp->version = $componentApp->version; + $cloudApp->app_version = $componentApp->app_version; + + if($componentApp->external) + { + $instance = $this->installExternalApp($cloudApp, $componentApp->external); + } + else + { + /* Check enough memory to install app, or not.*/ + if(!$this->instance->enoughMemory($cloudApp)) + { + $this->saveStatus($solutionID, 'notEnoughResource'); + dao::$errors[] = $this->lang->solution->errors->notEnoughResource; + return false; + } + + if(!$this->checkInstallStatus($solutionID)) return false; + $settings = $this->mountSettings($solutionSchema, $componentApp->chart, $components, $allMappings); + $instance = $this->installApp($cloudApp, $settings); + } + + if(!$instance) + { + $this->saveStatus($solutionID, 'cneError'); + dao::$errors[] = sprintf($this->lang->solution->errors->failToInstallApp, $cloudApp->name); + return false; + } + $this->dao->update(TABLE_INSTANCE)->set('solution')->eq($solutionID)->where('id')->eq($instance->id)->exec(); + + $componentApp->status = 'installing'; + $this->dao->update(TABLE_SOLUTION)->set('components')->eq(json_encode($components))->where('id')->eq($solution->id)->exec(); + } + + if($componentApp->external) + { + $tempMappings = $this->getExternalMapping($solutionSchema, $componentApp); + if($tempMappings) $allMappings[$categorty] = $tempMappings; + + $componentApp->status = 'configured'; + $this->dao->update(TABLE_SOLUTION)->set('components')->eq(json_encode($components))->where('id')->eq($solution->id)->exec(); + continue; + } + + /* Wait instanlled app started. */ + $instance = $this->waitInstanceStart($instance, $solutionID); + if($instance) + { + $mappingKeys = zget($solutionSchema->mappings, $instance->chart, ''); + if($mappingKeys) + { + /* Load settings mapping of installed app for next app. */ + $tempMappings = $this->cne->getSettingsMapping($instance, $mappingKeys); + if($tempMappings) $allMappings[$categorty] = $tempMappings; + } + $componentApp->status = 'installed'; + $this->dao->update(TABLE_SOLUTION)->set('components')->eq(json_encode($components))->where('id')->eq($solution->id)->exec(); + } + else + { + $this->saveStatus($solutionID, 'timeout'); + dao::$errors[] = $this->lang->solution->errors->timeout; + return false; + } + } + + $this->saveStatus($solutionID, 'installed'); + return true; + } + + /** + * Save status. + * + * @param int $solutionID + * @param string $status + * @access public + * @return int + */ + public function saveStatus($solutionID, $status) + { + return $this->dao->update(TABLE_SOLUTION)->set('status')->eq($status)->set('updatedDate')->eq(date("Y-m-d H:i:s"))->where('id')->eq($solutionID)->exec(); + } + + /** + * Mount settings for installing app. + * + * @param object $solutionSchema + * @param string $chart + * @param object $components + * @param array $mappings example: ['git' => ['env.GIT_USERNAME' => 'admin', ...], ...] + * @access private + * @return array + */ + private function mountSettings($solutionSchema, $chart, $components, $mappings) + { + $settings = array(); + + $appSettings = zget($solutionSchema->settings, $chart, array()); + foreach($appSettings as $item) + { + switch($item->type) + { + case 'static': + $settings[] = array('key' => $item->key, 'value' => $item->value); + break; + case 'choose': + $appInfo = zget($components, $item->target, ''); + if($appInfo) $settings[] = array('key' => $item->key, 'value' => $appInfo->chart); + break; + case 'mappings': + $mappingInfo = zget($mappings, $item->target, ''); + if($mappingInfo) $settings[] = array('key' => $item->key, 'value' => zget($mappingInfo, $item->key, '')); + break; + } + } + + return $settings; + } + + /** + * installApp + * + * @param object $cloudApp + * @param int $settings + * @access private + * @return mixed + */ + private function installApp($cloudApp, $settings) + { + /* Fake parameters for installation. */ + + $customData = new stdclass; + $customData->customName = $cloudApp->alias; + $customData->dbType = null; + $customData->customDomain = $this->loadModel('instance')->randThirdDomain(); + + $dbInfo = new stdclass; + $dbList = $this->loadModel('cne')->sharedDBList(); + if(count($dbList) > 0) + { + $dbInfo = reset($dbList); + + $customData->dbType = 'sharedDB'; + $customData->dbService = $dbInfo->name; // Use first shared database. + } + + return $this->instance->install($cloudApp, $dbInfo, $customData, null, $settings); + } + + /** + * Wait instance started. + * + * @param object $instance + * @access private + * @return object|bool + */ + private function waitInstanceStart($instance, $solutionID) + { + /* Query status of the installed instance. */ + $times = 0; + for($times = 0; $times < 50; $times++) + { + if(!$this->checkInstallStatus($solutionID)) return false; + $this->dao->update(TABLE_SOLUTION)->set('updatedDate')->eq(date("Y-m-d H:i:s"))->where('id')->eq($solutionID)->exec(); + + sleep(12); + $instance = $this->instance->freshStatus($instance); + $this->saveLog(date('Y-m-d H:i:s').' installing ' . $instance->name . ':' . $instance->status . '#' . $instance->solution); // Code for debug. + if($instance->status == 'running') return $instance; + } + + return false; + } + + /** + * Check solution status. + * + * @param int $solutionID + * @access public + * @return void + */ + public function checkInstallStatus($solutionID) + { + $solution = $this->getByID($solutionID); + if($solution->status != 'installing') return false; + return true; + } + + /** + * Uninstall solution and all included instances . + * + * @param int $solutionID + * @access public + * @return void + */ + public function uninstall($solutionID) + { + $this->loadModel('instance'); + /* Firstly change the status to 'unintalling' for abort installing process. */ + $this->dao->update(TABLE_SOLUTION)->set('status')->eq('uninstalling')->where('id')->eq($solutionID)->exec(); + + $solution = $this->getByID($solutionID); + if(empty($solution)) + { + dao::$errors[] = $this->lang->solution->notFound; + return; + } + + foreach($solution->instances as $instance) + { + $success = $this->instance->uninstall($instance); + if(!$success) + { + dao::$errors[] = sprintf($this->lang->solution->errors->failToUninstallApp, $instance->name); + return; + } + } + + $this->dao->update(TABLE_SOLUTION)->set('status')->eq('uninstalled')->set('deleted')->eq(1)->where('id')->eq($solutionID)->exec(); + } + + /** + * Convert schema choices to select options. + * + * @param object $schemaChoices + * @param object $cloudSolution + * @access public + * @return array + */ + public function createSelectOptions($schemaChoices, $cloudSolution) + { + $options = array(); + foreach($schemaChoices as $cloudApp) + { + $appInfo = zget($cloudSolution->apps, $cloudApp->name); + $options[$cloudApp->name] = zget($appInfo, 'alias', $cloudApp->name); + } + + return $options; + } + + /** + * Print CPU usage. + * + * @param object $solution + * @param object $metrics + * @param string $type 'bar' is progress bar, 'pie' is progress pie. + * @static + * @access public + * @return viod + */ + public function printCpuUsage($solution, $type = 'bar') + { + /* Calculate total usage of all instances. */ + $totalRate = 0; + $totalUsage = 0; + $totalLimit = 0; + $instancesMetric = $this->loadModel('cne')->instancesMetrics($solution->instances); + foreach($instancesMetric as $metric) + { + $totalRate += $metric->cpu->rate; + $totalUsage += $metric->cpu->usage; + $totalLimit += $metric->cpu->limit; + } + + $totalRate = round($totalRate / count($solution->instances), 2); + + $tip = "{$totalRate}% = {$totalUsage} / {$totalLimit}"; + + if(strtolower($type) == 'pie') return commonModel::printProgressPie($totalRate, '', $tip); + + return commonModel::printProgressBar($totalRate, '', $tip, 'percent'); + } + + /** + * Print memory usage. + * + * @param object $solution + * @param object $metrics + * @param string $type 'bar' is progress bar, 'pie' is progress pie. + * @static + * @access public + * @return viod + */ + public function printMemUsage($solution, $type = 'bar') + { + /* Calculate total usage of all instances. */ + $totalRate = 0; + $totalUsage = 0; + $totalLimit = 0; + $instancesMetric = $this->loadModel('cne')->instancesMetrics($solution->instances); + foreach($instancesMetric as $metric) + { + $totalRate += $metric->memory->rate; + $totalUsage += $metric->memory->usage; + $totalLimit += $metric->memory->limit; + } + + $totalRate = round($totalRate / count($solution->instances), 2); + + $tip = "{$totalRate}% = {$totalUsage} / {$totalLimit}"; + + if(strtolower($type) == 'pie') return commonModel::printProgressPie($totalRate, '', $tip); + + return commonModel::printProgressBar($totalRate, '', $tip, 'percent'); + } + + /** + * Save message to error log file. + * + * @param string $message + * @access public + * @return void + */ + public function saveLog($message) + { + $errorFile = $this->app->logRoot . 'php.' . date('Ymd') . '.log.php'; + if(!is_file($errorFile)) file_put_contents($errorFile, "\n"); + + file_put_contents($errorFile, $message . "\n", FILE_APPEND); + } +} diff --git a/module/store/model.php b/module/store/model.php index 553485259b..3ac04a13cf 100644 --- a/module/store/model.php +++ b/module/store/model.php @@ -101,6 +101,26 @@ class storeModel extends model return $result->data; } + /** + * Get app infos map by name array from cloud market. + * 根据名称查询多个应用信息。 + * + * @param array $nameList + * @access public + * @return object|null + */ + public function getAppMapByNames($nameList = array(), $channel = 'stable') + { + $apiParams = array('name_list' => $nameList, 'channel' => $channel); + + $apiUrl = $this->config->cloud->api->host; + $apiUrl .= '/api/market/app_info_list'; + $result = commonModel::apiPost($apiUrl, $apiParams, $this->config->cloud->api->headers); + if(!isset($result->code) || $result->code != 200) return null; + + return $result->data; + } + /** * Get app version pairs by id. * @@ -383,21 +403,22 @@ class storeModel extends model } /** - * Get solution info by ID. + * Get solution info. * - * @param int $id + * @param string $type + * @param int|string $value * @access public * @return object */ - public function getSolutionByID($id) + public function getSolution($type, $value) { $apiParams = array(); - $apiParams['id'] = $id; + $apiParams[$type] = $value; $apiUrl = $this->config->cloud->api->host; $apiUrl .= '/api/market/solution/info?channel='. $this->config->cloud->api->channel; $result = commonModel::apiGet($apiUrl, $apiParams, $this->config->cloud->api->headers); - if(!isset($result->code) || $result->code != 200) return null; + if(!isset($result->code) || $result->code != 200) return new stdclass(); $solution = $result->data; $solution->apps = array_combine(helper::arrayColumn($solution->apps, 'chart'), $solution->apps); @@ -405,21 +426,22 @@ class storeModel extends model return $solution; } /** - * Get solution config by ID. + * Get solution config. * - * @param int $id + * @param string $type + * @param int|string $value * @access public * @return object */ - public function solutionConfigByID($id) + public function solutionConfig($type, $value) { $apiParams = array(); - $apiParams['id'] = $id; + $apiParams[$type] = $value; $apiUrl = $this->config->cloud->api->host; $apiUrl .= '/api/market/solution/schema?channel='. $this->config->cloud->api->channel; $result = commonModel::apiGet($apiUrl, $apiParams, $this->config->cloud->api->headers); - if(!isset($result->code) || $result->code != 200) return null; + if(!isset($result->code) || $result->code != 200) return new stdclass(); return $result->data; } From 225133c8743d5dac8effc6282a5c7f2eb4c89216 Mon Sep 17 00:00:00 2001 From: qixinzhi Date: Fri, 22 Sep 2023 08:20:32 +0000 Subject: [PATCH 036/120] * Add metric calculate cron. --- db/update18.7.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/db/update18.7.sql b/db/update18.7.sql index 71e8a9bd66..b8161a6ec2 100644 --- a/db/update18.7.sql +++ b/db/update18.7.sql @@ -566,3 +566,5 @@ ALTER TABLE `zt_project` ADD `firstEnd` date DEFAULT NULL AFTER `end`; ALTER TABLE `zt_product` ADD `closedDate` date DEFAULT NULL AFTER `createdVersion`; ALTER TABLE `zt_productplan` ADD `finishedDate` datetime DEFAULT NULL AFTER `end`; ALTER TABLE `zt_productplan` ADD `closedDate` datetime DEFAULT NULL AFTER `finishedDate`; + +INSERT INTO `zt_cron`(`m`, `h`, `dom`, `mon`, `dow`, `command`, `remark`, `type`, `buildin`, `status`, `lastTime`) VALUES ('59', '23', '*', '*', '*', 'moduleName=metric&methodName=updateMetricLib', '计算度量数据', 'system', 1, 'normal', '0000-00-00 00:00:00'); From d2c54dc8255bf746191e5698bc04ebda01a0d7d3 Mon Sep 17 00:00:00 2001 From: songchenxuan <1097180981@qq.com> Date: Thu, 21 Sep 2023 23:56:11 +0800 Subject: [PATCH 037/120] * Add metric privs. --- module/group/lang/en.php | 1 + module/group/lang/resource.php | 20 ++++++++++++++++++-- module/group/lang/zh-cn.php | 1 + module/group/packagemanager.php | 13 +++++++++++++ module/metric/lang/de.php | 5 ++++- module/metric/lang/en.php | 5 ++++- module/metric/lang/fr.php | 5 ++++- module/metric/lang/zh-cn.php | 5 ++++- 8 files changed, 49 insertions(+), 6 deletions(-) diff --git a/module/group/lang/en.php b/module/group/lang/en.php index 1f491902f9..573eadde36 100644 --- a/module/group/lang/en.php +++ b/module/group/lang/en.php @@ -521,6 +521,7 @@ $lang->group->package->browseDataview = 'Browse Dataview'; $lang->group->package->manageDataview = 'Manage Dataview'; $lang->group->package->deleteDataview = 'Delete Dataview'; $lang->group->package->browseMetric = 'Browse Metric'; +$lang->group->package->manageMetric = 'Manage Metric'; $lang->group->package->browseDoc = 'Browse Doc'; $lang->group->package->manageDoc = 'Manage Doc'; $lang->group->package->deleteDoc = 'Delete Doc'; diff --git a/module/group/lang/resource.php b/module/group/lang/resource.php index 00b2e2abbb..8c8492c959 100644 --- a/module/group/lang/resource.php +++ b/module/group/lang/resource.php @@ -1717,9 +1717,25 @@ $lang->resource->chart->preview = 'preview'; $lang->chart->methodOrder[2] = 'preview'; $lang->resource->metric = new stdclass(); -$lang->resource->metric->preview = 'preview'; +$lang->resource->metric->preview = 'preview'; +$lang->resource->metric->browse = 'browse'; +$lang->resource->metric->create = 'create'; +$lang->resource->metric->edit = 'edit'; +$lang->resource->metric->view = 'view'; +$lang->resource->metric->implement = 'implementAction'; +$lang->resource->metric->delist = 'delistAction'; +$lang->resource->metric->delete = 'deleteAction'; +$lang->resource->metric->details = 'detailsAction'; -$lang->metric->methodOrder[2] = 'preview'; +$lang->metric->methodOrder[5] = 'preview'; +$lang->metric->methodOrder[6] = 'details'; +$lang->metric->methodOrder[10] = 'browse'; +$lang->metric->methodOrder[15] = 'create'; +$lang->metric->methodOrder[20] = 'edit'; +$lang->metric->methodOrder[25] = 'view'; +$lang->metric->methodOrder[30] = 'implement'; +$lang->metric->methodOrder[35] = 'delist'; +$lang->metric->methodOrder[40] = 'delete'; /* Report . */ $lang->resource->report = new stdclass(); diff --git a/module/group/lang/zh-cn.php b/module/group/lang/zh-cn.php index b363c24318..661c66ce56 100644 --- a/module/group/lang/zh-cn.php +++ b/module/group/lang/zh-cn.php @@ -521,6 +521,7 @@ $lang->group->package->browseDataview = '浏览数据表'; $lang->group->package->manageDataview = '创建维护数据表'; $lang->group->package->deleteDataview = '删除数据表'; $lang->group->package->browseMetric = '浏览度量项'; +$lang->group->package->manageMetric = '管理度量项'; $lang->group->package->browseDoc = '浏览文档'; $lang->group->package->manageDoc = '创建与维护文档'; $lang->group->package->deleteDoc = '删除文档'; diff --git a/module/group/packagemanager.php b/module/group/packagemanager.php index 14a8773933..7aca175227 100644 --- a/module/group/packagemanager.php +++ b/module/group/packagemanager.php @@ -3506,6 +3506,19 @@ $config->group->package->browseMetric->order = 5; $config->group->package->browseMetric->subset = 'metric'; $config->group->package->browseMetric->privs = array(); $config->group->package->browseMetric->privs['metric-preview'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 5, 'depend' => array(), 'recommend' => array()); +$config->group->package->browseMetric->privs['metric-details'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 5, 'depend' => array(), 'recommend' => array()); + +$config->group->package->manageMetric = new stdclass(); +$config->group->package->manageMetric->order = 10; +$config->group->package->manageMetric->subset = 'metric'; +$config->group->package->manageMetric->privs = array(); +$config->group->package->manageMetric->privs['metric-browse'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 5, 'depend' => array(), 'recommend' => array()); +$config->group->package->manageMetric->privs['metric-create'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 5, 'depend' => array(), 'recommend' => array()); +$config->group->package->manageMetric->privs['metric-edit'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 5, 'depend' => array(), 'recommend' => array()); +$config->group->package->manageMetric->privs['metric-view'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 5, 'depend' => array(), 'recommend' => array()); +$config->group->package->manageMetric->privs['metric-implement'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 5, 'depend' => array(), 'recommend' => array()); +$config->group->package->manageMetric->privs['metric-delist'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 5, 'depend' => array(), 'recommend' => array()); +$config->group->package->manageMetric->privs['metric-delete'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 5, 'depend' => array(), 'recommend' => array()); $config->group->package->browseDoc = new stdclass(); $config->group->package->browseDoc->order = 10; diff --git a/module/metric/lang/de.php b/module/metric/lang/de.php index 0a862f83aa..66ba746e0e 100644 --- a/module/metric/lang/de.php +++ b/module/metric/lang/de.php @@ -23,12 +23,13 @@ $lang->metric->system = "System"; $lang->metric->weekCell = "%s,Week %s"; $lang->metric->create = "Create " . $this->lang->metric->common; $lang->metric->edit = "Edit " . $this->lang->metric->common; +$lang->metric->view = 'View ' . $this->lang->metric->common; $lang->metric->afterCreate = "After Saving"; $lang->metric->definition = "Definition"; $lang->metric->declaration = "Definition"; $lang->metric->customUnit = "Custom Unit"; $lang->metric->delist = "Delist"; -$lang->metric->preview = "Preview"; +$lang->metric->preview = "Preview Metric"; $lang->metric->metricList = "Metric List"; $lang->metric->manage = "Manage"; $lang->metric->exitManage = "Exit manage"; @@ -81,6 +82,8 @@ $lang->metric->implementAction = 'Implement Metric'; $lang->metric->deleteAction = 'Delete Metric'; $lang->metric->implementAction = 'Implement Metric'; $lang->metric->deleteAction = 'Delete Metric'; +$lang->metric->delistAction = 'Delist Metric'; +$lang->metric->detailsAction = 'Metric Details'; $lang->metric->stageList = array(); $lang->metric->stageList['wait'] = "Not Released"; diff --git a/module/metric/lang/en.php b/module/metric/lang/en.php index 0a862f83aa..66ba746e0e 100644 --- a/module/metric/lang/en.php +++ b/module/metric/lang/en.php @@ -23,12 +23,13 @@ $lang->metric->system = "System"; $lang->metric->weekCell = "%s,Week %s"; $lang->metric->create = "Create " . $this->lang->metric->common; $lang->metric->edit = "Edit " . $this->lang->metric->common; +$lang->metric->view = 'View ' . $this->lang->metric->common; $lang->metric->afterCreate = "After Saving"; $lang->metric->definition = "Definition"; $lang->metric->declaration = "Definition"; $lang->metric->customUnit = "Custom Unit"; $lang->metric->delist = "Delist"; -$lang->metric->preview = "Preview"; +$lang->metric->preview = "Preview Metric"; $lang->metric->metricList = "Metric List"; $lang->metric->manage = "Manage"; $lang->metric->exitManage = "Exit manage"; @@ -81,6 +82,8 @@ $lang->metric->implementAction = 'Implement Metric'; $lang->metric->deleteAction = 'Delete Metric'; $lang->metric->implementAction = 'Implement Metric'; $lang->metric->deleteAction = 'Delete Metric'; +$lang->metric->delistAction = 'Delist Metric'; +$lang->metric->detailsAction = 'Metric Details'; $lang->metric->stageList = array(); $lang->metric->stageList['wait'] = "Not Released"; diff --git a/module/metric/lang/fr.php b/module/metric/lang/fr.php index 0a862f83aa..66ba746e0e 100644 --- a/module/metric/lang/fr.php +++ b/module/metric/lang/fr.php @@ -23,12 +23,13 @@ $lang->metric->system = "System"; $lang->metric->weekCell = "%s,Week %s"; $lang->metric->create = "Create " . $this->lang->metric->common; $lang->metric->edit = "Edit " . $this->lang->metric->common; +$lang->metric->view = 'View ' . $this->lang->metric->common; $lang->metric->afterCreate = "After Saving"; $lang->metric->definition = "Definition"; $lang->metric->declaration = "Definition"; $lang->metric->customUnit = "Custom Unit"; $lang->metric->delist = "Delist"; -$lang->metric->preview = "Preview"; +$lang->metric->preview = "Preview Metric"; $lang->metric->metricList = "Metric List"; $lang->metric->manage = "Manage"; $lang->metric->exitManage = "Exit manage"; @@ -81,6 +82,8 @@ $lang->metric->implementAction = 'Implement Metric'; $lang->metric->deleteAction = 'Delete Metric'; $lang->metric->implementAction = 'Implement Metric'; $lang->metric->deleteAction = 'Delete Metric'; +$lang->metric->delistAction = 'Delist Metric'; +$lang->metric->detailsAction = 'Metric Details'; $lang->metric->stageList = array(); $lang->metric->stageList['wait'] = "Not Released"; diff --git a/module/metric/lang/zh-cn.php b/module/metric/lang/zh-cn.php index 8b2c9555c3..937544f0ac 100644 --- a/module/metric/lang/zh-cn.php +++ b/module/metric/lang/zh-cn.php @@ -23,12 +23,13 @@ $lang->metric->system = "system"; $lang->metric->weekCell = "%s年第%s周"; $lang->metric->create = "创建" . $this->lang->metric->common; $lang->metric->edit = "编辑" . $this->lang->metric->common; +$lang->metric->view = '查看' . $this->lang->metric->common; $lang->metric->afterCreate = "保存后"; $lang->metric->definition = "计算规则"; $lang->metric->declaration = "度量定义"; $lang->metric->customUnit = "自定义"; $lang->metric->delist = "下架"; -$lang->metric->preview = "预览"; +$lang->metric->preview = "查看度量项"; $lang->metric->metricList = "度量项列表"; $lang->metric->manage = "管理度量项"; $lang->metric->exitManage = "退出管理"; @@ -85,6 +86,8 @@ $lang->metric->viewAction = '查看度量项'; $lang->metric->editAction = '编辑度量项'; $lang->metric->implementAction = '实现度量项'; $lang->metric->deleteAction = '删除度量项'; +$lang->metric->delistAction = '下架度量项'; +$lang->metric->detailsAction = '度量项详情'; $lang->metric->stageList = array(); $lang->metric->stageList['wait'] = "未发布"; From 5d1d8cc3ff12de7d2441a97d1f7b15c146ff7189 Mon Sep 17 00:00:00 2001 From: qixinzhi Date: Fri, 22 Sep 2023 09:13:42 +0000 Subject: [PATCH 038/120] * Fix action with delist and publish,bug#38669,task#103046. --- module/action/lang/en.php | 11 +++++++++++ module/action/lang/zh-cn.php | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/module/action/lang/en.php b/module/action/lang/en.php index a5abfff27f..a668a50b58 100755 --- a/module/action/lang/en.php +++ b/module/action/lang/en.php @@ -320,6 +320,9 @@ $lang->action->desc->autobackup = '$date, backed up of system' . "\ $lang->action->desc->autorestore = '$date, restored by system.' . "\n"; $lang->action->desc->deleteexpiredbackup = '$date, deleted the expired automatic backups by system.' . "\n"; +$lang->action->desc->delist = '$date, delist by $actor.' . "\n"; +$lang->action->desc->publish = '$date, publish by $actor.' . "\n"; + /* Used to display dynamic information. */ $lang->action->label = new stdclass(); $lang->action->label->install = 'install '; @@ -507,6 +510,7 @@ $lang->action->label->linkhost = 'link hosts to'; $lang->action->label->published = 'Published'; $lang->action->label->unpublished = 'Unpublished'; $lang->action->label->prompt = 'Prompt'; +$lang->action->label->delist = 'delist'; /* Dynamic information is grouped by object. */ $lang->action->dynamicAction = new stdclass; @@ -809,6 +813,13 @@ $lang->action->dynamicAction->ai['edited'] = 'Edited prompt'; $lang->action->dynamicAction->ai['published'] = 'Published prompt'; $lang->action->dynamicAction->ai['unpublished'] = 'Unpublished prompt'; +$lang->action->dynamicAction->metric['created'] = 'Create Metric'; +$lang->action->dynamicAction->metric['edited'] = 'Edit Metric'; +$lang->action->dynamicAction->metric['deleted'] = 'Delete Metric'; +$lang->action->dynamicAction->metric['undeleted'] = 'Undelete Metric'; +$lang->action->dynamicAction->metric['delist'] = 'Delist Metric'; +$lang->action->dynamicAction->metric['publish'] = 'Publish Metric'; + /* Generate the corresponding object link. */ $lang->action->label->product = $lang->productCommon . '|product|view|productID=%s'; $lang->action->label->productplan = 'Plan|productplan|view|productID=%s'; diff --git a/module/action/lang/zh-cn.php b/module/action/lang/zh-cn.php index 471270bf3a..2d58bb6cb4 100755 --- a/module/action/lang/zh-cn.php +++ b/module/action/lang/zh-cn.php @@ -320,6 +320,9 @@ $lang->action->desc->autobackup = '$date, 系统执行了自动备 $lang->action->desc->autorestore = '$date, 系统执行了自动还原。' . "\n"; $lang->action->desc->deleteexpiredbackup = '$date, 系统删除了过期的自动备份。' . "\n"; +$lang->action->desc->delist = '$date, 由 $actor 下架。' . "\n"; +$lang->action->desc->publish = '$date, 由 $actor 发布。' . "\n"; + /* 用来显示动态信息。*/ $lang->action->label = new stdclass(); $lang->action->label->install = '安装了'; @@ -507,6 +510,7 @@ $lang->action->label->linkhost = '主机关联到'; $lang->action->label->published = '发布了'; $lang->action->label->unpublished = '下架了'; $lang->action->label->prompt = '提词'; +$lang->action->label->delist = '下架了'; /* 动态信息按照对象分组 */ $lang->action->dynamicAction = new stdclass(); @@ -809,6 +813,13 @@ $lang->action->dynamicAction->ai['edited'] = '编辑提词'; $lang->action->dynamicAction->ai['published'] = '发布提词'; $lang->action->dynamicAction->ai['unpublished'] = '下架提词'; +$lang->action->dynamicAction->metric['created'] = '创建度量'; +$lang->action->dynamicAction->metric['edited'] = '编辑度量'; +$lang->action->dynamicAction->metric['deleted'] = '删除度量'; +$lang->action->dynamicAction->metric['undeleted'] = '还原度量'; +$lang->action->dynamicAction->metric['delist'] = '下架度量'; +$lang->action->dynamicAction->metric['publish'] = '发布度量'; + /* 用来生成相应对象的链接。*/ $lang->action->label->product = $lang->productCommon . '|product|view|productID=%s'; $lang->action->label->productplan = "计划|productplan|view|productID=%s"; From 677edd21151a1c54ee7c16507317fcac1ac0ce7b Mon Sep 17 00:00:00 2001 From: liwenrui Date: Mon, 25 Sep 2023 09:11:56 +0800 Subject: [PATCH 039/120] * add ai privs to ipd. --- module/group/packagemanager.php | 42 ++++++++++++++++----------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/module/group/packagemanager.php b/module/group/packagemanager.php index 7aca175227..efc80af6ee 100644 --- a/module/group/packagemanager.php +++ b/module/group/packagemanager.php @@ -3514,8 +3514,8 @@ $config->group->package->manageMetric->subset = 'metric'; $config->group->package->manageMetric->privs = array(); $config->group->package->manageMetric->privs['metric-browse'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 5, 'depend' => array(), 'recommend' => array()); $config->group->package->manageMetric->privs['metric-create'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 5, 'depend' => array(), 'recommend' => array()); -$config->group->package->manageMetric->privs['metric-edit'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 5, 'depend' => array(), 'recommend' => array()); -$config->group->package->manageMetric->privs['metric-view'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 5, 'depend' => array(), 'recommend' => array()); +$config->group->package->manageMetric->privs['metric-edit'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 5, 'depend' => array(), 'recommend' => array()); +$config->group->package->manageMetric->privs['metric-view'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 5, 'depend' => array(), 'recommend' => array()); $config->group->package->manageMetric->privs['metric-implement'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 5, 'depend' => array(), 'recommend' => array()); $config->group->package->manageMetric->privs['metric-delist'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 5, 'depend' => array(), 'recommend' => array()); $config->group->package->manageMetric->privs['metric-delete'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 5, 'depend' => array(), 'recommend' => array()); @@ -3778,50 +3778,50 @@ $config->group->package->executePrompt = new stdclass(); $config->group->package->executePrompt->order = 2040; $config->group->package->executePrompt->subset = 'ai'; $config->group->package->executePrompt->privs = array(); -$config->group->package->executePrompt->privs['ai-promptExecute'] = array('edition' => 'open,biz,max', 'vision' => 'rnd', 'order' => 85, 'depend' => array('ai-promptExecutionReset'), 'recommend' => array()); -$config->group->package->executePrompt->privs['ai-promptExecutionReset'] = array('edition' => 'open,biz,max', 'vision' => 'rnd', 'order' => 95, 'depend' => array('ai-promptExecute'), 'recommend' => array()); +$config->group->package->executePrompt->privs['ai-promptExecute'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 85, 'depend' => array('ai-promptExecutionReset'), 'recommend' => array()); +$config->group->package->executePrompt->privs['ai-promptExecutionReset'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 95, 'depend' => array('ai-promptExecute'), 'recommend' => array()); $config->group->package->manageLLM = new stdclass(); $config->group->package->manageLLM->order = 2060; $config->group->package->manageLLM->subset = 'ai'; $config->group->package->manageLLM->privs = array(); -$config->group->package->manageLLM->privs['ai-models'] = array('edition' => 'open,biz,max', 'vision' => 'rnd', 'order' => 5, 'depend' => array(), 'recommend' => array()); -$config->group->package->manageLLM->privs['ai-editModel'] = array('edition' => 'open,biz,max', 'vision' => 'rnd', 'order' => 10, 'depend' => array('ai-models', 'ai-testConnection'), 'recommend' => array()); -$config->group->package->manageLLM->privs['ai-testConnection'] = array('edition' => 'open,biz,max', 'vision' => 'rnd', 'order' => 15, 'depend' => array('ai-editModel', 'ai-models'), 'recommend' => array()); +$config->group->package->manageLLM->privs['ai-models'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 5, 'depend' => array(), 'recommend' => array()); +$config->group->package->manageLLM->privs['ai-editModel'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 10, 'depend' => array('ai-models', 'ai-testConnection'), 'recommend' => array()); +$config->group->package->manageLLM->privs['ai-testConnection'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 15, 'depend' => array('ai-editModel', 'ai-models'), 'recommend' => array()); $config->group->package->browsePrompt = new stdclass(); $config->group->package->browsePrompt->order = 2080; $config->group->package->browsePrompt->subset = 'ai'; $config->group->package->browsePrompt->privs = array(); -$config->group->package->browsePrompt->privs['ai-prompts'] = array('edition' => 'open,biz,max', 'vision' => 'rnd', 'order' => 75, 'depend' => array(), 'recommend' => array()); -$config->group->package->browsePrompt->privs['ai-promptView'] = array('edition' => 'open,biz,max', 'vision' => 'rnd', 'order' => 80, 'depend' => array('ai-prompts'), 'recommend' => array()); +$config->group->package->browsePrompt->privs['ai-prompts'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 75, 'depend' => array(), 'recommend' => array()); +$config->group->package->browsePrompt->privs['ai-promptView'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 80, 'depend' => array('ai-prompts'), 'recommend' => array()); $config->group->package->managePrompt = new stdclass(); $config->group->package->managePrompt->order = 2100; $config->group->package->managePrompt->subset = 'ai'; $config->group->package->managePrompt->privs = array(); -$config->group->package->managePrompt->privs['ai-createPrompt'] = array('edition' => 'biz,max', 'vision' => 'rnd', 'order' => 20, 'depend' => array('ai-prompts', 'ai-promptView'), 'recommend' => array('ai-promptAssignRole', 'ai-promptAudit', 'ai-promptDelete', 'ai-promptEdit', 'ai-promptFinalize', 'ai-promptSelectDataSource', 'ai-promptSetPurpose', 'ai-promptSetTargetForm')); -$config->group->package->managePrompt->privs['ai-promptEdit'] = array('edition' => 'biz,max', 'vision' => 'rnd', 'order' => 25, 'depend' => array('ai-createPrompt', 'ai-prompts', 'ai-promptView'), 'recommend' => array()); -$config->group->package->managePrompt->privs['ai-promptAssignRole'] = array('edition' => 'biz,max', 'vision' => 'rnd', 'order' => 35, 'depend' => array('ai-createPrompt', 'ai-promptAudit', 'ai-promptExecute', 'ai-promptFinalize', 'ai-prompts', 'ai-promptSelectDataSource', 'ai-promptSetPurpose', 'ai-promptSetTargetForm', 'ai-promptView', 'ai-roleTemplates'), 'recommend' => array()); -$config->group->package->managePrompt->privs['ai-promptSelectDataSource'] = array('edition' => 'biz,max', 'vision' => 'rnd', 'order' => 40, 'depend' => array('ai-createPrompt', 'ai-promptAssignRole', 'ai-promptAudit', 'ai-promptExecute', 'ai-promptFinalize', 'ai-prompts', 'ai-promptSetPurpose', 'ai-promptSetTargetForm', 'ai-promptView'), 'recommend' => array()); -$config->group->package->managePrompt->privs['ai-promptSetPurpose'] = array('edition' => 'biz,max', 'vision' => 'rnd', 'order' => 45, 'depend' => array('ai-createPrompt', 'ai-promptAssignRole', 'ai-promptAudit', 'ai-promptExecute', 'ai-promptFinalize', 'ai-prompts', 'ai-promptSelectDataSource', 'ai-promptSetTargetForm', 'ai-promptView'), 'recommend' => array()); -$config->group->package->managePrompt->privs['ai-promptSetTargetForm'] = array('edition' => 'biz,max', 'vision' => 'rnd', 'order' => 50, 'depend' => array('ai-createPrompt', 'ai-promptAssignRole', 'ai-promptAudit', 'ai-promptExecute', 'ai-promptFinalize', 'ai-prompts', 'ai-promptSelectDataSource', 'ai-promptSetPurpose', 'ai-promptView'), 'recommend' => array()); -$config->group->package->managePrompt->privs['ai-promptFinalize'] = array('edition' => 'biz,max', 'vision' => 'rnd', 'order' => 55, 'depend' => array('ai-createPrompt', 'ai-promptAssignRole', 'ai-promptAudit', 'ai-promptExecute', 'ai-prompts', 'ai-promptSelectDataSource', 'ai-promptSetPurpose', 'ai-promptSetTargetForm', 'ai-promptView'), 'recommend' => array()); -$config->group->package->managePrompt->privs['ai-promptAudit'] = array('edition' => 'biz,max', 'vision' => 'rnd', 'order' => 60, 'depend' => array('ai-createPrompt', 'ai-promptAssignRole', 'ai-promptExecute', 'ai-promptFinalize', 'ai-prompts', 'ai-promptSelectDataSource', 'ai-promptSetPurpose', 'ai-promptSetTargetForm', 'ai-promptView'), 'recommend' => array()); -$config->group->package->managePrompt->privs['ai-roleTemplates'] = array('edition' => 'biz,max', 'vision' => 'rnd', 'order' => 90, 'depend' => array('ai-promptAssignRole'), 'recommend' => array()); +$config->group->package->managePrompt->privs['ai-createPrompt'] = array('edition' => 'biz,max,ipd', 'vision' => 'rnd', 'order' => 20, 'depend' => array('ai-prompts', 'ai-promptView'), 'recommend' => array('ai-promptAssignRole', 'ai-promptAudit', 'ai-promptDelete', 'ai-promptEdit', 'ai-promptFinalize', 'ai-promptSelectDataSource', 'ai-promptSetPurpose', 'ai-promptSetTargetForm')); +$config->group->package->managePrompt->privs['ai-promptEdit'] = array('edition' => 'biz,max,ipd', 'vision' => 'rnd', 'order' => 25, 'depend' => array('ai-createPrompt', 'ai-prompts', 'ai-promptView'), 'recommend' => array()); +$config->group->package->managePrompt->privs['ai-promptAssignRole'] = array('edition' => 'biz,max,ipd', 'vision' => 'rnd', 'order' => 35, 'depend' => array('ai-createPrompt', 'ai-promptAudit', 'ai-promptExecute', 'ai-promptFinalize', 'ai-prompts', 'ai-promptSelectDataSource', 'ai-promptSetPurpose', 'ai-promptSetTargetForm', 'ai-promptView', 'ai-roleTemplates'), 'recommend' => array()); +$config->group->package->managePrompt->privs['ai-promptSelectDataSource'] = array('edition' => 'biz,max,ipd', 'vision' => 'rnd', 'order' => 40, 'depend' => array('ai-createPrompt', 'ai-promptAssignRole', 'ai-promptAudit', 'ai-promptExecute', 'ai-promptFinalize', 'ai-prompts', 'ai-promptSetPurpose', 'ai-promptSetTargetForm', 'ai-promptView'), 'recommend' => array()); +$config->group->package->managePrompt->privs['ai-promptSetPurpose'] = array('edition' => 'biz,max,ipd', 'vision' => 'rnd', 'order' => 45, 'depend' => array('ai-createPrompt', 'ai-promptAssignRole', 'ai-promptAudit', 'ai-promptExecute', 'ai-promptFinalize', 'ai-prompts', 'ai-promptSelectDataSource', 'ai-promptSetTargetForm', 'ai-promptView'), 'recommend' => array()); +$config->group->package->managePrompt->privs['ai-promptSetTargetForm'] = array('edition' => 'biz,max,ipd', 'vision' => 'rnd', 'order' => 50, 'depend' => array('ai-createPrompt', 'ai-promptAssignRole', 'ai-promptAudit', 'ai-promptExecute', 'ai-promptFinalize', 'ai-prompts', 'ai-promptSelectDataSource', 'ai-promptSetPurpose', 'ai-promptView'), 'recommend' => array()); +$config->group->package->managePrompt->privs['ai-promptFinalize'] = array('edition' => 'biz,max,ipd', 'vision' => 'rnd', 'order' => 55, 'depend' => array('ai-createPrompt', 'ai-promptAssignRole', 'ai-promptAudit', 'ai-promptExecute', 'ai-prompts', 'ai-promptSelectDataSource', 'ai-promptSetPurpose', 'ai-promptSetTargetForm', 'ai-promptView'), 'recommend' => array()); +$config->group->package->managePrompt->privs['ai-promptAudit'] = array('edition' => 'biz,max,ipd', 'vision' => 'rnd', 'order' => 60, 'depend' => array('ai-createPrompt', 'ai-promptAssignRole', 'ai-promptExecute', 'ai-promptFinalize', 'ai-prompts', 'ai-promptSelectDataSource', 'ai-promptSetPurpose', 'ai-promptSetTargetForm', 'ai-promptView'), 'recommend' => array()); +$config->group->package->managePrompt->privs['ai-roleTemplates'] = array('edition' => 'biz,max,ipd', 'vision' => 'rnd', 'order' => 90, 'depend' => array('ai-promptAssignRole'), 'recommend' => array()); $config->group->package->publishPrompt = new stdclass(); $config->group->package->publishPrompt->order = 2120; $config->group->package->publishPrompt->subset = 'ai'; $config->group->package->publishPrompt->privs = array(); -$config->group->package->publishPrompt->privs['ai-promptPublish'] = array('edition' => 'open,biz,max', 'vision' => 'rnd', 'order' => 65, 'depend' => array('ai-prompts', 'ai-promptView'), 'recommend' => array()); -$config->group->package->publishPrompt->privs['ai-promptUnpublish'] = array('edition' => 'open,biz,max', 'vision' => 'rnd', 'order' => 70, 'depend' => array('ai-prompts', 'ai-promptView'), 'recommend' => array()); +$config->group->package->publishPrompt->privs['ai-promptPublish'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 65, 'depend' => array('ai-prompts', 'ai-promptView'), 'recommend' => array()); +$config->group->package->publishPrompt->privs['ai-promptUnpublish'] = array('edition' => 'open,biz,max,ipd', 'vision' => 'rnd', 'order' => 70, 'depend' => array('ai-prompts', 'ai-promptView'), 'recommend' => array()); $config->group->package->deletePrompt = new stdclass(); $config->group->package->deletePrompt->order = 2140; $config->group->package->deletePrompt->subset = 'ai'; $config->group->package->deletePrompt->privs = array(); -$config->group->package->deletePrompt->privs['ai-promptDelete'] = array('edition' => 'biz,max', 'vision' => 'rnd', 'order' => 30, 'depend' => array('ai-prompts', 'ai-promptView'), 'recommend' => array()); +$config->group->package->deletePrompt->privs['ai-promptDelete'] = array('edition' => 'biz,max,ipd', 'vision' => 'rnd', 'order' => 30, 'depend' => array('ai-prompts', 'ai-promptView'), 'recommend' => array()); $config->group->package->dashboard = new stdclass(); $config->group->package->dashboard->order = 2160; From 51c225ea246a9b350bdb09ec103f984d542d06cc Mon Sep 17 00:00:00 2001 From: zenggang Date: Mon, 25 Sep 2023 01:30:23 +0000 Subject: [PATCH 040/120] * Adjust code. --- module/cne/model.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/module/cne/model.php b/module/cne/model.php index 17fc1a3c86..bcdbfc9657 100644 --- a/module/cne/model.php +++ b/module/cne/model.php @@ -1322,4 +1322,21 @@ class cneModel extends model $apiUrl = "/api/cne/platform/restore/status"; return $this->apiGet($apiUrl, $apiParams, $this->config->CNE->api->headers); } + + /** + * app资源调度尝试。 + * Try allocate for apps. + * + * @param array $apps + * @access public + * @return object + */ + public function tryAllocate(array $resources): object + { + $apiParams = new stdclass(); + $apiParams->resources = $resources; + + $apiUrl = "/api/cne/system/resource/try-allocate"; + return $this->apiPost($apiUrl, $apiParams, $this->config->CNE->api->headers); + } } From 4f75876dc2e511c99b6ab237ff8cfbbb9ce0cdff Mon Sep 17 00:00:00 2001 From: liwenrui Date: Mon, 25 Sep 2023 10:13:24 +0800 Subject: [PATCH 041/120] * tweak features modal. --- module/misc/lang/de.php | 3 ++- module/misc/lang/en.php | 3 ++- module/misc/lang/fr.php | 3 ++- module/misc/lang/zh-cn.php | 7 ++++--- module/misc/view/features.html.php | 7 ++++--- 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/module/misc/lang/de.php b/module/misc/lang/de.php index cf5bb30c79..d3d028a88a 100644 --- a/module/misc/lang/de.php +++ b/module/misc/lang/de.php @@ -97,7 +97,8 @@ $lang->misc->feature->youngBlueImage = 'theme/default/images/main/new_theme_e $lang->misc->feature->visions = "Interface switching"; $lang->misc->feature->nextStep = 'Next step'; $lang->misc->feature->prevStep = 'Previous step'; -$lang->misc->feature->close = 'Learn More'; +$lang->misc->feature->close = 'Close'; +$lang->misc->feature->learnMore = 'Learn More'; $lang->misc->feature->downloadFile = 'Download introduction'; $lang->misc->feature->tutorialDesc = '

ZenTao 15.0 has new functions, and you know how to use it through the "Tutorial".

Click your [Avatar-Theme-Young Blue] to set it.

'; $lang->misc->feature->themeDesc = '

ZenTao 15.0+ a new "Youth Blue" theme, the pages are more beautiful and the experience is more friendly.

Click your [Avatar-Theme-Young Blue] to set it.

'; diff --git a/module/misc/lang/en.php b/module/misc/lang/en.php index 67c394c998..747f569ee7 100644 --- a/module/misc/lang/en.php +++ b/module/misc/lang/en.php @@ -97,7 +97,8 @@ $lang->misc->feature->youngBlueImage = 'theme/default/images/main/new_theme_e $lang->misc->feature->visions = "Interface switching"; $lang->misc->feature->nextStep = 'Next step'; $lang->misc->feature->prevStep = 'Previous step'; -$lang->misc->feature->close = 'Learn More'; +$lang->misc->feature->close = 'Close'; +$lang->misc->feature->learnMore = 'Learn More'; $lang->misc->feature->downloadFile = 'Download introduction'; $lang->misc->feature->tutorialDesc = '

ZenTao 15.0 has new functions, and you know how to use it through the "Tutorial".

Click your [Avatar-Theme-Young Blue] to set it.

'; $lang->misc->feature->themeDesc = '

ZenTao 15.0+ a new "Youth Blue" theme, the pages are more beautiful and the experience is more friendly.

Click your [Avatar-Theme-Young Blue] to set it.

'; diff --git a/module/misc/lang/fr.php b/module/misc/lang/fr.php index ccbf5cb02b..0a719dedf3 100644 --- a/module/misc/lang/fr.php +++ b/module/misc/lang/fr.php @@ -97,7 +97,8 @@ $lang->misc->feature->youngBlueImage = 'theme/default/images/main/new_theme_e $lang->misc->feature->visions = "Interface switching"; $lang->misc->feature->nextStep = 'Next step'; $lang->misc->feature->prevStep = 'Previous step'; -$lang->misc->feature->close = 'Learn More'; +$lang->misc->feature->close = 'Close'; +$lang->misc->feature->learnMore = 'Learn More'; $lang->misc->feature->downloadFile = 'Download introduction'; $lang->misc->feature->tutorialDesc = '

ZenTao 15.0 has new functions, and you know how to use it through the "Tutorial".

Click your [Avatar-Theme-Young Blue] to set it.

'; $lang->misc->feature->themeDesc = '

ZenTao 15.0+ a new "Youth Blue" theme, the pages are more beautiful and the experience is more friendly.

Click your [Avatar-Theme-Young Blue] to set it.

'; diff --git a/module/misc/lang/zh-cn.php b/module/misc/lang/zh-cn.php index 9e2b90e82c..db6d541528 100644 --- a/module/misc/lang/zh-cn.php +++ b/module/misc/lang/zh-cn.php @@ -95,9 +95,10 @@ $lang->misc->feature->tutorialImage = 'theme/default/images/main/tutorial.pn $lang->misc->feature->youngBlueTheme = '全新青春蓝主题'; $lang->misc->feature->youngBlueImage = 'theme/default/images/main/new_theme.png'; $lang->misc->feature->visions = "不同场景界面切换"; -$lang->misc->feature->nextStep = '下一步'; -$lang->misc->feature->prevStep = '上一步'; -$lang->misc->feature->close = '了解更多'; +$lang->misc->feature->nextStep = '下一页'; +$lang->misc->feature->prevStep = '上一页'; +$lang->misc->feature->close = '开始体验'; +$lang->misc->feature->learnMore = '了解更多'; $lang->misc->feature->downloadFile = '下载新版本功能介绍文档'; $lang->misc->feature->tutorialDesc = "

禅道15系列新增了多项功能,您可以通过“新手引导教程”快速了解禅道的基本使用方法。

通过鼠标经过 [头像-新手引导],点击新手引导,即可进入新手引导教程。

"; $lang->misc->feature->themeDesc = "

禅道15系列上线了全新的“青春蓝”主题,页面呈现更加美观,体验更加友好。

通过鼠标经过 [头像-主题-青春蓝],点击青春蓝,即可设置成功。

"; diff --git a/module/misc/view/features.html.php b/module/misc/view/features.html.php index c6337d7088..9e901b19c9 100644 --- a/module/misc/view/features.html.php +++ b/module/misc/view/features.html.php @@ -31,10 +31,11 @@ -