You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

987 lines
28 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view class="applyform">
<u-form :model="submitForm" ref="submitForms" label-position="top" :label-width="140" :label-align="'left'"
:error-type="['message']">
<block v-for="(item,index) in course_forms">
<u-form-item :label="item.name" :prop="item.field"
:required="item.rule?item.rule.indexOf('required')!==-1:false">
<block v-if="item.edit_input==='text'">
<!-- <block v-if="item.field==='introduce'
|| item.field==='company_product' || item.field==='company_introduce'">
<u-input type="textarea" :placeholder="item.help?item.help:'请输入'" v-model="item.value" />
</block> -->
<u-input v-if="item.field==='company_name'"
@click="showCompanySelector = true" type="select" v-model="item.value" border :placeholder="item.help?item.help:'请选择公司名称'" />
<u-input v-else :type="item.field==='introduce'||
item.field==='company_fund'|| item.field==='company_product'||
item.field==='company_introduce'?'textarea':'text'" maxlength="9999" :placeholder="item.help?item.help:'请输入'" v-model="item.value" />
</block>
<block v-if="item.edit_input==='textarea'">
<!-- <block v-if="item.field==='introduce'
|| item.field==='company_product' || item.field==='company_introduce'">
<u-input type="textarea" :placeholder="item.help?item.help:'请输入'" v-model="item.value" />
</block> -->
<u-input :type="'textarea'" maxlength="9999" :placeholder="item.help?item.help:'请输入'" v-model="item.value" />
</block>
<block v-else-if="item.edit_input==='radio'">
<u-input :placeholder="item.help?item.help:'请选择'" v-model="item.value" :type="'select'"
@click="showSelect(item,index)" />
</block>
<block v-else-if="item.edit_input==='checkbox'">
<u-input
:value="getCheckboxDisplayValue(item)"
:placeholder="item.help?item.help:'请选择'"
type="select"
@click="openCheckboxModal(item, index)"
border
/>
</block>
<block v-else-if="item.edit_input==='date'">
<u-input :placeholder="item.help?item.help:'请选择'" v-model="item.value" :type="'select'"
@click="showDate(item,index)" />
</block>
<block v-else-if="item.edit_input==='datetime'">
<u-input :placeholder="item.help?item.help:'请选择'" v-model="item.value" :type="'select'"
@click="showDateTime(item,index)" />
</block>
<block v-else-if="item.edit_input==='files'">
<view class="file-upload-wrapper">
<view class="file-upload-btn" @click="chooseFile(item)">
<u-icon name="plus" size="40" color="#2979ff" />
<text class="file-upload-btn__text">上传文件</text>
</view>
<!-- 文件/图片列表展示 -->
<view
class="file-list"
v-if="item.fileListArr && item.fileListArr.length > 0"
>
<block v-for="(file, fIndex) in item.fileListArr" :key="fIndex">
<!-- 图片预览 -->
<view
v-if="isImageFile(file)"
class="file-list__image-wrapper"
@click="previewImageFile(file, item)"
>
<image
class="file-list__image"
:src="getFileUrl(file)"
mode="aspectFill"
/>
<view class="file-list__delete" @click.stop="removeFile(fIndex, item)">
<u-icon name="close" size="20" color="#fff" />
</view>
</view>
<!-- 普通文件预览 -->
<view
v-else
class="file-list__file"
>
<u-icon name="file-text" size="36" color="#2979ff" />
<text class="file-list__file-name">{{ getFileName(file) }}</text>
<view class="file-list__delete" @click.stop="removeFile(fIndex, item)">
<u-icon name="close" size="20" color="#fff" />
</view>
</view>
</block>
</view>
</view>
</block>
</u-form-item>
</block>
</u-form>
<view class="form-btn">
<view @click="submit" type="primary">提交</view>
</view>
<!-- 单选 -->
<u-picker @confirm="selectConfirm" v-model="selectShow" :range="selectList" range-key="value"
mode="selector"></u-picker>
<!-- 日期 -->
<u-picker @confirm="dateConfirm" mode="time" v-model="dateShow" :params="dateParams"></u-picker>
<!-- 日期时间 -->
<u-picker @confirm="dateTimeConfirm" mode="time" v-model="dateTimeShow" :params="dateTimeParams"></u-picker>
<!-- 公司选择器 -->
<company-selector v-model="showCompanySelector" @confirm="handleCompanyConfirm" @no-data="handleNoCompanyData"></company-selector>
<!-- 手动输入公司名称 -->
<view class="modal">
<u-popup v-model="showCompanyInput" mode="bottom">
<view class="modal-tip">输入公司名称</view>
<view class="modal-content" style="height:400rpx">
<view class="login-form">
<view>
<u-input :custom-style="inputStyle" :clearable="true" v-model="manualCompanyName"
placeholder="请输入公司全称"></u-input>
</view>
</view>
</view>
<view class="form-btn">
<view @click="confirmManualCompany" type="primary">确定</view>
</view>
</u-popup>
</view>
<!-- 多选弹窗 -->
<u-popup v-model="showCheckboxModal" mode="bottom" border-radius="20">
<view class="checkbox-modal">
<view class="checkbox-modal__header">
<text class="checkbox-modal__title">{{ currentCheckboxItem.name || '请选择' }}</text>
<text class="checkbox-modal__close" @click="showCheckboxModal = false">完成</text>
</view>
<scroll-view
class="checkbox-modal__content"
scroll-y="true"
:style="{ height: checkboxContentHeight + 'px' }"
>
<checkbox-group @change="(e)=>{checkboxGroupChange(e, currentCheckboxItem)}">
<label
class="checkbox-modal__item"
v-for="(checkboxitem, checkboxindex) in currentCheckboxItem.select_item"
:key="checkboxindex"
>
<checkbox
class="checkbox-modal__control"
:value="checkboxitem.value"
:checked="checkboxitem.checked"
/>
<text class="checkbox-modal__label">{{checkboxitem.value}}</text>
</label>
</checkbox-group>
</scroll-view>
</view>
</u-popup>
</view>
</template>
<script>
// import { watch } from "vue"
import {
ROOTPATH as baseUrl
} from "@/common/config.js"
import CompanySelector from '@/components/company-selector/company-selector.vue'
export default {
components: {
CompanySelector
},
props: {
course_forms: {
type: Array,
default () {
return []
}
}
},
data() {
return {
showCompanySelector: false,
showCompanyInput: false,
manualCompanyName: '',
submitForm: {},
now_fileld: 0, // 当前所操作的 filed index值
// 单选
selectShow: false,
selectList: [],
// 多选弹窗
showCheckboxModal: false,
currentCheckboxItem: {},
currentCheckboxIndex: 0,
checkboxContentHeight: 400, // 多选弹窗内容区域高度单位px
// 日期
dateShow: false,
dateParams: {
year: true,
month: true,
day: true,
hour: false,
minute: false,
second: false
},
// 日期时间
dateTimeShow: false,
dateTimeParams: {
year: true,
month: true,
day: true,
hour: true,
minute: true,
second: true
},
// 文件上传
action: `${baseUrl}/api/mobile/upload-file`,
fileList: [],
formData: {},
rules: {},
// 手动输入公司名称样式
inputStyle: {
'padding': '0rpx 30rpx',
'height': '80rpx',
'border': '1rpx solid #dad8d8;',
'border-radius': '20rpx'
},
}
},
onReady() {
// this.$refs.uForm.setRules(this.rules);
let token = uni.getStorageSync("stbc1_lifeData").vuex_token
console.log("token", token)
this.formData = {
token: token
}
this.calculateCheckboxHeight()
},
onLoad() {
},
methods: {
// 处理公司选择确认事件
handleCompanyConfirm(company) {
console.log('选中的公司:', company);
this.course_forms.map(item1 => {
if (item1.field === 'company_name') {
this.$set(item1,'value',company.enterpriseName||'')
}
if (item1.field === 'company_date') {
this.$set(item1,'value',company.startDate||'')
}
if (item1.field === 'company_product') {
this.$set(item1,'value',company.businessScope||'')
}
if (item1.field === 'company_type') {
const company_type = company.tagList && Array.isArray(company.tagList)?company.tagList.join(','):''
const _arr = company_type.split(',')
this.$set(item1,'value',company_type)
item1.select_item.forEach(item2 => {
console.log("item2",item2)
// 检查 item.value 是否存在于数组 b 中
const exists = _arr.includes(item2.value);
// 根据检查结果设置 checked 属性
item2.checked = exists;
this.$set(item2,'checked',exists)
});
}
if (item1.field === 'company_area') {
this.$set(item1,'value',company.country||'')
}
if (item1.field === 'company_address') {
this.$set(item1,'value',company.address||'')
}
if (item1.field === 'is_yuanhe') {
this.$set(item1,'value',company.isYhInvested?'是':'否')
}
})
console.log("this.course_forms",this.course_forms)
},
// 处理搜索无数据事件
handleNoCompanyData(searchKeyword) {
uni.showModal({
title: '提示',
content: '当前没有查询到公司信息,是否输入公司全称?',
success: (res) => {
if (res.confirm) {
// 关闭搜索窗口
this.showCompanySelector = false;
// 设置默认值为搜索关键词
this.manualCompanyName = searchKeyword || '';
// 打开输入框
this.showCompanyInput = true;
}
}
});
},
// 确认手动输入的公司名称
confirmManualCompany() {
if (this.base.isNull(this.manualCompanyName)) {
this.base.toast('请输入公司名称');
return;
}
// 将输入的公司名称赋给 course_forms 中 field === 'company_name' 的项的 value
this.course_forms.map(item1 => {
if (item1.field === 'company_name') {
this.$set(item1, 'value', this.manualCompanyName.trim());
}
});
// 关闭输入框
this.showCompanyInput = false;
// 清空输入
this.manualCompanyName = '';
},
// 单选
showSelect(item, index) {
this.selectList = item.select_item
this.now_fileld = index
this.selectShow = true
},
selectConfirm(e) {
this.course_forms[this.now_fileld]['value'] = this.selectList[e[0]].value
},
// 多选 - 获取显示值
getCheckboxDisplayValue(item) {
if (!item.value || this.base.isNull(item.value)) {
return ''
}
const selectedValues = item.value.split(',')
// 最多显示3个超过显示"等X项"
if (selectedValues.length <= 3) {
return selectedValues.join('、')
} else {
return selectedValues.slice(0, 3).join('、') + `等${selectedValues.length}项`
}
},
// 显示多选弹窗
openCheckboxModal(item, index) {
this.currentCheckboxItem = item
this.currentCheckboxIndex = index
this.showCheckboxModal = true
this.$nextTick(() => {
this.calculateCheckboxHeight()
})
},
// 计算多选弹窗内容区域高度
calculateCheckboxHeight() {
uni.getSystemInfo({
success: (res) => {
// 屏幕高度的 60%,减去 header 的高度
const maxHeight = res.windowHeight * 0.6
// header 大约 100rpx转换为 px
const headerHeight = 100 * (res.windowWidth / 750)
// content 高度 = 最大高度 - header - 底部 padding
this.checkboxContentHeight = maxHeight - headerHeight - 80
}
})
},
// 多选
checkboxGroupChange(e, item) {
const selectedValues = e.detail.value || []
if (selectedValues.length > 0) {
item.value = selectedValues.join(",")
} else {
item.value = ''
}
// 更新checked状态
item.select_item.forEach(option => {
option.checked = selectedValues.includes(option.value)
this.$set(option, 'checked', selectedValues.includes(option.value))
})
},
// 日期
showDate(item, index) {
this.now_fileld = index
this.dateShow = true
},
dateConfirm(e) {
console.log("date", e)
this.course_forms[this.now_fileld]['value'] = e.year + '-' + e.month + '-' + e.day
},
// 日期时间
showDateTime(item, index) {
this.now_fileld = index
this.dateTimeShow = true
},
dateTimeConfirm(e) {
console.log("date", e)
this.course_forms[this.now_fileld]['value'] = e.year + '-' + e.month + '-' + e.day +
' ' + e.hour + ':' + e.minute + ':' + e.second
},
// 根据文件对象获取真实 url
getFileUrl(file) {
if (!file) return ''
let url = ''
if (file.response && file.response.url) {
url = file.response.url
} else if (file.url) {
url = file.url
}
// 如果是相对路径,补全域名
if (url && url.indexOf('http') !== 0) {
url = baseUrl + url
}
return url || ''
},
// 判断是否为图片文件
isImageFile(file) {
if (!file) return false
const url = this.getFileUrl(file)
if (!url) return false
return /\.(jpg|jpeg|png|gif|bmp|webp)$/i.test(url)
},
// 预览图片
previewImageFile(file, item) {
const current = this.getFileUrl(file)
const urls = (item.fileListArr || [])
.filter(f => this.isImageFile(f))
.map(f => this.getFileUrl(f))
if (!urls.length) return
uni.previewImage({
current,
urls
})
},
// 获取文件名
getFileName(file) {
// 优先使用 original_name其次使用 name最后从 url 提取
if (file.response && file.response.original_name) {
return file.response.original_name
}
if (file.name) {
return file.name
}
const url = this.getFileUrl(file)
if (!url) return '未知文件'
const parts = url.split('/')
return parts[parts.length - 1]
},
// 打开普通文件pdf/doc/xls 等)
openFile(file) {
const url = this.getFileUrl(file)
if (!url) return
uni.showLoading({
title: '打开中...',
mask: true
})
uni.downloadFile({
url,
success: (res) => {
if (res.statusCode === 200) {
uni.openDocument({
filePath: res.tempFilePath,
success: () => {},
fail: (err) => {
console.error('openDocument 失败', err)
this.base && this.base.toast && this.base.toast('无法打开文件')
},
complete: () => {
uni.hideLoading()
}
})
} else {
uni.hideLoading()
this.base && this.base.toast && this.base.toast('文件下载失败')
}
},
fail: (err) => {
console.error('downloadFile 失败', err)
uni.hideLoading()
this.base && this.base.toast && this.base.toast('文件下载失败')
}
})
},
// 选择文件(支持图片和普通文件)
chooseFile(item) {
uni.showActionSheet({
itemList: ['选择图片', '选择文件'],
success: (res) => {
if (res.tapIndex === 0) {
// 选择图片
uni.chooseImage({
count: 9 - (item.fileListArr ? item.fileListArr.length : 0),
success: (res) => {
this.uploadFiles(res.tempFilePaths, item, 'image')
}
})
} else if (res.tapIndex === 1) {
// 选择文件 - 使用平台特定的API
const maxCount = 9 - (item.fileListArr ? item.fileListArr.length : 0)
// #ifdef MP-WEIXIN
// 微信小程序使用 wx.chooseMessageFile
if (typeof wx !== 'undefined' && wx.chooseMessageFile) {
wx.chooseMessageFile({
count: maxCount,
type: 'file',
success: (res) => {
const filePaths = res.tempFiles.map(f => f.path)
this.uploadFiles(filePaths, item, 'file')
},
fail: (err) => {
console.error('选择文件失败', err)
this.base && this.base.toast && this.base.toast('选择文件失败')
}
})
} else {
// 降级方案:提示用户使用图片选择
uni.showModal({
title: '提示',
content: '当前平台暂不支持选择文件,请使用图片上传功能',
showCancel: false
})
}
// #endif
// #ifndef MP-WEIXIN
// 其他平台尝试使用 uni.chooseFile如果支持
if (typeof uni.chooseFile === 'function') {
uni.chooseFile({
count: maxCount,
success: (res) => {
const filePaths = res.tempFiles ? res.tempFiles.map(f => f.path) : []
this.uploadFiles(filePaths, item, 'file')
},
fail: (err) => {
console.error('选择文件失败', err)
// 降级使用图片选择API
uni.showModal({
title: '提示',
content: '当前平台暂不支持选择文件,请使用图片上传功能',
showCancel: false
})
}
})
} else {
// 不支持文件选择,提示用户
uni.showModal({
title: '提示',
content: '当前平台暂不支持选择文件,请使用图片上传功能',
showCancel: false
})
}
// #endif
}
}
})
},
// 上传文件
uploadFiles(filePaths, item, type) {
// 找到对应的 course_forms 中的 item
const formItem = this.course_forms.find(f => f.field === item.field)
if (!formItem) {
console.error('找不到对应的表单字段', item.field)
return
}
if (!formItem.fileListArr) {
this.$set(formItem, 'fileListArr', [])
}
let uploadCount = 0
let successCount = 0
const totalCount = filePaths.length
if (totalCount === 0) return
uni.showLoading({
title: '上传中...',
mask: true
})
filePaths.forEach((filePath, index) => {
uni.uploadFile({
url: this.action,
filePath: filePath,
name: 'file',
formData: this.formData,
success: (res) => {
uploadCount++
try {
const result = JSON.parse(res.data)
// 兼容两种返回格式:
// 1. 直接返回对象 {id, url, ...}
// 2. 包装格式 {code: 200, data: {id, url, ...}}
let data = result
if (result.code === 200 && result.data) {
data = result.data
}
if (data && data.url) {
const fileObj = {
url: data.url,
response: data,
name: data.original_name || filePath.split('/').pop()
}
// 确保 fileListArr 存在
if (!formItem.fileListArr) {
this.$set(formItem, 'fileListArr', [])
}
// 使用 Vue.set 确保响应式更新
formItem.fileListArr.push(fileObj)
// 强制触发视图更新 - 创建新数组引用
this.$set(formItem, 'fileListArr', formItem.fileListArr.slice())
// 强制更新视图
this.$forceUpdate()
successCount++
console.log('上传成功', fileObj)
console.log('formItem.fileListArr', formItem.fileListArr)
console.log('formItem.field', formItem.field)
console.log('item.field', item.field)
} else {
console.error('上传响应格式错误缺少url字段', result)
if (uploadCount === totalCount) {
this.base && this.base.toast && this.base.toast('部分文件上传失败')
}
}
} catch (e) {
console.error('解析上传响应失败', e, res.data)
if (uploadCount === totalCount) {
this.base && this.base.toast && this.base.toast('部分文件上传失败')
}
}
// 所有文件上传完成
if (uploadCount === totalCount) {
uni.hideLoading()
if (successCount > 0) {
this.base && this.base.toast && this.base.toast(`成功上传${successCount}个文件`)
}
}
},
fail: (err) => {
uploadCount++
console.error('上传失败', err)
if (uploadCount === totalCount) {
uni.hideLoading()
this.base && this.base.toast && this.base.toast('上传失败')
}
}
})
})
},
// 删除文件
removeFile(index, item) {
uni.showModal({
title: '提示',
content: '确定要删除这个文件吗?',
success: (res) => {
if (res.confirm) {
// 找到对应的 course_forms 中的 item
const formItem = this.course_forms.find(f => f.field === item.field)
if (formItem && formItem.fileListArr) {
formItem.fileListArr.splice(index, 1)
// 强制触发视图更新
this.$set(formItem, 'fileListArr', [...formItem.fileListArr])
console.log('删除文件后', formItem.fileListArr)
}
}
}
})
},
// 提交
submit() {
console.log("course_forms", this.course_forms)
let errorCount = 0
this.course_forms.map(item => {
if (item.rule) {
// 不能为空
if (item.rule.indexOf('required') !== -1) {
if (this.base.isNull(item.value)) {
this.base.toast(`${item.name}不能为空`)
errorCount++
return
}
}
// 手机号
if (!this.base.isNull(item.value) && item.rule.indexOf('mobile') !== -1) {
if (!this.base.isMobile(item.value)) {
this.base.toast(`${item.name}不正确`)
errorCount++
return
}
}
// 身份证
if (!this.base.isNull(item.value) && item.rule.indexOf('idcard') !== -1) {
if (!this.$u.test.idCard(item.value)) {
this.base.toast(`${item.name}不正确`)
errorCount++
return
}
}
// 邮箱
if (item.rule.indexOf('email') !== -1) {
if (!this.base.isNull(item.value) && !this.base.isMail(item.value)) {
this.base.toast(`${item.name}不正确`)
errorCount++
return
}
}
// 整数
if (item.rule.indexOf('integer') !== -1) {
if (!this.base.isNull(item.value) && !this.base.isInteger(item.value)) {
this.base.toast(`${item.name}必须为整数`)
errorCount++
return
}
}
// 数字
if (item.rule.indexOf('numeric') !== -1) {
if (!this.base.isNull(item.value) && !this.base.isNumber(item.value)) {
this.base.toast(`${item.name}必须为数字`)
errorCount++
return
}
}
}
// 文件上传处理
if(item.edit_input==='files'){
let valueArr = []
let fileListArr = []
console.log("item.fileListArr",item.fileListArr)
if(item.fileListArr && item.fileListArr.length>0){
item.fileListArr.map(f=>{
if(f.response){
valueArr.push(f.response.url.replace(baseUrl, ''))
fileListArr.push(f.response)
}else{
valueArr.push(f.url.replace(baseUrl, ''))
fileListArr.push(f)
}
})
}else{
item.fileListArr = []
}
item.value = valueArr.join(",")
item.fileList = fileListArr
console.log("submit---",valueArr,fileListArr)
}
})
if (errorCount > 0) {
return
} else {
// return
this.$emit("backForm", this.course_forms)
}
},
},
watch: {
course_forms(newval) {
if (newval) {
// 验证规则
let that = this
let _rule = {}
newval.map(item => {
if (item.edit_input === 'checkbox') {
// 修改有值的时候 先split
let _arr = []
if (!this.base.isNull(item.value)) {
_arr = item.value.split(",")
console.log("_arr", _arr)
item.select_item.forEach(item1 => {
// 检查 item.value 是否存在于数组 b 中
const exists = _arr.includes(item1.value);
// 根据检查结果设置 checked 属性
item1.checked = exists;
});
}
}
if (item.edit_input === 'files') {
item.fileListArr = this.base.deepCopy(item.fileList)
}
})
}
}
}
}
</script>
<style scoped lang="scss">
.applyform {
position: relative;
z-index: 99
}
.form-btn {
width: 100%;
position: relative;
padding: 60rpx 0;
&>view {
width: 70%;
text-align: center;
margin: 0 auto;
color: #fff;
background: linear-gradient(to right, #5e5fbc, #0d0398);
border-radius: 30rpx;
padding: 20rpx;
}
}
.modal {
::v-deep .u-drawer-bottom {
border-radius: 40rpx;
}
&-tip {
text-align: center;
padding: 30rpx;
font-size: 32rpx;
}
&-content {
padding: 0 30rpx;
}
}
.login-form {
margin: 100rpx 50rpx;
&>view {
border-radius: 20rpx;
}
}
/* 多选项布局优化 */
.checkbox-group {
display: flex;
flex-wrap: wrap;
}
.checkbox-item {
width: 48%;
margin-bottom: 16rpx;
display: flex;
align-items: center;
padding: 12rpx 20rpx;
box-sizing: border-box;
border-radius: 12rpx;
border: 1rpx solid #e0e0e0;
background-color: #f9f9f9;
}
.checkbox-item__control {
transform: scale(0.9);
}
.checkbox-item__label {
margin-left: 12rpx;
font-size: 26rpx;
color: #333;
}
/* 多选弹窗样式 */
.checkbox-modal {
background-color: #fff;
border-radius: 20rpx 20rpx 0 0;
max-height: 80vh;
&__header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx;
border-bottom: 1rpx solid #f0f0f0;
}
&__title {
font-size: 32rpx;
font-weight: 600;
color: #333;
}
&__close {
font-size: 28rpx;
color: #2979ff;
}
&__content {
padding: 20rpx 30rpx 40rpx;
box-sizing: border-box;
}
&__item {
display: flex;
align-items: center;
padding: 24rpx 0;
padding-left: 10rpx; // 增加左侧 padding确保 checkbox 不被遮挡
border-bottom: 1rpx solid #f5f5f5;
box-sizing: border-box;
&:last-child {
border-bottom: none;
}
}
&__control {
transform: scale(1.1);
flex-shrink: 0; // 防止 checkbox 被压缩
}
&__label {
margin-left: 20rpx;
font-size: 28rpx;
color: #333;
flex: 1;
}
}
/* 文件上传样式 */
.file-upload-wrapper {
width: 100%;
}
.file-upload-btn {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 160rpx;
height: 160rpx;
border: 2rpx dashed #d0d0d0;
border-radius: 12rpx;
background-color: #fafafa;
margin-bottom: 20rpx;
&__text {
margin-top: 10rpx;
font-size: 24rpx;
color: #666;
}
}
.file-list {
display: flex;
flex-wrap: wrap;
gap: 20rpx;
margin-top: 20rpx;
&__image-wrapper {
position: relative;
width: 160rpx;
height: 160rpx;
border-radius: 12rpx;
overflow: hidden;
}
&__image {
width: 100%;
height: 100%;
}
&__file {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 160rpx;
height: 160rpx;
border: 1rpx solid #e0e0e0;
border-radius: 12rpx;
background-color: #f9f9f9;
padding: 20rpx;
box-sizing: border-box;
}
&__file-name {
margin-top: 10rpx;
font-size: 22rpx;
color: #666;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 100%;
}
&__delete {
position: absolute;
top: -10rpx;
right: -10rpx;
width: 40rpx;
height: 40rpx;
background-color: #ff4444;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
}
</style>