当前位置: 代码网 > it编程>前端脚本>Python > 订单系统和前台系统的交互---预订单--订单--支付--登录?

订单系统和前台系统的交互---预订单--订单--支付--登录?

2024年08月02日 Python 我要评论
new一个order,属性赋值,然后插入到数据库中,如果插入成功,则获取CarResult中List的每一个元素,让他转换为OrderGoods,设置订单商品中的订单号为订单编码,与Order关联起来,然后将OrderGoods放到一个List集合中,插入数据库中,如果插入成功,并未出现异常,则返回成功,否则返回失败,因为Controller需要一个订单编号,所以我们可以将返回的成功的信息里面放入我们的订单编号,在Controller就可以进行存入了。在这里生成的订单的状态信息会用一个枚举类来进行定义。

订单单点登录功能实现

导入shop-sso依赖

开启@enabledubbo

配置yml文件中的dubbo服务

提供应用信息和zookeeper地址

拦截器和配置拦截器类

因为订单这个系统是没有登录页面的,所以我们拦截器拦截这个订单系统的时候,如果他的ticket为空或者过期那么就跳回到前台系统的登录页面,因为这个是跨系统的,所以我们重定向的时候需要一个完整的路径,那么我们需要拿到前台系统的url,前台系统的url可以在yml文件中配置,通过@value("${shop.portal.url}")去获取。
在拦截器中我们根据ticket拦截,如果没有登录则去登录,登录成功后重定向到已经登录过后才可以访问的页面。

代码:important!!!

单点登录失败,从订单系统重定向前台系统

response.sendredirect(portalurl+"login?redirecturl="+request.getrequesturl());

这是一个javaweb中的重定向代码。response.sendredirect() 是重定向到指定的url,参数portalurl是重定向的url基础地址,login是登录页面的url,redirecturl是登录成功后要重定向回来的页面的url。request.getrequesturl()是获取当前请求的url,这里将其作为参数传递给了重定向url,登录成功后重回当前页面。其中redirecturl参数可以是任何需要登录后才能访问的页面,例如用户个人中心、订单页面等等。

代码
配置拦截器类:


/**
 * mvc配置类
 *
 * @author zhoubin
 * @since 1.0.0
 */
@configuration
@enablewebmvc
public class mvcconfig implements webmvcconfigurer {

	@autowired
	private orderlogininterceptor logininterceptor;
	@autowired
	private ordercommoninterceptor commoninterceptor;

	/**
	 * addinterceptor:添加自定义拦截器
	 * addpathpatterns:添加拦截请求  /**表示拦截所有
	 * excludepathpatterns:不拦截的请求
	 * @param registry
	 */
	@override
	public void addinterceptors(interceptorregistry registry) {
		registry.addinterceptor(commoninterceptor)
				.addpathpatterns("/**");
		registry.addinterceptor(logininterceptor)
				.addpathpatterns("/**")
				.excludepathpatterns("/static/**")
				.excludepathpatterns("/login/**")
				.excludepathpatterns("/image/**")
				.excludepathpatterns("/user/login/**")
				.excludepathpatterns("/user/logout/**");
	}

	/**
	 * 放行静态资源
	 * @param registry
	 */
	@override
	public void addresourcehandlers(resourcehandlerregistry registry) {
		registry.addresourcehandler("/static/**").addresourcelocations("classpath:/static/");
	}
}

拦截器三种方法:

@component
public class orderlogininterceptor implements handlerinterceptor {

	@reference(interfaceclass = shopssoservice.class)
	private shopssoservice ssoservice;
	@autowired
	private redistemplate<string,string> redistemplate;
	@value("${user.ticket}")
	private string userticket;
	@value("${shop.portal.url}")
	private string portalurl;

	/**
	 * 请求处理的方法之前执行
	 * @param request
	 * @param response
	 * @param handler
	 * @return
	 * @throws exception
	 */
	@override
	public boolean prehandle(httpservletrequest request, httpservletresponse response, object handler) throws exception {
		//获取用户票据
		string ticket = cookieutil.getcookievalue(request, "userticket");
		if (!stringutils.isempty(ticket)){
			//如果票据存在,进行验证
			admin admin = ssoservice.validate(ticket);
			//将用户信息存入session中,用于页面返显
			request.getsession().setattribute("user",admin);
			//重新设置失效时间
			valueoperations<string, string> valueoperations = redistemplate.opsforvalue();
			valueoperations.set(userticket+":"+ticket, jsonutil.object2jsonstr(admin),30, timeunit.minutes);
			return true;
		}
		//票据不存在或者用户验证失败,重定向至登录页面
		response.sendredirect(portalurl+"login?redirecturl="+request.getrequesturl());
		return false;
	}

	/**
	 * 请求处理的方法之后执行
	 * @param request
	 * @param response
	 * @param handler
	 * @param modelandview
	 * @throws exception
	 */
	@override
	public void posthandle(httpservletrequest request, httpservletresponse response, object handler, modelandview modelandview) throws exception {

	}

	/**
	 * 处理后执行清理工作
	 * @param request
	 * @param response
	 * @param handler
	 * @param ex
	 * @throws exception
	 */
	@override
	public void aftercompletion(httpservletrequest request, httpservletresponse response, object handler,
	                            exception ex) throws exception {

	}
}

在portal前台页面中编写login方法

 @requestmapping("login")
    public string login(string redirecturl, model model){
        model.addattribute("redirecturl",redirecturl);
        return "login";
    }

前台
!''表示如果获取到的值为空,则将其转换为空字符串。

<input type="hidden" id="redirecturl" value="${redirecturl!''}"/>
<script type="text/javascript">
    // 用户登录
    function userlogin() {
        $.ajax({
            url: "${ctx}/user/login",
            type: "post",
            data: $("#formlogin").serialize(),
            datatype: "json",
            success: function (result) {
                if (200 == result.code) {
                    // 如果存在重定向url则重定向至该url
                    if ($("#redirecturl").val()) {
                        location.href = $("#redirecturl").val();
                    }else {
                        location.href = "${ctx}/index";
                    }

                } else {
                    layer.msg("用户名或密码错误,请重新输入!");
                }
            },
            error: function () {
                layer.alert("亲,系统正在升级中,请稍后再试!");
            }
        });
    }
</script>

点击去结算跳转到预订单页面,说明为什么需要定义一个拦截器?@value?

去结算的那个页面是在前台系统的商品列表页面中,点击按钮之后跳转到订单系统的预订单页面。因此我们把订单系统的url放到前台系统的yml中,通过@value("${shop.order.url}")获取订单系统的完整的url
注意这里的小坑
@value注解是spring容器中的,我们无法在controller层也就是springmvc容器中获取key中的value值。

解决方法:我们可以把我们的url放到我们的一个最大的作用域application,通过拦截器去拿,因为拦截器会使用@component注解,这样我们就可以将@value注解注册到spring容器中了。然后将url放到application域中。
但是我们这个拦截器会不拦截请求,但是每一个请求他都会将url存入到我们的application域中,会造成一个频繁的写操作,因此我们要进行判断,如果这个url已经存过了,那么就不需要再存了。

配置拦截器类

@autowired
	private portalcommoninterceptor commoninterceptor;

	/**
	 * addinterceptor:添加自定义拦截器
	 * addpathpatterns:添加拦截请求  /**表示拦截所有
	 * excludepathpatterns:不拦截的请求
	 * @param registry
	 */
	@override
	public void addinterceptors(interceptorregistry registry) {
		registry.addinterceptor(commoninterceptor)
				.addpathpatterns("/**");
		registry.addinterceptor(logininterceptor)
				.addpathpatterns("/cart/**")
				.excludepathpatterns("/static/**")
				.excludepathpatterns("/login/**")
				.excludepathpatterns("/user/login/**")
				.excludepathpatterns("/user/logout/**");
	}

实现hanlerinterceptor接口

@component
public class portalcommoninterceptor implements handlerinterceptor {


	@value("${shop.order.url}")
	private string shoporderurl;

	@override
	public boolean prehandle(httpservletrequest request, httpservletresponse response, object handler) throws exception {
		//获取application对象
		servletcontext servletcontext = request.getsession().getservletcontext();
		string orderurl = (string) servletcontext.getattribute("orderurl");
		if (stringutils.isempty(orderurl)){
			servletcontext.setattribute("orderurl",shoporderurl);
		}
		return true;
	}
}

接下来就是实现从前台系统跳转到订单系统了。
此时portal的全局域内有orderurl,我们点击去结算按钮走重定向的controller,到达订单系统之后我们走订单系统的controller,去预订单页面。
前台系统的controller

    /**
     * 跳转订单系统
     * @return
     */
    @requestmapping("/topreorder")
    public string topreorder(httpservletrequest request){
        //获取servletcontext上下文中的值
        string orderurl = (string) request.getsession().getservletcontext().getattribute("orderurl");
        //重定向
        return "redirect:"+orderurl+"order/preorder";
    }

订单系统的controller

/**
	 * 跳转到预订单页面
	 *
	 * @return
	 */
	@requestmapping("/preorder")
	public string preorder(model model, httpservletrequest request) {
		admin admin = (admin) request.getsession().getattribute("user");
		model.addattribute("cartresult", cartservice.getcartlist(admin));
		return "order/preorder";
	}

到达预订单系统应当展示购物车列表和总金额

**怎么获取?**购物车列表和总金额可以调用rpc服务中的cartservice获取。要调用这个方法必须要获取用户信息,查看哪个用户的购物车信息。因为在拦截器里面登录的用户信息存放在session中,因此我们从session中获取用户信息。

@requestmapping("/preorder")
	public string preorder(model model, httpservletrequest request) {
		admin admin = (admin) request.getsession().getattribute("user");
		model.addattribute("cartresult", cartservice.getcartlist(admin));
		return "order/preorder";
	}

公共的页面展示出购物车的数量,调用rpc的catservice

@controller
@requestmapping("/cart")
public class cartcontroller {

	@reference(interfaceclass = cartservice.class)
	private cartservice cartservice;


	/**
	 * 获取购物车数量
	 * @return
	 */
	@requestmapping("/getcartnum")
	@responsebody
	public integer getcartnum(httpservletrequest request){
		admin admin = (admin) request.getsession().getattribute("user");
		return cartservice.getcartnum(admin);
	}

}

提交订单

点击提交按钮,前端传过来的有cartresult(购物车列表,总金额),
点击提交订单之后,有三件事情需要完成
1、跳转到订单页面
2、删除购物车中的数据
3、将提交的数据变道数据库里面去,为了后续的查看全部支部订单。
返回的是否成功,因为需要渲染页面,把订单和总金额传入前台。

生成订单

要把订单存入到数据库中首先要先生成订单。
通过mybatis-plus进行生成。
有关订单的数据库有t_order,t_order_goods,生成pojo,mapper,xml文件。
new一个order,属性赋值,然后插入到数据库中,如果插入成功,则获取carresult中list的每一个元素,让他转换为ordergoods,设置订单商品中的订单号为订单编码,与order关联起来,然后将ordergoods放到一个list集合中,插入数据库中,如果插入成功,并未出现异常,则返回成功,否则返回失败,因为controller需要一个订单编号,所以我们可以将返回的成功的信息里面放入我们的订单编号,在controller就可以进行存入了。
在这里生成的订单的状态信息会用一个枚举类来进行定义。

注意这里的订单编号是唯一的,我们用的是redis的自增key

@override
	public baseresult ordersave(admin admin, cartresult cartresult) {
		//创建order对象
		order order = new order();
		//订单编号 shop_年月日时分秒_自增key
		string ordersn = "shop_"+ datetimeformatter.ofpattern("yyyymmddhhmmss").format(localdatetime.now())+"_"+getincrement(redisorderincrement);
		order.setordersn(ordersn);
		//用户id
		order.setuserid(admin.getadminid().intvalue());
		//订单状态(未确认)
		order.setorderstatus(orderstatus.no_confirm.getstatus());
		//发货状态(未发货)
		order.setshippingstatus(sendstatus.no_pay.getstatus());
		//支付状态(未支付)
		order.setpaystatus(paystatus.no_pay.getstatus());
		//商品总价
		order.setgoodsprice(cartresult.gettotalprice());
		//应付金额
		order.setorderamount(cartresult.gettotalprice());
		//订单总价
		order.settotalamount(cartresult.gettotalprice());
		//订单时间
		long addtime = localdatetime.now().toepochsecond(zoneoffset.of("+8"));
		order.setaddtime(addtime.intvalue());
		int result = ordermapper.insertselective(order);
		//存储成功
		if (result>0){
			list<ordergoods> ordergoodslist  = new arraylist<>();
			for (cartvo cartvo : cartresult.getcartlist()) {
				//创建ordergoods对象
				ordergoods ordergoods = new ordergoods();
				//订单id
				ordergoods.setorderid(order.getorderid());
				//商品id
				ordergoods.setgoodsid(cartvo.getgoodsid());
				//商品名称
				ordergoods.setgoodsname(cartvo.getgoodsname());
				//商品价格
				ordergoods.setgoodsprice(cartvo.getmarketprice());
				//商品数量
				ordergoods.setgoodsnum(cartvo.getgoodsnum().shortvalue());
				//订单方式
				ordergoods.setpromtype(promtypestatus.normal.getstatus());
				//发货状态
				ordergoods.setissend(sendstatus.no_pay.getstatus());
				//添加到订单商品对象列表
				ordergoodslist.add(ordergoods);
			}
			//批量插入
			result = ordergoodsmapper.insertordergoodsbatch(ordergoodslist);
			if (result>0){
				baseresult baseresult = baseresult.success();
				baseresult.setmessage(ordersn);
				return baseresult;
			}
		}
		return baseresult.error();
	}

/**
	 * redis自增key
	 * @param key
	 * @return
	 */
	private long getincrement(string key){
		redisatomiclong entityidcounter = new redisatomiclong(key,redistemplate.getconnectionfactory());
		return entityidcounter.getandincrement();
	}
}

跳转到提交页面

1、生成订单
2、清空购物车
3、跳转页面

	@requestmapping("/submitorder")
	public string submitorder(model model, httpservletrequest request) {
		admin admin = (admin) request.getsession().getattribute("user");
		cartresult cartresult = cartservice.getcartlist(admin);
		//1.存入订单信息
		baseresult baseresult = orderservice.ordersave(admin, cartresult);
		//2.清除购物车信息
		cartservice.clearcart(admin);
		//总价
		model.addattribute("totalprice", cartresult.gettotalprice());
		//订单编号
		model.addattribute("ordersn", baseresult.getmessage());
		//3.页面跳转
		return "/order/submitorder";
	}

订单系统和前台系统的交互

订单系统可以在搜索框中进行搜索,搜索跳转到前台系统。

搜索进入前台页面

@controller
@requestmapping("search")
public class searchcontroller {

	/**
	 * 跳转搜索页面,传过去一个searchstr
	 * @param request
	 * @param searchstr
	 * @param model
	 * @return
	 */
	@requestmapping("index")
	public string index(httpservletrequest request, string searchstr, model model){
		try {
			//对输入的内容进行编码,防止中文乱码
			searchstr = urlencoder.encode(searchstr,"utf-8");
		} catch (unsupportedencodingexception e) {
			e.printstacktrace();
		}
		return "redirect:"+request.getsession().getservletcontext().getattribute("portalurl")+"search/index?searchstr="+searchstr;
	}

}

在订单系统点击登出:
重定向,从应用域中获取数据request.getsession().getservletcontext().getattribute()

	@requestmapping("/index")
	public string index(httpservletrequest request, string searchstr, model model){
		try {
			//对输入的内容进行编码,防止中文乱码
			searchstr = urlencoder.encode(searchstr,"utf-8");
		} catch (unsupportedencodingexception e) {
			e.printstacktrace();
		}
		return "redirect:"+request.getsession().getservletcontext().getattribute("portalurl")+"search/index?searchstr="+searchstr;
	}
}
(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com