contractList.vue 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094
  1. <script>
  2. import { defineComponent } from 'vue'
  3. export default defineComponent({
  4. // 进入前是否清除参数
  5. beforeRouteEnter(to, from, next) {
  6. if(from.path!='/contractdetail'&&from.path!='/contractdetaildc'&&from.path!='/addcontractdc'){
  7. sessionStorage.removeItem('contractListBack')
  8. sessionStorage.removeItem('contractListTabs')
  9. }
  10. next()
  11. }
  12. })
  13. </script>
  14. <script setup>
  15. import { ref,reactive,computed } from "vue";
  16. import { onBeforeRouteLeave ,useRouter} from 'vue-router';
  17. import {ElMessage,ElMessageBox} from "element-plus"
  18. import _ from 'lodash'
  19. import PreviewService from "./components/PreviewService.vue";
  20. import { contractInterface,customInterence } from "@/api/api.js";
  21. import ExplainDlg from './components/ExplainDlg.vue';
  22. import {formatter,formatPriceHasPoint} from "@/hooks/mixins/index"
  23. const $router = useRouter()
  24. // 离开前缓存页面状态
  25. onBeforeRouteLeave((to, from, next)=>{
  26. let obj={
  27. page:page.value,
  28. searchVal:searchVal.value,
  29. searchType:searchType.value,
  30. timeRange:timeRange.value,
  31. constractTypeVal:constractTypeVal.value,
  32. constractStatusVal:constractStatusVal.value,
  33. constractBelongVal:constractBelongVal.value,
  34. constractSellerVal:constractSellerVal.value,
  35. }
  36. sessionStorage.setItem('contractListBack',JSON.stringify(obj))
  37. sessionStorage.setItem('contractListTabs',tabsActive.value)
  38. next()
  39. })
  40. const tabs=[{name:'业务合同'},{name:"代付合同"}]
  41. //合同类型选项
  42. const constractTypeOptions=[
  43. {value: "新签合同",label: "新签合同"},
  44. {value: "续约合同",label: "续约合同"},
  45. {value: "补充协议",label: "补充协议"}]
  46. //合同状态选项
  47. const constractStatusOptions=ref([
  48. {value: "待提交",lable: "待提交"},
  49. {value: "待审批",lable: "待审批"},
  50. {value: "已撤回",lable: "已撤回"},
  51. {value: "已审批",lable: "已审批"},
  52. {value: "已驳回",lable: "已驳回"},
  53. {value: "已作废",lable: "已作废"},
  54. {value: "已签回",lable: "已签回"},
  55. {value: "已解约",lable: "已解约"}
  56. ])
  57. //合同归属选项
  58. const constractBelongOptions=[
  59. {value: "1",label: "FICC"},
  60. {value: "2",label: "权益"}]
  61. //销售级联配置
  62. const defaultSalesProps={
  63. multiple: true,
  64. label:'RealName',
  65. children:'ChildrenList',
  66. value:'AdminId'
  67. }
  68. const tabsActive=ref(sessionStorage.getItem('contractListTabs')||'业务合同')
  69. const searchType=ref('使用方')
  70. const showPreContractList=ref(false)
  71. const preContractList=ref([])
  72. const showAddTypeDia=ref(false)//新增合同类型弹窗
  73. const RoleType=ref(localStorage.getItem("Role") || "")
  74. const contractTemList=ref([])//合同模板列表
  75. const serviceCon=ref([])//套餐数据
  76. const showPreview=ref(false)//查看套餐弹窗
  77. const showDownload=ref(false)//下载合同模板弹窗
  78. const page=ref(1)
  79. const pageSize=ref(10)
  80. const total=ref(0)
  81. const searchVal=ref("")//搜索值
  82. const timeRange=ref(["", ""])//选择时间段
  83. const constractTypeVal=ref("")//选择的合同类型值
  84. const constractStatusVal=ref("")//选择的合同状态值
  85. const constractBelongVal=ref("")//合同归属值
  86. const constractSellerOptions=ref([])//申请销售列表
  87. const constractSellerVal=ref("")//申请销售值
  88. const tableList=ref([])//合同列表数据(表格)
  89. const uploadFileData=reactive({
  90. name:"",//文件名
  91. CompanyName:"",//客户名
  92. url:'',
  93. contractId:0,
  94. file:null,
  95. })//销售更新合同文件数据
  96. const showUploadAttachment=ref(false)//销售更新合同文件弹窗
  97. const explainShowDownload=ref(false)//操作详情
  98. const showlc=ref(false)
  99. const exportExcel=computed(()=>{
  100. let baseUrl = import.meta.env.VITE_APP_API_ROOT + "/contract/list";
  101. let token = localStorage.getItem("auth") || "";
  102. let paramStr = "";
  103. let obj = {
  104. ContractType: constractTypeVal.value,
  105. ContractStatus: constractStatusVal.value,
  106. ProductId: constractBelongVal.value || 0,
  107. ModifyStartTime: !timeRange.value?'':timeRange.value[0] ? `${timeRange.value[0]} 00:00:00` : "",
  108. ModifyEndTime: !timeRange.value?'':timeRange.value[1] ? `${timeRange.value[1]} 23:59:59` : "",
  109. SellerId: '',
  110. Keyword: searchVal.value,
  111. KeywordType:searchType.value,
  112. IsExport:true,
  113. ContractBusinessType:tabsActive.value,
  114. };
  115. if(constractSellerVal.value.length){
  116. obj.SellerId=constractSellerVal.value.map(item=>{
  117. return item[item.length-1]
  118. }).join(',')
  119. }
  120. for (let key in obj) {
  121. paramStr = `${paramStr}&${key}=${obj[key]}`;
  122. }
  123. return `${baseUrl}?${token}${paramStr}`;
  124. })
  125. // 业务合同、代付合同切换
  126. const handleChangeTabs=(e)=>{
  127. tabsActive.value=e
  128. handleRefreshPage()
  129. }
  130. // 业务合同查看代付合同、代付合同查看
  131. const handlePreviewContract=(e)=>{
  132. console.log(preContractList.value,'preContractList.value');
  133. // 只有一个直接跳转
  134. if(e.length===1){
  135. let contractId=0
  136. if(tabsActive.value==='业务合同'){
  137. contractId=e[0].PaymentOnBehalfContractId
  138. }else if(tabsActive.value==='代付合同'){
  139. contractId=e[0].ContractId
  140. }
  141. handleGoContractdtl(contractId)
  142. }else if(e.length>1){
  143. preContractList.value=e
  144. showPreContractList.value=true
  145. }
  146. }
  147. // 跳转合同预览
  148. const handleGoContractdtl=(id)=>{
  149. let {href} = $router.resolve({path:"/contractdtl",query:{contractid:id}});
  150. window.open(href,'_blank');
  151. }
  152. const checkFileBeforeUpload=(file)=>{
  153. let hostfile = file;
  154. let size = Math.floor(hostfile.size / 1024 / 1024);
  155. if (size > 200) {
  156. ElMessage.error("上传文件大小不能大于200M!");
  157. hostfile = {};
  158. return false;
  159. }
  160. if (hostfile.name.toLowerCase().includes(".pdf")||hostfile.name.toLowerCase().includes(".doc")||hostfile.name.toLowerCase().includes(".docx")) {
  161. uploadFileData.name=hostfile.name.toLowerCase()
  162. uploadFileData.file=hostfile
  163. } else {
  164. ElMessage.error("请上传PDF/word文件!");
  165. }
  166. return false
  167. }
  168. // 销售更新合同附件
  169. const handleUploadAttachment=()=>{
  170. $("#fileCard").click();
  171. }
  172. // 获取列表数据
  173. const getContractList=()=>{
  174. // 处理销售筛选
  175. let salesArr=[]
  176. if(constractSellerVal.value.length){
  177. salesArr=constractSellerVal.value.map(item=>{
  178. return item[item.length-1]
  179. })
  180. }
  181. let params = {
  182. ContractType: constractTypeVal.value,
  183. ContractStatus: constractStatusVal.value,
  184. ProductId: Number(constractBelongVal.value),
  185. ModifyStartTime: !timeRange.value?'':timeRange.value[0] ? `${timeRange.value[0]} 00:00:00` : "",
  186. ModifyEndTime: !timeRange.value?'':timeRange.value[1] ? `${timeRange.value[1]} 23:59:59` : "",
  187. SellerId: salesArr.join(','),
  188. Keyword: searchVal.value,
  189. KeywordType:searchType.value,
  190. CurrentIndex: page.value,
  191. PageSize: pageSize.value,
  192. ContractBusinessType:tabsActive.value,
  193. };
  194. contractInterface.getContractList(params).then((res) => {
  195. if (res.Ret === 200) {
  196. tableList.value = res.Data.List;
  197. total.value = res.Data.Paging.Totals;
  198. }
  199. });
  200. }
  201. //获取所属销售列表
  202. const getSellerList=()=>{
  203. contractInterface.getSellerList().then((res) => {
  204. if (res.Ret === 200) {
  205. constractSellerOptions.value = res.Data.List;
  206. }
  207. });
  208. }
  209. // 选择文件上传
  210. const fileSelected=()=>{
  211. //选择文件上传
  212. if (document.getElementById("fileCard").files[0]) {
  213. let hostfile = document.getElementById("fileCard").files[0];
  214. let size = Math.floor(hostfile.size / 1024 / 1024);
  215. if (size > 200) {
  216. ElMessage.error("上传文件大小不能大于200M!");
  217. hostfile = {};
  218. return false;
  219. }
  220. if (hostfile.name.toLowerCase().includes(".pdf")||hostfile.name.toLowerCase().includes(".doc")||hostfile.name.toLowerCase().includes(".docx")) {
  221. // let form = new FormData();
  222. // form.append("file", hostfile); //hostfile.name
  223. // customInterence.upload(form).then((res) => {
  224. // if (res.Ret === 200) {
  225. // // that.$message.success( '上传成功' );
  226. // this.uploadFileData.url = res.Data.ResourceUrl;
  227. // this.uploadFileData.name=hostfile.name.toLowerCase()
  228. // }
  229. // $("#fileCard").val("");
  230. // hostfile = {};
  231. // });
  232. uploadFileData.name=hostfile.name.toLowerCase()
  233. uploadFileData.file=hostfile
  234. } else {
  235. ElMessage.error("请上传PDF/word文件!");
  236. }
  237. }
  238. }
  239. // 确定更新合同附件
  240. const handleConfirmUpdateContractFile = async ()=>{
  241. if(!uploadFileData.file){
  242. ElMessage.warning('请上传文件');
  243. return
  244. }
  245. let form = new FormData();
  246. form.append("file", uploadFileData.file)
  247. form.append('ContractId',uploadFileData.contractId)
  248. // const res=await contractInterface.updateContractFile({
  249. // ContractId:this.uploadFileData.contractId,
  250. // FileUrl:this.uploadFileData.url
  251. // })
  252. const res=await contractInterface.updateContractFile(form)
  253. if(res.Ret===200){
  254. ElMessage.success('更新成功')
  255. getContractList()
  256. showUploadAttachment.value=false
  257. }
  258. }
  259. //下载合同模板
  260. const handleDownloadContractTemplate=()=>{
  261. contractInterface.getContractTemplate().then((res) => {
  262. if (res.Ret === 200) {
  263. contractTemList.value = res.Data;
  264. showDownload.value = true;
  265. }
  266. });
  267. }
  268. //刷新页面
  269. const handleRefreshPage=()=>{
  270. page.value = 1;
  271. searchVal.value = "";
  272. timeRange.value = ["", ""];
  273. constractTypeVal.value = "";
  274. constractStatusVal.value = "";
  275. constractBelongVal.value=''
  276. constractSellerVal.value=''
  277. getContractList();
  278. }
  279. //提交申请
  280. const handleSubmitApproval=(id)=>{
  281. contractInterface.applyContract({ ContractId: Number(id) }).then((res) => {
  282. if (res.Ret === 200) {
  283. ElMessage.success("提交成功");
  284. handleRefreshPage();
  285. }
  286. });
  287. }
  288. //撤回申请
  289. const handleCancelApplyContract=(ContractApprovalRecordId, ContractId)=>{
  290. contractInterface.cancelApplyContract({ ContractApprovalRecordId, ContractId }).then((res) => {
  291. if (res.Ret === 200) {
  292. ElMessage.success("撤回成功");
  293. handleRefreshPage();
  294. }
  295. });
  296. }
  297. /**
  298. * 操作
  299. * type 操作类型
  300. * e 数据
  301. * 查看套餐(viewPackage)、驳回理由(rejectReason)、申请重审(applyRetrial)
  302. * 删除(delete)、下载(download)、作废合同(cancelConstract)、撤回申请(backApply)
  303. * 修改合同(modifyConstract)、复制模板(copy)、编辑(edit)、提交审批(submitApproval)
  304. * 未提交审核的下载(downloadTem) 查看附件(已签回 checkBack 已解约rescind) 销售更新合同附件(updatefConstractFile)
  305. * 修改重审(modifyAndApply)
  306. */
  307. const handleOperation=_.debounce(function(type, e) {
  308. if(type==='checkBack'){
  309. const url=e.CheckBackFileUrl
  310. if(!url){
  311. ElMessage.warning('文件错误')
  312. return
  313. }
  314. const reg = /\.(pdf)$/;
  315. // pdf
  316. if(reg.test(url)){
  317. window.open(url,'_blank');
  318. }else{
  319. window.open('https://view.officeapps.live.com/op/view.aspx?src='+url,'_blank');
  320. }
  321. // window.open(e.CheckBackFileUrl,'_blank');
  322. }
  323. if(type==='rescind'){
  324. const url=e.RescindFileUrl
  325. if(!url){
  326. ElMessage.warning('文件错误')
  327. return
  328. }
  329. const reg = /\.(pdf)$/;
  330. // pdf
  331. if(reg.test(url)){
  332. window.open(url,'_blank');
  333. }else{
  334. window.open('https://view.officeapps.live.com/op/view.aspx?src='+url,'_blank');
  335. }
  336. // window.open(e.RescindFileUrl,'_blank');
  337. }
  338. if (type === "submitApproval") {
  339. handleSubmitApproval(e.ContractId);
  340. return;
  341. }
  342. if (type === "delete") {
  343. ElMessageBox.confirm("是否确认删除合同?", "提示", {
  344. confirmButtonText: "确定",
  345. cancelButtonText: "取消",
  346. type: "warning",
  347. }).then(() => {
  348. contractInterface.contractDelete({ ContractId: e.ContractId }).then((res) => {
  349. if (res.Ret === 200) {
  350. ElMessage.success("删除成功");
  351. handleRefreshPage();
  352. }
  353. });
  354. }).catch(()=>{})
  355. return;
  356. }
  357. if (type === "edit") {
  358. if(e.ContractBusinessType==='业务合同'){
  359. $router.push({
  360. path: "/editcontract",
  361. query: {
  362. contractId: e.ContractId,
  363. type: type,
  364. },
  365. });
  366. }else{
  367. $router.push({
  368. path: "/editcontractdc",
  369. query: {
  370. contractId: e.ContractId,
  371. type: type,
  372. },
  373. });
  374. }
  375. return;
  376. }
  377. if (type === "viewPackage") {
  378. if(e.ContractBusinessType==='业务合同'){
  379. serviceCon.value = e.Service;
  380. }else{
  381. let arr=[]
  382. e.RelationContractList.forEach(item=>{
  383. item.Service.forEach(item2=>{
  384. arr.push(item2)
  385. })
  386. })
  387. serviceCon.value=arr
  388. }
  389. showPreview.value = true;
  390. return;
  391. }
  392. if (type === "rejectReason") {
  393. ElMessageBox.alert(e.ApprovalRemark, "驳回理由", {
  394. confirmButtonText: "知道了",
  395. showCancelButton: false,
  396. }).then(() => {});
  397. return;
  398. }
  399. if (type === "cancelConstract") {
  400. ElMessageBox.confirm("作废后合同将不能再使用,是否确认作废合同?", "提示", {
  401. confirmButtonText: "确定",
  402. cancelButtonText: "取消",
  403. type: "warning",
  404. }).then(() => {
  405. contractInterface.contractInvalid({ ContractId: e.ContractId }).then((res) => {
  406. if (res.Ret === 200) {
  407. ElMessage.success("作废成功");
  408. handleRefreshPage();
  409. }
  410. });
  411. }).catch(()=>{})
  412. return;
  413. }
  414. if (type === "backApply") {
  415. ElMessageBox.confirm("确认撤回该合同吗?", "提示", {
  416. confirmButtonText: "确定",
  417. cancelButtonText: "取消",
  418. type: "warning",
  419. }).then(() => {
  420. handleCancelApplyContract(e.ContractApprovalRecordId, e.ContractId);
  421. }).catch(()=>{})
  422. return;
  423. }
  424. if (type === "download") {
  425. let link = document.createElement("a");
  426. link.href = e.FileUrl + "?response-content-type=application/octet-stream";
  427. link.setAttribute("download", e.ContractCode);
  428. link.style.display = "none"; //a标签隐藏
  429. document.body.appendChild(link);
  430. link.click();
  431. return;
  432. }
  433. if(type==='downloadTem'){
  434. let baseUrl = import.meta.env.VITE_APP_API_ROOT + "/contract/downLoad/tmpContract";
  435. let token = localStorage.getItem("auth") || "";
  436. let path=`${baseUrl}?${token}&ContractId=${e.ContractId}`
  437. let link = document.createElement("a");
  438. link.href = path;
  439. link.setAttribute("download", e.ContractCode);
  440. link.style.display = "none"; //a标签隐藏
  441. document.body.appendChild(link);
  442. link.click();
  443. return
  444. }
  445. if (type === "modifyConstract") {
  446. if(e.ContractBusinessType==='业务合同'){
  447. $router.push({
  448. path: "/editcontract",
  449. query: {
  450. contractId: e.ContractId,
  451. type: type,
  452. },
  453. });
  454. }else{
  455. $router.push({
  456. path: "/editcontractdc",
  457. query: {
  458. contractId: e.ContractId,
  459. type: type,
  460. },
  461. });
  462. }
  463. return;
  464. }
  465. if (type === "applyRetrial") {
  466. if(e.ContractBusinessType==='业务合同'){
  467. $router.push({
  468. path: "/retrialcontract",
  469. query: {
  470. contractId: e.ContractId,
  471. type: type,
  472. },
  473. });
  474. }else{
  475. $router.push({
  476. path: "/retrialcontractdc",
  477. query: {
  478. contractId: e.ContractId,
  479. type: type,
  480. },
  481. });
  482. }
  483. return;
  484. }
  485. if (type === "copy") {
  486. if(e.ContractBusinessType==='业务合同'){
  487. $router.push({
  488. path: "/copycontract",
  489. query: {
  490. contractId: e.ContractId,
  491. type: type,
  492. },
  493. });
  494. }else{
  495. $router.push({
  496. path: "/copycontract",
  497. query: {
  498. contractId: e.ContractId,
  499. type: type,
  500. },
  501. });
  502. $router.push({
  503. path: "/copycontractdc",
  504. query: {
  505. contractId: e.ContractId,
  506. type: type,
  507. },
  508. });
  509. }
  510. return;
  511. }
  512. // 销售更新合同附件
  513. if(type==='updatefConstractFile'){
  514. let fileName=e.FileUrl.substring(e.FileUrl.lastIndexOf('/') + 1)
  515. uploadFileData.name=fileName
  516. uploadFileData.CompanyName=e.CompanyName
  517. uploadFileData.contractId=e.ContractId
  518. uploadFileData.url=e.FileUrl
  519. showUploadAttachment.value=true
  520. }
  521. // 修改重审
  522. if(type==='modifyAndApply'){
  523. if(e.ContractBusinessType==='业务合同'){
  524. $router.push({
  525. path: "/modifyapply",
  526. query: {
  527. contractId: e.ContractId,
  528. type: type,
  529. },
  530. });
  531. }else{
  532. $router.push({
  533. path: "/modifyapplydc",
  534. query: {
  535. contractId: e.ContractId,
  536. type: type,
  537. },
  538. });
  539. }
  540. return
  541. }
  542. },200)
  543. //关闭查看套餐弹窗
  544. const handleClosePreviewService=()=>{
  545. showPreview.value = false;
  546. }
  547. //类型或者状态变更
  548. const handleSelectChange=()=>{
  549. searchVal.value = "";
  550. page.value = 1;
  551. getContractList();
  552. }
  553. //页码改变
  554. const handlePageChange=(e)=>{
  555. page.value = e;
  556. getContractList();
  557. }
  558. //跳转合同详情
  559. const handleGoDetail=(type,id)=>{
  560. if(type==='业务合同'){
  561. $router.push({ path: "/contractdetail", query: { contractId: id } });
  562. }else{
  563. $router.push({ path: "/contractdetaildc", query: { contractId: id } });
  564. }
  565. }
  566. //搜索
  567. const handleSearch=()=>{
  568. timeRange.value = ["", ""];
  569. constractTypeVal.value = "";
  570. constractStatusVal.value = "";
  571. constractSellerVal.value=''
  572. constractBelongVal.value=''
  573. page.value = 1;
  574. getContractList();
  575. }
  576. //查看详细操作说明
  577. const explainDialog=()=>{
  578. explainShowDownload.value=true;
  579. }
  580. // created
  581. if(sessionStorage.getItem('contractListBack')){
  582. let cache=JSON.parse(sessionStorage.getItem('contractListBack'))
  583. page.value=cache.page
  584. searchVal.value=cache.searchVal
  585. timeRange.value=cache.timeRange
  586. constractBelongVal.value=cache.constractBelongVal
  587. constractTypeVal.value=cache.constractTypeVal
  588. constractStatusVal.value=cache.constractStatusVal
  589. constractSellerVal.value=cache.constractSellerVal
  590. }
  591. if(RoleType.value === 'admin'){
  592. constractStatusOptions.value= [
  593. {
  594. value: "待审批",
  595. lable: "待审批",
  596. },
  597. {
  598. value: "已审批",
  599. lable: "已审批",
  600. },
  601. {
  602. value: "已驳回",
  603. lable: "已驳回",
  604. },
  605. {
  606. value: "已作废",
  607. lable: "已作废",
  608. },
  609. {
  610. value: "已签回",
  611. lable: "已签回",
  612. },
  613. {
  614. value: "已解约",
  615. lable: "已解约",
  616. },
  617. ] //合同状态选项
  618. }
  619. getContractList();
  620. getSellerList();
  621. </script>
  622. <template>
  623. <div class="contractlist-container">
  624. <div class="top-wrap">
  625. <template v-if="RoleType === 'ficc_seller' || RoleType === 'rai_seller'" style="margin-right:10px;">
  626. <el-button type="primary" @click="showAddTypeDia=true" size="large">添加合同</el-button>
  627. <el-button type="primary" plain @click="handleDownloadContractTemplate" size="large">合同操作指南</el-button>
  628. </template>
  629. <template v-if="!(RoleType === 'ficc_seller' || RoleType === 'rai_seller')" >
  630. <a :href="exportExcel" download>
  631. <el-button type="primary" size="large">下载EXCEL</el-button>
  632. </a>
  633. </template>
  634. <el-input placeholder="合同编号/客户名称/社会信用码" v-model="searchVal" size="large"
  635. style="max-width: 400px; float: right" @input="handleSearch" clearable>
  636. <i slot="prefix" class="el-input__icon el-icon-search"></i>
  637. </el-input>
  638. <el-select v-model="searchType" placeholder="请选择" style="width:120px;float: right;margin-right:10px" size="large">
  639. <el-option label="客户名称" value="使用方"></el-option>
  640. <el-option label="代付方" value="代付方"></el-option>
  641. </el-select>
  642. </div>
  643. <div class="list-wrap">
  644. <div style="margin-top: 10px; margin-bottom: 10px">
  645. <el-date-picker style="margin-bottom: 20px;margin-right:20px" v-model="timeRange" type="daterange" size="large"
  646. @change="handleSelectChange" value-format="yyyy-MM-dd" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期">
  647. </el-date-picker>
  648. <el-select v-if="tabsActive==='业务合同'" clearable v-model="constractTypeVal" @change="handleSelectChange" size="large"
  649. placeholder="合同类型" style="margin-bottom: 20px;margin-right:20px">
  650. <el-option v-for="item in constractTypeOptions" :key="item.value" :label="item.label" :value="item.value"> </el-option>
  651. </el-select>
  652. <el-select clearable v-model="constractStatusVal" @change="handleSelectChange" placeholder="合同状态" size="large"
  653. style="margin-bottom: 20px;margin-right:20px">
  654. <el-option v-for="item in constractStatusOptions" :key="item.value" :label="item.label" :value="item.value"> </el-option>
  655. </el-select>
  656. <template v-if="RoleType === 'admin'||RoleType==='compliance'||RoleType==='finance'">
  657. <el-select clearable v-model="constractBelongVal" @change="handleSelectChange" placeholder="合同归属"
  658. style="margin-bottom: 20px;margin-right:20px" size="large">
  659. <el-option v-for="item in constractBelongOptions" :key="item.value" :label="item.label" :value="item.value"> </el-option>
  660. </el-select>
  661. <!-- <el-select clearable v-model="constractSellerVal" @change="handleSelectChange" placeholder="申请销售" style="margin-bottom: 20px;margin-right:20px">
  662. <el-option v-for="item in constractSellerOptions" :key="item.AdminId" :label="item.RealName" :value="item.AdminId"> </el-option>
  663. </el-select> -->
  664. <el-cascader
  665. v-model="constractSellerVal"
  666. placeholder="申请销售"
  667. style="min-width:225px;margin-bottom: 20px;margin-right:20px"
  668. :options="constractSellerOptions"
  669. :props="defaultSalesProps"
  670. :show-all-levels="false"
  671. collapse-tags
  672. clearable
  673. filterable
  674. size="large"
  675. @change="handleSelectChange">
  676. </el-cascader>
  677. </template>
  678. </div>
  679. <ul class="tabs-wrap">
  680. <li
  681. v-for="item in tabs"
  682. :class="['tab',{'act':tabsActive === item.name}]"
  683. @click="handleChangeTabs(item.name)"
  684. >{{item.name}}</li>
  685. </ul>
  686. <el-table :data="tableList" border ref="table">
  687. <el-table-column key="合同编号" align="center" prop="ContractCode" label="合同编号" width="160">
  688. <template #default="scope">
  689. <span class="constract-sn" @click="handleGoDetail(scope.row.ContractBusinessType,scope.row.ContractId)">{{ scope.row.ContractCode }}</span>
  690. </template>
  691. </el-table-column>
  692. <el-table-column key="客户名称" align="center" prop="CompanyName" :label="tabsActive==='业务合同'?'客户名称':'代付方'"></el-table-column>
  693. <el-table-column key="社会信用码" align="center" prop="CreditCode" label="社会信用码" width="180"></el-table-column>
  694. <el-table-column key="代付方" align="center" prop="RelationContractList" :label="tabsActive==='业务合同'?'付款方':'客户名称'">
  695. <template #default="scope">
  696. <div v-if="!scope.row.RelationContractList">{{scope.row.PayChannel=='无'?scope.row.CompanyName:scope.row.PayChannel}}</div>
  697. <div v-else style="color:#409eff;cursor: pointer" @click="handlePreviewContract(scope.row.RelationContractList)">
  698. <span v-if="scope.row.RelationContractList.length===1">{{scope.row.RelationContractList[0].CompanyName}}</span>
  699. <span v-else>查看</span>
  700. </div>
  701. </template>
  702. </el-table-column>
  703. <el-table-column key="销售" align="center" prop="SellerName" label="销售" width="80"></el-table-column>
  704. <el-table-column key="合同类型" align="center" prop="ContractType" label="合同类型" width="80"></el-table-column>
  705. <el-table-column key="合同有效期" align="center" label="合同有效期" width="180">
  706. <template #default="scope">{{ scope.row.StartDateStr }}~{{ scope.row.EndDateStr }}</template>
  707. </el-table-column>
  708. <el-table-column key="合同金额" align="center" prop="Price" :label="tabsActive==='业务合同'?'合同金额':'代付金额'" width="100">
  709. <template #default="scope">{{ formatPriceHasPoint(scope.row.Price) }}</template>
  710. </el-table-column>
  711. <el-table-column key="合同状态" align="center" prop="Status" label="合同状态" width="80">
  712. <template #default="scope">
  713. <span :style="{ color: scope.row.Status === '已驳回'||scope.row.Status === '已解约' ? '#FF0000' : null }">{{ scope.row.Status }}</span>
  714. </template>
  715. </el-table-column>
  716. <el-table-column key="更新时间" align="center" prop="ModifyTimeStr" label="更新时间" width="160" :formatter="formatter"></el-table-column>
  717. <el-table-column key="seller操作" align="center" label="操作" width="200" v-if="RoleType === 'ficc_seller' || RoleType === 'rai_seller'">
  718. <template #default="scope">
  719. <div v-if="scope.row.Status === '待提交'">
  720. <span class="btn" @click="handleOperation('submitApproval', scope.row)">提交审批</span>
  721. <span class="btn" @click="handleOperation('edit', scope.row)">编辑</span>
  722. <!-- <span class="btn" @click="handleOperation('downloadTem', scope.row)">草稿下载</span> -->
  723. <span class="btn" @click="handleOperation('delete', scope.row)" style="color: #ff0000">删除</span>
  724. </div>
  725. <div v-if="scope.row.Status === '待审批'">
  726. <span class="btn" @click="handleOperation('viewPackage', scope.row)">查看套餐</span>
  727. <span class="btn" @click="handleOperation('backApply', scope.row)">撤回申请</span>
  728. </div>
  729. <div v-if="scope.row.Status === '已撤回'">
  730. <span class="btn" @click="handleOperation('viewPackage', scope.row)">查看套餐</span>
  731. <span class="btn" @click="handleOperation('modifyConstract', scope.row)">修改合同</span>
  732. <span class="btn" @click="handleOperation('delete', scope.row)" style="color: #ff0000">删除</span>
  733. </div>
  734. <div v-if="scope.row.Status === '已审批'">
  735. <span class="btn" @click="handleOperation('viewPackage', scope.row)">查看套餐</span>
  736. <span class="btn" @click="handleOperation('cancelConstract', scope.row)">作废合同</span>
  737. <span class="btn" @click="handleOperation('download', scope.row)">下载</span>
  738. <span class="btn" @click="handleOperation('modifyAndApply', scope.row)">修改重审</span>
  739. <!-- <span class="btn" @click="handleOperation('updatefConstractFile',scope.row)" v-if="scope.row.OpButton.UpdateFile">更新附件</span> -->
  740. </div>
  741. <div v-if="scope.row.Status === '已驳回'">
  742. <span class="btn" @click="handleOperation('viewPackage', scope.row)">查看套餐</span>
  743. <span class="btn" @click="handleOperation('rejectReason', scope.row)">驳回理由</span>
  744. <span class="btn" @click="handleOperation('applyRetrial', scope.row)">申请重审</span>
  745. <span class="btn" @click="handleOperation('delete', scope.row)" style="color: #ff0000">删除</span>
  746. </div>
  747. <div v-if="scope.row.Status === '已作废'">
  748. <span class="btn" @click="handleOperation('copy', scope.row)">复制模板</span>
  749. <span class="btn" @click="handleOperation('delete', scope.row)" style="color: #ff0000">删除</span>
  750. </div>
  751. <div v-if="scope.row.Status === '已签回'">
  752. <span class="btn" @click="handleOperation('checkBack', scope.row)">查看附件</span>
  753. </div>
  754. <div v-if="scope.row.Status === '已解约'">
  755. <span class="btn" @click="handleOperation('rescind', scope.row)">查看附件</span>
  756. </div>
  757. </template>
  758. </el-table-column>
  759. <el-table-column key="admin操作" align="center" label="操作" width="150" v-if="RoleType === 'admin'">
  760. <template #default="scope">
  761. <span class="btn" @click="handleOperation('viewPackage', scope.row)">查看套餐</span>
  762. <span class="btn" @click="handleOperation('download', scope.row)" v-if="scope.row.Status === '已审批'">下载</span>
  763. <span class="btn" @click="handleOperation('rejectReason', scope.row)" v-if="scope.row.Status === '已驳回'">驳回理由</span>
  764. </template>
  765. </el-table-column>
  766. </el-table>
  767. <!-- 分页 -->
  768. <el-pagination layout="total,prev,pager,next,jumper" background :current-page="page" size="large"
  769. @current-change="handlePageChange" :page-size="pageSize" :total="total" class="pagination-wrap">
  770. </el-pagination>
  771. </div>
  772. <!-- 下载提示弹框 -->
  773. <el-dialog
  774. v-dialogDrag
  775. :append-to-body="true"
  776. v-model="showDownload"
  777. width="50%"
  778. center
  779. >
  780. <template #header>
  781. <img src="../../assets/img/icons/warn.png" width="16" height="16" style="vertical-align: middle;margin-right: 4px" />
  782. <span style="vertical-align: middle">合同操作指南:</span>
  783. </template>
  784. <div class="download-popup-wrap">
  785. <!-- <img class="top-img" src="../../assets/img/constract/liucheng.png" alt="" /> -->
  786. <div class="top-img"></div>
  787. <!-- <a :href="item.Url+'?response-content-type=application/octet-stream'" :download="item.Title" v-for="item in contractTemList" :key="item.ContractTemplateId">{{ item.Title }}</a> -->
  788. <a @click="explainDialog">查看详细操作说明</a>
  789. <a @click="showlc=true" style="display:block;margin-top:10px;position:relative">查看详细操作流程图</a>
  790. </div>
  791. </el-dialog>
  792. <!-- 查看套餐弹框 -->
  793. <PreviewService :showPreview="showPreview" :serviceCon="serviceCon" @closePreviewService="handleClosePreviewService"></PreviewService>
  794. <!-- 查看合同列表弹框 -->
  795. <el-dialog
  796. v-dialogDrag
  797. :append-to-body="true"
  798. v-model="showPreContractList"
  799. width="40%"
  800. center
  801. >
  802. <template #header>
  803. <div style="font-size:15px">{{tabsActive==='业务合同'?'付款方列表':'代付方列表'}}</div>
  804. </template>
  805. <ul class="precontract-list">
  806. <li
  807. v-for="item in preContractList"
  808. :key="item.ContractId+item.PaymentOnBehalfContractId"
  809. @click="handleGoContractdtl(tabsActive==='业务合同'?item.PaymentOnBehalfContractId:item.ContractId)"
  810. >{{item.CompanyName}}</li>
  811. </ul>
  812. <div style="text-align:center;margin:40px 0 30px 0">
  813. <el-button type="primary" style="width:200px" @click="showPreContractList=false">关闭</el-button>
  814. </div>
  815. </el-dialog>
  816. <!-- 选择新增合同类型 -->
  817. <el-dialog
  818. v-dialogDrag
  819. :append-to-body="true"
  820. v-model="showAddTypeDia"
  821. width="800px"
  822. class="self-dialog"
  823. center
  824. >
  825. <div style="text-align:center;margin:30px 0 100px 0">
  826. <img width="191" src="../../assets/img/constract/bzht.png" @click="$router.push('/addcontract')" style="margin-right:80px;cursor: pointer;">
  827. <img width="191" src="../../assets/img/constract/dfht.png" @click="$router.push('/addcontractdc')" style="cursor: pointer;">
  828. <p style="font-size:15px;color:#333;text-align:left;padding-left:100px;margin-top:30px">
  829. 注:标准代付指的是无法签署三方协议和代付合同时,可以选择和代付方签署该类型合同
  830. </p>
  831. </div>
  832. </el-dialog>
  833. <!-- 销售更新合同文件 -->
  834. <el-dialog top="30vh" v-dialogDrag width="570px" v-model="showUploadAttachment" :modal-append-to-body="false" @close="showUploadAttachment=false">
  835. <div slot="title">
  836. <img width='15' src="../../assets/img/icons/edit1.png" alt="">
  837. <span style="display:inline-block;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;max-width:450px">更新合同附件({{uploadFileData.CompanyName}})</span>
  838. </div>
  839. <div class="upload-attachment-wrap">
  840. <div style="display:flex;align-items: center;">
  841. <input type="file" name="file" @change="fileSelected" id="fileCard" style="display: none" />
  842. <div class="box"><span v-if="!uploadFileData.name" style="color:#999">请选择文件</span>{{uploadFileData.name}}</div>
  843. <!-- <el-button type="primary" @click="handleUploadAttachment">选择文件</el-button> -->
  844. <el-upload :before-upload="checkFileBeforeUpload">
  845. <el-button type="primary">选择文件</el-button>
  846. </el-upload>
  847. </div>
  848. <div style="text-align:center;margin:60px 0 30px 0">
  849. <el-button type="primary" @click="handleConfirmUpdateContractFile">确定</el-button>
  850. <el-button type="primary" plain @click="showUploadAttachment=false">取消</el-button>
  851. </div>
  852. </div>
  853. </el-dialog>
  854. <explain-dlg :explainShowDownload="explainShowDownload" @close="explainShowDownload=false"/>
  855. <el-dialog
  856. v-dialogDrag
  857. :append-to-body="true"
  858. v-model="showlc"
  859. width="90vw"
  860. top="5vh"
  861. class="self-dialog"
  862. center>
  863. <img style="width:100%" src="../../assets/img/constract/bg.png" />
  864. </el-dialog>
  865. </div>
  866. </template>
  867. <style lang="scss">
  868. .el-message-box__header .el-message-box__title {
  869. color: #333 !important;
  870. }
  871. .el-date-table td.start-date div::after {
  872. content: "起";
  873. display: block;
  874. position: absolute;
  875. top: 64%;
  876. left: 50%;
  877. transform: translateX(-50%) scale(0.9);
  878. color: #666;
  879. z-index: 1000;
  880. font-size: 10px;
  881. }
  882. .el-date-table td.end-date div::after {
  883. content: "终";
  884. display: block;
  885. position: absolute;
  886. top: 64%;
  887. left: 50%;
  888. transform: translateX(-50%) scale(0.9);
  889. color: #666;
  890. z-index: 1000;
  891. font-size: 10px;
  892. }
  893. .el-table__empty-block{
  894. min-height: 300px;
  895. }
  896. .container-explain .el-dialog__header {
  897. background-color: #fff !important;
  898. }
  899. .self-dialog{
  900. // width: 100% !important;
  901. max-width: 100% !important;
  902. .el-dialog__header{
  903. background-color: #fff;
  904. .el-dialog__close.el-icon.el-icon-close{
  905. color: #666;
  906. }
  907. }
  908. }
  909. </style>
  910. <style lang="scss" scoped>
  911. .precontract-list{
  912. border: 1px solid #DCDFE6;
  913. li{
  914. font-size: 14px;
  915. color: #409eff;
  916. cursor: pointer;
  917. padding: 14px 20px;
  918. border-bottom: 1px solid #DCDFE6;
  919. }
  920. li:last-child{
  921. border: none;
  922. }
  923. }
  924. .upload-attachment-wrap{
  925. .box{
  926. width: 380px;
  927. display: inline-block;
  928. box-sizing: border-box;
  929. height: 40px;
  930. line-height: 40px;
  931. padding: 0 17px;
  932. font-size: 14px;
  933. border: 1px solid #DCDFE6;
  934. border-radius: 4px;
  935. margin-right: 20px;
  936. overflow: hidden;
  937. text-overflow: ellipsis;
  938. white-space: nowrap;
  939. }
  940. }
  941. .top-wrap {
  942. margin-bottom: 28px;
  943. padding: 20px 30px;
  944. // min-height: 50px;
  945. background: #fff;
  946. border: 1px solid #ececec;
  947. border-radius: 4px;
  948. box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
  949. }
  950. .tabs-wrap{
  951. display: flex;
  952. margin-bottom: 20px;
  953. align-items: center;
  954. .tab {
  955. padding-bottom: 5px;
  956. text-align: center;
  957. font-size: 14px;
  958. cursor: pointer;
  959. transition-delay: 0.05s;
  960. margin-right: 40px;
  961. color: #333;
  962. &:hover {
  963. color: #409EFF;
  964. }
  965. &.act {
  966. color: #409eff;
  967. border-bottom: 2px solid #409EFF;
  968. }
  969. }
  970. }
  971. .list-wrap {
  972. min-height: calc(100vh - 390px);
  973. padding: 20px 30px 80px;
  974. background: #fff;
  975. margin-top: 20px;
  976. position: relative;
  977. border: 1px solid #ececec;
  978. border-radius: 4px;
  979. box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
  980. .constract-sn {
  981. cursor: pointer;
  982. color: #409eff;
  983. }
  984. .btn {
  985. font-size: 14px;
  986. display: inline-block;
  987. color: #409eff;
  988. cursor: pointer;
  989. margin: 0 3px;
  990. }
  991. .pagination-wrap {
  992. position: absolute;
  993. bottom: 24px;
  994. right: 30px;
  995. }
  996. }
  997. .download-popup-wrap {
  998. text-align: center;
  999. padding-bottom: 80px;
  1000. .top-img {
  1001. // width: 80%;
  1002. // display: block;
  1003. // margin: 20px auto;
  1004. width: 100%;
  1005. padding-bottom: 53%;
  1006. background-image: url('../../assets/img/constract/liucheng.png');
  1007. background-size: cover;
  1008. background-position: center;
  1009. }
  1010. a {
  1011. color: #409eff;
  1012. cursor: pointer;
  1013. // &::before {
  1014. // content: "";
  1015. // display: inline-block;
  1016. // width: 15px;
  1017. // height: 15px;
  1018. // background-image: url("../../assets/img/constract/download.png");
  1019. // background-size: cover;
  1020. // margin-right: 10px;
  1021. // }
  1022. }
  1023. }
  1024. </style>