incomeDetail.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. <template>
  2. <view>
  3. <Header :borbtm="false" @change="headerChange">
  4. <template #search>
  5. <u-subsection :list="list" mode="subsection" :current="current" @change="topChange"></u-subsection>
  6. </template>
  7. <template #section>
  8. </template>
  9. </Header>
  10. <div v-if="current==0">
  11. <div class="content-detail">
  12. <div class="content-detail-top">
  13. <div>
  14. <div>
  15. 总营业额/元
  16. </div>
  17. <div>
  18. {{todayTotalIncome}}元
  19. </div>
  20. </div>
  21. <div>
  22. <div>
  23. 实收
  24. </div>
  25. <div>
  26. {{todayIncome.reduce((pre, cur) => pre+cur.amount,0 ) || 0}}元
  27. </div>
  28. </div>
  29. <div>
  30. <div>
  31. 欠款(预付)/元
  32. </div>
  33. <div>
  34. {{roomData.todayArrearsRoomData}}
  35. </div>
  36. </div>
  37. </div>
  38. <div class="content-detail-bottom">
  39. <!-- <div>
  40. <div>间夜数</div>
  41. <div>1234</div>
  42. </div> -->
  43. <div>
  44. <div>入住率</div>
  45. <div>{{((roomData.checkInRoomData/roomData.allRoomData) || 0).toFixed(2)}}%</div>
  46. </div>
  47. <div>
  48. <div>平均房价/元</div>
  49. <div>{{roomData.housingPrices}}</div>
  50. </div>
  51. <div>
  52. <div>RevPAR</div>
  53. <div v-if="roomData.checkInRoomData/roomData.allRoomData!=0 && roomData.allRoomData!=0" style="font-size: 18px;">{{((roomData.housingPrices*roomData.allRoomData)/(roomData.checkInRoomData/roomData.allRoomData).toFixed(2)).toFixed(2)}}</div>
  54. <div v-else style="font-size: 18px;">{{0}}</div>
  55. </div>
  56. </div>
  57. </div>
  58. <u-subsection style="margin-top:20px;" :list="listWay" mode="subsection" :current="currentWay" @change="WayChange"></u-subsection>
  59. <u-collapse @change="change" @close="close" @open="open" v-if="currentWay==0 && dataListTime.length>0">
  60. <u-collapse-item title="" name="Docs guide" v-for="(item, index) in dataListTime" :key="index">
  61. <b slot="title" class="u-page__item__title__slot-title">{{index+1}} {{item.roomName}} 收款合计{{item.detailList.reduce((pre, cur)=> pre+cur.money,0 )}}元</b>
  62. <div class="collapse-content" v-for="(sItem, index) in item.detailList" :key="index">
  63. <div>
  64. {{sItem.create_time}}
  65. </div>
  66. <div>
  67. {{sItem.money}}元/ {{sItem.subject_type_name}} / {{sItem.pay_name}}
  68. </div>
  69. <div>
  70. 收款人:
  71. </div>
  72. </div>
  73. </u-collapse-item>
  74. </u-collapse>
  75. <!-- <u-empty v-else mode="data" /> -->
  76. <u-collapse @change="change" @close="close" @open="open" v-if="currentWay==2 && dataListIncome.length>0">
  77. <u-collapse-item title="" name="Docs guide" v-for="(item, index) in dataListIncome" :key="index">
  78. <b slot="title" class="u-page__item__title__slot-title">{{index+1}} {{item.payTypeName}} 收款合计{{item.detailList.reduce((pre, cur)=> pre+cur.money,0 )}}元</b>
  79. <div class="collapse-content" v-for="(sItem, index) in item.detailList" :key="index">
  80. <div>
  81. {{sItem.create_time}}
  82. </div>
  83. <div>
  84. {{sItem.money}}元/ {{sItem.room_name}} / {{sItem.subject_type_name}}
  85. </div>
  86. <div>
  87. 收款人:
  88. </div>
  89. </div>
  90. </u-collapse-item>
  91. </u-collapse>
  92. <!-- <u-empty v-else mode="data" /> -->
  93. <uni-table style="margin-top:20px;" ref="table" :loading="false" border stripe type="" emptyText="暂无更多数据" @selection-change="selectionChange" v-if="currentWay==1">
  94. <uni-tr>
  95. <uni-th width="60" align="center">序号</uni-th>
  96. <uni-th width="60" align="center">时间</uni-th>
  97. <uni-th width="60" align="center">金额</uni-th>
  98. <uni-th width="60" align="center">房号</uni-th>
  99. <uni-th width="60" align="center">费项</uni-th>
  100. <uni-th width="60" align="center">收款方式</uni-th>
  101. </uni-tr>
  102. <uni-tr v-for="(item, index) in tableListIncome" :key="index">
  103. <uni-td align="center">{{ index+1 }}</uni-td>
  104. <uni-td>
  105. <view class="name">{{ item.create_time }}</view>
  106. </uni-td>
  107. <uni-td align="center">{{ item.money }}</uni-td>
  108. <uni-td align="center">{{ item.room_name }}</uni-td>
  109. <uni-td align="center">{{ item.subject_type_name }}</uni-td>
  110. <uni-td align="center">{{ item.pay_name }}</uni-td>
  111. </uni-tr>
  112. </uni-table>
  113. </div>
  114. <!-- 当日支出 -->
  115. <div v-if="current==1">
  116. <div class="content-detail">
  117. <div class="content-detail-top">
  118. <div>
  119. <div>
  120. 今日支出/元
  121. </div>
  122. <div>
  123. 65535元
  124. </div>
  125. </div>
  126. </div>
  127. <div class="content-detail-bottom">
  128. <div>
  129. <div>退还押金/元</div>
  130. <div>1234</div>
  131. </div>
  132. <div>
  133. <div>办公支出</div>
  134. <div>58</div>
  135. </div>
  136. <div>
  137. <div>租金支出/元</div>
  138. <div>325</div>
  139. </div>
  140. <div>
  141. <div>水电支出/元</div>
  142. <div>216</div>
  143. </div>
  144. </div>
  145. </div>
  146. <u-subsection style="margin-top:20px;" :list="listPay" mode="subsection" :current="currentPay" @change="PayChange"></u-subsection>
  147. <u-collapse @change="change" @close="close" @open="open" v-if="currentPay==0">
  148. <u-collapse-item title="" name="Docs guide" v-for="(item, index) in dataListPayProject" :key="index">
  149. <b slot="title" class="u-page__item__title__slot-title">01 退还押金 支出合计400 元</b>
  150. <div class="collapse-content" v-for="(sItem, index) in item.detailList || []" :key="index">
  151. <div>
  152. 2023/04/13 12:15
  153. </div>
  154. <div>
  155. 100.00元/ 房费 / 微信
  156. </div>
  157. <div>
  158. 操作员:沙暴蟑螂
  159. </div>
  160. </div>
  161. </u-collapse-item>
  162. </u-collapse>
  163. <u-collapse @change="change" @close="close" @open="open" v-if="currentPay==2">
  164. <u-collapse-item title="" name="Docs guide" v-for="(item, index) in dataListPay" :key="index">
  165. <b slot="title" class="u-page__item__title__slot-title">{{index+1}} {{item.payTypeName}} 支出合计{{item.detailList.reduce((pre, cur)=> pre+cur.money,0 ) || 0}} 元</b>
  166. <div class="collapse-content" v-for="(sItem, index) in item.detailList" :key="index">
  167. <div>
  168. {{sItem.create_time}}
  169. </div>
  170. <div>
  171. {{sItem.money}}元/ {{sItem.room_name}} / {{sItem.subject_type_name}}
  172. </div>
  173. <div>
  174. 收款人:
  175. </div>
  176. </div>
  177. </u-collapse-item>
  178. </u-collapse>
  179. <uni-table style="margin-top:20px;" ref="table" :loading="false" border stripe type="" emptyText="暂无更多数据" @selection-change="selectionChange" v-if="currentPay==1">
  180. <uni-tr>
  181. <uni-th width="60" align="center">序号</uni-th>
  182. <uni-th width="60" align="center">时间</uni-th>
  183. <uni-th width="60" align="center">金额</uni-th>
  184. <!-- <uni-th width="60" align="center">房号</uni-th> -->
  185. <uni-th width="60" align="center">事项</uni-th>
  186. <uni-th width="60" align="center">支出方式</uni-th>
  187. </uni-tr>
  188. <uni-tr v-for="(item, index) in tableListPay" :key="index">
  189. <uni-td align="center">{{ index+1 }}</uni-td>
  190. <uni-td>
  191. <view class="name">{{ item.create_time }}</view>
  192. </uni-td>
  193. <uni-td align="center">{{ item.money }}</uni-td>
  194. <uni-td align="center">{{ item.subject_type_name }}</uni-td>
  195. <uni-td align="center">{{ item.pay_name }}</uni-td>
  196. </uni-tr>
  197. </uni-table>
  198. </div>
  199. <HistoricalIncome v-if="current==2" />
  200. </view>
  201. </template>
  202. <script>
  203. import Header from '../header.vue'
  204. import PayMethodsVue from '../tableCharts/payMethods.vue'
  205. import RoomTypeVue from '../tableCharts/roomType.vue'
  206. import Time from '../tableCharts/time.vue'
  207. import FeeItemsVue from '../tableCharts/feeItems.vue'
  208. import SourceVue from '../tableCharts/source.vue'
  209. import CustomerTypeVue from '../tableCharts/customerType.vue'
  210. import OccupancyTypeVue from '../tableCharts/occupancyType.vue'
  211. import HistoricalIncome from './historicalIncome.vue'
  212. import {
  213. getRoomIncomeList,
  214. getTimeIncomeList,
  215. getPayMethodIncomeList,
  216. getMatterExpenditureList,
  217. getTimeExpenditureList,
  218. getPayMethodExpenditureList,
  219. } from '../../utils/incomeDetail'
  220. import {
  221. getHotelList,
  222. getRevPAR,
  223. getTodayIncome,
  224. getTodayTotalIncome,
  225. getStaySource,
  226. getRoomStatus,
  227. getIncomeAndExpenditure
  228. } from '../../utils/api.js';
  229. export default {
  230. components: {
  231. Header,
  232. Time,
  233. PayMethodsVue,
  234. RoomTypeVue,
  235. FeeItemsVue,
  236. SourceVue,
  237. CustomerTypeVue,
  238. OccupancyTypeVue,
  239. HistoricalIncome
  240. },
  241. data() {
  242. return {
  243. list: ['当日收入', '当日支出', '历史收入', '历史支出'],
  244. listWay: ['按房间', '按时间', '按收款方式'],
  245. listPay: ['按支出事项', '按支出时间', '按付款方式'],
  246. payMethodsList: ['查看营业额', '查看实收'],
  247. current: 0,
  248. currentWay: 0,
  249. currentPayMethods: 0,
  250. currentPay: 0,
  251. rangeTime: [{
  252. value: 0,
  253. text: "按日"
  254. },
  255. {
  256. value: 1,
  257. text: "按月"
  258. },
  259. {
  260. value: 2,
  261. text: "按季度"
  262. },
  263. {
  264. value: 3,
  265. text: "按年"
  266. },
  267. ],
  268. rangeDay: [{
  269. value: 0,
  270. text: "按营业日"
  271. },
  272. {
  273. value: 1,
  274. text: "按自然日"
  275. }
  276. ],
  277. timeCheck: 0,
  278. dayCheck: 0,
  279. startTime: (new Date().toLocaleDateString()).replace(/\//g, '-'),
  280. endTime: (new Date(new Date().getTime() + 24 * 60 * 60 * 1000).toLocaleDateString()).replace(/\//g, '-'),
  281. show: false,
  282. dataListTime:[],
  283. dataListIncome:[],
  284. dataListPay:[],
  285. dataListPayProject: [],
  286. tableListIncome: [],
  287. tableListPay: [],
  288. todayTotalIncome: 0, //今日总收款
  289. roomData: {
  290. //房间总数
  291. allRoomData: 0,
  292. //入住总数
  293. checkInRoomData: 0,
  294. //平均房价
  295. housingPrices: 0,
  296. // 今日预离
  297. todayLeaveRoomData: 0,
  298. //今日预抵
  299. todayArriveRoomData: 0,
  300. //今日欠费
  301. todayArrearsRoomData: 0,
  302. //脏房
  303. dirtyRoomData: 0,
  304. },
  305. todayIncome:[],
  306. }
  307. },
  308. mounted() {
  309. this.getData()
  310. },
  311. methods: {
  312. topChange(e) {
  313. this.current = e
  314. this.getData()
  315. },
  316. changeTime(e) {
  317. this.timeCheck = e
  318. },
  319. changeDay(e) {
  320. this.dayCheck = e
  321. },
  322. WayChange(e) {
  323. this.currentWay = e
  324. this.getData()
  325. },
  326. PayChange(e) {
  327. this.currentPay = e
  328. this.getData()
  329. },
  330. // 手风琴部分
  331. change(e) {
  332. console.log(e);
  333. },
  334. close(e) {
  335. console.log(e);
  336. },
  337. open(e) {
  338. console.log(e);
  339. },
  340. headerChange(e){
  341. console.log(e);
  342. this.getData()
  343. },
  344. getData() {
  345. getTodayTotalIncome({
  346. startTime: this.startTime,
  347. endTime: this.endTime
  348. }).then(res => {
  349. console.log(res);
  350. if (res.code == 200 && res.result.records.length > 0) {
  351. let brr = []
  352. let data = res.result.records
  353. data.forEach(item => {
  354. let arr = []
  355. arr = Object.keys(item).filter(items => items != 'department' && items != 'hotel_name')
  356. brr = Object.keys(item).filter(items => items == '现金' || items == '微信' || items == '支付宝')
  357. console.log(arr);
  358. arr.forEach(ele => {
  359. this.todayTotalIncome += item[ele] * 1
  360. })
  361. })
  362. let obj = {}
  363. let copy = []
  364. brr.forEach((item, i) => {
  365. console.log(obj);
  366. copy.push({
  367. name: item,
  368. amount: data.reduce((pre, cur) => {
  369. return pre + cur[item]
  370. }, 0)
  371. })
  372. })
  373. // this.paymentMethod = copy
  374. // console.log('2222222222', copy);
  375. // console.log(this.todayTotalIncome);
  376. } else {
  377. this.todayTotalIncome = 0
  378. }
  379. })
  380. // 房间数据统计
  381. getRevPAR({
  382. startTime: this.startTime,
  383. endTime: this.endTime
  384. }).then(res => {
  385. if (res.code == 200 && res.result.length > 0) {
  386. this.roomData.allRoomData = res.result[0]
  387. this.roomData.checkInRoomData = res.result[1]
  388. this.roomData.housingPrices = res.result[2]
  389. this.roomData.todayLeaveRoomData = res.result[3]
  390. this.roomData.todayArriveRoomData = res.result[4]
  391. this.roomData.todayArrearsRoomData = res.result[5]
  392. this.roomData.dirtyRoomData = res.result[6]
  393. }
  394. })
  395. //今日收入统计
  396. getTodayIncome({
  397. startTime: this.startTime,
  398. endTime: this.endTime
  399. }).then(res => {
  400. if (res.code == 200 && res.result.length > 0) {
  401. console.log(res.result);
  402. this.todayIncome = res.result
  403. } else {
  404. this.todayIncome = [{
  405. name: '押金',
  406. amount: 0
  407. },
  408. {
  409. name: '房费',
  410. amount: 0
  411. },
  412. {
  413. name: '商品',
  414. amount: 0
  415. }
  416. ]
  417. }
  418. })
  419. if (this.current == 0 && this.currentWay == 0) {
  420. getRoomIncomeList({startTime:this.startTime, endTime:this.endTime}).then(res => {
  421. console.log(res);
  422. if (res.code == 200) {
  423. this.dataListTime = res.result
  424. }
  425. })
  426. }
  427. if (this.current == 0 && this.currentWay == 1) {
  428. getTimeIncomeList({startTime:this.startTime, endTime:this.endTime}).then(res => {
  429. console.log(res);
  430. if (res.code == 200) {
  431. this.tableListIncome = res.result
  432. }
  433. })
  434. }
  435. if (this.current == 0 && this.currentWay == 2) {
  436. getPayMethodIncomeList({startTime:this.startTime, endTime:this.endTime}).then(res => {
  437. console.log(res);
  438. if (res.code == 200) {
  439. this.dataListIncome = res.result
  440. }
  441. })
  442. }
  443. if (this.current == 1 && this.currentPay == 0) {
  444. getMatterExpenditureList().then(res => {
  445. console.log(res);
  446. })
  447. }
  448. if (this.current == 1 && this.currentPay == 1) {
  449. getTimeExpenditureList().then(res => {
  450. console.log(res);
  451. if (res.code == 200) {
  452. this.tableListPay = res.result
  453. }
  454. })
  455. }
  456. if (this.current == 1 && this.currentPay == 2) {
  457. getPayMethodExpenditureList().then(res => {
  458. console.log(res);
  459. if (res.code == 200) {
  460. this.dataListPay = res.result
  461. }
  462. })
  463. }
  464. }
  465. }
  466. }
  467. </script>
  468. <style lang="scss" scoped>
  469. .pages {
  470. width: 100vw;
  471. height: 100vh;
  472. background-color: #f5f5f5;
  473. }
  474. .calendar {
  475. border: 1px solid;
  476. padding: 5px 10px;
  477. border-radius: 5px;
  478. color: #409EFF;
  479. font-size: 12px;
  480. // min-width: 30%;
  481. margin-left: 10px;
  482. display: flex;
  483. align-items: center;
  484. }
  485. .content-detail {
  486. background: #409EFF;
  487. padding: 10px;
  488. display: flex;
  489. flex-direction: column;
  490. box-shadow: 0 0 10px #000;
  491. color: #fff;
  492. height: 130px;
  493. justify-content: space-between;
  494. .content-detail-top {
  495. display: flex;
  496. justify-content: space-between;
  497. margin-bottom: 10px;
  498. div {
  499. display: flex;
  500. flex-direction: column;
  501. justify-content: center;
  502. align-items: center;
  503. flex: 1;
  504. }
  505. }
  506. .content-detail-bottom {
  507. display: flex;
  508. justify-content: space-between;
  509. div {
  510. display: flex;
  511. flex-direction: column;
  512. justify-content: center;
  513. align-items: center;
  514. flex: 1;
  515. font-size: 16px;
  516. }
  517. }
  518. }
  519. .collapse-content {
  520. display: flex;
  521. justify-content: space-between;
  522. align-items: center;
  523. font-size: 12px;
  524. }
  525. </style>