index.vue 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. <template>
  2. <HcCard>
  3. <template #header>
  4. <div class="w-72">
  5. <el-select v-model="searchForm.projectId" block clearable placeholder="项目名称" size="large">
  6. <el-option v-for="item in projectType" :label="item.projectName" :value="item.projectId" />
  7. </el-select>
  8. </div>
  9. <div class="ml-4">
  10. <el-button type="primary" size="large" @click="searchClick">
  11. <HcIcon name="search-2" />
  12. <span>搜索</span>
  13. </el-button>
  14. </div>
  15. <div class="ml-2">
  16. <el-button size="large" @click="resetClick">
  17. <HcIcon name="close-circle" />
  18. <span>重置</span>
  19. </el-button>
  20. </div>
  21. </template>
  22. <template #extra>
  23. <el-button v-auth-btn="['expense-invoice-draft-btn']" size="large" type="warning" hc-btn @click="draftsClick">
  24. <HcIcon name="draft" />
  25. <span>草稿箱{{ draftNum > 0 ? `(${draftNum})` : '' }}</span>
  26. </el-button>
  27. <el-button v-auth-btn="['expense-invoice-add-btn']" size="large" type="primary" hc-btn @click="addRowClick">
  28. <HcIcon name="add" />
  29. <span>开票审批</span>
  30. </el-button>
  31. </template>
  32. <HcTable :column="tableColumn" :datas="tableData" :loading="tableLoading">
  33. <template #action="{ row, index }">
  34. <el-button size="small" type="success" @click="invoiceItemUpload(row)">
  35. 上传
  36. </el-button>
  37. <el-button size="small" type="primary" @click="invoiceItemPdf(row)">
  38. 查看
  39. </el-button>
  40. <el-button size="small" type="danger" @click="rowCancel(row)">
  41. 删除
  42. </el-button>
  43. </template>
  44. </HcTable>
  45. <template #action>
  46. <HcPages :pages="searchForm" @change="pageChange" />
  47. </template>
  48. <!-- 草稿箱 -->
  49. <HcDialog
  50. is-to-body is-table bg-color="#ffffff" widths="62rem" :footer="false" :show="draftsModal"
  51. :title="draftNum > 0 ? `草稿箱(${draftNum})` : '草稿箱'" @close="draftsCloseClick"
  52. >
  53. <el-alert title="3个月内未更新的草稿将被自动删除" type="warning" show-icon />
  54. <div style="position: relative;height: calc(100% - 44px);">
  55. <HcTable :is-index="false" :column="tableDraftsColumn" :datas="tableDraftsData">
  56. <template #action="{ row, index }">
  57. <el-button size="small" type="primary" @click="editDraftClick(row)">
  58. 继续编辑
  59. </el-button>
  60. <el-button size="small" type="danger" @click="delDraftClick(row)">
  61. 删除
  62. </el-button>
  63. </template>
  64. </HcTable>
  65. </div>
  66. </HcDialog>
  67. <!-- 上传控件 -->
  68. <HcUploadFile
  69. ref="HcUploadFileRef"
  70. :options="uploadFileOptions"
  71. :echo-params="uploadEchoParams"
  72. @success="HcUploadFileSuccess"
  73. />
  74. <!-- 发票PDF -->
  75. <HcDialog is-to-body is-table bg-color="#ffffff" widths="62rem" :footer="false" :show="pdfModal" title="发票PDF" @close="pdfCloseClick">
  76. <HcPdf src="http://bladex-chongqing-info.oss-cn-hangzhou.aliyuncs.com//upload/20230504/911982ba85e66cfa58fb02d5a738bb2b.pdf" />
  77. </HcDialog>
  78. </HcCard>
  79. </template>
  80. <script setup>
  81. import { onActivated, ref } from 'vue'
  82. import { useRouter } from 'vue-router'
  83. import mainApi from '~api/expense/invoice'
  84. import { getProjectList } from '~api/other'
  85. import { getArrValue } from 'js-fast-way'
  86. import { delMessage } from '~uti/tools'
  87. import { getTokenHeader } from '~src/api/request/header'
  88. const router = useRouter()
  89. onActivated(() => {
  90. getApi()
  91. })
  92. const getApi = () => {
  93. getProjectData()
  94. getTableData()
  95. getDraftNum()
  96. }
  97. //项目类型
  98. const projectType = ref([])
  99. const getProjectData = async () => {
  100. const { error, code, data } = await getProjectList()
  101. //判断状态
  102. if (!error && code === 200) {
  103. projectType.value = getArrValue(data)
  104. } else {
  105. projectType.value = []
  106. }
  107. }
  108. //搜索表单
  109. const searchForm = ref({ projectId: null, current: 1, size: 20, total: 0 })
  110. //搜索
  111. const searchClick = () => {
  112. searchForm.value.current = 1
  113. getTableData()
  114. }
  115. //重置搜索表单
  116. const resetClick = () => {
  117. searchForm.value = { current: 1, size: 20, total: 0 }
  118. }
  119. //分页被点击
  120. const pageChange = ({ current, size }) => {
  121. searchForm.value.current = current
  122. searchForm.value.size = size
  123. getTableData()
  124. }
  125. //获取数据
  126. const tableLoading = ref(false)
  127. const tableColumn = [
  128. { key: 'invoiceDate', name: '申请时间', width: '160' },
  129. { key: 'projectName', name: '关联项目', minWidth: '220' },
  130. { key: 'invoiceDesc', name: '开票内容', minWidth: '160' },
  131. { key: 'invoiceMoney', name: '开票金额', width: '160', align: 'center' },
  132. { key: 'invoiceTypeName', name: '发票类型', width: '160', align: 'center' },
  133. { key: 'invoiceUserName', name: '开票人', width: '160', align: 'center' },
  134. { key: 'approvalResultName', name: '审批结果', width: '160', align: 'center' },
  135. { key: 'approvalStatusName', name: '审批状态', width: '140', align: 'center' },
  136. { key: 'createName', name: '创建人', width: '140', align: 'center' },
  137. { key: 'createTime', name: '创建时间', width: '160', align: 'center' },
  138. { key: 'action', name: '操作', width: '220', align: 'center', fixed: 'right' },
  139. ]
  140. const tableData = ref([])
  141. const getTableData = async () => {
  142. tableLoading.value = true
  143. const { error, code, data } = await mainApi.page(searchForm.value)
  144. //判断状态
  145. tableLoading.value = false
  146. if (!error && code === 200) {
  147. tableData.value = getArrValue(data['records'])
  148. searchForm.value.total = data['total'] || 0
  149. } else {
  150. tableData.value = []
  151. searchForm.value.total = 0
  152. }
  153. }
  154. //新增预算
  155. const addRowClick = () => {
  156. router.push({
  157. name: 'expense-invoice-billing',
  158. })
  159. }
  160. //上传配置
  161. const HcUploadFileRef = ref(null)
  162. const uploadEchoParams = ref({})
  163. const uploadFileOptions = {
  164. headers: getTokenHeader(),
  165. multiple: false,
  166. }
  167. //电子发票
  168. const invoiceItemUpload = ({ id }) => {
  169. uploadEchoParams.value = { rowId: id }
  170. HcUploadFileRef.value?.selectFile()
  171. }
  172. //上传完成
  173. const HcUploadFileSuccess = async ({ echoParams, resData }) => {
  174. const { rowId } = echoParams, { pdfUrl } = resData
  175. if (rowId && pdfUrl) {
  176. const { error, code, msg } = await mainApi.upload({
  177. id: rowId,
  178. pdfUrl: pdfUrl,
  179. })
  180. //判断状态
  181. if (!error && code === 200) {
  182. window.$message?.success(msg)
  183. getTableData().then()
  184. } else {
  185. window.$message?.error(msg)
  186. }
  187. } else {
  188. window.$message?.error('上传发票失败了')
  189. }
  190. }
  191. //查看发票
  192. const pdfModal = ref(false)
  193. const invoicePdfUrl = ref('')
  194. const invoiceItemPdf = async (row) => {
  195. const { error, code, data, msg } = await mainApi.pdf({
  196. id: row.id,
  197. })
  198. //判断状态
  199. if (!error && code === 200) {
  200. console.log(data)
  201. invoicePdfUrl.value = data
  202. pdfModal.value = true
  203. } else {
  204. invoicePdfUrl.value = ''
  205. window.$message?.error(msg)
  206. }
  207. }
  208. const pdfCloseClick = () => {
  209. invoicePdfUrl.value = ''
  210. pdfModal.value = false
  211. }
  212. //删除
  213. const rowCancel = (row) => {
  214. console.log('删除')
  215. delMessage(async () => {
  216. const { error, code, msg } = await mainApi.cancel({
  217. id: row.id,
  218. })
  219. //判断状态
  220. if (!error && code === 200) {
  221. window.$message?.success(msg)
  222. getTableData().then()
  223. } else {
  224. window.$message?.error(msg)
  225. }
  226. })
  227. }
  228. //草稿箱
  229. const draftsModal = ref(false)
  230. const draftsClick = () => {
  231. tableDraftsData.value = []
  232. draftsModal.value = true
  233. getDraftNum()
  234. }
  235. const draftsCloseClick = () => {
  236. draftsModal.value = false
  237. }
  238. //草稿箱数据
  239. const draftNum = ref(0)
  240. const tableDraftsColumn = [
  241. { key: 'title', name: '标题' },
  242. { key: 'updateTime', name: '更新时间', width: '200' },
  243. { key: 'action', name: '操作', width: '170', align: 'center' },
  244. ]
  245. const tableDraftsData = ref([])
  246. //获取草稿数量
  247. const getDraftNum = async () => {
  248. const { error, code, data } = await mainApi.draft()
  249. //判断状态
  250. if (!error && code === 200) {
  251. const res = getArrValue(data)
  252. tableDraftsData.value = res
  253. draftNum.value = res.length
  254. } else {
  255. tableDraftsData.value = []
  256. draftNum.value = 0
  257. }
  258. }
  259. //继续编辑
  260. const editDraftClick = ({ id }) => {
  261. draftsModal.value = false
  262. router.push({
  263. name: 'expense-invoice-billing',
  264. query: { id: id },
  265. })
  266. }
  267. //删除草稿
  268. const delDraftClick = ({ id }) => {
  269. delMessage(async () => {
  270. const { error, code, msg } = await mainApi.remove({
  271. id: id,
  272. })
  273. //判断状态
  274. if (!error && code === 200) {
  275. window.$message?.success(msg)
  276. getDraftNum().then()
  277. } else {
  278. window.$message?.error(msg)
  279. }
  280. })
  281. }
  282. </script>