# 开发 mm App 应用

## 规则（Rules）

### 1. 目录规范
- 所有 App 位于 `app/{模块名}/` 下，模块名用小写蛇形
- 一个 App 必须包含 2 个核心文件：`app.json` + `index.js`（无 app.js）
- 可选目录：`plugin/`、`pendant/`、`event_api/`、`static/`

### 2. 生命周期规范
- 生命周期方法统一写在 `module.exports = { ... }` 中

### 3. 加载顺序
- `app.json` 中 `sort` 值决定加载顺序，值越小越先加载
- 参考值：sys=10, home=10, tool=10, gateway=100, eshop=100

## 方法（Methods）

### 步骤1：创建 App 目录结构

使用 `make_dir` 创建目录。以 `myapp` 为例：

```
app/myapp/
├── app.json
├── index.js
├── plugin/          # 可选
└── event_api/       # 可选
```

### 步骤2：编写 app.json

使用 `write_text` 创建 `app/myapp/app.json`：

```json
{
    "name": "myapp",
    "version": "1.0",
    "title": "我的应用",
    "description": "应用描述",
    "author": "作者名",
    "scope": "server",
    "main": "./index.js",
    "func_name": "main",
    "sort": 50,
    "state": 1,
    "show": 0,
    "end": false
}
```

### 步骤3：编写 index.js 生命周期

使用 `write_text` 创建 `app/myapp/index.js`：

```javascript
module.exports = {
    async _install(option) {
        var msg = null;
        return msg;
    },

    async _init(option) {
        var msg = null;
        var api = $.admin.api('client', '客户端');
        await api.call('update', 'app/');
        return msg;
    },

    async _start(option) {
        var msg = null;
        return msg;
    },

    async _stop(option) {
        var msg = null;
        return msg;
    },

    async _update(option) {
        var msg = null;
        return msg;
    },

    async _destroy(option) {
        var msg = null;
        return msg;
    },

    async _uninstall(option) {
        var msg = null;
        return msg;
    },

    async _end(option) {
        var msg = null;
        return msg;
    },

    main(param1, param2) {
        var ret = null;
        return ret;
    },

    cmd(content) {
        var ret = "";
        return ret;
    },

    help(item) {
        var tip = "";
        return tip;
    }
};
```

### 步骤4：验证

1. 检查 app.json JSON 格式
2. 确认 `name` 与目录名一致
3. 确认 `main` 指向 `./index.js`
4. 设置 `state: 1`，重启服务端，观察日志确认加载成功
5. 调试时在生命周期方法内使用 `this.log('debug', '消息')` 或 `$.log.info()` 打印日志

### 步骤5：扩展功能（可选）

| 扩展方式 | 目录 |
|:--------|:-----|
| 插件 | `plugin/{插件名}/` |
| 事件 | `event_api/{client|web|manage}/` |
| 挂件 | `pendant/{挂件名}/` |

## 技巧（Tips）

- **API 注册**：`_init` 中写 `$.admin.api('名称', '标题').call('update', 'app/')` 自动注册 plugin/ 下所有 API
- **参考完整实现**：`app/sys/index.js`
- **参考简洁实现**：`app/gateway/index.js`
- **日志调试**：生命周期方法中用 `this.log('info', '消息')`
- **跨模块通信**：不同 App 间通过 Event 事件通信，不要直接 require
