0%

vue-demo-ssl-manager

证书管理vue-demo

需求

  • 证书的导入、删除、查看详情
  • 计算证书的剩余天数
  • 证书解析(后端处理)

代码

index.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
<template>
<div>
<el-row>
<el-col :span="18">
<el-button @click="dialogFormVisible = true">导入证书</el-button>
<el-dialog title="导入证书" :visible.sync="dialogFormVisible">
<el-form :model="form">
<el-form-item label="名称" :label-width="formLabelWidth">
<el-input v-model="form.name" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="上传方式" :label-width="formLabelWidth">
<el-radio-group v-model="form.type">
<el-radio label="证书内容"></el-radio>
<el-radio label="证书文件"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-show="form.type === '证书内容'" label="证书内容" :label-width="formLabelWidth">
<el-input type="textarea" :autosize="{ minRows: 2, maxRows: 4 }" placeholder="请输入内容" v-model="form.certificate"></el-input>
</el-form-item>

<el-form-item v-show="form.type === '证书文件'" label="证书文件" :label-width="formLabelWidth">
<input type="file" @change="getFile($event)" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button v-show="form.type === '证书内容'" type="primary" @click="onSubmit('form')">提 交</el-button>
<el-button v-show="form.type === '证书文件'" style="margin-left: 10px;" size="small" type="success" @click="onSubmit('form')">提 交</el-button>
</div>
</el-dialog>
</el-col>
</el-row>
<br />
<div>
<el-popconfirm confirm-button-text="好的" cancel-button-text="不用了" icon="el-icon-info" icon-color="red" title="确定是否删除勾选项" @confirm="handleDelete()">
<el-button size="mini" slot="reference" type="danger">删除</el-button>
</el-popconfirm>

<el-table :data="tableData" style="width: 100%" max-height="510" ref="multipleTable" :cell-style="changeCellStyle">
>
<el-table-column prop="selection" type="selection" width="55"></el-table-column>
<el-table-column prop="name" label="name" width="200"></el-table-column>
<el-table-column prop="unit" label="通用名称" width="200"></el-table-column>
<el-table-column prop="issuerName" label="颁发者"></el-table-column>
<el-table-column prop="beforeTime" label="证书起始时间"></el-table-column>
<el-table-column prop="afterTime" label="证书截止时间"></el-table-column>
<el-table-column prop="afterTime" style="color: red" label="剩余天数" :formatter="getTotalDate"></el-table-column>
<el-table-column prop="createTime" label="创建时间"></el-table-column>
<el-table-column prop="remark" label="备注"></el-table-column>
<el-table-column fixed="right" label="操作" width="120">
<template slot-scope="scope">
<el-button size="mini" type="primary" @click="handleMore(scope.$index, scope.row)">More</el-button>
</template>
</el-table-column>
</el-table>
</div>
<br />
<br />
<div>
<div class="block">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[10, 50, 100]"
:page-size="pagesize"
layout="total, sizes, prev, pager, next"
:total="total"
></el-pagination>
</div>
</div>
</div>
</template>

<script>
const axios = require("axios").default;
export default {
data() {
return {
tableData: [],
currentPage: 1,
pagesize: 10,
total: 10,
dialogFormVisible: false,
form: {},
formLabelWidth: "120px",
fileList: [],
multipleTable: [],
};
},
created() {
this.requestdata(10, 1);
},
methods: {
changeCellStyle(row, column, rowIndex, columnIndex) {
//列的label的名称
if (row.column.label === "剩余天数") {
return "color:red"; //修改的样式
} else {
return "";
}
},
handleDelete() {
var self = this;
var selection = this.$refs.multipleTable.selection;
var id_list = [];
for (let i in selection) {
id_list.push(selection[i].id);
}
axios({
method: "post",
url: "http://devops.zhaohongye.com/api/v1/ssl/_delete",
data: {
id: id_list,
},
responseType: "json",
}).then(function(response) {
self.requestdata(10, 1);
self.$message({ message: "删除成功,资源id为: " + String(id_list), type: "success" });
});
},

submitUpload() {
this.$refs.upload.submit();
},
handleRemove(file, fileList) {
console.log(file, fileList);
},
handlePreview(file) {
console.log(file);
},
getFile(event) {
this.form.certificateFile = event.target.files[0];
},
onSubmit(formName) {
var self = this;

if (self.form.type === "证书内容") {
axios({
method: "post",
url: "http://devops.zhaohongye.com/api/v1/ssl/_create",
data: self.form,
responseType: "json",
}).then(function(response) {
self.$message({ message: "证书导入成功", type: "success" });
self.dialogFormVisible = false;
self.form = {};
self.requestdata(10, 1);
});
} else {
let formData = new FormData();
formData.append("name", self.form.name);
formData.append("certificateFile", self.form.certificateFile);
axios.post("http://devops.zhaohongye.com/api/v1/ssl/_create", formData).then(function(response) {
self.$message({ message: "证书导入成功", type: "success" });
self.dialogFormVisible = false;
self.form = {};
self.requestdata(10, 1);
});
}
},
handleMore(index, row) {
this.$router.push({
path: "/ssl/detail",
query: { id: row.id },
});
},
handleChange(file, fileList) {
this.fileList = fileList.slice(-3);
},
handleSizeChange(val) {
const self = this;
if (self.serviceTreeNodeClicked) {
self.requestnodedata(self.serviceTreeNodeId, val, self.currentPage);
} else {
self.requestdata(val, self.currentPage);
}
},
handleCurrentChange(val) {
const self = this;
if (self.serviceTreeNodeClicked) {
self.requestnodedata(this.serviceTreeNodeId, self.pagesize, val);
} else {
self.requestdata(self.pagesize, val);
}
},
getTotalDate(row, column) {
var sDate = row.afterTime;
var date2 = new Date();
var date1 = new Date(Date.parse(sDate.replace(/-/g, "/")));
var totalDate = parseInt(Math.abs(date2.getTime() - date1.getTime()) / 1000 / 60 / 60 / 24);
// console.log(date1, date2, totalDate);
return totalDate;
},
requestdata(pageSize, pageNo) {
const self = this;
axios({
method: "get",
url: "http://devops.zhaohongye.com/api/v1/ssl/_list",
params: {
page: pageNo,
pageSize: pageSize,
},
responseType: "json",
}).then(function(response) {
var res = response.data.data;
self.tableData = res.list;
self.total = res.total;
self.currentPage = res.page;
self.pagesize = res.pagesize;
});
},
},
};
</script>

