| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956 |
- <template>
- <view class="bg-[#f5f7fa] min-h-screen pb-[120rpx]">
- <!-- 顶部操作栏 -->
- <view class="flex justify-around p-[20rpx] bg-white mb-[20rpx]">
- <view class="bg-[#e6f7ff] text-[#007aff] px-[30rpx] py-[10rpx] rounded-[40rpx] text-[28rpx]"
- @click="handleSave">暂存</view>
- <view class="bg-[#e6f7ff] text-[#007aff] px-[30rpx] py-[10rpx] rounded-[40rpx] text-[28rpx]"
- @click="handleSplitHousehold">分户</view>
- </view>
- <!-- 基本信息 -->
- <view class="bg-white rounded-[12rpx] mx-[20rpx] mb-[20rpx] p-[30rpx]">
- <view class="text-[32rpx] font-bold mb-[30rpx]">基本信息</view>
- <!-- 加载/错误状态 -->
- <view v-if="loading" class="py-[50rpx] text-center text-[28rpx] text-[#999]">加载中...</view>
- <view v-else-if="dictLoadError" class="py-[50rpx] text-center text-[28rpx] text-[#f56c6c]">
- <view>数据加载失败</view>
- <view class="text-[24rpx] mt-[10rpx]" @click="reloadDictData">点击重新加载</view>
- </view>
- <!-- 表单内容 -->
- <view v-else>
- <!-- 承包方姓名 -->
- <view class="flex items-center mb-[30rpx]">
- <view class="text-[30rpx] text-[#333] w-[200rpx]">承包方姓名<text class="text-red-500">*</text></view>
- <input
- class="flex-1 h-[80rpx] border border-[#e5e5e5] rounded-[12rpx] px-[20rpx] text-[30rpx] text-right"
- v-model="editForm.cbfmc" placeholder="请输入承包方姓名" />
- </view>
- <!-- 承包方编码 -->
- <view class="flex justify-between items-center mb-[30rpx]">
- <view class="text-[30rpx] text-[#666]">承包方编码</view>
- <view class="text-[30rpx] text-[#333]">{{ farmerInfo?.cbfbm || '未填写' }}</view>
- </view>
- <!-- 证件类型 -->
- <view class="flex items-center mb-[30rpx]">
- <view class="text-[30rpx] text-[#333] w-[200rpx]">证件类型<text class="text-red-500">*</text></view>
- <view class="flex-1">
- <view v-if="dictData.idType.length === 0"
- class="flex items-center justify-end text-[30rpx] text-[#999] h-[80rpx] border border-[#e5e5e5] rounded-[12rpx] px-[20rpx]">
- 暂无数据
- </view>
- <picker v-else @change="handleIdTypeChange" :range="dictData.idType" :range-key="'label'"
- :value="getIdTypeIndex()">
- <view
- class="flex items-center justify-end text-[30rpx] text-[#333] h-[80rpx] border border-[#e5e5e5] rounded-[12rpx] px-[20rpx]">
- {{ getDictLabel('idType', editForm.zjlx) || '请选择' }}
- </view>
- </picker>
- </view>
- </view>
- <!-- 证件号码 -->
- <view class="flex items-center mb-[30rpx]">
- <view class="text-[30rpx] text-[#333] w-[200rpx]">证件号码<text class="text-red-500">*</text></view>
- <input
- class="flex-1 h-[80rpx] border border-[#e5e5e5] rounded-[12rpx] px-[20rpx] text-[30rpx] text-right"
- v-model="editForm.cbfzjhm" placeholder="请输入证件号码" maxlength="18" />
- </view>
- <!-- 承包方类型 -->
- <view class="flex items-center mb-[30rpx]">
- <view class="text-[30rpx] text-[#333] w-[200rpx]">承包方类型<text class="text-red-500">*</text></view>
- <view class="flex-1">
- <view v-if="dictData.farmerType.length === 0"
- class="flex items-center justify-end text-[30rpx] text-[#999] h-[80rpx] border border-[#e5e5e5] rounded-[12rpx] px-[20rpx]">
- 暂无数据
- </view>
- <picker v-else @change="handleFarmerTypeChange" :range="dictData.farmerType"
- :range-key="'label'" :value="getFarmerTypeIndex()">
- <view
- class="flex items-center justify-end text-[30rpx] text-[#333] h-[80rpx] border border-[#e5e5e5] rounded-[12rpx] px-[20rpx]">
- {{ getDictLabel('farmerType', editForm.cbflx) || '请选择' }}
- </view>
- </picker>
- </view>
- </view>
- <!-- 联系电话 -->
- <view class="flex items-center mb-[30rpx]">
- <view class="text-[30rpx] text-[#333] w-[200rpx]">联系电话<text class="text-red-500">*</text></view>
- <input
- class="flex-1 h-[80rpx] border border-[#e5e5e5] rounded-[12rpx] px-[20rpx] text-[30rpx] text-right"
- v-model="editForm.lxdh" placeholder="请输入联系电话" type="number" maxlength="11" />
- </view>
- <!-- 邮政编码 -->
- <view class="flex items-center mb-[30rpx]">
- <view class="text-[30rpx] text-[#666] w-[200rpx]">邮政编码</view>
- <input
- class="flex-1 h-[80rpx] border border-[#e5e5e5] rounded-[12rpx] px-[20rpx] text-[30rpx] text-right"
- v-model="editForm.yzbm" placeholder="请输入邮政编码" type="number" maxlength="6" />
- </view>
- <!-- 承包方地址 -->
- <view class="flex items-start mb-[20rpx]">
- <view class="text-[30rpx] text-[#333] w-[200rpx] pt-[10rpx]">承包方地址<text
- class="text-red-500">*</text></view>
- <textarea
- class="flex-1 border border-[#e5e5e5] rounded-[12rpx] px-[20rpx] py-[15rpx] text-[30rpx] h-[120rpx]"
- v-model="editForm.cbfdz" placeholder="请输入承包方地址"></textarea>
- </view>
- </view>
- </view>
- <!-- 签名预览区域 -->
- <view class="bg-white rounded-[12rpx] mx-[20rpx] mb-[20rpx] p-[30rpx]" v-if="signaturePreview">
- <view class="text-[32rpx] font-bold mb-[20rpx]">签名预览</view>
- <image :src="signaturePreview" mode="widthFix"
- class="w-[300rpx] h-[120rpx] border border-[#eee] rounded-[10rpx]"></image>
- <view class="text-[28rpx] text-[#007aff] mt-[15rpx]" @click="openSignatureDialog">
- 重新签名
- </view>
- </view>
- <!-- 家庭成员/地块信息/附件信息 -->
- <view class="bg-white rounded-[12rpx] mx-[20rpx] mb-[20rpx] p-[30rpx]">
- <view class="flex justify-between items-center mb-[30rpx]">
- <view class="text-[32rpx] font-bold">家庭成员</view>
- <view class="text-[28rpx] text-[#007aff]" @click="handleChangeHouseholder">更改户主</view>
- </view>
- <view class="flex justify-between items-center mb-[20rpx]">
- <view class="text-[30rpx] text-[#333]">家庭成员信息({{ familyMembers.length }}) <text
- class="text-[#999] text-[24rpx]">✎</text></view>
- <view class="text-[28rpx] text-[#007aff]" @click="handleAddFamilyMember">+新增</view>
- </view>
- <view v-for="(item, index) in familyMembers" :key="index"
- class="bg-[#f8f9fa] rounded-[12rpx] p-[20rpx] mb-[20rpx] flex justify-between items-center"
- @click="handleEditFamilyMember(item, index)">
- <view>
- <view class="text-[30rpx] text-[#333] mb-[10rpx]">
- {{ item.cyxm }}
- {{ getDictLabel('cyxb', item.cyxb) }}
- {{ getDictLabel('yhzgx', item.yhzgx) }}
- </view>
- <view class="text-[32rpx] text-[#666] mt-[40rpx]">{{ item.cyzjhm }}</view>
- </view>
- <view class="text-[40rpx] text-[#ccc]">
- <uni-icons type="right" size="30"></uni-icons>
- </view>
- </view>
- </view>
- <view class="bg-white rounded-[12rpx] mx-[20rpx] mb-[20rpx] p-[30rpx]">
- <view class="flex items-center mb-[30rpx]">
- <view class="text-[32rpx] font-bold">地块信息</view>
- </view>
- <view class="text-[28rpx] text-[#666] mb-[20rpx] flex">
- <view class="flex-1 ">{{ landList.length }}块</view>
- <view class="text-[28rpx] text-[#007aff]" @click="handleAddLand">+新增 </view>
- <view class="text-[28rpx] text-[#007aff] ml-[20rpx]" @click="handleChooseRange('farmer','all')">+全部地块位置
- </view>
- </view>
- <view v-for="(item, index) in landList" :key="index"
- class="bg-[#f8f9fa] rounded-[12rpx] p-[20rpx] mb-[20rpx]" @click="handleEditLand(item, index)">
- <view class="flex justify-between items-center mb-[10rpx]">
- <view class="text-[30rpx] text-[#007aff] flex">
- <view class="">
- {{ item.dkDetail.dkbm ? item.dkDetail.dkbm.slice(-5) : '' }}
- </view>
- <view class="ml-[20rpx]">
- {{ item.dkDetail.dkmc }}
- </view>
- <view class="ml-[20rpx]">
- {{ item.htmjm }}亩
- </view>
- </view>
- <view class="text-[28rpx] text-[#007aff]" @click.stop="handleChooseRange('farmer','single',item)">
- 地块位置</view>
- </view>
- <view class="text-[32rpx] text-[#666] mb-[5rpx] flex ">
- <view class="">
- 地块东至:{{ item.dkDetail.dkdz }}
- </view>
- <view class="ml-[100rpx]">
- 地块西至:{{ item.dkDetail.dkxz }}
- </view>
- </view>
- <view class="text-[32rpx] text-[#666] flex mt-[20rpx]">
- <view class="">
- 地块南至:{{ item.dkDetail.dknz }}
- </view>
- <view class="ml-[100rpx]">
- 地块北至:{{ item.dkDetail.dkbz }}
- </view>
- </view>
- <view class="text-right text-[40rpx] text-[#ccc] mt-[10rpx]">
- <uni-icons type="right" size="30"></uni-icons>
- </view>
- </view>
- </view>
- <view class="bg-white rounded-[12rpx] mx-[20rpx] mb-[20rpx] p-[30rpx]">
- <view class="flex justify-between items-center">
- <view class="text-[32rpx] font-bold">附件信息</view>
- <view class="text-[28rpx] text-[#007aff]" @click="handleUploadAttachment">
- {{ attachmentList.length > 0 ? `√ 已上传${attachmentList.length}个` : '√ 暂无' }}
- </view>
- </view>
- </view>
- <!-- 底部 签名 + 提交 双按钮 -->
- <view class="fixed bottom-0 left-0 right-0 w-full bg-white pb-[20rpx] pt-[20rpx] shadow-lg px-[30rpx]">
- <view class="flex items-center mb-[20rpx]">
- <checkbox :checked="isAgree" @click="toggleAgree" @change="handleAgreeChange" />
- <text class="text-[24rpx] text-[#666] ml-[10rpx]">我已认真并确认以上信息无误</text>
- </view>
- <view class="flex gap-[20rpx]">
- <!-- 签名按钮 -->
- <button class="flex-1 h-[88rpx] bg-[#15b7b9] text-white rounded-[44rpx] text-[32rpx]"
- :disabled="!isAgree || dictLoadError" :class="{ 'bg-gray-400': !isAgree || dictLoadError }"
- @click="openSignatureDialog">
- {{ signaturePreview ? '重新签名' : '签名' }}
- </button>
- <!-- 提交按钮 -->
- <button class="flex-1 h-[88rpx] bg-[#007aff] text-white rounded-[44rpx] text-[32rpx]"
- :disabled="!isAgree || !signaturePreview || dictLoadError || dictData.farmerType.length === 0 || dictData.idType.length === 0"
- :class="{ 'bg-gray-400': !isAgree || !signaturePreview || dictLoadError || dictData.farmerType.length === 0 || dictData.idType.length === 0 }"
- @click="submitAllData">
- 提交
- </button>
- </view>
- </view>
- <!-- 🔴 签名弹窗 -->
- <view v-if="showSignatureDialog" class="signature-overlay" @click="closeSignatureDialog">
- <view class="signature-dialog" @click.stop>
- <view class="signature-header">
- <text class="signature-title">请手写签名</text>
- <text class="close-btn" @click="closeSignatureDialog">×</text>
- </view>
- <canvas ref="canvasRef" class="signature-canvas" canvas-id="signatureCanvas" @touchstart="onTouchStart"
- @touchmove="onTouchMove" @touchend="onTouchEnd" @touchcancel="onTouchEnd"></canvas>
- <view class="signature-btns">
- <button type="default" @click="clearSignature" class="signature-btn signature-btn-clear">清空</button>
- <button type="primary" @click="confirmSignatureOnly"
- class="signature-btn signature-btn-confirm">确认签名</button>
- </view>
- </view>
- </view>
- <!-- 🔴 更改户主弹窗 -->
- <view v-if="showChangeHouseholderDialog" class="dialog-overlay">
- <view class="dialog-container" @click.stop>
- <view class="dialog-header">
- <text class="dialog-title">更改户主</text>
- </view>
- <view class="dialog-content">
- <view class="dialog-tip">
- 通过两步更换户主,第一步选择新户主、第二步修改与户主关系,并上传户口本、身份证扫描件。
- </view>
- <view class="dialog-section">
- <view class="section-title">原户主信息</view>
- <view class="section-content">{{ originalHouseholderInfo }}</view>
- </view>
- <view class="dialog-section">
- <view class="section-title">选择新户主</view>
- <view class="radio-list">
- <view v-for="(member, index) in availableHouseholders" :key="member.cyzjhm || index"
- class="radio-item" @click.stop="selectNewHouseholder(member)">
- <view class="radio-icon"
- :class="{ 'radio-checked': selectedNewHouseholder?.cyzjhm === member.cyzjhm }">
- <text v-if="selectedNewHouseholder?.cyzjhm === member.cyzjhm"
- class="check-icon">✓</text>
- </view>
- <view class="radio-label">{{ member.cyxm }}({{ member.cyzjhm }})</view>
- </view>
- </view>
- </view>
- <view class="dialog-section">
- <view class="section-title">原户主处理方式</view>
- <view class="radio-list">
- <view class="radio-item" @click.stop="selectOriginalHandler('keep')">
- <view class="radio-icon" :class="{ 'radio-checked': originalHandler === 'keep' }">
- <text v-if="originalHandler === 'keep'" class="check-icon">✓</text>
- </view>
- <view class="radio-label">保留【改为家庭成员】</view>
- </view>
- <view class="radio-item" @click.stop="selectOriginalHandler('delete')">
- <view class="radio-icon" :class="{ 'radio-checked': originalHandler === 'delete' }">
- <text v-if="originalHandler === 'delete'" class="check-icon">✓</text>
- </view>
- <view class="radio-label">删除【去世、户口迁出等情况】</view>
- </view>
- </view>
- </view>
- </view>
- <view class="dialog-footer">
- <view class="dialog-btn dialog-btn-cancel" @click.stop="closeChangeHouseholderDialog">取消</view>
- <view class="dialog-btn dialog-btn-next" @click.stop="handleNextStep">下一步</view>
- </view>
- </view>
- </view>
- </view>
- </template>
- <script setup lang="ts">
- import { ref, computed, nextTick } from 'vue'
- import { onLoad } from '@dcloudio/uni-app';
- // @ts-ignore
- import { getfarmerLoginData, getDictData, getCbfjtcyData, getCbfdkxxData, getdkxxxxData, getAutographData, submitFamilyMembersData, submitParcelInformationData } from '@/api/farmerApi.js';
- // 核心状态
- const loading = ref<boolean>(false);
- const isAgree = ref<boolean>(false);
- const dictLoadError = ref<boolean>(false);
- // 签名相关
- const showSignatureDialog = ref(false);
- const canvasRef = ref(null);
- const signaturePreview = ref(''); // 签名预览图
- const signatureBase64 = ref(''); // 签名base64
- const signatureFileName = ref(''); // 签名文件名
- let ctx = null;
- let isWriting = false;
- let points = [];
- const CANVAS_WIDTH = 350;
- const CANVAS_HEIGHT = 200;
- // 更改户主弹窗
- const showChangeHouseholderDialog = ref<boolean>(false);
- const selectedNewHouseholder = ref<any>(null);
- const originalHandler = ref<string>('keep');
- const farmerInfo = ref<any>(null);
- const dictData = ref<any>({
- idType: [],
- farmerType: [],
- cyxb: [],
- yhzgx: []
- });
- const getCbfbmjump = ref<string[]>([]);
- const editForm = ref({
- cbfmc: '',
- zjlx: '',
- cbfzjhm: '',
- cbflx: '',
- lxdh: '',
- yzbm: '',
- cbfdz: ''
- });
- const familyMembers = ref<any[]>([]);
- const landList = ref([]);
- const attachmentList = ref<any[]>([]);
- // 户主相关计算
- const originalHouseholderInfo = computed(() => {
- const householder = familyMembers.value.find(item => item.yhzgx === 0);
- if (householder) {
- return `${householder.cyxm}(${householder.cyzjhm})`;
- }
- return farmerInfo.value ? `${farmerInfo.value.cbfmc}(${farmerInfo.value.cbfzjhm})` : '无';
- });
- const availableHouseholders = computed(() => {
- const householder = familyMembers.value.find(item => item.yhzgx === 0);
- return familyMembers.value.filter(item => item.cyzjhm !== householder?.cyzjhm);
- });
- // 工具方法
- const transformDictFormat = (originalDict : Record<string | number, string>) => {
- if (!originalDict || typeof originalDict !== 'object') return [];
- return Object.entries(originalDict).map(([key, value]) => ({
- value: String(key),
- label: value as string
- }));
- };
- const getDictLabel = (dictType : string, value : string | number | undefined) => {
- if (!value || !dictData.value[dictType]?.length) return '未知';
- const item = dictData.value[dictType].find((item : any) => String(item.value) === String(value));
- return item?.label || '未知';
- };
- const getIdTypeIndex = () => {
- const targetValue = editForm.value.zjlx || farmerInfo.value?.cbfzjlx;
- if (!targetValue || !dictData.value.idType.length) return 0;
- return dictData.value.idType.findIndex((item : any) => String(item.value) === String(targetValue));
- };
- const getFarmerTypeIndex = () => {
- const targetValue = editForm.value.cbflx || farmerInfo.value?.cbflx;
- if (!targetValue || !dictData.value.farmerType.length) return 0;
- return dictData.value.farmerType.findIndex((item : any) => String(item.value) === String(targetValue));
- };
- const handleIdTypeChange = (e : any) => {
- if (!dictData.value.idType.length) return;
- editForm.value.zjlx = dictData.value.idType[e.detail.value]?.value || '';
- };
- const handleFarmerTypeChange = (e : any) => {
- if (!dictData.value.farmerType.length) return;
- editForm.value.cbflx = dictData.value.farmerType[e.detail.value]?.value || '';
- };
- const handleAgreeChange = (e : any) => {
- isAgree.value = e.detail.value;
- };
- const toggleAgree = () => {
- isAgree.value = !isAgree.value;
- };
- // ==================== 签名功能 ====================
- function initCanvas() {
- ctx = uni.createCanvasContext('signatureCanvas');
- ctx.fillStyle = '#ffffff';
- ctx.fillRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
- ctx.setStrokeStyle('#000000');
- ctx.setLineWidth(2);
- ctx.setLineCap('round');
- ctx.setLineJoin('round');
- ctx.setMiterLimit(10);
- ctx.draw(true);
- points = [];
- isWriting = false;
- }
- function drawSmoothLine(points) {
- if (points.length < 2) return;
- ctx.beginPath();
- ctx.moveTo(points[0].x, points[0].y);
- for (let i = 1; i < points.length - 1; i++) {
- const p0 = points[i - 1];
- const p1 = points[i];
- const cpX = (p0.x + p1.x) / 2;
- const cpY = (p0.y + p1.y) / 2;
- ctx.quadraticCurveTo(cpX, cpY, p1.x, p1.y);
- }
- const last = points[points.length - 1];
- const prev = points[points.length - 2];
- ctx.quadraticCurveTo(prev.x, prev.y, last.x, last.y);
- ctx.stroke();
- ctx.draw(true);
- }
- function onTouchStart(e) {
- isWriting = true;
- const { x, y } = e.touches[0];
- points = [{ x, y }];
- }
- function onTouchMove(e) {
- if (!isWriting) return;
- const { x, y } = e.touches[0];
- points.push({ x, y });
- drawSmoothLine(points);
- }
- function onTouchEnd() {
- isWriting = false;
- points = [];
- }
- function clearSignature() {
- if (!ctx) return;
- ctx.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
- ctx.fillStyle = '#ffffff';
- ctx.fillRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
- ctx.draw(true);
- points = [];
- isWriting = false;
- }
- function openSignatureDialog() {
- if (!isAgree.value || !validateForm()) return;
- showSignatureDialog.value = true;
- nextTick(() => {
- initCanvas();
- });
- }
- function closeSignatureDialog() {
- showSignatureDialog.value = false;
- ctx = null;
- points = [];
- isWriting = false;
- }
- // 仅确认签名 → 本地暂存 + 预览
- function confirmSignatureOnly() {
- if (!ctx) {
- uni.showToast({ title: '画布异常', icon: 'none' });
- return;
- }
- uni.showLoading({ title: '生成签名...' });
- uni.canvasToTempFilePath({
- canvasId: 'signatureCanvas',
- width: 350,
- height: 200,
- destWidth: 700,
- destHeight: 400,
- success: (res) => {
- const tempPath = res.tempFilePath;
- const lastSlash = tempPath.lastIndexOf('/');
- const pngPos = tempPath.lastIndexOf('.png');
- const fileName = tempPath.slice(lastSlash + 1, pngPos + 4);
- uni.getFileSystemManager().readFile({
- filePath: tempPath,
- encoding: 'base64',
- success: (data) => {
- uni.hideLoading();
- signatureBase64.value = 'data:image/png;base64,' + data.data;
- signatureFileName.value = fileName;
- signaturePreview.value = tempPath; // 预览图
- uni.showToast({ title: '签名成功', icon: 'success' });
- closeSignatureDialog();
- },
- fail: () => {
- uni.hideLoading();
- uni.showToast({ title: '签名失败', icon: 'none' });
- }
- });
- },
- fail: () => {
- uni.hideLoading();
- uni.showToast({ title: '签名失败', icon: 'none' });
- }
- });
- }
- // 最终提交 → 上传签名
- async function submitAllData() {
- //家庭成员判断, bizStatus: 不为null的数据为新增数据
- let farmerResult = familyMembers.value.filter(item => item.bizStatus !== null);
- let farmerIDS = farmerResult.filter(i => i?.id).map(i => i.id);
- //判断地块中存在bizStatus则为新增,无此字段为老数据
- const lanDresult = landList.value.filter(item => 'bizStatus' in item.dkDetail);
- let landListIDS = lanDresult.filter(i => i?.dkDetail.bsm).map(i => i?.dkDetail.bsm);
- console.log(123, familyMembers.value, landList.value,landListIDS)
- if (!signatureBase64.value) {
- uni.showToast({ title: '请先完成签名', icon: 'none' });
- return;
- }
- uni.showLoading({ title: '提交中...' });
- try {
- const autographData = {
- base64: signatureBase64.value,
- fileName: signatureFileName.value,
- businessType: 'APPLICANT_SIGNATURE_JTCY'
- };
- await getAutographData(autographData);
- await submitFamilyMembersData(farmerIDS);
- await submitParcelInformationData(landListIDS);
- uni.hideLoading();
- uni.showToast({ title: '提交成功', icon: 'success' });
- setTimeout(() => {
- uni.navigateTo({ url: `/pages/farmer/index` })
- }, 1500);
- } catch (err) {
- uni.hideLoading();
- uni.showToast({ title: '提交失败', icon: 'none' });
- }
- }
- // 更改户主
- const handleChangeHouseholder = () => {
- selectedNewHouseholder.value = null;
- originalHandler.value = 'keep';
- showChangeHouseholderDialog.value = true;
- };
- const closeChangeHouseholderDialog = () => {
- showChangeHouseholderDialog.value = false;
- };
- const selectNewHouseholder = (member : any) => {
- selectedNewHouseholder.value = member;
- };
- const selectOriginalHandler = (type : string) => {
- originalHandler.value = type;
- };
- const handleNextStep = () => {
- if (!selectedNewHouseholder.value) {
- uni.showToast({ title: '请选择新户主', icon: 'none' });
- return;
- }
- closeChangeHouseholderDialog();
- uni.showToast({ title: '已选择新户主', icon: 'success' });
- };
- // 加载数据
- const loadDictData = async () => {
- try {
- dictLoadError.value = false;
- const [resFarmer, resIdType, resCyxb, resYhzgx] = await Promise.all([
- getDictData('dic_cbflx'),
- getDictData('dic_zjlx'),
- getDictData('dic_xb'),
- getDictData('dic_yhzgx')
- ]);
- dictData.value.farmerType = resFarmer?.code === 200 ? transformDictFormat(resFarmer.data) : [];
- dictData.value.idType = resIdType?.code === 200 ? transformDictFormat(resIdType.data) : [];
- dictData.value.cyxb = resCyxb?.code === 200 ? transformDictFormat(resCyxb.data) : [];
- dictData.value.yhzgx = resYhzgx?.code === 200 ? transformDictFormat(resYhzgx.data) : [];
- } catch (err) {
- dictLoadError.value = true;
- }
- };
- const reloadDictData = async () => {
- loading.value = true;
- await loadDictData();
- loading.value = false;
- };
- const getTotal = async (cbfbm : string) => {
- try {
- const res = await getfarmerLoginData({ cbfbm });
- if (res?.data?.length) {
- const info = res.data[0];
- farmerInfo.value = { ...info };
- editForm.value = {
- cbfmc: info.cbfmc || '',
- zjlx: info.cbfzjlx || '',
- cbfzjhm: info.cbfzjhm || '',
- cbflx: info.cbflx || '',
- lxdh: info.lxdh || '',
- yzbm: info.yzbm || '',
- cbfdz: info.cbfdz || ''
- };
- }
- } catch (err) { }
- };
- const getcbfjtcyTotal = async (cbfbm : string) => {
- try {
- const res = await getCbfjtcyData({ cbfbm });
- if (res?.data?.length){
- familyMembers.value = res.data;
- }
- } catch (err) { }
- };
- const getcbfDkxxTotal = async (cbfbm : string) => {
- try {
- const res = await getCbfdkxxData({ cbfbm });
- if (!res?.data?.length) return;
- const list = [...res.data];
- for (let i = 0; i < list.length; i++) {
- if (list[i]?.dkbm) {
- const dk = await getdkxxxxData({ dkbm: list[i].dkbm });
- list[i].dkDetail = dk?.data[0].dk || dk?.data[0].dkTemp || {};
- list[i].attachments = dk?.data[0].attachments || {};
- }
- }
- landList.value = list;
- console.log(123, landList.value)
- } catch (err) { }
- };
- const validateForm = () => {
- const { cbfmc, zjlx, cbfzjhm, cbflx, lxdh, cbfdz } = editForm.value;
- if (!cbfmc) return uni.showToast({ title: '请输入姓名', icon: 'none' });
- if (!zjlx) return uni.showToast({ title: '请选择证件类型', icon: 'none' });
- if (!cbfzjhm) return uni.showToast({ title: '请输入证件号', icon: 'none' });
- if (!cbflx) return uni.showToast({ title: '请选择承包方类型', icon: 'none' });
- if (!lxdh || lxdh.length !== 11) return uni.showToast({ title: '请输入11位手机号', icon: 'none' });
- if (!cbfdz) return uni.showToast({ title: '请输入地址', icon: 'none' });
- return true;
- };
- onLoad(async (options : any) => {
- loading.value = true;
- await loadDictData();
- if (options.groupInfo) {
- getCbfbmjump.value = JSON.parse(decodeURIComponent(options.groupInfo)) || [];
- console.log(12333, getCbfbmjump.value.cbfbm)
- const cbfbm = getCbfbmjump.value.cbfbm || '';
- const cbfmc = getCbfbmjump.value.cbfmc || '';
- await getTotal(cbfbm);
- await getcbfjtcyTotal(cbfbm);
- await getcbfDkxxTotal(cbfbm);
- }
- loading.value = false;
- });
- const handleSave = () => {
- if (!validateForm()) return;
- uni.showToast({ title: '暂存成功', icon: 'success' });
- };
- const handleSplitHousehold = () => {
- uni.showModal({ title: '提示', content: '确定分户?' });
- };
- const handleAddFamilyMember = () => uni.navigateTo({ url: `/pages/farmer/addFamilyMember?memberInfo=${encodeURIComponent(JSON.stringify(getCbfbmjump.value))}` });
- const handleEditFamilyMember = (item : any, index : number) => uni.navigateTo({
- url: `/pages/farmer/editFamilyMember?memberInfo=${encodeURIComponent(JSON.stringify(item))}&index=${index}`
- });
- const handleAddLand = () => uni.navigateTo({ url: `/pages/land/addLand?cbfbm=${getCbfbmjump.value.cbfbm}` });
- const handleChooseRange = (index, dsType, item) => {
- const tem_code = ref('');
- if (item) {
- tem_code.value = item.dkbm;
- } else {
- tem_code.value = getCbfbmjump.value.cbfbm;
- }
- uni.navigateTo({ url: `/pages/map/map?memberInfo=${encodeURIComponent(JSON.stringify(tem_code.value))}&type=${index}&displayType=${dsType}` })
- };
- const handleEditLand = (item) => uni.navigateTo({ url: `/pages/land/editLand?info=${JSON.stringify(item)}&cbfbm=${getCbfbmjump.value.cbfbm}` });
- const handleViewLandPosition = (item) => uni.navigateTo({ url: `/pages/land/landPosition?code=${item.dkbm}` });
- const handleUploadAttachment = () => {
- uni.chooseImage({
- count: 5,
- success: (res) => {
- attachmentList.value.push(...res.tempFilePaths);
- }
- });
- };
- </script>
- <style lang="scss" scoped>
- page {
- background-color: #f5f7fa;
- }
- button[disabled] {
- background-color: #999 !important;
- }
- .bg-gray-400 {
- background-color: #999 !important;
- }
- input,
- textarea {
- box-sizing: border-box;
- }
- /* 签名弹窗 */
- .signature-overlay {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: rgba(0, 0, 0, 0.6);
- display: flex;
- align-items: center;
- justify-content: center;
- z-index: 99999;
- }
- .signature-dialog {
- width: 90%;
- max-width: 700rpx;
- background: #ffffff;
- border-radius: 16rpx;
- padding: 30rpx;
- box-sizing: border-box;
- }
- .signature-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20rpx;
- }
- .signature-title {
- font-size: 32rpx;
- font-weight: bold;
- color: #333;
- }
- .close-btn {
- font-size: 48rpx;
- color: #999;
- line-height: 1;
- padding: 0 10rpx;
- }
- .signature-canvas {
- width: 100%;
- height: 400rpx;
- border: 2rpx solid #e5e5e5;
- background: #ffffff;
- border-radius: 8rpx;
- touch-action: none;
- box-sizing: border-box;
- }
- .signature-btns {
- display: flex;
- justify-content: center;
- gap: 30rpx;
- margin-top: 30rpx;
- }
- .signature-btn {
- flex: 1;
- height: 80rpx;
- border-radius: 40rpx;
- font-size: 30rpx;
- line-height: 80rpx;
- padding: 0;
- }
- .signature-btn-clear {
- background: #f5f5f5;
- color: #666;
- border: 1rpx solid #e5e5e5;
- }
- .signature-btn-confirm {
- background: #00b42a;
- color: #fff;
- border: none;
- }
- /* 户主弹窗 */
- .dialog-overlay {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: rgba(0, 0, 0, 0.5);
- display: flex;
- align-items: center;
- justify-content: center;
- z-index: 9999;
- }
- .dialog-container {
- background: #fff;
- border-radius: 16rpx;
- width: 90%;
- max-width: 700rpx;
- overflow: hidden;
- }
- .dialog-header {
- background: #409eff;
- padding: 20rpx;
- text-align: center;
- }
- .dialog-title {
- color: #fff;
- font-size: 34rpx;
- font-weight: bold;
- }
- .dialog-content {
- padding: 30rpx;
- max-height: 70vh;
- overflow-y: auto;
- }
- .dialog-tip {
- color: #f5222d;
- font-size: 28rpx;
- margin-bottom: 20rpx;
- }
- .dialog-section {
- margin-bottom: 30rpx;
- }
- .section-title {
- font-size: 32rpx;
- margin-bottom: 15rpx;
- font-weight: 500;
- }
- .radio-list {
- display: flex;
- flex-direction: column;
- gap: 20rpx;
- }
- .radio-item {
- display: flex;
- align-items: center;
- gap: 16rpx;
- }
- .radio-icon {
- width: 36rpx;
- height: 36rpx;
- border-radius: 50%;
- border: 2rpx solid #ccc;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .radio-checked {
- background: #409eff;
- border-color: #409eff;
- }
- .check-icon {
- color: #fff;
- font-size: 24rpx;
- }
- .dialog-footer {
- display: flex;
- padding: 20rpx 30rpx 30rpx;
- gap: 20rpx;
- }
- .dialog-btn {
- flex: 1;
- height: 80rpx;
- border-radius: 40rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 32rpx;
- }
- .dialog-btn-cancel {
- background: #e5e5e5;
- color: #666;
- }
- .dialog-btn-next {
- background: #409eff;
- color: #fff;
- }
- </style>
|