__DIR__ . '/data/feedback.db', 'site_name' => '轻反馈', 'site_desc' => '欢迎在这里反馈使用问题、提出功能建议。任何人都可以提问与回复,无需注册;只需填写昵称与邮箱。', // 展示用的官方邮箱(可留空) 'admin_email' => 'support@example.com', // 站点根地址(用于邮件正文里的链接)。留空则按访问域名自动探测。 // 例如:'https://feedback.example.com' 'base_url' => '', /* ---------------- 安全 ---------------- */ // 管理员口令:在"回复"表单里填入它,即以「官方」身份回复(高亮显示),并触发邮件通知。 // ★★ 请务必修改! ★★ 'admin_password' => 'CHANGE_ME_admin', // API 令牌:供自动化脚本 / AI 读取数据用。★ 请务必修改 ★ 'api_token' => 'CHANGE_ME_api_token', // 对访客 IP 做加盐哈希(数据库只保存哈希,不保存明文 IP)。★ 请修改为随机值 ★ 'ip_salt' => 'CHANGE_ME_random_salt', /* ---------------- 问题分类 ---------------- */ 'categories' => [ 'usage' => '使用问题', 'bug' => 'Bug 反馈', 'feature' => '功能建议', 'sync' => '同步问题', 'other' => '其他', ], /* ---------------- 处理状态 ---------------- */ 'statuses' => [ 'open' => '待处理', 'doing' => '处理中', 'resolved' => '已解决', 'closed' => '已关闭', ], /* ---------------- 邮件通知(SMTP) ---------------- */ 'smtp' => [ 'enabled' => false, // 填好下面参数后改为 true 才会真正发信 'host' => 'smtp.example.com', // 如 smtp.qiye.aliyun.com / smtp.exmail.qq.com 'port' => 465, 'secure' => 'ssl', // ssl(465)| tls(587 STARTTLS)| ''(25 不加密) 'user' => 'noreply@example.com', 'pass' => '', // 邮箱密码或"授权码" 'from' => 'noreply@example.com', // 发件地址(通常与 user 相同) 'from_name' => '轻反馈', 'timeout' => 15, 'verify_ssl' => true, // 若服务器缺少 CA 证书可临时设为 false ], // 通知策略 'notify' => [ 'enabled' => true, // 回复时是否尝试发送通知邮件 'on_every_reply' => true, // true=任何人回复都通知发帖人;false=仅"官方"回复才通知 'cooldown_seconds' => 300, // 同一帖同一收件人的通知节流(秒) ], /* ---------------- 审核(先审后显) ---------------- * enabled = true:新提交的问题默认**不公开**,由管理员在 admin.php 审核; * · 通过 → 公开显示(visible=1) * · 关闭 → 判定"不是应用的问题",保持不公开,并把管理员填写的说明邮件发给提问人 * 审核后台入口:/feedback/admin.php(口令= admin_password) */ 'moderation' => [ 'enabled' => true, 'close_mail_subject' => '关于你反馈的问题《%s》', // %s 会替换成问题标题 ], /* ---------------- 附件上传(阿里云 OSS · 服务器代理) ---------------- * ★ 架构:私有桶 + 内网 Endpoint,读写全部经服务器代理 * 桶设为【私有】、且只用【内网 Endpoint】(*-internal.aliyuncs.com,仅同地域 ECS 可达), * 浏览器既不直传、也不直连。数据流: * 上传:浏览器 → upload.php → 服务器 PUT 到内网 OSS * 读取:浏览器 → media.php → 服务器 GET 内网 OSS 并流式转发(支持 Range) * 好处:桶可彻底私有、公网完全看不到 Endpoint、AccessKey 永不出服务器。 * 代价:附件流量经过服务器(占带宽),需保证服务器磁盘临时空间够放单个上传文件。 * * ★ 凭证方式:ECS 实例 RAM 角色(推荐,服务器上不保存长期 AccessKey)或静态 AccessKey。 * 实例角色下,程序从内网元数据服务(http://100.100.100.200,链路本地、不出公网) * 读取一份「有时效、会自动轮换」的临时凭证来签名。AccessKey 永不落盘、永不进本文件。 * * ★ 开通步骤(详见 README.md): * ① 创建【与 ECS 同地域】的 Bucket,读写权限设为「私有」 * ⚠️ 内网 Endpoint 跨地域不通!ECS 在哪个地域,桶就建在哪个地域。 * ② RAM 建权限策略:只授予该 Bucket(某前缀下)的 oss:PutObject / GetObject / DeleteObject * ③ RAM 建角色(如 FeedLiteOssRole)并赋予上一步的策略 * ④ ECS 控制台把该角色【授予本实例】 * ⑤ 把 endpoint / bucket / instance_role 填到下面,use_internal_endpoint 保持 true,enabled = true * ⑥ 后台「站点设置 → 存储体检」确认桶连通性为 ✅ * (代理架构下【不需要】配置 CORS,也【不需要】绑定自定义域名) * * ★ 前提:站点必须运行在【阿里云 ECS】上并且已绑定 RAM 角色; * 未绑定则取不到凭证,上传接口会明确报错(其它功能不受影响)。 */ 'oss' => [ 'enabled' => false, // 填好参数后改为 true 才启用上传 'endpoint' => 'oss-cn-qingdao.aliyuncs.com', // 不含 http://;填公网或内网均可,程序按下方开关自动转换 'bucket' => 'your-bucket-name', // ★ ECS 实例 RAM 角色名 —— 必须与【ECS 实例实际绑定的角色名】逐字一致。 // 查法:curl http://100.100.100.200/latest/meta-data/ram/security-credentials/ // 注意:RAM 里"创建的角色名"和"授予实例后实例上生效的角色名"可能不同(如 // 建的是 MyOssRole,授予实例后生效名可能是系统预置策略对应的角色),以查询结果为准。 'instance_role' => '', // ★ 是否用内网 Endpoint(默认开)。开启后程序自动把 endpoint 改写成 *-internal 形式, // 走阿里云内网访问 OSS:免公网流量费、延迟更低,且公网完全无法直连该地址。 // ⚠️ 仅当【桶与本机 ECS 同地域】时可用;跨地域时内网不可达,必须关掉本开关 // (回落公网 Endpoint)或改用同地域的桶。后台「存储体检」会探测并提示。 'use_internal_endpoint' => true, // ---- 以下一般不用改 ---- 'metadata_url' => '', // 留空=http://100.100.100.200(ECS 内网元数据服务) 'metadata_v2' => false, // true=加固模式(先取一次性 token 再读元数据,防 SSRF 探测) 'metadata_ttl' => 600, // 加固模式 token 有效期(秒,最长 21600) 'credential_cache' => '', // 凭证缓存文件;留空=与数据库同目录的 oss.sts.php 'credential_refresh_margin' => 300, // 到期前多少秒就提前换新(秒) 'domain' => '', // 代理架构下【不再使用】:附件一律经本站 media.php 输出,无需自定义域名 'url_scheme' => 'https', // 公网 Endpoint 时使用的协议(内网 Endpoint 强制走 http) 'prefix' => 'fb', // 对象键前缀:fb/2026/09/xxxxxxxx.jpg 'visibility' => 'private', // 记录桶的读写权限:代理架构下推荐 private(浏览器永不直连桶) 'sign_ttl' => 600, // 服务器内部签名 URL 的有效期(秒),仅服务器侧使用 'link_ttl' => 604800, // 兼容保留;代理读取时签名有效期由代码收敛到 ≤300 秒 'image_process' => true, // 列表缩略图使用 OSS 图片处理(服务端缩放后再转发,省下行流量) 'verify' => true, // 提交时 HEAD 复核对象(防伪造/防超限) 'host_override' => '', // 仅特殊网关/联调使用;留空自动按 bucket.endpoint 拼接 ], /* ---------------- 附件限额 ---------------- * 单位:字节。原图上限指「压缩前」的原始文件大小(前端会先压缩到最长边 1600px)。 */ 'upload' => [ 'image_max_per_post' => 4, 'image_max_bytes' => 5242880, // 5 MB / 张 'image_exts' => ['jpg', 'jpeg', 'png', 'webp', 'gif'], 'image_mimes' => ['image/jpeg', 'image/png', 'image/webp', 'image/gif'], 'image_max_side' => 1600, // 前端压缩后的最长边(像素) 'video_max_per_post' => 1, 'video_max_bytes' => 52428800, // 50 MB / 个 'video_exts' => ['mp4', 'mov', 'webm'], 'video_mimes' => ['video/mp4', 'video/quicktime', 'video/webm'], 'total_cap_bytes' => 1073741824, // 全站附件总量上限 1 GB,达到后暂停接收新上传 'retention_days' => 365, // 附件保留天数,超期由 cron.php 清理 'upload_per_hour' => 60, // 每 IP 每小时最多申请多少次上传凭证 ], /* ---------------- 反垃圾 ---------------- */ 'rate_limit' => [ 'thread_per_hour' => 5, // 每个 IP 每小时最多发起的主题数 'reply_per_hour' => 20, // 每个 IP 每小时最多回复数 ], 'post_min_seconds' => 3, // 打开表单到提交不得少于该秒数(过快视为机器人) /* ---------------- 列表 ---------------- */ 'page_size' => 20, ];