consumption.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608
  1. <template>
  2. <div class="consump-layout">
  3. <div class="c-header">
  4. <ul class="tab-list">
  5. <li @click="active = i" :class="{active:i===active}" v-for="(item,i) in tabList" :key="i">
  6. {{item.name}}
  7. </li>
  8. </ul>
  9. <!-- <div class="tab-search" v-else :style="{border:!deviceLogin?'1px solid #ccc':'none'}">
  10. <template v-if="!deviceLogin">
  11. <input v-model="searchKey" @keyup.enter="getList(searchKey)" type="text" :placeholder="$t('manage.Spending.placeholdersearchID')">
  12. <i class="iconfont icon-sousuo" @click="getList(searchKey)"></i>
  13. </template>
  14. </div> -->
  15. </div>
  16. <div class="table-list">
  17. <div class="invoices" v-if="active===2">
  18. <span>相机</span>
  19. <div v-if="!deviceLogin" class="tab-select" ref="deviceMenu" @click="deviceActive=!deviceActive" :class="{'tab-active':deviceActive}">
  20. {{activeDevice||'暂无相机'}}
  21. <ul>
  22. <li v-for="(item,i) in invoicedevice" @click="selectInId(item)" :key="i" >{{item.childName}}</li>
  23. </ul>
  24. </div>
  25. <span v-else>{{deviceLogin}} </span>
  26. <div v-if="active===2 && !deviceLogin" class="tab-select" ref="invoiceMenu" @click="tabActive=!tabActive" :class="{'tab-active':tabActive}">
  27. {{activeType}}
  28. <ul>
  29. <li v-for="(item,i) in cameraList" @click="selectCamTy(item)" :key="i">{{item.name}}</li>
  30. </ul>
  31. </div>
  32. <span>可开票额度(元){{max}}</span>
  33. <div class="btn default" :class="{parmary:max>0&&!deviceLogin}" @click="openInvice">开票</div>
  34. </div>
  35. <tableList :header='tabHeader' :data='data' >
  36. <div slot-scope="{data}" slot="header">
  37. {{data.name}}
  38. </div>
  39. <div slot-scope="{data,canclick,item, subKey}" slot="item">
  40. <span class="edit" v-if="canclick" @click="showDetail(item)">{{data}}</span>
  41. <span v-else-if="subKey === 'payType'">{{ PAYSIDMAP[data] }}</span>
  42. <span v-else>{{data}}</span>
  43. </div>
  44. </tableList>
  45. <div class="paging" v-if="total">
  46. <vcenter>
  47. <Paging @clickHandle="pageChange" :current="currentPage" :total="total" :equable="pageSize" />
  48. </vcenter>
  49. </div>
  50. <div class="scene-nothing" v-if="!total">
  51. <img :src="`${$cdn}images/nothing.png`" >
  52. <div>{{$t('manage.Spending.norecord')}}</div>
  53. </div>
  54. </div>
  55. </div>
  56. </template>
  57. <script>
  58. import { mapState } from 'vuex'
  59. import tableList from '@/components/table'
  60. import {capacity, recharge, invoice} from './iconsumption'
  61. import Paging from '@/components/Paging'
  62. import vcenter from '@/components/vcenter'
  63. import MemberApi from '@/apis/member'
  64. import MallConfig from '@/config/mall'
  65. let AMOUNTSTR = {
  66. 0: '¥',
  67. 1: '¥',
  68. 2: '$'
  69. }
  70. let methodStr = {
  71. 0: 'getMemberOrderList',
  72. 1: 'getChargeList',
  73. 2: 'getInvoiceList'
  74. }
  75. let rechargeType = {
  76. 0: '系统赠送',
  77. '-1': '支出',
  78. 1: '充值',
  79. 2: '系统退充值'
  80. }
  81. let invoceStatusType = {
  82. 0: '未开票',
  83. 1: '已开票'
  84. }
  85. let invoiceType = {
  86. 1: '不需要发票',
  87. 2: '增值税普通发票',
  88. 3: '增值税专用发票'
  89. }
  90. export default {
  91. components: {
  92. tableList,
  93. Paging,
  94. vcenter
  95. },
  96. data () {
  97. let cameraList = [
  98. {
  99. name: '全部',
  100. id: ''
  101. },
  102. {
  103. name: '二目充值',
  104. id: 0
  105. },
  106. {
  107. name: '会员权益',
  108. id: 4
  109. }
  110. ]
  111. return {
  112. PAYSIDMAP: MallConfig.PAYSIDMAP,
  113. tabHeader: capacity,
  114. data: [],
  115. cameraList,
  116. active: 0,
  117. recharge,
  118. total: 30,
  119. pageSize: 10,
  120. currentPage: 1,
  121. tabActive: false,
  122. deviceActive: false,
  123. max: 0,
  124. activeDevice: '',
  125. activeType: '全部',
  126. activeId: '',
  127. activeTypeId: '',
  128. tabList: [
  129. {
  130. name: this.$t('manage.Spending.tabListMember')
  131. },
  132. {
  133. name: this.$t('manage.Spending.tabListRecharge')
  134. },
  135. {
  136. name: this.$t('manage.Spending.tabListInvoice')
  137. },
  138. ]
  139. }
  140. },
  141. computed: {
  142. ...mapState({
  143. token: state => state.user.token,
  144. language: state => state.language.current,
  145. deviceLogin: state => state.user.deviceLogin,
  146. // myexpansion: state => {
  147. // let type = Object.prototype.toString.call(state.user.myexpansion)
  148. // if (type === '[object Object]') {
  149. // return state.user.myexpansion
  150. // }
  151. // let condition = state.user.myexpansion && state.user.myexpansion !== 'null' && type !== '[object Array]'
  152. // return (condition ? JSON.parse(state.user.myexpansion) : {})
  153. // },
  154. mycharge: state => {
  155. let type = Object.prototype.toString.call(state.user.mycharge)
  156. if (type === '[object Object]') {
  157. return state.user.mycharge
  158. }
  159. let condition = state.user.mycharge && state.user.mycharge !== 'null' && type !== '[object Array]'
  160. return (condition ? JSON.parse(state.user.mycharge) : {})
  161. },
  162. myinvoicelist: state => {
  163. let type = Object.prototype.toString.call(state.user.myinvoicelist)
  164. if (type === '[object Object]') {
  165. return state.user.myinvoicelist
  166. }
  167. let condition = state.user.myinvoicelist && state.user.myinvoicelist !== 'null' && type !== '[object Array]'
  168. return (condition ? JSON.parse(state.user.myinvoicelist) : {})
  169. },
  170. invoicedevice: state => {
  171. let type = Object.prototype.toString.call(state.user.invoicedevice)
  172. if (type === '[object Object]') {
  173. return state.user.invoicedevice
  174. }
  175. let condition = state.user.invoicedevice && state.user.invoicedevice !== 'null'
  176. return (condition ? state.user.invoicedevice : [])
  177. },
  178. searchKey () {
  179. return this.$parent.searchKey
  180. }
  181. })
  182. },
  183. watch: {
  184. currentPage (newVal) {
  185. this.getList()
  186. },
  187. language (newVal) {
  188. this.active = 0
  189. this.data.forEach(item => {
  190. let condition = item['validDate'] === '终身有效' ? (newVal === 'en' ? 'N/A' : '终身有效') : item['validDate']
  191. item['validDateStr'] = condition
  192. item['unitSize1'] = item['unitSize'] + item['unit'] + '/' + this.$t(`manage.shixian.${item['month']}`)
  193. item['channel'] = this.$t(`manage.channelType.${item['status']}`)
  194. item['amount1'] = AMOUNTSTR[item['payType']] + item['amount']
  195. item['payTypeStr'] = this.$t(`manage.PAYSSTR.${item['payType']}`)
  196. })
  197. },
  198. activeId (newVal) {
  199. if (this.active === 2) {
  200. this.getList()
  201. }
  202. this.getInvoiceMax()
  203. },
  204. activeTypeId (newVal) {
  205. if (this.active === 2) {
  206. this.getList()
  207. }
  208. },
  209. active (newVal) {
  210. switch (newVal) {
  211. case 1:
  212. this.tabHeader = recharge
  213. break
  214. case 2:
  215. !this.deviceLogin && this.getAllDevice()
  216. this.tabHeader = invoice
  217. break
  218. default:
  219. this.tabHeader = capacity
  220. break
  221. }
  222. if (newVal !== 1) {
  223. this.$emit('changeSearchShow', false)
  224. } else {
  225. this.$emit('changeSearchShow', true)
  226. }
  227. this.currentPage === 1 ? this.getList() : this.currentPage = 1
  228. }
  229. },
  230. methods: {
  231. pageChange (data) {
  232. this.currentPage = data
  233. },
  234. selectInId (item) {
  235. this.activeDevice = item.childName
  236. this.activeId = item.id
  237. },
  238. selectCamTy (item) {
  239. this.activeType = item.name
  240. this.activeTypeId = item.id
  241. },
  242. showDetail (item) {
  243. this.$toast.showInvoiceDetail(item)
  244. },
  245. getList (searchKey = '') {
  246. window.scrollTo(0, 0)
  247. let str = methodStr[this.active]
  248. this[str](searchKey)
  249. },
  250. openInvice () {
  251. let params = {
  252. max: this.max,
  253. cameraId: this.activeId
  254. };
  255. (this.max && !this.deviceLogin) && this.$toast.showInvoice(params)
  256. },
  257. async getAllDevice (searchKey = '') {
  258. let params = {
  259. cameraType: ''
  260. }
  261. await this.$store.dispatch('getInvoiceDevice', params)
  262. this.activeDevice = this.invoicedevice[0].childName
  263. this.activeId = this.invoicedevice[0].id
  264. },
  265. // 扩容记录
  266. async getConsumpList (searchKey = '') {
  267. if (this.deviceLogin) {
  268. searchKey = this.deviceLogin
  269. }
  270. let data = {
  271. params: {
  272. childName: searchKey.trim(),
  273. pageNum: searchKey ? 1 : this.currentPage,
  274. pageSize: this.pageSize
  275. },
  276. url: this.deviceLogin ? '/device/virtualOrder/expansionList' : '/user/virtualOrder/expansionList'
  277. }
  278. await this.$store.dispatch('getUserExpansion', data)
  279. if (!this.myexpansion.total && searchKey && !this.deviceLogin) {
  280. return this.$toast.show('warn', this.$t('toast.25'), () => {
  281. this.getList()
  282. })
  283. }
  284. console.log(this.myexpansion, 'this.myexpansion')
  285. this.pageSize = this.myexpansion.pageSize
  286. this.total = this.myexpansion.total || 0
  287. this.data = this.myexpansion.list
  288. this.data.forEach(item => {
  289. let condition = item['validDate'] === '终身有效' ? (this.language === 'en' ? 'N/A' : '终身有效') : item['validDate']
  290. item['validDateStr'] = condition
  291. item['statusStr'] = this.$t(`manage.myOrders.${item['status']}`)
  292. item['unitSize1'] = item['unitSize'] + item['unit'] + '/' + this.$t(`manage.shixian.${item['month']}`)
  293. item['channel'] = this.$t(`manage.channelType.${item['status']}`)
  294. item['amount1'] = AMOUNTSTR[item['payType']] + item['amount']
  295. item['payTypeStr'] = this.$t(`manage.PAYSSTR.${item['payType']}`)
  296. })
  297. },
  298. getMemberOrderList () {
  299. let data = {
  300. snCode: this.searchKey,
  301. pageNum: this.currentPage,
  302. pageSize: this.pageSize
  303. }
  304. MemberApi.getVirtualOrderList(data).then(res => {
  305. this.data = res.data.data.list
  306. console.log(this.data)
  307. this.total = res.data.data.total
  308. })
  309. },
  310. async getInvoiceMax () {
  311. let res = await this.$http({
  312. method: 'post',
  313. data: {
  314. cameraId: this.activeId
  315. },
  316. headers: {
  317. token: this.token
  318. },
  319. url: '/user/invoice/max'
  320. })
  321. let data = res.data
  322. if (data.code !== 0) return
  323. this.max = data.data.maxInvoice
  324. },
  325. // 充值记录
  326. async getChargeList (searchKey = '') {
  327. if (this.deviceLogin) {
  328. searchKey = this.deviceLogin
  329. }
  330. let data = {
  331. params: {
  332. childName: searchKey,
  333. pageNum: searchKey ? 1 : this.currentPage,
  334. pageSize: this.pageSize
  335. },
  336. url: this.deviceLogin ? '/device/virtualOrder/chargeList' : '/user/virtualOrder/chargeList'
  337. }
  338. await this.$store.dispatch('getChargeList', data)
  339. if (!this.mycharge.total && searchKey && !this.deviceLogin) {
  340. return this.$toast.show('warn', this.$t('toast.25'), () => {
  341. this.getList()
  342. })
  343. }
  344. this.pageSize = this.mycharge.pageSize
  345. this.total = this.mycharge.total || 0
  346. this.data = this.mycharge.list
  347. this.data.forEach(item => {
  348. item['status'] = rechargeType[item['status']]
  349. })
  350. },
  351. // 发票记录
  352. async getInvoiceList () {
  353. let data = {
  354. params: {
  355. cameraId: this.activeId,
  356. pageNum: this.currentPage,
  357. pageSize: this.pageSize,
  358. type: this.activeTypeId
  359. },
  360. url: this.deviceLogin ? '/device/invoice/list' : '/user/invoice/list'
  361. }
  362. await this.$store.dispatch('getInvoiceList', data)
  363. this.pageSize = this.myinvoicelist.pageSize
  364. this.total = this.myinvoicelist.total || 0
  365. this.data = this.myinvoicelist.list
  366. this.data.forEach(item => {
  367. item['detail'] = '详细'
  368. item['money'] = '¥' + item['money']
  369. item['finish'] = invoceStatusType[item['finish']]
  370. item['type'] = invoiceType[item['type']]
  371. })
  372. },
  373. handleSearch (keyword) {
  374. this.getList(keyword)
  375. }
  376. },
  377. mounted () {
  378. this.getList()
  379. this.$bus.$off('refreshInvoice')
  380. this.$bus.$on('refreshInvoice', () => {
  381. if (this.active === 2) {
  382. this.getList()
  383. }
  384. this.getInvoiceMax()
  385. })
  386. document.addEventListener('click', (e) => {
  387. if (this.$refs.invoiceMenu) {
  388. if (!this.$refs.invoiceMenu.contains(e.target)) {
  389. this.tabActive = false
  390. }
  391. }
  392. if (this.$refs.deviceMenu) {
  393. if (!this.$refs.deviceMenu.contains(e.target)) {
  394. this.deviceActive = false
  395. }
  396. }
  397. })
  398. }
  399. }
  400. </script>
  401. <style lang="scss" scoped>
  402. $theme-color: #15BEC8;
  403. $font-color: #2d2d2d;
  404. $border-color: #d9d9d9;
  405. .btn {
  406. text-align: center;
  407. cursor: pointer;
  408. }
  409. .default {
  410. width: 88px;
  411. height: 28px;
  412. line-height: 28px;
  413. font-size: 14px;
  414. background-color: #e7e7e7;
  415. cursor: initial;
  416. }
  417. .parmary {
  418. background-color: $theme-color;
  419. cursor: pointer;
  420. }
  421. .consump-layout{
  422. .c-header{
  423. .tab-list{
  424. display: flex;
  425. color: #323233;
  426. li{
  427. line-height: 32px;
  428. cursor: pointer;
  429. font-size: 14px;
  430. background: #EBEBEB;
  431. width: 104px;
  432. text-align: center;
  433. margin-right: 1px;
  434. }
  435. .active{
  436. background: #ffff;
  437. position: relative;
  438. border: 1px solid rgba(235, 235, 235, 1);
  439. border-bottom: none;
  440. &::after {
  441. content: '';
  442. display: block;
  443. height: 1px;
  444. width: 100%;
  445. background: #fff;
  446. position: absolute;
  447. bottom: -1px;
  448. }
  449. }
  450. }
  451. }
  452. .invoices{
  453. display: flex;
  454. align-items: center;
  455. margin-top: 17px;
  456. position: relative;
  457. span{
  458. font-size: 14px;
  459. margin-right: 20px;
  460. }
  461. .tab-select{
  462. margin-right: 20px;
  463. }
  464. .default {
  465. position: absolute;
  466. right: 0;
  467. cursor: pointer;
  468. line-height: 32px;
  469. width: 104px;
  470. height: 32px;
  471. }
  472. }
  473. .tab-search{
  474. float: right;
  475. position: relative;
  476. width: 200px;
  477. padding-left: 10px;
  478. margin-right: 15px;
  479. border: 1px solid #ccc;
  480. display: flex;
  481. .iconfont{
  482. width: 28px;
  483. height: 28px;
  484. padding: 6px;
  485. background: #e4e4e4;
  486. cursor: pointer;
  487. }
  488. input{
  489. width: 100%;
  490. font-size: 14px;
  491. appearance: none;
  492. line-height: 28px;
  493. height: 28px;
  494. border: 0;
  495. }
  496. }
  497. .tab-select{
  498. float: right;
  499. position: relative;
  500. width: 200px;
  501. height: 32px;
  502. line-height: 32px;
  503. padding-left: 10px;
  504. border: 1px solid $border-color;
  505. font-size: 14px;
  506. color: #969696;
  507. cursor: pointer;
  508. &::after{
  509. position: absolute;
  510. right: 10px;
  511. top: 50%;
  512. transform: translateY(calc(-50% + 3px));
  513. content: '';
  514. width: 0;
  515. height: 0;
  516. border: 5px solid;
  517. display: inline-block;
  518. border-color: #828282 transparent transparent;
  519. }
  520. ul{
  521. position: absolute;
  522. max-height: 0;
  523. left: 0;
  524. top: 34px;
  525. background: #fff;
  526. overflow: hidden;
  527. width: 100%;
  528. transition:all 0.3s ease;
  529. box-shadow: 0 0 10px rgba($color: #000000, $alpha: 0.4);
  530. li{
  531. padding-left: 10px;
  532. &:hover{
  533. background: $theme-color;
  534. color: #2d2d2d;
  535. }
  536. }
  537. }
  538. }
  539. .tab-active{
  540. ul{
  541. max-height: 220px;
  542. overflow: auto;
  543. }
  544. }
  545. .table-list{
  546. padding: 0 30px;
  547. &>div{
  548. width: 100%;
  549. }
  550. .edit{
  551. color: $theme-color;
  552. cursor: pointer;
  553. }
  554. }
  555. .scene-nothing{
  556. padding: 42px 0 0 40px;
  557. text-align: center;
  558. img{
  559. padding-bottom: 22px;
  560. }
  561. div{
  562. font-size: 16px;
  563. color: #969696;
  564. text-align: center;
  565. }
  566. }
  567. .paging {
  568. height: 100%;
  569. }
  570. }
  571. </style>
  572. <style lang="less">
  573. .consump-layout {
  574. .table-list {
  575. border: 1px solid rgba(235, 235, 235, 1);
  576. .t-header, .t-item {
  577. line-height: 52px;
  578. border-bottom: 1px solid rgba(32, 32, 32, 0.2);
  579. font-size: 14px;
  580. padding: 0 !important;
  581. }
  582. }
  583. }
  584. </style>