---
url: /blog/vxcmqu16/index.md
---
# 协议添加功能开发规范

## 概述

本文档规定了在 ShopXO 系统中添加新协议功能的开发流程和规范，适用于开发人员参考。

## 功能说明

协议功能允许管理员在后台配置各类法律文档和政策条款，用户可通过前台查看。协议内容存储在系统配置中，支持富文本编辑。

## 开发步骤

### 1. 命名规范

在开始开发前，需要确定协议的唯一标识符（type），命名规则：

* **格式**: 小写字母，无下划线（示例：`register`, `privacy`, `paymentterms`）
* **建议**: 使用英文单词或词组的首字母小写驼峰（`paymentterms`）或全小写连字符（`return-exchange`）

### 2. 修改后台语言配置

**文件**: [`app/admin/lang/zh.php`](app/admin/lang/zh.php)

在 `agreement.base_nav_list` 数组中添加新协议项：

```php
'base_nav_list'    => [
    ['name' => '用户注册协议', 'type' => 'register'],
    ['name' => '用户隐私政策', 'type' => 'privacy'],
    ['name' => '账号注销协议', 'type' => 'logout'],
    ['name' => '商品退换货协议', 'type' => 'returnexchange'],
    // 在此添加新协议
    ['name' => '支付条款', 'type' => 'paymentterms'],
    ['name' => '退款政策', 'type' => 'refundpolicy'],
    ['name' => '推广佣金规则', 'type' => 'affiliatepolicy'],
],
```

**字段说明**:

* `name`: 后台导航显示名称
* `type`: 协议唯一标识符（需与配置键名后缀一致）

### 3. 创建后台编辑视图

**文件**: [`app/admin/view/default/agreement/{type}.html`](app/admin/view/default/agreement/)

创建新的视图文件，文件名与协议 type 一致。

**模板内容**:

```html
{{:ModuleInclude('public/header')}}

<!-- right content start  -->
<div class="content-right">
    <div class="content">
        <!-- nav start -->
        {{:ModuleInclude('public/nav_switch_tabs', [
            'nav_data'  => $nav_data,
            'nav_type'  => $type,
            'url'       => 'admin/agreement/index'
        ])}}
        <!-- form start -->
        <form class="am-form form-validation am-form-full-screen am-form-popup-sticky" action="{{:MyUrl('admin/agreement/save')}}" method="POST" request-type="ajax-view" request-value="{{:MyUrl('admin/agreement/index', ['type'=>$type])}}">
            <div class="nav-content">
                <!-- table tips start -->
                {{:ModuleInclude('agreement/tips')}}
                <!-- table tips end -->
                <div class="am-form-group">
                    <div class="am-flex am-flex-justify-between am-flex-items-center">
                        <label><span class="am-form-group-label-tips am-margin-left-0">{{$data.common_agreement_{type}.describe}}</span></label>
                        <a href="/api.php?s=agreement/index&document={type}" class="am-btn am-btn-primary-light-plain am-radius am-btn-xs am-border-0" target="_blank">
                            <span>{{:MyLang('agreement.view_detail_name')}}</span>
                        </a>
                    </div>
                    <textarea class="am-radius am-validate" name="{{$data.common_agreement_{type}.only_tag}}" id="editor-tag" data-validation-message="{{$data.common_agreement_{type}.error_tips}}">{{if !empty($data)}}{{$data.common_agreement_{type}.value|raw}}{{/if}}</textarea>
                </div>
            </div>
            <div class="am-form-popup-submit">
                <button type="submit" class="am-btn am-btn-primary am-radius am-btn-xs btn-loading-example" data-am-loading="{spinner: 'circle-o-notch', loadingText:'{{:MyLang('save_title')}}'}">
                    <i class="am-icon-save"></i>
                    <span>{{:MyLang('save_title')}}</span>
                </button>
            </div>
        </form>
        <!-- form end -->
    </div>
</div>
<!-- right content end  -->

<!-- footer start -->
{{:ModuleInclude('public/footer')}}
```

**替换说明**:

* 将 `{type}` 替换为实际的协议标识符（如 `paymentterms`）
* `$data.common_agreement_{type}` - 配置数据对象

### 4. 添加多语言配置

需要在所有语言文件中添加协议配置。系统支持的语言：

* [`app/lang/zh.php`](app/lang/zh.php) - 简体中文
* [`app/lang/en.php`](app/lang/en.php) - English
* [`app/lang/cht.php`](app/lang/cht.php) - 繁体中文
* [`app/lang/id.php`](app/lang/id.php) - Bahasa Indonesia
* [`app/lang/spa.php`](app/lang/spa.php) - Español

**配置格式**（以 `zh.php` 为例）:

```php
'common_agreement_{type}'  => [
    'name' => '协议显示名称',
    'desc' => '最多 105000 个字符',
    'tips' => '协议显示名称最多 105000 个字符',
],
```

**配置项说明**:

* `name`: 协议在表单中的标签名称
* `desc`: 配置项描述信息
* `tips`: 验证错误提示信息

**完整示例**:

