Commit 4fcaf270 authored by mhw's avatar mhw

版本更新

parent 84bea040
......@@ -23,7 +23,8 @@ module.exports = {
'lines-between-class-members': ['off'],
// 'no-undef': ['off', 'always'],
// 'no-unused-vars': ['off', 'always'],
'no-new-func': ['off', 'always']
'no-new-func': ['off', 'always'],
'space-before-function-paren':0
},
overrides: [
{
......
export default class ModelDeployment {
static list (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/app/modelDeploy/list', 'post', params, axiosOption, httpOption);
}
static listForTree (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/app/modelManage/listForTree', 'post', params, axiosOption, httpOption);
}
static add (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/app/modelDeploy/add', 'post', params, axiosOption, httpOption);
}
static delete (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/app/modelDeploy/delete', 'post', params, axiosOption, httpOption);
}
static deploy (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/app/modelDeploy/deploy', 'post', params, axiosOption, httpOption);
}
static getGpuInfo (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/app/modelDeploy/getGpuInfo', 'post', params, axiosOption, httpOption);
}
static stop (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/app/modelDeploy/stop', 'post', params, axiosOption, httpOption);
}
static canUseList (sender, params, axiosOption, httpOption) {
return sender.doUrl('/admin/app/modelDeploy/canUseList', 'post', params, axiosOption, httpOption);
}
}
......@@ -16,6 +16,7 @@ import TuningRun from './GptController/TuningRun.js';
import PyApi from './GptController/PyApi.js';
import KnowledgeManage from './GptController/KnowledgeManage.js';
import DatasetData from './GptController/DatasetData.js';
import ModelDeployment from './GptController/ModelDeployment.js';
export {
TemplateController,
......@@ -34,5 +35,6 @@ export {
TuningRun,
PyApi,
KnowledgeManage,
DatasetData
DatasetData,
ModelDeployment
}
module.exports = {
baseUrl: 'http://218.76.0.69:8082/',
// baseUrl: 'http://218.76.0.69:8082/',
baseUrl: 'http://192.168.0.34:8082/',
wsUrl: 'ws://218.76.0.69:7860/',
projectName: '灵境大模型平台'
}
......@@ -14,20 +14,21 @@ const routers = [
component: _import('login/index'),
name: 'root'
},
{path: '/aggregate', component: _import('welcome/index-2'), name: 'aggregate', meta: { title: '集群' }},
// {path: '/aggregate', component: _import('welcome/index'), name: 'aggregate', meta: { title: '集群' }},
{
path: '/main',
component: _import('layout/index'),
name: 'main',
props: getProps,
redirect: {
name: 'aggregate'
name: 'welcome'
},
meta: {
title: '主页',
showOnly: true
},
children: [
{ path: 'welcome', component: _import('welcome/index'), name: 'welcome', meta: { title: '欢迎' } },
{ path: 'formSysUser', component: _import('upms/formSysUser/index'), name: 'formSysUser', meta: { title: '用户管理' } },
{ path: 'formSysDept', component: _import('upms/formSysDept/index'), name: 'formSysDept', meta: { title: '部门管理' } },
{ path: 'formSysRole', component: _import('upms/formSysRole/index'), name: 'formSysRole', meta: { title: '角色管理' } },
......@@ -52,6 +53,7 @@ const routers = [
{ path: 'modelSquare', component: _import('gptTraining/modelManagement/modelSquare/index'), name: 'modelSquare', props: getProps, meta: { title: '模型广场' } },
{ path: 'modelEvaluation', component: _import('gptTraining/modelManagement/modelEvaluation/index'), name: 'modelEvaluation', props: getProps, meta: { title: '模型评估' } },
{ path: 'modelCompression', component: _import('gptTraining/modelManagement/modelCompression/index'), name: 'modelCompression', props: getProps, meta: { title: '模型压缩' } },
{ path: 'modelDeployment', component: _import('gptTraining/modelManagement/modelDeployment/index'), name: 'modelDeployment', props: getProps, meta: { title: '模型部署' } },
// 模型服务
{ path: 'serviceManagement', component: _import('gptTraining/modelService/serviceManagement/index'), name: 'serviceManagement', props: getProps, meta: { title: '在线服务' } },
{ path: 'applicationAccess', component: _import('gptTraining/modelService/applicationAccess/index'), name: 'applicationAccess', props: getProps, meta: { title: '应用接入' } },
......@@ -89,9 +91,7 @@ const routers = [
// { path: 'onLineOptimization', component: _import('gptTraining/promptProject/onLineOptimization/index'), name: 'onLineOptimization', props: getProps, meta: { title: '在线优化' } },
// { path: 'batchOptimization', component: _import('gptTraining/promptProject/batchOptimization/index'), name: 'batchOptimization', props: getProps, meta: { title: '批量优化' } },
// 知识库
{ path: 'knowledgeBase', component: _import('gptTraining/knowledgeBase/index'), name: 'knowledgeBase', props: getProps, meta: { title: '知识库' } },
{ path: 'welcome', component: _import('welcome/index'), name: 'welcome', meta: { title: '欢迎' } }
{ path: 'knowledgeBase', component: _import('gptTraining/knowledgeBase/index'), name: 'knowledgeBase', props: getProps, meta: { title: '知识库' } }
]
}
];
......
......@@ -455,7 +455,36 @@ const RunningStatus = new DictionaryBase('运行状态', [
symbol: 'TrainingUnderway'
}
]);
Vue.prototype.RunningStatus = RunningStatus;
const DeploymentStatus = new DictionaryBase('部署状态', [
{
id: -1,
name: '部署失败',
symbol: 'DeploymentFailure'
},
{
id: 0,
name: '部署中',
symbol: 'Deployed'
},
{
id: 1,
name: '部署成功',
symbol: 'DeploymentComplete'
},
{
id: 2,
name: '部署中断',
symbol: 'DeploymentInterrupt'
},
{
id: 3,
name: '待部署',
symbol: 'ToBeDeployed'
}
]);
Vue.prototype.DeploymentStatus = DeploymentStatus;
export {
TemplateLabelDict,
ScenarioTypeDict,
......@@ -475,5 +504,6 @@ export {
ModelCreationMode,
TrainingMethod,
ModeOfSpeaking,
RunningStatus
RunningStatus,
DeploymentStatus
}
<!-- 基本信息-->
<template>
<el-form label-position="left" ref="form" label-width="100px" :model="form" :size="defaultFormItemSize" :rules="rules">
<el-row class="title">基本信息</el-row>
<el-form-item label="服务名称:" prop="modelDeployDto.serviceName">
<el-input v-model="form.modelDeployDto.serviceName" class="inputWidth" placeholder="服务名称"></el-input>
<el-row>
<span class="introduce">支持中英文、数字、下划线(_),2-20个字符,不能以下划线为开头</span></el-row>
</el-form-item>
<el-form-item label="服务描述:">
<el-input type="textarea" :rows="2" v-model="form.modelDeployDto.serviceDescription" placeholder="服务描述"></el-input>
</el-form-item>
<el-form-item label="选择模型:" prop="modelDeployDto.versionId">
<el-cascader v-model="form.modelDeployDto.versionId" :options="modelList" :props='{ label: "name", value: "id", emitPath: false }'></el-cascader>
</el-form-item>
<el-form-item label="API地址:">
<el-input v-model="form.modelDeployDto.apiUrl" class="inputWidth" placeholder="API地址"></el-input>
</el-form-item>
<el-row class="title">模型配置</el-row>
<el-form-item label="资源配置:" prop="modelDeployDto.resourceInfo">
<modelConfiguration v-model="form.modelDeployDto.resourceInfo" />
</el-form-item>
<el-row type="flex" justify="end" class="dialog-btn-layer mt20">
<el-button :plain="true" @click="onCancel(false)">取消</el-button>
<el-button type="primary" @click="onSubmit">确定</el-button>
</el-row>
</el-form>
</template>
<script>
import { ModelDeployment } from '@/api/gptController.js'
import modelConfiguration from './modelConfiguration'
export default {
data() {
return {
modelList: [],
form: {
modelDeployDto: {
apiUrl: undefined,
resourceInfo: '',
serviceName: '',
serviceVersion: undefined,
versionId: undefined
}
},
rules: {
'modelDeployDto.serviceName': [{ required: true, message: '请输入服务名称', trigger: 'blur' }],
'modelDeployDto.resourceInfo': [{ required: true, message: '请选择资源配置', trigger: 'blur' }],
'modelDeployDto.versionId': [{ required: true, message: '请选择模型', trigger: 'blur' }]
}
}
},
props: ['isEdit', 'item'],
components: { modelConfiguration },
computed: {},
mounted() {
this.intFrom()
this.getModelList()
},
methods: {
intFrom() {
this.form = { ...this.form, ...this.item }
try {
this.form.templateLabel = JSON.parse(this.item.templateLabel)
} catch (error) {
// console.log(error);
}
},
onCancel(isSuccess) {
if (this.observer != null) {
this.observer.cancel(isSuccess)
}
},
onSubmit() {
return new Promise((resolve, reject) => {
this.$refs['form'].validate((valid) => {
if (valid) {
let params = {}
params = { ...this.form }
if (this.isEdit) {
ModelDeployment.update(this, params)
.then((res) => {
resolve(res)
this.$message.success('编辑成功')
this.onCancel(true)
})
.catch((e) => {
reject(e)
})
} else {
ModelDeployment.add(this, params)
.then((res) => {
resolve(res)
this.$message.success('添加成功')
this.onCancel(true)
})
.catch((e) => {
reject(e)
})
}
} else {
// reject();
}
})
})
},
getModelList() {
ModelDeployment.listForTree(this, {})
.then((res) => {
this.modelList = res.data
.filter((item) => item.isBaseModel === 1)
.map((item) => {
return {
id: item.modelId,
name: item.modelName,
children:
// prettier-ignore
item.modelVersionList === [] ? [] : item.modelVersionList.map((item2) => {
return { id: item2.versionId, name: 'V' + item2.modelVersion }
})
}
})
})
.catch((e) => {
console.log(e)
})
}
}
}
</script>
<style scoped>
.inputWidth {
width: 600px;
}
.title {
font-size: 20px;
margin-bottom: 16px;
}
.introduce {
font-size: 12px;
color: #909399;
}
</style>
<!-- 参数配置-->
<template>
<el-table :data="list" style="width: 100%" @selection-change="change">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column prop="gpu_id" label="gpuID" width="150">
</el-table-column>
<el-table-column prop="gpu_name" label="名称">
</el-table-column>
<el-table-column prop="total_memory" label="显存总大小(M)">
</el-table-column>
<el-table-column prop="used_memory" label="使用大小(M)">
</el-table-column>
<el-table-column prop="free_memory" label="剩余大小(M)">
</el-table-column>
<el-table-column prop="gpu_util" label="显卡利用率">
<template slot-scope="scope">
{{ scope.row.gpu_util }}%
</template>
</el-table-column>
</el-table>
</template>
<script>
import { ModelDeployment } from '@/api/gptController.js'
export default {
data() {
return {
list: [],
configData: undefined
}
},
props: ['existingTask', 'value'],
components: {},
computed: {},
mounted() {
this.getGpuInfo()
},
methods: {
change(data) {
console.log(data)
this.$emit('input', JSON.stringify(data))
},
isJSON(str) {
try {
return JSON.parse(str)
} catch (e) {
// 转换出错,抛出异常
return false
}
},
getGpuInfo() {
ModelDeployment.getGpuInfo(this, {})
.then((res) => {
this.list = this.isJSON(res.data).gpu_list
})
.catch((e) => {
console.log(e)
})
}
}
}
</script>
<style >
div /deep/ .el-cascader-menu__wrap {
height: auto;
}
</style>
<!-- 模型部署 -->
<template>
<div style="position: relative">
<div class="topBox">
<div class="title">模型部署</div>
<div class="instructions"></div>
</div>
<div class="tableBox" :style="{ height: tableHeight }">
<el-form ref="myDataSetPage" :model="myDataSetPage" label-width="75px" :size="defaultFormItemSize" label-position="right" @submit.native.prevent>
<filter-box :item-width="350" @search="refresh()" @reset="onReset">
<el-form-item label-width="0px">
<el-button class="add" type="primary" icon="el-icon-plus" :size="defaultFormItemSize" @click="add()">部署模型</el-button>
</el-form-item>
<el-form-item label-width="0px"> </el-form-item>
<el-form-item label="服务名称" prop="formFilter.serviceName" label-width="120px">
<el-input class="filter-item" v-model="myDataSetPage.formFilter.serviceName" :clearable="true" placeholder="服务名称" />
</el-form-item>
</filter-box>
</el-form>
<vxe-table border show-header-overflow show-overflow :row-config="{ isHover: true }" :data="myDataSetPage.tableData.impl.dataList" min-height="96">
<vxe-column field="serviceName" title="服务名称"></vxe-column>
<vxe-column field="versionName" title="模型版本"></vxe-column>
<vxe-column field="deployStatus" title="部署状态">
<template slot-scope="scope">
{{ DeploymentStatus.getValue(scope.row.deployStatus) }}
</template>
</vxe-column>
<vxe-column field="createTime" title="创建时间"></vxe-column>
<vxe-column field="updateTime" title="更新时间"></vxe-column>
<vxe-column field="operation" title="操作">
<template slot-scope="scope">
<el-button type="text" :size="defaultFormItemSize" @click="particulars(scope.row)">详情</el-button>
<el-button type="text" :size="defaultFormItemSize" @click="stop(scope.row)">卸载</el-button>
<el-button type="text" :size="defaultFormItemSize" @click="deploy(scope.row,'start')" v-if="scope.row.deployStatus==-1||scope.row.deployStatus==2||scope.row.deployStatus==3">启动</el-button>
<el-button type="text" :size="defaultFormItemSize" @click="deploy(scope.row,'reload')">重载</el-button>
<el-button type="text" :size="defaultFormItemSize" @click="del(scope.row)">删除</el-button>
</template>
</vxe-column>
</vxe-table>
<el-row slot="pagination" type="flex" justify="end" style="margin-top: 16px">
<el-pagination :total="myDataSetPage.tableData.impl.totalCount" :current-page="myDataSetPage.tableData.impl.currentPage" :page-size="myDataSetPage.tableData.impl.pageSize" :page-sizes="[10, 20, 50, 100]" layout="total, prev, pager, next, sizes" @current-change="myDataSetPage.tableData.impl.onCurrentPageChange" @size-change="myDataSetPage.tableData.impl.onPageSizeChange">
</el-pagination>
</el-row>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
/* eslint-disable-next-line */
import { TableWidget } from '@/utils/widget.js'
import { ModelDeployment } from '@/api/gptController.js'
import editOrAdd from './dialog/editOrAdd'
import particulars from './particulars/index'
export default {
data() {
return {
myDataSetPage: {
formFilter: {
serviceName: '',
isBaseModel: 0
},
tableData: {
impl: new TableWidget(this.getwidgetData, true, true, false, undefined, false)
}
}
}
},
components: {},
computed: {
...mapGetters(['getMainContextHeight']),
tableHeight() {
return this.getMainContextHeight - 145 + 'px'
}
},
methods: {
getwidgetData(params) {
if (params == null) params = {}
params = {
modelDeployDtoFilter: {
...this.myDataSetPage.formFilter
},
...params,
// orderParam: [
// {
// asc: true,
// dateAggregateBy: '',
// fieldName: ''
// }
// ],
// pageParam: {
// pageNum: 0,
// pageSize: 0
// },
promptTemplateDtoFilter: { ...this.myDataSetPage.formFilter }
}
return new Promise((resolve, reject) => {
ModelDeployment.list(this, params)
.then((res) => {
resolve({
dataList: res.data.dataList,
totalCount: res.data.totalCount
})
})
.catch((e) => {
reject(e)
})
})
},
add() {
this.$dialog
.show(
'创建服务',
editOrAdd,
{
area: ['100%', '100%']
},
{ isEdit: false }
)
.then((res) => {
this.refresh()
})
.catch((e) => {})
},
edit(item) {
this.$dialog
.show(
'修改服务',
editOrAdd,
{
area: ['100%', '100%']
},
{ isEdit: true, item: item }
)
.then((res) => {
this.refresh()
})
.catch((e) => {})
},
del(item) {
this.$confirm('是否确认删除', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
let params = { deployId: item.deployId }
ModelDeployment.delete(this, params)
.then((res) => {
this.$message.success('删除成功')
this.refresh()
})
.catch((e) => {
console.log(e)
})
})
},
particulars(item) {
this.$dialog
.show(
'详情',
particulars,
{
area: ['100%', '100%']
},
{ tableItem: item }
)
.then((res) => {
this.refresh()
})
.catch((e) => {})
},
deploy(item, type) {
// 部署
this.$confirm('是否确认部署', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
let params = { modelDeployDto: { deployId: item.deployId }, type }
ModelDeployment.deploy(this, params)
.then((res) => {
this.$message.success('部署成功')
this.refresh()
})
.catch((e) => {
console.log(e)
})
})
},
stop(item) {
// 卸载
this.$confirm('是否确认卸载', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
let params = { modelDeployDto: { deployId: item.deployId } }
ModelDeployment.stop(this, params)
.then((res) => {
this.$message.success('卸载成功')
this.refresh()
})
.catch((e) => {
console.log(e)
})
})
},
refresh(reloadData = false) {
if (reloadData) {
this.myDataSetPage.tableData.impl.refreshTable(true, 1)
} else {
this.myDataSetPage.tableData.impl.refreshTable()
}
},
onReset() {
this.$refs.myDataSetPage.resetFields()
this.refresh(true)
},
formInit() {
this.refresh()
}
},
mounted() {
this.formInit()
}
}
</script>
<style lang="scss" scoped>
@import '@/assets/style/element-variables.scss';
.topBox {
background-color: white;
width: 100%;
height: 95px;
margin-bottom: 16px;
.title {
color: $--color-text-primary;
font-size: 16px;
font-weight: 500;
margin-bottom: 8px;
padding: 20px 20px 10px 20px;
}
}
.instructions {
padding: 0px 20px 20px 20px;
.describe {
color: $--color-text-secondary;
margin-bottom: 16px;
}
.itemTitle {
color: $--color-text-primary;
font-size: 16px;
font-weight: 500;
margin-bottom: 8px;
}
.head-index {
font-size: 24px;
color: #e8e9eb;
line-height: 32px;
}
.itemDescribe {
width: 170px;
color: $--color-text-secondary;
}
.img {
height: 72px;
width: 140px;
}
}
.tableBox {
background-color: white;
width: 100%;
padding: 20px;
overflow: auto;
.add {
margin-bottom: 20px;
}
}
</style>
<!-- 详情 -->
<template>
<div style="position: relative">
<el-form label-position="left" ref="form" label-width="100px" :size="defaultFormItemSize">
<el-row class="title">基本信息</el-row>
<el-form-item label="服务名称:" prop="modelManageDto.serviceName">
{{ tableItem.serviceName }}
</el-form-item>
<el-form-item label="服务描述:">
{{ tableItem.serviceDescription }}
</el-form-item>
<el-form-item label="选择模型:">
{{ tableItem.modelName }}
</el-form-item>
<el-form-item label="API地址:">{{ tableItem.apiUrl}} </el-form-item>
<el-row class="title">模型配置</el-row>
<el-form-item label="资源配置:">
<el-table :data="getResourceInfoList" style="width: 100%">
<el-table-column prop="gpu_id" label="gpuID" width="150">
</el-table-column>
<el-table-column prop="gpu_name" label="名称">
</el-table-column>
<el-table-column prop="total_memory" label="显存总大小(M)">
</el-table-column>
<el-table-column prop="used_memory" label="使用大小(M)">
</el-table-column>
<el-table-column prop="free_memory" label="剩余大小(M)">
</el-table-column>
<el-table-column prop="gpu_util" label="显卡利用率">
<template slot-scope="scope">
{{ scope.row.gpu_util }}%
</template>
</el-table-column>
</el-table>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
data() {
return {}
},
components: {},
props: ['tableItem'],
computed: {
...mapGetters(['getMainContextHeight']),
tableHeight() {
return this.getMainContextHeight - 95 + 'px'
},
getResourceInfoList() {
return JSON.parse(this.tableItem.resourceInfo)
}
},
methods: {},
mounted() {}
}
</script>
<style lang="scss" scoped>
@import '@/assets/style/element-variables.scss';
.topBox {
background-color: white;
width: 100%;
height: 95px;
margin-bottom: 16px;
.title {
color: $--color-text-primary;
font-size: 16px;
font-weight: 500;
margin-bottom: 8px;
padding: 20px 20px 10px 20px;
}
}
.instructions {
padding: 0px 20px 20px 20px;
.describe {
color: $--color-text-secondary;
margin-bottom: 16px;
}
.itemTitle {
color: $--color-text-primary;
font-size: 16px;
font-weight: 500;
margin-bottom: 8px;
}
.head-index {
font-size: 24px;
color: #e8e9eb;
line-height: 32px;
}
.itemDescribe {
width: 170px;
color: $--color-text-secondary;
}
.img {
height: 72px;
width: 140px;
}
}
.tableBox {
background-color: white;
width: 100%;
padding: 20px;
overflow: auto;
.add {
margin-bottom: 20px;
}
}
/deep/ .el-descriptions__table {
width: 100%;
}
</style>
<template>
<div class="aggregate">
<div class="logo">
<img src="@/assets/img/logo2.png" alt="">
<span class="title">陆军装备知识图谱系统</span>
</div>
<div class="aggregateBox">
<div class="itemBox" v-for="(item,index) in itemList" :key="index" @click="goPage(item.url)">
<span class="text">
{{ item.name }}
</span>
</div>
</div>
</div>
</template>
<script>
export default {
data () {
return {
itemList: [
{
name: '基于NEO4J的知识图谱构建',
url: `http://${window.location.hostname}:${window.location.port}/#/main/welcome`
},
{
name: '基于大语言模型与知识图谱双轮驱动的机械维修保障智能问答系统',
url: `http://${window.location.hostname}:${window.location.port}/#/main/welcome`
},
{
name: '基于gstore的知识图谱系统',
url: `http://${window.location.hostname}:${window.location.port}/#/main/welcome`
}
]
}
},
components: {},
mounted () {
},
methods: {
goPage (url) {
location.href = url
}
}
}
</script>
<style lang="scss" scoped>
.logo {
position: absolute;
top: 20px;
left: 20px;
display: flex;
img {
height: 40px;
}
.title {
color: #fff;
font-size: 18px;
height: 40px;
line-height: 40px;
display: inline-block;
margin-left: 20px;
}
}
.aggregate {
height: 100%;
width: 100%;
background: url(~@/assets/img/login_bg_2.jpg) center center;
background-size: cover;
display: flex;
justify-content: center;
align-items: center;
position: relative;
overflow: hidden;
}
.aggregateBox {
width: 80%;
height: 50%;
min-width: 1000px;
min-height: 400px;
border-radius: 20px;
background-color: rgba(255, 255, 255, 0.1); /* 背景色透明度,根据需要调整 */
backdrop-filter: blur(10px); /* 模糊程度,根据需要调整 */
display: flex;
padding: 20px; /* 内边距,根据需要调整 */
justify-content: space-around;
flex-direction: row;
align-items: center;
.itemBox {
width: 400px;
cursor: pointer;
height: 200px;
background: url(~@/assets/img/cardBg.png) center center;
background-size: cover;
border-radius: 10px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 20px;
border: 1px solid #b1b1b1;
font-size: 20px;
line-height: 30px;
// color: #5b6fab;
color: #273379;
font-weight: 900;
.text {
background-color: #fff;
padding: 10px;
border-radius: 5px;
}
}
}
.aggregateBox :hover {
box-shadow: 1px 1px 8px 1px #fff;
transition: all 0.5s;
}
</style>
<template>
<div style="background-color: white;padding: 16px;" class="allCard">
<Card v-for="(item,index) in cardList" @click="cardClick(item)" :key="index">
<Card v-for="(item,index) in cardList" @click="cardClick(item)" :key="index">
<template #title>
<div class="title">
{{ item.name }}
</div>
<div class="title">
{{ item.name }}
</div>
</template>
<template #content>
<div class="content">
......@@ -18,15 +18,14 @@
</div>
</template>
</Card>
</div>
</template>
<script>
import Card from './card';
import * as echarts from 'echarts';
import Card from './card'
import * as echarts from 'echarts'
export default {
data () {
data() {
return {
echarts: undefined,
cardList: [
......@@ -52,10 +51,15 @@ export default {
},
{
name: '调用统计'
}
],
option: {
tooltip: {
trigger: 'axis',
position: function (pt) {
return [pt[0], '10%']
}
},
color: ['#37A2FF', '#FFBF00'],
legend: {
type: 'scroll',
......@@ -65,15 +69,15 @@ export default {
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
smooth: true,
smooth: false,
lineStyle: {
width: 0
},
......@@ -99,20 +103,20 @@ export default {
}
}
},
components: {Card},
mounted () {
components: { Card },
mounted() {
this.$nextTick(() => {
this.echarts = echarts.init(document.getElementById('homeMain'));
this.echarts.setOption(this.option, true);
this.echarts = echarts.init(document.getElementById('homeMain'))
this.echarts.setOption(this.option, true)
})
},
methods: {
cardClick () {
console.log(1);
cardClick() {
console.log(1)
},
resize () {
resize() {
if (this.echarts != null) {
this.echarts.resize();
this.echarts.resize()
}
}
}
......@@ -120,50 +124,50 @@ export default {
</script>
<style lang="scss" scoped>
@import '@/assets/style/element-variables.scss';
.title {
border-left: 1px solid;
border-left-width: 5px;
border-left-color: $--color-primary;
margin-bottom: 20px;
font-size: 17px;
padding-left: 10px;
}
#homeMain{
height:400px;
width:100%;
@import '@/assets/style/element-variables.scss';
.title {
border-left: 1px solid;
border-left-width: 5px;
border-left-color: $--color-primary;
margin-bottom: 20px;
font-size: 17px;
padding-left: 10px;
}
#homeMain {
height: 400px;
width: 100%;
}
.title p {
height: 40px;
line-height: 40px;
font-size: 16px;
margin: 0px;
padding-left: 20px;
}
.title p {
height: 40px;
line-height: 40px;
font-size: 16px;
margin: 0px;
padding-left: 20px;
}
.title p span {
font-size: 20px;
color: $--color-primary;
}
.title p span {
font-size: 20px;
color: $--color-primary;
}
.item-list {
margin: 0px;
}
.item-list li {
margin: 10px 0px;
}
.item-list {
margin: 0px;
}
.item-list li {
margin: 10px 0px;
}
.item {
height: 48px;
display: flex;
align-items: center;
}
.item {
height: 48px;
display: flex;
align-items: center;
}
strong.warning {
color: red;
font-size: 16px;
}
.allCard {
strong.warning {
color: red;
font-size: 16px;
}
.allCard {
display: grid !important;
/* grid-column-gap: 50px;
grid-row-gap: 50px; */
......@@ -175,23 +179,20 @@ height:400px;
.allCard :nth-child(5) {
grid-column-start: 1;
grid-column-end: 5;
}
.content{
.content {
height: calc(100% - 45px);
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
flex-direction: column;
justify-content: space-around;
align-items: center;
}
.num{
.num {
font-size: 40px;
font-weight: bold;
text-align: center;
}
.describe{
.describe {
text-align: center;
}
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment