| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527 |
- <template>
- <view class="page-container bg-[#f5f7fa] min-h-screen pb-[150rpx]">
- <!-- 基本信息区域 -->
- <view class="form-card bg-white rounded-[16rpx] mx-[20rpx] mb-[20rpx] p-[30rpx]">
- <view class="section-title text-[36rpx] font-bold mb-[30rpx]">基本信息</view>
- <view class="form-item">
- <view class="item-label">变更理由<text class="required text-red-500">*</text></view>
- <picker :range="dictData.bgly" :range-key="'label'" :value="bglyIndex" @change="handleBglyChange">
- <view class="item-picker">
- {{ getDictLabel('bgly', editForm.changeReason) || '请选择' }}
- <text class="picker-arrow">▼</text>
- </view>
- </picker>
- </view>
- <view class="form-item">
- <view class="item-label">地块名称<text class="required text-red-500">*</text></view>
- <input class="item-input" v-model="editForm.dkmc" placeholder="请输入" />
- </view>
- <view class="form-item">
- <view class="item-label">确权面积(合同)<text class="required text-red-500">*</text></view>
- <input class="item-input" v-model="editForm.htmjm" placeholder="请输入" type="digit" />
- <view class="unit text-[32rpx] text-[#333] ml-[10rpx]">亩</view>
- </view>
- <view class="form-item">
- <view class="item-label">所有权性质<text class="required text-red-500">*</text></view>
- <picker :range="dictData.syqxz" :range-key="'label'" :value="syqxzIndex" @change="handleSyqxzChange">
- <view class="item-picker">
- {{ getDictLabel('syqxz', editForm.syqxz) || '请选择' }}
- <text class="picker-arrow">▼</text>
- </view>
- </picker>
- </view>
- <view class="form-item">
- <view class="item-label">地块类别<text class="required text-red-500">*</text></view>
- <picker :range="dictData.dklb" :range-key="'label'" :value="dklbIndex" @change="handleDklbChange">
- <view class="item-picker">
- {{ getDictLabel('dklb', editForm.dklb) || '请选择' }}
- <text class="picker-arrow">▼</text>
- </view>
- </picker>
- </view>
- <view class="form-item">
- <view class="item-label">地力等级<text class="required text-red-500">*</text></view>
- <picker :range="dictData.dldj" :range-key="'label'" :value="dldjIndex" @change="handleDldjChange">
- <view class="item-picker">
- {{ getDictLabel('dldj', editForm.dldj) || '请选择' }}
- <text class="picker-arrow">▼</text>
- </view>
- </picker>
- </view>
- <view class="form-item">
- <view class="item-label">土地用途<text class="required text-red-500">*</text></view>
- <picker :range="dictData.tdyt" :range-key="'label'" :value="tdytIndex" @change="handleTdytChange">
- <view class="item-picker">
- {{ getDictLabel('tdyt', editForm.tdyt) || '请选择' }}
- <text class="picker-arrow">▼</text>
- </view>
- </picker>
- </view>
- <view class="form-item">
- <view class="item-label">基本农田<text class="required text-red-500">*</text></view>
- <picker :range="dictData.jbnt" :range-key="'label'" :value="jbntIndex" @change="handleJbntChange">
- <view class="item-picker">
- {{ getDictLabel('jbnt', editForm.sfjbnt) || '请选择' }}
- <text class="picker-arrow">▼</text>
- </view>
- </picker>
- </view>
- <view class="form-item">
- <view class="item-label">地块东至<text class="required text-red-500">*</text></view>
- <input class="item-input" v-model="editForm.dkdz" placeholder="请输入" />
- </view>
- <view class="form-item">
- <view class="item-label">地块西至<text class="required text-red-500">*</text></view>
- <input class="item-input" v-model="editForm.dkxz" placeholder="请输入" />
- </view>
- <view class="form-item">
- <view class="item-label">地块南至<text class="required text-red-500">*</text></view>
- <input class="item-input" v-model="editForm.dknz" placeholder="请输入" />
- </view>
- <view class="form-item">
- <view class="item-label">地块北至<text class="required text-red-500">*</text></view>
- <input class="item-input" v-model="editForm.dkbz" placeholder="请输入" />
- </view>
- <view class="form-item-textarea mt-[20rpx]">
- <view class="item-label">备注信息</view>
- <textarea class="item-textarea" v-model="editForm.remark" placeholder="请输入"></textarea>
- </view>
- </view>
- <!-- 现场指界 -->
- <view class="form-card bg-white rounded-[16rpx] mx-[20rpx] mb-[20rpx] p-[30rpx]">
- <view class="section-title text-[36rpx] font-bold mb-[30rpx]">现场指界</view>
- <view class="upload-wrap">
- <view class="upload-box" v-for="(img, idx) in imageList.xczj.img" :key="idx">
- <image :src="img" class="upload-img" mode="aspectFill" />
- <view class="del-btn" @click.stop="delImg('xczj', idx)">×</view>
- </view>
- <view class="upload-box add-box" @click="handleUploadImage('xczj')">
- <view class="upload-plus">+</view>
- </view>
- </view>
- </view>
- <!-- 附件资料 -->
- <view class="form-card bg-white rounded-[16rpx] mx-[20rpx] mb-[20rpx] p-[30rpx]">
- <view class="section-title text-[36rpx] font-bold mb-[30rpx]">附件资料</view>
- <view class="upload-wrap">
- <view class="upload-box" v-for="(img, idx) in imageList.fjzl.img" :key="idx">
- <image :src="img" class="upload-img" mode="aspectFill" />
- <view class="del-btn" @click.stop="delImg('fjzl', idx)">×</view>
- </view>
- <view class="upload-box add-box" @click="handleUploadImage('fjzl')">
- <view class="upload-plus">+</view>
- </view>
- </view>
- </view>
- <!-- 底部修改按钮 -->
- <view class="submit-btn" @click="handleSubmit">保存修改</view>
- </view>
- </template>
- <script setup>
- import { ref, computed } from 'vue'
- import { onLoad, onShow } from '@dcloudio/uni-app';
- import { getDictData, deletefMaterials, updateLandInfo } from '@/api/farmerApi.js';
- import { uploadFile } from '@/utils/upload.js';
- import { imgBaseURL } from '@/utils/request.js';
- // 数据
- const rowData = ref({})
- const zsData = ref({})
- const addCbfbm = ref('')
- const fbfbmcd = ref('')
- const coordinateData = ref([])
- // 字典
- const dictData = ref({
- bgly: [],
- syqxz: [],
- dklb: [],
- dldj: [],
- tdyt: [],
- jbnt: []
- })
- // 表单
- const editForm = ref({
- id: '',
- bsm: '',
- changeReason: '',
- dkmc: '',
- htmjm: '',
- syqxz: '',
- dklb: '',
- dldj: '',
- tdyt: '',
- sfjbnt: '',
- dkdz: '',
- dkxz: '',
- dknz: '',
- dkbz: '',
- remark: '',
- tdlylx: ''
- })
- // 图片
- const imageList = ref({
- xczj: { img: [], number: [] },
- fjzl: { img: [], number: [] }
- })
- // 字典工具
- const transformDictFormat = (dict) => {
- if (!dict || typeof dict !== 'object') return []
- return Object.entries(dict).map(([k, v]) => ({ value: String(k), label: v }))
- }
- const getDictLabel = (type, val) => {
- if (!val || !dictData.value[type]?.length) return ''
- const item = dictData.value[type].find(i => String(i.value) === String(val))
- return item?.label || ''
- }
- // 选择器索引
- const bglyIndex = computed(() => dictData.value.bgly.findIndex(i => i.value === editForm.value.changeReason) || 0)
- const syqxzIndex = computed(() => dictData.value.syqxz.findIndex(i => i.value === editForm.value.syqxz) || 0)
- const dklbIndex = computed(() => dictData.value.dklb.findIndex(i => i.value === editForm.value.dklb) || 0)
- const dldjIndex = computed(() => dictData.value.dldj.findIndex(i => i.value === editForm.value.dldj) || 0)
- const tdytIndex = computed(() => dictData.value.tdyt.findIndex(i => i.value === editForm.value.tdyt) || 0)
- const jbntIndex = computed(() => dictData.value.jbnt.findIndex(i => i.value === editForm.value.sfjbnt) || 0)
- // 选择器事件
- const handleBglyChange = (e) => editForm.value.changeReason = dictData.value.bgly[e.detail.value]?.value
- const handleSyqxzChange = (e) => editForm.value.syqxz = dictData.value.syqxz[e.detail.value]?.value
- const handleDklbChange = (e) => editForm.value.dklb = dictData.value.dklb[e.detail.value]?.value
- const handleDldjChange = (e) => editForm.value.dldj = dictData.value.dldj[e.detail.value]?.value
- const handleTdytChange = (e) => editForm.value.tdyt = dictData.value.tdyt[e.detail.value]?.value
- const handleJbntChange = (e) => editForm.value.sfjbnt = dictData.value.jbnt[e.detail.value]?.value
- // 加载字典
- const loadDictData = async () => {
- try {
- const [bgly, syqxz, dklb, dldj, tdyt, jbnt] = await Promise.all([
- getDictData('dic_bgly'),
- getDictData('dic_syqxz'),
- getDictData('dic_dklb'),
- getDictData('dic_dldj'),
- getDictData('dic_tdyt'),
- getDictData('dic_sf')
- ])
- dictData.value.bgly = transformDictFormat(bgly.data)
- dictData.value.syqxz = transformDictFormat(syqxz.data)
- dictData.value.dklb = transformDictFormat(dklb.data)
- dictData.value.dldj = transformDictFormat(dldj.data)
- dictData.value.tdyt = transformDictFormat(tdyt.data)
- dictData.value.jbnt = transformDictFormat(jbnt.data)
- } catch (err) {
- uni.showToast({ title: '字典加载失败', icon: 'none' })
- }
- }
- // 初始化编辑数据
- const initEditData = () => {
- if (!rowData.value?.dkDetail) return
- editForm.value = { ...editForm.value, ...rowData.value.dkDetail }
- editForm.value.htmjm = rowData.value.htmjm || ''
- }
- // 上传图片
- const handleUploadImage = async (type) => {
- try {
- const { tempFilePaths } = await uni.chooseImage({ count: 1, sizeType: ['compressed'] })
- uni.showLoading({ title: '上传中...' })
- const res = await uploadFile(tempFilePaths[0])
- if (res.code === 200 && res.data?.id) {
- imageList.value[type].img.push(tempFilePaths[0])
- imageList.value[type].number.push(res.data.id)
- uni.showToast({ title: '上传成功', icon: 'success' })
- }
- } catch (e) {
- uni.showToast({ title: '上传失败', icon: 'none' })
- } finally {
- uni.hideLoading()
- }
- }
- // 删除图片
- const delImg = async (type, index) => {
- const id = imageList.value[type].number[index]
- if (id) await deletefMaterials(id).catch(() => {})
- imageList.value[type].img.splice(index, 1)
- imageList.value[type].number.splice(index, 1)
- uni.showToast({ title: '已删除' })
- }
- // 地图选择
- const handleChooseRange = () => {
- uni.navigateTo({ url: `/pages/map/map?memberInfo=${encodeURIComponent(addCbfbm.value)}` })
- }
- // 表单校验
- const validateForm = () => {
- const { changeReason, dkmc, syqxz, dklb, dldj, tdyt, sfjbnt, dkdz, dkxz, dknz, dkbz } = editForm.value
- if (!changeReason) return uni.showToast({ title: '请选择变更理由', icon: 'none' })
- if (!dkmc) return uni.showToast({ title: '请输入地块名称', icon: 'none' })
- if (!syqxz) return uni.showToast({ title: '请选择所有权性质', icon: 'none' })
- if (!dklb) return uni.showToast({ title: '请选择地块类别', icon: 'none' })
- if (!dldj) return uni.showToast({ title: '请选择地力等级', icon: 'none' })
- if (!tdyt) return uni.showToast({ title: '请选择土地用途', icon: 'none' })
- if (!sfjbnt) return uni.showToast({ title: '请选择基本农田', icon: 'none' })
- if (!dkdz) return uni.showToast({ title: '请输入东至', icon: 'none' })
- if (!dkxz) return uni.showToast({ title: '请输入西至', icon: 'none' })
- if (!dknz) return uni.showToast({ title: '请输入南至', icon: 'none' })
- if (!dkbz) return uni.showToast({ title: '请输入北至', icon: 'none' })
- return true
- }
- // 提交
- const handleSubmit = async () => {
- if (!validateForm()) return
- const dkTemp = {
- auditOpinion: '',
- bizStatus: '',
- bsm: editForm.value.bsm || '',
- changeReason: editForm.value.changeReason,
- dkbm: zsData.value.dkbm || '',
- dkbz: editForm.value.dkbz,
- remark: editForm.value.remark || '',
- dkdz: editForm.value.dkdz,
- dklb: editForm.value.dklb,
- dkmc: editForm.value.dkmc,
- dknz: editForm.value.dknz,
- dkxz: editForm.value.dkxz,
- dldj: editForm.value.dldj,
- kjzb: '',
- scmj: '',
- sfjbnt: editForm.value.sfjbnt,
- status: '',
- syqxz: editForm.value.syqxz,
- tdlylx: editForm.value.tdlylx || '',
- tdyt: editForm.value.tdyt,
- ysdm: '',
- zjrxm: ''
- }
- const submitData = {
- dkTemp,
- attachmentxczjFileIds: imageList.value.xczj.number,
- attachmentfjzlFileIds: imageList.value.fjzl.number,
- geoJson: coordinateData.value,
- cbdkxxTemp: {
- cbfbm: addCbfbm.value,
- fbfbm: fbfbmcd.value,
- htmj: '',
- htmjm: editForm.value.htmjm
- }
- }
- uni.showLoading({ title: '提交中...' })
- try {
- const res = await updateLandInfo(submitData)
- if (res.code === 200) {
- uni.showToast({ title: '保存成功', icon: 'success' })
- setTimeout(() => uni.navigateBack(), 1500)
- } else {
- uni.showToast({ title: res.msg || '保存失败', icon: 'none' })
- }
- } catch (e) {
- uni.showToast({ title: '保存失败', icon: 'none' })
- } finally {
- uni.hideLoading()
- }
- }
- // 页面生命周期
- onShow(() => {
- const pages = getCurrentPages()
- const current = pages[pages.length - 1]
- if (current.$vm.selectedLandData) {
- coordinateData.value = current.$vm.selectedLandData.points
- current.$vm.selectedLandData = null
- }
- })
- onLoad(async (options) => {
- addCbfbm.value = options.cbfbm || ''
- fbfbmcd.value = options.cbfbm?.substring(0, 14) || ''
- if (options.info) {
- try {
- const data = JSON.parse(decodeURIComponent(options.info))
- zsData.value = data
- rowData.value = data
- // 图片回显(修复空对象判断)
- const att = data.attachments || {}
- if (att?.xczj?.length) {
- att.xczj.forEach(item => {
- imageList.value.xczj.img.push(imgBaseURL + item.filePath)
- imageList.value.xczj.number.push(String(item.id))
- })
- }
- if (att?.fjzl?.length) {
- att.fjzl.forEach(item => {
- imageList.value.fjzl.img.push(imgBaseURL + item.filePath)
- imageList.value.fjzl.number.push(String(item.id))
- })
- }
- } catch (e) {}
- }
- await loadDictData()
- initEditData()
- })
- </script>
- <style lang="scss" scoped>
- page {
- background-color: #f5f7fa;
- }
- .form-card {
- box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
- }
- .section-title {
- color: #333;
- }
- .form-item {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 30rpx 0;
- border-bottom: 1rpx solid #f0f0f0;
- .item-label {
- font-size: 32rpx;
- color: #333;
- flex-shrink: 0;
- }
- .item-input {
- flex: 1;
- text-align: right;
- font-size: 32rpx;
- color: #333;
- height: 40rpx;
- line-height: 40rpx;
- }
- .item-picker {
- flex: 1;
- display: flex;
- align-items: center;
- justify-content: flex-end;
- font-size: 32rpx;
- color: #333;
- height: 40rpx;
- line-height: 40rpx;
- }
- .picker-arrow {
- margin-left: 10rpx;
- font-size: 28rpx;
- color: #333;
- }
- }
- .form-item-textarea {
- .item-label {
- font-size: 32rpx;
- color: #333;
- margin-bottom: 20rpx;
- }
- .item-textarea {
- width: 100%;
- min-height: 200rpx;
- border: 1rpx solid #e5e5e5;
- border-radius: 12rpx;
- padding: 20rpx;
- font-size: 32rpx;
- color: #333;
- box-sizing: border-box;
- }
- }
- .upload-wrap {
- display: flex;
- flex-wrap: wrap;
- gap: 20rpx;
- align-items: center;
- }
- .upload-box {
- width: 280rpx;
- height: 280rpx;
- background-color: #f5f5f5;
- border-radius: 8rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- overflow: hidden;
- position: relative;
- }
- .upload-plus {
- font-size: 80rpx;
- color: #333;
- font-weight: 300;
- }
- .upload-img {
- width: 100%;
- height: 100%;
- }
- .add-box {
- border: 2rpx dashed #ccc;
- }
- .del-btn {
- position: absolute;
- top: 0;
- right: 0;
- width: 50rpx;
- height: 50rpx;
- background: rgba(255, 0, 0, 0.7);
- color: #fff;
- font-size: 30rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .submit-btn {
- width: 80%;
- height: 90rpx;
- background-color: #007aff;
- color: #fff;
- font-size: 36rpx;
- font-weight: 500;
- border-radius: 45rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- margin: 0 auto;
- box-shadow: 0 4rpx 12rpx rgba(0, 122, 255, 0.3);
- }
- </style>
|