basex-ti-cli
Version:
a tool for data-chart of SenTi.
359 lines (342 loc) • 11.4 kB
JavaScript
#! node
process.stdin.setEncoding('utf8');
const axios = require('axios');
const chalk = require("chalk");
const pinyin = require('tiny-pinyin');
const fs = require('fs');
const path = require('path');
const os = require('os');
const { execSync } = require('child_process');
const { Buffer } = require("buffer");
const getCurrentBranchName = require ( 'node-git-current-branch' ) ;
const tenant = 'ZJK';
const host = 'http://basex.uino.com/gateway/';
const account = 'superAdmin';
const password = 'basex@Uino';
const gitFeat = 'feat-20221206';
let token = '';
function readlineSync() {
return new Promise((resolve, reject) => {
process.stdin.resume();
process.stdin.on('data', (data) => {
process.stdin.pause(); // stops after one line reads
resolve(data);
});
});
}
function httpGet(url, params) {
return new Promise((resolve, reject) => {
axios.get(url, {
params,
headers: {
Authorization: token ? 'Bearer ' + token : undefined,
Tenant: tenant,
'Content-Type': 'application/json;charset=UTF-8',
'Access-Control-Allow-Origin-Type': '*',
}
}).then((res) => {
resolve(res.data);
}).catch((e) => {
console.log(e);
reject();
})
})
}
function httpPost(url, data) {
return new Promise((resolve, reject) => {
axios.post(url, data, {
headers: {
Authorization: 'Bearer ' + token,
Tenant: tenant,
'Content-Type': 'application/json;charset=UTF-8',
'Access-Control-Allow-Origin-Type': '*',
}
}).then((res) => {
resolve(res.data);
}).catch((e) => {
console.log(e);
reject();
})
})
}
function getSplitData(arr, ids) {
try {
const newArr = [];
ids.split(',').forEach((item) => {
newArr.push(arr[item - 1].value);
})
return newArr.join(',')
} catch(e) {
return false
}
}
function readFile(path) {
return new Promise((resolve, reject) => {
fs.readFile(path, 'utf8', (err, text) => {
if (err) {
reject(err);
} else {
resolve(text);
}
})
})
}
async function testProject() {
try {
const text = await readFile('./package.json');
const json = JSON.parse(text);
return json.name && json.name === 'ti-data-chart';
} catch(e) {
return false;
}
}
function replaceAll(find, replace, str) {
const find1 = find.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
return str.replace(new RegExp(find1, 'g'), replace);
}
function getUUID(){
return 'xxxx-xxxx-xxxx-xxxx-xxxx'.replace(/[xy]/g, function (c) {
const r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8)
return v.toString(16)
})
}
function getGitConfigPath(type) {
let configPath = '';
const workDir = process.cwd();
if (type === 'global') {
configPath = path.join(os.homedir(), '.gitconfig');
} else {
configPath = path.resolve(workDir, '.git/config');
}
if (!fs.existsSync(configPath)) {
configPath = path.join(os.homedir(), '.config/git/config');
}
return fs.existsSync(configPath) ? configPath : null;
}
async function testVersion() {
try {
const x = execSync('npm show basex-ti-cli version')
const buf = Buffer.from(x, "utf8");
const newVer = buf.toString().trim();
const jsonPath = path.resolve(__dirname, './package.json');
const text = await readFile(jsonPath);
const json = JSON.parse(text);
return json.version && json.version === newVer;
} catch(e) {
return false;
}
}
function testBranch() {
return getCurrentBranchName('./') === gitFeat;
}
async function main() {
if (! await testProject()) {
console.log('请在森钛指标项目下运行脚手架!');
process.exit();
}
if (! await testVersion()) {
console.log(`请使用${chalk.green('npm install basex-ti-cli -g')}更新脚手架版本!`)
process.exit();
}
let username = '';
try {
const gitInfo = await readFile(getGitConfigPath('global'));
const emails = gitInfo.match(/[\d\w]+\b@[a-zA-ZA-z0-9]+\.[a-z]+/g);
username = emails[0].split('@')[0];
} catch(e) {
console.log('git信息获取失败!');
process.exit();
}
if (!testBranch()){
console.log(`为了优化开发与打包速度,当前分支不再新建图表,仅可更新。请切换至[${chalk.yellow(gitFeat)}]分支!`);
process.exit();
}
let res = await httpPost(host + '/authx/oauth/token', {
username: account,
password,
"client_id": "basex",
"grant_type": "password"
})
if (res.code === 200) {
const { data } = res;
token = data;
} else {
console.log('BaseX登录异常!');
process.exit();
}
res = await httpPost(host + 'jrmx/get', {
'ZUO_ZHE_YING_SHE': {
'git': username
}
})
if (res.code !== 200) {
process.exit();
}
let author = '';
if (res['ZUO_ZHE_YING_SHE']) {
console.log(`请问您是[${chalk.green(res['ZUO_ZHE_YING_SHE']['anthor'])}]吗?(y/n)`);
let yes = await readlineSync();
if (yes.trim() === 'y') {
author = res['ZUO_ZHE_YING_SHE']['anthor'];
}
}
if (!author) {
let isOk = '';
let inputName = '';
do {
do {
console.log('请输入尊姓大名:');
inputName = await readlineSync();
} while(!inputName.trim());
console.log(`您的姓名是[${chalk.green(inputName.trim())}],确认吗?(y/n)`);
isOk = await readlineSync();
} while (isOk.trim() !== 'y');
author = inputName.trim();
}
if (!res['ZUO_ZHE_YING_SHE']) {
httpPost(host + 'jrmx/post', {
'ZUO_ZHE_YING_SHE': {
'git': username,
'anthor': author,
}
})
}
let name = ''
do {
console.log(`请输入组件名称${chalk.red('(将用作森钛指标的名称,支持中文)')}:`);
name = await readlineSync();
} while(!name.trim());
console.log('请输入组件描述:');
const desc = await readlineSync();
res = await httpGet(host + 'basex/dictType/dropDown', {code: 'HANG_YE_FEN_LEI'});
let groups = [];
if (res.code === 200) {
const { data } = res;
groups = data;
} else {
process.exit();
}
let grpStr = '';
do {
console.log('请选择行业分类(以英文逗号隔开):')
groups.forEach((item, index) => {
console.log(`${chalk.yellow.bold(index + 1)}.${chalk.green(item.value)}`);
});
const grpIdsStr = await readlineSync();
grpStr = getSplitData(groups, grpIdsStr);
} while (!grpStr)
res = await httpGet(host + 'basex/dictType/dropDown', {code: 'ZU_JIAN_LEI_XING'});
let types = [];
if (res.code === 200) {
const { data } = res;
types = data;
} else {
process.exit();
}
let typeStr = '';
do {
console.log('请选择图表类型(以英文逗号隔开):')
types.forEach((item, index) => {
console.log(`${chalk.yellow.bold(index + 1)}.${chalk.green(item.value)}`);
});
const typeIdsStr = await readlineSync();
typeStr = getSplitData(types, typeIdsStr);
} while (!typeStr)
console.log(`组件名称[${chalk.green(name.trim())}],所属行业[${chalk.green(grpStr)}],图表类型[${chalk.green(typeStr)}],你确定要创建吗?(y/n)`)
let yes = await readlineSync();
if (yes.trim() !== 'y') {
process.exit();
}
// let username = '';
// try {
// const gitInfo = await readFile(getGitConfigPath('global'));
// const emails = gitInfo.match(/[\d\w]+\b@[a-zA-ZA-z0-9]+\.[a-z]+/g);
// username = emails[0].split('@')[0];
// } catch(e) {
// console.log('git信息获取失败!');
// process.exit();
// }
if (! await testProject()) {
console.log('请在森钛指标项目下运行脚手架!');
process.exit();
}
const dirPath = './docs/ti/' + username;
try {
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath);
}
} catch(e) {
console.log('创建组件目录失败!');
process.exit();
}
const constDirPath = './docs/.vuepress/public/' + username;
try {
if (!fs.existsSync(constDirPath)) {
fs.mkdirSync(constDirPath);
}
} catch(e) {
console.log('创建静态资源目录失败!');
process.exit();
}
const snapShotDirPath = './docs/.vuepress/public/' + username + '/snapshot';
try {
if (!fs.existsSync(snapShotDirPath)) {
fs.mkdirSync(snapShotDirPath);
}
} catch(e) {
console.log('创建缩略图目录失败!');
process.exit();
}
const a = pinyin.convertToPinyin(name.trim(), '-', true);
const as = a.replace('-', '');
let fileName = '';
if (as.length <= 20) {
const bs = as.charAt(0);
const cs = bs.toUpperCase();
fileName = cs + as.slice(1);
} else {
const aArr = a.split('-');
aArr.forEach((item, index) => {
fileName += index <= 0 ? item.charAt(0).toUpperCase() : item.charAt(0);
})
}
const demoPath = path.resolve(__dirname, './templates/demo.md');
let temp = await readFile(demoPath);
temp = replaceAll('<% fileName %>', fileName, replaceAll('<% username %>', username, replaceAll('<% desc %>', desc.trim(), replaceAll('<% name %>', name.trim(), temp))));
let filePath = '';
try {
let i = '';
const sourceFn= fileName;
do {
fileName = fileName + i;
filePath = './docs/ti/' + username + '/' + fileName + '.md';
i = (i === '' ? 1 : (i + 1))
} while(fs.existsSync(filePath))
fs.writeFileSync(filePath, temp);
} catch(e) {
console.log('组件文件创建失败!');
process.exit();
}
console.log('正在创建图表...');
const router = gitFeat + '/ti/' + username + '/' + fileName + '.html';
res = await httpPost(host + 'jrmx/post', {
'ZHI_BIAO': {
'NAME': name,
'GRPID': grpStr,
'TYPEID': typeStr,
'ROUTER': router,
'CODE': getUUID(),
'AUTHOR': author,
}
})
if (res.code === 200) {
console.log(`${chalk.green('图表创建成功!')}`);
} else {
process.exit();
}
console.log(`组件文件路径:${chalk.green('/docs/ti/' + username + '/' + fileName + '.md')}`);
console.log(`静态资源路径:${chalk.green('/docs/.vuepress/public/' + username)}`);
console.log(`路由地址:${chalk.green('/ti/' + username + '/' + fileName + '.html')}`);
console.log(`森钛业务指标缩略图路径:${chalk.green('/docs/.vuepress/public/' + username + '/snapshot/' + fileName + '.png')}`);
}
main();