OpenCart3订单历史页商品详情显示异常:单商品重复出现
修复OpenCart3订单历史页面显示每个订单商品详情的问题
你遇到的核心问题是没有把商品数据和单个订单绑定,反而用了全局的$data['products']数组——每次循环订单时都会重置这个数组,最后所有订单自然只会显示最后一次循环的商品。另外你还需要补充商品图片的获取逻辑来满足需求,下面是具体的修复步骤:
1. 修正控制器代码(catalog/controller/account/order.php)
调整代码结构,让每个订单拥有独立的商品列表,并添加图片处理逻辑:
public function index() { // 保留原有权限验证、语言加载、页面标题设置等代码 if ($this->customer->isLogged()) { $this->load->language('account/order'); $this->document->setTitle($this->language->get('heading_title')); // 原有筛选、订单列表获取逻辑不变 $data['orders'] = array(); $results = $this->model_account_order->getOrders($filter_data); foreach ($results as $result) { // 先组装基础订单信息(原有逻辑保留) $order_data = array( 'order_id' => $result['order_id'], 'invoice_no' => $result['invoice_no'], 'date_added' => date($this->language->get('date_format_short'), strtotime($result['date_added'])), 'status' => $result['status'], 'total' => $this->currency->format($result['total'], $result['currency_code'], $result['currency_value']), 'view' => $this->url->link('account/order/info', 'order_id=' . $result['order_id'], true), 'reorder' => $this->url->link('account/order/reorder', 'order_id=' . $result['order_id'], true) ); // --- 新增商品详情处理逻辑 --- $this->load->model('catalog/product'); $this->load->model('tool/upload'); $order_info = $this->model_account_order->getOrder($result['order_id']); if ($order_info) { // 初始化当前订单的商品数组(绑定到当前订单,而非全局) $order_data['products'] = array(); $products = $this->model_account_order->getOrderProducts($result['order_id']); foreach ($products as $product) { $option_data = array(); $options = $this->model_account_order->getOrderOptions($result['order_id'], $product['order_product_id']); // 处理商品选项 foreach ($options as $option) { $value = $option['value']; if ($option['type'] == 'file') { $upload_info = $this->model_tool_upload->getUploadByCode($option['value']); $value = $upload_info ? $upload_info['name'] : ''; } $option_data[] = array( 'name' => $option['name'], 'value' => (utf8_strlen($value) > 20 ? utf8_substr($value, 0, 20) . '..' : $value) ); } // 获取商品信息,处理图片 $product_info = $this->model_catalog_product->getProduct($product['product_id']); $reorder = ''; $image = ''; if ($product_info) { $reorder = $this->url->link('account/order/reorder', 'order_id=' . $result['order_id'] . '&order_product_id=' . $product['order_product_id'], true); // 生成适配页面的缩略图 if ($product_info['image']) { $image = $this->model_tool_image->resize( $product_info['image'], $this->config->get('theme_' . $this->config->get('config_theme') . '_image_cart_width'), $this->config->get('theme_' . $this->config->get('config_theme') . '_image_cart_height') ); } } // 将当前商品加入订单的商品数组 $order_data['products'][] = array( 'image' => $image, 'name' => $product['name'], 'model' => $product['model'], 'option' => $option_data, 'quantity' => $product['quantity'], 'price' => $this->currency->format($product['price'] + ($this->config->get('config_tax') ? $product['tax'] : 0), $order_info['currency_code'], $order_info['currency_value']), 'total' => $this->currency->format($product['total'] + ($this->config->get('config_tax') ? ($product['tax'] * $product['quantity']) : 0), $order_info['currency_code'], $order_info['currency_value']), 'reorder' => $reorder, 'return' => $this->url->link('account/return/add', 'order_id=' . $result['order_id'] . '&product_id=' . $product['product_id'], true) ); } // 可选:绑定订单总计到当前订单 $order_data['totals'] = array(); $totals = $this->model_account_order->getOrderTotals($result['order_id']); foreach ($totals as $total) { $order_data['totals'][] = array( 'title' => $total['title'], 'text' => $this->currency->format($total['value'], $order_info['currency_code'], $order_info['currency_value']), ); } } // --- 商品详情处理结束 --- // 将包含商品的订单数据加入全局订单列表 $data['orders'][] = $order_data; } // 原有视图加载代码不变 $data['column_left'] = $this->load->controller('common/column_left'); $data['column_right'] = $this->load->controller('common/column_right'); $data['content_top'] = $this->load->controller('common/content_top'); $data['content_bottom'] = $this->load->controller('common/content_bottom'); $data['footer'] = $this->load->controller('common/footer'); $data['header'] = $this->load->controller('common/header'); $this->response->setOutput($this->load->view('account/order_list', $data)); } else { $this->response->redirect($this->url->link('account/login', '', true)); } }
关键修正点:
- 把商品数组从全局
$data['products']改为绑定到每个订单的$order_data['products'],确保订单与商品一一对应 - 添加了商品图片的获取与缩放逻辑,适配OpenCart主题的图片尺寸设置
- 调整代码结构,避免每次循环订单时重置商品数组
2. 修正模板文件(catalog/view/theme/你的主题/template/account/order_list.twig)
在订单循环内部嵌套商品循环,展示商品图片和详情:
{% if orders %} {% for order in orders %} <div class="order-container"> <div class="order-header"> <h3>订单 #{{ order.order_id }}</h3> <p>状态: {{ order.status }} | 下单时间: {{ order.date_added }}</p> <div class="order-actions"> <a href="{{ order.view }}" class="btn">查看完整订单</a> </div> </div> <!-- 订单商品列表 --> <div class="order-products-section"> <h4>订单商品</h4> {% if order.products %} <div class="products-grid"> {% for product in order.products %} <div class="product-item"> {% if product.image %} <img src="{{ product.image }}" alt="{{ product.name }}" class="product-thumbnail"> {% endif %} <div class="product-info"> <h5>{{ product.name }}</h5> <p>型号: {{ product.model }}</p> <p>数量: {{ product.quantity }} × {{ product.price }}</p> <p>小计: {{ product.total }}</p> {% if product.option %} <div class="product-options"> {% for option in product.option %} <small>{{ option.name }}: {{ option.value }}</small> {% endfor %} </div> {% endif %} {% if product.reorder %} <a href="{{ product.reorder }}" class="btn-small">重新购买</a> {% endif %} </div> </div> {% endfor %} </div> {% else %} <p>暂无商品记录</p> {% endif %} </div> <!-- 订单总计 --> {% if order.totals %} <div class="order-totals"> {% for total in order.totals %} <p>{{ total.title }}: {{ total.text }}</p> {% endfor %} </div> {% endif %} </div> {% endfor %} {% else %} <p>{{ text_no_results }}</p> {% endif %}
关键修正点:
- 在订单循环
{% for order in orders %}内部,新增商品循环{% for product in order.products %} - 添加商品图片的显示逻辑,确保图片正常加载
- 按需求展示商品名称、型号、数量、价格等信息
3. 测试验证
- 进入OpenCart后台,清除系统缓存(系统->缓存管理)
- 登录前端用户账号,访问订单历史页面,检查每个订单是否正确显示对应的所有商品及图片
内容的提问来源于stack exchange,提问作者Prosenjeet Paul
相关产品推荐
相关产品推荐

