一.页面展示
点击 ''个人中心'',跳转到用户中心 主页,并 渲染用户相关信息(后端获取用户相关数据,并渲染到前端html页面),点击左侧不同菜单栏,跳转到对应的页面,并渲染相关数据
注意:
在不同菜单栏上,对应栏位要 高亮
用户中心

用户中心-我的订单
功能:
1.展示订单列表以及订单相关信息(订单支付状态,订单号,支付方式,金额以及订单商品相关信息)
2.点击'订单详情',进入对应订单详情页面
3.条件查询:
(1).通过不同订单状态,查询对应状态的订单数据
(2).输入商品名称筛选相关订单
4.根据订单状态不同,展示'去支付','售后'等按钮
5.订单列表分页处理

用户中心-订单详情
功能:
展示订单相关数据(订单号,商品信息,物流信息); 物流信息在管理后台,商户发货后会进行更新(完善订单数据表:支付时间,取消订单时间等,可根据具体业务具体设计);
物流信息相关数据: 开发者可以在管理后台创建对应的功能(增加相关数据表,物流curd数据)


后台-订单管理
展示订单列表,筛选条件等(该功能自己实现,功能非常简单);订单详情:展示订单信息,并可以编辑支付方式,配送方式,发票信息,订单商品信息,费用信息,订单状态,配送状态等订单相关的信息,同时还有订单变更log操作;以上功能可以创建多个表保存,格式和订单表,订单商品表类似,都是关联关系的,这里就不一一说明

