|
@@ -1,95 +1,118 @@
|
|
<template>
|
|
<template>
|
|
|
|
|
|
- <TextViewDialog ref="textViewDialog" :title="'查看文件'" :content="textViewData"></TextViewDialog>
|
|
|
|
|
|
+ <TextViewDialog ref="textViewDialog" :title="'查看文件'" :content="textViewData"></TextViewDialog>
|
|
|
|
|
|
<el-row>
|
|
<el-row>
|
|
<el-page-header @back="handleGoBack" :content="jobData?.job_name" title="返回">
|
|
<el-page-header @back="handleGoBack" :content="jobData?.job_name" title="返回">
|
|
</el-page-header>
|
|
</el-page-header>
|
|
<el-divider></el-divider>
|
|
<el-divider></el-divider>
|
|
- </el-row>
|
|
|
|
|
|
+ </el-row>
|
|
<el-row>
|
|
<el-row>
|
|
<el-col :span="20">
|
|
<el-col :span="20">
|
|
- <el-tabs type="border-card" v-model="activeTab">
|
|
|
|
- <el-tab-pane label="基本信息" name="basic_info">
|
|
|
|
- <el-row>
|
|
|
|
- <el-col :span="6">
|
|
|
|
- <div class="prop_header">任务ID</div>
|
|
|
|
- </el-col>
|
|
|
|
- <el-col :span="6"><div>{{ jobData?.id }}</div></el-col>
|
|
|
|
- <el-col :span="6"><div class="prop_header">任务类型</div></el-col>
|
|
|
|
- <el-col :span="6">
|
|
|
|
- <div>{{ getJobCategory(jobData?.start_category) }}</div>
|
|
|
|
- </el-col>
|
|
|
|
- </el-row>
|
|
|
|
- <el-row>
|
|
|
|
- <el-col :span="6">
|
|
|
|
- <div class="prop_header">当前工序</div>
|
|
|
|
- </el-col>
|
|
|
|
- <el-col :span="6"><div>{{ getJobCategory(jobData?.job_category) }}</div></el-col>
|
|
|
|
- <el-col :span="6"><div class="prop_header">任务名称</div></el-col>
|
|
|
|
- <el-col :span="6">
|
|
|
|
- <el-tooltip class="item" effect="dark" :content="jobData?.job_name" placement="top-end">
|
|
|
|
- <div>{{ formatFilename(jobData?.job_name,20) }}</div>
|
|
|
|
- </el-tooltip>
|
|
|
|
- </el-col>
|
|
|
|
- </el-row>
|
|
|
|
- <el-row>
|
|
|
|
- <el-col :span="6"><div class="prop_header">任务状态</div></el-col>
|
|
|
|
- <el-col :span="6">
|
|
|
|
- <div>{{ getJobStatus(jobData?.status) }}</div>
|
|
|
|
- </el-col>
|
|
|
|
- <el-col :span="6"><div class="prop_header">创建人</div></el-col>
|
|
|
|
- <el-col :span="6">
|
|
|
|
- <div>{{ jobData?.job_creator }}</div>
|
|
|
|
- </el-col>
|
|
|
|
- </el-row>
|
|
|
|
- <el-row>
|
|
|
|
- <el-col :span="6">
|
|
|
|
- <div class="prop_header">创建时间</div>
|
|
|
|
- </el-col>
|
|
|
|
- <el-col :span="6"><div>{{ jobData?.created }}</div></el-col>
|
|
|
|
- <el-col :span="6"><div class="prop_header">更新时间</div></el-col>
|
|
|
|
- <el-col :span="6"><div>{{ jobData?.updated }}</div>
|
|
|
|
- </el-col>
|
|
|
|
- </el-row>
|
|
|
|
- <el-row>
|
|
|
|
- <div class="prop_header" style="background-color: #EFEFEF; width: 100%;">日志</div><br/>
|
|
|
|
- </el-row>
|
|
|
|
- <el-row>
|
|
|
|
- <div style="white-space: pre-wrap; height:500px; width:100%; overflow-y: auto;">{{ jobData?.job_logs }}</div>
|
|
|
|
|
|
+ <el-tabs type="border-card" v-model="activeTab">
|
|
|
|
+ <el-tab-pane label="基本信息" name="basic_info">
|
|
|
|
+ <el-row>
|
|
|
|
+ <el-col :span="6">
|
|
|
|
+ <div class="prop_header">任务ID</div>
|
|
|
|
+ </el-col>
|
|
|
|
+ <el-col :span="6">
|
|
|
|
+ <div>{{ jobData?.id }}</div>
|
|
|
|
+ </el-col>
|
|
|
|
+ <el-col :span="6">
|
|
|
|
+ <div class="prop_header">任务类型</div>
|
|
|
|
+ </el-col>
|
|
|
|
+ <el-col :span="6">
|
|
|
|
+ <div>{{ getJobCategory(jobData?.start_category) }}</div>
|
|
|
|
+ </el-col>
|
|
|
|
+ </el-row>
|
|
|
|
+ <el-row>
|
|
|
|
+ <el-col :span="6">
|
|
|
|
+ <div class="prop_header">当前工序</div>
|
|
|
|
+ </el-col>
|
|
|
|
+ <el-col :span="6">
|
|
|
|
+ <div>{{ getJobCategory(jobData?.job_category) }}</div>
|
|
|
|
+ </el-col>
|
|
|
|
+ <el-col :span="6">
|
|
|
|
+ <div class="prop_header">任务名称</div>
|
|
|
|
+ </el-col>
|
|
|
|
+ <el-col :span="6">
|
|
|
|
+ <el-tooltip class="item" effect="dark" :content="jobData?.job_name" placement="top-end">
|
|
|
|
+ <div>{{ formatFilename(jobData?.job_name, 20) }}</div>
|
|
|
|
+ </el-tooltip>
|
|
|
|
+ </el-col>
|
|
|
|
+ </el-row>
|
|
|
|
+ <el-row>
|
|
|
|
+ <el-col :span="6">
|
|
|
|
+ <div class="prop_header">任务状态</div>
|
|
|
|
+ </el-col>
|
|
|
|
+ <el-col :span="6">
|
|
|
|
+ <div>{{ getJobStatus(jobData?.status) }}</div>
|
|
|
|
+ </el-col>
|
|
|
|
+ <el-col :span="6">
|
|
|
|
+ <div class="prop_header">创建人</div>
|
|
|
|
+ </el-col>
|
|
|
|
+ <el-col :span="6">
|
|
|
|
+ <div>{{ jobData?.job_creator }}</div>
|
|
|
|
+ </el-col>
|
|
|
|
+ </el-row>
|
|
|
|
+ <el-row>
|
|
|
|
+ <el-col :span="6">
|
|
|
|
+ <div class="prop_header">创建时间</div>
|
|
|
|
+ </el-col>
|
|
|
|
+ <el-col :span="6">
|
|
|
|
+ <div>{{ jobData?.created }}</div>
|
|
|
|
+ </el-col>
|
|
|
|
+ <el-col :span="6">
|
|
|
|
+ <div class="prop_header">更新时间</div>
|
|
|
|
+ </el-col>
|
|
|
|
+ <el-col :span="6">
|
|
|
|
+ <div>{{ jobData?.updated }}</div>
|
|
|
|
+ </el-col>
|
|
|
|
+ </el-row>
|
|
|
|
+ <el-row>
|
|
|
|
+ <div class="prop_header" style="background-color: #EFEFEF; width: 100%;">日志</div><br />
|
|
|
|
+ </el-row>
|
|
|
|
+ <el-row>
|
|
|
|
+ <div style="white-space: pre-wrap; height:500px; width:100%; overflow-y: auto;">{{
|
|
|
|
+ jobData?.job_logs }}</div>
|
|
|
|
|
|
- </el-row>
|
|
|
|
|
|
+ </el-row>
|
|
|
|
|
|
|
|
|
|
- </el-tab-pane>
|
|
|
|
- <el-tab-pane label="文件夹" name="file_browse">
|
|
|
|
- <el-row >
|
|
|
|
|
|
+ </el-tab-pane>
|
|
|
|
+ <el-tab-pane label="文件夹" name="file_browse">
|
|
|
|
+ <el-row>
|
|
<el-col :span="4" style="border-right: 1px solid #CDCDCD;">
|
|
<el-col :span="4" style="border-right: 1px solid #CDCDCD;">
|
|
- <el-tree :data="jobFileData" :props="jobFileTree" @node-click="handleTreeNodeClick"></el-tree>
|
|
|
|
|
|
+ <el-tree :data="jobFileData" :props="jobFileTree"
|
|
|
|
+ @node-click="handleTreeNodeClick"></el-tree>
|
|
</el-col>
|
|
</el-col>
|
|
- <el-col :span="20" style="display:flex;flex-direction: row; flex-wrap: wrap; height:500px; overflow: auto;">
|
|
|
|
|
|
+ <el-col :span="20"
|
|
|
|
+ style="display:flex;flex-direction: row; flex-wrap: wrap; height:500px; overflow: auto;">
|
|
<template v-for="item in jobFileInDir">
|
|
<template v-for="item in jobFileInDir">
|
|
<el-card shadow="hover" style="width: 200px; height: 120px; margin: 10px;">
|
|
<el-card shadow="hover" style="width: 200px; height: 120px; margin: 10px;">
|
|
<div class="card-header">
|
|
<div class="card-header">
|
|
- <span style="font-size:10px;">
|
|
|
|
- <span v-if="item.type=='file'">文件</span>
|
|
|
|
- <span v-if="item.type=='dir'">文件夹</span>
|
|
|
|
- </span>
|
|
|
|
|
|
+ <span style="font-size:10px;">
|
|
|
|
+ <span v-if="item.type == 'file'">文件</span>
|
|
|
|
+ <span v-if="item.type == 'dir'">文件夹</span>
|
|
|
|
+ </span>
|
|
</div>
|
|
</div>
|
|
<div class="card-content">
|
|
<div class="card-content">
|
|
- <el-tooltip class="item" effect="dark" :content="item.name" placement="top-end">
|
|
|
|
- <span style="font-size:12px;display: flex; flex-wrap: nowrap; height:25px;">{{ formatFilename(item.name, 20) }}</span>
|
|
|
|
- </el-tooltip>
|
|
|
|
|
|
+ <el-tooltip class="item" effect="dark" :content="item.name" placement="top-end">
|
|
|
|
+ <span
|
|
|
|
+ style="font-size:12px;display: flex; flex-wrap: nowrap; height:25px;">{{
|
|
|
|
+ formatFilename(item.name, 20) }}</span>
|
|
|
|
+ </el-tooltip>
|
|
</div>
|
|
</div>
|
|
-
|
|
|
|
|
|
+
|
|
<div class="bottom clearfix">
|
|
<div class="bottom clearfix">
|
|
-
|
|
|
|
- <a :href="'/api/file/download/'+jobData?.id+'?path='+encodeURIComponent(item.path)">下载</a>
|
|
|
|
- <a @click="handleViewFile(jobData, item.path)">查看</a>
|
|
|
|
|
|
+
|
|
|
|
+ <a
|
|
|
|
+ :href="'/api/file/download/' + jobData?.id + '?path=' + encodeURIComponent(item.path)">下载</a>
|
|
|
|
+ <a @click="handleViewFile(jobData, item.path)">查看</a>
|
|
</div>
|
|
</div>
|
|
</el-card>
|
|
</el-card>
|
|
|
|
|
|
- </template>
|
|
|
|
|
|
+ </template>
|
|
<!-- <el-table v-if="jobFileInDir.length > 0" :data="jobFileInDir" highlight-current-row style="width: 100%;">
|
|
<!-- <el-table v-if="jobFileInDir.length > 0" :data="jobFileInDir" highlight-current-row style="width: 100%;">
|
|
<el-table-column prop="type" label="类型" width="50">
|
|
<el-table-column prop="type" label="类型" width="50">
|
|
|
|
|
|
@@ -105,36 +128,37 @@
|
|
</el-table-column>
|
|
</el-table-column>
|
|
</el-table> -->
|
|
</el-table> -->
|
|
</el-col>
|
|
</el-col>
|
|
- </el-row>
|
|
|
|
- </el-tab-pane>
|
|
|
|
- </el-tabs>
|
|
|
|
|
|
+ </el-row>
|
|
|
|
+ </el-tab-pane>
|
|
|
|
+ </el-tabs>
|
|
</el-col>
|
|
</el-col>
|
|
<el-col :span="4">
|
|
<el-col :span="4">
|
|
- <el-menu @select="handleMenuSelect" :default-active="activeTab" mode="vertical" class="el-menu-vertical-demo" menu-trigger="click" >
|
|
|
|
- <el-menu-item-group index="CHANGE_CATEGORY">
|
|
|
|
- <template #title>工序变更</template>
|
|
|
|
- <el-menu-item :index="jobData.start_category">开始文字提取</el-menu-item>
|
|
|
|
- <el-menu-item index="SYSTEM_CHUNKS">开始文本切片</el-menu-item>
|
|
|
|
- <el-menu-item index="SYSTEM_KB_EXTRACT">开始抽取知识</el-menu-item>
|
|
|
|
- <el-menu-item index="SYSTEM_KB_BUILD">开始构建图谱</el-menu-item>
|
|
|
|
- </el-menu-item-group>
|
|
|
|
- </el-menu>
|
|
|
|
|
|
+ <el-menu @select="handleMenuSelect" :default-active="activeTab" mode="vertical"
|
|
|
|
+ class="el-menu-vertical-demo" menu-trigger="click">
|
|
|
|
+ <el-menu-item-group index="CHANGE_CATEGORY">
|
|
|
|
+ <template #title>工序变更</template>
|
|
|
|
+ <el-menu-item :index="jobData.start_category">开始文字提取</el-menu-item>
|
|
|
|
+ <el-menu-item index="SYSTEM_CHUNKS">开始文本切片</el-menu-item>
|
|
|
|
+ <el-menu-item index="SYSTEM_KB_EXTRACT">开始抽取知识</el-menu-item>
|
|
|
|
+ <el-menu-item index="SYSTEM_KB_BUILD">开始构建图谱</el-menu-item>
|
|
|
|
+ </el-menu-item-group>
|
|
|
|
+ </el-menu>
|
|
</el-col>
|
|
</el-col>
|
|
- </el-row>
|
|
|
|
|
|
+ </el-row>
|
|
</template>
|
|
</template>
|
|
<script lang="ts" setup>
|
|
<script lang="ts" setup>
|
|
-import { onMounted, ref } from 'vue'
|
|
|
|
|
|
+import { onMounted, ref } from 'vue'
|
|
import { useRoute, useRouter } from 'vue-router'
|
|
import { useRoute, useRouter } from 'vue-router'
|
|
-import { getJob,browseJobFile,getJobStatus,getFileContent,putQueueJob,getJobCategory } from '@/api/AgentApi'
|
|
|
|
|
|
+import { getJob, browseJobFile, getJobStatus, getFileContent, putQueueJob, getJobCategory } from '@/api/AgentApi'
|
|
import { formatDate } from '@/utils/misc'
|
|
import { formatDate } from '@/utils/misc'
|
|
import TextViewDialog from '@/dialogs/TextViewDialog.vue'
|
|
import TextViewDialog from '@/dialogs/TextViewDialog.vue'
|
|
-import type { JobData } from '@/api/AgentApi'
|
|
|
|
|
|
+import type { JobData } from '@/api/AgentApi'
|
|
import { ElMessageBox, ElNotification } from 'element-plus'
|
|
import { ElMessageBox, ElNotification } from 'element-plus'
|
|
|
|
|
|
interface JobFile {
|
|
interface JobFile {
|
|
- type:string
|
|
|
|
- name:string
|
|
|
|
- path:string
|
|
|
|
|
|
+ type: string
|
|
|
|
+ name: string
|
|
|
|
+ path: string
|
|
}
|
|
}
|
|
const router = useRouter()
|
|
const router = useRouter()
|
|
|
|
|
|
@@ -145,57 +169,57 @@ var textViewContent = "hello"
|
|
const textViewData = ref(textViewContent)
|
|
const textViewData = ref(textViewContent)
|
|
const textViewDialog = ref()
|
|
const textViewDialog = ref()
|
|
const jobFileTree = ref({
|
|
const jobFileTree = ref({
|
|
- children: 'children',
|
|
|
|
- label: 'display_name'
|
|
|
|
- })
|
|
|
|
|
|
+ children: 'children',
|
|
|
|
+ label: 'display_name'
|
|
|
|
+})
|
|
const jobFileData = ref([])
|
|
const jobFileData = ref([])
|
|
const jobFileInDir = ref<JobFile[]>([])
|
|
const jobFileInDir = ref<JobFile[]>([])
|
|
|
|
|
|
const activeTab = ref('basic_info')
|
|
const activeTab = ref('basic_info')
|
|
-function formatFolderName(name: string){
|
|
|
|
|
|
+function formatFolderName(name: string) {
|
|
let translate = new Map([
|
|
let translate = new Map([
|
|
- ["logs", "日志"],
|
|
|
|
- ["results", "结果"],
|
|
|
|
- ["chunks", "切片"],
|
|
|
|
- ["files", "文件"],
|
|
|
|
- ["ocr_output", "文本转换结果"],
|
|
|
|
- ["kb_extract", "知识抽取"],
|
|
|
|
|
|
+ ["logs", "日志"],
|
|
|
|
+ ["results", "结果"],
|
|
|
|
+ ["chunks", "切片"],
|
|
|
|
+ ["files", "文件"],
|
|
|
|
+ ["ocr_output", "文本转换结果"],
|
|
|
|
+ ["kb_extract", "知识抽取"],
|
|
["kb_build", "知识构建"],
|
|
["kb_build", "知识构建"],
|
|
["upload", "文件上传"],
|
|
["upload", "文件上传"],
|
|
["output", "输出"]]
|
|
["output", "输出"]]
|
|
- )
|
|
|
|
|
|
+ )
|
|
if (translate.get(name) != undefined) {
|
|
if (translate.get(name) != undefined) {
|
|
return translate.get(name)
|
|
return translate.get(name)
|
|
}
|
|
}
|
|
return name
|
|
return name
|
|
}
|
|
}
|
|
function handleTreeNodeClick(data: any, node: any, event: any) {
|
|
function handleTreeNodeClick(data: any, node: any, event: any) {
|
|
- if (data.type=='dir'){
|
|
|
|
- browseJobFile({ job_id:jobData.value.id, path:data.name}).then((res) => {
|
|
|
|
|
|
+ if (data.type == 'dir') {
|
|
|
|
+ browseJobFile({ job_id: jobData.value.id, path: data.name }).then((res) => {
|
|
jobFileInDir.value = res.records
|
|
jobFileInDir.value = res.records
|
|
})
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-function handleViewFile(job:JobData, path:string) {
|
|
|
|
- const url = '/api/file/view/'+job?.id+'?path='+encodeURIComponent(path)
|
|
|
|
|
|
+function handleViewFile(job: JobData, path: string) {
|
|
|
|
+ const url = '/api/file/view/' + job?.id + '?path=' + encodeURIComponent(path)
|
|
console.log(url)
|
|
console.log(url)
|
|
getFileContent(url).then((res) => {
|
|
getFileContent(url).then((res) => {
|
|
console.log(res)
|
|
console.log(res)
|
|
textViewData.value = res.records[0].content
|
|
textViewData.value = res.records[0].content
|
|
- textViewDialog.value.showDialog(true)
|
|
|
|
|
|
+ textViewDialog.value.showDialog(true)
|
|
})
|
|
})
|
|
}
|
|
}
|
|
function handleGoBack() {
|
|
function handleGoBack() {
|
|
- router.push("/workspace/queue/0")
|
|
|
|
|
|
+ router.push({ name: 'queue', params: { id: 0 } })
|
|
}
|
|
}
|
|
function loadJobData() {
|
|
function loadJobData() {
|
|
console.log(jobId.value)
|
|
console.log(jobId.value)
|
|
getJob(jobId.value).then((res) => {
|
|
getJob(jobId.value).then((res) => {
|
|
jobData.value = res.records[0] as JobData
|
|
jobData.value = res.records[0] as JobData
|
|
-
|
|
|
|
- browseJobFile({ job_id:jobId.value, path:""}).then((res) => {
|
|
|
|
|
|
+
|
|
|
|
+ browseJobFile({ job_id: jobId.value, path: "" }).then((res) => {
|
|
for (let i = 0; i < res.records.length; i++) {
|
|
for (let i = 0; i < res.records.length; i++) {
|
|
- res.records[i]['label'] = res.records[i].name
|
|
|
|
|
|
+ res.records[i]['label'] = res.records[i].name
|
|
res.records[i]['children'] = []
|
|
res.records[i]['children'] = []
|
|
res.records[i]['display_name'] = formatFolderName(res.records[i].name)
|
|
res.records[i]['display_name'] = formatFolderName(res.records[i].name)
|
|
}
|
|
}
|
|
@@ -204,66 +228,67 @@ function loadJobData() {
|
|
})
|
|
})
|
|
})
|
|
})
|
|
}
|
|
}
|
|
-function formatFilename(name:string, length:number) {
|
|
|
|
- if (name == undefined){
|
|
|
|
|
|
+function formatFilename(name: string, length: number) {
|
|
|
|
+ if (name == undefined) {
|
|
return ""
|
|
return ""
|
|
}
|
|
}
|
|
if (name.length > length) {
|
|
if (name.length > length) {
|
|
- return name.substring(0, length/2) + "..." + name.substring(name.length - length/2)
|
|
|
|
- }
|
|
|
|
|
|
+ return name.substring(0, length / 2) + "..." + name.substring(name.length - length / 2)
|
|
|
|
+ }
|
|
return name
|
|
return name
|
|
}
|
|
}
|
|
-function handleMenuSelect(key:string, keyPath:string){
|
|
|
|
|
|
+function handleMenuSelect(key: string, keyPath: string) {
|
|
var category = getJobCategory(keyPath)
|
|
var category = getJobCategory(keyPath)
|
|
ElMessageBox.confirm(
|
|
ElMessageBox.confirm(
|
|
`确定要转移任务到队列 "${category}" 吗?`,
|
|
`确定要转移任务到队列 "${category}" 吗?`,
|
|
- '提示' ,
|
|
|
|
|
|
+ '提示',
|
|
).then(() => {
|
|
).then(() => {
|
|
let category = key.split("_")[0]
|
|
let category = key.split("_")[0]
|
|
- let name = key.split("_")[2] ? key.split("_")[1] +'_' + key.split("_")[2] : key.split("_")[1]
|
|
|
|
|
|
+ let name = key.split("_")[2] ? key.split("_")[1] + '_' + key.split("_")[2] : key.split("_")[1]
|
|
handleJobChangeCategory(category, name)
|
|
handleJobChangeCategory(category, name)
|
|
})
|
|
})
|
|
}
|
|
}
|
|
-function handleJobChangeCategory(category:string, name:string) {
|
|
|
|
|
|
+function handleJobChangeCategory(category: string, name: string) {
|
|
|
|
|
|
var params = { job_id: jobId.value, queue_category: category, queue_name: name }
|
|
var params = { job_id: jobId.value, queue_category: category, queue_name: name }
|
|
-
|
|
|
|
- putQueueJob(params).then((res:any) => {
|
|
|
|
|
|
+
|
|
|
|
+ putQueueJob(params).then((res: any) => {
|
|
ElNotification({
|
|
ElNotification({
|
|
title: '提示',
|
|
title: '提示',
|
|
message: '任务已转移到队列',
|
|
message: '任务已转移到队列',
|
|
- type: 'success',
|
|
|
|
|
|
+ type: 'success',
|
|
duration: 3000
|
|
duration: 3000
|
|
- })
|
|
|
|
- loadJobData()
|
|
|
|
})
|
|
})
|
|
|
|
+ loadJobData()
|
|
|
|
+ })
|
|
|
|
|
|
}
|
|
}
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
var route = useRoute()
|
|
var route = useRoute()
|
|
console.log(route.params)
|
|
console.log(route.params)
|
|
- var id = Number.parseInt(route.params.id as string)
|
|
|
|
|
|
+ var id = Number.parseInt(route.params.id as string)
|
|
jobId.value = id
|
|
jobId.value = id
|
|
loadJobData()
|
|
loadJobData()
|
|
})
|
|
})
|
|
</script>
|
|
</script>
|
|
<style lang="css" scoped>
|
|
<style lang="css" scoped>
|
|
- .prop_header {
|
|
|
|
- font-weight: bold;
|
|
|
|
- margin-bottom: 5px;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- .bottom {
|
|
|
|
|
|
+.prop_header {
|
|
|
|
+ font-weight: bold;
|
|
|
|
+ margin-bottom: 5px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.bottom {
|
|
margin-top: 15px;
|
|
margin-top: 15px;
|
|
line-height: 12px;
|
|
line-height: 12px;
|
|
- }
|
|
|
|
- .clearfix:before,
|
|
|
|
- .clearfix:after {
|
|
|
|
- display: table;
|
|
|
|
- content: "";
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- .clearfix:after {
|
|
|
|
- clear: both
|
|
|
|
- }
|
|
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.clearfix:before,
|
|
|
|
+.clearfix:after {
|
|
|
|
+ display: table;
|
|
|
|
+ content: "";
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.clearfix:after {
|
|
|
|
+ clear: both
|
|
|
|
+}
|
|
</style>
|
|
</style>
|