=== Sixiang Canyin — 问道餐饮 · 多语言电子菜单 ===
Contributors: dadao-institute
Tags: menu, restaurant, multilingual, qrcode, polylang
Requires at least: 6.0
Tested up to: 7.1
Requires PHP: 8.0
Stable tag: 0.21.0
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Multilingual QR e-menu for restaurants: scan-to-view, no login, mobile-first, per-table location, collecting usage signals from day one.

== Description ==

Sixiang Canyin is a multilingual electronic menu for restaurants and the first, customer-facing wedge of a wider restaurant industry-chain platform. It follows a land-and-expand strategy: start from the highest-frequency, lowest-complexity, guest-facing touchpoint — the menu — deploy immediately to generate real usage, then expand outward to ordering, restaurant management, procurement matching, and healthy meal planning.

It grows on a proven CMS foundation: reusing the sxai_* table naming, behavioral tracking, Polylang multilingual support, deterministic OpenCC Simplified-to-Traditional conversion, and WP-Cron orchestration. It coexists with sixiang-ai-cms without conflict (independent sxcy_ constants, sxcy_settings option, and sxcy/v1 REST namespace).

= Three core requirements =

* **Multilingual translation**: Polylang manages fr / zh_CN / zh_TW / en; when Traditional Chinese is missing, it is derived deterministically from Simplified via a built-in OpenCC s2twp character table (zero cost, no LLM, no network).
* **Easy access**: scan a table QR to open, no login, mobile-first, lazy-loaded images, statically cacheable menu, works on weak networks; the default language is suggested from the browser's Accept-Language.
* **Table setup and location**: configure Restaurant -> Area/Room -> Table in the admin; each table gets a unique QR token (generated locally, printable/downloadable as PNG, no external request), so scanning locates the guest to a specific table context, paving the way for table-side ordering.

= Usage signals (the menu as a sensing organ) =

Dish views, language distribution, and per-table scan heat are written to sxai_behavior. They accumulate with no heavy backend, providing the earliest real basis for later personalized meal planning and selection/supply planning.

= Scope =

Read-only display plus location; ordering and payment are handled by the ordering module. No sensitive health/constitution data is collected in this stage, avoiding early GDPR-sensitive burden.

== Installation ==

1. 上传 `sixiang-canyin` 到 `/wp-content/plugins/`，或在后台上传 ZIP。
2. 激活。激活时自动建表并导入「龙城」样例菜单（4 档套餐 + 单品 + 餐馆/区域/桌台）。
3. 进入「问道餐饮」菜单：在「餐馆与桌台」为每桌打印 QR；在「设置」调整语言。
4. 客人扫码即进入免登录移动菜单；亦可用短代码 `[sxcy_menu venue="longcheng-paris"]` 内嵌进任意页面。

== Changelog ==

= 0.21.0 =
* 功能对齐 Phase 1（菜品富字段）：`GET /manage/venues/{id}/dishes` 随列表下发表单 `schema`（多语言菜名/描述、分类、价格、辣度、欧盟14类过敏原、图片）供 APP 通用渲染；新增 `GET /manage/venues/{id}/dishes/{did}` 返回可编辑原始值（多语言 map）供编辑回填。POST 沿用现有 upsert（已支持这些字段）。纯增量、向后兼容。

= 0.20.0 =
* Phase 0 使能层：握手 `GET /manage/site` 新增动态能力（`capability_version`、`can_manage_site`、`addons`{id→enabled/premium/unlocked}、`license_active`、`is_central`）供 APP 按能力/分支显隐选项卡；新增许可证端点 `GET|POST|DELETE /manage/license`；新增站点设置端点 `GET|PUT /manage/settings`（菜单语言/默认语言/后台语言，带 schema 元数据供 APP 通用渲染）。均仅管理员。纯增量、向后兼容。

= 0.19.5 =
* CORS 跨域修复：将自定义认证头 `X-SXCY-Authorization` 加入 `rest_allowed_cors_headers`，并在本插件命名空间下当核心未发 CORS 头时补发——修正手机 APP 在浏览器/PWA 内核里跨域登录本站时预检(OPTIONS)失败导致的“Failed to fetch”。（原生 Capacitor 壳走原生 HTTP，不受此限。）

