fwxq.vue 92 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479
  1. <script setup lang="ts">
  2. import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue'
  3. import {
  4. ElButton,
  5. ElCard,
  6. ElCol,
  7. ElContainer,
  8. ElDatePicker,
  9. ElDialog,
  10. ElForm,
  11. ElFormItem,
  12. ElIcon,
  13. ElInput,
  14. ElInputNumber,
  15. ElMain,
  16. ElMessage,
  17. ElOption,
  18. ElRow,
  19. ElSelect,
  20. ElStep,
  21. ElSteps,
  22. ElTag,
  23. } from 'element-plus'
  24. import {
  25. ArrowLeft,
  26. BookText,
  27. Cpu,
  28. Eye,
  29. FileText,
  30. Home,
  31. MapPin,
  32. Plus,
  33. User,
  34. X,
  35. } from 'lucide-vue-next'
  36. import { useRoute, useRouter } from 'vue-router'
  37. import { clientGet, clientPost } from '@/utils/request.ts'
  38. // 导入docx-preview库
  39. import { renderAsync } from 'docx-preview'
  40. const router = useRouter()
  41. const route = useRoute()
  42. // 响应式数据
  43. const showRentalDialog = ref(false)
  44. const showTerminateDialog = ref(false)
  45. const showDocxPreviewDialog = ref(false) // 新增:DOCX预览对话框
  46. const docxPreviewLoading = ref(false) // 新增:DOCX加载状态
  47. const docxPreviewContainer = ref<HTMLElement>() // 新增:DOCX预览容器引用
  48. const currentStep = ref(0)
  49. const submitting = ref(false)
  50. const terminating = ref(false)
  51. const loading = ref(true)
  52. const MINIO_URL = import.meta.env.VITE_MINIO_BASE_URL
  53. const propertyInfo = ref({
  54. id: '',
  55. buildingNumber: '',
  56. priceRange: '',
  57. address: '',
  58. area: '',
  59. status: '', // 未租 或 已租
  60. floor: '',
  61. facilities: '',
  62. assetType: '', //公租房|厂房|创新创业基地
  63. })
  64. const receiptData = ref({})
  65. const basicInfo = ref({
  66. buildYear: '',
  67. orientation: '',
  68. houseType: '',
  69. })
  70. const assetFilter = reactive({
  71. category: '',
  72. })
  73. const assets = ref<DeviceInfo[]>([])
  74. const filteredAssets = computed(() => {
  75. return assets.value.filter((asset) => {
  76. const categoryMatch = !assetFilter.category || asset.deviceType === assetFilter.category
  77. return categoryMatch
  78. })
  79. })
  80. const tenantInfo = ref<TenantInfo | null>(null)
  81. const contractInfo = ref<ContractInfo | null>(null)
  82. interface ContractA {
  83. tenantName: string
  84. landlordName: string
  85. tenantTimeStart: string
  86. tenantTime: string
  87. tenantTimeEnd: string
  88. tenantRent: string
  89. tenantDeposit: string
  90. tenantDepositAmount: string
  91. }
  92. interface ContractB {
  93. purpose: string
  94. landlordName: string
  95. landlordUniCode: string
  96. landlordLegalRepresentative: string
  97. landlordDuty: string
  98. tenantName: string
  99. tenantUniCode: string
  100. tenantLegalRepresentative: string
  101. tenantDuty: string
  102. who: string
  103. whatTime: string
  104. title: string
  105. supportingRoomArea: string
  106. officeArea: string
  107. canteenArea: string
  108. totalLeasedArea: string
  109. dormTotalRooms: string
  110. dormSmallRooms: string
  111. dormLargeRooms: string
  112. deliveryDate: string
  113. productionProject: string
  114. leaseTermYears: string
  115. leaseStartDate: string
  116. leaseEndDate: string
  117. renewNoticeMonths: string
  118. factorySpecificFloor1: string
  119. rentPerSqmFloor1: string
  120. factorySpecificFloor2: string
  121. rentPerSqmFloor2: string
  122. factoryAnnualRent: string
  123. supportingRoomRentPerSqm: string
  124. supportingRoomAnnualRent: string
  125. dormSmallRoomRent: string
  126. dormLargeRoomRent: string
  127. dormAnnualRent: string
  128. totalAnnualRent: string
  129. propertyFeePerSqm: string
  130. factorySupportingPropertyFee: string
  131. dormSmallRoomPropertyFee: string
  132. dormLargeRoomPropertyFee: string
  133. dormAnnualPropertyFee: string
  134. totalAnnualPropertyFee: string
  135. annualTotalRentAndPropertyFee: string
  136. depositAmount: string
  137. }
  138. interface ContractC {
  139. lessorName: string
  140. lessorLegalRep: string
  141. lessorUniCode: string
  142. lesseeName: string
  143. lesseeLegalRep: string
  144. lesseeIdCode: string
  145. propertyLocation: string
  146. rentableArea: string
  147. usableArea: string
  148. sharedArea: string
  149. propertyUseNature: string
  150. storeName: string
  151. brand: string
  152. businessScope: string
  153. leaseTermMonths: string
  154. leaseStartDate: string
  155. leaseEndDate: string
  156. renovationStartDate: string
  157. renovationEndDate: string
  158. officialLeaseStartDate: string
  159. annualRentLower: string
  160. annualPropertyFeeLower: string
  161. depositAmount: string
  162. }
  163. const rentalForm = reactive<{
  164. houseId: string
  165. contractData: ContractA | ContractB | ContractC | null
  166. contractDataA: ContractA
  167. contractDataB: ContractB
  168. contractDataC: ContractC
  169. rentalInfo: {
  170. rentalName: string
  171. rentalPhone: string
  172. rentalIdCard: string
  173. rentalTimeStart: string
  174. rentalTime: string
  175. rentalRect: string
  176. }
  177. }>({
  178. houseId: route.query.houseId as string,
  179. contractData: null,
  180. rentalInfo: {
  181. rentalName: '',
  182. rentalPhone: '',
  183. rentalIdCard: '',
  184. rentalTimeStart: '',
  185. rentalTime: '',
  186. rentalRect: '',
  187. },
  188. contractDataA: {
  189. landlordName: '',
  190. tenantDeposit: '',
  191. tenantDepositAmount: '',
  192. tenantName: '',
  193. tenantRent: '',
  194. tenantTime: '',
  195. tenantTimeEnd: '',
  196. tenantTimeStart: '',
  197. },
  198. contractDataB: {
  199. annualTotalRentAndPropertyFee: '',
  200. canteenArea: '',
  201. deliveryDate: '',
  202. depositAmount: '',
  203. dormAnnualPropertyFee: '',
  204. dormAnnualRent: '',
  205. dormLargeRoomPropertyFee: '',
  206. dormLargeRoomRent: '',
  207. dormLargeRooms: '',
  208. dormSmallRoomPropertyFee: '',
  209. dormSmallRoomRent: '',
  210. dormSmallRooms: '',
  211. dormTotalRooms: '',
  212. factoryAnnualRent: '',
  213. factorySpecificFloor1: '',
  214. factorySpecificFloor2: '',
  215. factorySupportingPropertyFee: '',
  216. landlordDuty: '',
  217. landlordLegalRepresentative: '',
  218. landlordName: '',
  219. landlordUniCode: '',
  220. leaseEndDate: '',
  221. leaseStartDate: '',
  222. leaseTermYears: '',
  223. officeArea: '',
  224. productionProject: '',
  225. propertyFeePerSqm: '',
  226. purpose: '',
  227. renewNoticeMonths: '',
  228. rentPerSqmFloor1: '',
  229. rentPerSqmFloor2: '',
  230. supportingRoomAnnualRent: '',
  231. supportingRoomArea: '',
  232. supportingRoomRentPerSqm: '',
  233. tenantDuty: '',
  234. tenantLegalRepresentative: '',
  235. tenantName: '',
  236. tenantUniCode: '',
  237. title: '',
  238. totalAnnualPropertyFee: '',
  239. totalAnnualRent: '',
  240. totalLeasedArea: '',
  241. whatTime: '',
  242. who: '',
  243. },
  244. contractDataC: {
  245. annualPropertyFeeLower: '',
  246. annualRentLower: '',
  247. brand: '',
  248. businessScope: '',
  249. depositAmount: '',
  250. leaseEndDate: '',
  251. leaseStartDate: '',
  252. leaseTermMonths: '',
  253. lesseeIdCode: '',
  254. lesseeLegalRep: '',
  255. lesseeName: '',
  256. lessorLegalRep: '',
  257. lessorName: '',
  258. lessorUniCode: '',
  259. officialLeaseStartDate: '',
  260. propertyLocation: '',
  261. propertyUseNature: '',
  262. renovationEndDate: '',
  263. renovationStartDate: '',
  264. rentableArea: '',
  265. sharedArea: '',
  266. storeName: '',
  267. usableArea: '',
  268. },
  269. })
  270. const rentalRules = {
  271. // 租户信息验证规则
  272. 'rentalInfo.rentalName': [{ required: true, message: '请输入租户姓名', trigger: 'blur' }],
  273. 'rentalInfo.rentalPhone': [{ required: true, message: '请输入租户电话', trigger: 'blur' }],
  274. 'rentalInfo.rentalIdCard': [{ required: false, message: '请输入租户身份证号', trigger: 'blur' }],
  275. 'rentalInfo.rentalTimeStart': [
  276. { required: true, message: '请输入租期开始时间', trigger: 'blur' },
  277. ],
  278. 'rentalInfo.rentalTime': [{ required: true, message: '请输入租期', trigger: 'blur' }],
  279. 'rentalInfo.rentalRect': [{ required: true, message: '请输入租金', trigger: 'blur' }],
  280. // 公租房合同A验证规则
  281. 'contractDataA.tenantName': [{ required: true, message: '请输入租方', trigger: 'blur' }],
  282. 'contractDataA.landlordName': [{ required: true, message: '请输入房东', trigger: 'blur' }],
  283. 'contractDataA.tenantTimeStart': [
  284. { required: true, message: '请输入租期开始时间', trigger: 'blur' },
  285. ],
  286. 'contractDataA.tenantTime': [{ required: true, message: '请输入租期', trigger: 'blur' }],
  287. 'contractDataA.tenantTimeEnd': [
  288. { required: true, message: '请输入租期结束时间', trigger: 'blur' },
  289. ],
  290. 'contractDataA.tenantRent': [{ required: true, message: '请输入每套租金', trigger: 'blur' }],
  291. 'contractDataA.tenantDeposit': [{ required: true, message: '请输入每套物业费', trigger: 'blur' }],
  292. 'contractDataA.tenantDepositAmount': [{ required: true, message: '请输入押金', trigger: 'blur' }],
  293. // 厂房合同B验证规则 - 所有字段必填
  294. 'contractDataB.purpose': [{ required: true, message: '请输入用途', trigger: 'blur' }],
  295. 'contractDataB.landlordName': [{ required: true, message: '请输入房东', trigger: 'blur' }],
  296. 'contractDataB.landlordUniCode': [
  297. { required: true, message: '请输入法人统一社会信用代码', trigger: 'blur' },
  298. ],
  299. 'contractDataB.landlordLegalRepresentative': [
  300. { required: true, message: '请输入法定代表人', trigger: 'blur' },
  301. ],
  302. 'contractDataB.landlordDuty': [{ required: true, message: '请输入房东职务', trigger: 'blur' }],
  303. 'contractDataB.tenantName': [{ required: true, message: '请输入租方', trigger: 'blur' }],
  304. 'contractDataB.tenantUniCode': [
  305. { required: true, message: '请输入租方统一社会信用代码', trigger: 'blur' },
  306. ],
  307. 'contractDataB.tenantLegalRepresentative': [
  308. { required: true, message: '请输入法定代表人', trigger: 'blur' },
  309. ],
  310. 'contractDataB.tenantDuty': [{ required: true, message: '请输入租方职务', trigger: 'blur' }],
  311. 'contractDataB.who': [{ required: true, message: '请输入谁', trigger: 'blur' }],
  312. 'contractDataB.whatTime': [{ required: true, message: '请输入何时', trigger: 'blur' }],
  313. 'contractDataB.title': [{ required: true, message: '请输入标题', trigger: 'blur' }],
  314. 'contractDataB.supportingRoomArea': [
  315. { required: true, message: '请输入配套用房面积(㎡)', trigger: 'blur' },
  316. ],
  317. 'contractDataB.officeArea': [
  318. { required: true, message: '请输入办公室面积(㎡)', trigger: 'blur' },
  319. ],
  320. 'contractDataB.canteenArea': [
  321. { required: true, message: '请输入食堂面积(㎡)', trigger: 'blur' },
  322. ],
  323. 'contractDataB.totalLeasedArea': [
  324. { required: true, message: '请输入总面积(㎡)', trigger: 'blur' },
  325. ],
  326. 'contractDataB.dormTotalRooms': [
  327. { required: true, message: '请输入宿舍楼总间数', trigger: 'blur' },
  328. ],
  329. 'contractDataB.dormSmallRooms': [
  330. { required: true, message: '请输入宿舍小间数', trigger: 'blur' },
  331. ],
  332. 'contractDataB.dormLargeRooms': [
  333. { required: true, message: '请输入宿舍大间数', trigger: 'blur' },
  334. ],
  335. 'contractDataB.deliveryDate': [
  336. { required: true, message: '请输入标的交付日期', trigger: 'blur' },
  337. ],
  338. 'contractDataB.productionProject': [
  339. { required: true, message: '请输入生产项目名称', trigger: 'blur' },
  340. ],
  341. 'contractDataB.leaseTermYears': [
  342. { required: true, message: '请输入租赁期限(年)', trigger: 'blur' },
  343. ],
  344. 'contractDataB.leaseStartDate': [
  345. { required: true, message: '请输入租赁起始日', trigger: 'blur' },
  346. ],
  347. 'contractDataB.leaseEndDate': [{ required: true, message: '请输入租赁终止日', trigger: 'blur' }],
  348. 'contractDataB.renewNoticeMonths': [
  349. { required: true, message: '请输入续租提前通知月数', trigger: 'blur' },
  350. ],
  351. 'contractDataB.factorySpecificFloor1': [
  352. { required: true, message: '请输入标准化厂房某楼层', trigger: 'blur' },
  353. ],
  354. 'contractDataB.rentPerSqmFloor1': [
  355. { required: true, message: '请输入该楼层租金(元/㎡/月)', trigger: 'blur' },
  356. ],
  357. 'contractDataB.factorySpecificFloor2': [
  358. { required: true, message: '请输入标准化厂房另一楼层', trigger: 'blur' },
  359. ],
  360. 'contractDataB.rentPerSqmFloor2': [
  361. { required: true, message: '请输入该楼层租金(元/㎡/月)', trigger: 'blur' },
  362. ],
  363. 'contractDataB.factoryAnnualRent': [
  364. { required: true, message: '请输入厂房年租金(元)', trigger: 'blur' },
  365. ],
  366. 'contractDataB.supportingRoomRentPerSqm': [
  367. { required: true, message: '请输入配套用房租金(元/㎡/月)', trigger: 'blur' },
  368. ],
  369. 'contractDataB.supportingRoomAnnualRent': [
  370. { required: true, message: '请输入配套用房年租金(元)', trigger: 'blur' },
  371. ],
  372. 'contractDataB.dormSmallRoomRent': [
  373. { required: true, message: '请输入宿舍楼普通单间月租金(元)', trigger: 'blur' },
  374. ],
  375. 'contractDataB.dormLargeRoomRent': [
  376. { required: true, message: '请输入宿舍楼大单间月租金(元)', trigger: 'blur' },
  377. ],
  378. 'contractDataB.dormAnnualRent': [
  379. { required: true, message: '请输入宿舍楼年租金(元)', trigger: 'blur' },
  380. ],
  381. 'contractDataB.totalAnnualRent': [
  382. { required: true, message: '请输入总租金(元)', trigger: 'blur' },
  383. ],
  384. 'contractDataB.propertyFeePerSqm': [
  385. { required: true, message: '请输入标准化厂房和配套用房物业费(元/㎡/月)', trigger: 'blur' },
  386. ],
  387. 'contractDataB.factorySupportingPropertyFee': [
  388. { required: true, message: '请输入标准化厂房和配套用房年物业费(元)', trigger: 'blur' },
  389. ],
  390. 'contractDataB.dormSmallRoomPropertyFee': [
  391. { required: true, message: '请输入宿舍楼普通单间月物业费(元)', trigger: 'blur' },
  392. ],
  393. 'contractDataB.dormLargeRoomPropertyFee': [
  394. { required: true, message: '请输入宿舍楼大单间月物业费(元)', trigger: 'blur' },
  395. ],
  396. 'contractDataB.dormAnnualPropertyFee': [
  397. { required: true, message: '请输入宿舍楼年物业费(元)', trigger: 'blur' },
  398. ],
  399. 'contractDataB.totalAnnualPropertyFee': [
  400. { required: true, message: '请输入年物业管理费(元)', trigger: 'blur' },
  401. ],
  402. 'contractDataB.annualTotalRentAndPropertyFee': [
  403. { required: true, message: '请输入年租金和物业费用总计(元)', trigger: 'blur' },
  404. ],
  405. 'contractDataB.depositAmount': [
  406. { required: true, message: '请输入租赁押金金额(元)', trigger: 'blur' },
  407. ],
  408. // 创新创业基地合同C验证规则 - 所有字段必填
  409. 'contractDataC.lessorName': [
  410. { required: true, message: '请输入出租方(甲方)名称', trigger: 'blur' },
  411. ],
  412. 'contractDataC.lessorLegalRep': [
  413. { required: true, message: '请输入出租方法定代表人', trigger: 'blur' },
  414. ],
  415. 'contractDataC.lessorUniCode': [
  416. { required: true, message: '请输入出租方统一社会信用代码', trigger: 'blur' },
  417. ],
  418. 'contractDataC.lesseeName': [
  419. { required: true, message: '请输入承租方(乙方)名称', trigger: 'blur' },
  420. ],
  421. 'contractDataC.lesseeLegalRep': [
  422. { required: true, message: '请输入承租方法定代表人', trigger: 'blur' },
  423. ],
  424. 'contractDataC.lesseeIdCode': [
  425. { required: true, message: '请输入承租方统一社会信用代码/身份证号', trigger: 'blur' },
  426. ],
  427. 'contractDataC.propertyLocation': [
  428. { required: true, message: '请输入标的物坐落', trigger: 'blur' },
  429. ],
  430. 'contractDataC.rentableArea': [
  431. { required: true, message: '请输入计租面积(平方米)', trigger: 'blur' },
  432. ],
  433. 'contractDataC.usableArea': [
  434. { required: true, message: '请输入使用面积(平方米)', trigger: 'blur' },
  435. ],
  436. 'contractDataC.sharedArea': [
  437. { required: true, message: '请输入公摊面积(平方米)', trigger: 'blur' },
  438. ],
  439. 'contractDataC.propertyUseNature': [
  440. { required: true, message: '请输入标的物使用性质', trigger: 'blur' },
  441. ],
  442. 'contractDataC.storeName': [{ required: true, message: '请输入店铺名称', trigger: 'blur' }],
  443. 'contractDataC.brand': [{ required: true, message: '请输入商品/服务品牌', trigger: 'blur' }],
  444. 'contractDataC.businessScope': [{ required: true, message: '请输入经营范围', trigger: 'blur' }],
  445. 'contractDataC.leaseTermMonths': [
  446. { required: true, message: '请输入租赁期限(个月)', trigger: 'blur' },
  447. ],
  448. 'contractDataC.leaseStartDate': [
  449. { required: true, message: '请输入租赁起始日', trigger: 'blur' },
  450. ],
  451. 'contractDataC.leaseEndDate': [{ required: true, message: '请输入租赁终止日', trigger: 'blur' }],
  452. 'contractDataC.renovationStartDate': [
  453. { required: true, message: '请输入装修期起始日', trigger: 'blur' },
  454. ],
  455. 'contractDataC.renovationEndDate': [
  456. { required: true, message: '请输入装修期终止日', trigger: 'blur' },
  457. ],
  458. 'contractDataC.officialLeaseStartDate': [
  459. { required: true, message: '请输入正式起租时间', trigger: 'blur' },
  460. ],
  461. 'contractDataC.annualRentLower': [
  462. { required: true, message: '请输入年租金(小写)', trigger: 'blur' },
  463. ],
  464. 'contractDataC.annualPropertyFeeLower': [
  465. { required: true, message: '请输入年物业服务费(小写)', trigger: 'blur' },
  466. ],
  467. 'contractDataC.depositAmount': [
  468. { required: true, message: '请输入租赁保证金金额', trigger: 'blur' },
  469. ],
  470. }
  471. const rentalFormRef = ref()
  472. interface BaseResponse {
  473. code: number
  474. msg: string
  475. }
  476. interface HouseInfoVo {
  477. houseName: string | null
  478. address: string | null
  479. status: string | null
  480. rentRange: number | null
  481. tenantInfo: TenantInfo | null
  482. houseInfo: HouseInfo | null
  483. deviceInfo: DeviceInfo[] | null
  484. contractInfo: ContractInfo | null
  485. assetType: string | null
  486. }
  487. interface HouseInfoResponse extends BaseResponse {
  488. data: HouseInfoVo
  489. }
  490. interface AReceiptInfoResponse extends BaseResponse {
  491. data: PageType<AReceiptInfo>
  492. }
  493. interface TenantInfo {
  494. tenantName: string | null
  495. tenantNumber: string | null
  496. tenantIdCard: string | null
  497. tenantInDate: string | null
  498. tenantTime: string | null
  499. tenantRent: string | null
  500. }
  501. interface HouseInfo {
  502. area: string | null
  503. floor: string | null
  504. introduce: string | null
  505. houseType: string | null
  506. }
  507. interface DeviceInfo {
  508. deviceName: string | null
  509. deviceType: string | null
  510. deviceBrand: string | null
  511. deviceNumber: string | null
  512. devicePrice: string | null
  513. }
  514. interface ContractInfo {
  515. contractNumber: string | null
  516. contractDate: string | null
  517. contractTime: string | null
  518. contractExpirationDate: string | null
  519. contractDeposit: string | null
  520. contractStatus: string | null
  521. contractOriginalUrl: string | null
  522. }
  523. const deviceTypes = computed(() => {
  524. const types = new Set(assets.value.map((asset) => asset.deviceType).filter(Boolean))
  525. return Array.from(types)
  526. })
  527. // const openARViewing = () => {
  528. // ElMessage.info('正在启动AR看房功能...')
  529. // }
  530. const filterAssets = () => {
  531. // 筛选逻辑已通过计算属性实现
  532. }
  533. // 新增:预览DOCX文件的函数
  534. const previewDocx = async (url: string) => {
  535. url = MINIO_URL + url
  536. if (!url) {
  537. ElMessage.error('合同文件URL不存在')
  538. return
  539. }
  540. showDocxPreviewDialog.value = true
  541. docxPreviewLoading.value = true
  542. try {
  543. // 获取DOCX文件
  544. const response = await fetch(url)
  545. if (!response.ok) {
  546. throw new Error('无法获取合同文件')
  547. }
  548. const arrayBuffer = await response.arrayBuffer()
  549. // 等待DOM更新
  550. await nextTick()
  551. if (docxPreviewContainer.value) {
  552. // 清空容器
  553. docxPreviewContainer.value.innerHTML = ''
  554. // 渲染DOCX内容
  555. await renderAsync(arrayBuffer, docxPreviewContainer.value, undefined, {
  556. className: 'docx-wrapper',
  557. inWrapper: true,
  558. ignoreWidth: false,
  559. ignoreHeight: false,
  560. ignoreFonts: false,
  561. breakPages: true,
  562. ignoreLastRenderedPageBreak: true,
  563. experimental: false,
  564. trimXmlDeclaration: true,
  565. useBase64URL: false,
  566. renderHeaders: true,
  567. renderFooters: true,
  568. renderFootnotes: true,
  569. renderEndnotes: true,
  570. debug: false,
  571. })
  572. }
  573. } catch (error) {
  574. console.error('预览DOCX文件失败:', error)
  575. ElMessage.error('预览合同文件失败,请稍后重试')
  576. showDocxPreviewDialog.value = false
  577. } finally {
  578. docxPreviewLoading.value = false
  579. }
  580. }
  581. // 新增:关闭DOCX预览对话框
  582. const closeDocxPreview = () => {
  583. showDocxPreviewDialog.value = false
  584. if (docxPreviewContainer.value) {
  585. docxPreviewContainer.value.innerHTML = ''
  586. }
  587. }
  588. const getValidationFields = () => {
  589. const assetType = propertyInfo.value.assetType
  590. if (assetType === '公租房') {
  591. return [
  592. 'contractDataA.tenantName',
  593. 'contractDataA.landlordName',
  594. 'contractDataA.tenantTimeStart',
  595. 'contractDataA.tenantTime',
  596. 'contractDataA.tenantTimeEnd',
  597. 'contractDataA.tenantRent',
  598. 'contractDataA.tenantDeposit',
  599. 'contractDataA.tenantDepositAmount',
  600. ]
  601. } else if (assetType === '厂房') {
  602. return [
  603. 'contractDataB.purpose',
  604. 'contractDataB.landlordName',
  605. 'contractDataB.landlordUniCode',
  606. 'contractDataB.landlordLegalRepresentative',
  607. 'contractDataB.landlordDuty',
  608. 'contractDataB.tenantName',
  609. 'contractDataB.tenantUniCode',
  610. 'contractDataB.tenantLegalRepresentative',
  611. 'contractDataB.tenantDuty',
  612. 'contractDataB.who',
  613. 'contractDataB.whatTime',
  614. 'contractDataB.title',
  615. 'contractDataB.supportingRoomArea',
  616. 'contractDataB.officeArea',
  617. 'contractDataB.canteenArea',
  618. 'contractDataB.totalLeasedArea',
  619. 'contractDataB.dormTotalRooms',
  620. 'contractDataB.dormSmallRooms',
  621. 'contractDataB.dormLargeRooms',
  622. 'contractDataB.deliveryDate',
  623. 'contractDataB.productionProject',
  624. 'contractDataB.leaseTermYears',
  625. 'contractDataB.leaseStartDate',
  626. 'contractDataB.leaseEndDate',
  627. 'contractDataB.renewNoticeMonths',
  628. 'contractDataB.factorySpecificFloor1',
  629. 'contractDataB.rentPerSqmFloor1',
  630. 'contractDataB.factorySpecificFloor2',
  631. 'contractDataB.rentPerSqmFloor2',
  632. 'contractDataB.factoryAnnualRent',
  633. 'contractDataB.supportingRoomRentPerSqm',
  634. 'contractDataB.supportingRoomAnnualRent',
  635. 'contractDataB.dormSmallRoomRent',
  636. 'contractDataB.dormLargeRoomRent',
  637. 'contractDataB.dormAnnualRent',
  638. 'contractDataB.totalAnnualRent',
  639. 'contractDataB.propertyFeePerSqm',
  640. 'contractDataB.factorySupportingPropertyFee',
  641. 'contractDataB.dormSmallRoomPropertyFee',
  642. 'contractDataB.dormLargeRoomPropertyFee',
  643. 'contractDataB.dormAnnualPropertyFee',
  644. 'contractDataB.totalAnnualPropertyFee',
  645. 'contractDataB.annualTotalRentAndPropertyFee',
  646. 'contractDataB.depositAmount',
  647. ]
  648. } else if (assetType === '创新创业基地') {
  649. return [
  650. 'contractDataC.lessorName',
  651. 'contractDataC.lessorLegalRep',
  652. 'contractDataC.lessorUniCode',
  653. 'contractDataC.lesseeName',
  654. 'contractDataC.lesseeLegalRep',
  655. 'contractDataC.lesseeIdCode',
  656. 'contractDataC.propertyLocation',
  657. 'contractDataC.rentableArea',
  658. 'contractDataC.usableArea',
  659. 'contractDataC.sharedArea',
  660. 'contractDataC.propertyUseNature',
  661. 'contractDataC.storeName',
  662. 'contractDataC.brand',
  663. 'contractDataC.businessScope',
  664. 'contractDataC.leaseTermMonths',
  665. 'contractDataC.leaseStartDate',
  666. 'contractDataC.leaseEndDate',
  667. 'contractDataC.renovationStartDate',
  668. 'contractDataC.renovationEndDate',
  669. 'contractDataC.officialLeaseStartDate',
  670. 'contractDataC.annualRentLower',
  671. 'contractDataC.annualPropertyFeeLower',
  672. 'contractDataC.depositAmount',
  673. ]
  674. }
  675. return []
  676. }
  677. const nextStep = async () => {
  678. if (currentStep.value === 0) {
  679. try {
  680. await rentalFormRef.value.validateField([
  681. 'rentalInfo.rentalName',
  682. 'rentalInfo.rentalPhone',
  683. 'rentalInfo.rentalIdCard',
  684. 'rentalInfo.rentalTimeStart',
  685. 'rentalInfo.rentalTime',
  686. 'rentalInfo.rentalRect',
  687. ])
  688. currentStep.value++
  689. } catch (error) {
  690. console.log('第一步验证失败:', error)
  691. }
  692. } else if (currentStep.value === 1) {
  693. try {
  694. const fieldsToValidate = getValidationFields()
  695. await rentalFormRef.value.validateField(fieldsToValidate)
  696. currentStep.value++
  697. } catch (error) {
  698. console.log('第二步验证失败:', error)
  699. }
  700. }
  701. }
  702. const handleCloseRentalDialog = () => {
  703. showRentalDialog.value = false
  704. currentStep.value = 0
  705. Object.assign(rentalForm.rentalInfo, {
  706. rentalName: '',
  707. rentalPhone: '',
  708. rentalIdCard: '',
  709. rentalTimeStart: '',
  710. rentalTime: '',
  711. rentalRect: '',
  712. })
  713. Object.assign(rentalForm.contractDataA, {
  714. landlordName: '',
  715. tenantDeposit: '',
  716. tenantDepositAmount: '',
  717. tenantName: '',
  718. tenantRent: '',
  719. tenantTime: '',
  720. tenantTimeEnd: '',
  721. tenantTimeStart: '',
  722. })
  723. // 重置contractDataB的所有字段
  724. Object.assign(rentalForm.contractDataB, {
  725. annualTotalRentAndPropertyFee: '',
  726. canteenArea: '',
  727. deliveryDate: '',
  728. depositAmount: '',
  729. dormAnnualPropertyFee: '',
  730. dormAnnualRent: '',
  731. dormLargeRoomPropertyFee: '',
  732. dormLargeRoomRent: '',
  733. dormLargeRooms: '',
  734. dormSmallRoomPropertyFee: '',
  735. dormSmallRoomRent: '',
  736. dormSmallRooms: '',
  737. dormTotalRooms: '',
  738. factoryAnnualRent: '',
  739. factorySpecificFloor1: '',
  740. factorySpecificFloor2: '',
  741. factorySupportingPropertyFee: '',
  742. landlordDuty: '',
  743. landlordLegalRepresentative: '',
  744. landlordName: '',
  745. landlordUniCode: '',
  746. leaseEndDate: '',
  747. leaseStartDate: '',
  748. leaseTermYears: '',
  749. officeArea: '',
  750. productionProject: '',
  751. propertyFeePerSqm: '',
  752. purpose: '',
  753. renewNoticeMonths: '',
  754. rentPerSqmFloor1: '',
  755. rentPerSqmFloor2: '',
  756. supportingRoomAnnualRent: '',
  757. supportingRoomArea: '',
  758. supportingRoomRentPerSqm: '',
  759. tenantDuty: '',
  760. tenantLegalRepresentative: '',
  761. tenantName: '',
  762. tenantUniCode: '',
  763. title: '',
  764. totalAnnualPropertyFee: '',
  765. totalAnnualRent: '',
  766. totalLeasedArea: '',
  767. whatTime: '',
  768. who: '',
  769. })
  770. // 重置contractDataC的所有字段
  771. Object.assign(rentalForm.contractDataC, {
  772. annualPropertyFeeLower: '',
  773. annualRentLower: '',
  774. brand: '',
  775. businessScope: '',
  776. depositAmount: '',
  777. leaseEndDate: '',
  778. leaseStartDate: '',
  779. leaseTermMonths: '',
  780. lesseeIdCode: '',
  781. lesseeLegalRep: '',
  782. lesseeName: '',
  783. lessorLegalRep: '',
  784. lessorName: '',
  785. lessorUniCode: '',
  786. officialLeaseStartDate: '',
  787. propertyLocation: '',
  788. propertyUseNature: '',
  789. renovationEndDate: '',
  790. renovationStartDate: '',
  791. rentableArea: '',
  792. sharedArea: '',
  793. storeName: '',
  794. usableArea: '',
  795. })
  796. }
  797. const submitRental = async () => {
  798. submitting.value = true
  799. try {
  800. if (propertyInfo.value.assetType === '公租房') {
  801. rentalForm.contractData = rentalForm.contractDataA
  802. } else if (propertyInfo.value.assetType === '厂房') {
  803. rentalForm.contractData = rentalForm.contractDataB
  804. } else if (propertyInfo.value.assetType === '创新创业基地') {
  805. rentalForm.contractData = rentalForm.contractDataC
  806. }
  807. const res = await clientPost<typeof rentalForm, BaseResponse>(
  808. '/acontractInfo/signContract',
  809. rentalForm,
  810. )
  811. if (res.code !== 200) {
  812. ElMessage.error(res.msg)
  813. return
  814. }
  815. ElMessage.success(res.msg)
  816. handleCloseRentalDialog()
  817. await getData()
  818. // 新增:签订合同成功后自动预览DOCX
  819. if (contractInfo.value?.contractOriginalUrl) {
  820. setTimeout(() => {
  821. previewDocx(contractInfo.value!.contractOriginalUrl!)
  822. }, 500) // 延迟500ms确保数据更新完成
  823. }
  824. } catch (error) {
  825. console.error(error)
  826. ElMessage.error('出租失败,请重试')
  827. } finally {
  828. submitting.value = false
  829. }
  830. }
  831. const confirmTerminate = async () => {
  832. terminating.value = true
  833. try {
  834. const res = await clientGet<
  835. {
  836. houseId: string
  837. },
  838. BaseResponse
  839. >('/acontractInfo/returnRent', {
  840. params: {
  841. houseId: propertyInfo.value.id,
  842. },
  843. })
  844. if (res.code !== 200) {
  845. ElMessage.error(res.msg)
  846. return
  847. }
  848. ElMessage.success(res.msg)
  849. showTerminateDialog.value = false
  850. await getData()
  851. } catch (error) {
  852. console.error(error)
  853. ElMessage.error('退租失败,请重试')
  854. } finally {
  855. terminating.value = false
  856. }
  857. }
  858. const getReceiptData = async (contractNumber) => {
  859. loading.value = true
  860. try {
  861. const res = await clientGet<
  862. {
  863. receiptNumber: string
  864. payer: string
  865. paymentMethod: string
  866. contractNumber: string
  867. },
  868. AReceiptInfoResponse
  869. >('/AReceiptInfo//findByPageWithContract', {
  870. params: {
  871. pageNum: 1,
  872. pageSize: 10000,
  873. contractNumber: contractNumber,
  874. },
  875. })
  876. if (res.code !== 200) {
  877. ElMessage.error(res.msg)
  878. return
  879. }
  880. receiptData.value = res.data.records || {}
  881. } catch (error) {
  882. console.error(error)
  883. ElMessage.error('获取数据失败')
  884. } finally {
  885. loading.value = false
  886. }
  887. }
  888. const getData = async () => {
  889. try {
  890. loading.value = true
  891. const res = await clientGet<
  892. {
  893. houseId: string
  894. },
  895. HouseInfoResponse
  896. >('/asimplifiedHouseInfo/getHouseDetailInfo', {
  897. params: {
  898. houseId: route.query.houseId as string,
  899. },
  900. })
  901. if (res.code !== 200) {
  902. ElMessage.error(res.msg)
  903. return
  904. }
  905. const data = res.data
  906. // 新增:获取收据信息
  907. await getReceiptData(data.contractInfo?.contractNumber || '')
  908. console.log('接口返回数据:', data)
  909. propertyInfo.value = {
  910. id: route.query.houseId as string,
  911. buildingNumber: data.houseName || '',
  912. priceRange: data.rentRange ? `${data.rentRange}` : '',
  913. address: data.address || '',
  914. area: data.houseInfo?.area || '',
  915. status: data.status || '未租',
  916. floor: data.houseInfo?.floor || '',
  917. facilities: data.houseInfo?.introduce || '',
  918. assetType: data.assetType || '',
  919. }
  920. if (data.houseInfo) {
  921. basicInfo.value = {
  922. buildYear: '',
  923. orientation: '',
  924. houseType: data.houseInfo.houseType || '',
  925. }
  926. }
  927. if (data.deviceInfo && Array.isArray(data.deviceInfo)) {
  928. assets.value = data.deviceInfo.map((device) => ({
  929. deviceName: device.deviceName,
  930. deviceType: device.deviceType,
  931. deviceBrand: device.deviceBrand,
  932. deviceNumber: device.deviceNumber,
  933. devicePrice: device.devicePrice,
  934. }))
  935. } else {
  936. assets.value = []
  937. }
  938. if (data.status === '已租' && data.tenantInfo) {
  939. tenantInfo.value = {
  940. tenantName: data.tenantInfo.tenantName,
  941. tenantNumber: data.tenantInfo.tenantNumber,
  942. tenantIdCard: data.tenantInfo.tenantIdCard,
  943. tenantInDate: data.tenantInfo.tenantInDate,
  944. tenantTime: data.tenantInfo.tenantTime,
  945. tenantRent: data.tenantInfo.tenantRent,
  946. }
  947. } else {
  948. tenantInfo.value = null
  949. }
  950. if (data.status === '已租' && data.contractInfo) {
  951. contractInfo.value = {
  952. contractNumber: data.contractInfo.contractNumber,
  953. contractDate: data.contractInfo.contractDate,
  954. contractTime: data.contractInfo.contractTime,
  955. contractExpirationDate: data.contractInfo.contractExpirationDate,
  956. contractDeposit: data.contractInfo.contractDeposit,
  957. contractStatus: data.contractInfo.contractStatus,
  958. contractOriginalUrl: data.contractInfo.contractOriginalUrl,
  959. }
  960. } else {
  961. contractInfo.value = null
  962. }
  963. } catch (error) {
  964. console.error('获取房屋详情失败:', error)
  965. ElMessage.error('获取房屋详情失败')
  966. } finally {
  967. loading.value = false
  968. }
  969. }
  970. const calculateEndDate = computed(() => {
  971. if (!rentalForm.rentalInfo.rentalTimeStart || !rentalForm.rentalInfo.rentalTime) {
  972. return ''
  973. }
  974. const startDate = new Date(rentalForm.rentalInfo.rentalTimeStart)
  975. if (isNaN(startDate.getTime())) {
  976. return ''
  977. }
  978. // 创建结束日期副本
  979. const endDate = new Date(startDate)
  980. // 添加月数
  981. endDate.setMonth(endDate.getMonth() + parseInt(rentalForm.rentalInfo.rentalTime))
  982. // 减去一天,得到租期结束日期
  983. endDate.setDate(endDate.getDate() - 1)
  984. // 格式化为 YYYY-MM-DD
  985. const year = endDate.getFullYear()
  986. const month = String(endDate.getMonth() + 1).padStart(2, '0')
  987. const day = String(endDate.getDate()).padStart(2, '0')
  988. return `${year}-${month}-${day}`
  989. })
  990. watch(
  991. () => rentalForm.rentalInfo.rentalTimeStart,
  992. (newVal) => {
  993. if (newVal) {
  994. rentalForm.contractDataA.tenantTimeStart = newVal
  995. }
  996. },
  997. { immediate: true },
  998. )
  999. watch(
  1000. () => rentalForm.rentalInfo.rentalTime,
  1001. (newVal) => {
  1002. if (newVal) {
  1003. rentalForm.contractDataA.tenantTime = newVal
  1004. // 同时更新结束时间
  1005. updateContractEndDate()
  1006. }
  1007. },
  1008. { immediate: true },
  1009. )
  1010. watch(
  1011. () => rentalForm.rentalInfo.rentalRect,
  1012. (newVal) => {
  1013. if (newVal) {
  1014. rentalForm.contractDataA.tenantRent = newVal
  1015. }
  1016. },
  1017. { immediate: true },
  1018. )
  1019. // 添加一个方法来更新合同结束日期
  1020. const updateContractEndDate = () => {
  1021. if (rentalForm.contractDataA.tenantTimeStart && rentalForm.contractDataA.tenantTime) {
  1022. const startDate = new Date(rentalForm.contractDataA.tenantTimeStart)
  1023. if (!isNaN(startDate.getTime())) {
  1024. const endDate = new Date(startDate)
  1025. endDate.setMonth(
  1026. endDate.getMonth() + parseInt(rentalForm.contractDataA.tenantTime.toString()),
  1027. )
  1028. endDate.setDate(endDate.getDate() - 1)
  1029. rentalForm.contractDataA.tenantTimeEnd = formatDate(endDate)
  1030. }
  1031. }
  1032. }
  1033. // 添加日期格式化函数
  1034. const formatDate = (date: Date): string => {
  1035. const year = date.getFullYear()
  1036. const month = String(date.getMonth() + 1).padStart(2, '0')
  1037. const day = String(date.getDate()).padStart(2, '0')
  1038. return `${year}-${month}-${day}`
  1039. }
  1040. // 监听合同开始时间和租期的变化,自动更新结束时间
  1041. watch(
  1042. [() => rentalForm.contractDataA.tenantTimeStart, () => rentalForm.contractDataA.tenantTime],
  1043. () => {
  1044. updateContractEndDate()
  1045. },
  1046. )
  1047. onMounted(() => {
  1048. getData()
  1049. })
  1050. </script>
  1051. <template>
  1052. <el-container class="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100">
  1053. <el-main class="h-full" v-loading="loading">
  1054. <!-- <div class="py-0 has-footer">-->
  1055. <el-button type="primary" @click="router.back">
  1056. <el-icon class="mr-1"><ArrowLeft /></el-icon>
  1057. 返回
  1058. </el-button>
  1059. <!-- </div>-->
  1060. <div
  1061. class="bg-gradient-to-r from-blue-600 to-purple-700 text-white py-4 px-8 my-4 rounded-2xl"
  1062. >
  1063. <div class="w-full">
  1064. <div class="flex items-center justify-between">
  1065. <div>
  1066. <h1 class="text-3xl font-extrabold mb-2 my-0">{{ propertyInfo.buildingNumber }}</h1>
  1067. <p class="text-base opacity-90">
  1068. <el-icon class="mr-2 text-blue-500"><MapPin /></el-icon>
  1069. <span>{{ propertyInfo.address }}</span>
  1070. </p>
  1071. </div>
  1072. <div class="text-right flex items-center gap-6">
  1073. <div class="relative">
  1074. <!-- <button-->
  1075. <!-- @click="openARViewing"-->
  1076. <!-- class="ar-viewing-btn group relative overflow-hidden bg-gradient-to-r from-pink-500 via-purple-500 to-indigo-500 text-white px-6 py-3 rounded-2xl font-semibold text-sm shadow-2xl transform transition-all duration-300 hover:scale-105 hover:shadow-pink-500/25 active:scale-95"-->
  1077. <!-- >-->
  1078. <!-- <div-->
  1079. <!-- class="absolute inset-0 bg-gradient-to-r from-pink-600 via-purple-600 to-indigo-600 opacity-0 group-hover:opacity-100 transition-opacity duration-300"-->
  1080. <!-- ></div>-->
  1081. <!-- <div class="relative flex items-center gap-2">-->
  1082. <!-- <div class="w-5 h-5 relative">-->
  1083. <!-- <div-->
  1084. <!-- class="absolute inset-0 bg-white rounded-full opacity-20 animate-ping"-->
  1085. <!-- ></div>-->
  1086. <!-- <el-icon class="relative z-10"><Camera /></el-icon>-->
  1087. <!-- </div>-->
  1088. <!-- <span class="relative z-10">AR看房</span>-->
  1089. <!-- </div>-->
  1090. <!-- <div-->
  1091. <!-- class="absolute inset-0 bg-gradient-to-r from-transparent via-white/20 to-transparent -skew-x-12 -translate-x-full group-hover:translate-x-full transition-transform duration-1000"-->
  1092. <!-- ></div>-->
  1093. <!-- </button>-->
  1094. <div
  1095. class="absolute -inset-1 bg-gradient-to-r from-pink-500 via-purple-500 to-indigo-500 rounded-2xl blur opacity-30 group-hover:opacity-50 transition-opacity duration-300 -z-10"
  1096. ></div>
  1097. </div>
  1098. <div>
  1099. <el-tag
  1100. :type="propertyInfo.status === '未租' ? 'success' : 'warning'"
  1101. size="large"
  1102. class="mb-2"
  1103. >
  1104. {{ propertyInfo.status }}
  1105. </el-tag>
  1106. <div class="text-xl font-bold">{{ propertyInfo.priceRange }} 元/月</div>
  1107. </div>
  1108. </div>
  1109. </div>
  1110. </div>
  1111. </div>
  1112. <div class="py-0">
  1113. <div class="w-full">
  1114. <el-card
  1115. v-if="propertyInfo.status === '已租' && tenantInfo"
  1116. class="mb-6 shadow-lg rounded-2xl border-0"
  1117. >
  1118. <template #header>
  1119. <div class="flex items-center">
  1120. <el-icon class="mr-2 text-blue-500"><User /></el-icon>
  1121. <span class="text-lg font-semibold">租户信息</span>
  1122. </div>
  1123. </template>
  1124. <el-row :gutter="24">
  1125. <el-col :xs="24" :sm="12" :md="8">
  1126. <div class="mb-4">
  1127. <label class="block text-sm font-medium text-gray-700 mb-1">租户姓名</label>
  1128. <div class="text-lg font-semibold text-gray-800">{{ tenantInfo.tenantName }}</div>
  1129. </div>
  1130. </el-col>
  1131. <el-col :xs="24" :sm="12" :md="8">
  1132. <div class="mb-4">
  1133. <label class="block text-sm font-medium text-gray-700 mb-1">联系电话</label>
  1134. <div class="text-lg font-semibold text-gray-800">
  1135. {{ tenantInfo.tenantNumber }}
  1136. </div>
  1137. </div>
  1138. </el-col>
  1139. <el-col :xs="24" :sm="12" :md="8">
  1140. <div class="mb-4">
  1141. <label class="block text-sm font-medium text-gray-700 mb-1">身份证号</label>
  1142. <div class="text-lg font-semibold text-gray-800">
  1143. {{ tenantInfo.tenantIdCard }}
  1144. </div>
  1145. </div>
  1146. </el-col>
  1147. <el-col :xs="24" :sm="12" :md="8">
  1148. <div class="mb-4">
  1149. <label class="block text-sm font-medium text-gray-700 mb-1">入住时间</label>
  1150. <div class="text-lg font-semibold text-gray-800">
  1151. {{ tenantInfo.tenantInDate }}
  1152. </div>
  1153. </div>
  1154. </el-col>
  1155. <el-col :xs="24" :sm="12" :md="8">
  1156. <div class="mb-4">
  1157. <label class="block text-sm font-medium text-gray-700 mb-1">租期</label>
  1158. <div class="text-lg font-semibold text-gray-800">{{ tenantInfo.tenantTime }}</div>
  1159. </div>
  1160. </el-col>
  1161. <el-col :xs="24" :sm="12" :md="8">
  1162. <div class="mb-4">
  1163. <label class="block text-sm font-medium text-gray-700 mb-1">月租金</label>
  1164. <div class="text-lg font-semibold text-blue-600">
  1165. {{ tenantInfo.tenantRent }} 元
  1166. </div>
  1167. </div>
  1168. </el-col>
  1169. </el-row>
  1170. </el-card>
  1171. <el-card class="mb-6 shadow-lg rounded-2xl border-0">
  1172. <template #header>
  1173. <div class="flex items-center">
  1174. <el-icon class="mr-2 text-green-500"><Home /></el-icon>
  1175. <span class="text-lg font-semibold">房屋基本信息</span>
  1176. </div>
  1177. </template>
  1178. <el-row :gutter="24">
  1179. <el-col :xs="24" :sm="12" :md="6">
  1180. <div class="mb-4">
  1181. <label class="block text-sm font-medium text-gray-700 mb-1">建筑面积</label>
  1182. <div class="text-lg font-semibold text-gray-800">{{ propertyInfo.area }} ㎡</div>
  1183. </div>
  1184. </el-col>
  1185. <el-col :xs="24" :sm="12" :md="6" v-if="propertyInfo.floor">
  1186. <div class="mb-4">
  1187. <label class="block text-sm font-medium text-gray-700 mb-1">所在楼层</label>
  1188. <div class="text-lg font-semibold text-gray-800">{{ propertyInfo.floor }}</div>
  1189. </div>
  1190. </el-col>
  1191. <el-col :xs="24" :sm="12" :md="6">
  1192. <div class="mb-4">
  1193. <label class="block text-sm font-medium text-gray-700 mb-1">介绍</label>
  1194. <div class="text-lg font-semibold text-gray-800">
  1195. {{ propertyInfo.facilities }}
  1196. </div>
  1197. </div>
  1198. </el-col>
  1199. <el-col :xs="24" :sm="12" :md="6" v-if="basicInfo.houseType">
  1200. <div class="mb-4">
  1201. <label class="block text-sm font-medium text-gray-700 mb-1">房屋类型</label>
  1202. <div class="text-lg font-semibold text-gray-800">{{ basicInfo.houseType }}</div>
  1203. </div>
  1204. </el-col>
  1205. </el-row>
  1206. </el-card>
  1207. <el-card class="mb-6 shadow-lg rounded-2xl border-0">
  1208. <template #header>
  1209. <div class="flex items-center justify-between">
  1210. <div class="flex items-center">
  1211. <el-icon class="mr-2 text-purple-500"><Cpu /></el-icon>
  1212. <span class="text-lg font-semibold">房屋设备资产</span>
  1213. </div>
  1214. <div class="flex items-center gap-4">
  1215. <el-select
  1216. v-model="assetFilter.category"
  1217. placeholder="设备类型"
  1218. size="small"
  1219. style="width: 120px"
  1220. @change="filterAssets"
  1221. >
  1222. <el-option label="全部" value=""></el-option>
  1223. <el-option
  1224. v-for="type in deviceTypes"
  1225. :key="type"
  1226. :label="type"
  1227. :value="type"
  1228. ></el-option>
  1229. </el-select>
  1230. </div>
  1231. </div>
  1232. </template>
  1233. <el-row :gutter="16">
  1234. <el-col
  1235. :xs="24"
  1236. :sm="12"
  1237. :md="8"
  1238. :lg="6"
  1239. v-for="(asset, index) in filteredAssets"
  1240. :key="index"
  1241. class="mb-4"
  1242. >
  1243. <div
  1244. class="border border-gray-200 rounded-lg px-4 py-2 hover:shadow-md transition-shadow bg-white"
  1245. >
  1246. <div class="mb-3">
  1247. <span class="font-semibold text-gray-800 text-lg">{{ asset.deviceName }}</span>
  1248. <p class="text-sm text-gray-500">{{ asset.deviceType }}</p>
  1249. </div>
  1250. <div class="text-sm text-gray-600 space-y-1">
  1251. <p><strong>品牌:</strong>{{ asset.deviceBrand }}</p>
  1252. <p><strong>型号:</strong>{{ asset.deviceNumber }}</p>
  1253. <p>
  1254. <strong>价值:</strong>
  1255. <span class="text-green-600 font-semibold">{{ asset.devicePrice }} 元</span>
  1256. </p>
  1257. </div>
  1258. </div>
  1259. </el-col>
  1260. </el-row>
  1261. <div v-if="filteredAssets.length === 0" class="text-center py-8 text-gray-500">
  1262. 暂无符合条件的设备资产
  1263. </div>
  1264. </el-card>
  1265. <el-card
  1266. v-if="propertyInfo.status === '已租' && contractInfo"
  1267. class="mb-6 shadow-lg rounded-2xl border-0"
  1268. >
  1269. <template #header>
  1270. <div class="flex items-center justify-between">
  1271. <div class="flex items-center">
  1272. <el-icon class="mr-2 text-purple-500"><FileText /></el-icon>
  1273. <span class="text-lg font-semibold">合同信息</span>
  1274. </div>
  1275. <!-- 新增:预览合同按钮 -->
  1276. <el-button
  1277. v-if="contractInfo.contractOriginalUrl"
  1278. type="primary"
  1279. size="small"
  1280. @click="previewDocx(contractInfo.contractOriginalUrl)"
  1281. class="flex items-center gap-1"
  1282. >
  1283. <el-icon><Eye /></el-icon>
  1284. 预览合同
  1285. </el-button>
  1286. </div>
  1287. </template>
  1288. <el-row :gutter="24">
  1289. <el-col :xs="24" :sm="12" :md="8">
  1290. <div class="mb-4">
  1291. <label class="block text-sm font-medium text-gray-700 mb-1">合同编号</label>
  1292. <div class="text-lg font-semibold text-gray-800">
  1293. {{ contractInfo.contractNumber }}
  1294. </div>
  1295. </div>
  1296. </el-col>
  1297. <el-col :xs="24" :sm="12" :md="8">
  1298. <div class="mb-4">
  1299. <label class="block text-sm font-medium text-gray-700 mb-1">签约日期</label>
  1300. <div class="text-lg font-semibold text-gray-800">
  1301. {{ contractInfo.contractDate }}
  1302. </div>
  1303. </div>
  1304. </el-col>
  1305. <el-col :xs="24" :sm="12" :md="8">
  1306. <div class="mb-4">
  1307. <label class="block text-sm font-medium text-gray-700 mb-1">合同期限</label>
  1308. <div class="text-lg font-semibold text-gray-800">
  1309. {{ contractInfo.contractTime }}
  1310. </div>
  1311. </div>
  1312. </el-col>
  1313. <el-col :xs="24" :sm="12" :md="8">
  1314. <div class="mb-4">
  1315. <label class="block text-sm font-medium text-gray-700 mb-1">到期日期</label>
  1316. <div class="text-lg font-semibold text-gray-800">
  1317. {{ contractInfo.contractExpirationDate }}
  1318. </div>
  1319. </div>
  1320. </el-col>
  1321. <el-col :xs="24" :sm="12" :md="8">
  1322. <div class="mb-4">
  1323. <label class="block text-sm font-medium text-gray-700 mb-1">押金</label>
  1324. <div class="text-lg font-semibold text-gray-800">
  1325. {{ contractInfo.contractDeposit }} 元
  1326. </div>
  1327. </div>
  1328. </el-col>
  1329. <el-col :xs="24" :sm="12" :md="8">
  1330. <div class="mb-4">
  1331. <label class="block text-sm font-medium text-gray-700 mb-1">合同状态</label>
  1332. <div class="text-lg font-semibold text-gray-800">
  1333. {{ contractInfo.contractStatus }}
  1334. </div>
  1335. </div>
  1336. </el-col>
  1337. </el-row>
  1338. </el-card>
  1339. <el-card
  1340. v-if="propertyInfo.status === '已租' && tenantInfo"
  1341. class="mb-6 shadow-lg rounded-2xl border-0"
  1342. >
  1343. <template #header>
  1344. <div class="flex items-center">
  1345. <el-icon class="mr-2 text-blue-500"><BookText /></el-icon>
  1346. <span class="text-lg font-semibold">收据信息</span>
  1347. </div>
  1348. </template>
  1349. <el-table :data="receiptData" v-loading="loading" stripe class="w-full">
  1350. <el-table-column type="index" label="序号" min-width="80" />
  1351. <el-table-column prop="startDate" label="开始时间" min-width="80" />
  1352. <el-table-column prop="endDate" label="结束时间" min-width="80" />
  1353. <el-table-column prop="receiptReason" label="收款事由" />
  1354. </el-table>
  1355. </el-card>
  1356. <div class="flex justify-center gap-4">
  1357. <el-button
  1358. v-if="propertyInfo.status === '空闲'"
  1359. type="primary"
  1360. size="large"
  1361. @click="showRentalDialog = true"
  1362. class="px-8 py-3"
  1363. >
  1364. <el-icon class="mr-2"><Plus /></el-icon>
  1365. 出租房屋
  1366. </el-button>
  1367. <el-button
  1368. v-if="propertyInfo.status === '已租'"
  1369. type="danger"
  1370. size="large"
  1371. @click="showTerminateDialog = true"
  1372. class="px-8 py-3"
  1373. >
  1374. <el-icon class="mr-2"><X /></el-icon>
  1375. 退租房屋
  1376. </el-button>
  1377. </div>
  1378. </div>
  1379. </div>
  1380. </el-main>
  1381. <!-- 新增:DOCX预览对话框 -->
  1382. <el-dialog
  1383. v-model="showDocxPreviewDialog"
  1384. title="合同预览"
  1385. width="70%"
  1386. :before-close="closeDocxPreview"
  1387. class="docx-preview-dialog"
  1388. >
  1389. <div
  1390. v-loading="docxPreviewLoading"
  1391. element-loading-text="正在加载合同文件..."
  1392. class="docx-preview-wrapper"
  1393. >
  1394. <div ref="docxPreviewContainer" class="docx-container" v-show="!docxPreviewLoading"></div>
  1395. </div>
  1396. <template #footer>
  1397. <div class="flex justify-end">
  1398. <el-button @click="closeDocxPreview">关闭</el-button>
  1399. </div>
  1400. </template>
  1401. </el-dialog>
  1402. <el-dialog
  1403. v-model="showRentalDialog"
  1404. title="房屋出租"
  1405. width="800px"
  1406. :before-close="handleCloseRentalDialog"
  1407. >
  1408. <el-form :model="rentalForm" :rules="rentalRules" ref="rentalFormRef" label-width="120px">
  1409. <el-steps :active="currentStep" finish-status="success" class="mb-8">
  1410. <el-step title="租户信息" />
  1411. <el-step title="合同条款" />
  1412. <el-step title="确认提交" />
  1413. </el-steps>
  1414. <div v-show="currentStep === 0">
  1415. <el-form-item label="租户姓名" prop="rentalInfo.rentalName">
  1416. <el-input v-model="rentalForm.rentalInfo.rentalName" placeholder="请输入租户姓名" />
  1417. </el-form-item>
  1418. <el-form-item label="联系电话" prop="rentalInfo.rentalPhone">
  1419. <el-input v-model="rentalForm.rentalInfo.rentalPhone" placeholder="请输入联系电话" />
  1420. </el-form-item>
  1421. <el-form-item label="身份证号" prop="rentalInfo.rentalIdCard">
  1422. <el-input v-model="rentalForm.rentalInfo.rentalIdCard" placeholder="请输入身份证号" />
  1423. </el-form-item>
  1424. <el-form-item label="租期开始时间" prop="rentalInfo.rentalTimeStart">
  1425. <el-date-picker
  1426. type="date"
  1427. format="YYYY-MM-DD"
  1428. value-format="YYYY-MM-DD"
  1429. clearable
  1430. v-model="rentalForm.rentalInfo.rentalTimeStart"
  1431. placeholder="请输入租期开始时间"
  1432. />
  1433. </el-form-item>
  1434. <el-form-item label="租期(月)" prop="rentalInfo.rentalTime">
  1435. <el-input-number
  1436. :max="500"
  1437. :min="1"
  1438. v-model="rentalForm.rentalInfo.rentalTime"
  1439. placeholder="请输入租期"
  1440. />
  1441. </el-form-item>
  1442. <!-- 展示一个不可编辑的根据上方计算出的租期结束时间-->
  1443. <el-form-item label="租期结束时间" v-if="rentalForm.rentalInfo.rentalTimeStart">
  1444. <el-input
  1445. :value="calculateEndDate"
  1446. placeholder="根据开始时间和租期自动计算"
  1447. readonly
  1448. disabled
  1449. />
  1450. </el-form-item>
  1451. <el-form-item label="租金" prop="rentalInfo.rentalRect">
  1452. <el-input-number
  1453. :min="0"
  1454. :max="1000000"
  1455. v-model="rentalForm.rentalInfo.rentalRect"
  1456. placeholder="请输入租金"
  1457. />
  1458. </el-form-item>
  1459. </div>
  1460. <div v-show="currentStep === 1">
  1461. <div v-if="propertyInfo.assetType === '公租房'">
  1462. <el-form-item label="租方" prop="contractDataA.tenantName">
  1463. <el-input v-model="rentalForm.contractDataA.tenantName" placeholder="请输入租方" />
  1464. </el-form-item>
  1465. <el-form-item label="房东" prop="contractDataA.landlordName">
  1466. <el-input v-model="rentalForm.contractDataA.landlordName" placeholder="请输入房东" />
  1467. </el-form-item>
  1468. <el-form-item label="租期开始时间" prop="contractDataA.tenantTimeStart">
  1469. <el-date-picker
  1470. type="date"
  1471. format="YYYY-MM-DD"
  1472. value-format="YYYY-MM-DD"
  1473. clearable
  1474. v-model="rentalForm.contractDataA.tenantTimeStart"
  1475. placeholder="请输入租期开始时间"
  1476. :disabled="currentStep > 0"
  1477. />
  1478. </el-form-item>
  1479. <el-form-item label="租期(月)" prop="contractDataA.tenantTime">
  1480. <el-input-number
  1481. :max="500"
  1482. :min="1"
  1483. v-model="rentalForm.contractDataA.tenantTime"
  1484. placeholder="请输入租期"
  1485. :disabled="currentStep > 0"
  1486. />
  1487. </el-form-item>
  1488. <el-form-item label="租期结束时间" prop="contractDataA.tenantTimeEnd">
  1489. <el-date-picker
  1490. type="date"
  1491. format="YYYY-MM-DD"
  1492. value-format="YYYY-MM-DD"
  1493. disabled
  1494. v-model="rentalForm.contractDataA.tenantTimeEnd"
  1495. placeholder="请输入租期结束时间"
  1496. />
  1497. </el-form-item>
  1498. <el-form-item label="每套租金" prop="contractDataA.tenantRent">
  1499. <el-input-number
  1500. :min="0"
  1501. :max="1000000"
  1502. v-model="rentalForm.contractDataA.tenantRent"
  1503. placeholder="请输入每套租金"
  1504. :disabled="currentStep > 0"
  1505. />
  1506. </el-form-item>
  1507. <el-form-item label="每套物业费" prop="contractDataA.tenantDeposit">
  1508. <el-input
  1509. v-model="rentalForm.contractDataA.tenantDeposit"
  1510. placeholder="请输入每套物业费"
  1511. />
  1512. </el-form-item>
  1513. <el-form-item label="押金" prop="contractDataA.tenantDepositAmount">
  1514. <el-input-number
  1515. v-model="rentalForm.contractDataA.tenantDepositAmount"
  1516. placeholder="请输入押金"
  1517. />
  1518. </el-form-item>
  1519. </div>
  1520. <div v-if="propertyInfo.assetType === '厂房'">
  1521. <el-form-item label="用途" prop="contractDataB.purpose">
  1522. <el-input v-model="rentalForm.contractDataB.purpose" placeholder="请输入用途" />
  1523. </el-form-item>
  1524. <el-form-item label="房东" prop="contractDataB.landlordName">
  1525. <el-input v-model="rentalForm.contractDataB.landlordName" placeholder="请输入房东" />
  1526. </el-form-item>
  1527. <el-form-item label="法人统一社会信用代码" prop="contractDataB.landlordUniCode">
  1528. <el-input
  1529. v-model="rentalForm.contractDataB.landlordUniCode"
  1530. placeholder="请输入法人统一社会信用代码"
  1531. />
  1532. </el-form-item>
  1533. <el-form-item label="法定代表人" prop="contractDataB.landlordLegalRepresentative">
  1534. <el-input
  1535. v-model="rentalForm.contractDataB.landlordLegalRepresentative"
  1536. placeholder="请输入法定代表人"
  1537. />
  1538. </el-form-item>
  1539. <el-form-item label="房东职务" prop="contractDataB.landlordDuty">
  1540. <el-input
  1541. v-model="rentalForm.contractDataB.landlordDuty"
  1542. placeholder="请输入房东职务"
  1543. />
  1544. </el-form-item>
  1545. <el-form-item label="租方" prop="contractDataB.tenantName">
  1546. <el-input v-model="rentalForm.contractDataB.tenantName" placeholder="请输入租方" />
  1547. </el-form-item>
  1548. <el-form-item label="租方统一社会信用代码" prop="contractDataB.tenantUniCode">
  1549. <el-input
  1550. v-model="rentalForm.contractDataB.tenantUniCode"
  1551. placeholder="请输入租方统一社会信用代码"
  1552. />
  1553. </el-form-item>
  1554. <el-form-item label="法定代表人" prop="contractDataB.tenantLegalRepresentative">
  1555. <el-input
  1556. v-model="rentalForm.contractDataB.tenantLegalRepresentative"
  1557. placeholder="请输入法定代表人"
  1558. />
  1559. </el-form-item>
  1560. <el-form-item label="租方职务" prop="contractDataB.tenantDuty">
  1561. <el-input
  1562. v-model="rentalForm.contractDataB.tenantDuty"
  1563. placeholder="请输入租方职务"
  1564. />
  1565. </el-form-item>
  1566. <el-form-item label="谁" prop="contractDataB.who">
  1567. <el-input v-model="rentalForm.contractDataB.who" placeholder="请输入谁" />
  1568. </el-form-item>
  1569. <el-form-item label="何时" prop="contractDataB.whatTime">
  1570. <el-input v-model="rentalForm.contractDataB.whatTime" placeholder="请输入何时" />
  1571. </el-form-item>
  1572. <el-form-item label="标题" prop="contractDataB.title">
  1573. <el-input v-model="rentalForm.contractDataB.title" placeholder="请输入标题" />
  1574. </el-form-item>
  1575. <el-form-item label="配套用房面积 (㎡) " prop="contractDataB.supportingRoomArea">
  1576. <el-input
  1577. v-model="rentalForm.contractDataB.supportingRoomArea"
  1578. placeholder="请输入配套用房面积(㎡)"
  1579. />
  1580. </el-form-item>
  1581. <el-form-item label="办公室面积(㎡)" prop="contractDataB.officeArea">
  1582. <el-input
  1583. v-model="rentalForm.contractDataB.officeArea"
  1584. placeholder="请输入办公室面积(㎡)"
  1585. />
  1586. </el-form-item>
  1587. <el-form-item label="食堂面积(㎡)" prop="contractDataB.canteenArea">
  1588. <el-input
  1589. v-model="rentalForm.contractDataB.canteenArea"
  1590. placeholder="请输入食堂面积(㎡)"
  1591. />
  1592. </el-form-item>
  1593. <el-form-item label="总面积(㎡)" prop="contractDataB.totalLeasedArea">
  1594. <el-input
  1595. v-model="rentalForm.contractDataB.totalLeasedArea"
  1596. placeholder="请输入总面积(㎡)"
  1597. />
  1598. </el-form-item>
  1599. <el-form-item label="宿舍楼总间数" prop="contractDataB.dormTotalRooms">
  1600. <el-input
  1601. v-model="rentalForm.contractDataB.dormTotalRooms"
  1602. placeholder="请输入宿舍楼总间数"
  1603. />
  1604. </el-form-item>
  1605. <el-form-item label="宿舍小间数" prop="contractDataB.dormSmallRooms">
  1606. <el-input
  1607. v-model="rentalForm.contractDataB.dormSmallRooms"
  1608. placeholder="请输入宿舍小间数"
  1609. />
  1610. </el-form-item>
  1611. <el-form-item label="宿舍大间数" prop="contractDataB.dormLargeRooms">
  1612. <el-input
  1613. v-model="rentalForm.contractDataB.dormLargeRooms"
  1614. placeholder="请输入宿舍大间数"
  1615. />
  1616. </el-form-item>
  1617. <el-form-item label="标的交付日期" prop="contractDataB.deliveryDate">
  1618. <el-input
  1619. v-model="rentalForm.contractDataB.deliveryDate"
  1620. placeholder="请输入标的交付日期"
  1621. />
  1622. </el-form-item>
  1623. <el-form-item label="生产项目名称" prop="contractDataB.productionProject">
  1624. <el-input
  1625. v-model="rentalForm.contractDataB.productionProject"
  1626. placeholder="请输入生产项目名称"
  1627. />
  1628. </el-form-item>
  1629. <el-form-item label="租赁期限(年)" prop="contractDataB.leaseTermYears">
  1630. <el-input
  1631. v-model="rentalForm.contractDataB.leaseTermYears"
  1632. placeholder="请输入租赁期限(年)"
  1633. />
  1634. </el-form-item>
  1635. <el-form-item label="租赁起始日" prop="contractDataB.leaseStartDate">
  1636. <el-date-picker
  1637. type="date"
  1638. format="YYYY-MM-DD"
  1639. value-format="YYYY-MM-DD"
  1640. clearable
  1641. v-model="rentalForm.contractDataB.leaseStartDate"
  1642. placeholder="请输入租赁起始日"
  1643. />
  1644. </el-form-item>
  1645. <el-form-item label="租赁终止日" prop="contractDataB.leaseEndDate">
  1646. <el-date-picker
  1647. type="date"
  1648. format="YYYY-MM-DD"
  1649. value-format="YYYY-MM-DD"
  1650. clearable
  1651. v-model="rentalForm.contractDataB.leaseEndDate"
  1652. placeholder="请输入租赁终止日"
  1653. />
  1654. </el-form-item>
  1655. <el-form-item label="续租提前通知月数" prop="contractDataB.renewNoticeMonths">
  1656. <el-input
  1657. v-model="rentalForm.contractDataB.renewNoticeMonths"
  1658. placeholder="请输入续租提前通知月数"
  1659. />
  1660. </el-form-item>
  1661. <el-form-item label="标准化厂房某楼层" prop="contractDataB.factorySpecificFloor1">
  1662. <el-input
  1663. v-model="rentalForm.contractDataB.factorySpecificFloor1"
  1664. placeholder="请输入标准化厂房某楼层"
  1665. />
  1666. </el-form-item>
  1667. <el-form-item label="该楼层租金(元/㎡/月)" prop="contractDataB.rentPerSqmFloor1">
  1668. <el-input
  1669. v-model="rentalForm.contractDataB.rentPerSqmFloor1"
  1670. placeholder="请输入该楼层租金(元/㎡/月)"
  1671. />
  1672. </el-form-item>
  1673. <el-form-item label="标准化厂房另一楼层" prop="contractDataB.factorySpecificFloor2">
  1674. <el-input
  1675. v-model="rentalForm.contractDataB.factorySpecificFloor2"
  1676. placeholder="请输入标准化厂房另一楼层"
  1677. />
  1678. </el-form-item>
  1679. <el-form-item label="该楼层租金(元/㎡/月)" prop="contractDataB.rentPerSqmFloor2">
  1680. <el-input
  1681. v-model="rentalForm.contractDataB.rentPerSqmFloor2"
  1682. placeholder="请输入该楼层租金(元/㎡/月)"
  1683. />
  1684. </el-form-item>
  1685. <el-form-item label="厂房年租金(元)" prop="contractDataB.factoryAnnualRent">
  1686. <el-input-number
  1687. v-model="rentalForm.contractDataB.factoryAnnualRent"
  1688. placeholder="请输入厂房年租金(元)"
  1689. />
  1690. </el-form-item>
  1691. <el-form-item
  1692. label="配套用房租金(元/㎡/月)"
  1693. prop="contractDataB.supportingRoomRentPerSqm"
  1694. >
  1695. <el-input
  1696. v-model="rentalForm.contractDataB.supportingRoomRentPerSqm"
  1697. placeholder="请输入配套用房租金(元/㎡/月)"
  1698. />
  1699. </el-form-item>
  1700. <el-form-item
  1701. label="配套用房年租金(元)"
  1702. prop="contractDataB.supportingRoomAnnualRent"
  1703. >
  1704. <el-input-number
  1705. v-model="rentalForm.contractDataB.supportingRoomAnnualRent"
  1706. placeholder="请输入配套用房年租金(元)"
  1707. />
  1708. </el-form-item>
  1709. <el-form-item label="宿舍楼普通单间月租金(元)" prop="contractDataB.dormSmallRoomRent">
  1710. <el-input
  1711. v-model="rentalForm.contractDataB.dormSmallRoomRent"
  1712. placeholder="请输入宿舍楼普通单间月租金(元)"
  1713. />
  1714. </el-form-item>
  1715. <el-form-item label="宿舍楼大单间月租金(元)" prop="contractDataB.dormLargeRoomRent">
  1716. <el-input
  1717. v-model="rentalForm.contractDataB.dormLargeRoomRent"
  1718. placeholder="请输入宿舍楼大单间月租金(元)"
  1719. />
  1720. </el-form-item>
  1721. <el-form-item label="宿舍楼年租金(元)" prop="contractDataB.dormAnnualRent">
  1722. <el-input-number
  1723. v-model="rentalForm.contractDataB.dormAnnualRent"
  1724. placeholder="请输入宿舍楼年租金(元)"
  1725. />
  1726. </el-form-item>
  1727. <el-form-item label="总租金(元)" prop="contractDataB.totalAnnualRent">
  1728. <el-input-number
  1729. v-model="rentalForm.contractDataB.totalAnnualRent"
  1730. placeholder="请输入总租金(元)"
  1731. />
  1732. </el-form-item>
  1733. <el-form-item
  1734. label="标准化厂房和配套用房物业费(元/㎡/月)"
  1735. prop="contractDataB.propertyFeePerSqm"
  1736. >
  1737. <el-input
  1738. v-model="rentalForm.contractDataB.propertyFeePerSqm"
  1739. placeholder="请输入标准化厂房和配套用房物业费(元/㎡/月)"
  1740. />
  1741. </el-form-item>
  1742. <el-form-item
  1743. label="标准化厂房和配套用房年物业费(元)"
  1744. prop="contractDataB.factorySupportingPropertyFee"
  1745. >
  1746. <el-input-number
  1747. v-model="rentalForm.contractDataB.factorySupportingPropertyFee"
  1748. placeholder="请输入标准化厂房和配套用房年物业费(元)"
  1749. />
  1750. </el-form-item>
  1751. <el-form-item
  1752. label="宿舍楼普通单间月物业费(元)"
  1753. prop="contractDataB.dormSmallRoomPropertyFee"
  1754. >
  1755. <el-input
  1756. v-model="rentalForm.contractDataB.dormSmallRoomPropertyFee"
  1757. placeholder="请输入宿舍楼普通单间月物业费(元)"
  1758. />
  1759. </el-form-item>
  1760. <el-form-item
  1761. label="宿舍楼大单间月物业费(元)"
  1762. prop="contractDataB.dormLargeRoomPropertyFee"
  1763. >
  1764. <el-input
  1765. v-model="rentalForm.contractDataB.dormLargeRoomPropertyFee"
  1766. placeholder="请输入宿舍楼大单间月物业费(元)"
  1767. />
  1768. </el-form-item>
  1769. <el-form-item label="宿舍楼年物业费(元)" prop="contractDataB.dormAnnualPropertyFee">
  1770. <el-input-number
  1771. v-model="rentalForm.contractDataB.dormAnnualPropertyFee"
  1772. placeholder="请输入宿舍楼年物业费(元)"
  1773. />
  1774. </el-form-item>
  1775. <el-form-item label="年物业管理费(元)" prop="contractDataB.totalAnnualPropertyFee">
  1776. <el-input-number
  1777. v-model="rentalForm.contractDataB.totalAnnualPropertyFee"
  1778. placeholder="请输入年物业管理费(元)"
  1779. />
  1780. </el-form-item>
  1781. <el-form-item
  1782. label="年租金和物业费用总计(元)"
  1783. prop="contractDataB.annualTotalRentAndPropertyFee"
  1784. >
  1785. <el-input-number
  1786. v-model="rentalForm.contractDataB.annualTotalRentAndPropertyFee"
  1787. placeholder="请输入年租金和物业费用总计(元)"
  1788. />
  1789. </el-form-item>
  1790. <el-form-item label="租赁押金金额(元)" prop="contractDataB.depositAmount">
  1791. <el-input-number
  1792. v-model="rentalForm.contractDataB.depositAmount"
  1793. placeholder="请输入租赁押金金额(元)"
  1794. />
  1795. </el-form-item>
  1796. </div>
  1797. <div v-if="propertyInfo.assetType === '创新创业基地'">
  1798. <el-form-item label="出租方(甲方)名称" prop="contractDataC.lessorName">
  1799. <el-input
  1800. v-model="rentalForm.contractDataC.lessorName"
  1801. placeholder="请输入出租方(甲方)名称"
  1802. />
  1803. </el-form-item>
  1804. <el-form-item label="出租方法定代表人" prop="contractDataC.lessorLegalRep">
  1805. <el-input
  1806. v-model="rentalForm.contractDataC.lessorLegalRep"
  1807. placeholder="请输入出租方法定代表人"
  1808. />
  1809. </el-form-item>
  1810. <el-form-item label="出租方统一社会信用代码" prop="contractDataC.lessorUniCode">
  1811. <el-input
  1812. v-model="rentalForm.contractDataC.lessorUniCode"
  1813. placeholder="请输入出租方统一社会信用代码"
  1814. />
  1815. </el-form-item>
  1816. <el-form-item label="承租方(乙方)名称" prop="contractDataC.lesseeName">
  1817. <el-input
  1818. v-model="rentalForm.contractDataC.lesseeName"
  1819. placeholder="请输入承租方(乙方)名称"
  1820. />
  1821. </el-form-item>
  1822. <el-form-item label="承租方法定代表人" prop="contractDataC.lesseeLegalRep">
  1823. <el-input
  1824. v-model="rentalForm.contractDataC.lesseeLegalRep"
  1825. placeholder="请输入承租方法定代表人"
  1826. />
  1827. </el-form-item>
  1828. <el-form-item label="承租方统一社会信用代码/身份证号" prop="contractDataC.lesseeIdCode">
  1829. <el-input
  1830. v-model="rentalForm.contractDataC.lesseeIdCode"
  1831. placeholder="请输入承租方统一社会信用代码/身份证号"
  1832. />
  1833. </el-form-item>
  1834. <el-form-item label="标的物坐落" prop="contractDataC.propertyLocation">
  1835. <el-input
  1836. v-model="rentalForm.contractDataC.propertyLocation"
  1837. placeholder="请输入标的物坐落"
  1838. />
  1839. </el-form-item>
  1840. <el-form-item label="计租面积(平方米)" prop="contractDataC.rentableArea">
  1841. <el-input
  1842. v-model="rentalForm.contractDataC.rentableArea"
  1843. placeholder="请输入计租面积(平方米)"
  1844. />
  1845. </el-form-item>
  1846. <el-form-item label="使用面积(平方米)" prop="contractDataC.usableArea">
  1847. <el-input
  1848. v-model="rentalForm.contractDataC.usableArea"
  1849. placeholder="请输入使用面积(平方米)"
  1850. />
  1851. </el-form-item>
  1852. <el-form-item label="公摊面积(平方米)" prop="contractDataC.sharedArea">
  1853. <el-input
  1854. v-model="rentalForm.contractDataC.sharedArea"
  1855. placeholder="请输入公摊面积(平方米)"
  1856. />
  1857. </el-form-item>
  1858. <el-form-item label="标的物使用性质" prop="contractDataC.propertyUseNature">
  1859. <el-input
  1860. v-model="rentalForm.contractDataC.propertyUseNature"
  1861. placeholder="请输入标的物使用性质"
  1862. />
  1863. </el-form-item>
  1864. <el-form-item label="店铺名称" prop="contractDataC.storeName">
  1865. <el-input v-model="rentalForm.contractDataC.storeName" placeholder="请输入店铺名称" />
  1866. </el-form-item>
  1867. <el-form-item label="商品/服务品牌" prop="contractDataC.brand">
  1868. <el-input
  1869. v-model="rentalForm.contractDataC.brand"
  1870. placeholder="请输入商品/服务品牌"
  1871. />
  1872. </el-form-item>
  1873. <el-form-item label="经营范围" prop="contractDataC.businessScope">
  1874. <el-input
  1875. v-model="rentalForm.contractDataC.businessScope"
  1876. placeholder="请输入经营范围"
  1877. />
  1878. </el-form-item>
  1879. <el-form-item label="租赁期限(个月)" prop="contractDataC.leaseTermMonths">
  1880. <el-input
  1881. v-model="rentalForm.contractDataC.leaseTermMonths"
  1882. placeholder="请输入租赁期限(个月)"
  1883. />
  1884. </el-form-item>
  1885. <el-form-item label="租赁起始日" prop="contractDataC.leaseStartDate">
  1886. <el-date-picker
  1887. type="date"
  1888. format="YYYY-MM-DD"
  1889. value-format="YYYY-MM-DD"
  1890. clearable
  1891. v-model="rentalForm.contractDataC.leaseStartDate"
  1892. placeholder="请输入租赁起始日"
  1893. />
  1894. </el-form-item>
  1895. <el-form-item label="租赁终止日" prop="contractDataC.leaseEndDate">
  1896. <el-date-picker
  1897. type="date"
  1898. format="YYYY-MM-DD"
  1899. value-format="YYYY-MM-DD"
  1900. clearable
  1901. v-model="rentalForm.contractDataC.leaseEndDate"
  1902. placeholder="请输入租赁终止日"
  1903. />
  1904. </el-form-item>
  1905. <el-form-item label="装修期起始日" prop="contractDataC.renovationStartDate">
  1906. <el-input
  1907. v-model="rentalForm.contractDataC.renovationStartDate"
  1908. placeholder="请输入装修期起始日"
  1909. />
  1910. </el-form-item>
  1911. <el-form-item label="装修期终止日" prop="contractDataC.renovationEndDate">
  1912. <el-input
  1913. v-model="rentalForm.contractDataC.renovationEndDate"
  1914. placeholder="请输入装修期终止日"
  1915. />
  1916. </el-form-item>
  1917. <el-form-item label="正式起租时间" prop="contractDataC.officialLeaseStartDate">
  1918. <el-input
  1919. v-model="rentalForm.contractDataC.officialLeaseStartDate"
  1920. placeholder="请输入正式起租时间"
  1921. />
  1922. </el-form-item>
  1923. <el-form-item label="年租金(小写)" prop="contractDataC.annualRentLower">
  1924. <el-input-number
  1925. v-model="rentalForm.contractDataC.annualRentLower"
  1926. placeholder="请输入年租金(小写)"
  1927. />
  1928. </el-form-item>
  1929. <el-form-item label="年物业服务费(小写)" prop="contractDataC.annualPropertyFeeLower">
  1930. <el-input-number
  1931. v-model="rentalForm.contractDataC.annualPropertyFeeLower"
  1932. placeholder="请输入年物业服务费(小写)"
  1933. />
  1934. </el-form-item>
  1935. <el-form-item label="租赁保证金金额" prop="contractDataC.depositAmount">
  1936. <el-input-number
  1937. v-model="rentalForm.contractDataC.depositAmount"
  1938. placeholder="请输入租赁保证金金额"
  1939. />
  1940. </el-form-item>
  1941. </div>
  1942. </div>
  1943. <div v-show="currentStep === 2">
  1944. <div class="bg-gray-50 p-6 rounded-lg">
  1945. <h3 class="text-lg font-semibold mb-4">请确认以下信息:</h3>
  1946. <!-- 第一步:租户信息 -->
  1947. <div class="mb-6">
  1948. <h4 class="text-md font-semibold mb-3 text-blue-600">租户信息</h4>
  1949. <el-row :gutter="24">
  1950. <el-col :span="12">
  1951. <p><strong>租户姓名:</strong>{{ rentalForm.rentalInfo.rentalName }}</p>
  1952. <p><strong>联系电话:</strong>{{ rentalForm.rentalInfo.rentalPhone }}</p>
  1953. <p><strong>身份证号:</strong>{{ rentalForm.rentalInfo.rentalIdCard }}</p>
  1954. </el-col>
  1955. <el-col :span="12">
  1956. <p><strong>租金:</strong>{{ rentalForm.rentalInfo.rentalRect }} 元</p>
  1957. <p><strong>租期:</strong>{{ rentalForm.rentalInfo.rentalTime }}</p>
  1958. <p><strong>开始时间:</strong>{{ rentalForm.rentalInfo.rentalTimeStart }}</p>
  1959. </el-col>
  1960. </el-row>
  1961. </div>
  1962. <!-- 第二步:合同条款信息 -->
  1963. <div class="mb-6">
  1964. <h4 class="text-md font-semibold mb-3 text-green-600">合同条款信息</h4>
  1965. <!-- 公租房合同信息 -->
  1966. <div v-if="propertyInfo.assetType === '公租房'">
  1967. <el-row :gutter="24">
  1968. <el-col :span="12">
  1969. <p><strong>租方:</strong>{{ rentalForm.contractDataA.tenantName }}</p>
  1970. <p><strong>房东:</strong>{{ rentalForm.contractDataA.landlordName }}</p>
  1971. <p>
  1972. <strong>租期开始时间:</strong>{{ rentalForm.contractDataA.tenantTimeStart }}
  1973. </p>
  1974. <p><strong>租期:</strong>{{ rentalForm.contractDataA.tenantTime }}</p>
  1975. </el-col>
  1976. <el-col :span="12">
  1977. <p>
  1978. <strong>租期结束时间:</strong>{{ rentalForm.contractDataA.tenantTimeEnd }}
  1979. </p>
  1980. <p><strong>每套租金:</strong>{{ rentalForm.contractDataA.tenantRent }} 元</p>
  1981. <p>
  1982. <strong>每套物业费:</strong>{{ rentalForm.contractDataA.tenantDeposit }} 元
  1983. </p>
  1984. <p>
  1985. <strong>押金:</strong>{{ rentalForm.contractDataA.tenantDepositAmount }} 元
  1986. </p>
  1987. </el-col>
  1988. </el-row>
  1989. </div>
  1990. <!-- 厂房合同信息 -->
  1991. <div v-if="propertyInfo.assetType === '厂房'">
  1992. <el-row :gutter="24">
  1993. <el-col :span="12">
  1994. <p><strong>用途:</strong>{{ rentalForm.contractDataB.purpose }}</p>
  1995. <p><strong>房东:</strong>{{ rentalForm.contractDataB.landlordName }}</p>
  1996. <p>
  1997. <strong>法人统一社会信用代码:</strong
  1998. >{{ rentalForm.contractDataB.landlordUniCode }}
  1999. </p>
  2000. <p>
  2001. <strong>法定代表人:</strong
  2002. >{{ rentalForm.contractDataB.landlordLegalRepresentative }}
  2003. </p>
  2004. <p><strong>房东职务:</strong>{{ rentalForm.contractDataB.landlordDuty }}</p>
  2005. <p><strong>租方:</strong>{{ rentalForm.contractDataB.tenantName }}</p>
  2006. <p>
  2007. <strong>租方统一社会信用代码:</strong
  2008. >{{ rentalForm.contractDataB.tenantUniCode }}
  2009. </p>
  2010. <p>
  2011. <strong>租方法定代表人:</strong
  2012. >{{ rentalForm.contractDataB.tenantLegalRepresentative }}
  2013. </p>
  2014. <p><strong>租方职务:</strong>{{ rentalForm.contractDataB.tenantDuty }}</p>
  2015. <p><strong>谁:</strong>{{ rentalForm.contractDataB.who }}</p>
  2016. <p><strong>何时:</strong>{{ rentalForm.contractDataB.whatTime }}</p>
  2017. <p><strong>标题:</strong>{{ rentalForm.contractDataB.title }}</p>
  2018. <p>
  2019. <strong>配套用房面积:</strong
  2020. >{{ rentalForm.contractDataB.supportingRoomArea }} ㎡
  2021. </p>
  2022. <p><strong>办公室面积:</strong>{{ rentalForm.contractDataB.officeArea }} ㎡</p>
  2023. <p><strong>食堂面积:</strong>{{ rentalForm.contractDataB.canteenArea }} ㎡</p>
  2024. <p>
  2025. <strong>总面积:</strong>{{ rentalForm.contractDataB.totalLeasedArea }} ㎡
  2026. </p>
  2027. <p>
  2028. <strong>宿舍楼总间数:</strong>{{ rentalForm.contractDataB.dormTotalRooms }}
  2029. </p>
  2030. <p>
  2031. <strong>宿舍小间数:</strong>{{ rentalForm.contractDataB.dormSmallRooms }}
  2032. </p>
  2033. <p>
  2034. <strong>宿舍大间数:</strong>{{ rentalForm.contractDataB.dormLargeRooms }}
  2035. </p>
  2036. <p>
  2037. <strong>标的交付日期:</strong>{{ rentalForm.contractDataB.deliveryDate }}
  2038. </p>
  2039. <p>
  2040. <strong>生产项目名称:</strong
  2041. >{{ rentalForm.contractDataB.productionProject }}
  2042. </p>
  2043. <p>
  2044. <strong>租赁期限(年):</strong>{{ rentalForm.contractDataB.leaseTermYears }}
  2045. </p>
  2046. <p>
  2047. <strong>租赁起始日:</strong>{{ rentalForm.contractDataB.leaseStartDate }}
  2048. </p>
  2049. <p><strong>租赁终止日:</strong>{{ rentalForm.contractDataB.leaseEndDate }}</p>
  2050. </el-col>
  2051. <el-col :span="12">
  2052. <p>
  2053. <strong>续租提前通知月数:</strong
  2054. >{{ rentalForm.contractDataB.renewNoticeMonths }}
  2055. </p>
  2056. <p>
  2057. <strong>标准化厂房某楼层:</strong
  2058. >{{ rentalForm.contractDataB.factorySpecificFloor1 }}
  2059. </p>
  2060. <p>
  2061. <strong>该楼层租金(元/㎡/月):</strong
  2062. >{{ rentalForm.contractDataB.rentPerSqmFloor1 }}
  2063. </p>
  2064. <p>
  2065. <strong>标准化厂房另一楼层:</strong
  2066. >{{ rentalForm.contractDataB.factorySpecificFloor2 }}
  2067. </p>
  2068. <p>
  2069. <strong>该楼层租金(元/㎡/月):</strong
  2070. >{{ rentalForm.contractDataB.rentPerSqmFloor2 }}
  2071. </p>
  2072. <p>
  2073. <strong>厂房年租金:</strong
  2074. >{{ rentalForm.contractDataB.factoryAnnualRent }} 元
  2075. </p>
  2076. <p>
  2077. <strong>配套用房租金(元/㎡/月):</strong
  2078. >{{ rentalForm.contractDataB.supportingRoomRentPerSqm }}
  2079. </p>
  2080. <p>
  2081. <strong>配套用房年租金:</strong
  2082. >{{ rentalForm.contractDataB.supportingRoomAnnualRent }} 元
  2083. </p>
  2084. <p>
  2085. <strong>宿舍楼普通单间月租金:</strong
  2086. >{{ rentalForm.contractDataB.dormSmallRoomRent }} 元
  2087. </p>
  2088. <p>
  2089. <strong>宿舍楼大单间月租金:</strong
  2090. >{{ rentalForm.contractDataB.dormLargeRoomRent }} 元
  2091. </p>
  2092. <p>
  2093. <strong>宿舍楼年租金:</strong
  2094. >{{ rentalForm.contractDataB.dormAnnualRent }} 元
  2095. </p>
  2096. <p>
  2097. <strong>总租金:</strong>{{ rentalForm.contractDataB.totalAnnualRent }} 元
  2098. </p>
  2099. <p>
  2100. <strong>标准化厂房和配套用房物业费(元/㎡/月):</strong
  2101. >{{ rentalForm.contractDataB.propertyFeePerSqm }}
  2102. </p>
  2103. <p>
  2104. <strong>标准化厂房和配套用房年物业费:</strong
  2105. >{{ rentalForm.contractDataB.factorySupportingPropertyFee }} 元
  2106. </p>
  2107. <p>
  2108. <strong>宿舍楼普通单间月物业费:</strong
  2109. >{{ rentalForm.contractDataB.dormSmallRoomPropertyFee }} 元
  2110. </p>
  2111. <p>
  2112. <strong>宿舍楼大单间月物业费:</strong
  2113. >{{ rentalForm.contractDataB.dormLargeRoomPropertyFee }} 元
  2114. </p>
  2115. <p>
  2116. <strong>宿舍楼年物业费:</strong
  2117. >{{ rentalForm.contractDataB.dormAnnualPropertyFee }} 元
  2118. </p>
  2119. <p>
  2120. <strong>年物业管理费:</strong
  2121. >{{ rentalForm.contractDataB.totalAnnualPropertyFee }} 元
  2122. </p>
  2123. <p>
  2124. <strong>年租金和物业费用总计:</strong
  2125. >{{ rentalForm.contractDataB.annualTotalRentAndPropertyFee }} 元
  2126. </p>
  2127. <p>
  2128. <strong>租赁押金金额:</strong>{{ rentalForm.contractDataB.depositAmount }} 元
  2129. </p>
  2130. </el-col>
  2131. </el-row>
  2132. </div>
  2133. <!-- 创新创业基地合同信息 -->
  2134. <div v-if="propertyInfo.assetType === '创新创业基地'">
  2135. <el-row :gutter="24">
  2136. <el-col :span="12">
  2137. <p>
  2138. <strong>出租方(甲方)名称:</strong>{{ rentalForm.contractDataC.lessorName }}
  2139. </p>
  2140. <p>
  2141. <strong>出租方法定代表人:</strong
  2142. >{{ rentalForm.contractDataC.lessorLegalRep }}
  2143. </p>
  2144. <p>
  2145. <strong>出租方统一社会信用代码:</strong
  2146. >{{ rentalForm.contractDataC.lessorUniCode }}
  2147. </p>
  2148. <p>
  2149. <strong>承租方(乙方)名称:</strong>{{ rentalForm.contractDataC.lesseeName }}
  2150. </p>
  2151. <p>
  2152. <strong>承租方法定代表人:</strong
  2153. >{{ rentalForm.contractDataC.lesseeLegalRep }}
  2154. </p>
  2155. <p>
  2156. <strong>承租方统一社会信用代码/身份证号:</strong
  2157. >{{ rentalForm.contractDataC.lesseeIdCode }}
  2158. </p>
  2159. <p>
  2160. <strong>标的物坐落:</strong>{{ rentalForm.contractDataC.propertyLocation }}
  2161. </p>
  2162. <p>
  2163. <strong>计租面积:</strong>{{ rentalForm.contractDataC.rentableArea }} 平方米
  2164. </p>
  2165. <p>
  2166. <strong>使用面积:</strong>{{ rentalForm.contractDataC.usableArea }} 平方米
  2167. </p>
  2168. <p>
  2169. <strong>公摊面积:</strong>{{ rentalForm.contractDataC.sharedArea }} 平方米
  2170. </p>
  2171. <p>
  2172. <strong>标的物使用性质:</strong
  2173. >{{ rentalForm.contractDataC.propertyUseNature }}
  2174. </p>
  2175. <p><strong>店铺名称:</strong>{{ rentalForm.contractDataC.storeName }}</p>
  2176. </el-col>
  2177. <el-col :span="12">
  2178. <p><strong>商品/服务品牌:</strong>{{ rentalForm.contractDataC.brand }}</p>
  2179. <p><strong>经营范围:</strong>{{ rentalForm.contractDataC.businessScope }}</p>
  2180. <p>
  2181. <strong>租赁期限:</strong>{{ rentalForm.contractDataC.leaseTermMonths }} 个月
  2182. </p>
  2183. <p>
  2184. <strong>租赁起始日:</strong>{{ rentalForm.contractDataC.leaseStartDate }}
  2185. </p>
  2186. <p><strong>租赁终止日:</strong>{{ rentalForm.contractDataC.leaseEndDate }}</p>
  2187. <p>
  2188. <strong>装修期起始日:</strong
  2189. >{{ rentalForm.contractDataC.renovationStartDate }}
  2190. </p>
  2191. <p>
  2192. <strong>装修期终止日:</strong
  2193. >{{ rentalForm.contractDataC.renovationEndDate }}
  2194. </p>
  2195. <p>
  2196. <strong>正式起租时间:</strong
  2197. >{{ rentalForm.contractDataC.officialLeaseStartDate }}
  2198. </p>
  2199. <p>
  2200. <strong>年租金(小写):</strong
  2201. >{{ rentalForm.contractDataC.annualRentLower }} 元
  2202. </p>
  2203. <p>
  2204. <strong>年物业服务费(小写):</strong
  2205. >{{ rentalForm.contractDataC.annualPropertyFeeLower }} 元
  2206. </p>
  2207. <p>
  2208. <strong>租赁保证金金额:</strong
  2209. >{{ rentalForm.contractDataC.depositAmount }} 元
  2210. </p>
  2211. </el-col>
  2212. </el-row>
  2213. </div>
  2214. </div>
  2215. </div>
  2216. </div>
  2217. </el-form>
  2218. <template #footer>
  2219. <div class="flex justify-between">
  2220. <el-button v-if="currentStep > 0" @click="currentStep--">上一步</el-button>
  2221. <div class="flex gap-2">
  2222. <el-button @click="handleCloseRentalDialog">取消</el-button>
  2223. <el-button v-if="currentStep < 2" type="primary" @click="nextStep">下一步</el-button>
  2224. <el-button
  2225. v-if="currentStep === 2"
  2226. type="primary"
  2227. @click="submitRental"
  2228. :loading="submitting"
  2229. >确认出租</el-button
  2230. >
  2231. </div>
  2232. </div>
  2233. </template>
  2234. </el-dialog>
  2235. <el-dialog v-model="showTerminateDialog" title="退租确认" width="600px">
  2236. <div class="mb-6" v-if="contractInfo">
  2237. <h3 class="text-lg font-semibold mb-4">合同信息</h3>
  2238. <div class="bg-gray-50 p-4 rounded-lg">
  2239. <p><strong>合同编号:</strong>{{ contractInfo.contractNumber }}</p>
  2240. <p><strong>租户姓名:</strong>{{ tenantInfo?.tenantName }}</p>
  2241. <p><strong>租期:</strong>{{ contractInfo.contractTime }}</p>
  2242. <p><strong>到期日期:</strong>{{ contractInfo.contractExpirationDate }}</p>
  2243. <p><strong>押金:</strong>{{ contractInfo.contractDeposit }} 元</p>
  2244. </div>
  2245. </div>
  2246. <template #footer>
  2247. <div class="flex justify-end gap-2">
  2248. <el-button @click="showTerminateDialog = false">取消</el-button>
  2249. <el-button type="danger" @click="confirmTerminate" :loading="terminating">
  2250. 确认退租
  2251. </el-button>
  2252. </div>
  2253. </template>
  2254. </el-dialog>
  2255. </el-container>
  2256. </template>
  2257. <style scoped>
  2258. .el-card {
  2259. border: none;
  2260. }
  2261. .el-button {
  2262. font-weight: 600;
  2263. }
  2264. .el-steps {
  2265. margin-bottom: 2rem;
  2266. }
  2267. .ar-viewing-btn {
  2268. position: relative;
  2269. background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  2270. border: none;
  2271. cursor: pointer;
  2272. transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  2273. }
  2274. .ar-viewing-btn:hover {
  2275. transform: translateY(-2px) scale(1.05);
  2276. box-shadow: 0 20px 40px rgba(102, 126, 234, 0.4);
  2277. }
  2278. .ar-viewing-btn:active {
  2279. transform: translateY(0) scale(0.98);
  2280. }
  2281. .ar-viewing-btn::before {
  2282. content: '';
  2283. position: absolute;
  2284. top: 0;
  2285. left: 0;
  2286. right: 0;
  2287. bottom: 0;
  2288. background: linear-gradient(135deg, #f093fb 0%, #f5576c 50%, #4facfe 100%);
  2289. border-radius: inherit;
  2290. opacity: 0;
  2291. transition: opacity 0.3s ease;
  2292. z-index: -1;
  2293. }
  2294. .ar-viewing-btn:hover::before {
  2295. opacity: 1;
  2296. }
  2297. @keyframes gradient {
  2298. 0% {
  2299. background-position: 0% 50%;
  2300. }
  2301. 50% {
  2302. background-position: 100% 50%;
  2303. }
  2304. 100% {
  2305. background-position: 0% 50%;
  2306. }
  2307. }
  2308. .bg-gradient-to-r {
  2309. background-size: 200% 200%;
  2310. animation: gradient 15s ease infinite;
  2311. }
  2312. @keyframes ping {
  2313. 75%,
  2314. 100% {
  2315. transform: scale(2);
  2316. opacity: 0;
  2317. }
  2318. }
  2319. .animate-ping {
  2320. animation: ping 1s cubic-bezier(0, 0, 0.2, 1) infinite;
  2321. }
  2322. /* 新增:DOCX预览相关样式 */
  2323. .docx-preview-dialog {
  2324. --el-dialog-content-font-size: 14px;
  2325. }
  2326. .docx-preview-wrapper {
  2327. min-height: 400px;
  2328. max-height: 70vh;
  2329. overflow-y: auto;
  2330. border: 1px solid #e4e7ed;
  2331. border-radius: 4px;
  2332. background-color: #fff;
  2333. }
  2334. .docx-container {
  2335. padding: 20px;
  2336. font-family: 'Times New Roman', serif;
  2337. line-height: 1.6;
  2338. color: #333;
  2339. }
  2340. /* DOCX内容样式优化 */
  2341. .docx-container :deep(.docx-wrapper) {
  2342. max-width: 100%;
  2343. margin: 0 auto;
  2344. background: white;
  2345. box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  2346. padding: 40px;
  2347. }
  2348. .docx-container :deep(p) {
  2349. margin: 0 0 12px 0;
  2350. text-align: justify;
  2351. }
  2352. .docx-container :deep(table) {
  2353. width: 100%;
  2354. border-collapse: collapse;
  2355. margin: 16px 0;
  2356. }
  2357. .docx-container :deep(table td),
  2358. .docx-container :deep(table th) {
  2359. border: 1px solid #ddd;
  2360. padding: 8px;
  2361. text-align: left;
  2362. }
  2363. .docx-container :deep(table th) {
  2364. background-color: #f5f5f5;
  2365. font-weight: bold;
  2366. }
  2367. .docx-container :deep(h1),
  2368. .docx-container :deep(h2),
  2369. .docx-container :deep(h3),
  2370. .docx-container :deep(h4),
  2371. .docx-container :deep(h5),
  2372. .docx-container :deep(h6) {
  2373. margin: 20px 0 12px 0;
  2374. font-weight: bold;
  2375. }
  2376. .docx-container :deep(.page-break) {
  2377. page-break-before: always;
  2378. margin-top: 40px;
  2379. padding-top: 40px;
  2380. border-top: 1px dashed #ccc;
  2381. }
  2382. </style>