detail.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. <template>
  2. <view v-if="!refreshPage" class="uni-app">
  3. <view class="status-bar" />
  4. <wk-nav-bar
  5. :command-list="commandList"
  6. :refresh-prev="refreshPrevPage"
  7. title="发票详情"
  8. theme="white"
  9. class="nav-bar"
  10. @command="handleCommand" />
  11. <scroll-view
  12. v-if="!$isEmpty(detailData)"
  13. :scroll-y="true"
  14. class="main-container scroll-view-hook"
  15. @scrolltolower="handleScrollTolower">
  16. <view class="header-top">
  17. <view class="bg linear-gradient" />
  18. <view class="card">
  19. <view class="title-cell">
  20. <image :src="$static('images/crm/gray_contract.png')" class="type-icon" />
  21. <view class="title-text">
  22. {{ detailData.invoiceApplyNumber || '' }}
  23. </view>
  24. <view
  25. v-if="showCheckStatus"
  26. :style="{
  27. backgroundColor: statusObj.bg,
  28. color: statusObj.color
  29. }"
  30. class="title-status">
  31. <text
  32. :class="statusObj.icon"
  33. class="wk" />
  34. <text>{{ statusObj.label }}</text>
  35. </view>
  36. </view>
  37. <view class="info-cell">
  38. <view class="info-cell-item">
  39. <text class="text">
  40. 开票金额:
  41. </text>
  42. <text class="money">
  43. ¥{{ splitNumber(detailData.invoiceMoney) || '--' }}
  44. </text>
  45. </view>
  46. <view class="info-cell-item">
  47. <text class="text">
  48. 发票号码:{{ detailData.invoiceNumber || '--' }}
  49. </text>
  50. </view>
  51. <view class="info-cell-item">
  52. <text class="text">
  53. 实际开票日期:{{ detailData.realInvoiceDate | formatTime }}
  54. </text>
  55. </view>
  56. </view>
  57. <view class="main-info">
  58. <flow-progress
  59. v-if="detailData"
  60. :type="comType"
  61. :detail-id="id"
  62. :detail-data="detailData" />
  63. </view>
  64. <view
  65. class="relevance-cell"
  66. @click="handleToCustomer">
  67. <image :src="$static('images/application/customer.png')" class="cell-icon" />
  68. <text class="cell-body">
  69. {{ detailData.customerName }}
  70. </text>
  71. <text class="cell-link wk wk-arrow-right" />
  72. </view>
  73. <view
  74. v-if="auditInfo && auditInfo.isCheck === 1"
  75. class="check-box">
  76. <view class="btn success" @click="handleAuditAction('pass')">
  77. <text class="wk wk-check-fill icon" />
  78. <text>通过</text>
  79. </view>
  80. <view class="btn error" @click="handleAuditAction('refuse')">
  81. <text class="wk wk-close-fill icon" />
  82. <text>拒绝</text>
  83. </view>
  84. </view>
  85. </view>
  86. </view>
  87. <view class="wk-tabs">
  88. <view
  89. v-for="(tab, index) in tabs"
  90. :key="index"
  91. :class="{active: activeTab === tab.value}"
  92. class="wk-tab-item"
  93. @click="handleToggleTabs(tab.value)">
  94. {{ tab.label }}
  95. </view>
  96. </view>
  97. <wk-keep-alive v-if="id" v-model="activeTab">
  98. <wk-keep-alive-item>
  99. <detail-base-info
  100. :detail-id="id"
  101. :type="comType"
  102. :insert-fields="insertFields"
  103. class="detail-container" />
  104. </wk-keep-alive-item>
  105. <wk-keep-alive-item>
  106. <detail-about
  107. :detail-id="id"
  108. :detail-data="detailData"
  109. :batch-id="detailData.batchId"
  110. class="detail-about-container" />
  111. </wk-keep-alive-item>
  112. </wk-keep-alive>
  113. </scroll-view>
  114. <uni-popup ref="popup" type="dialog">
  115. <uni-popup-dialog
  116. :content="dialogMsg"
  117. type="warning"
  118. @confirm="handleDialogConfirm" />
  119. </uni-popup>
  120. </view>
  121. </template>
  122. <script>
  123. import {
  124. QueryById,
  125. DeleteByIds,
  126. ChangeOwnerUser
  127. } from 'API/crm/invoice'
  128. import { QueryExamineRecordList, AuditExamine } from 'API/examine'
  129. import DetailBaseInfo from '../components/detailSection/baseInfo'
  130. import DetailAbout from './components/tabsAbout'
  131. import FlowProgress from '../components/customFlow/flowProgress'
  132. import detailMixins from '../mixins/detail.js'
  133. import { mapGetters } from 'vuex'
  134. import { splitNumber } from '@/utils/lib.js'
  135. import moment from 'moment'
  136. export default {
  137. name: 'InvoiceDetail',
  138. filters: {
  139. formatTime(val) {
  140. if (!val) return '--'
  141. return moment(val).format('YYYY-MM-DD')
  142. }
  143. },
  144. components: {
  145. DetailBaseInfo,
  146. DetailAbout,
  147. FlowProgress
  148. },
  149. mixins: [detailMixins],
  150. data() {
  151. return {
  152. comType: 'crm_invoice',
  153. commandList: [],
  154. insertFields: [],
  155. tabs: [
  156. { label: '基本信息', value: 0 },
  157. { label: '相关信息', value: 1 }
  158. ],
  159. auditInfo: null
  160. }
  161. },
  162. computed: {
  163. ...mapGetters({
  164. calcStatus: 'base/calcStatus',
  165. userInfo: 'user/userInfo'
  166. }),
  167. showCheckStatus() {
  168. return this.detailData.hasOwnProperty('checkStatus') && this.detailData.examineRecordId
  169. },
  170. statusObj() {
  171. if (!this.showCheckStatus) return {}
  172. return this.calcStatus(this.detailData.checkStatus) || {}
  173. }
  174. },
  175. methods: {
  176. splitNumber(num) {
  177. return splitNumber(num)
  178. },
  179. /**
  180. * 获取详情
  181. */
  182. getDetail() {
  183. QueryById({invoiceId: this.id}).then(response => {
  184. this.detailData = response
  185. this.getAuditInfo()
  186. this.setInsertFields()
  187. }).catch(() => {
  188. this.goBack()
  189. })
  190. },
  191. setInsertFields() {
  192. const data = this.detailData
  193. const titleType = { 1: '单位', 2: '个人', }[data.titleType]
  194. this.insertFields = [
  195. {
  196. name: '发票信息',
  197. list: [
  198. { fieldId: 1, name: '抬头类型', formType: 'text', value: titleType },
  199. { fieldId: 2, name: '开票抬头', formType: 'text', value: data.invoiceTitle },
  200. { fieldId: 3, name: '纳税人识别号', formType: 'text', value: data.taxNumber },
  201. { fieldId: 4, name: '开户行', formType: 'text', value: data.depositBank },
  202. { fieldId: 5, name: '开户账号', formType: 'text', value: data.depositAccount },
  203. { fieldId: 6, name: '开票地址', formType: 'text', value: data.depositAddress },
  204. { fieldId: 7, name: '电话', formType: 'text', value: data.telephone }
  205. ]
  206. },
  207. {
  208. name: '邮寄信息',
  209. list: [
  210. { fieldId: 1, name: '联系人', formType: 'text', value: data.contactsName },
  211. { fieldId: 2, name: '联系方式', formType: 'text', value: data.contactsMobile },
  212. { fieldId: 3, name: '邮寄地址', formType: 'text', value: data.contactsAddress }
  213. ]
  214. }
  215. ]
  216. },
  217. /**
  218. * 获取审批流
  219. */
  220. getAuditInfo() {
  221. if (!this.detailData.examineRecordId) {
  222. this.auditInfo = null
  223. this.renderCommands()
  224. return
  225. }
  226. QueryExamineRecordList({
  227. recordId: this.detailData.examineRecordId,
  228. ownerUserId: this.detailData.ownerUserId
  229. }).then(res => {
  230. this.auditInfo = res || null
  231. this.renderCommands()
  232. }).catch()
  233. },
  234. /**
  235. * 渲染更多操作选项
  236. */
  237. renderCommands() {
  238. this.commandList = [
  239. {label: '查看审批流', imgIcon: 'read', noCheck: true, value: 'read'},
  240. {label: '转移', imgIcon: 'transfer', auth: 'crm.invoice.transfer', value: 'transfer'},
  241. {label: '编辑', imgIcon: 'update', auth: 'crm.invoice.update', value: 'update'},
  242. {label: '开票', imgIcon: 'dealStatus', auth: 'crm.invoice.updateInvoiceStatus', value: 'updateInvoiceStatus'},
  243. {label: '删除', imgIcon: 'delete', auth: 'crm.invoice.delete', value: 'delete'}
  244. ]
  245. // 判断是否能够撤回审批
  246. let index = this.commandList.findIndex(item => item.label === '撤回审批')
  247. if (this.auditInfo && this.auditInfo.isRecheck === 1 && index === -1) {
  248. this.commandList.splice(1, 0, {
  249. label: '撤回审批',
  250. imgIcon: 'reset',
  251. noCheck: true,
  252. value: 'reset'
  253. })
  254. } else if (this.auditInfo && this.auditInfo.isRecheck !== 1 && index !== -1) {
  255. this.commandList.splice(index, 1)
  256. }
  257. index = null
  258. // 如果没有审批流则删除查看审批流
  259. index = this.commandList.findIndex(item => item.value === 'read')
  260. if (index !== -1 && !this.detailData.examineRecordId) {
  261. this.commandList.splice(index, 1)
  262. }
  263. index = null
  264. const checkStatus = this.detailData.checkStatus
  265. // 判断是否能编辑
  266. index = this.commandList.findIndex(item => item.value === 'update')
  267. if (index !== -1) {
  268. // 审核拒绝 审核撤回 未提交才能编辑
  269. // if (
  270. // this.userInfo.userId !== this.detailData.createUserId ||
  271. // (![2, 4, 5].includes(checkStatus) && this.detailData.examineRecordId)) {
  272. // this.commandList.splice(index, 1)
  273. // }
  274. if (![2, 4, 5].includes(checkStatus) && this.detailData.examineRecordId) {
  275. this.commandList.splice(index, 1)
  276. }
  277. }
  278. index = null
  279. // 判断是否能删除
  280. index = this.commandList.findIndex(item => item.value === 'delete')
  281. if (index !== -1) {
  282. // 已撤回 未提交 作废 并且是超管才能删除
  283. if (!this.detailData.isAdmin === 1 ||
  284. (![4, 5, 8].includes(checkStatus) && this.detailData.examineRecordId)) {
  285. this.commandList.splice(index, 1)
  286. }
  287. }
  288. },
  289. handleCommand(command) {
  290. this.commandValue = command.value
  291. switch (command.value) {
  292. case 'read':
  293. this.$Router.navigateTo({
  294. url: '/pages_crm/auditList',
  295. query: {
  296. id: this.detailData.examineRecordId,
  297. u_id: this.detailData.ownerUserId
  298. }
  299. })
  300. break
  301. case 'reset':
  302. this.handleAuditAction('cancel')
  303. break
  304. case 'transfer':
  305. this.handleToChangeOwnerUser()
  306. break
  307. case 'update':
  308. this.handleEdit()
  309. break
  310. case 'updateInvoiceStatus':
  311. this.$Router.navigateTo({
  312. url: '/pages_crm/invoice/updateStatus',
  313. query: {
  314. id: this.id,
  315. status: this.detailData.invoiceStatus
  316. }
  317. })
  318. break
  319. case 'delete':
  320. this.dialogMsg = '您确定要删除该发票吗?'
  321. this.$refs.popup.open()
  322. break
  323. }
  324. },
  325. handleDialogConfirm(next) {
  326. switch (this.commandValue) {
  327. // case 'discard':
  328. // this.handleDiscard()
  329. // break
  330. case 'delete':
  331. this.handleDelete()
  332. break
  333. }
  334. next()
  335. },
  336. /**
  337. * 审核操作
  338. * @param action 审核动作
  339. */
  340. handleAuditAction(action) {
  341. getApp().globalData.auditInfo = this.auditInfo
  342. uni.$once('save-audit', this.handleAudit)
  343. this.$Router.navigateTo({
  344. url: '/pages_common/audit/index',
  345. query: {
  346. type: action
  347. }
  348. })
  349. },
  350. /**
  351. * 审核
  352. * @param form 审核信息
  353. */
  354. handleAudit(form) {
  355. let params = {
  356. typeId: this.id,
  357. recordId: this.detailData.examineRecordId,
  358. ...form
  359. }
  360. // console.log('audit', params)
  361. AuditExamine(params).then(() => {
  362. this.$toast(params.status === 4 ? '撤回成功' : '审核成功')
  363. this.getDetail()
  364. this.refreshPrevPage = true
  365. }).catch(() => {})
  366. },
  367. /**
  368. * 跳转到客户
  369. */
  370. handleToCustomer() {
  371. this.$Router.navigateTo({
  372. url: '/pages_crm/customer/detail',
  373. query: {
  374. id: this.detailData.customerId
  375. }
  376. })
  377. },
  378. /**
  379. * 删除
  380. */
  381. handleDelete() {
  382. DeleteByIds([this.id]).then(() => {
  383. this.$toast('删除成功')
  384. this.$refreshAndToPrev(this)
  385. }).catch(() => {})
  386. },
  387. /**
  388. * 转移
  389. */
  390. handleTransfer(user) {
  391. let params = {
  392. ids: [this.id],
  393. ownerUserId: user.userId,
  394. transferType: 1
  395. }
  396. ChangeOwnerUser(params).then(() => {
  397. this.$toast('转移成功')
  398. this.getDetail()
  399. this.$refreshAndToPrev(this)
  400. }).catch(() => {})
  401. }
  402. }
  403. }
  404. </script>
  405. <style scoped lang="scss">
  406. @import "../style/detail.scss";
  407. .info-cell {
  408. padding: 0 32rpx;
  409. margin-top: 20rpx;
  410. .info-cell-item {
  411. margin-bottom: 15rpx;
  412. @include left;
  413. .money {
  414. font-size: $wk-font-sm;
  415. font-weight: bold;
  416. color: $warning;
  417. }
  418. .text {
  419. font-size: $wk-font-mini;
  420. color: $gray;
  421. }
  422. }
  423. }
  424. </style>