Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b0a74f3607 | |||
| 543bd2712f | |||
| fab7bd21dd | |||
| 3b2ebc0202 | |||
| ff32c8a845 | |||
| af64e29459 |
@@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [1.0.26] - 2026-06-08
|
||||
|
||||
### 新功能
|
||||
- 公开商品 API 新增商品编码、条码、当前库存数量字段,供扫码页及第三方集成使用
|
||||
- 公开页「商品报错」「意见反馈」提交时自动携带门店编号和商品信息,方便运营追踪
|
||||
|
||||
### 修复
|
||||
- 注册页 API 地址改为配置文件驱动,支持分离部署场景(不再依赖 window.location.origin)
|
||||
- 注册成功提示的客户端导航路径由「系统设置 → 关于」修正为「系统设置」
|
||||
- 公开页页脚「关于岩美」链接改为配置项,不再硬编码
|
||||
|
||||
## [1.0.25] - 2026-06-08
|
||||
|
||||
### 新功能
|
||||
|
||||
@@ -17,16 +17,17 @@ func NewErrorReportHandler(db *gorm.DB) *ErrorReportHandler {
|
||||
}
|
||||
|
||||
type submitErrorRequest struct {
|
||||
ErrorType string `json:"error_type" binding:"required"`
|
||||
AppVersion string `json:"app_version"`
|
||||
Platform string `json:"platform"`
|
||||
Username string `json:"username"`
|
||||
ShopID uint64 `json:"shop_id"`
|
||||
ShopNo string `json:"shop_no"`
|
||||
Role string `json:"role"`
|
||||
ErrorMsg string `json:"error_msg" binding:"required"`
|
||||
StackTrace string `json:"stack_trace"`
|
||||
OccurredAt int64 `json:"occurred_at"` // Unix 毫秒
|
||||
ErrorType string `json:"error_type" binding:"required"`
|
||||
AppVersion string `json:"app_version"`
|
||||
Platform string `json:"platform"`
|
||||
Username string `json:"username"`
|
||||
ShopID uint64 `json:"shop_id"`
|
||||
ShopNo string `json:"shop_no"`
|
||||
Role string `json:"role"`
|
||||
ProductInfo string `json:"product_info"`
|
||||
ErrorMsg string `json:"error_msg" binding:"required"`
|
||||
StackTrace string `json:"stack_trace"`
|
||||
OccurredAt int64 `json:"occurred_at"` // Unix 毫秒
|
||||
}
|
||||
|
||||
// Submit POST /api/v1/public/errors
|
||||
@@ -49,17 +50,18 @@ func (h *ErrorReportHandler) Submit(c *gin.Context) {
|
||||
}
|
||||
|
||||
report := model.ErrorReport{
|
||||
ErrorType: req.ErrorType,
|
||||
AppVersion: req.AppVersion,
|
||||
Platform: req.Platform,
|
||||
Username: req.Username,
|
||||
ShopID: req.ShopID,
|
||||
ShopNo: req.ShopNo,
|
||||
Role: req.Role,
|
||||
ClientIP: c.ClientIP(),
|
||||
ErrorMsg: req.ErrorMsg,
|
||||
StackTrace: stack,
|
||||
OccurredAt: occurredAt,
|
||||
ErrorType: req.ErrorType,
|
||||
AppVersion: req.AppVersion,
|
||||
Platform: req.Platform,
|
||||
Username: req.Username,
|
||||
ShopID: req.ShopID,
|
||||
ShopNo: req.ShopNo,
|
||||
Role: req.Role,
|
||||
ProductInfo: req.ProductInfo,
|
||||
ClientIP: c.ClientIP(),
|
||||
ErrorMsg: req.ErrorMsg,
|
||||
StackTrace: stack,
|
||||
OccurredAt: occurredAt,
|
||||
}
|
||||
|
||||
if err := h.db.Create(&report).Error; err != nil {
|
||||
|
||||
@@ -72,6 +72,7 @@ func (h *PublicHandler) GetProduct(c *gin.Context) {
|
||||
"production_date": pdStr,
|
||||
"batch_no": inv.BatchNo,
|
||||
"in_stock_date": inv.CreatedAt.Format("2006-01-02"),
|
||||
"quantity": inv.Quantity,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,6 +101,8 @@ func (h *PublicHandler) GetProduct(c *gin.Context) {
|
||||
"data": gin.H{
|
||||
"id": product.ID,
|
||||
"name": product.Name,
|
||||
"code": product.Code,
|
||||
"barcode": product.Barcode,
|
||||
"series": product.Series,
|
||||
"spec": product.Spec,
|
||||
"brand": product.Brand,
|
||||
|
||||
@@ -12,8 +12,9 @@ type ErrorReport struct {
|
||||
Username string `gorm:"size:50;index" json:"username"`
|
||||
ShopID uint64 `gorm:"index" json:"shop_id"`
|
||||
ShopNo string `gorm:"size:50" json:"shop_no"`
|
||||
Role string `gorm:"size:20" json:"role"`
|
||||
ClientIP string `gorm:"size:60" json:"client_ip"`
|
||||
Role string `gorm:"size:20" json:"role"`
|
||||
ProductInfo string `gorm:"size:200" json:"product_info"`
|
||||
ClientIP string `gorm:"size:60" json:"client_ip"`
|
||||
ErrorMsg string `gorm:"type:text;not null" json:"error_msg"`
|
||||
StackTrace string `gorm:"type:text" json:"stack_trace"`
|
||||
OccurredAt time.Time `json:"occurred_at"`
|
||||
|
||||
@@ -34,6 +34,11 @@ class AppConfig {
|
||||
defaultValue: '',
|
||||
);
|
||||
|
||||
static const aboutUrl = String.fromEnvironment(
|
||||
'ABOUT_URL',
|
||||
defaultValue: 'https://jiu.51yanmei.com',
|
||||
);
|
||||
|
||||
static String get baseUrl => _baseUrl;
|
||||
static String get apiBaseUrl => '$_baseUrl/api/v1';
|
||||
static String get healthUrl => '$_baseUrl/health';
|
||||
|
||||
@@ -70,13 +70,22 @@ class _PublicProductScreenState extends State<PublicProductScreen> {
|
||||
title: title,
|
||||
hint: hint,
|
||||
onSubmit: (msg) async {
|
||||
final shopNo = (_data?['shop'] as Map<String, dynamic>?)?['code'] as String? ?? '';
|
||||
final productName = _data?['name'] as String? ?? '';
|
||||
final productCode = _data?['code'] as String? ?? '';
|
||||
final productInfo = [
|
||||
if (productName.isNotEmpty) productName,
|
||||
if (productCode.isNotEmpty) productCode,
|
||||
if (widget.publicId.isNotEmpty) widget.publicId,
|
||||
].join(' / ');
|
||||
await _dio.post(
|
||||
'${AppConfig.apiBaseUrl}/public/errors',
|
||||
data: {
|
||||
'error_type': errorType,
|
||||
'error_msg': msg,
|
||||
'platform': 'web-scan',
|
||||
'shop_no': (_data?['shop'] as Map<String, dynamic>?)?['code'] as String? ?? '',
|
||||
'shop_no': shopNo,
|
||||
if (productInfo.isNotEmpty) 'product_info': productInfo,
|
||||
},
|
||||
);
|
||||
},
|
||||
@@ -1484,7 +1493,7 @@ class _Footer extends StatelessWidget {
|
||||
const _FooterDivider(),
|
||||
_FooterTextLink(text: '意见反馈', onTap: onFeedback),
|
||||
const _FooterDivider(),
|
||||
_FooterTextLink(text: '关于岩美', url: 'https://www.yanmei.com'),
|
||||
_FooterTextLink(text: '关于岩美', url: AppConfig.aboutUrl),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
||||
+68
-68
@@ -102,8 +102,8 @@ ul.todo-list { list-style: none; margin: 0; padding: 0; }
|
||||
<div class="header-meta">生成于 2026-06-08 · 真相源 todo/todo.json</div>
|
||||
<div class="stats">
|
||||
<div class="stat-pill"><strong>15</strong>全部</div>
|
||||
<div class="stat-pill"><strong>5</strong>未完成</div>
|
||||
<div class="stat-pill"><strong>10</strong>已完成</div>
|
||||
<div class="stat-pill"><strong>1</strong>未完成</div>
|
||||
<div class="stat-pill"><strong>14</strong>已完成</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
@@ -132,7 +132,7 @@ ul.todo-list { list-style: none; margin: 0; padding: 0; }
|
||||
|
||||
<div class="wrap">
|
||||
|
||||
<div class="section-title">📋 未完成(5)</div>
|
||||
<div class="section-title">📋 未完成(1)</div>
|
||||
<ul class="todo-list" id="pendingList">
|
||||
|
||||
<li class="todo-card"
|
||||
@@ -153,69 +153,18 @@ ul.todo-list { list-style: none; margin: 0; padding: 0; }
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<li class="todo-card"
|
||||
data-id="3"
|
||||
data-level="low"
|
||||
data-tags="前端,Web"
|
||||
data-done="0">
|
||||
<div class="card-header">
|
||||
<span class="item-title">注册接口同源依赖问题</span>
|
||||
<span class="tag t-low">一般 / 优化</span>
|
||||
</div>
|
||||
<div class="item-desc">用 window.location.origin+'/api/v1/public/register',要求同源部署;分离部署时指错。需确认部署形态。</div>
|
||||
<div class="card-footer">
|
||||
<div class="tag-row"><span class="tag t-tag" data-tag="前端">前端</span> <span class="tag t-tag" data-tag="Web">Web</span></div>
|
||||
<div class="item-meta">
|
||||
<span class="meta-date">🕐 2026-06-08</span>
|
||||
<div class="done-section">
|
||||
<div class="section-title done-title">✅ 已完成(14)</div>
|
||||
<button class="done-toggle" id="doneToggle">▾ 展开已完成列表</button>
|
||||
<ul class="todo-list hidden" id="doneList">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="todo-card"
|
||||
data-id="5"
|
||||
data-level="low"
|
||||
data-tags="前端,Web"
|
||||
data-done="0">
|
||||
<div class="card-header">
|
||||
<span class="item-title">页脚双份维护</span>
|
||||
<span class="tag t-low">一般 / 优化</span>
|
||||
</div>
|
||||
<div class="item-desc">njk 站点用 footer.njk 读变量,功能页把页脚硬编码各写一份,改一处不同步。根因同「两套模板」。</div>
|
||||
<div class="card-footer">
|
||||
<div class="tag-row"><span class="tag t-tag" data-tag="前端">前端</span> <span class="tag t-tag" data-tag="Web">Web</span></div>
|
||||
<div class="item-meta">
|
||||
<span class="meta-date">🕐 2026-06-08</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="todo-card"
|
||||
data-id="6"
|
||||
data-level="low"
|
||||
data-tags="前端,Web"
|
||||
data-done="0">
|
||||
<div class="card-header">
|
||||
<span class="item-title">注册成功提示路径需核对</span>
|
||||
<span class="tag t-low">一般 / 优化</span>
|
||||
</div>
|
||||
<div class="item-desc">提示「忘记门店编码可在「系统设置→关于」查看」,需与实际客户端菜单路径一致。</div>
|
||||
<div class="card-footer">
|
||||
<div class="tag-row"><span class="tag t-tag" data-tag="前端">前端</span> <span class="tag t-tag" data-tag="Web">Web</span></div>
|
||||
<div class="item-meta">
|
||||
<span class="meta-date">🕐 2026-06-08</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="todo-card"
|
||||
<li class="todo-card done"
|
||||
data-id="13"
|
||||
data-level="low"
|
||||
data-tags="后端,iOS,Android"
|
||||
data-done="0">
|
||||
data-done="1">
|
||||
<div class="card-header">
|
||||
<span class="item-title">公开商品 API 补充 batch.quantity 和 product code/barcode</span>
|
||||
<span class="tag t-low">一般 / 优化</span>
|
||||
@@ -225,17 +174,68 @@ ul.todo-list { list-style: none; margin: 0; padding: 0; }
|
||||
<div class="tag-row"><span class="tag t-tag" data-tag="后端">后端</span> <span class="tag t-tag" data-tag="iOS">iOS</span> <span class="tag t-tag" data-tag="Android">Android</span></div>
|
||||
<div class="item-meta">
|
||||
<span class="meta-date">🕐 2026-06-08</span>
|
||||
|
||||
<span class="meta-date">✅ 完成 2026-06-08 · <span class="ver-badge">v1.0.25</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="todo-card done"
|
||||
data-id="6"
|
||||
data-level="low"
|
||||
data-tags="前端,Web"
|
||||
data-done="1">
|
||||
<div class="card-header">
|
||||
<span class="item-title">注册成功提示路径需核对</span>
|
||||
<span class="tag t-low">一般 / 优化</span>
|
||||
</div>
|
||||
<div class="item-desc">提示「忘记门店编码可在「系统设置→关于」查看」,需与实际客户端菜单路径一致。</div>
|
||||
<div class="card-footer">
|
||||
<div class="tag-row"><span class="tag t-tag" data-tag="前端">前端</span> <span class="tag t-tag" data-tag="Web">Web</span></div>
|
||||
<div class="item-meta">
|
||||
<span class="meta-date">🕐 2026-06-08</span>
|
||||
<span class="meta-date">✅ 完成 2026-06-08 · <span class="ver-badge">v1.0.25</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="todo-card done"
|
||||
data-id="5"
|
||||
data-level="low"
|
||||
data-tags="前端,Web"
|
||||
data-done="1">
|
||||
<div class="card-header">
|
||||
<span class="item-title">页脚双份维护</span>
|
||||
<span class="tag t-low">一般 / 优化</span>
|
||||
</div>
|
||||
<div class="item-desc">njk 站点用 footer.njk 读变量,功能页把页脚硬编码各写一份,改一处不同步。根因同「两套模板」。</div>
|
||||
<div class="card-footer">
|
||||
<div class="tag-row"><span class="tag t-tag" data-tag="前端">前端</span> <span class="tag t-tag" data-tag="Web">Web</span></div>
|
||||
<div class="item-meta">
|
||||
<span class="meta-date">🕐 2026-06-08</span>
|
||||
<span class="meta-date">✅ 完成 2026-06-08 · <span class="ver-badge">v1.0.25</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="todo-card done"
|
||||
data-id="3"
|
||||
data-level="low"
|
||||
data-tags="前端,Web"
|
||||
data-done="1">
|
||||
<div class="card-header">
|
||||
<span class="item-title">注册接口同源依赖问题</span>
|
||||
<span class="tag t-low">一般 / 优化</span>
|
||||
</div>
|
||||
<div class="item-desc">用 window.location.origin+'/api/v1/public/register',要求同源部署;分离部署时指错。需确认部署形态。</div>
|
||||
<div class="card-footer">
|
||||
<div class="tag-row"><span class="tag t-tag" data-tag="前端">前端</span> <span class="tag t-tag" data-tag="Web">Web</span></div>
|
||||
<div class="item-meta">
|
||||
<span class="meta-date">🕐 2026-06-08</span>
|
||||
<span class="meta-date">✅ 完成 2026-06-08 · <span class="ver-badge">v1.0.25</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="done-section">
|
||||
<div class="section-title done-title">✅ 已完成(10)</div>
|
||||
<button class="done-toggle" id="doneToggle">▾ 展开已完成列表</button>
|
||||
<ul class="todo-list hidden" id="doneList">
|
||||
|
||||
<li class="todo-card done"
|
||||
data-id="18"
|
||||
data-level="low"
|
||||
|
||||
+13
-13
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "酒库管理系统 — 项目 TODO",
|
||||
"updated_at": "2026-06-08T00:06:15.371Z"
|
||||
"updated_at": "2026-06-08T14:40:04.464Z"
|
||||
},
|
||||
"seq": 18,
|
||||
"items": [
|
||||
@@ -42,9 +42,9 @@
|
||||
"Web"
|
||||
],
|
||||
"created_at": "2026-06-07T17:30:32.237Z",
|
||||
"done": false,
|
||||
"completed_at": null,
|
||||
"version": null
|
||||
"done": true,
|
||||
"completed_at": "2026-06-08T14:33:22.523Z",
|
||||
"version": "v1.0.25"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
@@ -70,9 +70,9 @@
|
||||
"Web"
|
||||
],
|
||||
"created_at": "2026-06-07T17:30:32.334Z",
|
||||
"done": false,
|
||||
"completed_at": null,
|
||||
"version": null
|
||||
"done": true,
|
||||
"completed_at": "2026-06-08T14:33:22.584Z",
|
||||
"version": "v1.0.25"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
@@ -84,9 +84,9 @@
|
||||
"Web"
|
||||
],
|
||||
"created_at": "2026-06-07T17:30:32.381Z",
|
||||
"done": false,
|
||||
"completed_at": null,
|
||||
"version": null
|
||||
"done": true,
|
||||
"completed_at": "2026-06-08T14:33:22.648Z",
|
||||
"version": "v1.0.25"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
@@ -145,9 +145,9 @@
|
||||
"Android"
|
||||
],
|
||||
"created_at": "2026-06-07T18:12:43.136Z",
|
||||
"done": false,
|
||||
"completed_at": null,
|
||||
"version": null
|
||||
"done": true,
|
||||
"completed_at": "2026-06-08T14:40:04.464Z",
|
||||
"version": "v1.0.25"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
|
||||
+2
-2
@@ -161,7 +161,7 @@ pageStyle: |
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<p class="success-note">如忘记门店编码,登录后可在「系统设置 → 关于」中查看。</p>
|
||||
<p class="success-note">如忘记门店编码,登录后可在「系统设置」中查看。</p>
|
||||
<a href="/app/" class="btn btn-primary" style="display:inline-flex;align-items:center;gap:8px;">
|
||||
<i data-lucide="log-in" class="icon"></i>前往登录
|
||||
</a>
|
||||
@@ -172,7 +172,7 @@ pageStyle: |
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var API_URL = window.location.origin + '/api/v1/public/register';
|
||||
var API_URL = "{{ site.appBaseUrl }}/api/v1/public/register";
|
||||
|
||||
function $(id) { return document.getElementById(id); }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user