Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

apply.vue 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. <template>
  2. <view class="page-content">
  3. <view class="bg">
  4. <view class="title"> 基本信息 </view>
  5. <u-form label-width="230" :model="state.formData" ref="uForm" :label-style='labelStyle'>
  6. <u-form-item label="姓名" :left-icon='`${$imgUrl}issuance/point-form.png`' :left-icon-style='leftIcon' borderBottom>
  7. <u-input v-model="state.userName" placeholder='请输入姓名' inputAlign="right" disabled/>
  8. </u-form-item>
  9. <u-form-item label="手机号" :left-icon='`${$imgUrl}issuance/point-form.png`' :left-icon-style='leftIcon' borderBottom>
  10. <u-input placeholder='请填写手机号' v-model="state.userMobile" inputAlign="right" disabled/>
  11. </u-form-item>
  12. <u-form-item label="是否跨省" :left-icon='`${$imgUrl}issuance/point-form.png`' :left-icon-style='leftIcon' borderBottom>
  13. <custom-select-data v-model="state.formData.multiProvince" :dataList="isMultiProvince" :disabled="onlyApplyIsInput"></custom-select-data>
  14. </u-form-item>
  15. <u-form-item label="ETC卡号" :left-icon='`${$imgUrl}issuance/point-form.png`' :left-icon-style='leftIcon' borderBottom>
  16. <u-input placeholder='请填写ETC卡号' v-model="state.formData.cardId" inputAlign="right" :disabled="onlyApplyIsInput" />
  17. </u-form-item>
  18. <u-form-item label="车牌号" :left-icon='`${$imgUrl}issuance/point-form.png`' :left-icon-style='leftIcon' borderBottom>
  19. <car-number-input @numberInputResult="carNumber" :defaultStr="state.formData.vehiclePlate" :isClick="!onlyApplyIsInput"></car-number-input>
  20. </u-form-item>
  21. <u-form-item label="车型" :left-icon='`${$imgUrl}issuance/point-form.png`' :left-icon-style='leftIcon' borderBottom>
  22. <custom-select-dic v-model="state.formData.exVehClass" :disabled="onlyApplyIsInput" dicName="VEHICLE_TYPE" placeholder="请选择车型"></custom-select-dic>
  23. </u-form-item>
  24. <u-form-item label="车牌颜色" :left-icon='`${$imgUrl}issuance/point-form.png`' :left-icon-style='leftIcon' borderBottom>
  25. <u-input v-model="state.vehiclePlateColorStr" :disabled="onlyApplyIsInput" input-align='right' placeholder="请选择车牌颜色"/>
  26. </u-form-item>
  27. <u-form-item label="入站口" :left-icon='`${$imgUrl}issuance/point-form.png`' :left-icon-style='leftIcon' borderBottom>
  28. <u-input v-model="state.formData.enTollStationName" :disabled="onlyApplyIsInput" input-align='right' placeholder="请输入入站口"/>
  29. </u-form-item>
  30. <u-form-item label="出站口" :left-icon='`${$imgUrl}issuance/point-form.png`' :left-icon-style='leftIcon' borderBottom>
  31. <u-input v-model="state.formData.exTollStationName" :disabled="onlyApplyIsInput" input-align='right' placeholder="请输入出站口"/>
  32. </u-form-item>
  33. <u-form-item label="入口时间" :left-icon='`${$imgUrl}issuance/point-form.png`' :left-icon-style='leftIcon' borderBottom>
  34. <uni-datetime-picker ref="filterDate" v-model="state.formData.enTime" :disabled="onlyApplyIsInput" type="datetime" />
  35. </u-form-item>
  36. <u-form-item label="出口时间" :left-icon='`${$imgUrl}issuance/point-form.png`' :left-icon-style='leftIcon' borderBottom>
  37. <uni-datetime-picker ref="filterDate" v-model="state.formData.exTime" :disabled="onlyApplyIsInput" type="datetime" />
  38. </u-form-item>
  39. <u-form-item label="收费金额" :left-icon='`${$imgUrl}issuance/point-form.png`' :left-icon-style='leftIcon' borderBottom>
  40. <view class="flex-input">
  41. <u-input v-model="state.formData.tollAmount" type="number" input-align='right' :disabled="onlyApplyIsInput" placeholder="请输入收费金额"/>
  42. <text class="unit">元</text>
  43. </view>
  44. </u-form-item>
  45. <u-form-item label="支付类型" :left-icon='`${$imgUrl}issuance/point-form.png`' :left-icon-style='leftIcon' borderBottom>
  46. <custom-select-dic v-model="state.formData.unionPayTransFlag" :disabled="onlyApplyIsInput" dicName="PROVINCE_PAY_TYPE" placeholder="请选择支付类型"></custom-select-dic>
  47. </u-form-item>
  48. <u-form-item label="申请退费金额" :left-icon='`${$imgUrl}issuance/point-form.png`' :left-icon-style='leftIcon' borderBottom>
  49. <view class="flex-input">
  50. <u-input v-model="state.formData.fee" type="number" input-align='right' placeholder="请输入申请退费金额"/>
  51. <text class="unit">元</text>
  52. </view>
  53. </u-form-item>
  54. <u-form-item label="退费原因" :left-icon='`${$imgUrl}issuance/point-form.png`' :left-icon-style='leftIcon' borderBottom>
  55. </u-form-item>
  56. <u-input v-model="state.formData.refundReason" type="textarea" placeholder="请输入退费原因"/>
  57. <u-form-item label="退费信息" :left-icon='`${$imgUrl}issuance/point-form.png`' :left-icon-style='leftIcon' borderBottom>
  58. <u-input v-model="state.chooseBankInfo" type="select" placeholder='请输入开户行' @click="chooseBank" inputAlign="right"/>
  59. </u-form-item>
  60. </u-form>
  61. </view>
  62. <view class="bg">
  63. <view class="title">支付凭证<text class="upload-num">({{state.formData.payVoucherUrls.length}}/6)</text></view>
  64. <view class="image-list">
  65. <view class="image-out" v-for="(item, index) in state.formData.payVoucherUrls">
  66. <image
  67. :key="index"
  68. class="icon"
  69. :src="getFullImageUrl(item)"
  70. :style="{'--bgimg':`url(${$imgUrl}issuance/bg-border.png`}"
  71. mode="aspectFill"
  72. ></image>
  73. <view class="delete" @click="delectOption(index)"><u-icon name="close-circle-fill" color="#fa3534" size="30"></u-icon></view>
  74. </view>
  75. <view class="image-out" @click="uploadOtherFile">
  76. <image
  77. v-if="state.formData.payVoucherUrls.length < 6"
  78. class="icon"
  79. :src="`${$imgUrl}issuance/weituo.png`"
  80. :style="{'--bgimg':`url(${$imgUrl}issuance/bg-border.png`}">
  81. </image>
  82. </view>
  83. </view>
  84. </view>
  85. <view class="action">
  86. <button type="default" class="ui-btn" @click="submit()">
  87. 提交
  88. </button>
  89. </view>
  90. </view>
  91. <!-- 选择车牌颜色 -->
  92. <u-select v-model="show2" :list="state.refundInfoList" @confirm="changeRefundInfo"></u-select>
  93. </template>
  94. <script setup lang="ts">
  95. import { reactive, ref, computed } from "vue";
  96. import { onLoad, onShow } from "@dcloudio/uni-app";
  97. import { getItem, StorageKeys } from "@/utils/storage";
  98. import { checkStr, navTo, uploadFile, msg, getFullImageUrl, replaceBaseImageUrl, maskBankCard } from "@/utils/utils";
  99. import { requestNew } from "@/utils/network/request.js";
  100. import { submitEtcTransactionApply, getUserMsg, getRefundInfoPage } from "@/utils/network/api.js";
  101. import { useUserStore } from "@/stores/user";
  102. import { commonStore } from '@/stores/common.js'
  103. import { getCodeName } from '@/datas/queryKey.js'
  104. import carNumberInput from "@/components/car-number-input/car-number-input.vue";
  105. import { getVehiclePlateColorPai } from '@/datas/vehiclePlateColor'
  106. const commonStoreUse = commonStore()
  107. const { getSelectIndex, setIsRefresh } = commonStoreUse
  108. const refreshKey = 'runWaterRefundInfo'
  109. const show2 = ref(null)
  110. const isMultiProvince = [
  111. {name: '单省', id: 0},
  112. {name: '跨省', id: 1},
  113. ]
  114. interface uploadFileParams{
  115. imageUrl: string
  116. }
  117. const labelStyle = {
  118. color: "#004576",
  119. fontSize: "28rpx",
  120. }
  121. const leftIcon = {
  122. height: '100%',
  123. width: '8rpx',
  124. display: 'flex',
  125. 'align-items': 'center',
  126. 'margin-right': '4rpx',
  127. }
  128. const state = reactive({
  129. onlyApply: false, // 是否是单独申请
  130. userName: '',
  131. userMobile: '',
  132. formData: {
  133. cardId: '',
  134. vehiclePlate: '',
  135. vehiclePlateColor: '',
  136. payVoucherUrls: [],
  137. applyType: '1', // 1:省中心流水申请 2:自主申请
  138. bankIdCode: '',
  139. bankName: '',
  140. bankBranchName: '',
  141. enTime: '', // 入口时间
  142. enTollStationName: '', // 入口站名
  143. exTime: '', // 出口时间
  144. exTollStationName: '', // 出口站名
  145. multiProvince: 0, // 跨省标识,单省/多省--------
  146. tollAmount: '',
  147. fee: '', // 申请退费金额
  148. unionPayTransFlag: '4', // 支付类型 1 现金 2 其他第三方账户支付 3 银联卡支付 4 ETC支付 6 支付宝 7 微信 0 ETC支付 -1 未知
  149. exVehClass: '', // 车型
  150. refundReason: '', // 退费原因
  151. ownerId: '',
  152. passId: '',
  153. ygzListNo: '',
  154. ownerName: '',
  155. roadName: '',
  156. road: '',
  157. manageName: '',
  158. manageUnit: '',
  159. hexCardId: '',
  160. isFind: ''
  161. },
  162. range: [],
  163. bankProvinceName: '',
  164. vehiclePlateColorStr: '',
  165. colorRange: [],
  166. chooseBankInfo: '',
  167. refundInfoList: []
  168. })
  169. // 单独申请是否可输入
  170. const onlyApplyIsInput = computed(() => {
  171. return state.formData.applyType !== '2'
  172. })
  173. onLoad(({jsonData, onlyApply}) => {
  174. if (jsonData) {
  175. let data = JSON.parse(jsonData)
  176. state.formData.vehiclePlate = data.exVehPlate
  177. state.formData.vehiclePlateColor = data.vehiclePlateColor
  178. state.vehiclePlateColorStr = getVehiclePlateColorPai(data.vehiclePlateColor)
  179. if (onlyApply && onlyApply === '1') {
  180. state.onlyApply = true
  181. state.formData.applyType = '2'
  182. } else {
  183. state.formData.cardId = data.cardId
  184. state.formData.enTime = data.enTime
  185. state.formData.enTollStationName = data.enTollStationName
  186. state.formData.exTime = data.exTime
  187. state.formData.exTollStationName = data.exTollStationName
  188. state.formData.tollAmount = data.tollAmount
  189. state.formData.multiProvince = data.multiProvince
  190. // state.formData.fee = ''
  191. state.formData.unionPayTransFlag = data.unionPayTransFlag
  192. state.formData.exVehClass = data.exVehClass
  193. state.formData.ownerId = data.ownerId
  194. state.formData.passId = data.passId
  195. state.formData.ygzListNo = data.ygzListNo
  196. state.formData.ownerName = data.ownerName
  197. state.formData.roadName = data.roadName
  198. state.formData.road = data.road
  199. state.formData.manageName = data.manageName
  200. state.formData.manageUnit = data.manageUnit
  201. state.formData.hexCardId = data.hexCardId
  202. state.formData.isFind = data.isFind
  203. }
  204. }
  205. getRefundInfoList()
  206. getColorList()
  207. getUserInfo()
  208. })
  209. onShow(() => {
  210. })
  211. // 获取当前用户信息详情
  212. const getUserInfo = () => {
  213. let option = {
  214. type: 2,
  215. data: {},
  216. method: "POST",
  217. showLoading: true,
  218. }
  219. requestNew(getUserMsg, option).then(res => {
  220. state.userName = res.userName
  221. state.userMobile = res.mobile
  222. })
  223. }
  224. // 获取退费信息列表
  225. const getRefundInfoList = () => {
  226. let option = {
  227. type: 2,
  228. data: {pageSize: 50, staffId: 'opId'},
  229. method: "POST",
  230. showLoading: true,
  231. }
  232. requestNew(getRefundInfoPage, option).then(res => {
  233. const data = res.result ? res.result.map(item => {
  234. item.bankNameStr = getCodeName('BANK_TYPE', item.bankName)
  235. return {
  236. ...item,
  237. label: `${item.bankNameStr}(${maskBankCard(item.bankIdCode)})`,
  238. value: item.id
  239. }
  240. }) : [];
  241. state.refundInfoList = data
  242. })
  243. }
  244. const getColorList = () => {
  245. let getColor = getItem('key')['VEHICLE_COLOR_TYPE'];
  246. for (var k = 0; k < getColor.length; k++) {
  247. let obj = {};
  248. obj['value'] = getColor[k]['code']
  249. obj['label'] = getColor[k]['name']
  250. state.colorRange.push(obj)
  251. }
  252. }
  253. const submit = () => {
  254. if (!paramsVerify()) return;
  255. let params = JSON.parse(JSON.stringify(state.formData))
  256. params.tollAmount = params.tollAmount * 100
  257. params.fee = params.fee * 100
  258. const options = {
  259. type: 2,
  260. data: params,
  261. method: "POST",
  262. showLoading: true,
  263. }
  264. //调用方式
  265. requestNew(submitEtcTransactionApply, options).then(res => {
  266. uni.redirectTo({
  267. url: '/pages/common/submit-result?back=1&tipText=' + '预计1-3日完成资料审核'
  268. })
  269. })
  270. }
  271. // 选择退费银行卡信息
  272. const chooseBank = () => {
  273. show2.value = true
  274. }
  275. const selectProvince = () => {
  276. uni.navigateTo({
  277. url: '/pages/common/select-data-list'
  278. })
  279. }
  280. // 字段校验
  281. const paramsVerify = () => {
  282. let isVerify = true;
  283. if(!state.formData.cardId){
  284. msg('请输入ETC卡号');
  285. isVerify = false;
  286. } else if(!state.formData.vehiclePlate){
  287. msg('请输入车牌号');
  288. isVerify = false;
  289. } else if(!state.formData.exVehClass){
  290. msg('请选择车型');
  291. isVerify = false;
  292. } else if(!state.formData.vehiclePlateColor){
  293. msg('请选择车牌颜色');
  294. isVerify = false;
  295. } else if(!state.formData.enTollStationName){
  296. msg('请输入入站口');
  297. isVerify = false;
  298. } else if(!state.formData.exTollStationName){
  299. msg('请输入出站口');
  300. isVerify = false;
  301. } else if(!state.formData.enTime){
  302. msg('请输入入口时间');
  303. isVerify = false;
  304. } else if(!state.formData.exTime){
  305. msg('请输入出口时间');
  306. isVerify = false;
  307. } else if(!state.formData.tollAmount){
  308. msg('请输入收费金额');
  309. isVerify = false;
  310. } else if(!state.formData.unionPayTransFlag){
  311. msg('请选择支付类型');
  312. isVerify = false;
  313. } else if(!state.formData.fee){
  314. msg('请填写申请退费金额');
  315. isVerify = false;
  316. } else if (state.formData.fee > state.formData.tollAmount){
  317. msg('请填写申请退费金额');
  318. isVerify = false;
  319. } else if (!state.formData.refundReason) {
  320. msg('请填写退费原因');
  321. isVerify = false;
  322. } else if (!state.formData.bankIdCode || !state.formData.bankName || !state.formData.bankBranchName) {
  323. msg('请选择退费信息');
  324. isVerify = false;
  325. } else if (!state.formData.payVoucherUrls) {
  326. msg('请上传支付凭证');
  327. isVerify = false;
  328. }
  329. return isVerify;
  330. }
  331. // 授权证书上传
  332. const uploadOtherFile = () => {
  333. uni.chooseImage({
  334. count: 1, // 只能选取一张照片
  335. sizeType: ["original", "compressed"], //可以指定是原图还是压缩图,默认二者都有
  336. sourceType: ["camera", "album"], //从相册选择
  337. success: (res) => {
  338. uploadFile(res.tempFilePaths[0]).then((data: uploadFileParams) => {
  339. state.formData.payVoucherUrls.push(data.imageUrl)
  340. })
  341. },
  342. });
  343. }
  344. const delectOption = (index) => {
  345. state.formData.payVoucherUrls.splice(index, 1)
  346. }
  347. const changeColor = (item: any) => {
  348. state.formData.vehiclePlateColor = item[0].value
  349. state.vehiclePlateColorStr = item[0].label
  350. }
  351. const changeRefundInfo = (item: any) => {
  352. let chooseInfo = item[0]
  353. state.chooseBankInfo = chooseInfo.label
  354. let info = state.refundInfoList.find(obj => obj.value === chooseInfo.value)
  355. state.formData.bankIdCode = info.bankIdCode
  356. state.formData.bankName = info.bankName
  357. state.formData.bankBranchName = info.bankBranchName
  358. }
  359. //车牌号输入
  360. const carNumber = (val : any) => {
  361. state.formData.vehiclePlate = val.trim();
  362. };
  363. </script>
  364. <style lang="scss" scoped>
  365. .bg{
  366. background-color: white;
  367. margin:0 32rpx;
  368. margin-top: 20rpx;
  369. border-radius: 12rpx;
  370. border: 1px solid #FFFFFF;
  371. padding: 20rpx;
  372. }
  373. .card {
  374. display: flex;
  375. margin: 0 20rpx;
  376. align-items: center;
  377. }
  378. .picture-wrapper {
  379. margin-top: 30rpx;
  380. .bg {
  381. background: #F5F9FB;
  382. border-radius: 10rpx;
  383. padding: 40rpx 30rpx;
  384. display: flex;
  385. // align-items: center;
  386. justify-content: space-between;
  387. .title{
  388. color: #01243A;
  389. }
  390. .name {
  391. padding-top: 30rpx;
  392. font-size: 32rpx;
  393. font-family: SourceHanSansSC, SourceHanSansSC;
  394. font-weight: 500;
  395. color: #111;
  396. line-height: 34rpx;
  397. }
  398. .value {
  399. margin-top: 20rpx;
  400. font-size: 22rpx;
  401. font-family: SourceHanSansSC, SourceHanSansSC;
  402. font-weight: 400;
  403. color: #999999;
  404. line-height: 24rpx;
  405. }
  406. .tip {
  407. margin-top: 20rpx;
  408. text-align: center;
  409. width: 100rpx;
  410. height: 30rpx;
  411. border-radius: 6rpx;
  412. border: 1rpx solid #CCB375;
  413. .tip-value {
  414. font-size: 20rpx;
  415. font-family: Microsoft YaHei;
  416. font-weight: 400;
  417. color: #CCB375;
  418. line-height: 30rpx;
  419. opacity: 1;
  420. }
  421. }
  422. }
  423. .icon {
  424. width: 304rpx;
  425. height: 190rpx;
  426. background-image: var(--bgimg);
  427. background-size: 100% 100%;
  428. background-repeat: no-repeat;
  429. }
  430. }
  431. .action {
  432. background-color: #fff;
  433. border-radius: 30rpx 30rpx 0 0;
  434. width: 100vw;
  435. display: flex;
  436. align-items: center;
  437. justify-content: center;
  438. flex-direction: column;
  439. margin-top: 20rpx;
  440. padding: 24rpx 0 calc(24rpx + env(safe-area-inset-bottom));
  441. }
  442. ::deep.uni-select {
  443. font-size: 13px;
  444. height: 30px;
  445. line-height: 30px;
  446. }
  447. .choice-takePhoto-wrap {
  448. width: 100%;
  449. height: 100vh;
  450. background-color: rgba(127, 127, 127, 0.2);
  451. position: fixed;
  452. left: 0;
  453. top: 0;
  454. z-index: 11111;
  455. }
  456. .choice-takePhoto {
  457. position: absolute;
  458. bottom: 0;
  459. background-color: white;
  460. width: 100%;
  461. border-radius: 20rpx 20rpx 0 0;
  462. }
  463. .choice-takePhoto>view:first-child {
  464. text-align: center;
  465. height: 80rpx;
  466. line-height: 80rpx;
  467. border-bottom: 1rpx solid rgba(127, 127, 127, 0.3);
  468. background-color: white;
  469. }
  470. .choice-takePhoto>view:last-child {
  471. text-align: center;
  472. height: 80rpx;
  473. line-height: 80rpx;
  474. border-top: 6rpx solid rgba(127, 127, 127, 0.1);
  475. background-color: white;
  476. }
  477. .choice-takePhoto>view {
  478. text-align: center;
  479. height: 80rpx;
  480. line-height: 80rpx;
  481. background-color: white;
  482. }
  483. .choice-takePhoto-wrap {
  484. width: 100%;
  485. height: 100vh;
  486. background-color: rgba(127, 127, 127, 0.2);
  487. position: fixed;
  488. left: 0;
  489. top: 0;
  490. z-index: 11111;
  491. }
  492. .car-type{
  493. width: 400rpx;
  494. height: 68rpx;
  495. margin: 50rpx auto;
  496. border-radius: 68rpx;
  497. border: 1px #CCB375 solid;
  498. font-size: 28rpx;
  499. overflow: hidden;
  500. display: flex;
  501. .car-type-item{
  502. width: 50%;
  503. height: 100%;
  504. line-height: 68rpx;
  505. text-align: center;
  506. color: #CCB375;
  507. flex-shrink: 0;
  508. flex-grow: 0;
  509. }
  510. .active{
  511. color: #FFFFFF;
  512. background-color: #CCB375;
  513. }
  514. }
  515. .disabled-text{
  516. color: #999999;
  517. }
  518. .uni-list{
  519. width: 88%;
  520. margin: 24rpx auto;
  521. .left-owner-radio{
  522. margin-right: 12rpx;
  523. }
  524. }
  525. .page-content{
  526. position: relative;
  527. min-height: 100vh;
  528. }
  529. .flex-input{
  530. flex: 1;
  531. display: flex;
  532. align-items: center;
  533. justify-content: flex-end;
  534. .unit{
  535. color: #01243A;
  536. font-size: 26rpx;
  537. width: 60rpx;
  538. text-align: center;
  539. }
  540. }
  541. .image-list{
  542. display: flex;
  543. flex-wrap: wrap;
  544. margin-top: 24rpx;
  545. .icon{
  546. width: 180rpx;
  547. height: 180rpx;
  548. margin: 0 24rpx 24rpx 0;
  549. }
  550. .image-out{
  551. width: 180rpx;
  552. height: 180rpx;
  553. margin: 0 24rpx 24rpx 0;
  554. position: relative;
  555. .delete{
  556. position: absolute;
  557. right: 0;
  558. top: 0;
  559. }
  560. }
  561. }
  562. .upload-num{
  563. color: #999999;
  564. font-size: 26rpx;
  565. margin-left: 12rpx;
  566. }
  567. </style>