fwxq.vue 92 KB

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