一、版本号
版本号(version number)是版本的标识号。每一个操作系统(或广义的讲,每一个软件)都有一个版本号。
版本号能使用户了解所使用的操作系统是否为最新的版本以及它所提供的功能与设施。
每一个版本号可以分为主版本号与次版本号两部分。
二、GNU 风格的版本号管理策略
1.项目初版本时,版本号可以为 0.1 或 0.1.0,也可以为 1.0 或 1.0.0,如果你为人很低调,我想你会选择那个主版本号为 0 的方式;
2.当项目在进行了局部修改或 bug 修正时,主版本号和子版本号都不变,修正版本号加 1;
3.当项目在原有的基础上增加了部分功能时,主版本号不变,子版本号加 1,修正版本号复位为 0,因而可以被忽略掉;
4.当项目在进行了重大修改或局部修正累积较多,而导致项目整体发生全局变化时,主版本号加 1;
三、功能逻辑补充说明
1、当发布单元第一次新增部署任务,将会默认生成一个初始化版本号v0.1.0;
2、开发每新增一个部署任务,将自动新增一条版本号记录,最小版本号自动+1,最多不超过20个最小版本;
3、每超过20个最小版本,自动升级1个中版本;
4、每超过20个中版本,自动升级一个大版本;
5、开发可以手动升级中版本和大版本,不可以降低版本号;
四、v0.1.1版本
<el-form-item label="版本号" prop="version_num">
<el-input v-model="ruleForm.version_num" @focus='tipMessage' />
</el-form-item>
ruleForm: any = { version_num: '' };
rules: any = {
version_num: [{
required: true,
validator: this.versionNumChange,
trigger: 'change'
}],
};
private versionNumChange(value: string, callback: any): void {
let oldVersion = this.data.version_num.split('.');
let oldVersionNum1 = Number(oldVersion[0]);
let oldVersionNum2 = Number(oldVersion[1]);
let oldVersionNum3 = Number(oldVersion[2]);
let newVersion = value.split('.');
let newVersionNum1 = Number(newVersion[0]);
let newVersionNum2 = Number(newVersion[1]);
let newVersionNum3 = Number(newVersion[2]);
let oldVersionNum = `${oldVersionNum1}.${oldVersionNum2}.${oldVersionNum3}`;
if(newVersionNum1 > oldVersionNum1) {
this.ruleForm.version_num = `${newVersionNum1}.0.0`;
} else {
if(newVersionNum2 > oldVersionNum2) {
this.ruleForm.version_num = `${oldVersionNum1}.${newVersionNum2}.0`;
} else {
if(newVersionNum3 > oldVersionNum3){
this.ruleForm.version_num = `${oldVersionNum1}.${oldVersionNum2}.${newVersionNum3}`;
} else {
this.ruleForm.version_num = oldVersionNum;
};
};
};
if(newVersionNum1 > 19 ||newVersionNum2 > 19 || newVersionNum3 > 19) {
this.ruleForm.version_num = `${oldVersionNum1}.${oldVersionNum2}.${oldVersionNum3}`;
this.$message({ type: 'error', message: '版本号不能大于20' });
};
callback();
}
private tipMessage(): void {
this.$message({type: 'warning', message: '注意:新版本号不能低于之前的版本号!', duration: 5000 })
}
演示及说明
1、当获取焦点时,出现消息提示,提醒用户版本号不能低于之前版本

2、修改修正版本
当修正版本号高于之前修正版本时,会直接显示用户输入的新版本号;
当修正版本号低于之前修正版本时,返回旧的版本号;
当修正版本号大于20时,返回旧的版本号并提示用户版本号不能大于20;

3、修改子版本号
当子版本号高于之前子版本时,主版本号为旧版本号,子版本号为新版本号,修正版本号为0;
当子版本号低于之前子版本时,返回旧的版本号;
当子版本号大于20时,返回旧的版本号并提示用户版本号不能大于20;

4、修改主版本号
当主版本号高于之前主版本时,主版本号为新版本号,子版本号0,修正版本号为0;
当主版本号低于之前主版本时,返回旧的版本号;
当主版本号大于20时,返回旧的版本号并提示用户版本号不能大于20;

