Files
2026-04-30 17:50:53 +08:00

376 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="edit-popup">
<popup ref="popupRef" :title="popupTitle" :async="true" width="900px" @confirm="handleSubmit"
@close="handleClose">
<el-form ref="formRef" :model="formData" :rules="formRules">
<el-row :gutter="20">
<el-col :span="12">
<el-card shadow="never" class="mb-4">
<template #header>
<div class="card-header">
<span class="card-title">基本信息</span>
</div>
</template>
<el-form label-width="85px">
<el-form-item label="入驻城市" prop="city_name">
<el-input v-model="formData.city_name" clearable disabled />
</el-form-item>
<el-form-item label="姓名" prop="username">
<el-input v-model="formData.username" clearable placeholder="请输入姓名" disabled />
</el-form-item>
<el-form-item label="电话" prop="mobile">
<el-input v-model="formData.mobile" clearable placeholder="请输入电话" disabled />
</el-form-item>
<el-form-item label="性别" prop="gender">
<el-select v-model="formData.gender[0]" clearable placeholder="请选择" disabled>
<el-option label="男" value="1"></el-option>
<el-option label="女" value="2"></el-option>
</el-select>
</el-form-item>
<el-form-item label="出生年月" prop="both">
<el-input v-model="formData.both" clearable placeholder="请输入出生年月" disabled />
</el-form-item>
<el-form-item label="身高" prop="height">
<el-input v-model="formData.height" clearable placeholder="请输入身高" disabled />
</el-form-item>
<el-form-item label="体重" prop="weight">
<el-input v-model="formData.weight" clearable placeholder="请输入体重" disabled />
</el-form-item>
<el-form-item label="专属圈子" prop="label">
<el-tag v-for="(item, index) in labelMsg" :key="index" type="success"
class="mr-2 mb-2">
{{ item.label_name }}
</el-tag>
<span v-if="!labelMsg.length" class="text-gray-400">暂无</span>
</el-form-item>
<el-form-item label="审核状态" prop="status">
<el-select v-model="formData.status" clearable placeholder="请选择">
<el-option label="未审核" :value="0"></el-option>
<el-option label="通过" :value="1"></el-option>
<el-option label="驳回" :value="2"></el-option>
</el-select>
</el-form-item>
</el-form>
</el-card>
</el-col>
<el-col :span="12">
<el-card shadow="never" class="mb-4">
<template #header>
<div class="card-header">
<span class="card-title">证件照片</span>
</div>
</template>
<div class="image-grid">
<div class="image-item">
<div class="image-label">个人头像</div>
<el-image v-if="formData.avatar"
style="width: 120px; height: 120px; border-radius: 8px" :src="formData.avatar"
:zoom-rate="1.2" :max-scale="7" :min-scale="0.2"
:preview-src-list="[formData.avatar]" preview-teleported fit="cover" />
<div v-else class="image-placeholder">未上传</div>
</div>
</div>
<div class="image-grid mt-4">
<div class="image-item">
<div class="image-label">身份证正面</div>
<el-image v-if="formData.front_card"
style="width: 120px; height: 120px; border-radius: 8px"
:src="formData.front_card" :zoom-rate="1.2" :max-scale="7" :min-scale="0.2"
:preview-src-list="[formData.front_card]" preview-teleported fit="cover" />
<div v-else class="image-placeholder">未上传</div>
</div>
<div class="image-item">
<div class="image-label">身份证反面</div>
<el-image v-if="formData.back_card"
style="width: 120px; height: 120px; border-radius: 8px"
:src="formData.back_card" :zoom-rate="1.2" :max-scale="7" :min-scale="0.2"
:preview-src-list="[formData.back_card]" preview-teleported fit="cover" />
<div v-else class="image-placeholder">未上传</div>
</div>
</div>
<div class="image-grid mt-4">
<div class="image-item">
<div class="image-label">茶艺师资格证书</div>
<el-image v-if="formData.license_img"
style="width: 120px; height: 120px; border-radius: 8px"
:src="formData.license_img" :zoom-rate="1.2" :max-scale="7" :min-scale="0.2"
:preview-src-list="[formData.license_img]" preview-teleported fit="cover" />
<div v-else class="image-placeholder">未上传</div>
</div>
<div class="image-item">
<div class="image-label">健康证</div>
<el-image v-if="formData.health_certificate"
style="width: 120px; height: 120px; border-radius: 8px"
:src="formData.health_certificate" :zoom-rate="1.2" :max-scale="7"
:min-scale="0.2" :preview-src-list="[formData.health_certificate]"
preview-teleported fit="cover" />
<div v-else class="image-placeholder">未上传</div>
</div>
</div>
</el-card>
</el-col>
</el-row>
<el-card shadow="never" class="mb-4">
<template #header>
<div class="card-header">
<span class="card-title">个人展示</span>
<span class="text-gray-400 text-sm">{{ formData.image.length }} 张照片</span>
</div>
</template>
<div v-if="formData.image.length > 0" class="gallery-grid">
<div v-for="(item, index) in formData.image" :key="index" class="gallery-item">
<el-image style="width: 150px; height: 150px; border-radius: 8px" :src="item"
:zoom-rate="1.2" :max-scale="7" :min-scale="0.2" :preview-src-list="formData.image"
:initial-index="index" fit="cover" class="gallery-image" preview-teleported />
</div>
</div>
<el-empty v-else description="暂无个人展示照片" :image-size="80" />
</el-card>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup name="teamasterRealEdit">
import type { FormInstance } from 'element-plus'
import { ZoomIn } from '@element-plus/icons-vue'
import Popup from '@/components/popup/index.vue'
import { apiTeamasterRealAdd, apiTeamasterRealEdit, apiTeamasterRealDetail } from '@/api/teamaster_real'
import { timeFormat, removeImageUrlPrefix } from '@/utils/util'
import type { PropType } from 'vue'
defineProps({
dictData: {
type: Object as PropType<Record<string, any[]>>,
default: () => ({})
}
})
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
const labelMsg = ref([])
const popupTitle = computed(() => {
return mode.value = '茶艺师审核'
})
const formData = reactive({
id: '',
city_id: '',
city_name: '',
nickname: '',
username: '',
mobile: '',
gender: [],
user_id: '',
both: '',
height: '',
weight: '',
avatar: '',
health_certificate: '',
information: [],
image: [],
license_img: '',
hobby_introduce: '',
status: '',
label_id: '',
front_card: '',
back_card: '',
})
const formRules = reactive<any>({})
const setFormData = async (data: Record<any, any>) => {
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
formData[key] = data[key]
}
}
//@ts-ignore
data.gender && (formData.gender = String(data.gender).split(","))
//@ts-ignore
formData.shenhe_time = timeFormat(formData.shenhe_time, 'yyyy-mm-dd hh:MM:ss')
//@ts-ignore
formData.bohui_time = timeFormat(formData.bohui_time, 'yyyy-mm-dd hh:MM:ss')
//@ts-ignore
formData.create_time = timeFormat(formData.create_time, 'yyyy-mm-dd hh:MM:ss')
labelMsg.value = data.label_msg
}
const getDetail = async (row: Record<string, any>) => {
const data = await apiTeamasterRealDetail({
id: row.id
})
setFormData(data)
}
const handleSubmit = async () => {
await formRef.value?.validate()
let data = { ...formData, gender: formData.gender.join(",") }
data.avatar = removeImageUrlPrefix(data.avatar)
if (data.license_img) {
data.license_img = removeImageUrlPrefix(data.license_img)
}
mode.value == 'edit'
? await apiTeamasterRealEdit(data)
: await apiTeamasterRealAdd(data)
popupRef.value?.close()
emit('success')
}
const open = (type = 'add') => {
mode.value = type
popupRef.value?.open()
}
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<style scoped>
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.card-title {
font-weight: 600;
font-size: 15px;
color: #303133;
}
.mb-4 {
margin-bottom: 16px;
}
.mr-2 {
margin-right: 8px;
}
.mb-2 {
margin-bottom: 8px;
}
.text-gray-400 {
color: #909399;
font-size: 12px;
}
.text-sm {
font-size: 12px;
}
.image-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 16px;
}
.image-item {
display: flex;
flex-direction: column;
gap: 8px;
}
.image-label {
font-size: 13px;
color: #606266;
font-weight: 500;
}
.image-placeholder {
width: 120px;
height: 120px;
display: flex;
align-items: center;
justify-content: center;
background: #f5f7fa;
border-radius: 8px;
color: #909399;
font-size: 13px;
}
.gallery-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
gap: 16px;
}
.gallery-item {
position: relative;
width: 150px;
height: 150px;
border-radius: 8px;
overflow: hidden;
cursor: pointer;
}
.gallery-image {
width: 100%;
height: 100%;
transition: transform 0.3s ease;
}
.gallery-item:hover .gallery-image {
transform: scale(1.05);
}
.gallery-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
transition: opacity 0.3s ease;
}
.gallery-item:hover .gallery-overlay {
opacity: 1;
}
.gallery-overlay .el-icon {
font-size: 24px;
color: white;
}
:deep(.el-card__header) {
padding: 12px 20px;
border-bottom: 1px solid #ebeef5;
}
:deep(.el-card__body) {
padding: 20px;
}
:deep(.el-form-item) {
margin-bottom: 18px;
}
:deep(.el-form-item__label) {
font-weight: 500;
color: #606266;
}
</style>