= 0.19.4 =
* 握手 `GET /manage/site` 新增 `languages`（站点可用语言规范码）、`default_language`、`lang_names`——供手机 APP「界面语言随网站设置、显示跟随浏览器语言」使用。纯增量、向后兼容。

= 0.19.3 =
* 本站「餐馆菜品库」选取（供手机 APP #3）：`GET /manage/dish-library`（列出本人名下各餐馆 + 全局 venue_id=0 的既有菜品，按 slug 去重）、`POST /manage/venues/{id}/dish-copy`（把选中的既有菜品整份复制到目标餐馆，含分面/过敏原/营养/多语言）。归属守卫（来源须本人所属或全局）。

= 0.19.2 =
* 管理 REST 扩展（供手机 APP）：#5 扩展开关 `GET|POST /manage/addons`（站点级 addon，仅管理员，沿用付费门控）；#3 菜品库 `GET /manage/hub/search` + `POST /manage/venues/{id}/hub-import`（复用 SXCY_Hub_Client 检索/导入到本店）；#2 多菜单 `GET|POST /manage/venues/{id}/menus`、`DELETE .../menus/{mid}`、`GET|POST .../menus/{mid}/sections`、`DELETE .../sections/{sid}`、`POST .../sections/{sid}/items`（复用 SXCY_Layout：菜单→区块→区块内菜品，含区块字段）。全部归属守卫。

= 0.19.1 =
* Auth fallback for reverse-proxy setups that strip the HTTP Authorization header (common on nginx→Apache→PHP-FPM stacks), which otherwise breaks all Application Password auth site-wide. The phone app can now send the same credential in a custom `X-SXCY-Authorization` header (value `Basic base64(user:app_password)`); the plugin reads it (or an Authorization recovered from REDIRECT_HTTP_AUTHORIZATION / getallheaders) and authenticates the WordPress user via core's own application-password validator. Same security as standard Basic app-password auth (same credential, still HTTPS); only engages when no user is otherwise authenticated. New file includes/class-sxcy-auth.php.

