InvoiceInfo.vue 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. <template>
  2. <div class="invoice-info">
  3. <info-card title="开票概览">
  4. <div class="invoice-info-content">
  5. <div class="invoice-info-item">
  6. 开票状态:{{ getInvoiceStatus(orderDetail?.orderData?.invoiced_status) }}
  7. </div>
  8. <div class="invoice-info-item">
  9. 已开票金额:¥{{ formatNumber(invoiceData?.invoiceMoney || 0) }}
  10. </div>
  11. <div class="invoice-info-item">
  12. 未开票金额:¥{{ formatNumber(invoiceData?.remainingMoney || 0) }}
  13. </div>
  14. </div>
  15. </info-card>
  16. <info-card title="开票详情" :length="invoiceList.length || 0" :is-show-length="true">
  17. <div class="invoice-info-detail">
  18. <TableCard
  19. class="invoice-info-content-table"
  20. :table-data="invoiceList"
  21. :columns="invoiceColumns"
  22. width="1108px"
  23. >
  24. <template #code_url-header>
  25. <div class="column-label-cell">
  26. <div class="column-label-cell-title">操作</div>
  27. <div class="column-label-cell-tip">查看开票二维码,支持客户扫码换开或查看发票</div>
  28. </div>
  29. </template>
  30. <template v-slot:id="{ row }">
  31. <span class="column-cell" @click="getInvoiceDetailInfo(row.row)">{{ row.row.id }}</span>
  32. </template>
  33. <template v-slot:code_url="{ row }">
  34. <div class="invoice-info-action">
  35. <span class="column-cell" v-if="row.row.code_url" @click="getInvoiceInfo(row.row)">查看开票二维码</span>
  36. <span class="column-cell" v-if="showAgainBtn(row.row)" @click="againInvoce(row.row)">重新开票</span>
  37. <span class="column-cell" v-if="showEditBtn()" @click="editInvoice(row.row)">编辑发票</span>
  38. </div>
  39. </template>
  40. <template v-slot:invoice_money="{ row }">
  41. <span>¥{{ formatNumber(row.row.invoice_money) }}</span>
  42. </template>
  43. <template v-slot:invoice_status="{ row }">
  44. <span>{{ backInvoiceStatus(row.row.invoice_status) }}</span>
  45. </template>
  46. </TableCard>
  47. </div>
  48. </info-card>
  49. <new-set-order-info
  50. ref="invoiceRef"
  51. :show-content="4"
  52. :show-dialog="showInvoiceDialog"
  53. :orderInfo="orderData"
  54. title="开票二维码"
  55. @close="showInvoiceDialog = false"
  56. >
  57. <div style="display:flex;flex-direction:column;" slot="content">
  58. <span>订单编号:{{selectInvoice.invoice_order_code}}</span>
  59. <span>开票金额合计:{{selectInvoice.invoice_money / 100}}元</span>
  60. </div>
  61. </new-set-order-info>
  62. <new-code-model
  63. ref="invoiceDetailRef"
  64. :codeDetail="selectInvoice"
  65. />
  66. </div>
  67. </template>
  68. <script>
  69. import InfoCard from '../../ui/InfoCard.vue';
  70. import TableCard from '../../ui/TableCard.vue';
  71. import newSetOrderInfo from '../newSetOrderInfo.vue';
  72. import newCodeModel from '@/views/order/components/new-codeModel.vue';
  73. import { mapState } from 'vuex';
  74. export default {
  75. name: 'InvoiceInfo',
  76. components: {
  77. InfoCard,
  78. TableCard,
  79. newSetOrderInfo,
  80. newCodeModel
  81. },
  82. data() {
  83. return {
  84. invoiceColumns: [
  85. { prop: 'id', label: '发票ID', width: 160 },
  86. { prop: 'invoice_serialnum', label: '发票编号', width: 160, render: (row) => row.invoice_serialnum || '-' },
  87. { prop: 'invoice_money', label: '关联订单开票金额', width: 160 },
  88. { prop: 'invoice_status', label: '发票状态', width: 120 },
  89. { prop: 'code_url', label: '开票二维码', width: 188 },
  90. { prop: 'operable_time', label: '操作时间', width: 160 },
  91. { prop: 'operator', label: '操作人', width: 160 }
  92. ],
  93. invoiceList: [{
  94. invoice_number: '20231231',
  95. invoice_code: '20231231',
  96. invoice_money: 100022.00,
  97. invoice_status: '已申请',
  98. code_url: '查看',
  99. operable_time: '2023-12-31 13:21:32',
  100. operator: '张三'
  101. }],
  102. invoiceData: {},
  103. invoiceSta: [
  104. {v: 0, n: '未开票'},
  105. {v: 2, n: '全额开票'},
  106. {v: 3, n: '部分开票'}
  107. ],
  108. showInvoiceDialog: false,
  109. selectInvoice: {},
  110. orderData: {}
  111. }
  112. },
  113. computed: {
  114. ...mapState({
  115. orderDetail: state => state.order.orderDetail
  116. })
  117. },
  118. mounted() {
  119. this.invoiceData = this.orderDetail?.invoiceData || {}
  120. this.invoiceList = this.invoiceData?.invoiceInfo || []
  121. this.orderData = this.orderDetail?.orderData || {}
  122. },
  123. methods: {
  124. formatNumber(num, x = 2) {
  125. num = Number(num) || 0
  126. return (num / 100).toFixed(x)
  127. },
  128. showAgainBtn(item) {
  129. /**
  130. * 1. 超级管理员
  131. * 2. 销管
  132. * 3. 客服
  133. * 4. 行政
  134. * 5. 财务
  135. */
  136. // this.orderDetail.userIdentity
  137. // 按钮展示权限:发票状态为已开具或开票失败时,且管理后台用户群组为“财务”时才展示,否则不展示;
  138. const status = item.invoice_status === 1 || item.invoice_status === -1
  139. const root = Array.isArray(this.orderDetail?.userIdentity) && this.orderDetail?.userIdentity.includes(5)
  140. const url = item.code_url
  141. return status && root && url
  142. },
  143. showEditBtn() {
  144. /**
  145. * 1. 超级管理员
  146. * 2. 销管
  147. * 3. 客服
  148. * 4. 行政
  149. * 5. 财务
  150. */
  151. // this.orderDetail.userIdentity
  152. // 线下开票
  153. const applybillStatus = this.orderDetail.orderData?.applybill_status === 2
  154. const root = Array.isArray(this.orderDetail?.userIdentity) && this.orderDetail?.userIdentity.includes(5)
  155. return applybillStatus && root
  156. },
  157. backInvoiceStatus(val) {
  158. if (val == -2) {
  159. return '已冲红'
  160. } else if (val == -1) {
  161. return '开票失败'
  162. } else if (val == 0) {
  163. return '已申请'
  164. } else if (val == 1) {
  165. return '已开具'
  166. }
  167. },
  168. getInvoiceStatus(val) {
  169. const item = this.invoiceSta.find(item => item.v === val) || {};
  170. return item.n || '-';
  171. },
  172. getInvoiceInfo(item) {
  173. this.selectInvoice = item
  174. this.$nextTick(() => {
  175. this.$refs.invoiceRef.QrCodeImage = item.code_url;
  176. });
  177. this.showInvoiceDialog = true;
  178. },
  179. againInvoce(item) {
  180. const { code_url } = item
  181. const URLS = new URL(code_url)
  182. const domain = URLS.origin;
  183. const params = code_url.split('?')[1]
  184. const path = `${domain}/jy_mobile/invoice/Invoicing?type=Replace&${params}&finance=1`
  185. window.open(path, '_blank')
  186. },
  187. editInvoice(item) {
  188. const { code_url } = item
  189. const URLS = new URL(code_url)
  190. const domain = URLS.origin;
  191. },
  192. getInvoiceDetailInfo(item) {
  193. this.selectInvoice = item;
  194. this.$refs.invoiceDetailRef.codeShow = true;
  195. }
  196. },
  197. }
  198. </script>
  199. <style lang="scss" scoped>
  200. .invoice-info {
  201. .invoice-info-content {
  202. display: flex;
  203. align-items: center;
  204. .invoice-info-item {
  205. min-width: 255px;
  206. margin-right: 32px;
  207. font-size: 14px;
  208. line-height: 22px;
  209. color: $gray_10;
  210. }
  211. }
  212. // margin-top: 20px;
  213. .invoice-info-content-table {
  214. border-radius: 4px;
  215. ::v-deep {
  216. .cell {
  217. text-align: center;
  218. font-size: 14px;
  219. color: $gray_10;
  220. }
  221. .has-gutter {
  222. th {
  223. background: #F9FAFB;
  224. .cell {
  225. padding: 0;
  226. color: #686868;
  227. font-weight: 400;
  228. .column-label-cell-tip {
  229. color: #2ABED1;
  230. }
  231. }
  232. }
  233. }
  234. .invoice-info-action {
  235. display: flex;
  236. flex-direction: column;
  237. }
  238. .column-cell {
  239. color: $color_main;
  240. cursor: pointer;
  241. }
  242. }
  243. }
  244. .num-active {
  245. color: $color_main;
  246. }
  247. }
  248. </style>