BillRoomInfo.vue 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157
  1. <template>
  2. <div>
  3. <div style="display: flex; gap: 15px">
  4. <div style="width: 40%">
  5. <div style="display: flex; justify-content: space-between">
  6. <h4
  7. style="
  8. color: rgba(255, 141, 26, 1);
  9. font-weight: 600;
  10. margin-top: 15px;
  11. "
  12. >
  13. 入住信息
  14. </h4>
  15. <div style="display: flex">
  16. <div style="display: flex; flex-direction: column">
  17. <a-icon
  18. type="clock-circle"
  19. style="color: rgba(255, 141, 26, 1); font-size: 18px"
  20. /><a-button type="link"> 叫醒服务 </a-button>
  21. </div>
  22. <div style="display: flex; flex-direction: column">
  23. <a-icon
  24. type="compass"
  25. style="color: rgba(255, 141, 26, 1); font-size: 18px"
  26. /><a-button
  27. type="link"
  28. :disabled="selectRoomId == '1'"
  29. @click="splitLiving"
  30. >
  31. 拆分房间
  32. </a-button>
  33. </div>
  34. </div>
  35. </div>
  36. <a-divider />
  37. <a-tabs @change="tabChange">
  38. <a-tab-pane
  39. :key="item.roomId"
  40. v-for="(item, livingIndex) in model.livingRoomIds"
  41. >
  42. <span slot="tab">
  43. {{ item.roomName }}
  44. <a-badge
  45. dot
  46. :number-style="{ backgroundColor: '#52c41a' }"
  47. v-if="item.livingOrder && item.livingOrder.settleType == 1"
  48. >
  49. <span style="font-size: 12px">已结退房</span>
  50. </a-badge>
  51. <a-badge
  52. dot
  53. :number-style="{ backgroundColor: '#52c41a' }"
  54. v-if="item.livingOrder && item.livingOrder.settleType == 2"
  55. >
  56. <span style="font-size: 12px">未结退房</span>
  57. </a-badge>
  58. </span>
  59. <a-descriptions :column="2">
  60. <a-descriptions-item label="主客姓名">
  61. {{
  62. item.livingCustomers
  63. ? item.livingCustomers[0].customerName
  64. : "--"
  65. }}
  66. <a-icon
  67. type="edit"
  68. style="color: rgba(255, 141, 26, 1); font-size: 18px"
  69. /></a-descriptions-item>
  70. <a-descriptions-item label="性别">
  71. {{
  72. item.livingCustomers
  73. ? item.livingCustomers[0].gender === 1
  74. ? "男"
  75. : "女"
  76. : "--"
  77. }}</a-descriptions-item
  78. >
  79. <a-descriptions-item label="房间数量">
  80. {{ livingIndex == 0 ? model.livingRoomIds.length : 1 }}间
  81. </a-descriptions-item>
  82. <a-descriptions-item label="手机号">
  83. {{
  84. item.livingCustomers ? item.livingCustomers[0].phone : "--"
  85. }}
  86. <a-icon
  87. type="edit"
  88. style="color: rgba(255, 141, 26, 1); font-size: 18px"
  89. /></a-descriptions-item>
  90. <a-descriptions-item label="宾客类型">
  91. {{ customerTypeName(model.orderInfo.customerType) }}
  92. <a-icon
  93. type="edit"
  94. style="color: rgba(255, 141, 26, 1); font-size: 18px"
  95. /></a-descriptions-item>
  96. <a-descriptions-item label="入住时间">
  97. {{ model.orderInfo.arrivalTime }}
  98. </a-descriptions-item>
  99. <a-descriptions-item label="房价方案"> -- </a-descriptions-item>
  100. <a-descriptions-item label="预离时间">
  101. {{ model.orderInfo.dueOutTime }}
  102. </a-descriptions-item>
  103. <a-descriptions-item label="订单来源">
  104. {{ customerSourceName(model.orderInfo.customerSource) }}
  105. <a-icon
  106. type="edit"
  107. style="color: rgba(255, 141, 26, 1); font-size: 18px"
  108. /></a-descriptions-item>
  109. <a-descriptions-item label="入住类型">
  110. {{ model.orderInfo.bookingType == 1 ? "全天" : "钟点" }}
  111. </a-descriptions-item>
  112. <a-descriptions-item label="入住天数">
  113. {{ model.orderInfo.dayCount }}
  114. </a-descriptions-item>
  115. <a-descriptions-item label="早餐券">
  116. {{ model.orderInfo.breakfastNum }}
  117. </a-descriptions-item>
  118. <a-descriptions-item label="外部单号">
  119. {{ model.orderInfo.outerOrdersNo }}
  120. </a-descriptions-item>
  121. <a-descriptions-item label="销售员工">
  122. {{ warranterName(model.orderInfo.warranter) }}
  123. <a-icon
  124. type="edit"
  125. style="color: rgba(255, 141, 26, 1); font-size: 18px"
  126. /></a-descriptions-item>
  127. <a-descriptions-item label="订单备注" :span="2">
  128. {{ model.orderInfo.remark
  129. }}<a-icon
  130. type="edit"
  131. style="color: rgba(255, 141, 26, 1); font-size: 18px"
  132. />
  133. </a-descriptions-item>
  134. <a-descriptions-item
  135. label="叫醒服务"
  136. :span="2"
  137. v-for="(item, index) in wakeList"
  138. :key="index"
  139. >
  140. <a-select
  141. style="width: 100px"
  142. placeholder="房间号"
  143. @change="onChange"
  144. >
  145. <a-select-option value="jack"> 1001 </a-select-option>
  146. <a-select-option value="lucy"> 1002 </a-select-option>
  147. </a-select>
  148. <a-date-picker
  149. style="width: 120px; margin-left: 2px"
  150. placeholder="日期"
  151. @change="onChange"
  152. />
  153. <a-time-picker
  154. style="width: 100px; margin-left: 2px"
  155. :default-value="moment('12:08', 'HH:mm')"
  156. format="HH:mm"
  157. />
  158. <a-icon
  159. v-if="wakeList.length - 1 == index"
  160. type="plus-circle"
  161. class="dynamic-delete-button"
  162. @click="puls()"
  163. />
  164. <a-icon
  165. type="minus-circle"
  166. style="color: #f56c6c"
  167. class="dynamic-delete-button"
  168. v-if="wakeList.length > 1"
  169. @click="() => remove(index)"
  170. />
  171. </a-descriptions-item>
  172. </a-descriptions>
  173. <div style="display: flex; justify-content: space-between">
  174. <h4
  175. style="
  176. color: rgba(255, 141, 26, 1);
  177. font-weight: 600;
  178. margin-top: 15px;
  179. "
  180. >
  181. 同住人
  182. </h4>
  183. <div style="display: flex">
  184. <div style="display: flex; flex-direction: column">
  185. <a-icon
  186. type="user-add"
  187. style="color: rgba(255, 141, 26, 1); font-size: 18px"
  188. /><a-button
  189. type="link"
  190. @click="addlivingCustomer(item.livingOrder.id, item.roomId)"
  191. >
  192. 添加
  193. </a-button>
  194. </div>
  195. </div>
  196. </div>
  197. <div id="livingCustomers-grid">
  198. <a-row
  199. v-for="(customer, index) in item.livingCustomers"
  200. :key="customer.id"
  201. >
  202. <template v-if="index > 0">
  203. <a-col :span="7"> {{ customer.customerName }} </a-col>
  204. <a-col :span="1"
  205. >{{ customer.gender == 1 ? "男" : "女" }}
  206. </a-col>
  207. <a-col :span="8"> {{ customer.certNo }}</a-col>
  208. <a-col :span="6"> {{ customer.phone }}</a-col>
  209. <a-col :span="2">
  210. <a-icon
  211. type="minus-circle"
  212. style="color: #f56c6c"
  213. class="dynamic-delete-button"
  214. @click="() => removeLivingCustomer(customer.id)"
  215. /></a-col>
  216. </template>
  217. </a-row>
  218. </div>
  219. </a-tab-pane>
  220. </a-tabs>
  221. <template v-if="vipCustomer && vipCustomer.id">
  222. <h4
  223. style="
  224. color: rgba(255, 141, 26, 1);
  225. font-weight: 600;
  226. margin-top: 50px;
  227. "
  228. >
  229. 会员信息
  230. </h4>
  231. <a-divider />
  232. <a-descriptions :column="2">
  233. <a-descriptions-item label="姓名">
  234. {{ vipCustomer.name }}
  235. </a-descriptions-item>
  236. <a-descriptions-item label="证件号"
  237. >{{ vipCustomer.certificateNo }}
  238. </a-descriptions-item>
  239. <a-descriptions-item label="卡号">
  240. {{ vipCustomer.cardNo }}
  241. </a-descriptions-item>
  242. <a-descriptions-item label="手机号">
  243. {{ vipCustomer.mobile }}
  244. </a-descriptions-item>
  245. <a-descriptions-item label="会员级别">
  246. {{ vipCustomer.gradeName }}
  247. </a-descriptions-item>
  248. <a-descriptions-item label="余额"
  249. >{{ vipCustomer.balance.toFixed(2) }} 元
  250. </a-descriptions-item>
  251. <a-descriptions-item label="积分">
  252. {{ vipCustomer.integral }} 分
  253. </a-descriptions-item>
  254. </a-descriptions></template
  255. >
  256. </div>
  257. <div style="width: 40%">
  258. <div style="display: flex; justify-content: space-between">
  259. <h4
  260. style="
  261. color: rgba(255, 141, 26, 1);
  262. font-weight: 600;
  263. margin-top: 15px;
  264. "
  265. >
  266. 消费详情
  267. </h4>
  268. <div style="display: flex">
  269. <div style="display: flex; flex-direction: column">
  270. <a-icon
  271. type="tool"
  272. style="color: rgba(255, 141, 26, 1); font-size: 18px"
  273. /><a-button
  274. type="link"
  275. :disabled="selectRoomId == '1'"
  276. @click="addProjectFee"
  277. >
  278. 增加消费
  279. </a-button>
  280. </div>
  281. <div style="display: flex; flex-direction: column">
  282. <a-icon
  283. type="import"
  284. style="color: rgba(255, 141, 26, 1); font-size: 18px"
  285. /><a-button type="link"> 退单 </a-button>
  286. </div>
  287. <div style="display: flex; flex-direction: column">
  288. <a-icon
  289. type="property-safety"
  290. style="color: rgba(255, 141, 26, 1); font-size: 18px"
  291. /><a-button
  292. type="link"
  293. :disabled="selectedRowKeys1.length == 0 || selectRoomId == '1'"
  294. @click="partialSettle"
  295. >
  296. 部分结账
  297. </a-button>
  298. </div>
  299. </div>
  300. </div>
  301. <a-divider />
  302. <a-table
  303. :columns="columns"
  304. :data-source="feesList"
  305. :pagination="false"
  306. :scroll="{ y: 160 }"
  307. rowKey="id"
  308. :row-selection="rowSelection"
  309. >
  310. <template slot="subjectType" slot-scope="text, record, index">
  311. {{ getSubjectTypeText(text) }}
  312. </template>
  313. <template slot="roomId" slot-scope="text, record, index">
  314. {{ getRoomName(text) }}
  315. </template>
  316. </a-table>
  317. <div
  318. style="
  319. color: rgba(255, 87, 51, 1);
  320. font-weight: 600;
  321. text-align: right;
  322. "
  323. >
  324. 合计消费:{{ feesAmount.toFixed(2) }}
  325. </div>
  326. <div
  327. style="
  328. display: flex;
  329. justify-content: space-between;
  330. margin-top: 30px;
  331. "
  332. >
  333. <h4
  334. style="
  335. color: rgba(255, 141, 26, 1);
  336. font-weight: 600;
  337. margin-top: 15px;
  338. "
  339. >
  340. 收款详情
  341. </h4>
  342. <div style="display: flex">
  343. <div style="display: flex; flex-direction: column">
  344. <a-icon
  345. type="transaction"
  346. style="color: rgba(255, 141, 26, 1); font-size: 18px"
  347. /><a-button type="link"> 收款 </a-button>
  348. </div>
  349. <div style="display: flex; flex-direction: column">
  350. <a-icon
  351. type="trademark"
  352. style="color: rgba(255, 141, 26, 1); font-size: 18px"
  353. /><a-button type="link"> 退款 </a-button>
  354. </div>
  355. <div style="display: flex; flex-direction: column">
  356. <a-icon
  357. type="pound"
  358. style="color: rgba(255, 141, 26, 1); font-size: 18px"
  359. /><a-button type="link"> 冲账 </a-button>
  360. </div>
  361. </div>
  362. </div>
  363. <a-divider />
  364. <a-table
  365. :columns="columns2"
  366. :data-source="paymentList"
  367. :pagination="false"
  368. :scroll="{ y: 160 }"
  369. rowKey="id"
  370. :rowSelection="{
  371. selectedRowKeys: selectedRowKeys,
  372. onChange: onSelectChange,
  373. }"
  374. >
  375. <template slot="payType" slot-scope="text, record, index">
  376. {{ getPayTypeText(text) }}
  377. </template>
  378. <template slot="subjectType" slot-scope="text, record, index">
  379. {{ getSubjectTypeText(record.subjectType) }}
  380. </template>
  381. </a-table>
  382. <div
  383. style="
  384. color: rgba(255, 87, 51, 1);
  385. font-weight: 600;
  386. text-align: right;
  387. "
  388. >
  389. 合计收款:{{ paymentAmount.toFixed(2) }}
  390. </div>
  391. </div>
  392. <div style="width: 20%">
  393. <h4 style="color: rgba(255, 141, 26, 1); font-weight: 600">财务汇总</h4>
  394. <a-divider />
  395. <a-descriptions :column="1">
  396. <a-descriptions-item label="合计收款">
  397. + {{ paymentAmount.toFixed(2) }}
  398. </a-descriptions-item>
  399. <a-descriptions-item label="合计消费"
  400. >-{{ feesAmount.toFixed(2) }}
  401. </a-descriptions-item>
  402. <a-descriptions-item
  403. label="结账应退"
  404. v-if="paymentAmount - feesAmount > 0"
  405. >
  406. {{ (paymentAmount - feesAmount).toFixed(2) }}
  407. </a-descriptions-item>
  408. <a-descriptions-item label="结账应收" v-else>
  409. {{ (paymentAmount - feesAmount).toFixed(2) }}
  410. </a-descriptions-item>
  411. </a-descriptions>
  412. <a-button
  413. v-if="paymentAmount - feesAmount > 0"
  414. @click="handleAdd"
  415. type="danger"
  416. style="margin-left: 100px"
  417. :disabled="btnSisabled"
  418. >结账退款</a-button
  419. >
  420. <a-button
  421. v-else
  422. @click="handleAdd"
  423. type="danger"
  424. style="margin-left: 100px"
  425. :disabled="btnSisabled"
  426. >结账收款</a-button
  427. >
  428. </div>
  429. </div>
  430. <customer-modal ref="modalCustomerForm" @ok="modalFormOk"></customer-modal>
  431. <refund-modal ref="modalRefundForm" @ok="modalFormOk"></refund-modal>
  432. <payment-modal ref="modalPaymentForm" @ok="modalFormOk"></payment-modal>
  433. <fee-modal ref="modalFeeForm" @ok="modalFormOk"></fee-modal>
  434. <member-message-modal ref="modalMemberMessage"></member-message-modal>
  435. <lease-goods-modal ref="modalLeaseGoods"></lease-goods-modal>
  436. <select-check-in-room-order-modal
  437. ref="modalSelectCheckInRoomOrder"
  438. @ok="modalFormOk"
  439. ></select-check-in-room-order-modal>
  440. </div>
  441. </template>
  442. <script>
  443. import { httpAction, getAction, deleteAction } from "@/api/manage";
  444. import { validateDuplicateValue } from "@/utils/util";
  445. import moment from "moment";
  446. import CustomerModal from "./CustomerModal.vue";
  447. import RefundModal from "./RefundModal.vue";
  448. import PaymentModal from "./PaymentModal.vue";
  449. import FeeModal from "./FeeModal";
  450. import MemberMessageModal from "@/views/room/modules/membergoodsmanage/membermessageModal";
  451. import LeaseGoodsModal from "@/views/room/modules/leasegoods/leasegoodsModal";
  452. import SelectCheckInRoomOrderModal from "./SelectCheckInRoomOrderModal.vue";
  453. import { match } from "assert";
  454. const columns = [
  455. // {
  456. // title: "",
  457. // dataIndex: "key",
  458. // width: 20,
  459. // },
  460. {
  461. title: "房间号",
  462. dataIndex: "roomId",
  463. width: 70,
  464. scopedSlots: { customRender: "roomId" },
  465. },
  466. {
  467. title: "费项",
  468. dataIndex: "subjectType",
  469. width: 60,
  470. scopedSlots: { customRender: "subjectType" },
  471. },
  472. {
  473. title: "入账日期",
  474. dataIndex: "dayTime",
  475. width: 110,
  476. },
  477. {
  478. title: "单价",
  479. dataIndex: "id",
  480. // width: 60,
  481. customRender: function (text, record) {
  482. return record.money;
  483. },
  484. },
  485. {
  486. title: "优惠价",
  487. dataIndex: "money",
  488. // width: 80,
  489. },
  490. {
  491. title: "数量",
  492. dataIndex: "feeType",
  493. // width: 60,
  494. customRender: function (text) {
  495. return 1;
  496. },
  497. },
  498. {
  499. title: "小计",
  500. dataIndex: "livingOrderId",
  501. // width: 60,
  502. customRender: function (text, record) {
  503. return record.money;
  504. },
  505. },
  506. ];
  507. const columns2 = [
  508. {
  509. title: "入账时间",
  510. dataIndex: "createTime",
  511. // width: 110,
  512. },
  513. {
  514. title: "支付方式",
  515. dataIndex: "payType",
  516. // width: 100,
  517. scopedSlots: { customRender: "payType" },
  518. },
  519. {
  520. title: "备注",
  521. dataIndex: "remark",
  522. // width: 120,
  523. scopedSlots: { customRender: "subjectType" },
  524. },
  525. {
  526. title: "金额",
  527. dataIndex: "money",
  528. // width: 60,
  529. },
  530. ];
  531. const data = [];
  532. for (let i = 0; i < 100; i++) {
  533. data.push({
  534. key: i,
  535. name: `100${i}`,
  536. age: "房费",
  537. address: 280,
  538. });
  539. }
  540. const data2 = [];
  541. for (let i = 0; i < 8; i++) {
  542. data2.push({
  543. key: i,
  544. name: `2023-02-0${i} 10:52`,
  545. age: "支付宝",
  546. remark: "押金",
  547. amount: 888,
  548. });
  549. }
  550. const date = new Date();
  551. const endDate = new Date(date.setDate(date.getDate() + 1));
  552. export default {
  553. name: "BusMeetingRoomForm",
  554. components: {
  555. CustomerModal,
  556. RefundModal,
  557. PaymentModal,
  558. FeeModal,
  559. MemberMessageModal,
  560. LeaseGoodsModal,
  561. SelectCheckInRoomOrderModal,
  562. },
  563. props: {
  564. //表单禁用
  565. disabled: {
  566. type: Boolean,
  567. default: false,
  568. required: false,
  569. },
  570. },
  571. data() {
  572. return {
  573. selectedRowKeys: [],
  574. data,
  575. columns,
  576. data2,
  577. columns2,
  578. wakeList: [{}],
  579. model: {
  580. // data: data,
  581. orderInfo: {},
  582. roomIds: [],
  583. layoutDayPrices: [],
  584. livingRoomIds: [],
  585. },
  586. labelCol: {
  587. xs: { span: 24 },
  588. sm: { span: 5 },
  589. },
  590. wrapperCol: {
  591. xs: { span: 24 },
  592. sm: { span: 16 },
  593. },
  594. confirmLoading: false,
  595. validatorRules: {
  596. dateRange: [{ required: true, message: "请选择维修时间!" }],
  597. remark: [{ required: true, message: "请输入维修原因!" }],
  598. },
  599. url: {
  600. add: "/business/busMeetingRoom/add",
  601. edit: "/business/busMeetingRoom/edit",
  602. queryById: "/business/busMeetingRoom/queryById",
  603. getBookingOrderInfo:
  604. "/business/busRoomBookingOrders/getBookingOrderInfo",
  605. },
  606. id: "",
  607. customerSourceList: [],
  608. warranterList: [],
  609. key: 0,
  610. feesList: [],
  611. oldfeesList: [],
  612. paymentList: [],
  613. oldpaymentList: [],
  614. payTypeList: [],
  615. vipCustomer: {},
  616. selectRoomId: "1",
  617. selectedRowKeys1: [],
  618. };
  619. },
  620. computed: {
  621. formDisabled() {
  622. return this.disabled;
  623. },
  624. feesAmount() {
  625. return this.feesList.reduce(function (total, item) {
  626. return total + item.money;
  627. }, 0);
  628. },
  629. paymentAmount() {
  630. var list = this.paymentList.filter((t) => t.subjectType !== 5);
  631. var amount = list.reduce(function (total, item) {
  632. return total + item.money;
  633. }, 0);
  634. var list2 = this.paymentList.filter((t) => t.subjectType == 5);
  635. var amount2 = list2.reduce(function (total, item) {
  636. return total + item.money;
  637. }, 0);
  638. return amount - amount2;
  639. },
  640. btnSisabled() {
  641. var index = this.model.livingRoomIds.findLastIndex(
  642. (t) => t.roomId == this.selectRoomId
  643. );
  644. var find = this.model.livingRoomIds[index];
  645. if (find) {
  646. return find.livingOrder.settleType == 1;
  647. }
  648. return false;
  649. },
  650. rowSelection() {
  651. return {
  652. onChange: (selectedRowKeys, selectedRows) => {
  653. // console.log(
  654. // `selectedRowKeys: ${selectedRowKeys}`,
  655. // "selectedRows: ",
  656. // selectedRows
  657. // );
  658. this.selectedRowKeys1 = selectedRowKeys;
  659. },
  660. getCheckboxProps: (record) => ({
  661. props: {
  662. disabled: record.preferentialStatus === 2,
  663. id: record.id,
  664. },
  665. }),
  666. };
  667. },
  668. },
  669. created() {
  670. var _info = JSON.parse(localStorage.getItem("storeInfo"));
  671. if (_info) {
  672. this.model.hotelId = _info.id;
  673. }
  674. //备份model原始值
  675. this.modelDefault = JSON.parse(JSON.stringify(this.model));
  676. getAction("/business/busDictItem/list", {
  677. hotelId: _info.id,
  678. dictId: "1639538915239743490",
  679. }).then((res) => {
  680. if (res.success) {
  681. this.customerSourceList = res.result.records;
  682. }
  683. });
  684. getAction("/business/busSalesPerson/list", {
  685. hotelId: _info.id,
  686. pageNo: 1,
  687. pageSize: 100,
  688. }).then((res) => {
  689. if (res.success) {
  690. this.warranterList = res.result.records;
  691. }
  692. });
  693. },
  694. methods: {
  695. splitLiving() {
  696. var that = this;
  697. this.$confirm({
  698. title: "提示",
  699. content: "确认要拆分房间?",
  700. onOk: function () {
  701. var index = that.model.livingRoomIds.findLastIndex(
  702. (t) => t.roomId == that.selectRoomId
  703. );
  704. var livingRoom = that.model.livingRoomIds[index];
  705. httpAction(
  706. "business/busRoomBookingOrders/split-living?livingOrderId=" +
  707. livingRoom.livingOrder.id,
  708. {},
  709. "post"
  710. )
  711. .then((res) => {
  712. if (res.success) {
  713. that.$message.success("拆分成功");
  714. that.getBookingOrderInfo();
  715. that.$emit("ok");
  716. } else {
  717. that.$message.warning(res.message);
  718. }
  719. })
  720. .finally(() => {
  721. that.confirmLoading = false;
  722. });
  723. },
  724. });
  725. },
  726. addUnion() {
  727. if (this.selectRoomId === "1") {
  728. this.$message.warning("请先选择房间");
  729. return;
  730. }
  731. var index = this.model.livingRoomIds.findLastIndex(
  732. (t) => t.roomId == this.selectRoomId
  733. );
  734. var find = this.model.livingRoomIds[index];
  735. this.$refs.modalSelectCheckInRoomOrder.add();
  736. this.$refs.modalSelectCheckInRoomOrder.title = "请选择需要关联的订单";
  737. this.$refs.modalSelectCheckInRoomOrder.disableSubmit = false;
  738. this.$refs.modalSelectCheckInRoomOrder.livingOrderId =
  739. find.livingOrder.id;
  740. this.$refs.modalSelectCheckInRoomOrder.livingRoomId = find.roomId;
  741. },
  742. addLeaseGoods() {
  743. if (this.selectRoomId === "1") {
  744. this.$message.warning("请先选择房间");
  745. return;
  746. }
  747. var index = this.model.livingRoomIds.findLastIndex(
  748. (t) => t.roomId == this.selectRoomId
  749. );
  750. var find = this.model.livingRoomIds[index];
  751. this.$refs.modalLeaseGoods.add();
  752. this.$refs.modalLeaseGoods.title = "客人留言";
  753. this.$refs.modalLeaseGoods.disableSubmit = false;
  754. this.$refs.modalLeaseGoods.livingOrderId = find.livingOrder.id;
  755. },
  756. addMessage() {
  757. if (this.selectRoomId === "1") {
  758. this.$message.warning("请先选择房间");
  759. return;
  760. }
  761. var index = this.model.livingRoomIds.findLastIndex(
  762. (t) => t.roomId == this.selectRoomId
  763. );
  764. var find = this.model.livingRoomIds[index];
  765. this.$refs.modalMemberMessage.add();
  766. this.$refs.modalMemberMessage.title = "客人留言";
  767. this.$refs.modalMemberMessage.disableSubmit = false;
  768. this.$refs.modalMemberMessage.livingOrderId = find.livingOrder.id;
  769. },
  770. addProjectFee() {
  771. var index = this.model.livingRoomIds.findLastIndex(
  772. (t) => t.roomId == this.selectRoomId
  773. );
  774. var livingRoom = this.model.livingRoomIds[index];
  775. this.$refs.modalFeeForm.add();
  776. this.$refs.modalFeeForm.livingOrderId = livingRoom.livingOrder.id;
  777. this.$refs.modalFeeForm.title = "增加消费项目";
  778. this.$refs.modalFeeForm.disableSubmit = false;
  779. },
  780. partialSettle() {
  781. var list2 = this.feesList.filter((t) =>
  782. this.selectedRowKeys1.includes(t.id)
  783. );
  784. console.log(list2);
  785. var amount = list2.reduce(function (total, item) {
  786. return total + item.money;
  787. }, 0);
  788. var index = this.model.livingRoomIds.findLastIndex(
  789. (t) => t.roomId == this.selectRoomId
  790. );
  791. var livingRoom = this.model.livingRoomIds[index];
  792. this.$refs.modalPaymentForm.edit({
  793. billAmount: parseFloat(amount.toFixed(2)),
  794. deposit: 0,
  795. roomFee: parseFloat(amount.toFixed(2)),
  796. subjectType: 5,
  797. feeType: 2,
  798. bookingOrderId: this.model.orderInfo.id,
  799. livingOrderId:
  800. livingRoom.roomId != "1" ? livingRoom.livingOrder.id : "",
  801. preferentialType: 1,
  802. couponFirstAmount: 0,
  803. discount: 9,
  804. vipCustomerId: this.model.orderInfo.vipCustomerId,
  805. selectedFeeIds: this.selectedRowKeys1,
  806. });
  807. this.$refs.modalPaymentForm.title = "部分结账收款";
  808. this.$refs.modalPaymentForm.disableSubmit = false;
  809. },
  810. tabChange(e) {
  811. console.log(e);
  812. this.selectRoomId = e;
  813. if (e == "1") {
  814. this.feesList = this.oldfeesList;
  815. this.paymentList = this.oldpaymentList;
  816. } else {
  817. this.feesList = this.oldfeesList.filter((t) => t.roomId == e);
  818. this.paymentList = this.oldpaymentList.filter((t) => t.roomId == e);
  819. }
  820. },
  821. getPayTypeText(text) {
  822. var find = this.payTypeList.find((t) => t.id == text);
  823. return find ? find.name : "";
  824. },
  825. getRoomName(id) {
  826. var index = this.model.livingRoomIds.findLastIndex((t) => t.roomId == id);
  827. var find = this.model.livingRoomIds[index];
  828. return find ? find.roomName : "";
  829. },
  830. getSubjectTypeText(text) {
  831. var msg = "";
  832. if (text == 1) {
  833. msg = "押金";
  834. } else if (text == 2) {
  835. msg = "预收房费";
  836. } else if (text == 3) {
  837. msg = "每日房费";
  838. } else if (text == 4) {
  839. msg = "优惠金额";
  840. } else if (text == 5) {
  841. msg = "结账收款";
  842. } else if (text == 6) {
  843. msg = "商品";
  844. } else if (text == 7) {
  845. msg = "点餐";
  846. } else if (text == 8) {
  847. msg = "夜审房费";
  848. }
  849. return msg;
  850. },
  851. async getbusRoomPayType() {
  852. await getAction("/business/busRoomPayType/list", {
  853. pageSize: 99999,
  854. pageNo: 1,
  855. }).then((res) => {
  856. if (res.success) {
  857. this.payTypeList = res.result.records;
  858. }
  859. });
  860. },
  861. removeLivingCustomer(id) {
  862. deleteAction("/business/busLivingCustomer/delete", { id: id }).then(
  863. (res) => {
  864. if (res.success) {
  865. this.getBookingOrderInfo();
  866. }
  867. }
  868. );
  869. },
  870. addlivingCustomer(id, roomId) {
  871. console.log(id, roomId);
  872. this.$refs.modalCustomerForm.add(id, roomId);
  873. this.$refs.modalCustomerForm.title = "添加同住人";
  874. this.$refs.modalCustomerForm.disableSubmit = false;
  875. },
  876. modalFormOk(e) {
  877. this.getBookingOrderInfo();
  878. this.$emit("ok");
  879. },
  880. customerTypeName(customerType) {
  881. switch (customerType) {
  882. case 1:
  883. return "散客";
  884. case 2:
  885. return "会员";
  886. case 3:
  887. return "协议单位";
  888. case 4:
  889. return "中介";
  890. default:
  891. return "散客";
  892. }
  893. },
  894. warranterName(warranter) {
  895. var find = this.warranterList.find((t) => t.id == warranter);
  896. return find ? find.name : "--";
  897. },
  898. customerSourceName(customerSource) {
  899. var find = this.customerSourceList.find((t) => t.id == customerSource);
  900. return find ? find.itemText : "--";
  901. },
  902. getMemberCard() {
  903. getAction("/business/busMemberCard/list", {
  904. id: this.model.orderInfo.vipCustomerId,
  905. }).then((res) => {
  906. if (res.success) {
  907. if (res.result.records && res.result.records.length > 0) {
  908. this.vipCustomer = res.result.records[0];
  909. }
  910. }
  911. });
  912. },
  913. async getBookingOrderInfo() {
  914. if (this.payTypeList == 0) {
  915. await this.getbusRoomPayType();
  916. }
  917. var obj = {
  918. bookingNo: this.id,
  919. };
  920. if (this.key && this.key == 1) {
  921. obj = {
  922. bookingOrderId: this.id,
  923. };
  924. }
  925. getAction(this.url.getBookingOrderInfo, obj).then((res) => {
  926. if (res.success) {
  927. var livingRoomId = JSON.parse(
  928. JSON.stringify(res.result.livingRoomIds[0])
  929. );
  930. livingRoomId.roomId = "1";
  931. livingRoomId.roomName = "全部";
  932. var list = [];
  933. res.result.livingRoomIds.forEach((t) => {
  934. if (t.livingCustomers) {
  935. list = [...list, ...t.livingCustomers];
  936. }
  937. });
  938. livingRoomId.livingCustomers = list;
  939. res.result.livingRoomIds.unshift(livingRoomId);
  940. this.model = res.result;
  941. getAction("/business/busRoomBookingOrders/living-fees", {
  942. bookingOrderId: this.model.orderInfo.id,
  943. }).then((res) => {
  944. if (res.success) {
  945. if (res.result && res.result.length > 0) {
  946. this.feesList = res.result.filter((t) => t.feeType === 1);
  947. this.oldfeesList = JSON.parse(JSON.stringify(this.feesList));
  948. this.paymentList = res.result.filter((t) => t.feeType === 2);
  949. this.oldpaymentList = JSON.parse(
  950. JSON.stringify(this.paymentList)
  951. );
  952. }
  953. }
  954. });
  955. if (this.model.orderInfo.vipCustomerId) {
  956. this.getMemberCard();
  957. }
  958. }
  959. });
  960. },
  961. onSelectChange(selectedRowKeys, selectionRows) {
  962. this.selectedRowKeys = selectedRowKeys;
  963. this.selectionRows = selectionRows;
  964. },
  965. handleAdd() {
  966. var list = this.paymentList.filter((t) => t.subjectType === 1);
  967. var deposit = list.reduce(function (total, item) {
  968. return total + item.money;
  969. }, 0);
  970. var list2 = this.paymentList.filter((t) => t.subjectType === 2);
  971. var sum = list2.reduce(function (total, item) {
  972. return total + item.money;
  973. }, 0);
  974. var list3 = this.feesList.filter((t) => t.subjectType === 3);
  975. var sum2 = list3.reduce(function (total, item) {
  976. return total + item.money;
  977. }, 0);
  978. var index = this.model.livingRoomIds.findLastIndex(
  979. (t) => t.roomId == this.selectRoomId
  980. );
  981. var livingRoom = this.model.livingRoomIds[index];
  982. if (this.paymentAmount - this.feesAmount > 0) {
  983. this.$refs.modalRefundForm.edit({
  984. billRefund: this.paymentAmount - this.feesAmount,
  985. deposit: deposit - (sum - sum2),
  986. roomFee: sum - sum2,
  987. money: this.paymentAmount - this.feesAmount,
  988. subjectType: 5,
  989. feeType: 2,
  990. bookingOrderId: this.model.orderInfo.id,
  991. livingOrderId:
  992. livingRoom.roomId != "1" ? livingRoom.livingOrder.id : "",
  993. });
  994. this.$refs.modalRefundForm.title = "结账退款";
  995. this.$refs.modalRefundForm.disableSubmit = false;
  996. } else {
  997. this.$refs.modalPaymentForm.edit({
  998. billAmount: parseFloat(
  999. Math.abs(this.paymentAmount - this.feesAmount).toFixed(2)
  1000. ),
  1001. deposit: deposit - (sum - sum2),
  1002. roomFee: parseFloat(
  1003. Math.abs(this.paymentAmount - this.feesAmount).toFixed(2)
  1004. ),
  1005. subjectType: 5,
  1006. feeType: 2,
  1007. bookingOrderId: this.model.orderInfo.id,
  1008. livingOrderId:
  1009. livingRoom.roomId != "1" ? livingRoom.livingOrder.id : "",
  1010. preferentialType: 1,
  1011. couponFirstAmount: 0,
  1012. discount: 9,
  1013. vipCustomerId: this.model.orderInfo.vipCustomerId,
  1014. });
  1015. this.$refs.modalPaymentForm.title = "结账收款";
  1016. this.$refs.modalPaymentForm.disableSubmit = false;
  1017. }
  1018. },
  1019. puls() {
  1020. this.wakeList.push({});
  1021. },
  1022. remove(index) {
  1023. this.wakeList.splice(index, 1);
  1024. },
  1025. moment,
  1026. onChange(e) {
  1027. console.log(e);
  1028. },
  1029. add(id, key) {
  1030. this.key = key;
  1031. this.id = id;
  1032. this.edit(this.modelDefault);
  1033. this.getBookingOrderInfo();
  1034. },
  1035. edit(record) {
  1036. this.model = Object.assign({}, record);
  1037. this.visible = true;
  1038. },
  1039. handleLeaveNotSettle() {
  1040. if (this.selectRoomId === "1") {
  1041. this.$message.warning("请先选择房间");
  1042. return;
  1043. }
  1044. var index = this.model.livingRoomIds.findLastIndex(
  1045. (t) => t.roomId == this.selectRoomId
  1046. );
  1047. var find = this.model.livingRoomIds[index];
  1048. httpAction(
  1049. "/business/busRoomBookingOrders/leave-not-settle?bookingOrderId=" +
  1050. find.bookingOrdersId +
  1051. "&livingOrderId=" +
  1052. find.livingOrder.id,
  1053. {},
  1054. "post"
  1055. ).then((res) => {
  1056. if (res.success) {
  1057. this.$message.success(res.message);
  1058. this.getBookingOrderInfo();
  1059. this.$emit("ok");
  1060. } else {
  1061. this.$message.warning(res.message);
  1062. }
  1063. });
  1064. },
  1065. submitForm() {
  1066. const that = this;
  1067. that.$message.warning("未实现");
  1068. return;
  1069. // 触发表单验证
  1070. this.$refs.form.validate((valid) => {
  1071. if (valid) {
  1072. that.confirmLoading = true;
  1073. let httpurl = "";
  1074. let method = "";
  1075. if (!this.model.id) {
  1076. httpurl += this.url.add;
  1077. method = "post";
  1078. } else {
  1079. httpurl += this.url.edit;
  1080. method = "put";
  1081. }
  1082. httpAction(httpurl, this.model, method)
  1083. .then((res) => {
  1084. if (res.success) {
  1085. that.$message.success(res.message);
  1086. that.$emit("ok");
  1087. } else {
  1088. that.$message.warning(res.message);
  1089. }
  1090. })
  1091. .finally(() => {
  1092. that.confirmLoading = false;
  1093. });
  1094. }
  1095. });
  1096. },
  1097. },
  1098. };
  1099. </script>
  1100. <style scoped>
  1101. /deep/ .ant-btn-link {
  1102. flex: 1;
  1103. color: rgba(255, 141, 26, 1) !important;
  1104. }
  1105. .menu {
  1106. display: flex;
  1107. flex-direction: column;
  1108. flex: 1;
  1109. color: #fff;
  1110. margin-top: 12px;
  1111. }
  1112. .dynamic-delete-button {
  1113. cursor: pointer;
  1114. position: relative;
  1115. /* top: 4px; */
  1116. margin-left: 5px;
  1117. font-size: 18px;
  1118. color: #1890ff;
  1119. transition: all 0.3s;
  1120. }
  1121. .dynamic-delete-button:hover {
  1122. color: #777;
  1123. }
  1124. .dynamic-delete-button[disabled] {
  1125. cursor: not-allowed;
  1126. opacity: 0.5;
  1127. }
  1128. /deep/.ant-table-thead > tr > th {
  1129. background: rgba(42, 130, 228, 1);
  1130. color: #ffffff;
  1131. }
  1132. /deep/.ant-divider-horizontal {
  1133. margin: 12px 0 !important;
  1134. }
  1135. /deep/ .ant-table-tbody .ant-table-row td {
  1136. padding-top: 5px;
  1137. padding-bottom: 5px;
  1138. }
  1139. /deep/.ant-table-thead > tr > th,
  1140. .ant-table-tbody > tr > td {
  1141. padding: 5px 5px !important;
  1142. overflow-wrap: break-word;
  1143. }
  1144. #livingCustomers-grid [class~="ant-col"] {
  1145. border: #ccc 1px solid;
  1146. }
  1147. #livingCustomers-grid [class~="ant-col"]:last-child {
  1148. border: 0;
  1149. }
  1150. </style>