二.代码展示
订单数据模型
订单数据表增加相关字段,并体现到模型上
package models
//订单表相关结构体
type Order struct {
Id int
OrderId string //订单号
Uid int //用户id
AllPrice float64 //订单总价
Phone string //收货人手机号
Name string //收货人姓名
Address string //收货地址
PayStatus int // 支付状态: 0 表示未支付, 1 已经支付
PayType int // 支付类型: 0 alipay, 1 wechat
OrderStatus int // 订单状态: 0 已下单 ,1 已付款,2 已配货,3、发货, 4 交易成功, 5 退货, 6 取消
AddTime int //订单生成时间
PayTime int //支付时间
DistributionTime int //配货时间
ExwarehouseTime int //出库时间
SuccessfulTime int //交易成功时间
CancelTime int //取消时间
ReturnTime int //退款时间
LogisticsCompany int //物流公司id: 可以创建对应的物流公司数据表,然后在后台增加对应的物流信息
WaybillNo string //运单号
//其他的字段
//订单商品关联关系
OrderItem []OrderItem `gorm:"foreignKey:OrderId;references:Id"`
}
func (Order) TableName() string {
return "order"
}
用户中心控制器
在controllers/frontend下创建用户中心相关控制器UserController.go,主要方法:
个人中心首页-index: 展示用户相关信息
我的订单列表-orderList:
功能:
1.展示订单列表以及订单相关信息(订单支付状态,订单号,支付方式,金额以及订单商品相关信息)
2.点击'订单详情',进入对应订单详情页面
3.条件查询:
(1).通过不同订单状态,查询对应状态的订单数据
(2).输入商品名称筛选相关订单
4.根据订单状态不同,展示'去支付','售后'等按钮
5.订单列表分页处理
订单详情-OrderInfo: 展示订单详情相关数据
...
package frontend
//用户中心
import (
"goshop/models"
"math"
"github.com/gin-gonic/gin"
"net/http"
)
type UserController struct {
BaseController
}
//个人中心首页
func (con UserController) Index(c *gin.Context) {
var tpl = "frontend/user/welcome.html"
con.Render(c, tpl, gin.H{})
}
//我的订单列表
func (con UserController) OrderList(c *gin.Context) {
// 页码数: 当前页
page, _ := models.Int(c.Query("page"))
if page == 0 {
page = 1
}
//页大小
pageSize := 2
//获取当前用户
user := models.User{}
models.Cookie.Get(c, "user", &user)
//模糊查询
where := "uid =" + models.String(user.Id)
keywords := c.Query("keywords")
if keywords != "" {
//查询订单商品title
orderItemList := []models.OrderItem{}
models.DB.Where("product_title like ?", "%" + keywords + "%").Find(&orderItemList)
//拼接订单id
var str string
// 字符串: 12,12,22
for i := 0; i < len(orderItemList); i++ {
if i == 0 {
str += models.String(orderItemList[i].OrderId)
} else {
str += "," + models.String(orderItemList[i].OrderId)
}
}
//拼接where条件
where += " AND id in (" + str + ")"
}
//获取订单状态: 按照状态筛选订单
orderStatus, statusErr := models.Int(c.Query("orderStatus"))
if statusErr == nil && orderStatus >= 0 { // 判断订单状态
where += " AND order_status=" + models.String(orderStatus)
} else {
orderStatus = -1
}
//获取当前用户下面订单信息(条件查询,关联查询)
orderList := []models.Order{}
models.DB.Where(where).Offset((page - 1) * pageSize).Limit(pageSize).Preload("OrderItem").Order("add_time desc").Find(&orderList)
//获取总数量
var count int64
models.DB.Where(where).Table("order").Count(&count)
var tpl = "frontend/user/order.html"
con.Render(c, tpl, gin.H{
"order": orderList,
"page": page,
"keywords": keywords,
"orderStatus": orderStatus,
"totalPages": math.Ceil(float64(count) / float64(pageSize)), //计算总页数
})
}
//订单详情
func (con UserController) OrderInfo(c *gin.Context) {
//获取有效的订单id
id, err := models.Int(c.Query("id"))
if err != nil {
c.Redirect(http.StatusFound, "/user/order")
}
//获取用户数据
user := models.User{}
models.Cookie.Get(c, "user", &user)
//获取订单数据
order := []models.Order{}
models.DB.Where("id = ? And uid = ?", id, user.Id).Preload("OrderItem").Find(&order)
//判断订单是否存在:不存在则跳转到用户订单列表页面
if len(order) == 0 {
c.Redirect(http.StatusFound, "/user/order")
return
}
//跳转到订单详情页面
var tpl = "frontend/user/order_info.html"
con.Render(c, tpl, gin.H{
"order": order[0],
})
}
路由
在routers/frontendRouters.go下增加用户个人中心相关路由
//用户个人中心首页
defaultRouters.GET("/user", middlewares.InitUserAuthMiddleware, frontend.UserController{}.Index)
//用户订单列表
defaultRouters.GET("/user/order", middlewares.InitUserAuthMiddleware, frontend.UserController{}.OrderList)
//用户订单详情
defaultRouters.GET("/user/orderinfo", middlewares.InitUserAuthMiddleware, frontend.UserController{}.OrderInfo)
html,js
个人中心左侧菜单栏html
在templates/frontend/user下创建个人中心左侧菜单栏公共html: user_left.html,以便各个页面公用
{{ define "frontend/user/user_left.html" }}
<ul>
<li {{if eq .pathname "/user"}}class="active"{{end}}><a href="/user">欢迎页面</a></li>
<li {{if eq .pathname "/user/order"}}class="active"{{end}} {{if eq .pathname "/user/orderinfo"}}class="active"{{end}}><a href="/user/order">我的订单</a></li>
<li><a href="#">用户信息</a></li>
<li><a href="#">我的收藏</a></li>
<li><a href="#">我的评论</a></li>
</ul>
{{end}}
个人中心首页html
在templates/frontend/user下创建个人中心html: welcome.html,显示用户相关信息
{{ define "frontend/user/welcome.html" }}
{{ template "frontend/public/page_header.html" .}}
{{ template "frontend/public/middle_nav.html" .}}
<link rel="stylesheet" href="/static/frontend/css/welcome.css" />
<!-- self_info -->
<div class="grzxbj">
<div class="selfinfo center">
<div class="lfnav fl">
<div class="ddzx">用户中心</div>
<div class="subddzx">
{{ template "frontend/user/user_left.html" .}}
</div>
</div>
<div class="rtcont fr">
<div class="portal-content-box">
<div class="box-bd">
<div class="portal-main clearfix">
<div class="user-card">
<h2 class="username">2152135723</h2>
<p class="tip">晚上好</p>
<a class="link" href="https://account.xiaomi.com/pass/userInfo" target="_blank"
data-stat-id="30d619c492c43471"
onclick="_msq.push(['trackEvent', 'f4f3444fdfa3d27a-30d619c492c43471', 'https://account.xiaomi.com/pass/userInfo', 'pcpid', '']);">修改个人信息
></a>
<img class="avatar" src="https://account.xiaomi.com/static/img/passport/photo.jpg"
width="150" height="150" alt="2152135723">
</div>
<div class="user-actions">
<ul class="action-list">
<li>账户安全:<span class="level level-2">普通</span></li>
<li>绑定手机:<span class="tel">150********01</span></li>
<li>绑定邮箱:<span class="tel"></span><a class="btn btn-small btn-primary"
href="https://account.xiaomi.com/pass/userInfo" target="_blank"
data-stat-id="d36648c4ef44cb77"
onclick="_msq.push(['trackEvent', 'f4f3444fdfa3d27a-d36648c4ef44cb77', 'https://account.xiaomi.com/pass/userInfo', 'pcpid', '']);">绑定</a>
</li>
</ul>
</div>
</div>
<div class="portal-sub">
<ul class="info-list clearfix">
<li>
<h3>待支付的订单:<span class="num">0</span></h3>
<a href="//static.mi.com/order/?type=7" data-stat-id="ff48b3f50874dae7">查看待支付订单</a>
<img src="//s01.mifile.cn/i/user/portal-icon-1.png" alt="">
</li>
<li>
<h3>待收货的订单:<span class="num">0</span></h3>
<a href="//static.mi.com/order/?type=8" data-stat-id="f7b15ff4b8710895">查看待收货订单</a>
<img src="//s01.mifile.cn/i/user/portal-icon-2.png" alt="">
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="clear"></div>
</div>
</div>
<!-- self_info -->
{{template "frontend/public/page_footer.html" .}}
</body>
</html>
{{end}}
个人中心css
略
我的订单列表页面html
在templates/frontend/user下创建我的订单列表页面: order.html,渲染相关数据:
1.展示订单列表以及订单相关信息(订单支付状态,订单号,支付方式,金额以及订单商品相关信息)
2.点击'订单详情',进入对应订单详情页面
3.条件查询:
(1).通过不同订单状态,查询对应状态的订单数据
(2).输入商品名称筛选相关订单
4.根据订单状态不同,展示'去支付','售后'等按钮
5.订单列表分页处理
{{ define "frontend/user/order.html" }}
{{ template "frontend/public/page_header.html" .}}
{{ template "frontend/public/middle_nav.html" .}}
<script src="/static/frontend/js/jqPaginator.js"></script>
<link rel="stylesheet" href="/static/frontend/css/order.css"/>
<!-- self_info -->
<div class="grzxbj">
<div class="selfinfo center">
<div class="lfnav fl">
<div class="ddzx">用户中心</div>
<div class="subddzx">
{{ template "frontend/user/user_left.html" .}}
</div>
</div>
<div class="rtcont fr">
<h1>我的订单</h1>
<div class="uc-content-box">
<div class="box-hd">
<div class="more clearfix">
<ul class="filter-list J_orderType">
<li class="first active"><a href="/user/order">全部订单</a></li>
<li><a href="/user/order?orderStatus=0">待支付</a></li>
<li><a href="/user/order?orderStatus=1">已支付</a></li>
<li><a href="/user/order?orderStatus=3">待收货</a></li>
<li><a href="/user/order?orderStatus=6">已关闭</a></li>
</ul>
<form id="J_orderSearchForm" class="search-form clearfix" action="/user/order" method="get">
<input class="search-text" type="search" id="J_orderSearchKeywords" name="keywords"
autocomplete="off" placeholder="输入商品名称" value="{{.keywords}}">
<input type="submit" class="search-btn iconfont" value="搜索">
</form>
</div>
</div>
<div class="box-bd">
{{if .order}}
<table class="table">
{{range $key,$value := .order}}
<tr>
<td colspan="2">
<div class="order-summary">
<h2>
{{if eq $value.OrderStatus 0}}
已下单 未支付
{{else if eq $value.OrderStatus 1}}
已付款
{{else if eq $value.OrderStatus 2}}
已配货
{{else if eq $value.OrderStatus 3}}
已发货
{{else if eq $value.OrderStatus 4}}
交易成功
{{else if eq $value.OrderStatus 5}}
已退货
{{else if eq $value.OrderStatus 6}}
无效 已取消
{{end}}
</h2>
{{$value.AddTime | UnixToTime}} | {{$value.Name}} |
订单号:{{$value.OrderId}} | 在线支付
实付金额:{{$value.AllPrice}} 元
</div>
{{range $k,$v := $value.OrderItem}}
<div class="order-info clearfix">
<div class="col_pic">
<img src="/{{$v.ProductImg}}"/>
</div>
<div class="col_title">
<p>{{$v.ProductTitle}}</p>
<p>{{$v.ProductPrice}}元 × {{$v.ProductNum}}</p>
<p>合计:{{Mul $v.ProductPrice $v.ProductNum}}元</p>
</div>
</div>
{{end}}
</td>
<td>
{{if eq $value.PayStatus 1}}
<span>
<a class="btn" href="/user/orderinfo?id={{$value.Id}}">订单详情</a>
<br>
<br>
<a class="btn" href="#">申请售后</a>
</span>
{{else}}
<span>
<a class="delete btn btn-primary"
href="/buy/confirm?id={{$value.Id}}">去支付</a>
<br>
<br>
<a class="delete btn" href="/user/orderinfo?id={{$value.Id}}">订单详情</a>
</span>
{{end}}
</td>
</tr>
{{end}}
</table>
<div id="page" class="pagination fr"></div>
{{else}}
<p style="text-align:center; padding-top:100px;">没有查找到订单</p>
{{end}}
</div>
</div>
<script>
$('#page').jqPaginator({
totalPages: {{.totalPages}},
visiblePages: 8,
currentPage: {{.page}},
onPageChange: function (num, type) {
if (type == 'change') {
location.href = "/user/order?page=" + num + "&keywords={{.keywords}}&orderStatus={{.orderStatus}}";
}
}
});
</script>
</div>
<div class="clear"></div>
</div>
</div>
<!-- self_info -->
{{template "frontend/public/page_footer.html" .}}
</body>
</html>
{{end}}
分页js
在static/frontend/js下增加分页js: jqPaginator.js
(function ($) {
'use strict';
$.jqPaginator = function (el, options) {
if(!(this instanceof $.jqPaginator)){
return new $.jqPaginator(el, options);
}
var self = this;
self.$container = $(el);
self.$container.data('jqPaginator', self);
self.init = function () {
if (options.first || options.prev || options.next || options.last || options.page) {
options = $.extend({}, {
first: '',
prev: '',
next: '',
last: '',
page: ''
}, options);
}
self.options = $.extend({}, $.jqPaginator.defaultOptions, options);
self.verify();
self.extendJquery();
self.render();
self.fireEvent(this.options.currentPage, 'init');
};
self.verify = function () {
var opts = self.options;
if (!self.isNumber(opts.totalPages)) {
throw new Error('[jqPaginator] type error: totalPages');
}
if (!self.isNumber(opts.totalCounts)) {
throw new Error('[jqPaginator] type error: totalCounts');
}
if (!self.isNumber(opts.pageSize)) {
throw new Error('[jqPaginator] type error: pageSize');
}
if (!self.isNumber(opts.currentPage)) {
throw new Error('[jqPaginator] type error: currentPage');
}
if (!self.isNumber(opts.visiblePages)) {
throw new Error('[jqPaginator] type error: visiblePages');
}
if (!opts.totalPages && !opts.totalCounts) {
throw new Error('[jqPaginator] totalCounts or totalPages is required');
}
if (!opts.totalPages && !opts.totalCounts) {
throw new Error('[jqPaginator] totalCounts or totalPages is required');
}
if (!opts.totalPages && opts.totalCounts && !opts.pageSize) {
throw new Error('[jqPaginator] pageSize is required');
}
if (opts.totalCounts && opts.pageSize) {
opts.totalPages = Math.ceil(opts.totalCounts / opts.pageSize);
}
if (opts.currentPage < 1 || opts.currentPage > opts.totalPages) {
throw new Error('[jqPaginator] currentPage is incorrect');
}
if (opts.totalPages < 1) {
throw new Error('[jqPaginator] totalPages cannot be less currentPage');
}
};
self.extendJquery = function () {
$.fn.jqPaginatorHTML = function (s) {
return s ? this.before(s).remove() : $('<p>').append(this.eq(0).clone()).html();
};
};
self.render = function () {
self.renderHtml();
self.setStatus();
self.bindEvents();
};
self.renderHtml = function () {
var html = [];
var pages = self.getPages();
for (var i = 0, j = pages.length; i < j; i++) {
html.push(self.buildItem('page', pages[i]));
}
self.isEnable('prev') && html.unshift(self.buildItem('prev', self.options.currentPage - 1));
self.isEnable('first') && html.unshift(self.buildItem('first', 1));
self.isEnable('statistics') && html.unshift(self.buildItem('statistics'));
self.isEnable('next') && html.push(self.buildItem('next', self.options.currentPage + 1));
self.isEnable('last') && html.push(self.buildItem('last', self.options.totalPages));
if (self.options.wrapper) {
self.$container.html($(self.options.wrapper).html(html.join('')).jqPaginatorHTML());
} else {
self.$container.html(html.join(''));
}
};
self.buildItem = function (type, pageData) {
var html = self.options[type]
.replace(/{{page}}/g, pageData)
.replace(/{{totalPages}}/g, self.options.totalPages)
.replace(/{{totalCounts}}/g, self.options.totalCounts);
return $(html).attr({
'jp-role': type,
'jp-data': pageData
}).jqPaginatorHTML();
};
self.setStatus = function () {
var options = self.options;
if (!self.isEnable('first') || options.currentPage === 1) {
$('[jp-role=first]', self.$container).addClass(options.disableClass);
}
if (!self.isEnable('prev') || options.currentPage === 1) {
$('[jp-role=prev]', self.$container).addClass(options.disableClass);
}
if (!self.isEnable('next') || options.currentPage >= options.totalPages) {
$('[jp-role=next]', self.$container).addClass(options.disableClass);
}
if (!self.isEnable('last') || options.currentPage >= options.totalPages) {
$('[jp-role=last]', self.$container).addClass(options.disableClass);
}
$('[jp-role=page]', self.$container).removeClass(options.activeClass);
$('[jp-role=page][jp-data=' + options.currentPage + ']', self.$container).addClass(options.activeClass);
};
self.getPages = function () {
var pages = [],
visiblePages = self.options.visiblePages,
currentPage = self.options.currentPage,
totalPages = self.options.totalPages;
if (visiblePages > totalPages) {
visiblePages = totalPages;
}
var half = Math.floor(visiblePages / 2);
var start = currentPage - half + 1 - visiblePages % 2;
var end = currentPage + half;
if (start < 1) {
start = 1;
end = visiblePages;
}
if (end > totalPages) {
end = totalPages;
start = 1 + totalPages - visiblePages;
}
var itPage = start;
while (itPage <= end) {
pages.push(itPage);
itPage++;
}
return pages;
};
self.isNumber = function (value) {
var type = typeof value;
return type === 'number' || type === 'undefined';
};
self.isEnable = function (type) {
return self.options[type] && typeof self.options[type] === 'string';
};
self.switchPage = function (pageIndex) {
self.options.currentPage = pageIndex;
self.render();
};
self.fireEvent = function (pageIndex, type) {
return (typeof self.options.onPageChange !== 'function') || (self.options.onPageChange(pageIndex, type) !== false);
};
self.callMethod = function (method, options) {
switch (method) {
case 'option':
self.options = $.extend({}, self.options, options);
self.verify();
self.render();
break;
case 'destroy':
self.$container.empty();
self.$container.removeData('jqPaginator');
break;
default :
throw new Error('[jqPaginator] method "' + method + '" does not exist');
}
return self.$container;
};
self.bindEvents = function () {
var opts = self.options;
self.$container.off();
self.$container.on('click', '[jp-role]', function () {
var $el = $(this);
if ($el.hasClass(opts.disableClass) || $el.hasClass(opts.activeClass)) {
return;
}
var pageIndex = +$el.attr('jp-data');
if (self.fireEvent(pageIndex, 'change')) {
self.switchPage(pageIndex);
}
});
};
self.init();
return self.$container;
};
$.jqPaginator.defaultOptions = {
wrapper: '',
first: '<li class="first"><a href="javascript:;">第一页</a></li>',
prev: '<li class="prev"><a href="javascript:;">上一页</a></li>',
next: '<li class="next"><a href="javascript:;">下一页</a></li>',
last: '<li class="last"><a href="javascript:;">最后一页</a></li>',
page: '<li class="page"><a href="javascript:;">{{page}}</a></li>',
totalPages: 0,
totalCounts: 0,
pageSize: 0,
currentPage: 1,
visiblePages: 7,
disableClass: 'disabled',
activeClass: 'active',
onPageChange: null
};
$.fn.jqPaginator = function () {
var self = this,
args = Array.prototype.slice.call(arguments);
if (typeof args[0] === 'string') {
var $instance = $(self).data('jqPaginator');
if (!$instance) {
throw new Error('[jqPaginator] the element is not instantiated');
} else {
return $instance.callMethod(args[0], args[1]);
}
} else {
return new $.jqPaginator(this, args[0]);
}
};
})(jQuery);
我的订单详情页面html
在templates/frontend/user下创建我的订单详情页面html: order_info.html,显示用户订单详情相关数据
{{ define "frontend/user/order_info.html" }}
{{ template "frontend/public/page_header.html" .}}
{{ template "frontend/public/middle_nav.html" .}}
<!-- end banner_x -->
<link rel="stylesheet" href="/static/frontend/css/order.css" />
<!-- self_info -->
<div class="grzxbj">
<div class="selfinfo center">
<div class="lfnav fl">
<div class="ddzx">用户中心</div>
<div class="subddzx">
{{ template "frontend/user/user_left.html" .}}
</div>
</div>
<div class="rtcont fr">
<h1>订单详情</h1>
<div class="uc-content-box">
<div class="uc-box uc-main-box">
<div class="uc-content-box order-view-box">
<div class="box-hd">
<div class="more clearfix">
<h2 class="subtitle">订单号:{{.order.OrderId}}
<span class="tag tag-subsidy"></span>
</h2>
<div class="actions">
<a title="申请售后" href="http://service.order.mi.com/apply/order/id/1160529723001145" class="btn btn-small btn-line-gray" data-stat-id="12e905752ea93db8" onclick="_msq.push(['trackEvent', '4a854694de3347de-12e905752ea93db8', 'http://service.order.mi.com/apply/order/id/1160529723001145', 'pcpid', '']);">申请售后</a>
</div>
</div>
</div>
<div class="box-bd">
<div class="uc-order-item uc-order-item-finish">
<div class="order-detail">
<div class="order-summary">
<div class="order-status">
{{if eq .order.OrderStatus 0}}
已下单 未支付
{{else if eq .order.OrderStatus 1}}
已付款
{{else if eq .order.OrderStatus 2}}
已配货
{{else if eq .order.OrderStatus 3}}
已发货
{{else if eq .order.OrderStatus 4}}
交易成功
{{else if eq .order.OrderStatus 5}}
已退货
{{else if eq .order.OrderStatus 6}}
无效 已取消
{{end}}
</div>
<div class="order-progress">
<ol class="progress-list clearfix progress-list-5">
<li class="step step-first {{if ge .order.OrderStatus 0}}step-done{{end}}">
<div class="progress"><span class="text">下单</span></div>
<div class="info">2022年01月29日 18:45</div>
</li>
<li class="step {{if ge .order.OrderStatus 1}}step-done{{end}}">
<div class="progress"><span class="text">付款</span></div>
<div class="info">2022年01月29日 18:49</div>
</li>
<li class="step {{if ge .order.OrderStatus 2}}step-done{{end}}">
<div class="progress"><span class="text">已配货</span></div>
<div class="info">2022年01月29日 18:59</div>
</li>
<li class="step {{if ge .order.OrderStatus 3}}step-done{{end}}">
<div class="progress"><span class="text">已发货</span></div>
<div class="info">2022年01月30日 17:50</div>
</li>
{{if eq .order.OrderStatus 4}}
<li class="step {{if eq .order.OrderStatus 4}}step-done{{end}} step-active step-last">
<div class="progress"><span class="text">交易成功</span></div>
<div class="info">2022年02月04日 13:58</div>
</li>
{{else if eq .order.OrderStatus 5}}
<li class="step {{if eq .order.OrderStatus 5}}step-done{{end}} step-active step-last">
<div class="progress"><span class="text">已退货</span></div>
<div class="info">2022年02月04日 13:58</div>
</li>
{{else if eq .order.OrderStatus 6}}
<li class="step {{if eq .order.OrderStatus 6}}step-done{{end}} step-active step-last">
<div class="progress"><span class="text">已取消</span></div>
<div class="info">2022年02月04日 13:58</div>
</li>
{{else}}
<li class="step step-active step-last">
<div class="progress"><span class="text">交易中</span></div>
<div class="info"></div>
</li>
{{end}}
</ol>
</div>
<div class="order-delivery order-delivery-detail" style="display:block;border:none;">
<p class="delivery-num">
物流公司:
<a href="http://www.sf-express.com" target="_blank" data-stat-id="d4af14ade0c175da" >顺丰(北京) </a>
运单号:199384067236
</p>
</div>
</div>
<table class="order-items-table">
<tbody>
{{range $k,$v := .order.OrderItem}}
<tr>
<td class="col col-thumb">
<div class="figure figure-thumb">
<img src="/{{$v.ProductImg}}" width="60px" />
</div>
</td>
<td class="col col-name">
<p class="name">
<a href="#">{{$v.ProductTitle}}</a>
</p>
</td>
<td class="col col-price">
<p class="price">{{$v.ProductPrice}}元 × {{$v.ProductNum}}</p>
</td>
<td class="col col-actions">
</td>
</tr>
{{end}}
</tbody>
</table>
</div>
<!-- 订金盲约订单 -->
<div id="editAddr" class="order-detail-info">
<h3>收货信息</h3>
<table class="info-table">
<tbody>
<tr>
<th>姓 名:</th>
<td>{{.order.Name}}</td>
</tr>
<tr>
<th>联系电话:</th>
<td>{{.order.Phone}}</td>
</tr>
<tr>
<th>收货地址:</th>
<td>{{.order.Address}}</td>
</tr>
</tbody>
</table>
<div class="actions">
</div>
</div>
<div id="editTime" class="order-detail-info">
<h3>支付方式</h3>
<table class="info-table">
<tbody>
<tr>
<th>支付方式:</th>
<td>在线支付</td>
</tr>
</tbody>
</table>
<div class="actions">
</div>
</div>
<div class="order-detail-info">
<h3>发票信息</h3>
<table class="info-table">
<tbody>
<tr>
<th>发票类型:</th>
<td>电子发票</td>
</tr>
<tr>
<th>发票内容:</th>
<td>购买商品明细</td>
</tr>
<tr>
<th>发票抬头:</th>
<td>个人</td>
</tr>
</tbody>
</table>
</div>
<div class="order-detail-total">
<table class="total-table">
<tbody>
<tr>
<th>商品总价:</th>
<td><span class="num">{{.order.AllPrice}}</span>元</td>
</tr>
<tr>
<th class="total">实付金额:</th>
<td class="total"><span class="num">{{.order.AllPrice}}</span>元</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="clear"></div>
</div>
</div>
<!-- self_info -->
{{template "frontend/public/page_footer.html" .}}
</body>
</html>
{{end}}
[上一节][golang gin框架] 34.Gin 商城项目- 集成支付宝微信支付、生成支付二维码、监听处理异步通知跳转到订单页面
[下一节][golang gin框架] 36.Gin 商城项目-RESTful API 设计指南,允许Cros跨域 ,提供api接口实现前后端分离,以及JWT的使用