蚂蚁拼车小程序开发

一 前端

1.统一请求 响应

https://blog.youkuaiyun.com/qq_36375343/article/details/136250792

https://blog.youkuaiyun.com/qq_67195968/article/details/134847507

/src/http/index.ts

const baseUrl = 'http://192.168.21.69:8090/api'; // 域名

// 带 Token 请求
const request = ( params:any) => {
	uni.onNetworkStatusChange(function(res) {
		if (!res.isConnected) {
			uni.showToast({
				title: '网络连接不可用!',
				icon: 'none'
			});
		}
		return false
	});
		let token = uni.getStorageSync('token');
		let httpDefaultOpts = {
			url: baseUrl + params.url,
			data: params.data,
			method: params.method || 'GET',
			header: params.method == 'get' ? {
				'token': token,
				'X-Requested-With': 'XMLHttpRequest',  //用于标记请求是由 AJAX 发起的
				"Accept": "application/json",
				"Content-Type": "application/x-www-form-urlencoded"  //请求在url后面
			} : {
				'token': token,
				'X-Requested-With': 'XMLHttpRequest',
				'Content-Type': 'application/json; charset=UTF-8'
			},
			dataType: 'json',
		}
		let promise = new Promise(function(resolve, reject) {
			uni.request(httpDefaultOpts).then(
				(res:any) => {
					if (res.data.code == 0) {
						resolve(res.data.data)
					} else {
						if (res.data.code == 401) {
							uni.showModal({
								title: '提示',
								content: res.data.message,
								success: function (res) {
									if (res.confirm) {
										uni.reLaunch({
											url: '/pages/index/index'
										});
										uni.clearStorageSync();
									} 
								}
							});
							/* 清除持久化数据 */
							uni.clearStorageSync();
						} else {
							uni.showModal({
								title: '提示',
								content: res.data.message,
							});
						}
					}
				}
			).catch(
				(response) => {
					reject(response)
				}
			)
		})
		return promise;
	
};

// 导出去
export default request;

/src/api

//引入request.js文件
import request from "../http/index";

/* 根据用户ID查询用户行程 */
export function selectTripByUserId(params: any) {
    return request({
        url: "/trip/selectTripByUserId", // 这个地址是去掉公共地址剩下的地址
        method: "GET", // 请求方式 支持多种方式  get post put delete 等等
		data:params
    });
}

原来这种:封装请求为对象中的方法

import http from "@/http"

