addSeal.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  1. <template>
  2. <view class="add-page white-wrap">
  3. <view class="section white-wrap">
  4. <view class="section-title require">用印用途</view>
  5. <view class="section-select-box" :style="{color:purpose?'#333':'#999'}" @click="showPurpose=true">{{purpose?purpose:'请选择'}}</view>
  6. </view>
  7. <view class="section white-wrap">
  8. <van-radio-group :value="radioVal" @change="radioChange" direction="horizontal">
  9. <van-radio name="系统合同" style="margin-right: 70px;">系统合同</van-radio>
  10. <van-radio name="上传附件">上传附件</van-radio>
  11. </van-radio-group>
  12. </view>
  13. <!-- 系统合同模块 -->
  14. <view v-if="radioVal==='系统合同'">
  15. <view class="section white-wrap">
  16. <view class="section-title require">客户名称(全称)</view>
  17. <view
  18. class="section-select-box"
  19. :style="{color:customeName?'#333':'#999'}"
  20. @click="showCustome=true"
  21. >
  22. {{customeName?customeName:'请输入客户名称'}}
  23. </view>
  24. </view>
  25. <view class="section white-wrap" v-if="CreditCode">
  26. <view class="section-title require">统一社会信用码</view>
  27. <input type="text" v-model="CreditCode" placeholder="请填写统一社会信用码" disabled/>
  28. </view>
  29. <view class="section white-wrap" v-if="UseCompanyName">
  30. <view class="section-title">实际使用方名称</view>
  31. <input type="text" v-model="UseCompanyName" placeholder="请填写实际使用方名称" disabled/>
  32. </view>
  33. <view class="section white-wrap" v-if="ServiceType">
  34. <view class="section-title require">业务类型</view>
  35. <view :style="{color:ServiceType?'#333':'#999'}">{{ServiceType?ServiceType:'请选择业务类型'}}</view>
  36. </view>
  37. </view>
  38. <!-- 上传附件模块 -->
  39. <view v-if="radioVal==='上传附件'">
  40. <view class="section white-wrap">
  41. <view class="section-title require">客户名称(全称)</view>
  42. <input type="text" v-model="customeName" placeholder="请输入客户名称"/>
  43. </view>
  44. <view class="section white-wrap">
  45. <view class="section-title require">统一社会信用码</view>
  46. <input type="text" v-model="CreditCode" placeholder="请填写统一社会信用码"/>
  47. </view>
  48. <view class="section white-wrap">
  49. <view class="section-title">实际使用方名称</view>
  50. <input type="text" v-model="UseCompanyName" placeholder="请填写实际使用方名称"/>
  51. </view>
  52. <view class="section white-wrap">
  53. <view class="section-title require">业务类型</view>
  54. <view class="section-select-box" :style="{color:ServiceType?'#333':'#999'}" @click="showServiceType=true">{{ServiceType?ServiceType:'请选择业务类型'}}</view>
  55. </view>
  56. </view>
  57. <view class="section white-wrap">
  58. <view class="section-title require">文件份数</view>
  59. <input type="number" v-model="fileNum" placeholder="请填写总共盖章文件份数"/>
  60. </view>
  61. <view class="section white-wrap">
  62. <view class="section-title require">加盖何种印章</view>
  63. <view class="section-select-box" :style="{color:type?'#333':'#999'}" @click="showType=true">{{type?type:'请选择'}}</view>
  64. </view>
  65. <view class="section white-wrap">
  66. <view class="section-title">备注</view>
  67. <textarea type="text" v-model="remark" placeholder="请填写备注"></textarea>
  68. </view>
  69. <view class="section white-wrap" v-if="radioVal==='系统合同'&&ContractfileUrl">
  70. <view class="section-title require">合同附件</view>
  71. <image src="../static/pdf.png" mode="aspectFill" style="width: 102rpx;height: 120rpx;" @click="handlePreviewFiles({type:'pdf',url:ContractfileUrl})"></image>
  72. </view>
  73. <view class="section white-wrap" v-if="radioVal==='上传附件'">
  74. <view class="section-title require">附件上传</view>
  75. <div class="check-file-box" :style="'background-image:url('+file.img+')'" v-if="file.url" @click="handlePreviewFiles(file)">
  76. <image class="del-icon" src="../static/del-icon.png" @click.stop="handleDeleteCheckFile"></image>
  77. </div>
  78. <image v-else @click="handleUpload" src="../static/upload-icon.png" mode="aspectFill" style="width: 102rpx;height: 120rpx;"></image>
  79. </view>
  80. <!-- 流程模块 -->
  81. <view class="section white-wrap process-wrap" v-if="processData">
  82. <view class="title" style="font-size: 16px;font-weight: bold;">审批流程</view>
  83. <steps :data="processData"></steps>
  84. </view>
  85. <view class="fix-bottom-wrap" style="text-align: center;">
  86. <van-button type="info" custom-class="btn" round @click="handleSubmit">提交</van-button>
  87. </view>
  88. <!-- 用印用途 -->
  89. <van-popup :show="showPurpose" @close="showPurpose=false" position="bottom">
  90. <van-picker
  91. show-toolbar
  92. title="选择用印用途"
  93. :columns="purposeArr"
  94. @confirm="handlePurposeConfirm"
  95. @cancel="showPurpose=false"
  96. />
  97. </van-popup>
  98. <!-- 何种印章 -->
  99. <van-popup :show="showType" @close="showType=false" position="bottom">
  100. <van-picker
  101. show-toolbar
  102. title="选择何种印章"
  103. :columns="typeArr"
  104. @confirm="handleTypeConfirm"
  105. @cancel="showType=false"
  106. />
  107. </van-popup>
  108. <!-- 业务类型 -->
  109. <van-popup :show="showServiceType" @close="showServiceType=false" position="bottom">
  110. <van-picker
  111. show-toolbar
  112. title="选择业务类型"
  113. :columns="ServiceTypeArr"
  114. @confirm="handleServiceTypeConfirm"
  115. @cancel="showServiceType=false"
  116. />
  117. </van-popup>
  118. <!-- 客户搜索 -->
  119. <van-popup :show="showCustome" @close="showCustome=false" position="bottom" custom-style="height: 100vh">
  120. <view class="custome-search-wrap">
  121. <van-search use-left-icon-slot use-action-slot shape="round" :value="searchCustomeVal" placeholder="请输入客户名称/社会信用码" @change="onSearchValChange" @search="onSearch"
  122. custom-class="search-box" field-class="search-con">
  123. <view slot="left-icon">
  124. <image src="../static/search-icon.png" mode="aspectFill" class="search-icon"></image>
  125. </view>
  126. <view slot="action" @click="showCustome=false" class="search-btn">取消</view>
  127. </van-search>
  128. <view class="search-result">
  129. <view class="result-custome-box" v-if="searchContractList.length===0">
  130. <van-empty description="暂无数据" :image="require('@/static/empty.png')" v-if="!searchCustomeStatus"/>
  131. <view v-else>
  132. <view class="result-item flex" v-for="item in searchCustomeList" :key="item" @click="getContract(item)">
  133. <image src="../static/search-icon.png" mode="aspectFill" class="search-icon"></image>
  134. <view class="con van-ellipsis">{{item}}</view>
  135. <image src="../static/click-icon.png" mode="aspectFill" class="click-icon"></image>
  136. </view>
  137. </view>
  138. </view>
  139. <view class="result-contract-box" v-else>
  140. <view class="result-contract-item" v-for="item in searchContractList" :key="item.ContractId" @click="handleChooseContract(item)">
  141. <view class="name">{{item.CompanyName}}</view>
  142. <view style="margin-top: 20rpx;">合同编号:{{item.ContractCode}}</view>
  143. <view style="margin-top: 20rpx;">合同类型:{{item.ContractType}}</view>
  144. <view style="margin-top: 20rpx;">合同金额:{{item.Price}}</view>
  145. </view>
  146. </view>
  147. </view>
  148. </view>
  149. </van-popup>
  150. </view>
  151. </template>
  152. <script>
  153. import steps from '../components/steps.vue'
  154. import {apiFlowDetail,apiSealAdd,apiSearchCustome,apiSearchContract} from '@/api/approve/seal.js'
  155. import {uploadFiles} from '@/utils/uploadFile.js'
  156. import {preViewFile} from '../utils/util.js'
  157. export default{
  158. components:{
  159. steps
  160. },
  161. watch:{
  162. showCustome(){
  163. this.searchCustomeVal=''
  164. this.searchCustomeStatus=true
  165. this.searchCustomeList=[]
  166. this.searchContractList=[]
  167. }
  168. },
  169. data() {
  170. return {
  171. showPurpose:false,//显示用印用途选项
  172. purposeArr:['销售合同','渠道合同','付款通知函','招投标','战略合作协议'],
  173. purpose:"",
  174. showType:false,//显示用印用途选项
  175. typeArr:['公章','合同章','法人章'],
  176. type:"",
  177. showServiceType:false,//显示业务类型选项
  178. ServiceTypeArr:['新签合同','续约合同','补充协议'],
  179. ServiceType:'',//业务类型
  180. showCustome:false,//显示搜索客户名称
  181. customeName: '',//客户名称
  182. fileNum:'',//文件数
  183. remark:'',//备注
  184. CreditCode:'',//社会统一信用代码
  185. UseCompanyName:'',//实际使用方客户名称
  186. ContractId:0,//合同id
  187. ContractfileUrl:'',//合同文件地址 pdf
  188. file:{
  189. type:'',
  190. img:'',
  191. url:''
  192. },//上传附件 文件
  193. processData:null,//流程数据
  194. radioVal:'系统合同',
  195. searchCustomeVal:'',//搜索客户输入数据
  196. searchCustomeStatus:true,//搜索客户 是否有结果
  197. searchCustomeList:[],//搜索到的客户名称列表
  198. searchContractList:[],//选择搜索中的客户后合同列表数据
  199. }
  200. },
  201. methods: {
  202. //删除上传的附件
  203. handleDeleteCheckFile(){
  204. this.file={
  205. type:'',
  206. img:'',
  207. url:''
  208. }
  209. },
  210. //预览文件
  211. handlePreviewFiles(e){
  212. if (e.type === "pdf") {
  213. preViewFile(e.url)
  214. } else {
  215. uni.previewImage({
  216. urls: [e.url]
  217. })
  218. }
  219. },
  220. //上传附件
  221. async handleUpload(){
  222. const res=await uploadFiles({type:'all'})
  223. const reg = /\.(pdf)$/;
  224. if(reg.test(res[0])){
  225. this.file={
  226. type:'pdf',
  227. url:res[0],
  228. img:require('../static/pdf.png')
  229. }
  230. }else{
  231. this.file={
  232. type:'img',
  233. url:res[0],
  234. img:res[0]
  235. }
  236. }
  237. },
  238. // 客户搜索
  239. // 先搜索出客户 再通过客户去请求出客户下面存在的合同
  240. onSearchValChange(e){
  241. this.searchCustomeVal=e.detail
  242. },
  243. //搜索客户
  244. async onSearch(){
  245. this.searchContractList=[]
  246. this.searchCustomeList=[]
  247. const res=await apiSearchCustome({Keyword:this.searchCustomeVal})
  248. if(res.code===200){
  249. this.searchCustomeList=res.data
  250. if(res.data.length===0){
  251. this.searchCustomeStatus=false
  252. }else{
  253. this.searchCustomeStatus=true
  254. }
  255. }
  256. },
  257. // 搜索客户对应的合同
  258. async getContract(e){
  259. const res=await apiSearchContract({Keyword:e})
  260. if(res.code===200){
  261. if(res.data.List){
  262. this.searchContractList=res.data.List
  263. }else{
  264. uni.showToast({
  265. title:"此客户无合同,请重新选择",
  266. icon:"none"
  267. })
  268. }
  269. }
  270. },
  271. // 选择合同 更新表单数据
  272. handleChooseContract(e){
  273. this.customeName=e.CompanyName
  274. this.CreditCode=e.CreditCode
  275. this.ServiceType=e.ContractType
  276. this.UseCompanyName=e.CompanyName
  277. this.ContractId=e.ContractId
  278. this.ContractfileUrl=e.FileUrl
  279. // 关闭搜索弹窗
  280. this.showCustome=false
  281. this.searchCustomeVal=''
  282. this.searchContractList=[]
  283. this.searchCustomeList=[]
  284. },
  285. // 系统合同 上传附件类型切换
  286. radioChange(e){
  287. this.radioVal=e.detail
  288. this.customeName=''
  289. this.CreditCode=''
  290. this.ServiceType=''
  291. this.UseCompanyName=''
  292. this.ContractfileUrl=''
  293. this.fileUrlArr=[]
  294. },
  295. // 选择用印用途
  296. handlePurposeConfirm(e) {
  297. this.purpose=e.detail.value
  298. this.showPurpose=false
  299. },
  300. //选择盖章类型
  301. handleTypeConfirm(e){
  302. this.type=e.detail.value
  303. this.showType=false
  304. this.getProcessData()
  305. },
  306. //选择业务类型
  307. handleServiceTypeConfirm(e){
  308. this.ServiceType=e.detail.value
  309. this.showServiceType=false
  310. },
  311. //合同章5 公章、法人章 6
  312. async getProcessData(){
  313. let id=0
  314. if(this.type==='合同章'){
  315. id=5
  316. }else{
  317. id=6
  318. }
  319. let res=await apiFlowDetail({FlowId:id})
  320. if(res.code===200){
  321. this.processData=res.data||null
  322. }
  323. },
  324. // 提交申请
  325. async handleSubmit(){
  326. let fileUrl=''
  327. if(this.radioVal==='系统合同'){
  328. fileUrl=this.ContractfileUrl
  329. }else{
  330. fileUrl=this.file.url
  331. }
  332. let params={
  333. CompanyName:this.customeName,
  334. ContractId:this.ContractId,
  335. CreditCode:this.CreditCode,
  336. FileUrl:fileUrl,
  337. FileNum:Number(this.fileNum),
  338. Remark:this.remark,
  339. SealType:this.type,
  340. ServiceType:this.ServiceType,
  341. Use:this.purpose,
  342. UseCompanyName:this.UseCompanyName,
  343. }
  344. if(!params.Use){
  345. uni.showToast({
  346. title:'请选择用印用途',
  347. icon:"none"
  348. })
  349. return
  350. }
  351. if(!params.CompanyName){
  352. uni.showToast({
  353. title:'客户名称不能为空',
  354. icon:"none"
  355. })
  356. return
  357. }
  358. if(!params.CreditCode){
  359. uni.showToast({
  360. title:'信用代码不能为空',
  361. icon:"none"
  362. })
  363. return
  364. }
  365. if(!params.ServiceType){
  366. uni.showToast({
  367. title:'业务类型不能为空',
  368. icon:"none"
  369. })
  370. return
  371. }
  372. if(!params.FileNum){
  373. uni.showToast({
  374. title:'请填写文件份数',
  375. icon:"none"
  376. })
  377. return
  378. }
  379. if(params.FileNum<1){
  380. uni.showToast({
  381. title:'文件份数不合法',
  382. icon:"none"
  383. })
  384. return
  385. }
  386. if(!params.SealType){
  387. uni.showToast({
  388. title:'印章类型不能为空',
  389. icon:"none"
  390. })
  391. return
  392. }
  393. if(!params.FileUrl){
  394. uni.showToast({
  395. title:'请上传文件',
  396. icon:"none"
  397. })
  398. return
  399. }
  400. console.log(params);
  401. const res=await apiSealAdd(params)
  402. if(res.code===200){
  403. uni.showToast({
  404. title:"用印申请单已提交",
  405. icon:"none"
  406. })
  407. setTimeout(()=>{
  408. uni.navigateBack({
  409. delta:1
  410. })
  411. },1000)
  412. }
  413. }
  414. },
  415. }
  416. </script>
  417. <style lang="scss">
  418. .check-file-box{
  419. width: 102rpx;
  420. height: 120rpx;
  421. background-size: cover;
  422. background-position: center;
  423. position: relative;
  424. .del-icon{
  425. position: absolute;
  426. width: 30rpx;
  427. height: 30rpx;
  428. top: -15rpx;
  429. right: -15rpx;
  430. }
  431. }
  432. .add-page{
  433. width: 100%;
  434. min-height: 100vh;
  435. padding-bottom: calc(150rpx + constant(safe-area-inset-bottom));
  436. padding-bottom: calc(150rpx + env(safe-area-inset-bottom));
  437. }
  438. .section{
  439. padding: 30rpx 34rpx;
  440. border-top: 10rpx solid #F5F5F5;
  441. position: relative;
  442. textarea{
  443. width: 100%;
  444. height: 200rpx;
  445. }
  446. .section-title{
  447. font-size: 16px;
  448. margin-bottom: 20rpx;
  449. }
  450. .require::before{
  451. content: '*';
  452. font-size: 16px;
  453. color: #FF0000;
  454. position: absolute;
  455. left: 20rpx;
  456. }
  457. .section-select-box{
  458. color: #999;
  459. position: relative;
  460. &::after{
  461. position: absolute;
  462. right: 0;
  463. top: 50%;
  464. content: '';
  465. display: block;
  466. width: 18rpx;
  467. height: 18rpx;
  468. border-top: 1px solid #999;
  469. border-right: 1px solid #999;
  470. transform: translateY(-50%) rotate(45deg);
  471. }
  472. }
  473. }
  474. .btn{
  475. width: 360rpx;
  476. height: 60rpx;
  477. }
  478. .radio-wrap{
  479. .radio{
  480. font-size: 14px;
  481. &::before{
  482. content: '';
  483. display: inline-block;
  484. }
  485. }
  486. }
  487. .custome-search-wrap{
  488. padding: 34rpx;
  489. height: 100%;
  490. .search-box {
  491. border: 1px solid #3385FF;
  492. padding: 0 !important;
  493. border-radius: 60rpx;
  494. background-color: #fff !important;
  495. }
  496. .search-con {
  497. background-color: #fff !important;
  498. }
  499. .van-search__content {
  500. background-color: #fff !important;
  501. padding-left: 30rpx !important;
  502. }
  503. .search-btn {
  504. position: relative;
  505. color: #3385FF;
  506. &::before {
  507. content: '';
  508. display: block;
  509. width: 1px;
  510. height: 60%;
  511. background-color: #D1D1D1;
  512. position: absolute;
  513. left: -16rpx;
  514. top: 20%;
  515. }
  516. }
  517. .search-icon{
  518. width: 40rpx;
  519. height: 40rpx;
  520. display: block;
  521. position: relative;
  522. top: 4rpx;
  523. margin-right: 20rpx;
  524. }
  525. .click-icon{
  526. width: 24rpx;
  527. height: 24rpx;
  528. }
  529. .result-item{
  530. align-items: center;
  531. padding: 20rpx 0;
  532. border-bottom: 1px solid #EBEBEB;
  533. .con{
  534. flex: 1;
  535. margin-right: 20rpx;
  536. }
  537. }
  538. .search-result{
  539. overflow-y: auto;
  540. height: 100%;
  541. }
  542. .result-contract-box{
  543. padding: 0 10rpx;
  544. .result-contract-item{
  545. margin-top: 30rpx;
  546. box-shadow: 0px 0px 12rpx rgba(175, 175, 175, 0.38);
  547. padding: 30rpx;
  548. border-radius: 8px;
  549. .name{
  550. font-size: 16px;
  551. font-weight: bold;
  552. &::before{
  553. content:'';
  554. display:inline-block;
  555. width: 31rpx;
  556. height: 34rpx;
  557. background-image: url(../../static/man.png);
  558. background-size: cover;
  559. position: relative;
  560. top: 4rpx;
  561. margin-right: 10rpx;
  562. }
  563. }
  564. }
  565. }
  566. }
  567. </style>