= 0.19.0 =
* Membership multi-restaurant + mobile-app management API — ported forward onto the 0.18.x line (this feature first shipped in 0.17.0 but was absent from the 0.18.0–0.18.2 i18n releases). Each restaurant now has an owner (sxai_venue.owner_id); a "restaurant member" is a WordPress user holding the new sxcy_owner role and authenticates from the companion phone app via built-in Application Passwords over HTTPS. New authenticated REST surface sxcy/v1/manage/* lets a member create and run only their own venues (ownership-guarded): /manage/site handshake, public rate-limited /manage/membership/register (mints a one-time app password), /manage/me, venues CRUD + /initialize, per-venue dishes/areas/tables/QR/orders/loyalty/reports/settings/menu-preview. Free members may create 1 venue; the registration unlock lifts the cap. Added the "Restaurant Members" admin page with the registration open/closed toggle (问道餐饮 → 餐馆会员). Role registered on activate and on in-place upgrade; removed on uninstall (member accounts preserved). Built in both editions (Development full / public Release without Inner Rotor).

= 0.18.2 =
* Admin backend now available in German, Spanish and Japanese in addition to English, Français and Simplified/Traditional Chinese (seven admin locales). Choose it under Settings -> Plugin admin language. The dev-only Inner Rotor screens fall back to English. Sample brand strings finalized to "Reasoning Dining".

= 0.18.1 =
* Front-door (diner-facing) menu UI now ships in all seven Polylang-selectable languages — added German, Spanish and Japanese to the button, order-status and allergen labels (English, Français, 简体/繁體中文 already present). The menu shell now renders natively in whichever of the seven a guest picks.

= 0.18.0 =
* Completed the English admin translation (setup wizard, Extensions and Recommended Library pages, registration and environment strings — 118 new strings). Sample restaurant brand finalized to "Reasoning Dining". Two editions are now built: a public Release (Inner Rotor removed) and a Development build (full).

= 0.17.0 =
* Extension unlocking changed from a paid license key to free registration: enter the restaurant name, address, phone and email and click Register; the details are sent to the dish hub, which files the restaurant and returns an activation that unlocks the extensions and lifts the 50-dish local cap. All new output is escaped and the new strings carry translators comments, keeping Plugin Check clean.

= 0.16.3 =
* Plugin Check, third pass — cleared the last error and remaining warnings: bumped Tested up to; added an explicit version to the Google Fonts enqueue; kept load_plugin_textdomain() (required for the plugin's own admin-locale switching) with a documented ignore; prefixed the uninstall script's globals. The 400+ PrefixAllGlobals reports are view template variables that are method-local at runtime (each view is required inside a render_*() method) and the 200+ NonceVerification reports are handlers whose nonce is verified via a guard() wrapper the sniff cannot trace — both annotated as reviewed at file scope. No runtime behavior changed.

= 0.16.2 =
* Plugin Check, second pass (security warnings on verified-safe code): every $wpdb query already binds user values via $wpdb->prepare() and interpolates only prefix-derived table names — annotated the data-access classes at file scope so the DirectDB/InterpolatedNotPrepared sniffs recognize them as reviewed. All admin form input is int/float-cast or wp_unslash()+sanitized under a nonce+capability guard — scoped the two over-reporting ValidatedSanitizedInput sub-sniffs in the admin controller (NonceVerification and all other sniffs stay active). No query or handler logic changed.

= 0.16.1 =
* Plugin Check compliance pass: added `translators:` comments to every gettext call with placeholders; escaped all remaining dynamic output (esc_url/esc_html/int casts); annotated the standalone front-door document's inline stylesheet/script (no wp_head/wp_footer context); English short description and Description; refreshed Tested up to and Stable tag.

= 0.16.0 =
* Federated the recommended-dish library (sixiang-caipin-library) into the industry-chain rotor: browse and adopt recommended dishes from the hub, carrying the mandatory EU14 allergen-verification gate across sites (unverified adoptions land as drafts).

= 0.13.0 - 0.15.5 =
* Procurement demand feed and receive-quote -> purchase-order -> receiving-to-inventory mapping; P6 intrinsic rotor connected to the WEB-N.0 generative core (guard validation); freemium local-dish cap plus stepped setup wizard and paid-extension gating; assorted view parse-error and i18n fixes.

= 0.12.8 =
* **修复英文后台残留中文。** 菜品「类别（幂集层级）」下拉项（单品/套餐/团餐/服务包）、订单页「全部状态」、库存流水类型/收银方式/报表支付方式标签、若干输入框占位符、优惠券「全局/满」等此前写死中文未走翻译，现全部包 __() 并补齐英文词条。
* **样例餐馆英文名统一为 Reasoning Dining。** 种子更新（Wendao→Reasoning）；并加一次性数据迁移，把既有数据中样例品牌名（Longcheng / Wendao Dining 及其套餐名）改为 Reasoning Dining（仅替换这些明确样例串，只跑一次）。

= 0.12.7 =
* **修复：菜品表单「菜系(F3)」的区域标题（亚洲/欧洲…）在英文后台仍显示中文。** 区域名原写死取 zh_CN 元素；改用 SXCY_Facets::pick_row() 跟随后台语言（en→Asia/Europe…，fr→Asie…，zh_TW 繁化）。

= 0.12.6 =
* **统一各字段的语言解析，修复不一致。** 订单行菜名/区域名、导入配料生成的库存物品名此前用「$lang→硬编码 zh_CN」的临时回退，现统一走 SXCY_I18n::pick() 回退链（请求语言→zh_TW 由 zh_CN 繁化→缺省语言→任一）。后台各列表（餐馆/菜品/区域/类别选择器等 19 处）不再硬编码显示简体名（缺简体时曾退化为 slug），改用新助手 SXCY_I18n::display() 按「插件后台语言」显示。设置页色调/版式标签亦跟随后台语言。订单缺语言时回退缺省语言而非中文；vestigial 的 venue.default_lang 默认改 en。

= 0.12.5 =
* **修复：首屏未按浏览器语言自动选择。** 旧逻辑只要 Accept-Language 里“任意位置”出现 zh 就判中文，导致「英文/法文为主、列表里含中文」的浏览器（很常见）总被判成中文。改为按 Accept-Language 的 q 值优先级逐项匹配，尊重浏览器顺序；匹配不到再回退英语。

= 0.12.4 =
* **修复：部分主机 /wp-json/ 重写失效导致前门菜单语言切换（及下单等）全部 404。** 即便站点设了漂亮固定链接，若服务器未正确重写 /wp-json/，rest_url() 给出的地址会整体 404。前门 REST 基址改用 WP 核心无条件支持的 `?rest_route=/sxcy/v1` 形式（新增 SXCY_Menu::rest_base()），绕过 /wp-json/ 重写，任何站点都可用。经真实站点验证：语言切换恢复正常。

= 0.12.3 =
* **修复：前门菜单（含默认菜单）语言选择在「朴素固定链接」站点失效。** 该模式下 REST 基址为 site/?rest_route=/sxcy/v1，menu.js 旧代码追加 `/menu?venue=…&lang=…` 会产生第二个「?」使路由 404、语言切换请求静默失败。新增 apiUrl() 助手：REST 基址已含「?」时用「&」拼接查询串，两类固定链接均正确；/menu、/track、/voucher/check、/order 统一改走该助手。

= 0.12.2 =
* **新增前门菜单「渲染模板（版式）」层：现代 / 经典 / 中华 / 法式 / 和风。** 与色系正交组合——模板换字体族·标题装饰·分隔线·留白·圆角以呼应菜系/风格，色系换配色。中华=宋体印章方点双线；法式=衬线小型大写居中点线菜列；和风=明朝体疏朗左竖线；经典=衬线居中花饰；现代=无衬线卡片。根元素 data-template 切换，与 data-theme 自由搭配。「设置」可选默认版式（附推荐配色）+ 是否允许顾客用 🖋 切换器自选；范例（?sxcy_demo=1）内已开放版式×色系预览。新增 SXCY_Templates。
* **修复前门链接在就地升级/调试站点上不工作。** L0 表未迁移时对缺表查询会在开启 WP_DEBUG 的站点把 SQL 错误打进前门页面、破坏渲染——现全部 L0 查询加 tables_ready() 守卫，缺表时静默回退。
* 前门路由改在 template_redirect 优先级 0 接管，抢在 redirect_canonical 之前，避免 ?sxcy_v= / ?sxcy_m= 参数被规范化重定向丢弃。
* 就地升级（maybe_upgrade_db）也补发前门菜单 token。
* 概览页「前门链接」面板：嵌入「查看前门菜单范例」按钮；每店显示其默认前门菜单的专属免登录链接（未编排时提示去「前门菜单」新建）。

= 0.12.1 =
* **内置「前门菜单范例」并打包入插件**：访问 `你的站点/?sxcy_demo=1` 即得一份自包含的问道餐饮样例前门菜单——无需任何餐馆/菜品数据，用插件真实 menu.css/menu.js 渲染，四语切换、六套色调、分面徽章、欧盟过敏原三态、供应时段与下单一应俱全。「前门菜单」后台页加「查看前门菜单范例」按钮。样例载荷打包为 data/frontdoor-demo.json，始终跟随插件真实前端资源，不会过时。

= 0.12.0 =
* **重构菜品库与前门链接结构：餐馆级菜品库 → 多份独立前门菜单。** 「菜品」页更名「菜品库」（本店菜品池，可从菜品库站点导入，与菜单分离）；「菜单编排」更名「前门菜单」。
* **每份菜单 = 一个独立的免登录前门移动菜单**：sxai_menu 增列 token（唯一），每菜单自带专属链接 `?sxcy_m=<token>` 与二维码（后台「前门菜单」页展示链接+QR+短代码）。前门路由 sxcy_m 免登录直达该份精选菜单；build_payload/resolve 支持指定菜单；短代码 [sxcy_menu menu="slug"] 可内嵌指定菜单。
* dbDelta 自动加 token 列并为既有菜单补发 token（激活即迁移）。桌台扫码 ?sxcy_t 仍走默认菜单，向后兼容。

= 0.11.0 =
* **新增 L0 呈现层「菜单编排」（分层分面模型·呈现与分类分离）。** 后台新增「菜单编排」页：运营者建菜单（场景/多语言/默认）→ 自定义有序区块（多语言名、供应时段 avail_start/end、可跨午夜）→ 区块引用菜品；**同一道菜可放入多个区块**，可按区块改价。新增 3 张表 sxai_menu / sxai_menu_section / sxai_menu_item（dbDelta 自动迁移）与 SXCY_Layout。
* 电子菜单前端：配置了菜单编排则按区块呈现（区块标题 + 供应时段徽章，非供应时段自动淡化）；未配置则回退按分类分组（向后兼容）。
* **Schema.org 互操作**：全屏菜单页输出 Menu → MenuSection → MenuItem 的 JSON-LD（Offer 价格/币种、suitableForDiet、servesCuisine、区块 availabilityStarts/Ends）。
* 样例餐馆自动生成示范菜单（招牌推荐 + 全部菜品 + 午市套餐 11:00–14:00），演示一菜多区块与供应时段。

= 0.10.0 =
* **菜品分类体系升级为「分层分面模型」（正式方案 v1.0）。** 菜品表单重构为 L1–L5 分面录入：F1 膳食角色(单值)、F2 主食材、F3 菜系(区域树·支持融合)、F5 烹饪方式、F6 温度、F7 辣度；**F8 欧盟 14 类过敏原三态强制声明网格**（不含/可能含有/含有）；F9 膳食适宜、F10 宗教伦理、F11 成分标志；F12 营养。
* 代码优先 + 本地化标签：分面以稳定 code 存储，前端按菜单语言渲染标签（新增 SXCY_Facets 受控词表）。sxai_dish 增列 role_code/temp_code/facets_json/allergen_states_json/nutrition_json（dbDelta 自动迁移，旧过敏原清单自动升级为三态）。
* 电子菜单前端新增膳食适宜/菜系徽章与过敏原三态呈现（「含有」法定醒目、「可能含有」弱化）。
* 联邦：菜品库导入/贡献均携带完整分面。

= 0.9.6 =
* **电子菜单语言选择改为下拉菜单（<select>）。** 仅一种语言时不显示选择器。
* **首屏语言权威解析**：由 build_payload 依据顾客浏览器 Accept-Language，在“菜单实际具备的语种”（内容驱动并集）中匹配；匹配不到回退英语。suggest_language 增加候选集参数，render_full_page/shortcode/REST 统一改由 build_payload 解析，避免内容语言（如仅菜品含有的语种）被漏配。

= 0.9.5 =
* **修复：后台语言设为英语时仍显示中文。** 补齐英文翻译目录 languages/sixiang-canyin-en_US.mo（447 条后台词条全译），并在 init 调用 load_plugin_textdomain 实际加载；配合已有 plugin_locale 过滤器，「设置 → 插件后台语言」选 English 即整套后台切英文。

= 0.9.4 =
* **缺省语言默认改为英语。** 新增 SXCY_I18n::default_language()（默认 en，可在「设置」更改），缺翻回退、菜单语言守卫、最终兜底全部走它，不再硬编码 zh_CN。
* 电子菜单首屏仍自动依据顾客浏览器语言（suggest_language 解析 Accept-Language），仅当无法匹配时回退到缺省英语。
* 某菜品/词条缺某语言翻译时，显示为缺省语言（英语）。

= 0.9.3 =
* **修复：电子菜单语言切换按钮无效。** 顾客端语言选择改为**内容驱动**——凡菜品数据中实际含有的语言都会出现在切换栏，与站点配置语言取并集。此前语言列表仅由 Polylang/设置决定，当 Polylang 只启用一种语言时切换栏塌缩为一个、且切换请求会被打回默认语言。新增 SXCY_I18n::menu_languages()（按 zh_CN/zh_TW/en/fr 优先排序），build_payload 提前取菜品并据此构建语言栏与语言守卫。

= 0.9.2 =
* 品牌更名为「问道餐饮」（开发者/插件名/菜单品牌/后台菜单等全部用户可见处），示例餐馆由「龙城」改为「问道餐饮」（套餐同步为「问道套餐」）。
* 示例菜品/餐馆/区域补齐繁体中文（zh_TW，由 s2twp 确定性繁化）。

= 0.9.1 =
* **修复菜品库连接**（多路加固）：URL 缺协议自动补 https；search/fetch/contribute 全部关闭 SSL 校验（兼容本地/自签证书，此前只有 discover 关了）；同站判定去 www. 前缀更宽松；异站发现依次尝试 发现指针→REST 伪静态(/wp-json)→REST 朴素(?rest_route=)，朴素固定链接也能连。
* 「菜品库导入」新增**连接诊断**面板：显示主机比对、连接方式（进程内/HTTP/REST 朴素）、发现与检索测试结果、具体错误与排查建议；换库自动清缓存。

= 0.9.0 =
* **P4 食材/耗材交易撮合（里程碑一）**：打通架构旋机相生边 水→木（供应→生产）。
  * 供应商：登记资质/供应种类/交期/评分 + 逐物品报价（sxai_supplier / sxai_supplier_item）。
  * 撮合引擎（太阳·WP-Cron 每日）：据 P3 真实消耗（消耗流水）测算补货需求（日均×(交期+覆盖)−库存，低于阈值强制补），为每项撮合价优/评分高的供应商，生成撮合清单——无需手工假消耗。
  * 采购闭环：一键据撮合生成采购单（sxai_purchase_order/_item），发送→收货，**收货即入库回补库存与移动加权成本**。
  * 后台「供应商」「采购撮合」页；设置新增撮合参数（回看/覆盖/提前期）。

= 0.8.0 =
* **配料表接入 → 点菜自动扣库存全自动化**：从菜品库导入菜品时，可一并拉取其配料表；把菜品库食材**映射/自动新建**为本店库存物品（按 hub_slug 关联，缺则建，成本默认 0 待补），并建立本地配料表。之后点菜结账即按配方自动扣库存（消耗回填，接 P3）。
* sxai_item 加 hub_slug 列；新增 SXCY_Inventory::import_recipe / get_item_by_hub_slug；同站本地 fetch 也带 recipe。
* 设置与导入页新增「导入配料表」开关；导入结果回报映射条数与新建物品数。

= 0.7.0 =
* **前端 UI 全面可翻译**：把所有面向客人的界面文案（菜单外壳、点餐、结算、订单状态、过敏原标签、按钮/提示）集中到服务端注册表 class-sxcy-menu-strings.php，按菜单语言随 payload 下发；前端 JS 不再内置文案。
* 未内置语言自动回退英文，且缺 zh_TW 词条由 s2twp 从简体繁化；提供 `sxcy_menu_ui`/`sxcy_menu_statuses`/`sxcy_menu_allergens` 过滤器，可为任意语言补充翻译而无需改代码。
* 修复深色/新语言下按钮文案回退中文的问题；品牌页脚、色调按钮等剩余硬编码文案一并纳入翻译。

= 0.6.0 =
* **语言框架重构（Polylang 驱动 + 菜品库采纳）**：语言不再固定四语，改由 Polylang 设置动态决定（母语名自动取自 Polylang）；未装 Polylang 时可在设置里从常见语言中勾选。语言码规范化（en_US→en，zh 保留简繁）。
* 菜品/餐馆/菜单的多语言字段随可用语言动态增减。
* 从「菜品库导入」时**自动采纳菜品库的语言种类**（并入本店菜单语言），修复导入语言不显示。
* **修复菜品导入无法连接**：菜品库与餐馆同站时走进程内直连（绕过回环 HTTP/SSL）；异站发现指针不可达时回退 REST /health 探测并合成端点；错误信息更明确。

= 0.5.0 =
* **P3 餐馆信息管理（里程碑二）**：存在侧良基记账全流程。
  * 收银结账：订单一键结账（现金/刷卡/第三方/券/会员储值），支付平台不代收；结账即触发库存消耗回填并计入报表。
  * 库存管理：物品(食材/耗材/设备)、入库/出货/盘盈/报损流水、报警阈值、移动加权成本；菜品配料表→点菜后按配方自动核减（消耗流即 P4 撮合的真实输入）。
  * 会员(贵宾)：分级/储值/积分/累计消费；结账绑会员自动记账升级、储值支付扣减。
  * 销售报表：营业额/单量/客单价、单品排行、按日、时段分布、支付方式分布（日/月/年区间）。
  * 财务报表：营业额、COGS、毛利/毛利率、服务费、优惠、采购应付、库存现值。
  * 实时桌台图：按区域展示桌台状态（空闲/占用/预留），占用桌显示当前订单；下单占用、结账释放。
  * 新表 sxai_item / sxai_stock_ledger / sxai_dish_ingredient / sxai_member；订单加结算字段。

= 0.4.0 =
* **P2 在线点餐**：菜单从展示升级为交易入口。
  * 扫码点餐：菜品/套餐「加入」→ 悬浮购物车 → 结算浮层；购物车按桌台持久化到本机。
  * 口味/忌口：每行可选辣度偏好 + 忌口 + 备注；整单可填人数、预约时间、备注。
  * 优惠策略：服务费（设置层百分比）+ 代金券（券码校验、百分比/定额、最低消费、有效期、次数）。
  * 订单实体 sxai_order + sxai_order_item + sxai_voucher；服务端权威定价，绝不信任前端金额。
  * 桌台定位归属订单；下单成功回执（订单号/状态/明细/合计）。支付走到店/线下或第三方，平台不代收款。
  * 订餐套餐/预订：可填预约时间，系统据「变更提前时限」算出可改截止，客人可在时限内自助改人数/时间（REST /order/{no}/modify）。
  * 后台新增「订单」（列表+明细+状态流转 待确认→已确认→制作中→已上菜→完成/取消）与「优惠券」管理；太阴新增加购/结算/下单信号。

= 0.3.1 =
* 新增**运行环境自检**：安装后检查 PHP≥8.0 / mbstring / json / 数据表等硬性依赖，缺失即在全后台顶部给出清晰的「需安装/需修复」提示；Polylang 多语言与菜品库联邦作为可选增强给出指引。「概览」新增「运行环境自检」面板逐项 ✓/⚠/❌。

= 0.3.0 =
* 新增**菜品库联邦**（解决菜品录入难题）：与「菜品数据库站点」sixiang-caipin-ku 联邦互通。
  * 「设置」填入菜品库站点 URL → 自动发现（/.well-known/canyin-dish-hub）。
  * 新增「菜品库导入」页：检索公共菜品库 → 勾选 → 一键导入到本店菜单（免逐条录入；缺失繁体由 s2twp 派生）。
  * 「菜品」列表新增「贡献」：把本地菜品贡献回菜品库（经库端审核）。
* 新增 `class-sxcy-hub-client.php`（发现/检索/读取/贡献 + 信封↔本地映射）。沿 WEB-N.0 / sxai-fed 联邦约定。

= 0.2.0 =
* 新增电子菜单**色调方案**：六套固定品牌调色板（中国红 / 水墨 / 青瓷 / 鎏金 / 暖橘 / 石墨），覆盖餐饮网站设计的通行配色家族。运营者在「设置」选默认色调（可视色片预览）；可选开启顾客端 🎨 切换器（顾客自选并记忆到本机 localStorage）。
* 菜单 CSS 全量令牌化（新增 header 前景色与过敏原标签令牌）；色调经根元素 data-theme 切换，弱网首屏即生效。

= 0.1.0 =
* 首个版本：P0 精简地基（sxai_dish / venue / area / table / behavior 建表 + 龙城种子）+ P1 多语言电子菜单（扫码即达、四语切换、桌台定位、每桌本地 QR、太阴埋点、REST sxcy/v1）。
* 自包含 QR 生成器（byte 模式 · 纠错级别 M · 版本 1–10），已对标成熟库逐位校验通过。
* 确定性 OpenCC s2twp 繁化字表（覆盖菜单域 + 常用字）。