export default {
  get: {
    name: "获取状态枚举",
    path: "/api/enum",
    call: async function (params: any = {}) {
      return await http.get(this.path, params)
    }
  }

直接定义请求函数

export function selectTripByUserId(params: any) {
  return request({
    url: "/trip/selectTripByUserId", // 这个地址是去掉公共地址剩下的地址
    method: "GET", // 请求方式 支持多种方式  get post put delete 等等
    data: params
  });
}

感受:原来的更直观一些 看起来更明了

直接定义请求函数

其中:baseUrl 使用的ip地址 不建议使用 localhost 后面如果真机调试 无法使用

uni.getStorageSync() 和 uni.setStorageSync() 是在多端应用开发框架中,用于操作本地存储的方法。这些方法是同步的

uni.clearStorageSync() 用于清除所有通过 uni.setStorageSync 存储在本地缓存中的数据。

对于更大的数据集或更复杂的操作,建议使用异步版本的 uni.getStorage 和 uni.setStorage。

uni.onNetworkStatusChange 是一个 API,用于监听网络状态的变化。当网络连接状态发生变化时,会触发相应的回调函数。

在微信小程序中 数据存储在微信小程序的沙箱环境中,通常是客户端设备上的本地存储空间内。

2.前端 功能页

2.1 拼车界面

2.1.1 省市区 选择

一个字 抄!!!

  1. 看看组件库有没有

https://wot-design-uni.netlify.app/component/col-picker.html

https://vant-ui.github.io/vant/#/zh-CN/area

2.找找别人有没有写过类似的 能不能拿来改改用

https://blog.youkuaiyun.com/yunhuaikong/article/details/134187623?ops_request_misc=&request_id=&biz_id=102&utm_term=uniapp%E5%9F%8E%E5%B8%82%E9%80%89%E6%8B%A9%E5%88%97%E8%A1%A8&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-8-134187623.142^v100^pc_search_result_base6&spm=1018.2226.3001.4187

2.1.2 时间选择器

组件库:

uni-app ui

https://uniapp.dcloud.net.cn/component/picker.html#%E6%97%B6%E9%97%B4%E9%80%89%E6%8B%A9%E5%99%A8

2.1.3 地图选点

csdn:

https://blog.youkuaiyun.com/luhanglh/article/details/140442793?ops_request_misc=%257B%2522request%255Fid%2522%253A%252264B5BE78-34E1-4749-B603-6981FDD64C61%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=64B5BE78-34E1-4749-B603-6981FDD64C61&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-140442793-null-null.142^v100^pc_search_result_base6&utm_term=uniapp%20%E4%BD%BF%E7%94%A8%E9%AB%98%E5%BE%B7%E5%9C%B0%E5%9B%BE&spm=1018.2226.3001.4187

其中区别:

上述代码:所使用的为获取周边 不是在全国范围内

getPoiAround

				myAmapFun.value.getPoiAround({
					iconPath: '标记图片',
					iconWidth: 22,
					iconHeight: 32,
					querykeywords: searchKey.value,
					success: (data) => {
						if (data.poisData.length == 0) {
							uni.showModal({
								title: '提示',
								content: '没有搜索到结果',
								showCancel: false,
							});
						} else {
							searchAddressList.value = data.poisData; // 将搜索回来的数据放在列表中显示
						}
					},
					fail: (data) => {
						console.log('搜索失败', data);
					},

高德:

https://lbs.amap.com/api/wx/guide/get-data/get-inputtips

getInputtips

			myAmapFun.value.getInputtips({
			keywords: searchKey.value,
			location: '',
			success: function (data) {
				if (data && data.tips) {
				console.log(data)
				searchAddressList.value = data.tips;
				}
			}
		})

点击地图的事件:

handleMarkerTap

	const handleMarkerTap = (ev) => {
		latitude.value = ev.detail.latitude;
		longitude.value = ev.detail.longitude;
		// 更改标记点
		markers.value = [{
			id: 1,
			width: 40,
			height: 40,
			latitude: ev.detail.latitude,
			longitude: ev.detail.longitude,
			
		}, ];
		getRegeo();
	};

2.2我的行程

主要使用高德路线规划

https://lbs.amap.com/api/wx/guide/route/route

2.3 我的界面

登录看微信小程序开发 微信登录

一个简单的修改用户信息:

3.后端

关于 统一请求响应 token 拦截器 用原来写的 就好

其中特殊:

调用微信小程序 后端跨域问题 简单解决

在Controller上加个@CrossOrigin 注解 然后写相对应的方法

关于mongodb:

乘客取消行程 需要去除 passengerId 中对应的乘客id 并将 可乘坐的乘客数量 +1 :

        Query query = new Query(Criteria.where("id").is(tripDto.getTripId()));
        Update update = new Update()
                .pull("passengerId", tripDto.getId())
                .inc("num", 1);  //想减1 可以直接 -1
        UpdateResult result = mongoTemplate.updateFirst(query, update, Trip.class);

时间范围查询:

其中get gtelte 分别代表“大于等于”和“小于等于” 时间类型为Date

        query.addCriteria(
                Criteria.where("startLocation.city").is(strings[0])
                        .andOperator(
                                Criteria.where("endLocation.city").is(strings2[0]),
                                Criteria.where("startData").gte(todayStartTime).lte(todayEndTime),
                                Criteria.where("status").is(1)
                        )
        );

三. 常用组件

3.1 uni 提示框

https://blog.youkuaiyun.com/Quentin0823/article/details/131530559

			uni.showModal({
								title: '提示',
								content: res.data.message,
							});		

	//提示框 并且附带选择列表
uni.showActionSheet({
		itemList: ['一座', '二座', '三座', '四座', '五座'],
		success(res) {
			num.value = res.tapIndex + 1,
				create()
		},
	})

3.2 界面跳转

uni.reLaunch关闭所有页面并打开到应用内的某个页面

			uni.reLaunch({
											url: '/pages/index/index'
										});

跳转到某个界面

	uni.navigateTo({
		url: "/pages/updateUserInfo/updateUserInfo"
	})

界面返回// 返回上一级页面
uni.navigateBack();

// 返回上两级页面
uni.navigateBack({
  delta: 2
});

其他:

检测向下滑动:
	onPullDownRefresh(()=>{
		console.log('触发了下拉刷新')
		selectByUserId()
		uni.stopPullDownRefresh()
	})

下拉刷新

https://blog.youkuaiyun.com/yasinawolaopo/article/details/122070348	import {
		onPullDownRefresh
	} from '@dcloudio/uni-app';
		onPullDownRefresh(()=>{
		console.log('触发了下拉刷新')
		selectByUserId()
		uni.stopPullDownRefresh()  //结束下拉刷新
	})

四 微信服务号消息提醒

已经学过了 钉钉信息 邮件信息

4.1 首先进入微信开发者平台

https://mp.weixin.qq.com/

4.2 选择消息模板

点击基础功能 订阅消息 在公共模板库 找到线路调整通知

选择关键词 输入使用场景 点击提交

提交之后我们点击 我的模板 查看详情 模板id 与 详细内容的参数 很重要

微信关于参数内容限制 很严格 必须遵守 查询网址:


https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-message-management/subscribe-message/sendMessage.html#%E5%85%B6%E4%BB%96%E8%AF%B4%E6%98%8E

我这里选择的有 thing 与 time两种类型参数

4.3 前端授权

官网文档:

https://developers.weixin.qq.com/miniprogram/dev/api/open-api/subscribe-message/wx.requestSubscribeMessage.html

其中 tmplIds 为 我们申请的模板id

可以把他添加到我们的任意方法中

wx.requestSubscribeMessage({
  tmplIds: [''],
  success (res) { }
})

4.4 后端方法

官方文档:

https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-message-management/subscribe-message/sendMessage.html

调用了一个post请求 请求体为json 类型 参数为所选择的参数

​	请求路径中 token获取 appid 微信的小程序id secret为对应的密钥

​	String url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+*appid*+"&secret="+*secret*;

​	如上我们所选择的参数变成json 应当为

{
  "touser": "OPENID",               //用户的open_id
  "template_id": "TEMPLATE_ID",    //模板编号id
  "page": "index",					// 点击跳转小程序界面路径
  "miniprogram_state":"developer",	 //跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版
  "lang":"zh_CN",                  //语言
  "data": {
      "thing1": {
          "value": "线路详情"
      },
      "thing3": {
          "value": "始发站"
      },
      "thing5": {
          "value": "重点站"
      } ,
      "thing6": {
          "value": "提示说明"
      } ,
      "time8": {
          "value": "2024年10月10日 10:10"
      }
  }
}

后端写了个发送请求的工具类: 感觉既然是json 用 JSONObject可能更好@Component
public class TripNotifyUtil {


    private static String appid = "xxxxxxxxxxx";
    private static String secret = "xxxxxxxxxxxxxx";


    /*司机取消行程 给乘客发送信息*/
    public static void cancelTripMessageNotify(String openId, Trip trip){

        Map map = new HashMap();
        map.put("template_id","boB9rZjDtrATPPuls4ydza64Q6gef6N0uSR0Infb1D4");
        map.put("page","/pages/trip/trip");//点击详细跳转小程序页面,不填就没有查看详情
        map.put("touser",openId);//发送用户的open_id
        //跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版
        map.put("miniprogram_state","developer");
        map.put("lang","zh_CN");
        Map data = new HashMap();
//        JSONObject jsonObject = new JSONObject();
//        jsonObject.set()
        Map thing1 = new HashMap();
        /*线路详情*/
        String str1 = trip.getStartLocation().getDistrict() + "-" + trip.getEndLocation().getDistrict();
        thing1.put("value",str1);
        /*始发站*/
        Map thing3 = new HashMap();
        String str2 = trip.getStartLocation().getCity()  + "-" + trip.getStartLocation().getDistrict();
        thing3.put("value",str2);
        /*重点站*/
        Map thing5 = new HashMap();
        String str3 = trip.getEndLocation().getCity()  + "-" + trip.getEndLocation().getDistrict();
        thing5.put("value",str3);
        /*提示说明*/
        Map thing6 = new HashMap();
        String str4 = "行程取消";
        thing6.put("value",str4);
        /*发车时间*/
        Map time8 = new HashMap();
        LocalDateTime now = LocalDateTime.now();
        String date = now.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm"));
        time8.put("value",date);

        data.put("thing1",thing1);
        data.put("thing3",thing3);
        data.put("thing5",thing5);
        data.put("thing6",thing6);
        data.put("time8",time8);
        map.put("data",data);

        String accessToken = getXcxAccessToken();//获取小程序的accessToken
        // 使用 Hutool 解析 JSON 字符串
        String ACCESS_TOKEN = JSONUtil.parseObj(accessToken).getStr("access_token");
        String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=ACCESS_TOKEN";
        String sendUrl = url.replace("ACCESS_TOKEN", ACCESS_TOKEN);
        String post = HttpUtil.post(sendUrl, JSONUtil.toJsonStr(map));
        System.out.println(post);
    }
    /*获取SessionKey*/
    public static String getXcxAccessToken(){
        String url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appid+"&secret="+secret;
        return HttpUtil.get(url);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

这孩子叫逆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值