```php
// 简体中文 (zh.php)
'common_agreement_paymentterms'  => [
    'name' => '支付条款',
    'desc' => '最多 105000 个字符',
    'tips' => '支付条款最多 105000 个字符',
],

// 英文 (en.php)
'common_agreement_paymentterms'  => [
    'name' => 'Payment Terms',
    'desc' => 'Up to 105000 characters',
    'tips' => 'Payment Terms can be 105000 characters at most',
],

// 印尼语 (id.php)
'common_agreement_paymentterms'  => [
    'name' => 'Syarat dan Ketentuan Pembayaran',
    'desc' => 'Maksimal 105000 karakter',
    'tips' => 'Syarat dan Ketentuan Pembayaran maksimal 105000 karakter',
],

// 西班牙语 (spa.php)
'common_agreement_paymentterms'  => [
    'name' => 'Términos de Pago',
    'desc' => 'Hasta 105000 caracteres',
    'tips' => 'Términos de Pago tiene un máximo de 105000 caracteres',
],

// 繁体中文 (cht.php)
'common_agreement_paymentterms'  => [
    'name' => '支付條款',
    'desc' => '最多105000個字',
    'tips' => '支付條款最多105000個字',
],
```

### 5. 更新配置服务

**文件**: [`app/service/ConfigService.php`](app/service/ConfigService.php)

需要在两个数组中添加新协议配置：

#### 5.1 不参与缓存的配置列表

```php
// 第 28 行附近
public static $not_cache_field_list = [
    'common_agreement_userregister',
    'common_agreement_userprivacy',
    'common_agreement_userlogout',
    'common_agreement_goodsreturnexchange',
    'common_agreement_paymentterms',      // 新增
    'common_agreement_refundpolicy',      // 新增
    'common_agreement_affiliatepolicy',   // 新增
];
```

#### 5.2 富文本字段列表

```php
// 第 39 行附近
public static $rich_text_list = [
    'common_agreement_userregister',
    'common_agreement_userprivacy',
    'common_agreement_userlogout',
    'common_agreement_goodsreturnexchange',
    'common_agreement_paymentterms',      // 新增
    'common_agreement_refundpolicy',      // 新增
    'common_agreement_affiliatepolicy',   // 新增
    // ... 其他富文本字段
];
```

### 6 数据库变动

```
INSERT INTO  `sxo_config` (`value`, `name`, `describe`, `error_tips`, `type`, `only_tag`, `upd_time`) VALUES ( '<p>支付条款</p>', '支付条款', '最多 105000 个字符', '支付条款最多 105000 个字符', 'common', 'common_agreement_paymentterms', 1768960086);
INSERT INTO  `sxo_config` (`value`, `name`, `describe`, `error_tips`, `type`, `only_tag`, `upd_time`) VALUES ( '<p>退款政策</p>', '退款政策', '最多 105000 个字符', '退款政策最多 105000 个字符', 'common', 'common_agreement_refundpolicy', 1768960086);
INSERT INTO  `sxo_config` (`value`, `name`, `describe`, `error_tips`, `type`, `only_tag`, `upd_time`) VALUES ( '<p>推广佣金规则</p>', '推广佣金规则', '最多 105000 个字符', '推广佣金规则最多 105000 个字符', 'common', 'common_agreement_affiliatepolicy', 1768960086);
```

## 前台访问

协议创建后，用户可通过以下 URL 访问：

```
/api.php/agreement/index?document={type}
/api.php/agreement/index?document={type}&lang={lang} //按照语言
```

**示例**:

* 商品退换货协议: `/api.php/agreement/index?document=goodsreturnexchange`

```
{
  "msg": "操作成功",
  "code": 0,
  "data": {
    "name": "商品退换货协议",
    "value": "xxxx",
    "type": "common",
    "upd_time": 1768811981,
    "upd_time_time": "2026-01-19 15:39:41"
  }
}
```

* 商品退换货协议: `/api.php/agreement/index?document=goodsreturnexchange&lang=id`

```
{
  "msg": "Operasi berhasil",
  "code": 0,
  "data": {
    "name": "Perjanjian Pengembalian Barang",
    "value": "xxxx",
    "type": "common",
    "upd_time": 1768811981,
    "upd_time_time": "2026-01-19 15:39:41"
  }
}
```

## 数据存储

协议内容存储在数据库配置表中，通过 `ConfigService` 管理：

* **配置键名格式**: `common_agreement_{type}`
* **内容类型**: 富文本 HTML
* **最大长度**: 105,000 个字符

## 参考提交

* **Commit**: `4f18df59457586ab7accf55eced94d96eb758e49`
* **描述**: feat(agreement): 新增支付条款、退款政策、推广佣金规则

## 相关文件清单

| 文件路径 | 修改类型 | 说明 |
|---------|---------|------|
| `app/admin/lang/zh.php` | 修改 | 后台导航列表 |
| `app/admin/view/default/agreement/{type}.html` | 新建 | 后台编辑视图 |
| `app/lang/zh.php` | 修改 | 简体中文配置 |
| `app/lang/en.php` | 修改 | 英文配置 |
| `app/lang/cht.php` | 修改 | 繁体中文配置 |
| `app/lang/id.php` | 修改 | 印尼语配置 |
| `app/lang/spa.php` | 修改 | 西班牙语配置 |
| `app/service/ConfigService.php` | 修改 | 配置服务 |
