| New file |
| | |
| | | import request from '@/router/axios'; |
| | | |
| | | export const getList = (current, size, params) => { |
| | | return request({ |
| | | url: '/api/function/function/list', |
| | | method: 'get', |
| | | params: { |
| | | ...params, |
| | | current, |
| | | size, |
| | | } |
| | | }) |
| | | } |
| | | |
| | | export const getAll = (params) => { |
| | | return request({ |
| | | url: '/api/function/function/all', |
| | | method: 'get', |
| | | params: { |
| | | ...params, |
| | | } |
| | | }) |
| | | } |
| | | |
| | | export const getDetail = (id) => { |
| | | return request({ |
| | | url: '/api/function/function/detail', |
| | | method: 'get', |
| | | params: { |
| | | id |
| | | } |
| | | }) |
| | | } |
| | | |
| | | export const remove = (ids) => { |
| | | return request({ |
| | | url: '/api/function/function/remove', |
| | | method: 'post', |
| | | params: { |
| | | ids, |
| | | } |
| | | }) |
| | | } |
| | | |
| | | export const add = (row) => { |
| | | return request({ |
| | | url: '/api/function/function/submit', |
| | | method: 'post', |
| | | data: row |
| | | }) |
| | | } |
| | | |
| | | export const update = (row) => { |
| | | return request({ |
| | | url: '/api/function/function/submit', |
| | | method: 'post', |
| | | data: row |
| | | }) |
| | | } |
| | | |
| New file |
| | |
| | | import request from '@/router/axios'; |
| | | |
| | | export const getList = (current, size, params) => { |
| | | return request({ |
| | | url: '/api/modules/modules/list', |
| | | method: 'get', |
| | | params: { |
| | | ...params, |
| | | current, |
| | | size, |
| | | } |
| | | }) |
| | | } |
| | | |
| | | export const getDetail = (id) => { |
| | | return request({ |
| | | url: '/api/modules/modules/detail', |
| | | method: 'get', |
| | | params: { |
| | | id |
| | | } |
| | | }) |
| | | } |
| | | |
| | | export const remove = (ids) => { |
| | | return request({ |
| | | url: '/api/modules/modules/remove', |
| | | method: 'post', |
| | | params: { |
| | | ids, |
| | | } |
| | | }) |
| | | } |
| | | |
| | | export const add = (row) => { |
| | | return request({ |
| | | url: '/api/modules/modules/submit', |
| | | method: 'post', |
| | | data: row |
| | | }) |
| | | } |
| | | |
| | | export const update = (row) => { |
| | | return request({ |
| | | url: '/api/modules/modules/submit', |
| | | method: 'post', |
| | | data: row |
| | | }) |
| | | } |
| | | |
| New file |
| | |
| | | <template> |
| | | <div> |
| | | <div class="avue-crud__menu"> |
| | | <!-- 头部左侧按钮模块 --> |
| | | <div class="avue-crud__left"> |
| | | <el-button size="small" class="button" icon="el-icon-back" @click="backModules">返回</el-button> |
| | | <el-button size="small" type="primary" icon="el-icon-plus" @click="handleAdd">新增</el-button> |
| | | </div> |
| | | </div> |
| | | {{ modulesId }} |
| | | <el-row> |
| | | <!--左侧列表--> |
| | | <el-col :span="6"> |
| | | <div class="func"> |
| | | <!--列表展示--> |
| | | <div class="list"> |
| | | <el-tree v-if="funList.length >0" |
| | | :data="funList" |
| | | :props="defaultProps" |
| | | node-key="id" |
| | | @node-click="handleNodeClick" |
| | | > |
| | | <span class="custom-tree-node" slot-scope="{ node, data }"> |
| | | <span>{{ data.name }}</span> |
| | | <span> |
| | | <el-button type="text" size="mini" @click="() => handleEdit(data)">编辑</el-button> |
| | | <el-button type="text" size="mini" @click="() => handleDelete(data)">删除</el-button> |
| | | </span> |
| | | </span> |
| | | </el-tree> |
| | | <el-empty v-else> |
| | | <el-button type="primary" @click="handleAdd">添加</el-button> |
| | | </el-empty> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <!--占位--> |
| | | <el-col :span="1"></el-col> |
| | | <!--右侧预览--> |
| | | <el-col :span="17"> |
| | | <div class="func-content"> |
| | | <div class="header"> |
| | | |
| | | </div> |
| | | <!--flash--> |
| | | <div> |
| | | |
| | | </div> |
| | | |
| | | <!--图册--> |
| | | <div v-if="content.type == 2"> |
| | | <avue-form :option="imgOption" v-model="imgForm" @submit="handleSubmitImg"></avue-form> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <!-- 表单模块 --> |
| | | <el-dialog :title="title" :visible.sync="box" width="50%" :before-close="beforeClose" append-to-body> |
| | | <avue-form |
| | | ref="form" |
| | | v-model="form" |
| | | :option="option" |
| | | @submit="handleSubmit"> |
| | | </avue-form> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import {getAll, add, update, remove} from "@/api/modules/function"; |
| | | |
| | | export default { |
| | | name: "function", |
| | | props: ['modulesId'], |
| | | data() { |
| | | return { |
| | | funList: [], |
| | | // 弹框标题 |
| | | title: '', |
| | | // 是否展示弹框 |
| | | box: false, |
| | | //功能表单配置 |
| | | option: { |
| | | height: 'auto', |
| | | calcHeight: 30, |
| | | tip: false, |
| | | searchShow: true, |
| | | searchMenuSpan: 6, |
| | | border: true, |
| | | index: true, |
| | | viewBtn: true, |
| | | selection: true, |
| | | dialogClickModal: false, |
| | | column: [ |
| | | { |
| | | label: "主键", |
| | | prop: "id", |
| | | type: "input", |
| | | display: false |
| | | }, |
| | | { |
| | | label: "模块主键", |
| | | prop: "modulesId", |
| | | type: "input", |
| | | display: false |
| | | }, |
| | | { |
| | | label: "功能名称", |
| | | prop: "name", |
| | | type: "input", |
| | | span: 24, |
| | | rules: [{ |
| | | required: true, |
| | | message: "请输入功能名称", |
| | | trigger: "blur", |
| | | }], |
| | | }, |
| | | { |
| | | label: "功能类型", |
| | | prop: "property", |
| | | type: 'radio', |
| | | dicUrl: "/api/blade-system/dict-biz/dictionary?code=function_property", |
| | | props: { |
| | | label: "dictValue", |
| | | value: "dictKey" |
| | | }, |
| | | span: 24, |
| | | rules: [{ |
| | | required: true, |
| | | message: "请选择功能类型", |
| | | trigger: "blur", |
| | | }], |
| | | }, |
| | | { |
| | | label: "内容类型", |
| | | prop: "type", |
| | | type: 'radio', |
| | | dicUrl: "/api/blade-system/dict-biz/dictionary?code=function_type", |
| | | props: { |
| | | label: "dictValue", |
| | | value: "dictKey" |
| | | }, |
| | | span: 24, |
| | | display: false, |
| | | rules: [{ |
| | | required: true, |
| | | message: "请选择内容类型", |
| | | trigger: "blur", |
| | | }], |
| | | }, |
| | | { |
| | | label: "排序", |
| | | prop: "sort", |
| | | min:1, |
| | | max:999999, |
| | | type:'number', |
| | | span: 24, |
| | | display: false, |
| | | rules: [{ |
| | | required: true, |
| | | message: "请输入排序", |
| | | trigger: "blur", |
| | | }], |
| | | }, |
| | | { |
| | | label: "页面背景", |
| | | prop: "fileUrl", |
| | | type: 'upload', |
| | | limit: 1, |
| | | drag: true, |
| | | loadText: '模板上传中,请稍等', |
| | | accept: 'image/png, image/jpeg', |
| | | propsHttp: { |
| | | res: 'data', |
| | | url: 'link' |
| | | }, |
| | | action: "/api/blade-resource/oss/endpoint/put-file-attach", |
| | | span: 24, |
| | | display: false, |
| | | }, |
| | | { |
| | | label: "租户ID", |
| | | prop: "tenantId", |
| | | type: "input", |
| | | display: false |
| | | }, |
| | | { |
| | | label: "创建人", |
| | | prop: "createUser", |
| | | type: "input", |
| | | display: false |
| | | }, |
| | | { |
| | | label: "创建部门", |
| | | prop: "createDept", |
| | | type: "input", |
| | | display: false |
| | | }, |
| | | { |
| | | label: "创建时间", |
| | | prop: "createTime", |
| | | type: "input", |
| | | display: false |
| | | }, |
| | | { |
| | | label: "修改人", |
| | | prop: "updateUser", |
| | | type: "input", |
| | | display: false |
| | | }, |
| | | { |
| | | label: "修改时间", |
| | | prop: "updateTime", |
| | | type: "input", |
| | | display: false |
| | | }, |
| | | { |
| | | label: "状态", |
| | | prop: "status", |
| | | type: "input", |
| | | display: false |
| | | }, |
| | | { |
| | | label: "是否已删除", |
| | | prop: "isDeleted", |
| | | type: "input", |
| | | display: false |
| | | }, |
| | | ] |
| | | }, |
| | | form: {}, |
| | | |
| | | imgOption: { |
| | | column: [ |
| | | { |
| | | label: '图片', |
| | | prop: 'imgUrl', |
| | | type: 'upload', |
| | | span: 24, |
| | | dragFile: true, |
| | | accept: 'image/png, image/jpeg', |
| | | listType: "picture-card", |
| | | propsHttp: { |
| | | res: 'data', |
| | | url: 'link' |
| | | }, |
| | | action: "/api/blade-resource/oss/endpoint/put-file-attach" |
| | | }, |
| | | ] |
| | | }, |
| | | imgForm: {}, |
| | | |
| | | defaultProps: { |
| | | children: 'children', |
| | | label: 'name' |
| | | }, |
| | | content: {}, |
| | | } |
| | | }, |
| | | watch: { |
| | | "form.property": { |
| | | handler(newVal) { |
| | | if (newVal) { |
| | | const columnType = this.findObject(this.option.column, "type") |
| | | const columnSort = this.findObject(this.option.column, "sort") |
| | | const columnFile = this.findObject(this.option.column, "fileUrl") |
| | | if (newVal == 2) { |
| | | columnType.display = true |
| | | columnSort.display = true |
| | | columnFile.display = false |
| | | } else { |
| | | columnFile.display = true |
| | | columnType.display = false |
| | | columnSort.display = false |
| | | } |
| | | } |
| | | } |
| | | }, |
| | | }, |
| | | mounted() { |
| | | this.getAllFunc() |
| | | }, |
| | | methods: { |
| | | //返回模块列表页 |
| | | backModules() { |
| | | this.$emit('backModules') |
| | | }, |
| | | //获取当前模块id下的所有子功能 |
| | | getAllFunc() { |
| | | let params = { |
| | | modulesId: this.modulesId |
| | | } |
| | | getAll(params).then(res => { |
| | | if (res.data.code == 200) { |
| | | this.funList = res.data.data |
| | | } |
| | | }) |
| | | }, |
| | | handleSubmit(form, done) { |
| | | form.modulesId = this.modulesId |
| | | if (!form.id) { |
| | | add(form).then(() => { |
| | | this.box = false; |
| | | this.getAllFunc() |
| | | this.$message({ |
| | | type: "success", |
| | | message: "操作成功!" |
| | | }); |
| | | done() |
| | | }); |
| | | } else { |
| | | update(form).then(() => { |
| | | this.box = false; |
| | | this.getAllFunc() |
| | | this.$message({ |
| | | type: "success", |
| | | message: "操作成功!" |
| | | }); |
| | | done() |
| | | }) |
| | | } |
| | | }, |
| | | handleAdd() { |
| | | this.title = '新增' |
| | | this.box = true |
| | | this.initColumn() |
| | | }, |
| | | //初始化column |
| | | initColumn() { |
| | | const columnType = this.findObject(this.option.column, "type") |
| | | const columnSort = this.findObject(this.option.column, "sort") |
| | | const columnFile = this.findObject(this.option.column, "fileUrl") |
| | | |
| | | columnType.display = false |
| | | columnSort.display = false |
| | | columnFile.display = false |
| | | |
| | | this.$nextTick(() => { |
| | | this.$refs.form.resetForm() |
| | | this.form.id = "" |
| | | }) |
| | | }, |
| | | handleEdit(row) { |
| | | this.title = '编辑' |
| | | this.box = true |
| | | this.form = row |
| | | }, |
| | | handleView(row) { |
| | | }, |
| | | handleDelete(data) { |
| | | this.$confirm("确定将选择数据删除?", { |
| | | confirmButtonText: "确定", |
| | | cancelButtonText: "取消", |
| | | type: "warning" |
| | | }).then(() => { |
| | | return remove(data.id); |
| | | }).then(() => { |
| | | this.getAllFunc() |
| | | this.$message({ |
| | | type: "success", |
| | | message: "操作成功!" |
| | | }); |
| | | }); |
| | | }, |
| | | beforeClose(done) { |
| | | done() |
| | | this.$refs.form.resetForm() |
| | | this.form = {} |
| | | this.view = false; |
| | | }, |
| | | // 节点点击事件 |
| | | handleNodeClick(data) { |
| | | this.content = data |
| | | if (data.type == 2) { |
| | | this.imgForm.imgUrl = data.fileUrl |
| | | } |
| | | }, |
| | | // 图片提交 |
| | | handleSubmitImg(form, done) { |
| | | this.content.fileUrl = form.imgUrl |
| | | this.handleSubmit(this.content, done) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .func { |
| | | height: 77vh; |
| | | border: 1px solid; |
| | | } |
| | | |
| | | .func-content { |
| | | height: 77vh; |
| | | border: 1px solid; |
| | | } |
| | | |
| | | .custom-tree-node { |
| | | flex: 1; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | font-size: 14px; |
| | | padding-right: 8px; |
| | | } |
| | | </style> |
| New file |
| | |
| | | <template> |
| | | <basic-container> |
| | | <div v-if="!isFunction" class="avue-crud"> |
| | | <!--按钮--> |
| | | <el-row> |
| | | <div class="avue-crud__menu"> |
| | | <!-- 头部左侧按钮模块 --> |
| | | <div class="avue-crud__left"> |
| | | <el-button size="small" type="primary" icon="el-icon-plus" @click="handleAdd">新增</el-button> |
| | | </div> |
| | | <!-- 头部右侧按钮模块 --> |
| | | <div class="avue-crud__right"> |
| | | <el-button :size="option.size" icon="el-icon-refresh" @click="searchChange" circle></el-button> |
| | | <el-button :size="option.size" icon="el-icon-search" @click="searchHide" circle></el-button> |
| | | </div> |
| | | </div> |
| | | </el-row> |
| | | |
| | | <!-- 列表模块 --> |
| | | <el-row> |
| | | |
| | | <!--卡片显示--> |
| | | <el-col :span="4" v-for="(o, index) in data" :key="o" :offset="index > 0 ? 1 : 0"> |
| | | <el-card :body-style="{ padding: '0px' }"> |
| | | <img @click="setContent(o.id)" :src="o.background.length>0?o.background[0].value: '/img/bg/img-logo.png' " |
| | | class="image"> |
| | | <div style="padding: 14px;"> |
| | | <span>{{ o.name }}</span> |
| | | <div class="bottom clearfix"> |
| | | <el-button type="text" class="button">预览</el-button> |
| | | <el-button type="text" class="button" @click="handleDelete(o.id)">删除</el-button> |
| | | <el-button type="text" class="button" @click="handleEdit(o)">编辑</el-button> |
| | | </div> |
| | | </div> |
| | | </el-card> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <!-- 分页模块 --> |
| | | <el-row> |
| | | <el-pagination |
| | | align="right" background |
| | | @size-change="sizeChange" |
| | | @current-change="currentChange" |
| | | :current-page="page.currentPage" |
| | | :page-sizes="[10, 20, 30, 40, 50, 100]" |
| | | :page-size="page.pageSize" |
| | | layout="total, sizes, prev, pager, next, jumper" |
| | | :total="page.total"> |
| | | </el-pagination> |
| | | </el-row> |
| | | |
| | | <!-- 表单模块 --> |
| | | <el-dialog :title="title" :visible.sync="box" width="50%" :before-close="beforeClose" append-to-body> |
| | | <avue-form ref="form" v-model="form" :option="option" @submit="handleSubmit"></avue-form> |
| | | </el-dialog> |
| | | |
| | | </div> |
| | | <!-- 功能详情--> |
| | | <Function ref="func" v-if="isFunction" :modulesId="modulesId" @backModules="backModules"></Function> |
| | | </basic-container> |
| | | </template> |
| | | |
| | | <script> |
| | | import {getList, getDetail, add, update, remove} from "@/api/modules/modules"; |
| | | import {mapGetters} from "vuex"; |
| | | import Function from "@/views/modules/function"; |
| | | |
| | | export default { |
| | | components: {Function}, |
| | | data() { |
| | | return { |
| | | // 弹框标题 |
| | | title: '', |
| | | // 是否展示弹框 |
| | | box: false, |
| | | // 是否显示查询 |
| | | search: true, |
| | | // 加载中 |
| | | loading: true, |
| | | // 是否为查看模式 |
| | | view: false, |
| | | // 查询信息 |
| | | query: {}, |
| | | // 分页信息 |
| | | page: { |
| | | currentPage: 1, |
| | | pageSize: 10, |
| | | total: 40 |
| | | }, |
| | | // 表单数据 |
| | | form: {}, |
| | | // 选择行 |
| | | selectionList: [], |
| | | // 表单配置 |
| | | option: { |
| | | height: 'auto', |
| | | calcHeight: 30, |
| | | tip: false, |
| | | searchShow: true, |
| | | searchMenuSpan: 6, |
| | | border: true, |
| | | index: true, |
| | | viewBtn: true, |
| | | selection: true, |
| | | dialogClickModal: false, |
| | | column: [ |
| | | { |
| | | label: "模块名称", |
| | | prop: "name", |
| | | type: "input", |
| | | span: 24, |
| | | rules: [{ |
| | | required: true, |
| | | message: "请输入模块名称", |
| | | trigger: "blur" |
| | | }], |
| | | }, |
| | | { |
| | | label: "宽", |
| | | prop: "width", |
| | | type: "input", |
| | | rules: [{ |
| | | required: true, |
| | | message: "请输入宽", |
| | | trigger: "blur" |
| | | }], |
| | | }, |
| | | { |
| | | label: "高", |
| | | prop: "height", |
| | | type: "input", |
| | | rules: [{ |
| | | required: true, |
| | | message: "请输入高", |
| | | trigger: "blur" |
| | | }], |
| | | }, |
| | | { |
| | | label: "模块背景", |
| | | prop: "background", |
| | | type: 'upload', |
| | | limit: 1, |
| | | listType: 'picture-card', |
| | | accept: 'image/png, image/jpeg', |
| | | drag: true, |
| | | loadText: '模板上传中,请稍等', |
| | | propsHttp: { |
| | | res: 'data', |
| | | url: 'link' |
| | | }, |
| | | action: "/api/blade-resource/oss/endpoint/put-file-attach" |
| | | }, |
| | | ] |
| | | }, |
| | | // 表单列表 |
| | | data: [], |
| | | isFunction: false, |
| | | modulesId: "", |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.init(); |
| | | this.onLoad(this.page); |
| | | }, |
| | | computed: { |
| | | ...mapGetters(["permission"]), |
| | | ids() { |
| | | let ids = []; |
| | | this.selectionList.forEach(ele => { |
| | | ids.push(ele.id); |
| | | }); |
| | | return ids.join(","); |
| | | } |
| | | }, |
| | | methods: { |
| | | init() { |
| | | }, |
| | | searchHide() { |
| | | this.search = !this.search; |
| | | }, |
| | | searchChange() { |
| | | this.onLoad(this.page); |
| | | }, |
| | | searchReset() { |
| | | this.query = {}; |
| | | this.page.currentPage = 1; |
| | | this.onLoad(this.page); |
| | | }, |
| | | handleSubmit(form, done) { |
| | | if (!this.form.id) { |
| | | add(this.form).then(() => { |
| | | this.box = false; |
| | | this.onLoad(this.page); |
| | | this.$message({ |
| | | type: "success", |
| | | message: "操作成功!" |
| | | }); |
| | | done() |
| | | }); |
| | | } else { |
| | | update(this.form).then(() => { |
| | | this.box = false; |
| | | this.onLoad(this.page); |
| | | this.$message({ |
| | | type: "success", |
| | | message: "操作成功!" |
| | | }); |
| | | done() |
| | | }) |
| | | } |
| | | }, |
| | | handleAdd() { |
| | | this.title = '新增' |
| | | this.box = true |
| | | this.$nextTick(() => { |
| | | this.$refs.form.resetForm() |
| | | //resetForm无法清除残留id,因此手动清除 |
| | | this.form.id = "" |
| | | }) |
| | | }, |
| | | handleEdit(row) { |
| | | this.title = '编辑' |
| | | this.box = true |
| | | getDetail(row.id).then(res => { |
| | | this.form = res.data.data; |
| | | this.fileList = this.form.background |
| | | }); |
| | | }, |
| | | handleView(row) { |
| | | this.title = '查看' |
| | | this.view = true; |
| | | this.box = true; |
| | | getDetail(row.id).then(res => { |
| | | this.form = res.data.data; |
| | | }); |
| | | }, |
| | | handleDelete(id) { |
| | | this.$confirm("确定将选择数据删除?", { |
| | | confirmButtonText: "确定", |
| | | cancelButtonText: "取消", |
| | | type: "warning" |
| | | }) |
| | | .then(() => { |
| | | return remove(id); |
| | | }) |
| | | .then(() => { |
| | | // this.selectionClear(); |
| | | this.onLoad(this.page); |
| | | this.$message({ |
| | | type: "success", |
| | | message: "操作成功!" |
| | | }); |
| | | }); |
| | | }, |
| | | rowDel(row) { |
| | | this.$confirm("确定将选择数据删除?", { |
| | | confirmButtonText: "确定", |
| | | cancelButtonText: "取消", |
| | | type: "warning" |
| | | }) |
| | | .then(() => { |
| | | return remove(row.id); |
| | | }) |
| | | .then(() => { |
| | | this.onLoad(this.page); |
| | | this.$message({ |
| | | type: "success", |
| | | message: "操作成功!" |
| | | }); |
| | | }); |
| | | }, |
| | | beforeClose(done) { |
| | | done() |
| | | this.$refs.form.resetForm() |
| | | this.form = {} |
| | | this.view = false; |
| | | }, |
| | | selectionChange(list) { |
| | | this.selectionList = list; |
| | | }, |
| | | selectionClear() { |
| | | this.selectionList = []; |
| | | this.$refs.table.clearSelection(); |
| | | }, |
| | | currentChange(currentPage) { |
| | | this.page.currentPage = currentPage; |
| | | this.onLoad(this.page); |
| | | }, |
| | | sizeChange(pageSize) { |
| | | this.page.pageSize = pageSize; |
| | | this.onLoad(this.page); |
| | | }, |
| | | onLoad(page, params = {}) { |
| | | this.loading = true; |
| | | getList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => { |
| | | const data = res.data.data; |
| | | this.page.total = data.total; |
| | | this.data = data.records; |
| | | this.loading = false; |
| | | // this.selectionClear(); |
| | | }); |
| | | }, |
| | | //显示功能页 |
| | | setContent(id) { |
| | | this.modulesId = id |
| | | this.isFunction = !this.isFunction |
| | | }, |
| | | //返回模块页 |
| | | backModules() { |
| | | this.isFunction = !this.isFunction |
| | | } |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .el-pagination { |
| | | margin-top: 20px; |
| | | } |
| | | |
| | | .bottom { |
| | | margin-top: 13px; |
| | | line-height: 12px; |
| | | } |
| | | |
| | | .button { |
| | | padding: 0; |
| | | float: right; |
| | | } |
| | | |
| | | .image { |
| | | width: 100%; |
| | | height: 230px; |
| | | display: block; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .clearfix:before, |
| | | .clearfix:after { |
| | | display: table; |
| | | content: ""; |
| | | } |
| | | |
| | | .clearfix:after { |
| | | clear: both |
| | | } |
| | | </style> |