此处其实还是有一些缺陷的:
1、用户无法主动编辑,只能做修改,因为校验规则的关系,用户删除一个版本号时,例如'0.1.',此时系统会判断最后一位为'',会转化为0,而在判断比较的时候0 < 1,因此会直接返回旧的版本号'0.1.1';
2、版本号修改时,应该每次只能升1个版本,这里没有做判断;
五、v0.1.2版本
1、优化内容
1、优化了用户不能输入,体验不好的bug;
2、新增了正则表达式来判断用户输入的版本号是否为'XX.XX.XX'格式;
3、新增了当用户进行版本升级时,跳版本升级返回只升级一个版本;
2、修改的代码
rules: any = {
version_num: [{
required: true,
validator: this.versionNumChange,
trigger: 'blur' }]
};
private versionNumChange(rule: any, value: string, callback: any): void {
++ const reg = /^[0-1]?[0-9]\.[0-1]?[0-9]\.[0-1]?[0-9]$/;
let oldVersion = this.data.version_num.split('.');
let oldVersionNum1 = Number(oldVersion[0]);
let oldVersionNum2 = Number(oldVersion[1]);
let oldVersionNum3 = Number(oldVersion[2]);
let newVersion = value.split('.');
let newVersionNum1 = Number(newVersion[0]);
let newVersionNum2 = Number(newVersion[1]);
let newVersionNum3 = Number(newVersion[2]);
let oldVersionNum = `${oldVersionNum1}.${oldVersionNum2}.${oldVersionNum3}`;
++ if(reg.test(value)){
if(newVersionNum1 > oldVersionNum1) {
++ this.ruleForm.version_num = `${oldVersionNum1 + 1}.0.0`;
} else {
if(newVersionNum2 > oldVersionNum2) {
++ this.ruleForm.version_num = `${oldVersionNum1}.${oldVersionNum2 + 1}.0`;
} else {
if(newVersionNum3 > oldVersionNum3){
++ this.ruleForm.version_num = `${oldVersionNum1}.${oldVersionNum2}.${oldVersionNum3 + 1}`;
} else {
this.ruleForm.version_num = oldVersionNum;
};
};
};
if(newVersionNum1 > 19 ||newVersionNum2 > 19 || newVersionNum3 > 19) {
this.ruleForm.version_num = `${oldVersionNum1}.${oldVersionNum2}.${oldVersionNum3}`;
this.$message({ type: 'error', message: '版本号不能大于20' });
};
callback();
++ } else {
this.ruleForm.version_num = `${oldVersionNum1}.${oldVersionNum2}.${oldVersionNum3}`;
++ this.$message({type: 'error', message: '请输入正确的版本号', duration: 3000 });
++ };
};
private tipMessage(): void {
this.$message({type: 'warning', message: '注意:新版本号不能低于之前的版本号!', duration: 5000 });
}
3、演示效果
修改修正版本

修改子版本

修改主版本

六、v0.1.3版本
1、优化内容
1、优化了用户点击输入框,消息一直提示的用户体验问题
2、修改的代码
<el-form-item label="版本号" prop="version_num" class="version_num">
<div class="tipMessage" v-if="inputFocus">注意:新版本号不能低于之前的版本号!</div>
<el-input
v-model="ruleForm.version_num"
:disabled="isDisabled"
@focus='showTipMessage'
@blur="hideTipMessage" />
</el-form-item>
private inputFocus: boolean = false;
private showTipMessage(): void {
this.inputFocus = true;
}
private hideTipMessage(): void {
this.inputFocus = false;
}
<style lang="less" scoped>
/deep/ .version_num{
margin: 25px 0 20px;
position: relative;
left: 0;
top: 0;
/deep/ .tipMessage{
position: absolute;
top: -22px;
left: 3px;
color: red;
font-size: 12px;
}
}
</style>
3、演示效果

