<template>
|
<div class="right-main pageAlg">
|
<div class="bread-crumb">
|
<span class="prev-title">
|
<router-link to="/layout/PageAlgorithm">算法列表</router-link>
|
</span>
|
<span class="devide"></span>
|
<span class="cur-title">{{ action == "create" ? "添加" : "编辑" }}</span>
|
</div>
|
|
<div style="min-height: calc(100vh - 150px); background: #fff">
|
<el-form
|
:model="algForm"
|
ref="algForm"
|
:rules="rules"
|
label-width="120px"
|
v-loading="loading"
|
>
|
<div class="base-info info-block">
|
<div class="info-header">
|
<span class="title">基本信息</span>
|
</div>
|
<div class="info-body">
|
<div class="left">
|
<el-form-item label="应用算法名称" prop="sdk_name">
|
<el-input v-model="algForm.sdk_name" size="small"></el-input>
|
</el-form-item>
|
<el-form-item label="对应基础算法" prop="sdk_type">
|
<el-select v-model="algForm.sdk_type" size="small">
|
<el-option
|
:label="item.sdk_type"
|
:value="item.sdk_type"
|
v-for="item in baseSdkList"
|
:key="item.id"
|
></el-option>
|
</el-select>
|
</el-form-item>
|
<el-form-item label="对应SO" prop="rule_so">
|
<el-input v-model="algForm.rule_so" size="small"></el-input>
|
</el-form-item>
|
</div>
|
<div class="right">
|
<el-form-item label="算法logo">
|
<el-upload
|
class="avatar-uploader"
|
drag
|
action="https://jsonplaceholder.typicode.com/posts/"
|
:show-file-list="false"
|
:http-request="uploadAlgLogo"
|
:on-success="onSuccess"
|
:before-upload="beforeUpload"
|
>
|
<el-image
|
v-if="algForm.iconBlob"
|
:src="
|
algForm.iconBlob.indexOf(',') > 0
|
? algForm.iconBlob
|
: `data:image/png;base64,${algForm.iconBlob}`
|
"
|
style="width: 100%; height: 100%"
|
fit="contain"
|
></el-image>
|
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
|
<div class="el-upload__text">
|
将图片拖到此处,或
|
<em>点击上传</em>
|
</div>
|
</el-upload>
|
<span class="second-icon-desc">其它风格应用logo:</span>
|
<el-upload
|
class="avatar-uploader"
|
drag
|
action="https://jsonplaceholder.typicode.com/posts/"
|
:show-file-list="false"
|
:http-request="uploadAlgLogo2"
|
:on-success="onSuccess"
|
:before-upload="beforeUpload"
|
>
|
<el-image
|
v-if="algForm.iconBlob2"
|
:src="
|
algForm.iconBlob2.indexOf(',') > 0
|
? algForm.iconBlob2
|
: `data:image/png;base64,${algForm.iconBlob2}`
|
"
|
style="width: 100%; height: 100%"
|
fit="contain"
|
></el-image>
|
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
|
<div class="el-upload__text">
|
将图片拖到此处,或
|
<em>点击上传</em>
|
</div>
|
</el-upload>
|
</el-form-item>
|
<el-form-item label="是否跟踪" prop="enTrack">
|
<el-switch v-model="algForm.enTrack" size="small"></el-switch>
|
</el-form-item>
|
</div>
|
</div>
|
</div>
|
<div class="base-info info-block">
|
<div class="info-header">
|
<span class="title">参数设置</span>
|
<div class="toAdd" @click="toAddParam">
|
<i class="el-icon-circle-plus-outline"></i>
|
<span>添加</span>
|
</div>
|
</div>
|
<div class="info-body">
|
<el-table :data="algParams" border style="width: 100%">
|
<el-table-column
|
type="index"
|
width="50"
|
label="序号"
|
align="center"
|
></el-table-column>
|
<el-table-column
|
prop="arg_type"
|
label="目标/标签"
|
width="110"
|
align="center"
|
>
|
<template slot-scope="scope">
|
<div>
|
<el-select v-model="scope.row.arg_type" size="mini">
|
<el-option label="目标" value="target"></el-option>
|
<el-option label="标签" value="label"></el-option>
|
</el-select>
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column
|
prop="alias"
|
label="算法参数"
|
width="140"
|
align="center"
|
>
|
<template slot-scope="scope">
|
<div>
|
<el-input v-model="scope.row.alias" size="mini"></el-input>
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column
|
prop="name"
|
label="应用参数名称"
|
width="150"
|
align="center"
|
>
|
<template slot-scope="scope">
|
<div>
|
<el-input v-model="scope.row.name" size="mini"></el-input>
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column
|
prop="operators"
|
label="符号关系"
|
width="200"
|
align="center"
|
>
|
<template slot-scope="scope">
|
<div>
|
<el-select
|
v-model="scope.row.operators"
|
size="mini"
|
multiple
|
collapse-tags
|
>
|
<el-option
|
:label="item.name"
|
:value="item"
|
v-for="item in operatorList"
|
:key="item.id"
|
></el-option>
|
</el-select>
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column
|
prop="default_value"
|
label="参数值"
|
width="120"
|
align="center"
|
>
|
<template slot-scope="scope">
|
<div>
|
<el-input
|
v-model="scope.row.default_value"
|
size="mini"
|
></el-input>
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column
|
prop="unit"
|
label="单位"
|
width="90"
|
align="center"
|
>
|
<template slot-scope="scope">
|
<div>
|
<el-input v-model="scope.row.unit" size="mini"></el-input>
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column
|
prop="range"
|
label="参数区间"
|
width="100"
|
align="center"
|
>
|
<template slot-scope="scope">
|
<div>
|
<el-input v-model="scope.row.range" size="mini"></el-input>
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column
|
prop="type"
|
label="值类型"
|
width="110"
|
align="center"
|
>
|
<template slot-scope="scope">
|
<div>
|
<el-select v-model="scope.row.type" size="mini">
|
<el-option label="值" value="value"></el-option>
|
<el-option label="被选项" value="option"></el-option>
|
</el-select>
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column
|
prop="isConfigurable"
|
label="是否可配置"
|
width="100"
|
align="center"
|
>
|
<template slot-scope="scope">
|
<div>
|
<el-select
|
v-model="scope.row.config.isConfigurable"
|
size="mini"
|
>
|
<el-option label="是" :value="true"></el-option>
|
<el-option label="否" :value="false"></el-option>
|
</el-select>
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column
|
prop="isMulti"
|
label="是否多选"
|
width="80"
|
align="center"
|
>
|
<template slot-scope="scope">
|
<div>
|
<el-select v-model="scope.row.config.isMulti" size="mini">
|
<el-option label="是" :value="true"></el-option>
|
<el-option label="否" :value="false"></el-option>
|
</el-select>
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column
|
prop="isOptional"
|
label="是否可选项"
|
width="100"
|
align="center"
|
>
|
<template slot-scope="scope">
|
<div>
|
<el-select
|
v-model="scope.row.config.isOptional"
|
size="mini"
|
>
|
<el-option label="是" :value="true"></el-option>
|
<el-option label="否" :value="false"></el-option>
|
</el-select>
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column
|
prop="isShow"
|
label="是否可见"
|
width="80"
|
align="center"
|
>
|
<template slot-scope="scope">
|
<div>
|
<el-select v-model="scope.row.config.isShow" size="mini">
|
<el-option label="是" :value="true"></el-option>
|
<el-option label="否" :value="false"></el-option>
|
</el-select>
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column label="操作" align="center">
|
<template slot-scope="scope">
|
<div class="operation">
|
<el-tooltip content="上移一位">
|
<i
|
class="el-icon-top"
|
@click="moveUp(scope.$index)"
|
v-show="scope.$index != 0"
|
></i>
|
</el-tooltip>
|
<el-tooltip content="移除该项配置,须保存表单后方能生效">
|
<i
|
class="el-icon-remove-outline"
|
@click="removeParam(scope.$index)"
|
></i>
|
</el-tooltip>
|
</div>
|
</template>
|
</el-table-column>
|
</el-table>
|
</div>
|
<el-form-item size="large" class="form-end">
|
<el-button size="small" @click="backForm">取消</el-button>
|
<el-button type="primary" size="small" @click="saveForm"
|
>保存</el-button
|
>
|
</el-form-item>
|
</div>
|
</el-form>
|
<div class="base-info info-block">
|
<div class="info-header">
|
<span class="title">算法版本</span>
|
<div class="toAdd" @click="toAddVersion">
|
<i class="el-icon-circle-plus-outline"></i>
|
<span>添加</span>
|
</div>
|
</div>
|
<div class="info-body">
|
<el-table :data="versionInfo" style="width: 100%" border>
|
<el-table-column
|
type="index"
|
width="50"
|
label="序号"
|
align="center"
|
></el-table-column>
|
<el-table-column
|
prop="version"
|
width="150"
|
label="版本号"
|
align="center"
|
>
|
<template slot-scope="scope">
|
<div v-if="isVersionEdit && curEditIndex == scope.$index">
|
<el-input v-model="editData.version" size="mini"></el-input>
|
</div>
|
<div v-else>
|
<span>{{ scope.row.version }}</span>
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column
|
prop="content"
|
width="500"
|
label="版本更新内容"
|
header-align="center"
|
>
|
<template slot-scope="scope">
|
<div v-if="isVersionEdit && curEditIndex == scope.$index">
|
<el-input v-model="editData.content" size="mini"></el-input>
|
</div>
|
<div v-else>
|
<span>{{ scope.row.content }}</span>
|
</div>
|
</template>
|
</el-table-column>
|
<el-table-column width="290" label="更新时间" align="center">
|
<template slot-scope="scope">
|
<div>{{ scope.row.update_time || scope.row.create_time }}</div>
|
</template>
|
</el-table-column>
|
<el-table-column
|
prop="updateUserName"
|
width="150"
|
label="更新人"
|
align="center"
|
></el-table-column>
|
<el-table-column width="250" label="附件" align="center">
|
<template slot-scope="scope">
|
<div v-if="isVersionEdit && curEditIndex == scope.$index">
|
<file-uploader
|
single
|
uploadPlaceholder="上传算法文件"
|
url="/data/api-f/file/upload"
|
@complete="onFileUpload"
|
@file-added="onFileAdded"
|
/>
|
</div>
|
<div v-else>{{ scope.row.component_name }}</div>
|
</template>
|
</el-table-column>
|
<el-table-column label="操作" align="center">
|
<template slot-scope="scope">
|
<div v-if="isVersionEdit && curEditIndex == scope.$index">
|
<span class="cursor-pointer" @click="cancel(scope.row)"
|
>取消</span
|
>
|
<span
|
class="cursor-pointer"
|
@click="saveRowVersion(scope.row)"
|
>保存</span
|
>
|
</div>
|
<div class="operation" v-else>
|
<i
|
class="el-icon-edit"
|
@click="edit(scope.row, scope.$index)"
|
></i>
|
<i
|
class="el-icon-remove-outline"
|
@click="remove(scope.row)"
|
></i>
|
</div>
|
</template>
|
</el-table-column>
|
</el-table>
|
</div>
|
</div>
|
</div>
|
</div>
|
</template>
|
<script>
|
// import {
|
// savePageAlg,
|
// findAllBaseAlg,
|
// savePageAlgVersion,
|
// delPageAlgVersion,
|
// showPageAlgDetail,
|
// } from "@/api/algorithm";
|
import { findDicByType } from "@/api/product";
|
import { getFilePath } from "@/api/utils";
|
import FileUploader from "@/components/subComponents/FileUpload/index";
|
export default {
|
components: {
|
FileUploader,
|
},
|
props: ["action", "id"],
|
data() {
|
return {
|
copy_id: this.id,
|
loading: false,
|
algForm: {
|
sdk_name: "",
|
sdk_type: "", //基础算法
|
iconBlob: "",
|
iconBlob2: "",
|
rule_so: "",
|
enTrack: true,
|
},
|
baseSdkList: [],
|
operatorList: [],
|
rules: {
|
sdk_name: [
|
{ required: true, message: "请输入算法名称", trigger: "blur" },
|
{ min: 1, max: 15, message: "长度在1到15个字符", trigger: "blur" },
|
],
|
sdk_type: [
|
{ required: true, message: "请选择基础算法", trigger: "change" },
|
],
|
rule_so: [{ required: true, message: "请输入so", trigger: "blur" }],
|
},
|
algParams: [],
|
algParam: {
|
sort: 0,
|
arg_type: "target",
|
alias: "",
|
name: "",
|
operators: [],
|
range: "",
|
default_value: "",
|
unit: "",
|
type: "value",
|
config: {
|
isConfigurable: true,
|
isMulti: true,
|
isOptional: true,
|
isShow: true,
|
},
|
},
|
versionInfo: [],
|
versionParam: {
|
version: "",
|
content: "",
|
updateTime: "",
|
person: "",
|
component_name: "",
|
component_path: "",
|
},
|
editData: {},
|
curEditVersion: {},
|
isVersionEdit: false,
|
curEditIndex: 0,
|
curEditRow: {},
|
};
|
},
|
mounted() {
|
this.getAllBaseSDK();
|
this.getOperatorList();
|
if (this.action == "create") {
|
//this.id = ''
|
this.copy_id = "";
|
}
|
if (this.copy_id) {
|
this.getPageDetail();
|
}
|
},
|
methods: {
|
newVersion() {
|
return {
|
version: "",
|
content: "",
|
updateTime: "",
|
person: "",
|
component_name: "",
|
component_path: "",
|
};
|
},
|
backForm() {
|
//this.getPageDetail();
|
//this.$router.push('/layout/AppManage');
|
this.$router.go(-1);
|
},
|
getPageDetail() {
|
//回显页面参数
|
showPageAlgDetail({ id: this.copy_id }).then((res) => {
|
if (res.code == 200) {
|
this.algForm.enTrack = res.data.sdkInfo.enTrack;
|
this.algForm.iconBlob = res.data.sdkInfo.iconBlob;
|
this.algForm.iconBlob2 = res.data.sdkInfo.iconBlob2;
|
this.algForm.rule_so = res.data.sdkInfo.rule_so;
|
this.algForm.sdk_type = res.data.sdkInfo.sdk_type;
|
this.algForm.sdk_name = res.data.sdkInfo.sdk_name;
|
this.algParams = res.data.sdkInfo.argDef;
|
this.algParams.forEach((arg) => {
|
arg.operators = arg.operators.map((item) => {
|
return {
|
name: item.name,
|
value: item.operator,
|
};
|
});
|
});
|
|
this.versionInfo = res.data.versions;
|
}
|
});
|
},
|
getAllBaseSDK() {
|
findAllBaseAlg().then((res) => {
|
if (res.code == 200) {
|
this.baseSdkList = res.data.list;
|
}
|
});
|
},
|
getOperatorList() {
|
//this.operatorList
|
findDicByType({ type: "RULECOMPUTE" }).then((res) => {
|
if (res.code == 200) {
|
this.operatorList = res.data.dics;
|
}
|
});
|
},
|
toAddParam() {
|
let algTemp = JSON.parse(JSON.stringify(this.algParam));
|
algTemp.sort = this.algParams.length + 1;
|
this.algParams.push(algTemp);
|
},
|
toAddVersion() {
|
if (this.isVersionEdit) return;
|
//let versionTemp = JSON.parse(JSON.stringify(this.versionParam));
|
// let versionTemp = this.newVersion();
|
// this.versionInfo.push(versionTemp);
|
this.editData = this.newVersion();
|
this.versionInfo.push(this.editData);
|
this.isVersionEdit = true;
|
this.curEditIndex = this.versionInfo.length - 1;
|
},
|
beforeUpload() {},
|
uploadAlgLogo(params) {
|
let file = params.file;
|
let fileReader = new FileReader();
|
if (file) {
|
fileReader.readAsDataURL(file);
|
}
|
fileReader.onload = () => {
|
this.algForm.iconBlob = fileReader.result;
|
};
|
},
|
uploadAlgLogo2(params) {
|
let file = params.file;
|
let fileReader = new FileReader();
|
if (file) {
|
fileReader.readAsDataURL(file);
|
}
|
fileReader.onload = () => {
|
this.algForm.iconBlob2 = fileReader.result;
|
};
|
},
|
onSuccess() {},
|
moveUp(curIndex) {
|
let lastOne = JSON.parse(JSON.stringify(this.algParams[curIndex - 1]));
|
let curOne = JSON.parse(JSON.stringify(this.algParams[curIndex]));
|
//this.algParams.splice(curIndex,1,curIndex-1);
|
this.$set(this.algParams, curIndex, lastOne);
|
this.$set(this.algParams, curIndex - 1, curOne);
|
this.algParams[curIndex - 1].sort = curIndex;
|
this.algParams[curIndex].sort = curIndex + 1;
|
},
|
removeParam(index) {
|
// this.$notify({
|
// type:'info',
|
// message:'请在保存后查看最新内容'
|
// });
|
this.algParams.splice(index, 1);
|
},
|
remove(row) {
|
this.$confirm("确定删除该项吗?", "提示", {
|
confirmButtonText: "确定",
|
cancelButtonText: "取消",
|
type: "warning",
|
center: true,
|
})
|
.then(() => {
|
delPageAlgVersion(row.id).then((res) => {
|
if (res.code == 200) {
|
this.$message({
|
type: "success",
|
message: "删除成功!",
|
});
|
this.getPageDetail();
|
}
|
});
|
})
|
.catch((e) => {
|
console.log(e);
|
});
|
},
|
cancel(row) {
|
this.isVersionEdit = false;
|
if (!row.id) {
|
this.versionInfo.splice(this.versionInfo.length - 1, 1);
|
}
|
},
|
// rowClick (row, column, ev) {
|
// this.curEditRow = JSON.parse(JSON.stringify(row));
|
// },
|
saveForm() {
|
this.$refs["algForm"].validate((valid) => {
|
if (valid) {
|
//处理operators
|
this.algParams.forEach((param) => {
|
param.operators = param.operators.map((item) => {
|
return {
|
name: item.name,
|
operator: item.value,
|
};
|
});
|
});
|
|
let params = {
|
argDef: this.algParams,
|
enTrack: this.algForm.enTrack,
|
iconBlob: this.algForm.iconBlob,
|
iconBlob2: this.algForm.iconBlob2,
|
id: this.copy_id,
|
rule_so: this.algForm.rule_so,
|
sdk_name: this.algForm.sdk_name,
|
sdk_type: this.algForm.sdk_type,
|
};
|
|
let warning = "";
|
|
params.argDef.forEach((item) => {
|
if (
|
item.alias === "" ||
|
item.name === "" ||
|
item.operators.length === 0 ||
|
item.default_value === "" ||
|
item.unit === "" ||
|
item.range === ""
|
) {
|
warning = "参数信息不全";
|
}
|
});
|
|
if (warning) {
|
this.$notify({
|
type: "warning",
|
message: "参数信息不全",
|
});
|
return;
|
}
|
this.loading = true;
|
|
savePageAlg(params)
|
.then((res) => {
|
this.$notify({
|
type: "success",
|
message: "保存成功!",
|
duration: 2500,
|
offset: 57,
|
});
|
//this.id = res.data.id;
|
this.copy_id = res.data.id;
|
this.getPageDetail();
|
this.loading = false;
|
})
|
.catch((e) => {
|
console.log(e);
|
if (e && e.status == 401) {
|
return;
|
}
|
if (e && e.data == "算法名称不允许重复") {
|
this.$notify({
|
type: "error",
|
message: "保存失败,算法名称不允许重复",
|
duration: 2500,
|
offset: 57,
|
});
|
this.loading = false;
|
return;
|
}
|
this.$notify({
|
type: "error",
|
message: "保存失败,请稍后重试!",
|
duration: 2500,
|
offset: 57,
|
});
|
this.loading = false;
|
});
|
} else {
|
return false;
|
}
|
});
|
},
|
saveRowVersion(row) {
|
this.isVersionEdit = false;
|
let params = {
|
component_name: this.curEditRow.component_name,
|
component_path: this.curEditRow.component_path,
|
content: this.editData.content,
|
id: this.editData.id,
|
sdkId: this.copy_id,
|
create_by: this.editData.create_by,
|
create_time: this.editData.create_time,
|
update_by: this.editData.update_by,
|
update_time: this.editData.update_time,
|
version: this.editData.version,
|
};
|
|
savePageAlgVersion(params)
|
.then((res) => {
|
if (res.code == 200) {
|
this.$notify({
|
type: "success",
|
message: "保存成功!",
|
position: "bottom-right",
|
duration: 2500,
|
});
|
this.getPageDetail();
|
}
|
})
|
.catch((e) => {
|
this.$notify({
|
type: "error",
|
message: e.data,
|
position: "bottom-right",
|
duration: 2500,
|
});
|
this.getPageDetail();
|
});
|
},
|
edit(row, index) {
|
this.isVersionEdit = true;
|
this.curEditIndex = index;
|
this.editData = JSON.parse(JSON.stringify(row));
|
},
|
onFileUpload(params) {
|
this.curEditRow.component_name = params.filename;
|
getFilePath(params).then((res) => {
|
if (res.code == 200) {
|
this.curEditRow.component_path = res.data;
|
}
|
});
|
},
|
onFileAdded() {},
|
},
|
};
|
</script>
|
<style lang="scss">
|
.pageAlg {
|
height: 100%;
|
.el-switch.is-checked .el-switch__core {
|
border-color: #1a99ff;
|
background-color: #1a99ff;
|
}
|
.orderTop {
|
width: calc(100% - 60px);
|
height: 30px;
|
background: #fff;
|
padding: 15px 30px;
|
p {
|
font-family: "PingFangSC-Regular";
|
text-align: left;
|
font-size: 14px;
|
line-height: 30px;
|
}
|
}
|
.orderBody {
|
width: calc(100% - 40px);
|
//height: calc(100% - 100px);
|
padding: 20px;
|
background: #f0f2f5;
|
}
|
}
|
.info-block {
|
background: #fff;
|
padding: 20px;
|
.info-header {
|
border-bottom: 1px solid #eee;
|
display: flex;
|
padding: 10px 5px;
|
margin-bottom: 10px;
|
.title {
|
font-size: 15px;
|
font-weight: bold;
|
margin-right: 16px;
|
}
|
}
|
.info-body {
|
display: flex;
|
width: 100%;
|
margin-bottom: 20px;
|
.left,
|
.right {
|
width: 50%;
|
text-align: left;
|
.el-select {
|
width: 100%;
|
}
|
.el-upload {
|
width: 100px;
|
height: 100px;
|
line-height: 100px;
|
}
|
}
|
.el-table {
|
overflow: hidden;
|
}
|
.el-table th {
|
background: rgb(248, 248, 248);
|
color: rgb(34, 34, 34);
|
}
|
.operation {
|
font-size: 20px;
|
cursor: pointer;
|
.el-icon-top {
|
color: #409eff;
|
margin-right: 10px;
|
}
|
.el-icon-remove-outline {
|
color: red;
|
}
|
.el-icon-edit {
|
margin-right: 10px;
|
}
|
}
|
}
|
.form-end {
|
padding-top: 20px;
|
}
|
}
|
.toAdd {
|
font-size: 13px;
|
color: #1a99ff !important;
|
&:hover {
|
color: #45abfc !important;
|
}
|
&:focus {
|
color: #1789e5 !important;
|
}
|
cursor: pointer;
|
i {
|
font-size: 15px;
|
margin-right: 2px;
|
}
|
}
|
.avatar-uploader {
|
float: left;
|
}
|
.second-icon-desc {
|
float: left;
|
margin-left: 50px;
|
}
|
.avatar-uploader .el-upload {
|
border-radius: 6px;
|
cursor: pointer;
|
position: relative;
|
overflow: hidden;
|
}
|
.avatar-uploader .el-upload-dragger {
|
width: 100px;
|
height: 100px;
|
}
|
.avatar-uploader .el-upload:hover {
|
border-color: #409eff;
|
}
|
.avatar-uploader-icon {
|
font-size: 28px;
|
color: #8c939d;
|
}
|
.avatar {
|
width: 178px;
|
height: 178px;
|
display: block;
|
}
|
</style>
|