addSeal.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  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" auto-height 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. if(!this.searchCustomeVal){
  246. uni.showToast({
  247. title:'请输入搜索关键字',
  248. icon:'none'
  249. })
  250. return
  251. }
  252. this.searchContractList=[]
  253. this.searchCustomeList=[]
  254. const res=await apiSearchCustome({Keyword:this.searchCustomeVal})
  255. if(res.code===200){
  256. this.searchCustomeList=res.data
  257. if(res.data.length===0){
  258. this.searchCustomeStatus=false
  259. }else{
  260. this.searchCustomeStatus=true
  261. }
  262. }
  263. },
  264. // 搜索客户对应的合同
  265. async getContract(e){
  266. const res=await apiSearchContract({Keyword:e})
  267. if(res.code===200){
  268. if(res.data.List){
  269. this.searchContractList=res.data.List
  270. }else{
  271. uni.showToast({
  272. title:"此客户无合同,请重新选择",
  273. icon:"none"
  274. })
  275. }
  276. }
  277. },
  278. // 选择合同 更新表单数据
  279. handleChooseContract(e){
  280. this.customeName=e.CompanyName
  281. this.CreditCode=e.CreditCode
  282. this.ServiceType=e.ContractType
  283. this.UseCompanyName=e.CompanyName
  284. this.ContractId=e.ContractId
  285. this.ContractfileUrl=e.FileUrl
  286. // 关闭搜索弹窗
  287. this.showCustome=false
  288. this.searchCustomeVal=''
  289. this.searchContractList=[]
  290. this.searchCustomeList=[]
  291. },
  292. // 系统合同 上传附件类型切换
  293. radioChange(e){
  294. this.radioVal=e.detail
  295. this.customeName=''
  296. this.CreditCode=''
  297. this.ServiceType=''
  298. this.UseCompanyName=''
  299. this.ContractfileUrl=''
  300. this.fileUrlArr=[]
  301. },
  302. // 选择用印用途
  303. handlePurposeConfirm(e) {
  304. this.purpose=e.detail.value
  305. this.showPurpose=false
  306. },
  307. //选择盖章类型
  308. handleTypeConfirm(e){
  309. this.type=e.detail.value
  310. this.showType=false
  311. this.getProcessData()
  312. },
  313. //选择业务类型
  314. handleServiceTypeConfirm(e){
  315. this.ServiceType=e.detail.value
  316. this.showServiceType=false
  317. },
  318. //合同章5 公章、法人章 6
  319. async getProcessData(){
  320. let id=0
  321. if(this.type==='合同章'){
  322. id=5
  323. }else{
  324. id=6
  325. }
  326. let res=await apiFlowDetail({FlowId:id})
  327. if(res.code===200){
  328. this.processData=res.data||null
  329. }
  330. },
  331. // 提交申请
  332. async handleSubmit(){
  333. let fileUrl=''
  334. if(this.radioVal==='系统合同'){
  335. fileUrl=this.ContractfileUrl
  336. }else{
  337. fileUrl=this.file.url
  338. }
  339. let params={
  340. CompanyName:this.customeName,
  341. ContractId:this.ContractId,
  342. CreditCode:this.CreditCode,
  343. FileUrl:fileUrl,
  344. FileNum:Number(this.fileNum),
  345. Remark:this.remark,
  346. SealType:this.type,
  347. ServiceType:this.ServiceType,
  348. Use:this.purpose,
  349. UseCompanyName:this.UseCompanyName,
  350. }
  351. if(!params.Use){
  352. uni.showToast({
  353. title:'请选择用印用途',
  354. icon:"none"
  355. })
  356. return
  357. }
  358. if(!params.CompanyName){
  359. uni.showToast({
  360. title:'客户名称不能为空',
  361. icon:"none"
  362. })
  363. return
  364. }
  365. if(!params.CreditCode){
  366. uni.showToast({
  367. title:'信用代码不能为空',
  368. icon:"none"
  369. })
  370. return
  371. }
  372. if(!params.ServiceType){
  373. uni.showToast({
  374. title:'业务类型不能为空',
  375. icon:"none"
  376. })
  377. return
  378. }
  379. if(!params.FileNum){
  380. uni.showToast({
  381. title:'请填写文件份数',
  382. icon:"none"
  383. })
  384. return
  385. }
  386. if(params.FileNum<1){
  387. uni.showToast({
  388. title:'文件份数不合法',
  389. icon:"none"
  390. })
  391. return
  392. }
  393. if(!params.SealType){
  394. uni.showToast({
  395. title:'印章类型不能为空',
  396. icon:"none"
  397. })
  398. return
  399. }
  400. if(!params.FileUrl){
  401. uni.showToast({
  402. title:'请上传文件',
  403. icon:"none"
  404. })
  405. return
  406. }
  407. console.log(params);
  408. const res=await apiSealAdd(params)
  409. if(res.code===200){
  410. uni.showToast({
  411. title:"用印申请单已提交",
  412. icon:"none"
  413. })
  414. uni.$emit('sealApproveListUpdate',{
  415. ContractApprovalId:0,
  416. ContractApprovalRecordId:0,
  417. SealId:0
  418. })
  419. setTimeout(()=>{
  420. uni.navigateBack({
  421. delta:1
  422. })
  423. },1000)
  424. }
  425. }
  426. },
  427. }
  428. </script>
  429. <style lang="scss">
  430. .check-file-box{
  431. width: 102rpx;
  432. height: 120rpx;
  433. background-size: cover;
  434. background-position: center;
  435. position: relative;
  436. .del-icon{
  437. position: absolute;
  438. width: 30rpx;
  439. height: 30rpx;
  440. top: -15rpx;
  441. right: -15rpx;
  442. }
  443. }
  444. .add-page{
  445. width: 100%;
  446. min-height: 100vh;
  447. padding-bottom: calc(150rpx + constant(safe-area-inset-bottom));
  448. padding-bottom: calc(150rpx + env(safe-area-inset-bottom));
  449. }
  450. .section{
  451. padding: 30rpx 34rpx;
  452. border-top: 10rpx solid #F5F5F5;
  453. position: relative;
  454. textarea{
  455. width: 100%;
  456. height: 200rpx;
  457. }
  458. .section-title{
  459. font-size: 16px;
  460. margin-bottom: 20rpx;
  461. }
  462. .require::before{
  463. content: '*';
  464. font-size: 16px;
  465. color: #FF0000;
  466. position: absolute;
  467. left: 20rpx;
  468. }
  469. .section-select-box{
  470. color: #999;
  471. position: relative;
  472. &::after{
  473. position: absolute;
  474. right: 0;
  475. top: 50%;
  476. content: '';
  477. display: block;
  478. width: 18rpx;
  479. height: 18rpx;
  480. border-top: 1px solid #999;
  481. border-right: 1px solid #999;
  482. transform: translateY(-50%) rotate(45deg);
  483. }
  484. }
  485. }
  486. .btn{
  487. width: 360rpx;
  488. height: 60rpx;
  489. }
  490. .radio-wrap{
  491. .radio{
  492. font-size: 14px;
  493. &::before{
  494. content: '';
  495. display: inline-block;
  496. }
  497. }
  498. }
  499. .custome-search-wrap{
  500. padding: 34rpx;
  501. height: 100%;
  502. .search-box {
  503. border: 1px solid #3385FF;
  504. padding: 0 !important;
  505. border-radius: 60rpx;
  506. background-color: #fff !important;
  507. }
  508. .search-con {
  509. background-color: #fff !important;
  510. }
  511. .van-search__content {
  512. background-color: #fff !important;
  513. padding-left: 30rpx !important;
  514. }
  515. .search-btn {
  516. position: relative;
  517. color: #3385FF;
  518. &::before {
  519. content: '';
  520. display: block;
  521. width: 1px;
  522. height: 60%;
  523. background-color: #D1D1D1;
  524. position: absolute;
  525. left: -16rpx;
  526. top: 20%;
  527. }
  528. }
  529. .search-icon{
  530. width: 40rpx;
  531. height: 40rpx;
  532. display: block;
  533. position: relative;
  534. top: 4rpx;
  535. margin-right: 20rpx;
  536. }
  537. .click-icon{
  538. width: 24rpx;
  539. height: 24rpx;
  540. }
  541. .result-item{
  542. align-items: center;
  543. padding: 20rpx 0;
  544. border-bottom: 1px solid #EBEBEB;
  545. .con{
  546. flex: 1;
  547. margin-right: 20rpx;
  548. }
  549. }
  550. .search-result{
  551. overflow-y: auto;
  552. height: 100%;
  553. }
  554. .result-contract-box{
  555. padding: 0 10rpx;
  556. .result-contract-item{
  557. margin-top: 30rpx;
  558. box-shadow: 0px 0px 12rpx rgba(175, 175, 175, 0.38);
  559. padding: 30rpx;
  560. border-radius: 8px;
  561. .name{
  562. font-size: 16px;
  563. font-weight: bold;
  564. &::before{
  565. content:'';
  566. display:inline-block;
  567. width: 31rpx;
  568. height: 34rpx;
  569. background-image: url(../../static/man.png);
  570. background-size: cover;
  571. position: relative;
  572. top: 4rpx;
  573. margin-right: 10rpx;
  574. }
  575. }
  576. }
  577. }
  578. }
  579. </style>