detail.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
<template>
<div>
<!-- <el-container> -->
<!-- <el-card> -->
<h3 style="text-align: left;">证书详情</h3>
<div style="margin-left: 50px">
<el-row type="flex" class="row-bg" justify="center">
<el-col :span="12" style="text-align: left;">通用名称:{{ data.unit }}</el-col>
<el-col :span="12" style="text-align: left;">组织:{{ data.organization }}</el-col>
</el-row>
<el-row type="flex" class="row-bg" justify="center">
<el-col :span="12" style="text-align: left;">颁发者:{{ data.issuerName }}</el-col>
<el-col :span="12" style="text-align: left;">省份:{{ data.city }}</el-col>
</el-row>
<el-row type="flex" class="row-bg" justify="center">
<el-col :span="12" style="text-align: left;">颁发者组织:{{ data.issuerOrganization }}</el-col>
<el-col :span="12" style="text-align: left;">国家:{{ data.country }}</el-col>
</el-row>
<el-row type="flex" class="row-bg" justify="center">
<el-col :span="12" style="text-align: left;">颁发者单位:{{ data.issuerUnit }}</el-col>
<el-col :span="12" style="text-align: left;">编号:{{ data.serialNumber }}</el-col>
</el-row>
<el-row type="flex" class="row-bg" justify="center">
<el-col :span="12" style="text-align: left;">颁发日期:{{ data.beforeTime }}</el-col>
<el-col :span="12" style="text-align: left;">加密算法:{{ data.issuerName }}</el-col>
</el-row>
<el-row type="flex" class="row-bg" justify="center">
<el-col :span="12" style="text-align: left;">截止日期:{{ data.afterTime }}</el-col>
<el-col :span="12" style="text-align: left;">加密强度:{{ data.pubkeyBits }}</el-col>
</el-row>
<el-row type="flex" class="row-bg" justify="center">
<el-col :span="12" style="text-align: left;">导入日期:{{ data.createTime }}</el-col>
<el-col :span="12" style="text-align: left;">签名算法:{{ data.signatureAlgorithm }}</el-col>
</el-row>
<el-row type="flex" class="row-bg" justify="center">
<el-col :span="12" style="text-align: left;">SHA1指纹:{{ data.gitUrl }}</el-col>
<el-col :span="12" style="text-align: left;">公钥SHA256-PIN:{{ data.thirdPartyCompany }}</el-col>
</el-row>
<el-row type="flex" class="row-bg" justify="center">
<el-col :span="12" style="text-align: left;">SHA256指纹:{{ data.desc }}</el-col>
<el-col :span="12" style="text-align: left;">颁发者Hash:{{ data.desc }}</el-col>
</el-row>
</div>

<!-- <el-container> -->
<!-- <el-card> -->
<h3 style="text-align: left;">证书内容</h3>
<div style="margin-left: 50px">
<el-row type="flex" class="row-bg" justify="center">
<el-col :span="12" style="text-align: left;">
<el-input type="textarea" autosize :disabled="true" placeholder="空空如也" v-model="textarea"></el-input>
<!-- {{ textarea }} -->
</el-col>
</el-row>
</div>
</div>
</template>

<script>
const axios = require("axios").default;
export default {
data() {
return {
data: {},
textarea: "",
};
},
created() {
this.requestdata();
// this.handtree();
},
methods: {
handleChange(val) {
console.log(val);
},
requestdata() {
const self = this;
axios({
method: "get",
url: "http://devops.zhaohongye.com/api/v1/ssl/_detail",
params: {
id: self.$route.query.id,
},
responseType: "json",
}).then(function(response) {
var res = response.data.data;
console.log(res);
self.data = res;
self.textarea = res.certificate;
});
},
},
};
</script>

<style>
.el-row {
margin-bottom: 20px;
&:last-child {
margin-bottom: 0;
}
}
.el-col {
border-radius: 4px;
}
.bg-purple-dark {
background: #99a9bf;
}
.bg-purple {
background: #d3dce6;
}
.bg-purple-light {
background: #e5e9f2;
}
.grid-content {
border-radius: 4px;
min-height: 36px;
}
.row-bg {
padding: 10px 0;
/* background-color: #f9fafc; */
}
</style>