金诚优选前端代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

605 lines
18 KiB

  1. <template>
  2. <view class="w-picker">
  3. <view class="mask" :class="{'show':showPicker}" @tap="maskTap" @touchmove.stop.prevent catchtouchmove="true"></view>
  4. <view class="w-picker-cnt" :class="{'show':showPicker}">
  5. <view class="w-picker-hd" @touchmove.stop.prevent catchtouchmove="true">
  6. <view class="w-picker-btn" @tap="pickerCancel">取消</view>
  7. <view class="w-picker-btn" :style="{'color':themeColor}" @tap="pickerConfirm">确定</view>
  8. </view>
  9. <view class="w-picker-view" v-if="mode=='date'||mode=='dateTime'||mode=='yearMonth'">
  10. <picker-view :indicator-style="itemHeight" :value="pickVal" @change="bindChange">
  11. <picker-view-column>
  12. <view class="w-picker-item" v-for="(item,index) in data.years" :key="index">{{item}}</view>
  13. </picker-view-column>
  14. <picker-view-column>
  15. <view class="w-picker-item" v-for="(item,index) in data.months" :key="index">{{item}}</view>
  16. </picker-view-column>
  17. <picker-view-column v-if="mode!='yearMonth'">
  18. <view class="w-picker-item" v-for="(item,index) in data.days" :key="index">{{item}}</view>
  19. </picker-view-column>
  20. <picker-view-column v-if="mode=='dateTime'">
  21. <view class="w-picker-item" v-for="(item,index) in data.hours" :key="index">{{item}}</view>
  22. </picker-view-column>
  23. <picker-view-column v-if="mode=='dateTime'">
  24. <view class="w-picker-item" v-for="(item,index) in data.minutes" :key="index">{{item}}</view>
  25. </picker-view-column>
  26. <picker-view-column v-if="mode=='dateTime'">
  27. <view class="w-picker-item" v-for="(item,index) in data.seconds" :key="index">{{item}}</view>
  28. </picker-view-column>
  29. </picker-view>
  30. </view>
  31. <view class="w-picker-view" v-if="mode=='range'">
  32. <picker-view :indicator-style="itemHeight" :value="pickVal" @change="bindChange">
  33. <picker-view-column>
  34. <view class="w-picker-item" v-for="(item,index) in data.fyears" :key="index">{{item}}</view>
  35. </picker-view-column>
  36. <picker-view-column>
  37. <view class="w-picker-item" v-for="(item,index) in data.fmonths" :key="index">{{item}}</view>
  38. </picker-view-column>
  39. <picker-view-column>
  40. <view class="w-picker-item" v-for="(item,index) in data.fdays" :key="index">{{item}}</view>
  41. </picker-view-column>
  42. <view>--</view>
  43. <picker-view-column>
  44. <view class="w-picker-item">-</view>
  45. </picker-view-column>
  46. <picker-view-column>
  47. <view class="w-picker-item" v-for="(item,index) in data.tyears" :key="index">{{item}}</view>
  48. </picker-view-column>
  49. <picker-view-column>
  50. <view class="w-picker-item" v-for="(item,index) in data.tmonths" :key="index">{{item}}</view>
  51. </picker-view-column>
  52. <picker-view-column>
  53. <view class="w-picker-item" v-for="(item,index) in data.tdays" :key="index">{{item}}</view>
  54. </picker-view-column>
  55. </picker-view>
  56. </view>
  57. <view class="w-picker-view" v-if="mode=='time'">
  58. <picker-view :indicator-style="itemHeight" :value="pickVal" @change="bindChange">
  59. <picker-view-column>
  60. <view class="w-picker-item" v-for="(item,index) in data.hours" :key="index">{{item}}</view>
  61. </picker-view-column>
  62. <picker-view-column>
  63. <view class="w-picker-item" v-for="(item,index) in data.minutes" :key="index">{{item}}</view>
  64. </picker-view-column>
  65. <picker-view-column>
  66. <view class="w-picker-item" v-for="(item,index) in data.seconds" :key="index">{{item}}</view>
  67. </picker-view-column>
  68. </picker-view>
  69. </view>
  70. <view class="w-picker-view" v-if="mode=='region'">
  71. <picker-view :indicator-style="itemHeight" :value="pickVal" @change="bindChange">
  72. <picker-view-column>
  73. <view class="w-picker-item" v-for="(item,index) in data.provinces" :key="index">{{item.label}}</view>
  74. </picker-view-column>
  75. <picker-view-column>
  76. <view class="w-picker-item" v-for="(item,index) in data.citys" :key="index">{{item.label}}</view>
  77. </picker-view-column>
  78. <picker-view-column>
  79. <view class="w-picker-item" v-for="(item,index) in data.areas" :key="index">{{item.label}}</view>
  80. </picker-view-column>
  81. </picker-view>
  82. </view>
  83. <view class="w-picker-view" v-if="mode=='selector'">
  84. <picker-view :indicator-style="itemHeight" :value="pickVal" @change="bindChange">
  85. <picker-view-column>
  86. <view class="w-picker-item" v-for="(item,index) in data" :key="index">{{item.label}}</view>
  87. </picker-view-column>
  88. </picker-view>
  89. </view>
  90. <view class="w-picker-view" v-if="mode=='limit'">
  91. <picker-view :indicator-style="itemHeight" :value="pickVal" @change="bindChange">
  92. <picker-view-column>
  93. <view class="w-picker-item" v-for="(item,index) in data.date" :key="index">{{item.label}}</view>
  94. </picker-view-column>
  95. <picker-view-column>
  96. <view class="w-picker-item" v-for="(item,index) in data.hours" :key="index">{{item.label}}</view>
  97. </picker-view-column>
  98. <picker-view-column>
  99. <view class="w-picker-item" v-for="(item,index) in data.minutes" :key="index">{{item.label}}</view>
  100. </picker-view-column>
  101. </picker-view>
  102. </view>
  103. </view>
  104. </view>
  105. </template>
  106. <script>
  107. import provinces from './city-data/province.js';
  108. import citys from './city-data/city.js';
  109. import areas from './city-data/area.js';
  110. import initPicker from "./w-picker.js";
  111. export default {
  112. data() {
  113. return {
  114. result:[],
  115. data:{},
  116. checkArr:[],
  117. checkValue:[],
  118. pickVal:[],
  119. showPicker:false,
  120. resultStr:"",
  121. itemHeight:`height: ${uni.upx2px(88)}px;`
  122. };
  123. },
  124. computed:{
  125. },
  126. props:{
  127. mode:{
  128. type:String,
  129. default(){
  130. return "date"
  131. }
  132. },
  133. themeColor:{
  134. type:String,
  135. default(){
  136. return "#f5a200"
  137. }
  138. },
  139. startYear:{
  140. type:String,
  141. default(){
  142. return "1970"
  143. }
  144. },
  145. endYear:{
  146. type:String,
  147. default(){
  148. return new Date().getFullYear()+''
  149. }
  150. },
  151. defaultVal:{
  152. type:Array,
  153. default(){
  154. return [0,0,0,0,0,0,0]
  155. }
  156. },
  157. step:{
  158. type:[String,Number],
  159. default:1
  160. },
  161. current:{
  162. type:Boolean,
  163. default:false
  164. },
  165. selectList:{
  166. type:Array,
  167. default(){
  168. return [];
  169. }
  170. },
  171. //以下参数仅对mode==disabledBefore有效
  172. dayStep:{
  173. type:[String,Number],
  174. default:7
  175. },
  176. startHour:{
  177. type:[String,Number],
  178. default:8
  179. },
  180. endHour:{
  181. type:[String,Number],
  182. default:20
  183. },
  184. minuteStep:{
  185. type:[String,Number],
  186. default:10
  187. },
  188. afterStep:{
  189. type:[String,Number],
  190. default:30
  191. }
  192. },
  193. watch:{
  194. mode(){
  195. this.initData();
  196. }
  197. },
  198. methods:{
  199. useCurrent(){
  200. let aToday=new Date();
  201. let tYear=aToday.getFullYear().toString();
  202. let tMonth=this.formatNum(aToday.getMonth()+1).toString();
  203. let tDay=this.formatNum(aToday.getDate()).toString();
  204. let tHours=this.formatNum(aToday.getHours()).toString();
  205. let tMinutes=this.formatNum(aToday.getMinutes()).toString();
  206. let tSeconds=this.formatNum(aToday.getSeconds()).toString();
  207. if(this.current){
  208. return [tYear,tMonth,tDay,tHours,(Math.floor(tMinutes/this.step)*this.step).toString(),tSeconds];
  209. }else{
  210. return this.defaultVal;
  211. }
  212. },
  213. formatNum(num){
  214. return num<10?'0'+num:num+'';
  215. },
  216. maskTap(){
  217. this.showPicker = false;
  218. },
  219. show(){
  220. this.showPicker = true;
  221. },
  222. hide(){
  223. this.showPicker = false;
  224. },
  225. pickerCancel(){
  226. this.$emit("cancel",{
  227. checkArr:this.checkArr,
  228. defaultVal:this.pickVal
  229. });
  230. this.showPicker = false;
  231. },
  232. pickerConfirm(e){
  233. switch(this.mode){
  234. case "range":
  235. let checkArr=this.checkArr;
  236. let fDateTime=new Date(checkArr[0],checkArr[1],checkArr[2]);
  237. let tDateTime=new Date(checkArr[3],checkArr[4],checkArr[5]);
  238. if(fDateTime>tDateTime){
  239. uni.showModal({
  240. title:"提示",
  241. content:"结束日期不能小于开始时间",
  242. confirmColor:this.themeColor
  243. });
  244. return;
  245. }
  246. this.$emit("confirm",{
  247. checkArr:this.checkArr,
  248. from:checkArr[0]+"-"+checkArr[1]+"-"+checkArr[2],
  249. to:checkArr[3]+"-"+checkArr[4]+"-"+checkArr[5],
  250. defaultVal:this.pickVal,
  251. result:this.resultStr
  252. });
  253. break;
  254. case "limit":
  255. let aTime=new Date().getTime();
  256. let bTime=new Date(this.resultStr.replace(/-/g,'/')).getTime();
  257. if(aTime>bTime){
  258. uni.showModal({
  259. title:"提示",
  260. content:"选择时间必须大于当前时间",
  261. confirmColor:this.themeColor
  262. });
  263. return;
  264. }
  265. this.$emit("confirm",{
  266. checkArr:this.checkArr,
  267. defaultVal:this.pickVal,
  268. result:this.resultStr
  269. });
  270. break;
  271. case "region":
  272. this.$emit("confirm",{
  273. checkArr:this.checkArr,
  274. checkValue:this.checkValue,
  275. defaultVal:this.pickVal,
  276. result:this.resultStr
  277. });
  278. break;
  279. default:
  280. this.$emit("confirm",{
  281. checkArr:this.checkArr,
  282. defaultVal:this.pickVal,
  283. result:this.resultStr
  284. });
  285. break;
  286. }
  287. this.showPicker = false;
  288. },
  289. bindChange(val){
  290. let _this=this;
  291. let arr=val.detail.value;
  292. let year="",month="",day="",hour="",minute="",second="",province,city,area;
  293. let checkArr=_this.checkArr;
  294. let days=[];
  295. let mode=_this.mode;
  296. switch(mode){
  297. case "limit":
  298. let col1,col2;
  299. col1=_this.data.date[arr[0]];
  300. //col2=_this.data.hours[arr[1]];
  301. if(col1.flag){
  302. col2=_this.data.hours[arr[1]];
  303. _this.data=initPicker.limit(_this.dayStep,_this.starHour,_this.endHour,_this.minuteStep,_this.afterStep);
  304. if(!col2.flag){
  305. let minutes=initPicker.initLimitMinutes(_this.minuteStep);
  306. _this.data.minutes=minutes;
  307. }else{
  308. _this.data=initPicker.limit(_this.dayStep,_this.starHour,_this.endHour,_this.minuteStep,_this.afterStep);
  309. };
  310. }else{
  311. let hours=initPicker.initLimitHours(_this.startHour,_this.endHour);
  312. let minutes=initPicker.initLimitMinutes(_this.minuteStep);
  313. _this.data.hours=hours;
  314. _this.data.minutes=minutes;
  315. }
  316. let d=_this.data.date[arr[0]];
  317. let h=_this.data.hours[arr[1]];
  318. let m=_this.data.minutes[arr[2]];
  319. _this.checkArr=[d,h,m];
  320. _this.resultStr=`${d.value+' '+((h&&h.value)||'')+':'+((m&&m.value)||'')+":"+"00"}`;
  321. break;
  322. case "range":
  323. let fyear=_this.data.fyears[arr[0]];
  324. let fmonth=_this.data.fmonths[arr[1]];
  325. let fday=_this.data.fdays[arr[2]];
  326. let tyear=_this.data.tyears[arr[4]];
  327. let tmonth=_this.data.tmonths[arr[5]];
  328. let tday=_this.data.tdays[arr[6]];
  329. if(fyear!=checkArr[0]){
  330. days=initPicker.initRangeDays(fyear,fmonth);
  331. _this.data.fdays=days;
  332. };
  333. if(fmonth!=checkArr[1]){
  334. days=initPicker.initRangeDays(fyear,fmonth);
  335. _this.data.fdays=days;
  336. };
  337. if(tyear!=checkArr[3]){
  338. days=initPicker.initRangeDays(tyear,tmonth);
  339. _this.data.tdays=days;
  340. };
  341. if(tmonth!=checkArr[4]){
  342. days=initPicker.initRangeDays(tyear,tmonth);
  343. _this.data.tdays=days;
  344. };
  345. _this.checkArr=[fyear,fmonth,fday,tyear,tmonth,tday];
  346. _this.resultStr=`${fyear+'-'+fmonth+'-'+fday+'至'+tyear+'-'+tmonth+'-'+tday}`;
  347. break;
  348. case "date":
  349. year=_this.data.years[arr[0]];
  350. month=_this.data.months[arr[1]];
  351. day=_this.data.days[arr[2]];
  352. if(year!=checkArr[0]){
  353. days=initPicker.initDays(year,month);
  354. _this.data.days=days;
  355. };
  356. if(month!=checkArr[1]){
  357. days=initPicker.initDays(year,month);
  358. _this.data.days=days;
  359. };
  360. _this.checkArr=[year,month,day];
  361. _this.resultStr=`${year+'-'+month+'-'+day}`;
  362. break;
  363. case "yearMonth":
  364. year=_this.data.years[arr[0]];
  365. month=_this.data.months[arr[1]];
  366. _this.checkArr=[year,month];
  367. _this.resultStr=`${year+'-'+month}`;
  368. break;
  369. case "dateTime":
  370. year=_this.data.years[arr[0]];
  371. month=_this.data.months[arr[1]];
  372. day=_this.data.days[arr[2]];
  373. hour=_this.data.hours[arr[3]];
  374. minute=_this.data.minutes[arr[4]];
  375. second=_this.data.seconds[arr[5]];
  376. if(year!=checkArr[0]){
  377. days=initPicker.initDays(year,month);
  378. _this.data.days=days;
  379. };
  380. if(month!=checkArr[1]){
  381. days=initPicker.initDays(year,month);
  382. _this.data.days=days;
  383. };
  384. _this.checkArr=[year,month,day,hour,minute,second];
  385. _this.resultStr=`${year+'-'+month+'-'+day+' '+hour+':'+minute+':'+second}`;
  386. break;
  387. case "time":
  388. hour=_this.data.hours[arr[0]];
  389. minute=_this.data.minutes[arr[1]];
  390. second=_this.data.seconds[arr[2]];
  391. _this.checkArr=[hour,minute,second];
  392. _this.resultStr=`${hour+':'+minute+':'+second}`;
  393. break;
  394. case "region":
  395. province=_this.data.provinces[arr[0]].label;
  396. city=_this.data.citys[arr[1]].label;
  397. area=_this.data.areas[arr[2]].label;
  398. if(province!=checkArr[0]){
  399. _this.data.citys = citys[arr[0]];
  400. _this.data.areas = areas[arr[0]][0];
  401. arr[1] = 0;
  402. arr[2] = 0;
  403. city=_this.data.citys[arr[1]].label;
  404. area=_this.data.areas[arr[2]].label;
  405. };
  406. if(city!=checkArr[1]){
  407. _this.data.areas = areas[arr[0]][arr[1]];
  408. arr[2]=0;
  409. area=_this.data.areas[arr[2]].label;
  410. };
  411. _this.checkArr=[province,city,area];
  412. _this.checkValue=[_this.data.provinces[arr[0]].value,_this.data.citys[arr[1]].value,_this.data.areas[arr[2]].value];
  413. _this.resultStr=province+city+area;
  414. break;
  415. case "selector":
  416. _this.checkArr=_this.data[arr[0]];
  417. _this.resultStr=_this.data[arr[0]].label;
  418. break;
  419. }
  420. _this.$nextTick(()=>{
  421. _this.pickVal=arr;
  422. })
  423. },
  424. initData(){
  425. let _this=this;
  426. let data={};
  427. let mode=_this.mode;
  428. let year,month,day,hour,minute,second,province,city,area;
  429. if(mode=="region"){
  430. data={
  431. provinces:provinces,
  432. citys:citys[_this.defaultVal[0]],
  433. areas:areas[_this.defaultVal[0]][_this.defaultVal[1]]
  434. };
  435. }else if(mode=="selector"){
  436. data=_this.selectList;
  437. }else if(mode=="limit"){
  438. data=initPicker.limit(_this.dayStep,_this.starHour,_this.endHour,_this.minuteStep,_this.afterStep);
  439. }else if(mode=="range"){
  440. data=initPicker.range(_this.startYear,_this.endYear,_this.useCurrent(),_this.current);
  441. }else{
  442. data=initPicker.date(_this.startYear,_this.endYear,_this.mode,_this.step,_this.useCurrent(),_this.current);
  443. };
  444. _this.data=data;
  445. let dVal=(data.defaultVal&&_this.current)?data.defaultVal:_this.defaultVal;
  446. switch(mode){
  447. case "limit":
  448. let col1,col2,col3;
  449. col1=data.date[dVal[0]];
  450. col2=data.hours[dVal[1]];
  451. col3=data.minutes[dVal[2]];
  452. _this.checkArr=[col1,col2,col3];
  453. _this.resultStr=`${col1.value+' '+col2.value+':'+col3.value+":"+"00"}`;
  454. break;
  455. case "range":
  456. let fYear=data.fyears[dVal[0]];
  457. let fmonth=data.fmonths[dVal[1]];
  458. let fday=data.fdays[dVal[2]];
  459. let tYear=data.tyears[dVal[4]];
  460. let tmonth=data.tmonths[dVal[5]];
  461. let tday=data.tdays[dVal[6]];
  462. _this.checkArr=[fYear,fmonth,fday,tYear,tmonth,tday];
  463. _this.resultStr=`${fYear+'-'+fmonth+'-'+fday+'至'+tYear+'-'+tmonth+'-'+tday}`;
  464. break;
  465. case "date":
  466. year=data.years[dVal[0]];
  467. month=data.months[dVal[1]];
  468. day=data.days[dVal[2]];
  469. _this.checkArr=[year,month,day];
  470. _this.resultStr=`${year+'-'+month+'-'+day}`;
  471. break;
  472. case "yearMonth":
  473. year=data.years[dVal[0]];
  474. month=data.months[dVal[1]];
  475. _this.checkArr=[year,month];
  476. _this.resultStr=`${year+'-'+month}`;
  477. break;
  478. case "dateTime":
  479. year=data.years[dVal[0]];
  480. month=data.months[dVal[1]];
  481. day=data.days[dVal[2]];
  482. hour=data.hours[dVal[3]];
  483. minute=data.minutes[dVal[4]];
  484. second=data.seconds[dVal[5]];
  485. _this.resultStr=`${year+'-'+month+'-'+day+' '+hour+':'+minute+':'+second}`;
  486. _this.checkArr=[year,month,day,hour,minute];
  487. break;
  488. case "time":
  489. hour=data.hours[dVal[0]];
  490. minute=data.minutes[dVal[1]];
  491. second=data.seconds[dVal[2]];
  492. _this.checkArr=[hour,minute,second];
  493. _this.resultStr=`${hour+':'+minute+':'+second}`;
  494. break;
  495. case "region":
  496. province=data.provinces[dVal[0]];
  497. city=data.citys[dVal[1]];
  498. area=data.areas[dVal[2]];
  499. _this.checkArr=[province.label,city.label,area.label];
  500. _this.checkValue=[province.value,city.value,area.value];
  501. _this.resultStr=province.label+city.label+area.label;
  502. break;
  503. case "selector":
  504. _this.checkArr=data[dVal[0]];
  505. _this.resultStr=data[dVal[0]].label;
  506. break;
  507. }
  508. _this.$nextTick(()=>{
  509. if(data.defaultVal&&_this.current){
  510. _this.pickVal=data.defaultVal;
  511. }else{
  512. _this.pickVal=_this.defaultVal;
  513. }
  514. })
  515. }
  516. },
  517. mounted() {
  518. this.initData();
  519. }
  520. }
  521. </script>
  522. <style lang="scss">
  523. .w-picker{
  524. position: relative;
  525. z-index: 888;
  526. .mask {
  527. position: fixed;
  528. z-index: 1000;
  529. top: 0;
  530. right: 0;
  531. left: 0;
  532. bottom: 0;
  533. background: rgba(0, 0, 0, 0.6);
  534. visibility: hidden;
  535. opacity: 0;
  536. transition: all 0.3s ease;
  537. }
  538. .mask.show{
  539. visibility: visible;
  540. opacity: 1;
  541. }
  542. .w-picker-cnt {
  543. position: fixed;
  544. bottom: 0;
  545. left: 0;
  546. width: 100%;
  547. transition: all 0.3s ease;
  548. transform: translateY(100%);
  549. z-index: 3000;
  550. }
  551. .w-picker-cnt.show {
  552. transform: translateY(0);
  553. }
  554. .w-picker-hd {
  555. display: flex;
  556. align-items: center;
  557. padding: 0 30upx;
  558. height: 88upx;
  559. background-color: #fff;
  560. position: relative;
  561. text-align: center;
  562. font-size: 32upx;
  563. justify-content: space-between;
  564. .w-picker-btn{
  565. font-size: 30upx;
  566. }
  567. }
  568. .w-picker-hd:after {
  569. content: ' ';
  570. position: absolute;
  571. left: 0;
  572. bottom: 0;
  573. right: 0;
  574. height: 1px;
  575. border-bottom: 1px solid #e5e5e5;
  576. color: #e5e5e5;
  577. transform-origin: 0 100%;
  578. transform: scaleY(0.5);
  579. }
  580. .w-picker-item {
  581. text-align: center;
  582. width: 100%;
  583. height: 88upx;
  584. line-height: 88upx;
  585. text-overflow: ellipsis;
  586. white-space: nowrap;
  587. font-size: 30upx;
  588. }
  589. .w-picker-view {
  590. width: 100%;
  591. height: 476upx;
  592. overflow: hidden;
  593. background-color: rgba(255, 255, 255, 1);
  594. z-index: 666;
  595. }
  596. picker-view{
  597. height: 100%;
  598. }
  599. }
  600. </style>