七、v0.1.4版本
1、优化内容
1、增加了提交时的判断
2、修改了版本号的判断逻辑,更多的判断交给了后端
2、修改的代码
private versionNumChange(rule: any, value: string, callback: any): void {
this.verNum = this.data.version_num;
this.verRevision = this.data.revision;
this.verFeature = this.data.feature;
const reg = /^[0-1]?[0-9]\.[0-1]?[0-9]\.[0-1]?[0-9]$/;
let oldVersion = this.data.version_num.split('.');
let oldVersionNum1 = Number(oldVersion[0]);
let oldVersionNum2 = Number(oldVersion[1]);
let oldVersionNum3 = Number(oldVersion[2]);
let newVersion = value.split('.');
let newVersionNum1 = Number(newVersion[0]);
let newVersionNum2 = Number(newVersion[1]);
let newVersionNum3 = Number(newVersion[2]);
let oldVersionNum = `${oldVersionNum1}.${oldVersionNum2}.${oldVersionNum3}`;
if(reg.test(value)){
if(newVersionNum1 < 20 && newVersionNum2 < 20 && newVersionNum3 <20) {
if((newVersionNum1 == oldVersionNum1 + 1 && newVersionNum2 == 0 && newVersionNum3 == 0) || (newVersionNum1 == oldVersionNum1 && newVersionNum2 == oldVersionNum2 + 1 && newVersionNum3 == 0) || (newVersionNum1 == oldVersionNum1 && newVersionNum2 == oldVersionNum2 && newVersionNum3 == oldVersionNum3 + 1) || (newVersionNum1 == oldVersionNum1 && newVersionNum2 == oldVersionNum2 && newVersionNum3 == oldVersionNum3)){
this.ruleForm.version_num = `${newVersionNum1}.${newVersionNum2}.${newVersionNum3}`;
} else {
return callback(new Error(`请从${oldVersionNum1+1}.0.0 / ${oldVersionNum1}.${oldVersionNum2+1}.0 / ${oldVersionNum1}.${oldVersionNum2}.${oldVersionNum3+1} 中选择您要修改的版本号`));
}
}
callback();
} else {
return callback(new Error(`请从${oldVersionNum1+1}.0.0 / ${oldVersionNum1}.${oldVersionNum2+1}.0 / ${oldVersionNum1}.${oldVersionNum2}.${oldVersionNum3+1} 中选择您要修改的版本号`));
};
}
private confirm(): void {
this.formRef.validate((valid: boolean) => {
if (valid) {
let params = {
id : this.ruleForm.id,
version_num : this.ruleForm.version_num,
revision : this.ruleForm.revision.trim(),
feature : this.ruleForm.feature.trim()
};
let newDatas = [];
let h = this.$createElement;
if( this.ruleForm.version_num === this.verNum && this.ruleForm.revision.trim() === this.verRevision && this.ruleForm.feature.trim() === this.verFeature) {
this.$message({ type: 'info', message: '您未修改任何信息,本次修改失败!' });
this.closeDialog();
} else {
if(this.ruleForm.revision.trim() === this.verRevision && this.ruleForm.feature.trim() === this.verFeature) {
let confirmText = [ `版本号:${this.ruleForm.version_num}`];
for (const i in confirmText) { newDatas.push(h('p', undefined, confirmText[i])) };
this.$confirm('',{ title: '请确认提交信息:', message: h('div', undefined, newDatas), showCancelButton: true, distinguishCancelAndClose: true, closeOnPressEscape:true, confirmButtonText: '确认修改', cancelButtonText: '放弃修改', type: 'warning' })
.then(() => { this.configForm(params); })
.catch(action => { this.$message({ type: 'warning', message: action === 'cancel' ? '您放弃了本次修改' : '版本号未修改' }); });
} else if (this.ruleForm.version_num === this.verNum && this.ruleForm.feature.trim() === this.verFeature) {
let confirmText = [ `新特性:${this.ruleForm.revision}`];
for (const i in confirmText) { newDatas.push(h('p', undefined, confirmText[i])) };
this.$confirm('',{ title: '请确认提交信息:', message: h('div', undefined, newDatas), showCancelButton: true, distinguishCancelAndClose: true, closeOnPressEscape:true, confirmButtonText: '确认修改', cancelButtonText: '放弃修改', type: 'warning' })
.then(() => { this.configForm(params); })
.catch(action => { this.$message({ type: 'warning', message: action === 'cancel' ? '您放弃了本次修改' : '版本号未修改' }); });
} else if (this.ruleForm.version_num === this.verNum && this.ruleForm.revision.trim() === this.verRevision) {
let confirmText = [ `优化和提升:${this.ruleForm.feature}`];
for (const i in confirmText) { newDatas.push(h('p', undefined, confirmText[i])) };
this.$confirm('',{ title: '请确认提交信息:', message: h('div', undefined, newDatas), showCancelButton: true, distinguishCancelAndClose: true, closeOnPressEscape:true, confirmButtonText: '确认修改', cancelButtonText: '放弃修改', type: 'warning' })
.then(() => { this.configForm(params); })
.catch(action => { this.$message({ type: 'warning', message: action === 'cancel' ? '您放弃了本次修改' : '版本号未修改' }); });
} else {
let confirmText = [ `版本号:${this.ruleForm.version_num}` , `新特性:${this.ruleForm.revision}` , `优化和提升:${this.ruleForm.feature}`];
for (const i in confirmText) { newDatas.push(h('p', undefined, confirmText[i])) };
this.$confirm('',{ title: '请确认提交信息:', message: h('div', undefined, newDatas), showCancelButton: true, distinguishCancelAndClose: true, closeOnPressEscape:true, confirmButtonText: '确认修改', cancelButtonText: '放弃修改', type: 'warning' })
.then(() => { this.configForm(params); })
.catch(action => { this.$message({ type: 'warning', message: action === 'cancel' ? '您放弃了本次修改' : '版本号未修改' }); });
}
};
} else {
this.$message({ type: 'error', message: '请输入正确的表单数据' });
};
});
}
3、演示效果

Thank you for your reading!