detail.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669
  1. <template>
  2. <view class="detail-page white-wrap">
  3. <view>
  4. <!-- 基础信息 -->
  5. <view class="section white-wrap base-info-wrap" v-if="detail">
  6. <image :src="statusImg" mode="aspectFill" class="status-img"></image>
  7. <view class="title">
  8. <text>{{detail.CompanyName}}</text>
  9. <!-- van-tag
  10. color="#ECF5FF"
  11. text-color="#4A83F1"
  12. style="margin-bottom:0;margin-left: 10rpx;"
  13. >新签</van-tag> -->
  14. </view>
  15. <view class="base-info-list">
  16. <view>
  17. <text class="lable">合同编号:</text>
  18. <text >{{detail.ContractCode}}</text>
  19. <van-tag color="#ECF5FF" text-color="#4A83F1" style="margin-left:5px;margin-top:2px">{{detail.ContractType}}</van-tag>
  20. </view>
  21. <view style="margin-bottom:0">
  22. <text class="lable">合同期限:</text>
  23. <text>{{detail.StartDate|formatDate}}~{{detail.EndDate | formatDate}}</text>
  24. </view>
  25. <view style="padding-left:140rpx">({{detail.StartDate|formateYear(detail.EndDate)}})</view>
  26. <view>
  27. <text class="lable">合同金额:</text>
  28. <text style="color:#FE6B7C">{{detail.Price}}元</text>
  29. </view>
  30. <view>
  31. <text class="lable">合同归属:</text>
  32. <text>{{detail.ProductId===1?'FICC':'权益'}}</text>
  33. </view>
  34. <view>付款方式说明:{{detail.PayRemark}}</view>
  35. <view>付款渠道:{{detail.PayChannel}}</view>
  36. <view v-if="detail.SellerRemark">备注:{{detail.SellerRemark}}</view>
  37. <view v-if="detail && detail.Status === '已驳回'">
  38. <text class="lable" style="color:#FE6B7C">驳回理由:</text>
  39. <text style="color:#FE6B7C">{{ detail.ApprovalRemark }}</text>
  40. </view>
  41. </view>
  42. </view>
  43. <!-- 变更说明 -->
  44. <view class="section white-wrap change-info-wrap" v-if="changeDesc.length>0">
  45. <view class="title">变更说明</view>
  46. <view style="margin-bottom: 20rpx;" v-for="(item,index) in changeDesc" :key="index">{{index+1}}、{{item}}</view>
  47. </view>
  48. <!-- 服务内容 -->
  49. <view class="section white-wrap service-wrap">
  50. <view class="title">服务内容</view>
  51. <view style="margin-bottom: 30rpx;" >
  52. <view class="service-item flex" v-for="item in detail.Service" :key="item.Title">
  53. <text style="width:60%">{{item.Title}}</text>
  54. <text class="btn" @click="handlePreviewImg(item.Value)">查看服务单</text>
  55. </view>
  56. </view>
  57. <view v-if="detail.Remark" style="border-top: 1px dashed rgba(112, 112, 112, .21);padding-top:10px;margin-bottom: 30rpx;">补充内容:{{detail.Remark}}</view>
  58. <view style="border-top: 1px dashed rgba(112, 112, 112, .21);padding-top:10px" v-if="varietyList.length>0">
  59. <view style="margin-bottom:10rpx">小套餐包含品种</view>
  60. <view class="variety-list">
  61. <view class="variety-item flex" v-for="item in varietyList" :key="item.ClassifyName">
  62. <view class="lable">{{ item.ClassifyName }}:</view>
  63. <view class="content">
  64. <van-tag color="#ECF5FF" text-color="#4A83F1" v-for="tag in item.Items"
  65. :key="tag.ChartPermissionId" custom-class="tag">{{ tag.PermissionName }}</van-tag>
  66. </view>
  67. </view>
  68. </view>
  69. </view>
  70. </view>
  71. <!-- 回签附件 -->
  72. <view class="section white-wrap contract-wrap" v-if="detail.Status==='已签回'">
  73. <view class="title">回签附件</view>
  74. <view class="contract-list">
  75. <view class="contract-item" v-for="item in checkBackFiles" :key="item.url"
  76. @click="preViewContract(item)">
  77. <image class="contract-img" mode="aspectFill" :src="item.img"></image>
  78. </view>
  79. </view>
  80. </view>
  81. <!-- 解约附件 -->
  82. <view class="section white-wrap contract-wrap" v-if="detail.Status==='已解约'">
  83. <view class="title">解约附件</view>
  84. <view class="contract-list">
  85. <view class="contract-item" v-for="item in rescindFile" :key="item.url"
  86. @click="preViewContract(item)">
  87. <image class="contract-img" mode="aspectFill" :src="item.img"></image>
  88. </view>
  89. </view>
  90. </view>
  91. <!-- 合同模块 -->
  92. <view class="section white-wrap contract-wrap" v-if="constractFiles.length !== 0&&detail.Status!='已签回'&&detail.Status!='已解约'">
  93. <view class="title">合同预览</view>
  94. <view class="contract-list">
  95. <view class="contract-item" v-for="item in constractFiles" :key="item.url"
  96. @click="preViewContract(item)">
  97. <image class="contract-img" mode="aspectFill" :src="item.img"></image>
  98. </view>
  99. </view>
  100. </view>
  101. <!-- 客户信息模块 -->
  102. <view class="section white-wrap customer-wrap">
  103. <view class="title">客户信息</view>
  104. <view class="customer-main-info">
  105. <view class="customer-info-item">
  106. <text>客户名称:</text>
  107. <text>{{detail.CompanyName}}</text>
  108. </view>
  109. <view class="customer-info-item">
  110. <text>社会信用码:</text>
  111. <text>{{detail.CreditCode}}</text>
  112. </view>
  113. <view class="customer-info-item">
  114. <text>地址:</text>
  115. <text>{{detail.Province}}{{detail.City}}{{detail.Address}}</text>
  116. </view>
  117. <view class="customer-info-item">
  118. <text>申请人:</text>
  119. <text>{{detail.SellerName}}</text>
  120. </view>
  121. </view>
  122. </view>
  123. <!-- 流程模块 -->
  124. <view class="section white-wrap process-wrap" v-if="flowNodeList">
  125. <view class="title">审批流程</view>
  126. <steps :data="flowNodeList"></steps>
  127. </view>
  128. </view>
  129. <!-- 审批按钮 -->
  130. <view class="fix-bottom-wrap btns-wrap flex" v-if="opt.Approval">
  131. <button class="pass-btn" @click="handlePass">通过</button>
  132. <button class="refuse-btn" @click="handleRefuse">驳回</button>
  133. </view>
  134. <!-- 上传回签附件 -->
  135. <view class="fix-bottom-wrap btns-wrap flex" v-if="opt.UploadFile">
  136. <button class="pass-btn" style="width: 450rpx;" @click="handleUploadMethod('file')">{{detail.Status==='已审批'?'上传回签附件':'更新回签附件'}}</button>
  137. </view>
  138. <!-- 作废合同 -->
  139. <!-- <view class="fix-bottom-wrap btns-wrap flex" v-if="opt.Invalid">
  140. <button class="refuse-btn" style="width: 450rpx;" >作废合同</button>
  141. </view> -->
  142. <!-- 上传回签附件选择上传文件类型弹窗 -->
  143. <van-popup :show="show" @close="show=false" round>
  144. <view style="width: 50vw;text-align: center;font-size: 16px;padding: 32rpx;line-height: 80rpx;">
  145. <view @click="handleUploadMethod('img')">上传图片</view>
  146. <view @click="handleUploadMethod('file')">上传文件</view>
  147. </view>
  148. </van-popup>
  149. <!-- 上传回签附件弹窗 -->
  150. <van-popup :show="showUpload" @close="showUpload=false" position="bottom" round>
  151. <view class="uploadfile-wrap">
  152. <view style="text-align: center;font-size: 16px;font-weight: bold;">上传回签附件</view>
  153. <view class="contract-list" style="height: 30vh;">
  154. <view class="contract-item" v-for="item in files" :key="item.url"
  155. @click="preViewContract(item)">
  156. <image class="contract-img" mode="aspectFill" :src="item.img"></image>
  157. </view>
  158. </view>
  159. <button style="width: 450rpx;" @click='handleConfirmSignBack'>确定</button>
  160. </view>
  161. </van-popup>
  162. <van-dialog id="van-dialog" />
  163. </view>
  164. </template>
  165. <script>
  166. import {apiContractDetail,apiContractApproved,apiContractApprovalDetail,apiContractSignBackFiles} from '@/api/approve/contract.js'
  167. import steps from '../components/steps.vue'
  168. import {preViewFile} from '../utils/util.js'
  169. import {uploadImg,uploadFiles} from '@/utils/uploadFile.js'
  170. import {CalculationDate} from '@/utils/calculationDate.js'
  171. export default{
  172. components:{
  173. steps
  174. },
  175. filters:{
  176. formatDate(e){
  177. if(e==='0001-01-01T00:00:00Z'){
  178. return ''
  179. }else{
  180. return e.split('T')[0].replace(/-/g,'.')
  181. }
  182. },
  183. formatTime(e){
  184. if(e==='0001-01-01T00:00:00Z'){
  185. return ''
  186. }else{
  187. return e.replace(/T/g,' ').replace(/\+08:00/g,' ').replace(/-/g,'.')
  188. }
  189. },
  190. formateYear(s,e){
  191. return `有效期为 ${CalculationDate(s,e)}`;
  192. }
  193. },
  194. computed:{
  195. // 处理变更说明
  196. changeDesc(){
  197. return this.detail&&this.detail.ModifyContent&&this.detail.ModifyContent.split('<br/>').filter(item=> item)
  198. },
  199. //回签附件
  200. checkBackFiles(){
  201. const reg = /\.(pdf)|\.doc|\.docx$/;
  202. return this.detail&&this.detail.CheckBackFileUrl&&this.detail.CheckBackFileUrl.split("#").map((item) => {
  203. if (reg.test(item)) {
  204. return {
  205. type: "pdf",
  206. url: item,
  207. img: require("@/pages-approve/static/pdf.png"),
  208. };
  209. } else {
  210. return {
  211. type: "img",
  212. url: item,
  213. img: item,
  214. };
  215. }
  216. });
  217. },
  218. //解约附件
  219. rescindFile(){
  220. const reg = /\.(pdf)|\.doc|\.docx$/;
  221. return this.detail&&this.detail.RescindFileUrl&&this.detail.RescindFileUrl.split("#").map((item) => {
  222. if (reg.test(item)) {
  223. return {
  224. type: "pdf",
  225. url: item,
  226. img: require("@/pages-approve/static/pdf.png"),
  227. };
  228. } else {
  229. return {
  230. type: "img",
  231. url: item,
  232. img: item,
  233. };
  234. }
  235. });
  236. },
  237. // 合同附件
  238. constractFiles(){
  239. const reg = /\.(pdf)|\.doc|\.docx$/;
  240. return this.detail&&this.detail.FileUrl&&this.detail.FileUrl.split("#").map((item) => {
  241. if (reg.test(item)) {
  242. return {
  243. type: "pdf",
  244. url: item,
  245. img: require("@/pages-approve/static/pdf.png"),
  246. };
  247. } else {
  248. return {
  249. type: "img",
  250. url: item,
  251. img: item,
  252. };
  253. }
  254. });
  255. },
  256. // 状态图标
  257. statusImg(){
  258. if(!this.detail) return
  259. if(this.detail.Status==='已审批'){
  260. return require('../static/pass-icon.png')
  261. }else if(this.detail.Status==='已签回'){
  262. return require('../static/draw-back-icon.png')
  263. }else if(this.detail.Status==='已驳回'){
  264. return require('../static/fail-icon.png')
  265. }else if(this.detail.Status==='已作废'){
  266. return require('../static/cancel-icon.png')
  267. }else if(this.detail.Status==='已撤回'){
  268. return require('../static/recall-icon.png')
  269. }else if(this.detail.Status==='处理中'){
  270. return require('../static/processing-icon.png')
  271. }else if(this.detail.Status==='已解约'){
  272. return require('../static/jieyue-icon.png')
  273. }
  274. }
  275. },
  276. data() {
  277. return {
  278. ContractApprovalId: null,//审批单id
  279. ContractApprovalRecordId:null,//审批流程单id
  280. ContractId:null,//合同id
  281. detail:null,
  282. flowNodeList:null,
  283. opt:{},
  284. show:false,
  285. showUpload:false,
  286. files:[],
  287. varietyList:[],
  288. }
  289. },
  290. onLoad(options) {
  291. this.ContractApprovalId=options.ContractApprovalId||0
  292. this.ContractApprovalRecordId=options.ContractApprovalRecordId||0
  293. this.ContractId=options.ContractId||0
  294. },
  295. onShow() {
  296. // 当合同id 不存在时(或0) 使用审批详情
  297. if(this.ContractId!=0){
  298. this.getContractDetail()
  299. }else{
  300. this.getApprovalDetail()
  301. }
  302. },
  303. onPullDownRefresh() {
  304. if(this.ContractId!=0){
  305. this.getContractDetail()
  306. }else{
  307. this.getApprovalDetail()
  308. }
  309. setTimeout(()=>{
  310. uni.stopPullDownRefresh()
  311. },1000)
  312. },
  313. methods: {
  314. //确认提交上传回签附件
  315. async handleConfirmSignBack(){
  316. let FileUrlarr=this.files.map(item=>item.url)
  317. const res=await apiContractSignBackFiles({
  318. ContractId:Number(this.detail.ContractId),
  319. FileUrl:FileUrlarr.join('#')
  320. })
  321. if(res.code===200){
  322. uni.showToast({
  323. title:'操作成功',
  324. icon:'none'
  325. })
  326. // 已审批上传签回附件更新列表
  327. if(this.detail.Status==='已审批'){
  328. uni.$emit('contractApproveListUpdate',{
  329. ContractApprovalId:this.ContractApprovalId,
  330. ContractApprovalRecordId:this.ContractApprovalRecordId,
  331. ContractId:this.ContractId
  332. })
  333. }
  334. setTimeout(()=>{
  335. this.showUpload=false
  336. this.files=[]
  337. if(this.ContractId!=0){
  338. this.getContractDetail()
  339. }else{
  340. this.getApprovalDetail()
  341. }
  342. },1000)
  343. }
  344. },
  345. // 上传回签附件文件
  346. async handleUploadMethod(type){
  347. let res=[]
  348. if(type==='img'){
  349. res=await uploadImg()
  350. }else if(type==='file'){
  351. res=await uploadFiles({type:'file'})
  352. }
  353. const reg = /\.(pdf)|\.doc|\.docx$/;
  354. if(!reg.test(res[0])){
  355. uni.showToast({
  356. title:'请上传pdf/word格式文件',
  357. icon:"none"
  358. })
  359. return
  360. }
  361. this.files=[{type:'pdf',url:res[0],img: require("@/pages-approve/static/pdf.png")}]
  362. // this.files=res.map((item) => {
  363. // if (reg.test(item)) {
  364. // return {
  365. // type: "pdf",
  366. // url: item,
  367. // img: require("@/pages-approve/static/pdf.png"),
  368. // };
  369. // } else {
  370. // return {
  371. // type: "img",
  372. // url: item,
  373. // img: item,
  374. // };
  375. // }
  376. // });
  377. this.show=false
  378. this.showUpload=true
  379. },
  380. // 审批单详情
  381. async getApprovalDetail() {
  382. const res=await apiContractApprovalDetail({
  383. ContractApprovalId:Number(this.ContractApprovalId),
  384. ContractApprovalRecordId:Number(this.ContractApprovalRecordId)
  385. })
  386. if(res.code===200){
  387. this.detail=res.data.ContractDetail
  388. this.opt=res.data.OpButton
  389. this.flowNodeList=res.data.FlowNodeList
  390. this.handleVariety(res.data.ContractDetail.Service)
  391. }
  392. },
  393. //合同详情
  394. async getContractDetail(){
  395. const res=await apiContractDetail({ContractId:Number(this.ContractId)})
  396. if(res.code===200){
  397. this.detail=res.data.ContractDetail
  398. this.opt=res.data.OpButton
  399. this.flowNodeList=res.data.FlowNodeList
  400. this.handleVariety(res.data.ContractDetail.PermissionLookList)
  401. }
  402. },
  403. // 处理小套餐选中的品种
  404. handleVariety(e){
  405. let arr=e.filter(item=>{
  406. return item.CheckList.length>0
  407. })
  408. arr.forEach(item=>{
  409. item.Items=item.Items.filter(_item=>{
  410. return item.CheckList.includes(_item.ChartPermissionId);
  411. })
  412. })
  413. this.varietyList=arr
  414. },
  415. handlePreviewImg(url){
  416. uni.previewImage({
  417. urls:[url]
  418. })
  419. },
  420. // 预览合同文件
  421. preViewContract(e) {
  422. if (e.type === "pdf") {
  423. preViewFile(e.url)
  424. } else {
  425. this.handlePreviewImg(e.url)
  426. }
  427. },
  428. //审批通过
  429. async handlePass(){
  430. const res=await apiContractApproved({ContractId:Number(this.detail.ContractId)})
  431. if(res.code===200){
  432. this.$dialog.alert({
  433. title: "处理成功",
  434. confirmButtonColor: "#5890FB",
  435. }).then(() => {
  436. // on close
  437. // 当合同id 不存在时(或0) 使用审批详情
  438. if(this.ContractId!=0){
  439. this.getContractDetail()
  440. }else{
  441. this.getApprovalDetail()
  442. }
  443. // 更新列表
  444. uni.$emit('contractApproveListUpdate',{
  445. ContractApprovalId:this.ContractApprovalId,
  446. ContractApprovalRecordId:this.ContractApprovalRecordId,
  447. ContractId:this.ContractId
  448. })
  449. });
  450. }
  451. },
  452. //审批驳回
  453. handleRefuse(){
  454. uni.$once('contractApproveReject',()=>{
  455. // 更新列表
  456. uni.$emit('contractApproveListUpdate',{
  457. ContractApprovalId:this.ContractApprovalId,
  458. ContractApprovalRecordId:this.ContractApprovalRecordId,
  459. ContractId:this.ContractId
  460. })
  461. })
  462. uni.navigateTo({
  463. url:"./reason?ContractId="+this.detail.ContractId
  464. })
  465. }
  466. },
  467. }
  468. </script>
  469. <style lang="scss">
  470. .detail-page {
  471. width: 100%;
  472. min-height: 100%;
  473. padding-bottom: calc(150rpx + constant(safe-area-inset-bottom));
  474. padding-bottom: calc(150rpx + env(safe-area-inset-bottom));
  475. }
  476. .section {
  477. padding: 30rpx 34rpx;
  478. border-bottom: 14rpx solid #f5f5f5;
  479. &:last-child {
  480. margin-bottom: 0;
  481. border: none;
  482. }
  483. .title {
  484. font-size: 16px;
  485. font-weight: bold;
  486. margin: 0 0 40rpx 0;
  487. color: #333;
  488. }
  489. .lable {
  490. color: #666;
  491. flex-shrink: 0;
  492. font-size: 14px;
  493. }
  494. }
  495. .section::last-child{
  496. border: none;
  497. }
  498. .base-info-wrap {
  499. position: relative;
  500. .status-img{
  501. position: absolute;
  502. width: 222rpx;
  503. height: 222rpx;
  504. right: 0;
  505. top: 150rpx;
  506. z-index: 10;
  507. }
  508. .title {
  509. margin: 0 0 40rpx 0;
  510. &::before {
  511. content: "";
  512. display: inline-block;
  513. width: 15px;
  514. height: 17px;
  515. background-image: url("@/static/man.png");
  516. background-size: cover;
  517. background-repeat: no-repeat;
  518. margin-right: 10rpx;
  519. position: relative;
  520. top: 4rpx;
  521. }
  522. }
  523. .base-info-list {
  524. font-size: 14px;
  525. color: #000;
  526. view {
  527. margin-bottom: 10px;
  528. display: flex;
  529. }
  530. }
  531. }
  532. .contract-list {
  533. display: flex;
  534. flex-wrap: wrap;
  535. .contract-img {
  536. width: 102rpx;
  537. height: 120rpx;
  538. margin-right: 20rpx;
  539. margin-bottom: 20rpx;
  540. }
  541. }
  542. .service-wrap{
  543. color: #666;
  544. .service-item{
  545. margin-bottom: 30rpx;
  546. position: relative;
  547. justify-content: space-between;
  548. .btn{
  549. color: #3385FF;
  550. }
  551. // &::after{
  552. // content: '查看服务单';
  553. // display: inline-block;
  554. // color: #3385FF;
  555. // position: absolute;
  556. // left: 35%;
  557. // }
  558. }
  559. }
  560. .customer-main-info {
  561. padding-bottom: 40rpx;
  562. }
  563. .customer-info-item {
  564. font-size: 14px;
  565. color: #999;
  566. margin-bottom: 20rpx;
  567. }
  568. .customer-info-list {
  569. flex-wrap: wrap;
  570. padding-top: 20rpx;
  571. }
  572. .variety-list{
  573. .variety-item {
  574. padding-top: 24rpx;
  575. padding-bottom: 24rpx;
  576. border-bottom: 1px dashed rgba(112, 112, 112, 0.2);
  577. }
  578. .variety-item:first-child {
  579. padding-top: 0;
  580. }
  581. .variety-item:last-child {
  582. border-bottom: none;
  583. }
  584. .tag {
  585. margin-right: 10rpx;
  586. margin-bottom: 10rpx;
  587. }
  588. }
  589. .btns-wrap {
  590. justify-content: center;
  591. button {
  592. width: 260rpx;
  593. height: 70rpx;
  594. border-radius: 28px;
  595. border: none;
  596. margin: 0 15px;
  597. font-size: 15px;
  598. color: #fff;
  599. line-height: 70rpx;
  600. }
  601. .pass-btn {
  602. background-color: #5890fb;
  603. }
  604. .refuse-btn {
  605. background-color: #f55768;
  606. }
  607. }
  608. .uploadfile-wrap{
  609. width: 100%;
  610. height: 50vh;
  611. background-color: #FFFFFF;
  612. padding: 32rpx;
  613. button {
  614. margin-left: auto;
  615. margin-right: auto;
  616. width: 260rpx;
  617. height: 70rpx;
  618. display: block;
  619. border-radius: 28px;
  620. border: none;
  621. font-size: 15px;
  622. color: #fff;
  623. line-height: 70rpx;
  624. background-color: #5890fb;
  625. }
  626. }
  627. </style>