// ==UserScript==
// @name GitLab Assistant
// @namespace http://tampermonkey.net/
// @version 1.097
// @description GitLab Viewer Publish and Deploy Project!
// @author Sean
// @match http://192.168.0.200*
// @match http://192.168.0.200/*
// @match http://192.168.0.200/fe3project/*
// @match http://192.168.0.200/frontend_pc/project/*
// @match https://oa.epoint.com.cn/interaction-design-portal/portal/pages/casestemplates/casetemplatesdetail*
// @match https://oa.epoint.com.cn/interaction-design-portal/portal/pages/generalpagetemplates/generalpagetemplatesdetail*
// @match http://192.168.201.159:9999/webapp/pages/default/onlinecase.html*
// @match http://192.168.118.60:9999/webapp/pages/caselib/create.html*
// @icon http://192.168.0.200/assets/favicon-7901bd695fb93edb07975966062049829afb56cf11511236e61bcf425070e36e.png
// @require https://cdn.bootcdn.net/ajax/libs/vue/2.7.14/vue.min.js
// @require https://unpkg.com/element-ui/lib/index.js
// @require https://cdn.bootcdn.net/ajax/libs/jszip/3.7.1/jszip.min.js
// @grant GM_getResourceURL
// @grant GM_addStyle
// @grant GM_getResourceText
// @resource ElementCSS https://unpkg.com/element-ui/lib/theme-chalk/index.css
// @grant GM_xmlhttpRequest
// @license MIT
// @run-at document-end
// ==/UserScript==
// 个性化 gitlab 样式,
// 满足项目详情多行显示,
// 项目列表中的链接新窗口打开,
// 搜索框 placeholder 个性化提示
// 增加CodePipeline 入口等
(function() {
'use strict';
let regs = [/^http:\/\/192\.168\.0\.200\/fe3project\//,
/^http:\/\/192\.168\.0\.200\/frontend_pc\/project\//,
/^http:\/\/192\.168\.0\.200/,
/^http:\/\/192\.168\.0\.200\//];
let match = false;
for(let r = 0, lr = regs.length; r < lr; r++) {
if(regs[r].test(location.href)) {
match = true;
break;
}
}
if(!match) {
return;
}
// 注入样式:改变容器宽度,项目描述多行展示
let injectStyle = ".group-list-tree .group-row-contents .description p { white-space: normal; } .container-limited.limit-container-width { max-width: 1400px } .limit-container-width .info-well {max-width: none;}";
injectStyle += ".container-fluid.container-limited.limit-container-width .file-holder.readme-holder.limited-width-container .file-content {max-width: none;}"
injectStyle += 'button:focus {outline-color: transparent !important;}'
// 添加注入样式
let extraStyleElement = document.createElement("style");
extraStyleElement.innerHTML = injectStyle;
document.head.appendChild(extraStyleElement);
const fontUrl = 'https://element.eleme.io/2.11/static/element-icons.535877f.woff';
// 添加样式规则,将字体应用到指定元素上
GM_addStyle(`
@font-face {
font-family: element-icons;
src: url(${fontUrl}) format("woff");
}
`);
GM_addStyle(GM_getResourceText('ElementCSS'));
// 改变列表打开链接方式,改为新窗口打开
let change = false;
let tryTimes = 3;
function changeOpenType() {
if(!change){
setTimeout(()=> {
let links = document.querySelectorAll('.description a');
if(links.length) {
for(let i = 0, l = links.length; i < l; i++) {
links[i].target = "_blank";
if(i === l - 1) {
change = true;
}
}
} else {
changeOpenType();
}
}, 1000);
}
}
function stopLinkProp() {
setTimeout(()=> {
const links = document.querySelectorAll('.description a');
for(let i = 0, l = links.length; i < l; i++) {
links[i].addEventListener('click', ()=> {
event.stopPropagation();
});
}
}, 1000);
}
// 等待页面加载完成
window.addEventListener('load', function() {
var targetDiv = document.querySelector('section');
if(targetDiv) {
// 创建一个 Mutation Observer 实例
var observer = new MutationObserver(function(mutations) {
// 在这里处理 div 子元素的变化
mutations.forEach(function(mutation) {
if(mutation.addedNodes && mutation.addedNodes.length) {
change = false;
changeOpenType();
stopLinkProp();
}
});
});
// 配置 Mutation Observer
var config = { childList: true, subtree: true };
// 开始观察目标 div 元素
observer.observe(targetDiv, config);
}
const placeholder = document.createElement('div');
// 创建 Vue 实例并挂载到页面
const vueInstance = new Vue({
el: placeholder,
methods: {
// 进入管理平台 code pipeline
manage() {
window.open('http://192.168.219.170/code-pipeline')
}
},
template: `<div id="my-ext" style="margin-top:4px;">
<el-tooltip content="进入 Code Pipeline 管理平台" placement="top" effect="light">
<el-button type="primary" icon="el-icon-attract" size="small" circle @click="manage"></el-button>
</el-tooltip>
</div>`
});
// 将占位元素追加到 body 元素中
document.querySelector('.title-container').appendChild(vueInstance.$el);
// 修改 placehodler
const listInput = document.getElementById('group-filter-form-field');
const listInput2 = document.getElementById('project-filter-form-field');
if(listInput) {
listInput.setAttribute("placeholder", "按项目名称、日期、开发者搜索,关键字≥3");
listInput.style.width = '305px';
}
if(listInput2) {
listInput2.setAttribute("placeholder", "按项目名称、日期、开发者搜索,关键字≥3");
listInput2.style.width = '305px';
}
});
})();
// GitLab Viewer Publish and Deploy Project
// 查看项目、部署项目、发布项目功能
(function() {
'use strict';
let regs = [/^http:\/\/192\.168\.0\.200\/fe3project\//,
/^http:\/\/192\.168\.0\.200\/frontend_pc\/project\//];
let match = false;
for(let r = 0, lr = regs.length; r < lr; r++) {
if(regs[r].test(location.href)) {
match = true;
break;
}
}
if(!match) {
return;
}
/*
const fontUrl = 'https://element.eleme.io/2.11/static/element-icons.535877f.woff';
// 添加样式规则,将字体应用到指定元素上
GM_addStyle(`
@font-face {
font-family: element-icons;
src: url(${fontUrl}) format("woff");
}
`);
GM_addStyle(GM_getResourceText('ElementCSS'));
*/
let epointCss = ".epoint-tool {position: fixed; bottom: 0%; right:10px; transform: translateY(-40%);}";
epointCss += ".el-row { padding: 3px 0;} .el-dialog__body .el-tree{min-height: 420px; max-height: 500px;overflow: auto;}";
epointCss += ".deploy-body {height: 306px;}"
epointCss += ".el-loading-spinner {margin-top: -60px;} .el-button--primary:focus {outline: 0 !important;}";
// 添加注入样式
let extraStyleElement = document.createElement("style");
extraStyleElement.innerHTML = epointCss;
document.head.appendChild(extraStyleElement);
const MyComponent = {
template: `<div class="epoint-wrap">
<div class="epoint-tool">
<el-row><el-button type="primary" icon="el-icon-search" round @click="viewProject">查看</el-button></el-row>
<el-row>
<el-tooltip content="一键部署到170服务器" placement="top" effect="light">
<el-button type="primary" icon="el-icon-s-unfold" round @click="doDeploy">部署</el-button>
</el-tooltip>
</el-row>
<el-row>
<el-tooltip content="一键发布到项目案例库" placement="top" effect="light">
<el-button type="primary" icon="el-icon-upload" round @click="publish">发布</el-button>
</el-tooltip>
</el-row>
<el-row>
<el-tooltip content="进入 Code Pipeline 管理平台进行更多操作" placement="top" effect="light">
<el-button type="primary" icon="el-icon-attract" round @click="manage">管理</el-button>
</el-tooltip>
</el-row>
</div>
<el-dialog
title="目录结构"
width="900px"
:append-to-body="true"
:visible.sync="dialogVisible"
:before-close="handleClose">
<el-tree
class="filter-tree"
:data="data"
:props="defaultProps"
node-key="id"
default-expand-all
@node-click="handleNodeClick"
v-loading="loadingTree"
element-loading-background="rgba(255, 255, 255, 1)"
element-loading-text="拼命加载中......"
ref="tree">
</el-tree>
</el-dialog>
<el-dialog
title="部署"
width="420px"
:visible.sync="depDialogVisible">
<div class="deploy-body"
v-loading="loading"
element-loading-text="正在打包部署至 170 服务器,请耐心等待"
element-loading-spinner="el-icon-loading">
</div>
</el-dialog>
<el-dialog title="部署提示" width="640px" :visible.sync="dialogDeployVisible">
<el-alert
title="此操作将把 GitLab 资源打包部署至 170 服务器,已部署过的项目会进行覆盖部署,是否继续?"
type="warning" :closable="false" style="margin-bottom: 20px;">
</el-alert>
<el-form :model="form" ref="form" :rules="rules">
<el-form-item label="框架类型" :label-width="formLabelWidth" prop="frame">
<el-select v-model="form.frame" placeholder="请框架类型">
<el-option v-for="item in framework" :key="item.value" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogDeployVisible = false">取 消</el-button>
<el-button type="primary" @click="doDeploy">确 定</el-button>
</div>
</el-dialog>
</div>`,
data() {
return {
dialogVisible: false, // 查看目录结构弹窗
data: [], // 目录结构树的数据结构
defaultProps: {
children: 'children',
label: 'label'
},
loadingTree: false,
depDialogVisible: false, // 部署中弹窗
loading: false,
projectLibUrl: 'http://192.168.118.60:9999/webapp/pages/caselib/create.html', // 项目案例库地址
projectIsDeployed: false, // 项目是否部署过
projectFtpUrl: '', // ftp路径
projectEntryUrl: '', // 项目案例库发布表单的入口页面
supportDeploy: true, // 项目是否支持部署
dialogDeployVisible: false,
formLabelWidth: '120px',
form: {
frame: ''
},
framework: [
{label: '重构模板', value: 1},
{label: 'f9x1.0', value: 2},
{label: 'f9x2.0', value: 3},
{label: 'f950', value: 4},
{label: 'f950sp1', value: 5},
{label: 'f950sp2', value: 6},
{label: 'f950sp3', value: 7},
{label: 'f951', value: 18},
{label: 'f940', value: 8},
{label: 'f941', value: 10},
{label: 'f942', value: 9},
{label: 'f934', value: 11},
{label: 'f933', value: 12},
{label: 'f932', value: 13},
{label: 'f9211', value: 14},
{label: '骨架', value: 15},
{label: 'Vue', value: 16},
{label: 'React', value: 17}
],
rules: {
frame: [
{ required: true, message: '请选择框架类型', trigger: 'change' }
]
},
clickNodeEntry: null
};
},
methods: {
handleClose(done) {
done();
/*
this.$confirm('确认关闭?')
.then(_ => {
done();
})
.catch(_ => {});*/
},
handleNodeClick(data) {
console.log(data);
if(data.type === 'folder') {
return false;
}
var self = this;
var entry = data.entry;
self.clickNodeEntry = entry;
if(self.projectFtpUrl) {
window.open('http://192.168.219.170' + self.projectFtpUrl + data.entry);
self.clickNodeEntry = null;
} else {
if(this.supportDeploy === false) {
this.$message({
type: 'error',
message: '当前项目暂时只支持查看,请耐心等待功能升级。'
});
self.clickNodeEntry = null;
return false;
}
this.$confirm('资源未部署,部署至 170 服务器后可查看,是否部署?')
.then(_ => {
this.dialogDeployVisible = true;
/*
this.depDialogVisible = true;
this.loading = true;
// 部署
this.getDeployInfo({ type: '1' }, (data)=> {
this.loading = false;
this.depDialogVisible = false;
this.data = data.custom.detail;
this.projectFtpUrl = data.custom.ftpUrl;
this.$alert('部署成功!', '提示', {
confirmButtonText: '确定',
callback: action => {
window.open('http://192.168.219.170' + self.projectFtpUrl + entry)
}
});
});*/
})
.catch(_ => {});
}
},
// 部署
doDeploy () {
if(!this.isDownLoadPage()) {
return;
}
if(!this.dialogDeployVisible) {
this.dialogDeployVisible = true;
return;
}
let self = this;
this.$refs['form'].validate((valid) => {
if (valid) {
this.dialogDeployVisible = false;
this.depDialogVisible = true;
this.loading = true;
// 部署
this.getDeployInfo({ type: '1', frame: this.form.frame }, (data)=> {
this.loading = false;
this.depDialogVisible = false;
if(!data.custom.text){
this.data = data.custom.pageTreeData;
this.projectFtpUrl = data.custom.projectRootPath;
this.supportDeploy = data.custom.supportDeploy;
this.setProjectEntry();
// 从部署按钮直接过来的
if(!this.clickNodeEntry) {
this.$message({
type: 'success',
message: '部署成功!'
});
// 打开查看弹窗
this.viewProject();
} else {// 从点击目录结构过来的,可以调整点击的树节点页面
this.$alert('部署成功!', '提示', {
confirmButtonText: '确定',
callback: action => {
window.open('http://192.168.219.170' + self.projectFtpUrl + self.clickNodeEntry);
self.clickNodeEntry = null;
}
});
}
} else {
this.$message({
type: 'error',
message: data.custom.text
});
}
});
} else {
console.log('error submit!!');
return false;
}
});
/*
this.$confirm('此操作将把 GitLab 资源打包部署至 170 服务器,已部署过的项目会进行覆盖部署,是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
}).catch(() => {
this.$message({
type: 'info',
message: '已取消部署'
});
});*/
},
// 发布项目案例库
publish () {
this.$confirm('此操作将把项目发布至 <a href="'+ this.projectLibUrl +'" target="_blank">项目案例库</a>,已发布过的项目案例库会有重复项,是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
dangerouslyUseHTMLString: true,
type: 'warning'
}).then(() => {
const themes = document.querySelectorAll('.badge-secondary');
let keys = [];
for(let i = 0, l = themes.length; i < l; i++) {
if(themes[0].innerText == '智能设备' && i > 0) {
keys.push(themes[i].innerText);
} else if (themes[0].innerText !== '智能设备' && i > 1) {
keys.push(themes[i].innerText);
}
}
// 存在更多主题的情况
const moreKeyEl = document.querySelector('.gl-w-full .text-nowrap');
if(moreKeyEl) {
const moreKeyElContent = moreKeyEl.getAttribute('data-content');
const regex = />([^<]+)</g;
const matches = moreKeyElContent.match(regex);
const results = matches.filter(function(match) {
return match.length > 3;
});
const moreKeyData = results.map(function(match) {
return match.substring(2, match.length - 2);
});
if(moreKeyData && moreKeyData.length) {
keys = keys.concat(moreKeyData);
}
}
// 组织项目案例库所需参数
const projectName = document.querySelector('.home-panel-title').innerText;
const projectBU = themes[0] ? themes[0].innerText : null;
const projectKeys = keys.join(' ');
const entryUrl = this.projectEntryUrl;
let projectType = themes[1] ? themes[1].innerText : null;
if(themes[0]) {
if(themes[0].innerText == '智能设备') {
projectType = themes[1] ? themes[0].innerText : null;
} else {
projectType = themes[1] ? themes[1].innerText : null;
}
}
const destUrl = this.projectLibUrl + '?projectName=' + projectName + '&projectBU=' + projectBU + '&projectType=' + projectType + '&projectKeys=' + projectKeys + '&entryUrl=' + entryUrl + '&git=' + window.location.href;
this.$message({
type: 'success',
message: destUrl
});
window.open(destUrl);
}).catch(() => {
this.$message({
type: 'info',
message: '已取消发布'
});
});
},
// 查看项目
viewProject () {
if(!this.isDownLoadPage()) {
return;
}
this.dialogVisible = true;
this.loadingTree = true;
let self = this;
// 发送ajax请求,查看是否进行过部署
this.getDeployInfo((data)=> {
// 有部署信息,直接赋值,
if(data) {
self.projectIsDeployed = true;
self.data = data.custom.pageTreeData;
self.projectFtpUrl = data.custom.projectRootPath;
self.supportDeploy = data.custom.supportDeploy;
self.loadingTree = false;
self.setProjectEntry();
} else {
// 无部署信息,仅查看文件目录
getZipResource((data)=> {
self.data = data;
self.loadingTree = false;
});
}
});
},
// 项目部署信息
getDeployInfo(params, callback) {
const projectId = document.body.getAttribute('data-project-id');
const downloadBtn = document.querySelector('.gl-button.btn-sm.btn-confirm');
const sourceUrl = downloadBtn.getAttribute('href');
const downloadUrl = window.location.origin + sourceUrl;
const files = document.body.getAttribute('data-find-file').split('/');
const name = document.body.getAttribute('data-project') + '-' + files[files.length - 1];
const author = document.querySelector('.current-user .gl-font-weight-bold').innerText.trim();
const projectName = document.querySelector('.sidebar-context-title').innerText.trim();
const deployManOA = document.querySelector('.current-user>a').getAttribute('data-user');
const projectGitUrl = 'http://192.168.0.200' + document.body.getAttribute('data-find-file').split('/-/')[0];
if(typeof params == 'function') {
callback = params;
params = null;
}
if(projectId && projectId.length && sourceUrl) {
fetch('http://192.168.219.170:3008/api/getDeployInfo', {
method: 'POST',
// 允许跨域请求
mode: 'cors',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({//post请求参数
params: {
"type": (params && params.type !== undefined) ? params.type : '0',// 0 代表查看, 1代表部署
"name": name, // 项目路径英文名
"deployMan": author, // 部署人姓名
"deployManOA": deployManOA, // 部署人账号
"projectName": projectName, // 项目名称
"downloadUrl": downloadUrl, // 下载地址
"projectId": projectId, // 主键,gitlab上的项目id
"projectGitUrl": projectGitUrl,
"frame": (params && params.frame) ? params.frame : undefined
}
})
})
.then(response => response.text())
.then((result) => {
var data = JSON.parse(result);
callback && callback(data);
})
.catch(error => {
this.depDialogVisible = false;
this.dialogVisible = false;
this.$message({
type: 'error',
message: '系统故障,请联系管理员。'
});
console.error(error);
});
} else {
this.$message({
type: 'error',
message: '本页不支持查看和部署,请至仓库页。'
});
console.error('部署信息请求参数error');
}
},
// 进入管理平台 code pipeline
manage() {
window.open('http://192.168.219.170/code-pipeline')
},
// 设置入口
setProjectEntry(){
const firstNode = findFirstFileNode(this.data);
if(firstNode) {
this.projectEntryUrl = 'http://192.168.219.170' + this.projectFtpUrl + firstNode.entry;
}else {
this.projectEntryUrl = null;
}
},
isDownLoadPage() {
const downloadBtn = document.querySelector('.gl-button.btn-sm.btn-confirm');
const sourceUrl = downloadBtn && downloadBtn.getAttribute('href');
if(downloadBtn && sourceUrl) {
return true;
} else {
this.$message({
type: 'error',
message: '本页面不支持查看和部署,请移至仓库页。'
});
return false;
}
}
},
mounted() {
}
};
const placeholder = document.createElement('div');
// 创建 Vue 实例并挂载到页面
const vueInstance = new Vue({
el: placeholder,
components: {
MyComponent
},
methods: {
},
template: `<my-component></my-component>`
});
// 等待页面加载完成
window.addEventListener('load', function() {
// 将占位元素追加到 body 元素中
document.body.appendChild(vueInstance.$el);
});
// 将文件条目组织成嵌套结构
function organizeFileEntries(fileEntries) {
const root = {
label: document.querySelector('.home-panel-title').innerText || document.getElementById('project_name_edit').value,
type: 'folder',
children: []
};
// 创建嵌套结构
fileEntries.forEach(entry => {
const pathSegments = entry.name.split('/');
let currentFolder = root;
// 遍历路径中的每个部分,创建相应的文件夹节点
for (let i = 0; i < pathSegments.length - 1; i++) {
const folderName = pathSegments[i];
let folder = currentFolder.children.find(child => child.label === folderName);
if(isExcludeFolder(entry.name)) {
continue;
}
if (!folder) {
folder = {
label: folderName,
type: 'folder',
children: []
};
currentFolder.children.push(folder);
}
currentFolder = folder;
}
// 创建文件节点并添加到相应的文件夹中
const fileName = pathSegments[pathSegments.length - 1];
if(fileName && fileName.length && isIncludeFile(fileName) && !isExcludeFolder(entry.name)) {
const fileNode = {
label: fileName,
type: 'file',
entry: entry.name
};
currentFolder.children.push(fileNode);
}
});
return [root];
}
// 是否排除的文件夹
function isExcludeFolder(entry) {
if(entry.indexOf('css') > -1 ||
entry.indexOf('scss') > -1 ||
entry.indexOf('js') > -1 ||
entry.indexOf('images') > -1 ||
entry.indexOf('fui') > -1 ||
entry.indexOf('lib') > -1 ||
entry.indexOf('test') > -1 ||
entry.indexOf('font') > -1 ||
entry.indexOf('frame/fui') > -1) {
return true;
} else {
return false;
}
}
// 是否包含的文件
function isIncludeFile(fileName) {
if(fileName.indexOf('.html') > -1) {
return true;
} else {
return false;
}
}
function getZipResource(callback) {
const downloadUrl = window.location.origin + document.querySelector('.gl-button.btn-sm.btn-confirm').getAttribute('href');
fetch(downloadUrl)
.then(response => response.arrayBuffer())
.then(data => {
// 将 ZIP 文件的二进制数据传递给 JSZip 进行解析
return JSZip.loadAsync(data);
})
.then(zip => {
// 获取 ZIP 文件中的所有条目(文件和目录)
const zipEntries = Object.values(zip.files);
const treeData = organizeFileEntries(zipEntries)
callback && callback(treeData);
})
.catch(error => {
console.error(error);
});
}
// 树结构第一个节点数据
function findFirstFileNode(tree) {
// 遍历树的节点
for (let i = 0; i < tree.length; i++) {
const node = tree[i];
// 如果节点的类型为 file,则返回该节点
if (node.type === 'file') {
return node;
}
// 如果节点有子节点,则递归调用该函数查找子节点中的第一个 file 节点
if (node.children && node.children.length > 0) {
const fileNode = findFirstFileNode(node.children);
if (fileNode) {
return fileNode;
}
}
}
// 如果没有找到 file 节点,则返回 null
return null;
}
})();
// 修改项目描述的长度
(function() {
'use strict';
let regs = [/^http:\/\/192\.168\.0\.200\/fe3project\//,
/^http:\/\/192\.168\.0\.200\/frontend_pc\/project\//];
let match = false;
for(let r = 0, lr = regs.length; r < lr; r++) {
if(regs[r].test(location.href)) {
match = true;
break;
}
}
if(!match) {
return;
}
let tryTimes = 6;
let changed = false;
// 增加项目描述的输入长度
function modifyTextareaLen() {
if(tryTimes > 0 && !changed) {
setTimeout(() => {
const textarea = document.getElementById('project_description');
tryTimes--;
if(textarea) {
textarea.setAttribute("maxlength", "1000");
changed = true;
} else {
modifyTextareaLen();
}
}, 1000);
}
}
window.onload = function() {
modifyTextareaLen();
}
})();
// 设计门户增加通往前端仓库的跳板
(function() {
'use strict';
let regs = [/^https:\/\/oa\.epoint\.com\.cn\/interaction-design-portal\/portal\/pages\/casestemplates\/casetemplatesdetail/,
/^https:\/\/oa\.epoint\.com\.cn\/interaction-design-portal\/portal\/pages\/generalpagetemplates\/generalpagetemplatesdetail/];
let match = false;
for(let r = 0, lr = regs.length; r < lr; r++) {
if(regs[r].test(location.href)) {
match = true;
break;
}
}
if(!match) {
return;
}
function addStyle() {
// 注入样式:增加按钮
let injectStyle = ".content { position: relative; } .front-proto { position: absolute; top: 20px; right: 20px; width: 106px; height: 36px; border-radius: 4px; cursor: pointer; line-height: 36px; background: #25c2c9; color: #fff; text-align: center; font-size: 14px}";
// 添加注入样式
let extraStyleElement = document.createElement("style");
extraStyleElement.innerHTML = injectStyle;
document.head.appendChild(extraStyleElement);
}
function getUrlParameters() {
var params = {};
var search = window.location.search.substring(1);
var urlParams = search.split('&');
for (var i = 0; i < urlParams.length; i++) {
var param = urlParams[i].split('=');
var paramName = decodeURIComponent(param[0]);
var paramValue = decodeURIComponent(param[1] || '');
params[paramName] = paramValue;
}
return params;
}
window.onload = ()=> {
addStyle();
const $content = jQuery('.content');
$content.append('<div class="front-proto">前端原型</div>');
const $frontBtn = jQuery('.front-proto', $content);
$frontBtn.on('click', ()=> {
window.open('http://192.168.0.200/?name=' + getUrlParameters().guid);
});
};
})();
// 前端项目案例库增加获取参数的能力
// 前端项目案例库增加部署能力
(function() {
'use strict';
let regs = [/^http:\/\/192\.168\.118\.60:9999\/webapp\/pages\/caselib\/create\.html/,
/^http:\/\/192\.168\.201\.159:9999\/webapp\/pages\/default\/onlinecase.html/];
let match = false;
for(let r = 0, lr = regs.length; r < lr; r++) {
if(regs[r].test(location.href)) {
match = true;
break;
}
}
if(!match) {
return;
}
const fontUrl = 'https://element.eleme.io/2.11/static/element-icons.535877f.woff';
// 添加样式规则,将字体应用到指定元素上
GM_addStyle(`
@font-face {
font-family: element-icons;
src: url(${fontUrl}) format("woff");
}
`);
GM_addStyle(GM_getResourceText('ElementCSS'));
const businessType = [
{ Value: '7a20e23c-30b8-47e2-8d8d-f2691c9c63c4', Text: '政务服务' },
{ Value: 'c12150bb-b358-452f-87f0-8a2254df87cb', Text: '政务协同' },
{ Value: '3845804e-de68-421c-9402-7b238cfb5a70', Text: '大数据' },
{ Value: '3c28ee56-f24d-4843-b9a2-93e6b96264f4', Text: '电子交易' },
{ Value: '673b5918-51bc-4f1a-ab73-fca86e54d7d1', Text: '数字建设' },
{ Value: '6d9e7d84-7de3-4e0f-bd4f-ed4722ed25b5', Text: '建筑企业' },
{ Value: 'c22f8d2f-518d-4381-b88c-1da68536ed3a', Text: '公共安全' },
{ Value: 'c5810829-1b21-4b22-85cd-390b1edd9614', Text: '智能设备' },
{ Value: '080c7560-c261-428b-a45d-b86b57b47ffb', Text: '中央研究院' }
];
const projectType = [
{ Value: 'dca44f63-be3f-4e9c-b78f-d786571c22c9', Text: '网站' },
{ Value: 'c7861460-163b-4060-80ec-d60604c50435', Text: '业务系统' },
{ Value: '49accc71-6f7d-43f3-b726-58decf58b6fa', Text: '智能设备' },
{ Value: '90209c65-1a55-4d8c-a836-2e5c6b834ada', Text: '大屏可视化' },
{ Value: 'fb0415fb-65ee-42c1-895a-dca042c2568e', Text: '中屏可视化' },
{ Value: '2b83f9b1-ec78-4819-a400-d7d49ea1ecc5', Text: '其他' }
];
let $businesstype;
let $projecttype;
function getUrlParameters() {
var params = {};
var search = window.location.search.substring(1);
var urlParams = search.split('&');
for (var i = 0; i < urlParams.length; i++) {
var param = urlParams[i].split('=');
var paramName = decodeURIComponent(param[0]);
var paramValue = decodeURIComponent(param[1] || '');
params[paramName] = paramValue;
}
return params;
}
function initForm (params) {
if(typeof params === 'object') {
document.getElementsByName('Title')[0].value = params.projectName ? params.projectName : '';
document.getElementsByName('KeyWords')[0].value = params.projectKeys ? params.projectKeys : '';
document.getElementsByName('Entry')[0].value = params.entryUrl ? params.entryUrl : '';
document.getElementsByName('SourceCode')[0].value = params.git ? params.git : '';
}
}
let setSuccess = false;
let setTimes = 5;
function initSelect(params) {
if(typeof params !== 'object') {
return;
}
if(setTimes > 0 && !setSuccess) {
setTimeout(()=> {
setTimes--;
businessType.forEach((item)=> {
if(params.projectBU) {
if(item.Text === params.projectBU.trim()) {
$businesstype.val(item.Value);
} else if( params.projectBU.trim() == '一网统管' || params.projectBU.trim() == '一网协同' || params.projectBU.trim() == '一网通办' ) {
$businesstype.val('7a20e23c-30b8-47e2-8d8d-f2691c9c63c4');
}
$businesstype.trigger("chosen:updated");
}
});
projectType.forEach((item)=> {
if(params.projectType && item.Text === params.projectType.trim()) {
$projecttype.val(item.Value);
$projecttype.trigger("chosen:updated");
}
});
setSuccess = true;
}, 1000);
} else {
initSelect(params);
}
}
function addRelatedDom() {
const sourceInput = document.getElementsByName('SourceCode')[0];
const $sourceInput = jQuery(sourceInput);
$sourceInput.after('<a class="btn" style="cursor: pointer;margin-left:10px;" id="deploy">部署</a><a class="btn hidden" style="cursor: pointer;margin-left:10px" id="view">查看</a>')
}
function addStyle() {
let epointCss = ".el-loading-spinner {margin-top: -50px;} .el-button--primary:focus {outline: 0 !important;}";
// 添加注入样式
let extraStyleElement = document.createElement("style");
extraStyleElement.innerHTML = epointCss;
document.head.appendChild(extraStyleElement);
}
window.onload = ()=> {
const params = getUrlParameters();
$businesstype = jQuery('#businesstype');
$projecttype = jQuery('#projecttype');
initForm(params);
initSelect(params);
// 有url参数填充,则不做部署功能展示
addRelatedDom();
addStyle();
const placeholder = document.createElement('div');
// 创建 Vue 实例并挂载到页面
const vueInstance = new Vue({
el: placeholder,
data() {
return {
framework: [
{label: '重构模板', value: 1},
{label: 'f9x1.0', value: 2},
{label: 'f9x2.0', value: 3},
{label: 'f950', value: 4},
{label: 'f950sp1', value: 5},
{label: 'f950sp2', value: 6},
{label: 'f950sp3', value: 7},
{label: 'f951', value: 18},
{label: 'f940', value: 8},
{label: 'f941', value: 10},
{label: 'f942', value: 9},
{label: 'f934', value: 11},
{label: 'f933', value: 12},
{label: 'f932', value: 13},
{label: 'f9211', value: 14},
{label: '骨架', value: 15},
{label: 'Vue', value: 16},
{label: 'React', value: 17}
],
data: [], // 目录结构树
defaultProps: {
children: 'children',
label: 'label'
},
loadingTree: false,
dialogVisible: false,
dialogDeployVisible: false,
showDeployPath: false,
depDialogVisible: false,
loading: false,
formLabelWidth: '120px',
supportDeploy: false,
form: {
frame: '',
deployPath: ''
},
rules: {
frame: [
{ required: true, message: '请选择框架类型', trigger: 'change' }
],
deployPath: [
{ required: true, message: '请输入部署到 170/showcase 下的目标路径名称', trigger: 'change' }
]
}
}
},
methods: {
// 部署
doDeploy() {
let self = this;
this.$refs['form'].validate((valid) => {
if (valid) {
this.dialogDeployVisible = false;
this.depDialogVisible = true;
this.loading = true;
// 部署
this.getDeployInfo({ type: '1', frame: this.form.frame, deployPath: this.form.deployPath }, (data)=> {
this.loading = false;
this.depDialogVisible = false;
if(!data.custom.text){
this.data = data.custom.pageTreeData;
this.projectFtpUrl = data.custom.projectRootPath;
this.supportDeploy = data.custom.supportDeploy;
this.$message({
type: 'success',
message: '部署成功!'
});
// 打开查看弹窗
this.viewProject();
this.toggleViewButton(true);
} else {
this.$message({
type: 'error',
message: data.custom.text
});
}
});
} else {
console.log('error submit!!');
return false;
}
});
},
// 项目部署
getDeployInfo(params, callback) {
const author = document.querySelector('#account a').innerText.trim().substring(4);
const projectName = document.getElementsByName('Title')[0].value.trim();
const projectGitUrl = document.getElementsByName('SourceCode')[0].value.trim();
if(typeof params == 'function') {
callback = params;
params = null;
}
if(author && author.length && projectGitUrl) {
fetch('http://192.168.219.170:3008/api/getDeployInfo', {
method: 'POST',
// 允许跨域请求
mode: 'cors',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({//post请求参数
params: {
"type": (params && params.type !== undefined) ? params.type : '0',// 0 代表查看, 1代表部署
"deployMan": author, // 部署人姓名
"projectName": projectName, // 项目名称
"projectGitUrl": projectGitUrl,
"frame": (params && params.frame) ? params.frame : undefined,
"deployPath": (params && params.deployPath) ? params.deployPath : undefined // 部署的目标目录
}
})
})
.then(response => response.text())
.then((result) => {
var data = JSON.parse(result);
callback && callback(data);
})
.catch(error => {
this.depDialogVisible = false;
this.dialogVisible = false;
this.$message({
type: 'error',
message: '系统故障,请联系管理员。'
});
console.error(error);
});
} else {
this.$message({
type: 'error',
message: '本页面不支持查看和部署,请先登录。'
});
console.error('部署信息请求参数error');
}
},
// 查看项目
viewProject () {
this.dialogVisible = true;
let self = this;
if(this.data) {
this.loadingTree = false;
} else {
this.loadingTree = true;
// 发送ajax请求,查看是否进行过部署
this.getDeployInfo((data)=> {
// 有部署信息,直接赋值,
if(data) {
self.projectIsDeployed = true;
self.data = data.custom.pageTreeData;
self.projectFtpUrl = data.custom.projectRootPath;
self.supportDeploy = data.custom.supportDeploy;
self.loadingTree = false;
self.toggleViewButton(true);
}
});
}
},
handleNodeClick(data) {
console.log(data);
if(data.type === 'folder') {
return false;
}
var self = this;
var entry = data.entry;
self.clickNodeEntry = entry;
if(self.projectFtpUrl) {
window.open('http://192.168.219.170' + self.projectFtpUrl + data.entry);
self.clickNodeEntry = null;
} else {
if(this.supportDeploy === false) {
this.$message({
type: 'error',
message: '当前项目暂时只支持查看,请耐心等待功能升级。'
});
self.clickNodeEntry = null;
return false;
}
this.$confirm('资源未部署,部署至 170 服务器后可查看,是否部署?')
.then(_ => {
this.dialogDeployVisible = true;
})
.catch(_ => {});
}
},
// svn 需要制定目录名称,showDeployPath
showDialog(showDeployPath) {
this.showDeployPath = showDeployPath;
this.dialogDeployVisible = true;
},
// 查看按钮显影控制
toggleViewButton(show) {
const $viewBtn = jQuery('#view');
if(!$viewBtn.length) {
return;
}
if(show) {
$viewBtn.removeClass('hidden');
} else {
$viewBtn.addClass('hidden');
}
}
},
mounted() {
const $btnDeloy = jQuery('#deploy');
const $btnView = jQuery('#view');
// 绑定vue组件外的事件
$btnDeloy.on('click', function() {
// 源码地址和项目名称判断
const sourceInput = document.getElementsByName('SourceCode');
const projectNameInput = document.getElementsByName('Title');
let sourceInputVal = sourceInput[0].value.trim(),
projectNameInputVal = projectNameInput[0].value.trim();
const gitpattern = /^http:\/\/192\.168/;
const svnpattern = /^svn:\/\/192\.168/;
const sourcepattern = /^(svn:\/\/192\.168|http:\/\/192\.168)/;
if (!sourceInputVal) {
vueInstance.$message({
type: 'error',
message: '请输入源码地址!'
});
return
}
if (!sourcepattern.test(sourceInputVal)) {
vueInstance.$message({
type: 'error',
message: '请输入准确的源码 gitlab 或 svn 地址!'
});
return
}
if (svnpattern.test(sourceInputVal) && !projectNameInputVal) {
vueInstance.$message({
type: 'error',
message: ' svn 仓库地址部署需要填写项目(案例)名称!'
});
return
}
vueInstance.showDialog(svnpattern.test(sourceInputVal));
});
// 查看项目
$btnView.on('click', function() {
vueInstance.viewProject();
});
},
template: `<div id="my-form">
<el-dialog title="部署提示" width="640px" :visible.sync="dialogDeployVisible">
<el-alert
title="此操作将把 GitLab / SVN 资源打包部署至 170 服务器,已部署过的项目会进行覆盖部署,是否继续?"
type="warning" :closable="false" style="margin-bottom: 20px;">
</el-alert>
<el-form :model="form" ref="form" :rules="rules">
<el-form-item label="框架类型" :label-width="formLabelWidth" prop="frame">
<el-select v-model="form.frame" placeholder="请框架类型" style="width:380px;">
<el-option v-for="item in framework" :key="item.value" :label="item.label" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="部署路径" :label-width="formLabelWidth" prop="deployPath" v-if="showDeployPath">
<el-input v-model="form.deployPath" placeholder="请输入部署至服务器 170/showcase 下的目标路径名称" style="width:380px;"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogDeployVisible = false">取 消</el-button>
<el-button type="primary" @click="doDeploy">确 定</el-button>
</div>
</el-dialog>
<el-dialog
title="部署"
width="420px"
:visible.sync="depDialogVisible">
<div class="deploy-body"
style="height: 306px;"
v-loading="loading"
element-loading-text="正在打包部署至 170 服务器,请耐心等待"
element-loading-spinner="el-icon-loading">
</div>
</el-dialog>
<el-dialog
title="目录结构"
width="900px"
:append-to-body="true"
:visible.sync="dialogVisible">
<el-tree
class="filter-tree"
:data="data"
:props="defaultProps"
node-key="id"
default-expand-all
@node-click="handleNodeClick"
v-loading="loadingTree"
element-loading-background="rgba(255, 255, 255, 1)"
element-loading-text="拼命加载中......"
ref="tree">
</el-tree>
</el-dialog>
</div>`
});
// 将占位元素追加到 body 元素中
jQuery('.form-container').after(vueInstance.$el);
};
})();