| New file |
| | |
| | | <template> |
| | | <div class="coupon-management"> |
| | | <!-- 搜索区域 --> |
| | | <Card class="filter-container"> |
| | | <div class="filter-header"> |
| | | <Icon type="ios-search" size="18" /> |
| | | <span class="filter-title">筛选搜索</span> |
| | | <div class="filter-actions"> |
| | | <Button type="primary" @click="getList" size="small">查询搜索</Button> |
| | | <Button @click="handleResetSearch" size="small" style="margin-left: 10px;">重置</Button> |
| | | <Button type="primary" @click="addModal" size="small" style="margin-left: 10px;">新增</Button> |
| | | </div> |
| | | </div> |
| | | <div class="filter-content"> |
| | | <Form |
| | | :model="listQuery" |
| | | :label-width="90" |
| | | class="search-form" |
| | | inline |
| | | > |
| | | <FormItem label="模板名称"> |
| | | <Input |
| | | v-model="listQuery.templateName" |
| | | style="width: 180px;" |
| | | clearable |
| | | placeholder="请输入模板名称" |
| | | > |
| | | </Input> |
| | | </FormItem> |
| | | <FormItem label="启用状态:"> |
| | | <Select |
| | | v-model="listQuery.status" |
| | | placeholder="全部状态" |
| | | clearable |
| | | style="width: 180px" |
| | | > |
| | | <Option value="DISABLE">未启用</Option> |
| | | <Option value="ENABLE">已起用</Option> |
| | | </Select> |
| | | </FormItem> |
| | | |
| | | |
| | | </Form> |
| | | </div> |
| | | </Card> |
| | | |
| | | <!-- 表格区域 --> |
| | | <Card class="table-container"> |
| | | <Table |
| | | :loading="listLoading" |
| | | border |
| | | :columns="tableColumns" |
| | | :data="list" |
| | | ref="table" |
| | | class="coupon-table" |
| | | > |
| | | <template slot-scope="{ row }" slot="action"> |
| | | <Button |
| | | type="primary" |
| | | size="small" |
| | | style="margin-right: 5px" |
| | | @click="delTemplate(row)" |
| | | >删除</Button |
| | | > |
| | | <Button |
| | | type="primary" |
| | | size="small" |
| | | style="margin-right: 5px" |
| | | @click="updateTemplate(row)" |
| | | >修改</Button |
| | | > |
| | | <Button |
| | | type="primary" |
| | | size="small" |
| | | style="margin-right: 5px" |
| | | @click="changeStatus(row)" |
| | | >{{ row.status ==='ENABLE' ? '禁用':'开启'}}</Button |
| | | > |
| | | </template> |
| | | </Table> |
| | | </Card> |
| | | |
| | | <!-- 分页区域 --> |
| | | <div class="pagination-container"> |
| | | <Page |
| | | :current="listQuery.pageNumber" |
| | | :page-size="listQuery.pageSize" |
| | | :total="total" |
| | | :page-size-opts="[10, 20, 30, 50]" |
| | | show-elevator |
| | | show-sizer |
| | | show-total |
| | | @on-change="handleCurrentChange" |
| | | @on-page-size-change="handleSizeChange" |
| | | /> |
| | | </div> |
| | | |
| | | <Modal |
| | | v-model="showModal" |
| | | :title="modalTitle" |
| | | width="800" |
| | | :mask-closable="false" |
| | | > |
| | | <Form |
| | | ref="form" |
| | | :model="form" |
| | | :label-width="90" |
| | | class="search-form" |
| | | :rules="formRules" |
| | | inline> |
| | | <Row> |
| | | <Col :span="24"> |
| | | <FormItem label="模板名称" prop="templateName"> |
| | | <Input v-model="form.templateName" autocomplete="off"/> |
| | | </FormItem> |
| | | </Col> |
| | | <Col :span="24"> |
| | | <FormItem label="选择新增标题"> |
| | | <Button type="primary" @click="addTitle('TEXT')">添加文字标题</Button> |
| | | <Button type="primary" style="margin-left: 10px" @click="addTitle('IMAGE')">添加图片标题</Button> |
| | | </FormItem> |
| | | </Col> |
| | | |
| | | <Col :span="24"> |
| | | |
| | | <!-- 已添加的标题列表 --> |
| | | <div v-for="(title, index) in form.titles" :key="index" class="title-item"> |
| | | <card class="title-text"> |
| | | <Input v-model="title.templateTitle" placeholder="请输入文本标题" style="width: 300px; margin-top: 8px;"/> |
| | | <Button class="delete-btn" type="text" @click="removeTitle(index)" style="color: #ff4d4f;">删除</Button> |
| | | </card> |
| | | <!-- <card v-if="title.contentType === 'IMAGE'" class="title-image">--> |
| | | <!-- <Upload--> |
| | | <!-- v-if="!title.imgTempUrl"--> |
| | | <!-- :before-upload="(file) => handleBeforeUpload(file,title)"--> |
| | | <!-- :format="['jpg','jpeg','png','gif']"--> |
| | | <!-- :max-size="20480"--> |
| | | <!-- action=""--> |
| | | <!-- accept="image/*"--> |
| | | <!-- >--> |
| | | <!-- <Button icon="ios-cloud-upload-outline">上传封面图片</Button>--> |
| | | <!-- </Upload>--> |
| | | <!-- <div v-else class="upload-file-info">--> |
| | | |
| | | <!-- <Col :span="24">--> |
| | | <!-- <img :src="title.imgTempUrl" alt="活动图片" class="preview-image-limit">--> |
| | | <!-- </Col>--> |
| | | <!-- <Button type="text" @click="handleRemoveImage(title)">删除</Button>--> |
| | | <!-- </div>--> |
| | | |
| | | <!-- <Button class="delete-btn" type="text" @click="removeTitle(index)" style="color: #ff4d4f;">删除</Button>--> |
| | | <!-- </card>--> |
| | | </div> |
| | | </Col> |
| | | <Col :span="24"> |
| | | <FormItem label="模板图片" > |
| | | <div style="display: flex; flex-wrap: wrap;"> |
| | | <vuedraggable :animation="200" :list="showListImages"> |
| | | <div v-for="(item, __index) in showListImages" :key="__index" |
| | | class="demo-upload-list"> |
| | | <template> |
| | | <img :src="item"/> |
| | | <div class="demo-upload-list-cover"> |
| | | <div> |
| | | <Icon size="30" type="md-search" @click.native="handleViewGoodsPicture(item)"></Icon> |
| | | <Icon size="30" type="md-trash" @click.native="handleRemoveGoodsPicture(item)"></Icon> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | </div> |
| | | </vuedraggable> |
| | | </div> |
| | | <div style="width: 100%;display: flex;justify-content: start;margin-top: 10px;"> |
| | | <Button @click="handleCLickImg('goodsGalleryFiles')" type="primary">上传图片</Button> |
| | | </div> |
| | | <Modal v-model="goodsPictureVisible" title="View Image"> |
| | | <img v-if="goodsPictureVisible" :src="previewGoodsPicture" style="width: 100%"/> |
| | | </Modal> |
| | | </FormItem> |
| | | </Col> |
| | | |
| | | </Row> |
| | | |
| | | |
| | | </Form> |
| | | <div slot="footer"> |
| | | <Button type="text" @click="showModal = false">关闭</Button> |
| | | <Button type="primary" :loading="submitLoading" @click="saveOrUpdate">确认</Button> |
| | | </div> |
| | | </Modal> |
| | | |
| | | <Modal v-model="picModelFlag" width="1200px"> |
| | | <div class="demo-upload-list" v-for="(item,index) in showListImages"> |
| | | <template> |
| | | <img :src="item"> |
| | | <div class="demo-upload-list-cover"> |
| | | <Icon type="ios-eye-outline" @click.native="handleView(item)"></Icon> |
| | | <Icon type="ios-trash-outline" @click.native="handleRemove(null,index)"></Icon> |
| | | </div> |
| | | </template> |
| | | </div> |
| | | <div class="demo-upload-list"> |
| | | <Upload |
| | | :before-upload="upLoadImg" |
| | | accept="image/*" |
| | | action="-" |
| | | type="drag" |
| | | style=" display: inline-block;width: 58px" |
| | | > |
| | | <div style="width: 58px;height:58px;line-height: 58px;"> |
| | | <Icon type="ios-camera" size="20"></Icon> |
| | | </div> |
| | | </Upload> |
| | | </div> |
| | | </Modal> |
| | | <Modal v-model="visible" title="预览图片"> |
| | | <img v-if="visible" :src="previewPicture" style="width: 100%"> |
| | | </Modal> |
| | | |
| | | </div> |
| | | </template> |
| | | <script> |
| | | |
| | | import { getPage,edit,add,del,changeStatus,detail } from "@/api/goods-customeize-template.js" |
| | | import vuedraggable from "vuedraggable"; |
| | | import COS from "cos-js-sdk-v5"; |
| | | import {getFileKey} from "@/utils/file.js"; |
| | | import {getFilePreview, getSts} from "@/api/file"; |
| | | |
| | | export default { |
| | | name: 'GoodsCustomizeTemplate', |
| | | components: {vuedraggable}, |
| | | data() { |
| | | return { |
| | | // 预览图片路径 |
| | | previewPicture: "", |
| | | visible:false, |
| | | picModelFlag: false, // 图片选择器 |
| | | goodsPictureVisible: false, |
| | | showListImages: [], |
| | | listImages: [], |
| | | previewGoodsPicture: "", |
| | | selectedFormBtnName: "", // 点击图片绑定form |
| | | |
| | | //新增 |
| | | modalTitle:"", |
| | | showModal:false, |
| | | |
| | | list: [], |
| | | total: 0, |
| | | listLoading: false, |
| | | submitLoading: false, |
| | | |
| | | listQuery: { |
| | | pageNumber: 1, |
| | | pageSize: 10, |
| | | templateName:"", |
| | | status:"", |
| | | }, |
| | | form:{ |
| | | titles: [] |
| | | }, |
| | | // 表单验证规则 |
| | | formRules: { |
| | | templateName:[ |
| | | {required:true,message:"模板名不能为空",trigger:"blur"} |
| | | ] |
| | | }, |
| | | |
| | | // 表头配置 |
| | | tableColumns: [ |
| | | { |
| | | type: 'selection', |
| | | width: 60, |
| | | align: 'center' |
| | | }, |
| | | { |
| | | title: '模板名称', |
| | | key: 'templateName', |
| | | align: 'center', |
| | | ellipsis: true, |
| | | tooltip: true |
| | | }, |
| | | { |
| | | title: '启用状态', |
| | | key: 'status', |
| | | width: 120, |
| | | align: 'center', |
| | | render: (h, params) => { |
| | | const status = params.row.status; |
| | | const color = status === 'ENABLE' ? 'success' : status === 'DISABLE' ? 'default' : 'warning'; |
| | | const text = status === 'ENABLE' ? '启用' : status === 'DISABLE' ? '未启用' : '未知'; |
| | | |
| | | return h('Tag', { |
| | | props: { |
| | | color: color |
| | | } |
| | | }, text); |
| | | } |
| | | }, |
| | | { |
| | | title: '操作', |
| | | slot: 'action', |
| | | width: 200, |
| | | align: 'center' |
| | | }, |
| | | ] |
| | | } |
| | | }, |
| | | methods: { |
| | | changeStatus(row){ |
| | | changeStatus(row.id).then(res =>{ |
| | | if (res.code ===200 ){ |
| | | this.$Message.success(res.msg) |
| | | } |
| | | this.getList() |
| | | }) |
| | | |
| | | }, |
| | | async updateTemplate(row){ |
| | | this.showModal = true; |
| | | this.modalTitle = "修改模板"; |
| | | |
| | | await detail(row.id).then(res =>{ |
| | | if (res.code === 200){ |
| | | this.form = { |
| | | id: res.data.id, |
| | | templateName: res.data.templateName || '', // 确保不为undefined |
| | | titles: res.data.titles || [] // 标题列表 |
| | | }; |
| | | this.form.titles.map((i) =>{ |
| | | i.id = null; |
| | | return i |
| | | }) |
| | | this.listImages = res.data.listImages.map((i) => { |
| | | return i.imgUrl |
| | | }); |
| | | |
| | | } |
| | | }) |
| | | const stsInfo = await getSts(); |
| | | const endpoint = stsInfo.data.endpoint; |
| | | console.log() |
| | | this.showListImages = this.listImages.map((i) => { |
| | | if (i!=null&&i.indexOf('http')===-1) |
| | | return endpoint+'/'+i; |
| | | else return i; |
| | | }) |
| | | |
| | | }, |
| | | delTemplate(row){ |
| | | del(row.id).then(res =>{ |
| | | if (res.code === 200){ |
| | | this.$Message.success(res.msg) |
| | | } |
| | | this.getList() |
| | | }) |
| | | }, |
| | | async upLoadImg(file) { |
| | | console.log("打印上传1") |
| | | if (this.listImages.length >= 10) { |
| | | this.$Message.error("图片上传不能超过10个"); |
| | | return; |
| | | } |
| | | console.log("打印上传2") |
| | | try { |
| | | // 获取文件上传临时密钥 |
| | | const sts = await getSts(); |
| | | const cos = new COS({ |
| | | getAuthorization: async function (options, callback) { |
| | | callback({ |
| | | TmpSecretId: sts.data.tmpSecretId, |
| | | TmpSecretKey: sts.data.tmpSecretKey, |
| | | SecurityToken: sts.data.sessionToken, |
| | | // 建议返回服务器时间作为签名的开始时间,避免客户端本地时间偏差过大导致签名错误 |
| | | StartTime: sts.data.stsStartTime, // 时间戳,单位秒,如:1580000000 |
| | | ExpiredTime: sts.data.stsEndTime,// 时间戳,单位秒,如:1580000000 |
| | | ScopeLimit: true, // 细粒度控制权限需要设为 true,会限制密钥只在相同请求时重复使用 |
| | | }); |
| | | } |
| | | }) |
| | | const fileKey = getFileKey(file.name) |
| | | const upData = await cos.uploadFile({ |
| | | Bucket: sts.data.bucket, |
| | | Region: sts.data.region, |
| | | Key: fileKey, |
| | | Body: file, // 要上传的文件对象。 |
| | | SliceSize: 1024 * 1024 * 5, |
| | | onProgress: function (progressData) { |
| | | console.log('上传进度:', progressData); |
| | | }, |
| | | }); |
| | | console.log("上传成功", upData) |
| | | this.$nextTick(() => { |
| | | this.listImages.push(fileKey); |
| | | this.showListImages.push(sts.data.endpoint + "/" + fileKey); |
| | | |
| | | }) |
| | | |
| | | } catch (e) { |
| | | console.log("上传失败", upData) |
| | | return false; |
| | | } finally { |
| | | |
| | | } |
| | | return false; |
| | | }, |
| | | handleView(url) { |
| | | this.previewPicture = url; |
| | | this.visible = true; |
| | | }, |
| | | handleRemove(item, index) { |
| | | if (!item) { |
| | | this.listImages.splice(index, 1); |
| | | this.showListImages.splice(index, 1); |
| | | |
| | | } else { |
| | | console.log('移除测试',item, index); |
| | | item.splice(index, 1) |
| | | } |
| | | this.previewPicture = ""; |
| | | }, |
| | | |
| | | handleCLickImg(val, index) { |
| | | this.picModelFlag = true; |
| | | this.selectedFormBtnName = val; |
| | | }, |
| | | handleViewGoodsPicture(url) { |
| | | this.previewGoodsPicture = url; |
| | | this.goodsPictureVisible = true; |
| | | }, |
| | | // 移除商品图片 |
| | | handleRemoveGoodsPicture(file) { |
| | | // this.baseInfoForm.goodsGalleryFiles = |
| | | // this.baseInfoForm.goodsGalleryFiles.filter((i) => i !== file); |
| | | }, |
| | | |
| | | addTitle(type){ |
| | | this.form.titles.push( |
| | | { |
| | | contentType: type, |
| | | templateTitle: '', |
| | | imgTempUrl:null,//图片临时地址 |
| | | file:null, |
| | | }); |
| | | }, |
| | | // 移除标题 |
| | | removeTitle(index) { |
| | | this.form.titles.splice(index, 1); |
| | | }, |
| | | |
| | | saveOrUpdate() { |
| | | const submitData = { |
| | | ...this.form, |
| | | listImages: this.listImages, |
| | | }; |
| | | |
| | | console.log(submitData) |
| | | |
| | | const isTitlesValid = (titles) => { |
| | | console.log("进入判断") |
| | | // 数组本身为null/undefined或空数组 |
| | | if (!titles || titles.length === 0) return false; |
| | | // 检查每个元素的有效性 |
| | | return titles.every(title => { |
| | | // 基础校验:必须是对象且包含contentType |
| | | if (!title || typeof title !== 'object' || !title.contentType) return false; |
| | | |
| | | return title.templateTitle !== null |
| | | && title.templateTitle !== undefined |
| | | && title.templateTitle.trim() !== ''; |
| | | // 未知类型 |
| | | return false; |
| | | }); |
| | | }; |
| | | |
| | | const isImagesValid = (images) => { |
| | | if (!images || images.length === 0) return false; |
| | | return images.some(img => img && (typeof img === 'string' ? img.trim() !== '' : true)); |
| | | }; |
| | | |
| | | this.$refs.form.validate(async (valid) => { |
| | | if (valid) { |
| | | try { |
| | | // 先处理所有图片上传(等待异步完成) |
| | | this.submitLoading = true; |
| | | |
| | | // 上传完成后再验证 |
| | | if (!isTitlesValid(submitData.titles)) { |
| | | this.$Message.error('请确保所有标题都填写完整(文本标题不能为空,图片标题需上传成功)'); |
| | | this.submitLoading = false; |
| | | return; |
| | | } |
| | | |
| | | if (!isImagesValid(submitData.listImages)) { |
| | | this.$Message.error('请添加有效的图片(至少一张图片)'); |
| | | this.submitLoading = false; |
| | | return; |
| | | } |
| | | |
| | | // 验证通过,提交数据 |
| | | const api = this.form.id ? edit : add; |
| | | const res = await api(submitData); |
| | | |
| | | if (res.code === 200) { |
| | | this.$Message.success(res.msg); |
| | | this.modelShow = false; |
| | | this.getList(); |
| | | } else { |
| | | this.$Message.error(res.msg); |
| | | } |
| | | } catch (error) { |
| | | this.$Message.error('提交失败,请重试'); |
| | | console.error(error); |
| | | } finally { |
| | | this.submitLoading = false; |
| | | this.showModal = false; |
| | | } |
| | | } |
| | | }); |
| | | }, |
| | | addModal(){ |
| | | this.form = { |
| | | titles: [] |
| | | }; |
| | | this.showModal = true; |
| | | this.modalTitle = "新增模板"; |
| | | this.showListImages =[]; |
| | | this.listImages =[]; |
| | | }, |
| | | detail(row){ |
| | | console.log(row) |
| | | }, |
| | | |
| | | // 获取列表数据 |
| | | getList() { |
| | | this.listLoading = true; |
| | | // 模拟API调用 |
| | | getPage(this.listQuery).then(res =>{ |
| | | this.listLoading = false; |
| | | this.list = res.data; |
| | | this.total = res.total; |
| | | }) |
| | | }, |
| | | |
| | | // 重置搜索条件 |
| | | handleResetSearch() { |
| | | this.listQuery = { |
| | | pageNumber: 1, |
| | | pageSize: 10, |
| | | storeName: "", |
| | | couponName: "", |
| | | generateStatus: "", |
| | | status: "" |
| | | }; |
| | | this.getList(); |
| | | }, |
| | | |
| | | // 分页大小改变 |
| | | handleSizeChange(size) { |
| | | this.listQuery.pageSize = size; |
| | | this.listQuery.pageNumber = 1; |
| | | this.getList(); |
| | | }, |
| | | |
| | | // 当前页码改变 |
| | | handleCurrentChange(pageNumber) { |
| | | this.listQuery.pageNumber = pageNumber; |
| | | this.getList(); |
| | | }, |
| | | |
| | | // 提交表单 |
| | | handleSubmit() { |
| | | this.$refs.dataForm.validate((valid) => { |
| | | if (valid) { |
| | | } |
| | | }); |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.getList(); |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="less"> |
| | | .preview-image-limit{ |
| | | max-width: 100%; |
| | | max-height: 200px; |
| | | object-fit: contain; |
| | | border-radius: 4px; |
| | | box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); |
| | | display: block; |
| | | } |
| | | .delete-btn { |
| | | position: absolute; /* 绝对定位 */ |
| | | top: 12px; /* 距离顶部的距离 */ |
| | | right: 12px; /* 距离右侧的距离 */ |
| | | padding: 4px 8px; /* 调整按钮大小 */ |
| | | line-height: 1; /* 调整行高 */ |
| | | } |
| | | .title-item { |
| | | margin-bottom: 12px; |
| | | padding-bottom: 12px; |
| | | border-bottom: 1px dashed #e9e9e9; |
| | | } |
| | | |
| | | .title-type-selector { |
| | | display: flex; |
| | | justify-content: center; |
| | | padding: 20px 0; |
| | | } |
| | | |
| | | .type-option { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | margin: 0 20px; |
| | | cursor: pointer; |
| | | padding: 15px; |
| | | border-radius: 4px; |
| | | transition: all 0.3s; |
| | | |
| | | &:hover { |
| | | background-color: #f5f7fa; |
| | | } |
| | | |
| | | span { |
| | | margin-top: 10px; |
| | | } |
| | | } |
| | | .coupon-management { |
| | | padding: 16px; |
| | | background: #f5f7f9; |
| | | min-height: 100vh; |
| | | } |
| | | |
| | | .filter-container { |
| | | margin-bottom: 16px; |
| | | |
| | | .filter-header { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-bottom: 16px; |
| | | |
| | | .filter-title { |
| | | margin-left: 8px; |
| | | font-weight: 600; |
| | | font-size: 16px; |
| | | } |
| | | |
| | | .filter-actions { |
| | | margin-left: auto; |
| | | } |
| | | } |
| | | |
| | | .filter-content { |
| | | .search-form { |
| | | /deep/ .ivu-form-item { |
| | | margin-bottom: 16px; |
| | | margin-right: 16px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .operation-container { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 16px; |
| | | padding: 12px 16px; |
| | | background: #fff; |
| | | border-radius: 4px; |
| | | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); |
| | | |
| | | .operation-info { |
| | | color: #999; |
| | | font-size: 14px; |
| | | } |
| | | } |
| | | |
| | | .table-container { |
| | | margin-bottom: 16px; |
| | | |
| | | .coupon-table { |
| | | /deep/ .ivu-table-cell { |
| | | padding: 8px 12px; |
| | | } |
| | | |
| | | .action-btns { |
| | | display: flex; |
| | | justify-content: center; |
| | | |
| | | button { |
| | | margin: 0 2px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .pagination-container { |
| | | display: flex; |
| | | justify-content: flex-end; |
| | | background: #fff; |
| | | padding: 12px 16px; |
| | | border-radius: 4px; |
| | | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | // 响应式调整 |
| | | @media (max-width: 768px) { |
| | | .coupon-management { |
| | | padding: 8px; |
| | | } |
| | | |
| | | .filter-content .search-form { |
| | | /deep/ .ivu-form-item { |
| | | width: 100%; |
| | | margin-right: 0; |
| | | |
| | | .ivu-form-item-content { |
| | | width: 100%; |
| | | |
| | | .ivu-input, .ivu-select { |
| | | width: 100% !important; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .operation-container { |
| | | flex-direction: column; |
| | | align-items: flex-start; |
| | | |
| | | .add-btn { |
| | | margin-bottom: 8px; |
| | | } |
| | | } |
| | | |
| | | .action-btns { |
| | | flex-direction: column; |
| | | |
| | | button { |
| | | margin: 2px 0 !important; |
| | | width: 100%; |
| | | } |
| | | } |
| | | } |
| | | .demo-upload-list { |
| | | display: inline-block; |
| | | width: 60px; |
| | | height: 60px; |
| | | text-align: center; |
| | | line-height: 60px; |
| | | border: 1px solid transparent; |
| | | border-radius: 4px; |
| | | overflow: hidden; |
| | | background: #fff; |
| | | position: relative; |
| | | box-shadow: 0 1px 1px rgba(0, 0, 0, .2); |
| | | margin-right: 4px; |
| | | } |
| | | |
| | | .demo-upload-list img { |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | |
| | | .demo-upload-list-cover { |
| | | display: none; |
| | | position: absolute; |
| | | top: 0; |
| | | bottom: 0; |
| | | left: 0; |
| | | right: 0; |
| | | background: rgba(0, 0, 0, .6); |
| | | } |
| | | |
| | | .demo-upload-list:hover .demo-upload-list-cover { |
| | | display: block; |
| | | } |
| | | |
| | | .demo-upload-list-cover i { |
| | | color: #fff; |
| | | font-size: 20px; |
| | | cursor: pointer; |
| | | margin: 0 2px; |
| | | } |
| | | </style> |