pay.vue 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. <template>
  2. <view class="content">
  3. <form action="">
  4. <view class="fixedBox">
  5. <view class="fixedTitle left">缴纳金额:<text class="smallTitle">实缴{{actualFee()}}元<text v-if="isService=='1'">,手续费{{fumoney}}元</text></text></view>
  6. <navigator url="/pages/payInfo/payInfo" class="right">
  7. <text class="fixedTitle2">缴费标准</text>
  8. </navigator>
  9. </view>
  10. <view class="payBox">
  11. <input
  12. type="digit"
  13. class="payInput"
  14. v-model="fee"
  15. maxlength="11"
  16. placeholder-style="payInputHolder"
  17. placeholder="请输入计算基数,不小于1900"
  18. @input="inputPay"
  19. />
  20. </view>
  21. <view class="flex_center_center">
  22. <text class="fixedTitle3">* 按月领取工资的人员,每月以工资总额中相对固定的,经常性的工资收入(税后)为计算基数\n</text>
  23. <text class="fixedTitle3">* 根据郑州市运行规定,计算基数不得低于1900元\n</text>
  24. <text class="fixedTitle3">* 系统缴费将会收取千分之六的手续费,可手动选择是否缴纳</text>
  25. </view>
  26. <view class="serviceChargerBox">
  27. <view class="fixedTitle4">缴纳手续费:</view>
  28. <radio-group @change="selectService">
  29. <label class="radiolabel">
  30. <radio value="1" class="radioBox" checked="checked" />是
  31. </label>
  32. <label class="radiolabel">
  33. <radio value="3" class="radioBox" />否
  34. </label>
  35. </radio-group>
  36. </view>
  37. <picker
  38. mode="date"
  39. :value="date"
  40. :start="startDate"
  41. :end="endDate"
  42. @change="bindDateChange"
  43. fields="month"
  44. >
  45. <view class="selectTime">
  46. <view>选择缴费时间:</view>
  47. <view class="uni-input afterArrow">{{date}}</view>
  48. </view>
  49. </picker>
  50. <button type="primary" class="submitBtn" @click="submitPay">确认缴纳</button>
  51. </form>
  52. </view>
  53. </template>
  54. <script>
  55. import {toPay} from "../../api/index.js"
  56. import { mapState } from "vuex"
  57. export default{
  58. data(){
  59. const currentDate = this.getDate({
  60. format: true
  61. })
  62. return {
  63. fee:"1900",
  64. date: currentDate,
  65. isService:'1',
  66. matchPoint:true
  67. }
  68. },
  69. computed: {
  70. startDate() {
  71. return this.getDate('start');
  72. },
  73. endDate() {
  74. return this.getDate('end');
  75. },
  76. fumoney(){
  77. const fee=this.actualFee()
  78. if(!fee || Number(fee)===0){
  79. return 0
  80. }else{
  81. if(fee*6/1000<0.01){
  82. return 0.01
  83. }else{
  84. return (Math.ceil(fee*6/10)/100).toFixed(2)
  85. }
  86. }
  87. },
  88. ...mapState(["openid"])
  89. },
  90. methods:{
  91. inputPay(){
  92. if(this.fee){
  93. let fee=(this.fee.match(/^\d*(\.?\d{0,2})/g)[0])
  94. this.$nextTick(()=>{
  95. this.fee=fee
  96. })
  97. }
  98. },
  99. actualFee(){
  100. let fee=String(this.fee);
  101. if(fee.indexOf('.')!=-1 && fee.lastIndexOf('.')!==fee.indexOf('.')){
  102. return 0;
  103. }
  104. fee=Number(fee);
  105. let actualFee=0;
  106. if(fee<=3000){
  107. actualFee=Math.ceil(fee*5)/1000;
  108. }else if(fee>3000 && fee<=5000){
  109. actualFee=Math.ceil(fee*1)/100;
  110. }else if(fee>5000 && fee<=10000){
  111. actualFee=Math.ceil(fee*1.5)/100;
  112. }else{
  113. actualFee=Math.ceil(fee*2)/100;
  114. }
  115. return actualFee.toFixed(2);
  116. },
  117. selectService(e){
  118. this.isService=e.detail.value
  119. },
  120. bindDateChange(e) {
  121. this.date = e.target.value
  122. },
  123. getDate(type) {
  124. const date = new Date();
  125. let year = date.getFullYear();
  126. let month = date.getMonth() + 1;
  127. if (type === 'start') {
  128. year = `${year}-01`;
  129. } else if (type === 'end') {
  130. year = `${year + 10}-12`;
  131. }
  132. month = month > 9 ? month : '0' + month;
  133. return `${year}-${month}`;
  134. },
  135. check(){
  136. let date=this.date.split("-");
  137. let year=Number(date[0]);
  138. let month=Number(date[1]);
  139. let fee=this.fee;
  140. if(!fee){
  141. return {
  142. status:1,
  143. msg:'请输入计算基数'
  144. }
  145. }else{
  146. fee=String(fee);
  147. if(fee.indexOf('.')!=-1 && (fee.lastIndexOf('.')!==fee.indexOf('.'))){
  148. return {
  149. status:1,
  150. msg:'计算基数格式不正确'
  151. }
  152. }else{
  153. fee=Number(fee)
  154. if( year<2019 || (year==2019 && month<10)){
  155. this.fee=1000;
  156. let str= this.isService==='1' ? '(手续费:0.03元)': ''
  157. return {
  158. status: 0,
  159. msg:'根据规定,2019年10月之前,缴费金额统一为5元'+str
  160. }
  161. }else{
  162. if(fee<1900){
  163. return {
  164. status: 1,
  165. msg:'根据郑州市最低工资标准,输入的计算基数不能低于1900元'
  166. }
  167. }else{
  168. return {
  169. status: 2,
  170. msg: ''
  171. }
  172. }
  173. }
  174. }
  175. }
  176. },
  177. submitPay(){
  178. let flag=this.check();
  179. if(flag.status===0){
  180. uni.showModal({
  181. title:'确认缴费金额',
  182. content: flag.msg,
  183. success:res=>{
  184. if (res.confirm) {
  185. this.pay()
  186. }
  187. }
  188. })
  189. }else if(flag.status===1){
  190. uni.showToast({
  191. title:flag.msg,
  192. icon:"none",
  193. duration: 2500
  194. })
  195. }else{
  196. this.pay()
  197. }
  198. },
  199. pay(){
  200. if(!this.matchPoint){
  201. return false;
  202. }
  203. this.matchPoint = false
  204. const that=this
  205. toPay({
  206. month:that.date,
  207. fee:that.fee,
  208. openid:that.openid,
  209. is_v:that.isService
  210. }).then(result=>{
  211. this.matchPoint = true
  212. if(result.error_code===200){
  213. const payInfo=result.data
  214. // 调起小程序支付
  215. uni.requestPayment({
  216. provider:"weixin",
  217. timeStamp:payInfo.timestamp,
  218. nonceStr:payInfo.nonceStr,
  219. package:payInfo.package,
  220. signType:payInfo.signType,
  221. paySign:payInfo.paySign,
  222. success:function(p_res){
  223. that.fee=that.fee
  224. uni.showToast({
  225. title:"支付成功",
  226. icon:"success",
  227. duration: 2500
  228. })
  229. },
  230. fail:function(err){
  231. uni.showToast({
  232. title:"支付失败",
  233. icon:"none",
  234. duration: 2500
  235. })
  236. }
  237. })
  238. }else{
  239. uni.showToast({
  240. title:"获取支付信息失败",
  241. icon:"none",
  242. duration: 2500
  243. })
  244. }
  245. }).catch(e=>{
  246. this.matchPoint = true
  247. })
  248. }
  249. }
  250. }
  251. </script>
  252. <style lang="scss">
  253. page{
  254. width: 100%;
  255. height: 100%;
  256. background: $uni-bg-color-normal;
  257. }
  258. .content{
  259. padding: 64rpx 30rpx 0 48rpx;
  260. }
  261. .fixedBox{
  262. display: flex;
  263. justify-content: space-between;
  264. align-items: flex-start;
  265. .left{
  266. width: calc(100% - 150rpx);
  267. }
  268. .right{
  269. width: 150rpx;
  270. }
  271. }
  272. .fixedTitle{
  273. color: #4D4D4D;
  274. font-size: 34rpx;
  275. }
  276. .fixedTitle2{
  277. font-size: 32rpx;
  278. color: #2E8BFC;
  279. }
  280. .payInput{
  281. border: 1px solid #999999;
  282. height: 76rpx;
  283. line-height: 76rpx;
  284. width: calc(100% - 53rpx - 82rpx);
  285. border-radius: 3px;
  286. margin: 51rpx 53rpx 36rpx 0;
  287. font-size: 26rpx;
  288. padding: 0 41rpx;
  289. }
  290. .payInputHolder{
  291. color: #DDDDDD;
  292. }
  293. .fixedTitle3{
  294. color: #FE7444;
  295. font-size: 24rpx;
  296. text-align: left;
  297. display: block;
  298. line-height: 45rpx;
  299. }
  300. .flex_center_center{
  301. margin-bottom:30rpx;
  302. text-align: center;
  303. }
  304. .submitBtn{
  305. width: 432rpx;
  306. height: 76rpx;
  307. line-height: 76rpx;
  308. margin: 0 auto;
  309. background: #2E8BFC !important;
  310. font-size: 32rpx;
  311. }
  312. .selectTime{
  313. display: flex;
  314. justify-content: space-between;
  315. align-items: center;
  316. margin-bottom: 62rpx;
  317. font-size: 32rpx;
  318. color: #4D4D4D;
  319. height: 100rpx;
  320. }
  321. .afterArrow{
  322. display: flex;
  323. justify-content: flex-end;
  324. align-items: center;
  325. }
  326. .afterArrow::after{
  327. content: "";
  328. display:block;
  329. width: 30rpx;
  330. height: 30rpx;
  331. background: url(../../static/arrow_right_2.png);
  332. background-size: 100% 100%;
  333. }
  334. .timeBox{
  335. height: 300rpx;
  336. }
  337. .serviceChargerBox{
  338. display: flex;
  339. justify-content: space-between;
  340. align-items: center;
  341. font-size: 32rpx;
  342. color: #4D4D4D;
  343. height: 76rpx;
  344. line-height: 76rpx;
  345. }
  346. .radioBox{
  347. transform:scale(0.7);
  348. }
  349. .radiolabel:nth-of-type(1){
  350. margin-right: 20rpx;
  351. }
  352. .smallTitle{
  353. font-size: 24rpx;
  354. }
  355. </style>