Browse Source

Merge branch 'dev' of https://git.citupro.com/zhengnaiwen_citu/menduner into dev

lifanagju_citu 8 tháng trước cách đây
mục cha
commit
640081e07e

+ 20 - 0
src/utils/index.js

@@ -86,4 +86,24 @@ export const DPR = () => {
   }
   // 直接返回高像素比
   return 8
+}
+
+// 文件下载 
+export const getBlob = (url) => {
+  return new Promise(resolve => {
+    const xhr = new XMLHttpRequest()
+    xhr.open('GET', url, true)
+    xhr.responseType = 'blob'
+    xhr.onload = () => {
+      if (xhr.status === 200) resolve(xhr.response)
+    }
+    xhr.send()
+  })
+}
+
+export const saveAs = (blob, filename) => {
+  var link = document.createElement('a')
+  link.href = window.URL.createObjectURL(blob)
+  link.download = filename
+  link.click()
 }

+ 85 - 1
src/views/recruit/enterprise/memberCenter/tradingOrder/components/transaction.vue

@@ -12,7 +12,27 @@
     itemKey="id"
     @pageHandleChange="handleChangePage"
   >
+    <template #action="{ item }">
+      <v-btn v-if="!invoiceStatus(item.payOrderId)" color="primary" variant="text" @click="handleInvoice(item)">申请开票</v-btn>
+      <v-btn v-if="invoiceStatus(item.payOrderId, true)?.status === 1" color="success" variant="text" @click="handleDownload(item)">下载发票</v-btn>
+      <span v-if="invoiceStatus(item.payOrderId, true)?.status === 0" class="color-warning">开票中,请耐心等待...</span>
+    </template>
   </CtTable>
+
+  <CtDialog :visible="show" :widthType="2" titleClass="text-h6" title="选择要开票的抬头信息" @close="handleClose" @submit="handleSubmit">
+    <v-radio-group v-model="radio" color="primary">
+      <v-radio v-for="k in invoiceTitleList" :key="k.id" :value="k.id">
+        <template v-slot:label>
+          <div>{{ k.title }}-{{ k.code }}</div>
+        </template>
+      </v-radio>
+    </v-radio-group>
+    <div class="text-start ml-5 mt-5">
+      开票金额:
+      <span class="color-error font-weight-bold font-size-20">{{ (order.price / 10.0).toFixed(2) }}</span>
+      元
+    </div>
+  </CtDialog>
 </template>
 
 <script setup>
@@ -20,6 +40,9 @@ defineOptions({ name: 'trading-order-transaction'})
 import { ref } from 'vue'
 import { timesTampChange } from '@/utils/date'
 import { getEnterpriseTradeOrderPage } from '@/api/recruit/enterprise/member/points'
