invoice.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. <template>
  2. <div class="w-full min-h-[70vh] bg-page pt-6">
  3. <div class="main-container flex justify-between">
  4. <sidebar></sidebar>
  5. <el-card class="box-card flex-1 ml-4" shadow="never">
  6. <el-tabs v-model="activeName" class="demo-tabs" @tab-change="handleClick">
  7. <el-tab-pane :label="t('all')" name="all"></el-tab-pane>
  8. <el-tab-pane :label="t('invoice')" :name="1"></el-tab-pane>
  9. <el-tab-pane :label="t('uninvoice')" :name="0"></el-tab-pane>
  10. </el-tabs>
  11. <div>
  12. <el-table size="large" class="table-top">
  13. <el-table-column :label="t('gooodsInfo')" align="center" min-width="260" />
  14. <el-table-column :label="t('invoiceType')" align="center" min-width="100" />
  15. <el-table-column :label="t('status')" align="center" min-width="100" />
  16. <el-table-column :label="t('operation')" align="center" min-width="100" />
  17. </el-table>
  18. <div class="table-body min-h-[150px]" v-loading="invoiceTableData.loading">
  19. <div v-if="!invoiceTableData.loading">
  20. <template v-if="invoiceTableData.data.length">
  21. <div v-for="(item, index) in invoiceTableData.data" :key="index">
  22. <div class="flex items-center justify-between bg-[#f7f8fa] mt-[20px] px-3 h-[35px] text-[12px] text-[#666]">
  23. <span class="ml-5">{{ t('orderDate') }}{{ item.orderData.create_time }}</span>
  24. </div>
  25. <el-table :data="(item as any).orderData.orderGoods" size="large" border :show-header="false" :span-method="arraySpanMethod">
  26. <el-table-column align="left" min-width="260">
  27. <template #default="{ row }">
  28. <div class="flex cursor-pointer">
  29. <div class="flex items-center min-w-[80px] mr-[10px]">
  30. <img class="w-[80px] h-[80px]" v-if="row.goods_image" :src="img(row.goods_image)" alt="">
  31. <img class="w-[80px] h-[80px]" v-else src="" alt="">
  32. </div>
  33. <div class="flex flex-col justify-between min-w-[200px]">
  34. <div>
  35. <div class="multi-hidden text-[14px] leading-[18px]">{{ row.goods_name }}</div>
  36. <div class="text-[12px] text-[#999] mt-[4px]">{{ row.sku_name }}</div>
  37. </div>
  38. <div class="flex items-center justify-between">
  39. <span class="text-[13px]">{{ row.goods_money }}</span>
  40. <span class="text-[13px]">x{{ row.num }}</span>
  41. </div>
  42. </div>
  43. </div>
  44. </template>
  45. </el-table-column>
  46. <el-table-column min-width="100" align="center">
  47. <template #default>
  48. {{item.type_name}}
  49. </template>
  50. </el-table-column>
  51. <el-table-column min-width="100" align="center">
  52. <template #default="{ row }">
  53. <div class="">
  54. {{ item.is_invoice_name }}
  55. </div>
  56. </template>
  57. </el-table-column>
  58. <el-table-column min-width="100" align="center">
  59. <template #default>
  60. <div class="flex justify-center">
  61. <div class="w-[86px] h-[30px] leading-[28px] text-[12px] text-[var(--el-color-primary)] rounded-[15px] text-center border-[1px] border-solid border-[var(--el-color-primary)] cursor-pointer" @click="handleDetail(item.id)">{{ t('detail') }}</div>
  62. </div>
  63. </template>
  64. </el-table-column>
  65. </el-table>
  66. </div>
  67. </template>
  68. <el-empty v-else description="暂无数据" :image-size="200" :image="img('static/resource/images/system/empty.png')" />
  69. </div>
  70. </div>
  71. <div class="mt-[16px] flex justify-end">
  72. <el-pagination v-model:current-page="invoiceTableData.page" v-model:page-size="invoiceTableData.limit"
  73. layout="total, sizes, prev, pager, next, jumper" :total="invoiceTableData.total"
  74. @size-change="loadOrderList()" @current-change="loadInvoiceList" />
  75. </div>
  76. </div>
  77. </el-card>
  78. </div>
  79. <!-- 发票详情 -->
  80. <el-dialog v-model="dialogInvoiceVisible" :title="t('invoiceInfo')" width="600px" :destroy-on-close="true">
  81. <el-scrollbar height="250px" v-loading="loading">
  82. <el-form :model="invoiceData" label-width="100px" ref="formRef" class="px-[10px]" label-position="left">
  83. <el-row>
  84. <el-col :span="12" v-if="invoiceData.is_invoice_name">
  85. <el-form-item :label="t('invoiceStatus')">
  86. <div class="input-width">{{ invoiceData.is_invoice_name }}</div>
  87. </el-form-item>
  88. </el-col>
  89. <el-col :span="12" v-if="invoiceData.header_name">
  90. <el-form-item :label="t('headerName')">
  91. <div class="input-width">{{ invoiceData.header_name }}</div>
  92. </el-form-item>
  93. </el-col>
  94. <el-col :span="12" v-if="invoiceData.header_type_name">
  95. <el-form-item :label="t('headTypeName')">
  96. <div class="input-width">{{ invoiceData.header_type_name }}</div>
  97. </el-form-item>
  98. </el-col>
  99. <el-col :span="12" v-if="invoiceData.name">
  100. <el-form-item :label="t('name')">
  101. <div class="input-width">{{ invoiceData.name }}</div>
  102. </el-form-item>
  103. </el-col>
  104. <el-col :span="12" v-if="invoiceData.invoice_number">
  105. <el-form-item :label="t('invoiceNumber')">
  106. <div class="input-width">{{ invoiceData.invoice_number}}</div>
  107. </el-form-item>
  108. </el-col>
  109. <el-col :span="12" v-if="invoiceData.type_name">
  110. <el-form-item :label="t('typeName')">
  111. <div class="input-width">{{ invoiceData.type_name}}</div>
  112. </el-form-item>
  113. </el-col>
  114. <el-col :span="12">
  115. <el-form-item :label="t('email')">
  116. <div class="input-width">{{ invoiceData.email }}</div>
  117. </el-form-item>
  118. </el-col>
  119. <el-col :span="12" v-if="invoiceData.money">
  120. <el-form-item :label="t('money')">
  121. <div class="input-width">{{ invoiceData.money}}</div>
  122. </el-form-item>
  123. </el-col>
  124. <el-col :span="12" v-if="invoiceData.invoice_time">
  125. <el-form-item :label="t('invoiceTime')">
  126. <div class="input-width">{{ invoiceData.invoice_time === 0 ? '' : invoiceData.invoice_time }}</div>
  127. </el-form-item>
  128. </el-col>
  129. <template v-if="invoiceData.header_type == 2">
  130. <el-col :span="12" v-if="invoiceData.tax_number">
  131. <el-form-item :label="t('taxNumber')">
  132. <div class="input-width">{{ invoiceData.tax_number}}</div>
  133. </el-form-item>
  134. </el-col>
  135. <el-col :span="12" v-if="invoiceData.bank_name">
  136. <el-form-item :label="t('bankTame')">
  137. <div class="input-width">{{ invoiceData.bank_name }}</div>
  138. </el-form-item>
  139. </el-col>
  140. <el-col :span="12" v-if="invoiceData.bank_card_number">
  141. <el-form-item :label="t('bankCardNumber')">
  142. <div class="input-width">{{ invoiceData.bank_card_number }}</div>
  143. </el-form-item>
  144. </el-col>
  145. <el-col :span="12" v-if="invoiceData.address">
  146. <el-form-item :label="t('address')">
  147. <div class="input-width">{{ invoiceData.address }}</div>
  148. </el-form-item>
  149. </el-col>
  150. <el-col :span="12" v-if="invoiceData.telephone">
  151. <el-form-item :label="t('telephone')">
  152. <div class="input-width">{{ invoiceData.telephone }}</div>
  153. </el-form-item>
  154. </el-col>
  155. </template>
  156. <el-col :span="12">
  157. <el-form-item :label="t('applyTime')">
  158. <div class="input-width">{{ invoiceData.create_time }}</div>
  159. </el-form-item>
  160. </el-col>
  161. <el-col :span="12" v-if="invoiceData.invoice_voucher">
  162. <el-form-item :label="t('invoiceVoucher')">
  163. <div><img class="w-[50px] max-h-[50px] inline-block" :src="img(invoiceData.invoice_voucher)" alt="" @click="previewImage" ></div>
  164. </el-form-item>
  165. </el-col>
  166. <el-col :span="12" v-if="invoiceData.remark">
  167. <el-form-item :label="t('remark')">
  168. <div class="input-width break-all">{{ invoiceData.remark }}</div>
  169. </el-form-item>
  170. </el-col>
  171. </el-row>
  172. </el-form>
  173. </el-scrollbar>
  174. <template #footer>
  175. <div class="dialog-footer">
  176. <el-button type="primary" class="!bg-[var(--el-color-primary)] !border-[var(--el-color-primary)]" @click="dialogInvoiceVisible = false" dark>{{ t('confirm') }}</el-button>
  177. </div>
  178. </template>
  179. </el-dialog>
  180. <el-image-viewer :url-list="previewImageList" v-if="imageViewer.show" @close="imageViewer.show = false" :initial-index="imageViewer.index" :zoom-rate="1" />
  181. </div>
  182. </template>
  183. <script setup lang="ts">
  184. import { reactive, ref } from 'vue'
  185. import { getMallInvoice , getMallInvoiceDetail} from '@/addon/mall/api/invoice'
  186. import { useRouter } from 'vue-router'
  187. const router = useRouter()
  188. const activeName = ref('all')
  189. // 获取会员列表
  190. const invoiceTableData = reactive({
  191. page: 1,
  192. limit: 10,
  193. total: 0,
  194. loading: true,
  195. data: []
  196. })
  197. const loadInvoiceList = (page = 1) =>{
  198. invoiceTableData.page = page
  199. invoiceTableData.loading = true
  200. getMallInvoice({
  201. page: invoiceTableData.page,
  202. limit: invoiceTableData.limit,
  203. is_invoice: activeName.value
  204. }).then(res =>{
  205. invoiceTableData.loading = false
  206. invoiceTableData.total = res.data.total
  207. invoiceTableData.data = res.data.data.map((el: any) => {
  208. el.orderData.orderGoods.forEach((v: any) => {
  209. v.rowNum = el.orderData.orderGoods.length
  210. })
  211. return el
  212. })
  213. })
  214. }
  215. loadInvoiceList()
  216. // 切换状态
  217. const handleClick = (event:any) =>{
  218. activeName.value = event
  219. loadInvoiceList()
  220. }
  221. // 查看发票详情
  222. const loading = ref(false)
  223. const dialogInvoiceVisible = ref(false)
  224. const invoiceData = ref({})
  225. const handleDetail = (id) =>{
  226. loading.value = true
  227. getMallInvoiceDetailFn(id)
  228. dialogInvoiceVisible.value = true
  229. }
  230. const getMallInvoiceDetailFn = async (id:any) => {
  231. invoiceData.value = await (await getMallInvoiceDetail(id)).data
  232. if(invoiceData.value.invoice_voucher) {
  233. previewImageList.push(img(invoiceData.value.invoice_voucher))
  234. }
  235. loading.value = false
  236. }
  237. //合并表格行
  238. const arraySpanMethod = ({
  239. row,
  240. column,
  241. rowIndex,
  242. columnIndex
  243. }) => {
  244. if (rowIndex === 0) {
  245. if (columnIndex === 0) {
  246. return [1, 1]
  247. } else if (columnIndex > 0) {
  248. return [row.rowNum, 1]
  249. } else {
  250. return [1, 1]
  251. }
  252. } else {
  253. if (columnIndex === 0) {
  254. return [1, 1]
  255. } else if (columnIndex > 0) {
  256. return [0, 0]
  257. } else {
  258. return [1, 1]
  259. }
  260. }
  261. }
  262. let previewImageList: string[] = reactive([])
  263. /**
  264. * 查看图片
  265. */
  266. const imageViewer = reactive({
  267. show: false,
  268. index: 0
  269. })
  270. const previewImage = () => {
  271. imageViewer.show = true
  272. }
  273. </script>
  274. <style lang="scss" scoped>
  275. .box-shadow{
  276. box-shadow: 0 3px 20px rgba(0,0,0,.08);
  277. }
  278. .table-top :deep(.el-table__body-wrapper) {
  279. display: none;
  280. }
  281. :deep(.el-table) {
  282. --el-table-row-hover-bg-color: var(--el-transfer-border-color);
  283. }
  284. </style>