@ -0,0 +1,928 @@
< template >
< div class = "ssp-report-page" >
<!-- 顶部导航 -- >
< div class = "top-nav" >
< div class = "nav-left" @click ="goBack" >
< van -icon name = "arrow-left" / >
< / div >
< div class = "nav-title" > 随手拍 < / div >
< div class = "nav-right" @click ="handleSubmit" >
提交
< / div >
< / div >
< ! - - 表单内容 - - >
< div class = "form-content" >
<!-- 设备信息 -- >
< div class = "section-card" >
< div class = "section-header" @click ="toggleSection('device')" >
< div class = "section-title-box" >
< span class = "section-icon" > ▶ < / span >
< span class = "section-title" > 设备信息 < / span >
< / div >
< van-icon : name = "openSections.device ? 'arrow-up' : 'arrow-down'" / >
< / div >
< div class = "section-body" v-show = "openSections.device" >
< van -cell -group :border = "false" >
< van-field v-model = "formData.sbbh" is-link readonly name="设备编号" label="设备编号" placeholder="请选择"
@click ="openPicker({ columns: deviceColumns, title: '选择设备编号', onConfirm: onDeviceConfirm })" / >
< van-field v-model = "formData.zfmj" is-link readonly name="执法民警" label="执法民警" placeholder="请选择"
@click ="openPicker({ columns: officerColumns, title: '选择执法民警', onConfirm: onOfficerConfirm })" / >
< / van-cell-group >
< / div >
< / div >
<!-- 车辆信息 -- >
< div class = "section-card" >
< div class = "section-header" @click ="toggleSection('vehicle')" >
< div class = "section-title-box" >
< span class = "section-icon" > ▶ < / span >
< span class = "section-title" > 车辆信息 < / span >
< / div >
< van-icon : name = "openSections.vehicle ? 'arrow-up' : 'arrow-down'" / >
< / div >
< div class = "section-body" v-show = "openSections.vehicle" >
< van -cell -group :border = "false" >
< van-field v-model = "formData.clfl" is-link readonly name="车辆分类" label="车辆分类" placeholder="请选择"
@click ="openPicker({ columns: clflColumns, title: '选择车辆分类', onConfirm: onClflConfirm })" / >
< van-field v-model = "formData.hpzl" is-link readonly name="号牌种类" label="号牌种类" placeholder="请选择"
@click ="openPicker({ columns: hpzlColumns, title: '选择号牌种类', onConfirm: onHpzlConfirm })" / >
< van-field v-model = "formData.hppch" name="号牌牌号" label="号牌牌号" placeholder="请输入" maxlength="10" / >
< / van-cell-group >
< / div >
< / div >
<!-- 违法信息 -- >
< div class = "section-card" >
< div class = "section-header" @click ="toggleSection('violation')" >
< div class = "section-title-box" >
< span class = "section-icon" > ▶ < / span >
< span class = "section-title" > 违法信息 < / span >
< / div >
< van-icon : name = "openSections.violation ? 'arrow-up' : 'arrow-down'" / >
< / div >
< div class = "section-body" v-show = "openSections.violation" >
< van -cell -group :border = "false" >
< van-field v-model = "formData.wgxzq" is-link readonly name="非法行政区划" label="非法行政区划" placeholder="请输入非法行政区划"
@click ="openPicker({ columns: xzqhColumns, title: '选择行政区划', onConfirm: onXzqhConfirm })" / >
< van-field v-model = "formData.wgdd" name="违法地点" label="违法地点" placeholder="请输入违法地点" / >
< van-field v-model = "formData.ldmkms" name="路段码公里数" label="路段码公里数" placeholder="请输入路段码公里数" / >
< van-field v-model = "formData.ddmcs" name="地点米数" label="地点米数" placeholder="请输入地点米数" / >
< van-field v-model = "formData.wfdz" name="违法地址" label="违法地址" placeholder="请输入违法地址" / >
< van-field v-model = "formData.wffssj" is-link readonly name="违法发生时间" label="违法发生时间" placeholder="请选择违法发生时间"
@click ="showWffssjPicker = true" / >
< van-field v-model = "formData.wfsj" name="违法时间" label="违法时间" placeholder="HH:mm:ss" / >
< van-field v-model = "formData.scz" name="实测值" label="实测值" placeholder="请输入实测值" / >
< van-field v-model = "formData.bzz" name="标准值" label="标准值" placeholder="请输入标准值" / >
< van-field v-model = "formData.wffxjg" name="违法发现机关" label="违法发现机关" placeholder="请输入违法发现机关" / >
< / van-cell-group >
< / div >
< / div >
<!-- 照片信息 -- >
< div class = "section-card" >
< div class = "section-header" @click ="toggleSection('photo')" >
< div class = "section-title-box" >
< span class = "section-icon" > ▶ < / span >
< span class = "section-title" > 照片信息 < / span >
< / div >
< van-icon : name = "openSections.photo ? 'arrow-up' : 'arrow-down'" / >
< / div >
< div class = "section-body" v-show = "openSections.photo" >
< ! - - 照片上传卡片 - - >
< div class = "photo-upload-list" >
< div class = "photo-upload-item" v-for = "(photo, index) in photoList" :key="index" >
< div style = "text-align: left;" > 照片 { { index + 1 } } < / div >
< van-uploader :max-count = "1" : after -read = " ( file ) = > onPhotoRead ( file , index ) " :preview-size=" 200 "
:show-upload=" ! photo . url ">
<div class=" photo - upload - content " v-if=" ! photo . url ">
<van-icon name=" photograph " class=" photo - icon " />
<div class=" photo - text ">点击拍照/上传</div>
</div>
</van-uploader>
<van-image
v-if=" photo . url "
:src=" photo . url "
class=" photo - preview - img "
width=" 100 "
height=" 100 "
fit=" cover "
radius=" 6 "
preview
:preview-src-list=" [ photo . url ] "
/>
<van-icon name=" cross " class=" photo - delete " v-if=" photo . url " @click.stop=" deletePhoto ( index ) " />
<van-field v-model=" photo . url " label=" 图片链接 " placeholder=" 请输入图片链接 " class=" photo - link - field " />
</div>
</div>
<!-- 照片基本信息 -->
<van-cell-group :border=" false ">
<van-field v-model=" formData . zpsl " is-link readonly name=" 照片数量 " label=" 照片数量 * " placeholder=" 请选择照片数量 "
@click=" openPicker ( { columns : zpslColumns , title : '选择照片数量' , onConfirm : onZpslConfirm } ) " />
<van-field v-model=" formData . tpmc " name=" 图片文件名 " label=" 图片文件名 " placeholder=" 请输入图片文件名 " />
<van-field v-model=" formData . tpfs " is-link readonly name=" 图片方式 " label=" 图片方式 " placeholder=" 请选择图片方式 "
@click=" openPicker ( { columns : tpfsColumns , title : '选择图片方式' , onConfirm : onTpfsConfirm } ) " />
<van-field v-model=" formData . wfspdz " name=" 违法视频地址 " label=" 违法视频地址 " placeholder=" 请输入违法视频地址 " />
</van-cell-group>
</div>
</div>
<!-- 其他信息 -->
<div class=" section - card ">
<div class=" section - header " @click=" toggleSection ( 'other' ) ">
<div class=" section - title - box ">
<span class=" section - icon ">▶</span>
<span class=" section - title ">其他信息</span>
</div>
<van-icon :name=" openSections . other ? 'arrow-up' : 'arrow-down' " />
</div>
<div class=" section - body " v-show=" openSections . other ">
<van-cell-group :border=" false ">
<van-field v-model=" formData . qtlx " is-link readonly name=" 通知书号 " label=" 通知书号 " placeholder=" 请输入通知书号 "
@click=" openPicker ( { columns : qtlxColumns , title : '选择通知书号' , onConfirm : onQtlxConfirm } ) " />
<van-field v-model=" formData . bz " name=" 通知日期 " label=" 通知日期 " placeholder=" 请输入通知日期 " />
</van-cell-group>
</div>
</div>
</div>
<!-- 底部提交按钮 -->
<div class=" bottom - action ">
<van-button type=" primary " block round color=" # 2563 eb " @click=" handleSubmit ">
提交
</van-button>
</div>
<!-- 通用选择器 -->
<van-popup v-model:show=" pickerState . show " position=" bottom ">
<van-picker :columns=" pickerState . columns " :title=" pickerState . title " @confirm=" onPickerConfirm " @cancel=" pickerState . show = false " />
</van-popup>
<!-- 违法发生时间选择器 -->
<van-popup v-model:show=" showWffssjPicker " position=" bottom ">
<van-datetime-picker v-model=" currentDate " type=" datetime " title=" 选择违法发生时间 " :min-date=" minDate "
:max-date=" maxDate " @confirm=" onWffssjConfirm " @cancel=" showWffssjPicker = false " />
</van-popup>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from " vue ";
import { useRouter } from " vue - router ";
import { showToast, showConfirmDialog } from " vant ";
import { upImage } from " @ / api / common ";
const router = useRouter();
// 日期选择器
const currentDate = ref(new Date());
const minDate = ref(new Date(2020, 0, 1));
const maxDate = ref(new Date(new Date().getFullYear() + 10, 11, 31));
// 表单数据
const formData = reactive({
sbbh: " ",
sbbhdm: " ",
zfmj: " ",
zfmjdm: " ",
clfl: " ",
clfldm: " ",
hpzl: " ",
hpzldm: " ",
hppch: " ",
wgxzq: " ",
wgdd: " ",
ldmkms: " ",
ddmcs: " ",
wfdz: " ",
wffssj: " ",
wfrq: " ",
wfsj: " ",
wffxjg: " ",
zplj1: " ",
zplj2: " ",
zplj3: " ",
zpsl: " 3 ",
wfspdz: " ",
tpfs: " ",
tpfsdm: " ",
tpmc: " ",
qtlx: " ",
qtlxdm: " ",
bz: " "
});
// 图片列表
const fileList = ref([]);
// 区域展开状态
const openSections = reactive({
device: true,
vehicle: true,
violation: true,
photo: true,
video: true,
other: true
});
// 照片列表
const photoList = ref([
{ label: " 照片1 ", url: " ", link: " " },
{ label: " 照片2 ", url: " ", link: " " },
{ label: " 照片3 ", url: " ", link: " " }
]);
const currentUploadIndex = ref(0);
const fileInputs = ref(null);
// 照片数量选择器选项
const zpslColumns = [
{ text: " 1 ", value: " 1 " },
{ text: " 2 ", value: " 2 " },
{ text: " 3 ", value: " 3 " },
{ text: " 4 ", value: " 4 " },
{ text: " 5 ", value: " 5 " }
];
// 图片方式选择器选项
const tpfsColumns = [
{ text: " 手机拍摄 ", value: " 01 " },
{ text: " 相机拍摄 ", value: " 02 " },
{ text: " 监控截图 ", value: " 03 " },
{ text: " 行车记录仪 ", value: " 04 " }
];
// 选择器显示状态(通用)
const pickerState = reactive({
show: false,
columns: [],
onConfirm: null,
title: " "
});
function openPicker({ columns, onConfirm, title }) {
pickerState.columns = columns;
pickerState.title = title;
pickerState.onConfirm = onConfirm;
pickerState.show = true;
}
function onPickerConfirm({ selectedOptions }) {
if (pickerState.onConfirm) {
pickerState.onConfirm(selectedOptions);
}
pickerState.show = false;
}
// 选择器显示状态
const showWffssjPicker = ref(false);
// 选择器列数据(模拟数据)
const deviceColumns = [
{ text: " 设备001 ", value: " 001 " },
{ text: " 设备002 ", value: " 002 " },
{ text: " 设备003 ", value: " 003 " }
];
const officerColumns = [
{ text: " 张三 ", value: " 001 " },
{ text: " 李四 ", value: " 002 " },
{ text: " 王五 ", value: " 003 " }
];
const clflColumns = [
{ text: " 小型汽车 ", value: " 01 " },
{ text: " 大型汽车 ", value: " 02 " },
{ text: " 摩托车 ", value: " 03 " },
{ text: " 电动车 ", value: " 04 " }
];
const hpzlColumns = [
{ text: " 蓝色 ", value: " 01 " },
{ text: " 黄色 ", value: " 02 " },
{ text: " 绿色 ", value: " 03 " },
{ text: " 白色 ", value: " 04 " },
{ text: " 黑色 ", value: " 05 " }
];
const qtlxColumns = [
{ text: " 闯红灯 ", value: " 01 " },
{ text: " 逆行 ", value: " 02 " },
{ text: " 超速 ", value: " 03 " },
{ text: " 违规停车 ", value: " 04 " },
{ text: " 违规变道 ", value: " 05 " },
{ text: " 其他 ", value: " 99 " }
];
// 行政区划列数据
const xzqhColumns = [
{ text: " 北京市 ", value: " 110000 " },
{ text: " 天津市 ", value: " 120000 " },
{ text: " 河北省 ", value: " 130000 " },
{ text: " 山西省 ", value: " 140000 " },
{ text: " 内蒙古 ", value: " 150000 " },
{ text: " 辽宁省 ", value: " 210000 " },
{ text: " 吉林省 ", value: " 220000 " },
{ text: " 黑龙江省 ", value: " 230000 " },
{ text: " 上海市 ", value: " 310000 " },
{ text: " 江苏省 ", value: " 320000 " },
{ text: " 浙江省 ", value: " 330000 " },
{ text: " 安徽省 ", value: " 340000 " },
{ text: " 福建省 ", value: " 350000 " },
{ text: " 江西省 ", value: " 360000 " },
{ text: " 山东省 ", value: " 370000 " },
{ text: " 河南省 ", value: " 410000 " },
{ text: " 湖北省 ", value: " 420000 " },
{ text: " 湖南省 ", value: " 430000 " },
{ text: " 广东省 ", value: " 440000 " },
{ text: " 广西 ", value: " 450000 " },
{ text: " 海南省 ", value: " 460000 " },
{ text: " 重庆市 ", value: " 500000 " },
{ text: " 四川省 ", value: " 510000 " },
{ text: " 贵州省 ", value: " 520000 " },
{ text: " 云南省 ", value: " 530000 " },
{ text: " 西藏 ", value: " 540000 " },
{ text: " 陕西省 ", value: " 610000 " },
{ text: " 甘肃省 ", value: " 620000 " },
{ text: " 青海省 ", value: " 630000 " },
{ text: " 宁夏 ", value: " 640000 " },
{ text: " 新疆 ", value: " 650000 " },
{ text: " 台湾省 ", value: " 710000 " },
{ text: " 香港 ", value: " 810000 " },
{ text: " 澳门 ", value: " 820000 " }
];
// 切换区域展开状态
function toggleSection(key) {
openSections[key] = !openSections[key];
}
// 选择器确认事件
function onDeviceConfirm({ selectedOptions }) {
formData.sbbh = selectedOptions[0].text;
formData.sbbhdm = selectedOptions[0].value;
}
function onOfficerConfirm({ selectedOptions }) {
formData.zfmj = selectedOptions[0].text;
formData.zfmjdm = selectedOptions[0].value;
}
function onClflConfirm({ selectedOptions }) {
formData.clfl = selectedOptions[0].text;
formData.clfldm = selectedOptions[0].value;
}
function onHpzlConfirm({ selectedOptions }) {
formData.hpzl = selectedOptions[0].text;
formData.hpzldm = selectedOptions[0].value;
}
function onQtlxConfirm({ selectedOptions }) {
formData.qtlx = selectedOptions[0].text;
formData.qtlxdm = selectedOptions[0].value;
}
function onXzqhConfirm({ selectedOptions }) {
formData.wgxzq = selectedOptions[0].text;
}
function onZpslConfirm({ selectedOptions }) {
formData.zpsl = selectedOptions[0].value;
}
function onTpfsConfirm({ selectedOptions }) {
formData.tpfs = selectedOptions[0].text;
formData.tpfsdm = selectedOptions[0].value;
}
function onWffssjConfirm(value) {
// 格式化日期时间
const date = new Date(value);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, " 0 ");
const day = String(date.getDate()).padStart(2, " 0 ");
const hours = String(date.getHours()).padStart(2, " 0 ");
const minutes = String(date.getMinutes()).padStart(2, " 0 ");
const seconds = String(date.getSeconds()).padStart(2, " 0 ");
const dateTimeStr = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
formData.wffssj = dateTimeStr;
formData.wfrq = `${year}-${month}-${day}`;
formData.wfsj = `${hours}:${minutes}:${seconds}`;
showWffssjPicker.value = false;
}
// 触发上传
function triggerUpload(index) {
currentUploadIndex.value = index;
fileInputs.value.click();
}
// 文件选择处理
function onFileChange(event) {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = (e) => {
photoList.value[currentUploadIndex.value].url = e.target.result;
// 更新照片数量
const uploadedCount = photoList.value.filter(p => p.url).length;
formData.zpsl = uploadedCount.toString();
};
reader.readAsDataURL(file);
}
// 清空input值, 允许重复选择同一张图片
event.target.value = " ";
}
// 删除照片
function deletePhoto(index) {
photoList.value[index].url = " ";
const uploadedCount = photoList.value.filter(p => p.url).length;
formData.zpsl = uploadedCount.toString();
}
// vant upload上传后处理
function onPhotoRead(file, index) {
photoList.value[index].url = file.content;
const uploadedCount = photoList.value.filter(p => p.url).length;
formData.zpsl = uploadedCount.toString();
}
// 图片上传后处理
function afterRead(file) {
// 如果是多个文件,遍历处理
if (Array.isArray(file)) {
file.forEach(item => {
uploadImage(item);
});
} else {
uploadImage(file);
}
}
function uploadImage(file) {
// 模拟上传,实际项目中调用接口
file.status = " uploading ";
file.message = " 上传中 ... ";
// 模拟上传成功
setTimeout(() => {
file.status = " success ";
file.message = " ";
showToast(" 图片上传成功 ");
}, 1000);
}
// 删除图片前处理
function beforeDelete(file, item) {
return true;
}
// 返回上一页
function goBack() {
router.back();
}
// 提交表单
function handleSubmit() {
// 表单验证
if (!formData.sbbh) {
showToast(" 请选择设备编号 ");
return;
}
if (!formData.zfmj) {
showToast(" 请选择执法民警 ");
return;
}
if (!formData.wgdd) {
showToast(" 请输入违法地点 ");
return;
}
if (!formData.zpsl) {
showToast(" 请选择照片数量 ");
return;
}
showConfirmDialog({
title: " 提示 ",
message: " 确认提交随手拍信息 ? "
})
.then(() => {
// 提交数据
const submitData = {
...formData,
photos: photoList.value.filter(p => p.url).map(p => p.url)
};
console.log(" 提交数据 : ", submitData);
showToast(" 提交成功 ");
router.back();
})
.catch(() => {
// 取消操作
});
}
onMounted(() => {
// 获取用户信息
const userInfo = JSON.parse(localStorage.getItem(" userInfo ") || " { } ");
if (userInfo.userName) {
formData.zfmj = userInfo.userName;
formData.zfmjdm = userInfo.userId;
}
});
</script>
<style lang=" scss " scoped >
. ssp - report - page {
min - height : 100 vh ;
background : # f5f5f5 ;
padding - bottom : 80 px ;
}
. top - nav {
position : fixed ;
top : 0 ;
left : 0 ;
right : 0 ;
height : 44 px ;
background : # 2563 eb ;
display : flex ;
align - items : center ;
justify - content : space - between ;
padding : 0 16 px ;
z - index : 100 ;
. nav - left {
color : white ;
font - size : 18 px ;
display : flex ;
align - items : center ;
}
. nav - title {
color : white ;
font - size : 17 px ;
font - weight : 600 ;
}
. nav - right {
color : white ;
font - size : 15 px ;
}
}
. form - content {
padding - top : 44 px ;
padding : 44 px 12 px 16 px ;
}
. section - card {
background : white ;
border - radius : 8 px ;
margin - bottom : 12 px ;
overflow : hidden ;
}
. section - header {
display : flex ;
align - items : center ;
justify - content : space - between ;
padding : 12 px 16 px ;
background : white ;
border - bottom : 1 px solid # f0f0f0 ;
. section - title - box {
display : flex ;
align - items : center ;
gap : 8 px ;
. section - icon {
font - size : 12 px ;
color : # 2563 eb ;
transition : transform 0.3 s ;
}
. section - title {
font - size : 15 px ;
font - weight : 600 ;
color : # 333 ;
}
}
}
. section - body {
padding : 4 px 0 ;
: deep ( . van - cell - group ) {
background : transparent ;
}
: deep ( . van - cell ) {
padding : 12 px 16 px ;
& : : after {
left : 16 px ;
right : 16 px ;
}
}
: deep ( . van - field _ _label ) {
color : # 666 ;
font - size : 14 px ;
width : 130 px ;
}
: deep ( . van - field _ _control ) {
color : # 333 ;
font - size : 14 px ;
}
: deep ( . van - field _ _body ) {
justify - content : flex - end ;
}
}
. photo - upload {
padding : 16 px ;
: deep ( . van - uploader ) {
display : block ;
}
: deep ( . van - uploader _ _wrapper ) {
display : flex ;
flex - wrap : wrap ;
gap : 12 px ;
}
: deep ( . van - uploader _ _preview ) {
margin : 0 ;
}
: deep ( . van - uploader _ _preview - image ) {
width : 80 px ;
height : 80 px ;
border - radius : 8 px ;
}
: deep ( . van - uploader _ _preview - delete ) {
width : 18 px ;
height : 18 px ;
background : rgba ( 0 , 0 , 0 , 0.6 ) ;
border - radius : 50 % ;
top : - 6 px ;
right : - 6 px ;
}
. upload - btn {
width : 80 px ;
height : 80 px ;
background : # f5f5f5 ;
border - radius : 8 px ;
border : 1 px dashed # dcdee0 ;
display : flex ;
flex - direction : column ;
align - items : center ;
justify - content : center ;
gap : 4 px ;
color : # 969799 ;
span {
font - size : 12 px ;
}
}
}
. photo - upload - list {
display : flex ;
flex - direction : column ;
gap : 16 px ;
padding : 12 px 16 px ;
margin - top : 12 px ;
}
. photo - upload - item {
position : relative ;
display : flex ;
flex - direction : column ;
gap : 8 px ;
padding : 12 px ;
background : # f9fafb ;
border - radius : 8 px ;
border : 1 px solid # e5e7eb ;
: deep ( . van - uploader ) {
width : 100 % ;
}
: deep ( . van - uploader _ _wrapper ) {
display : block ;
}
: deep ( . van - uploader _ _preview ) {
margin : 0 ;
}
: deep ( . van - uploader _ _preview - image ) {
width : 100 % ;
aspect - ratio : 3 / 1 ;
border - radius : 6 px ;
object - fit : cover ;
}
: deep ( . van - uploader _ _preview - delete ) {
width : 18 px ;
height : 18 px ;
background : rgba ( 0 , 0 , 0 , 0.6 ) ;
border - radius : 50 % ;
top : - 6 px ;
right : - 6 px ;
}
: deep ( . van - uploader _ _upload ) {
margin : 0 ;
width : 100 % ;
aspect - ratio : 3 / 1 ;
background : # fff ;
border : 1 px dashed # d1d5db ;
border - radius : 6 px ;
}
: deep ( . van - uploader _ _upload - icon ) {
font - size : 28 px ;
color : # 9 ca3af ;
}
: deep ( . van - uploader _ _upload - text ) {
font - size : 12 px ;
color : # 6 b7280 ;
}
. photo - upload - content {
width : 100 % ;
aspect - ratio : 3 / 1 ;
background : # fff ;
border : 1 px dashed # d1d5db ;
border - radius : 6 px ;
display : flex ;
flex - direction : column ;
align - items : center ;
justify - content : center ;
gap : 6 px ;
. photo - icon {
font - size : 32 px ;
color : # 9 ca3af ;
}
. photo - text {
font - size : 12 px ;
color : # 6 b7280 ;
}
}
. photo - preview - img {
width : 100 px ;
border - radius : 6 px ;
object - fit : cover ;
}
. photo - delete {
position : absolute ;
top : 8 px ;
right : 8 px ;
width : 20 px ;
height : 20 px ;
background : rgba ( 0 , 0 , 0 , 0.6 ) ;
border - radius : 50 % ;
color : # fff ;
font - size : 12 px ;
display : flex ;
align - items : center ;
justify - content : center ;
cursor : pointer ;
}
. photo - label {
font - size : 13 px ;
color : # 374151 ;
font - weight : 500 ;
}
. photo - link - field {
width : 100 % ;
background : # fff ;
border - radius : 6 px ;
margin - top : 4 px ;
: deep ( . van - field _ _label ) {
width : 70 px ;
color : # 6 b7280 ;
}
: deep ( . van - field _ _control ) {
font - size : 13 px ;
}
}
}
. photo - address - input {
display : flex ;
align - items : center ;
gap : 8 px ;
margin : 16 px ;
padding : 12 px ;
background : # f5f5f5 ;
border - radius : 6 px ;
cursor : pointer ;
& : active {
background : # eeeeee ;
}
. address - icon {
font - size : 18 px ;
color : # 666 ;
}
. address - text {
flex : 1 ;
font - size : 14 px ;
color : # 333 ;
}
. address - placeholder {
flex : 1 ;
font - size : 14 px ;
color : # 999 ;
}
}
. photo - address - dialog {
padding : 16 px ;
}
. photo - item {
position : relative ;
aspect - ratio : 1 ;
border - radius : 8 px ;
overflow : hidden ;
cursor : pointer ;
. photo - preview {
width : 100 % ;
height : 100 % ;
object - fit : cover ;
}
. photo - placeholder {
width : 100 % ;
height : 100 % ;
background : # f5f5f5 ;
border : 1 px dashed # dcdee0 ;
border - radius : 8 px ;
display : flex ;
flex - direction : column ;
align - items : center ;
justify - content : center ;
gap : 4 px ;
color : # 969799 ;
font - size : 12 px ;
}
. photo - delete {
position : absolute ;
top : 4 px ;
right : 4 px ;
width : 20 px ;
height : 20 px ;
background : rgba ( 0 , 0 , 0 , 0.5 ) ;
border - radius : 50 % ;
display : flex ;
align - items : center ;
justify - content : center ;
color : white ;
font - size : 12 px ;
}
& : active {
opacity : 0.8 ;
}
}
. bottom - action {
position : fixed ;
bottom : 0 ;
left : 0 ;
right : 0 ;
padding : 12 px 16 px ;
background : white ;
box - shadow : 0 - 2 px 10 px rgba ( 0 , 0 , 0 , 0.05 ) ;
: deep ( . van - button ) {
height : 44 px ;
font - size : 16 px ;
font - weight : 600 ;
}
}
< / style >