+import { getInvoiceListPage, createInvoice, getInvoiceTitlePage } from '@/api/recruit/enterprise/member/invoice'
+import Snackbar from '@/plugins/snackbar'
+import { getBlob, saveAs } from '@/utils'
 
 const dataList = ref([])
 const headers = [
@@ -27,7 +50,8 @@ const headers = [
   { title: '使用点数', key: 'price', sortable: false },
   { title: '是否已支付', key: 'payStatus', sortable: false, value: item => item.payStatus ? '已支付' : '未支付' },
   { title: '支付订单编号', key: 'payOrderId', sortable: false },
-  { title: '订单支付时间', key: 'payTime', value: item =>  timesTampChange(item.payTime), sortable: false }
+  { title: '订单支付时间', key: 'payTime', value: item =>  timesTampChange(item.payTime), sortable: false },
+  { title: '操作', key: 'action', sortable: false }
 ]
 
 const total = ref(0)
@@ -37,11 +61,29 @@ const query = ref({
   payStatus: true, // 支付状态,订单数据true只显示已支付的
 })
 
+const invoiceList = ref([])
+// 查询可开票订单
+const checkStatus = async () => {
+  const payOrderIds = dataList.value.map(e => e.payOrderId)
+  const { list }  = await getInvoiceListPage({ payOrderIds })
+  invoiceList.value = list
+}
+
+// 查询是否可开发票
+const invoiceStatus = (payOrderId, status) => {
+  // status: 0开票中   1已开票
+  const obj = invoiceList.value.find(e => e.payOrderId === Number(payOrderId))
+  if (status) return obj
+  if (obj) return true
+}
+
+// 订单列表
 const getData = async () => {
   dataList.value = []; total.value = 0
   const res = await getEnterpriseTradeOrderPage(query.value)
   dataList.value = res?.list || []
   total.value = res.total
+  checkStatus()
 }
 getData()
 
@@ -49,6 +91,48 @@ const handleChangePage = (e) => {
   query.value.pageNo = e
   getData()
 }
+
+// 获取发票抬头列表
+const invoiceTitleList = ref([])
+const getInvoiceTitleList = async () => {
+  const { list } = await getInvoiceTitlePage({})
+  invoiceTitleList.value = list
+}
+getInvoiceTitleList()
+
+// 申请开票
+const show = ref(false)
+const radio = ref()
+const order = ref({})
+const handleInvoice = (item) => {
+  order.value = item
+  show.value = true
+}
+
+const handleClose = () => {
+  show.value = false
+  order.value = {}
+  radio.value = null
+}
+
+const handleSubmit = async () => {
+  if (!radio.value) return Snackbar.warning('请选择要进行开票的抬头信息')
+  const obj = invoiceTitleList.value.find(e => e.id === radio.value)
+  await createInvoice({ ...obj, payOrderId: order.value.payOrderId })
+  Snackbar.success('申请成功,开票中...')
+  handleClose()
+  getData()
+}
+
+// 发票下载
+const handleDownload = (item) => {
+  const obj = invoiceList.value.find(e => e.payOrderId === Number(item.payOrderId))
+  if (!obj) return Snackbar.warning('发票地址错误,下载失败')
+
+  getBlob(obj.fileUrl).then(blob => {
+    saveAs(blob, item.spuName + '发票')
+  })
+}
 </script>
 
 <style scoped lang="scss">

+ 1 - 60
src/views/recruit/personal/PersonalCenter/dynamic/right.vue

@@ -41,9 +41,6 @@
         <div class="d-flex attachment-item my-2" v-for="k in attachmentList" :key="k.id">
           <v-icon color="primary">mdi-file-account</v-icon>
           <div class="file-name ellipsis ml-2">{{ k.title }}</div>
-          <!-- <v-icon class="cursor-pointer" color="primary" @click="previewFile(k.url)">mdi-eye-outline</v-icon>
-          <v-icon class="cursor-pointer mx-2" color="primary" @click="handleDownload(k)">mdi-download-box-outline</v-icon>
-          <v-icon class="cursor-pointer" color="error" @click="handleDelete(k)">mdi-trash-can-outline</v-icon> -->
           <span class="cursor-pointer color-primary" @click="previewFile(k.url)">预览</span>
           <span class="cursor-pointer mx-2 color-primary" @click="handleDownload(k)">下载</span>
           <span class="cursor-pointer color-error" @click="handleDelete(k)">删除</span>
@@ -51,15 +48,6 @@
       </div>
       <div v-else class="more-text d-flex justify-center">暂无简历,请先上传</div>
     </div>
-    <v-navigation-drawer
-      v-model="showInterviewSchedule"
-      style="height: 100vh; overflow: hidden;"
-      temporary
-      location="right"
-      width="300"
-    >
-      <interviewSchedule :dataList="invitePageList" @handleMore="interviewScheduleMore()"></interviewSchedule>
-    </v-navigation-drawer>
   </div>
 </template>
 
@@ -68,15 +56,12 @@ defineOptions({ name: 'personal-center-right'})
 import { ref } from 'vue'
 import { previewFile } from '@/utils'
 import { useRouter } from 'vue-router'
-import { useRoute } from 'vue-router'; const route = useRoute()
 import { getPersonResumeCv, savePersonResumeCv, deletePersonResumeCv } from '@/api/recruit/personal/resume'
 import { useI18n } from '@/hooks/web/useI18n'
 import { useUserStore } from '@/store/user'
 import Snackbar from '@/plugins/snackbar'
 import Confirm from '@/plugins/confirm'
-import interviewSchedule from './../components/interviewSchedule.vue'
-import { getUserInterviewInvitePage } from '@/api/recruit/personal/personalCenter'
-import { dealDictObjData } from '@/utils/position'
+import { getBlob, saveAs } from '@/utils'
 
 const { t } = useI18n()
 const router = useRouter()
@@ -93,15 +78,9 @@ userStore.$subscribe((mutation, state) => {
 
 const resumeList = ref([
   { name: 'refresh', icon: 'mdi-refresh', title: t('resume.refreshResume'), desc: t('resume.enhanceResumeActivity') },
-  // { name: 'interview', icon: 'mdi-account-multiple-check-outline', title: t('resume.interviewSchedule'), desc: '' },
   { name: 'order', icon: 'mdi-clipboard-list-outline', title: '我的订单', desc: '交易订单' },
 ])
-const showInterviewSchedule = ref(false)
 const resumeClick = async (val) => {
-  // if (val.name === 'interview') {
-  //   await getUserInterviewInvitePageList() // 获取最新数据
-  //   showInterviewSchedule.value = true
-  // }
   if (val.name === 'order') router.push('/recruit/personal/tradeOrder')
 }
 
@@ -137,50 +116,12 @@ const handleDelete = ({ id }) => {
   })
 }
 
-const getBlob = (url) => {
-  return new Promise(resolve => {
-    const xhr = new XMLHttpRequest()
-    xhr.open('GET', url, true)
-    xhr.responseType = 'blob'
-    xhr.onload = () => {
-      if (xhr.status === 200) resolve(xhr.response)
-    }
-    xhr.send()
-  })
-}
-
-const saveAs = (blob, filename) => {
-  var link = document.createElement('a')
-  link.href = window.URL.createObjectURL(blob)
-  link.download = filename
-  link.click()
-}
-
 // 下载附件
 const handleDownload = (k) => {
   getBlob(k.url).then(blob => {
     saveAs(blob, k.title)
   })
 }
-
-// 面试日程
-const invitePageList = ref([])
-const getUserInterviewInvitePageList = async () => {
-  const res = await getUserInterviewInvitePage()
-  invitePageList.value = res?.list.map(e => {
-    e.job = { ...e.job, ...dealDictObjData({}, e.job) }
-    e.enterprise = { ...e.enterprise, ...dealDictObjData({}, e.enterprise)}
-    return e
-  }) || []
-  // const interview = resumeList.value.find(f => f.name === 'interview')
-  // if (interview) interview.desc = '有' + (res?.total || '0') + '个待面试'
-}
-// getUserInterviewInvitePageList()
-const interviewScheduleMore = () => {
-  showInterviewSchedule.value = false
-  const path = route.path
-  router.push({ path, query: { showInterviewScheduleMore: true } })
-}
 </script>
 
 <style scoped lang="scss">