★ 宪法总纲:编辑任何资源的唯一正确姿势

★ 建站顺序另见《云酷德建站流程法》(tempx buildlaw.index,打开章程,2026-10-05 定稿):先名后形 → 计划六表 → 补正 → 开工 → newresname 建名 → 照 funtxt 施工 → samekdatatotab 回填 → 验收。

以前文档里写的是「直接调 API 接口」——那是旧约,作废。所有资源的增删改,一律按下述六步走。

  1. 先登录,拿三件套
    GET 本站域名/localxres/funx/commonlogin/?uid=<账号>&pass=<makepass密文>&sysid=<系统id>
    返回 JSON 的 msg 就是 stoken。随后 Cookie 必须带 三个值:uid、stoken、deadline=time()+3600*72。
    坑:只带 uid+stoken、不带 deadline,会被 heartbeat 的 $leftt>0 拦掉,现象是 302 静默跳转,接口返回空。
  2. 建资源名
    funx.newresname?restype=<类型>&rescode=<域.名>&sysid=<系统>&restitle=<标题>
    Cookie 里的 uid 在 coode_userlist 中必须 PRIME=1。tempx 的 rescode 若含点号,点前是域、点后是单元名;不含点号则自动补 .index。
  3. 查编辑器地址
    到 coode_sysrestypedefine 按 restypecode 查 cloudpath 字段——它就是该类型资源的编辑器地址。
    分水岭:cloudpath 值为 mysql 的,说明这类资源基本不落盘,可以直接改数据;值是一条 URL 的,说明会落盘,必须进编辑器改,直接改库会造成库盘不一致。
  4. 打开编辑器
    编辑器地址不用猜、不用记——去 coode_sysrestypedefine 找到该 restypecode 那一行,读它的 cloudpath 字段,那就是现成的完整编辑器地址,? 后面已经把参数位留好了;你要做的只是把占位符换成资源名或该数据的 SNO 序号。
    三个完整地址示例:
    https://qianjilian.com/localxres/tempx/tempeditor/index.html?unitid=xianfa.index
    https://qianjilian.com/localxres/pagex/htmleditor/WrvLoe/index.html?funid=savefunc
    https://qianjilian.com/localxres/pagex/htmleditor/WrvLoe/index.html?funid=coode_funsetfile@SNO:12345.funfull
  5. 编辑器里能调哪些后端方法
    由 coode_funlist 的 usearea 字段声明:它写明该方法允许被哪个页面调用,形如 tempx.tempeditor.index。
    heartbeat 会把 HTTP Referer 解析成 pgmark(资源类型.目录.单元),拿它和 usearea 比对,不匹配直接判无权。所以「在哪个页面里调」不是形式,是权限本身。
    usearea 为空 = 不限制来源,可从外部调用(如 newresname、savetoseed、makelayfolder)。
  6. 鉴权在哪
    数据集 heartbeat 的 refreshtoken 方法:校验 stoken 是否有效、刷新 coode_loginstoken 有效期、并下发 deadline。所有「为什么明明登录了还是没权限」的答案都在这里。

26 类资源:编辑器完整地址 / 能不能直接改库

下表「编辑器 / 落点」列即 coode_sysrestypedefine.cloudpath 的值(已补全域名前缀),可直接复制使用。

类型主表编辑器 / 落点(完整地址)
funx 函数coode_funlisthttps://qianjilian.com/localxres/pagex/htmleditor/WrvLoe/index.html?funid=<函数名>
clsx 类coode_phpclshttps://qianjilian.com/localxres/pagex/htmleditor/WrvLoe/index.html?funid=<类名>
sfunx 函数集coode_funsetfilehttps://qianjilian.com/localxres/pagex/htmleditor/WrvLoe/index.html?funid=coode_funsetfile@SNO:<该数据序号>.funfull
dfunx 数据函数coode_datafunhttps://qianjilian.com/localxres/pagex/htmleditor/WrvLoe/index.html?funid=coode_funsetfile@SNO:<该数据序号>.funfull
constx 静态量coode_sysconstanthttps://qianjilian.com/localxres/pagex/htmleditor/WrvLoe/index.html?funid=coode_funsetfile@SNO:<该数据序号>.funfull
configx 系统参数coode_sysconfighttps://qianjilian.com/localxres/pagex/htmleditor/WrvLoe/index.html?funid=coode_funsetfile@SNO:<该数据序号>.funfull
tempx 模板coode_domainunithttps://qianjilian.com/localxres/tempx/tempeditor/index.html?unitid=<域.单元>
pagex 页面coode_tinyhttps://qianjilian.com/localxres/tempx/tinylayeditor/index.html?unitid=<域.单元>&tinyid=<tinymark>
mfunx 分布函数coode_multifunlisthttps://qianjilian.com/localxres/tempx/tinylayeditor/index.html?unitid=resuptool.index&tinyid=o16CUI
tabx 表coode_tablisthttps://qianjilian.com/localxres/funx/anyjsshort/?stid=2qPIqS-sfile:anyjsshort.php-&pnum=150:<表名>&page=1:TABLE_NAME&
formx 表单coode_shortdatahttps://qianjilian.com/localxres/funx/anyjsshort/?datatype=html&stid=keydtly-&pnum=100:<shortid>&page=1:shortid&
dataspacex 数据空间coode_dataspacehttps://qianjilian.com/localxres/tempx/dspcmgr/index.html
sysx 系统容器coode_sysinformationmysql:不落盘,可直接改库
appx 应用容器coode_appdefaultmysql:不落盘,可直接改库
layx 输出容器coode_applaymysql:不落盘,可直接改库
cdtrdrx 条件跳转coode_cdtrdrmysql:不落盘,可直接改库
parardrx 参数跳转coode_parardrmysql:不落盘,可直接改库
groupx 一级分类coode_grouplistmysql:不落盘,可直接改库
plotx 节点coode_plotlistmysql:不落盘,可直接改库
csspagex 样式页面coode_facelistmysql:不落盘,可直接改库
iconsetx 图标库coode_iconsetmysql:不落盘,可直接改库
databasex 数据库coode_dblistmysql:不落盘,可直接改库
afunx 事务函数coode_affairfunlistmysql:不落盘,可直接改库
parax 外部框架coode_paramysql:不落盘,可直接改库
apix 接口密钥coode_apipoolmysql:不落盘,可直接改库
smallcssx 小CSScoode_codedemomysql:不落盘,可直接改库
首页 功能与逻辑 数据与存储 容器与结构 界面与样式
云酷德宪法 / 功能与逻辑 / apix

apix · 接口密钥

统一存放第三方接口的密钥(AK / SK / Token / AppID),不在代码里硬编码,不各建各的表。

它解决什么问题

以前每个新系统接一个第三方(七牛、百度、火山、高德、GitHub)就顺手建一张配置表, 结果密钥散落各处,谁也说不清存哪。apix 的做法是:所有接口密钥一律进同一张表, 靠 sysid(哪个系统)+ CRTOR(哪个用户/归属人)隔离。

主表:coode_apipool

字段类型说明
SNOint主键
sysidvarchar(50)★ 归属系统(tjx / massqrcode / 0 / 1 / v …)
apicodevarchar(50)★ 资源码,唯一索引。一个接口一条码,如 qnywxh、qnywxl
appidvarchar(100)应用标识 / 空间名(七牛就是 bucket)
apikeyvarchar(255)★ 主密钥(AK)
apivalvarchar(255)★ 副密钥(SK / 第二个值)
apititlevarchar(1024)标题,如「七牛云-王晓华接口」
parcodevarchar(100)服务商官网,如 https://www.qiniu.com/
partitlevarchar(255)服务商名,如「七牛云」「火山」「百度」
CRTORvarchar(255)★ 归属人(多用户隔离就靠它)
OLMKvarchar(255)唯一标记
OPRTvarchar(1024)附加信息(现用于存访问域名)
STATUSdecimal状态,1 = 启用
CRTM / UPTMdatetime创建 / 更新时间
VRTvarchar(255)校验值(多为 md5)
⛔ apicode 是唯一索引:两条记录不能共用同一个 apicode。 多用户场景要给每个用户生成专属码(见下面实战),不要都写 qny。

约定俗成

隔离检索条件固定带 sysid + CRTOR,谁的系统谁的号,互不干扰 主副密钥apikey 放主密钥,apival 放副密钥/第二个值 空间名七牛这类「空间」概念放 appid,域名通常就是 appid + 域名后缀 附加信息字段不够用时放 OPRT(如访问域名),别再建新表

查一条配置

SELECT appid, apikey, apival, IFNULL(OPRT,'') AS domain
  FROM coode_apipool
 WHERE sysid = 'tjx'
   AND CRTOR = '18841880246'
   AND apicode LIKE 'qny%'
   AND STATUS = 1
 ORDER BY SNO DESC LIMIT 1;

新增一条(以七牛为例)

INSERT INTO coode_apipool
  (sysid, apicode, appid, apikey, apival, apititle, parcode, partitle,
   CRTM, UPTM, CRTOR, OLMK, OPRT, STATUS, STCODE)
VALUES
  ('tjx', 'qnye74af2', 'wrdstock', '<AK>', '<SK>', '七牛云-18841880246',
   'https://www.qiniu.com/', '七牛云', now(), now(),
   '18841880246', 'tjxqny18841880246', 'wrdstock.divlovecss.com', 1, '');

改一个字段(万能写通道)

POST 本站域名/localxres/funx/savefunc/?fn=SNO:37.apikey@coode_apipool
Cookie: uid=divlovecss; stoken=; deadline=
Content-Type: application/x-www-form-urlencoded
dt=<新的值>
# fn 写法:fn=SNO:<主键>.<列名>@<表名>   可以按主键改任意表任意列

实战:某系统的「用户自带七牛」

场景:多用户系统里,每个用户填自己的七牛空间,上传的照片进他自己的空间,互不打混。

def acode_of(uid):
    return 'qny' + hashlib.md5(('tjxqny' + str(uid)).encode('utf-8')).hexdigest()[:6]
def qn_cfg(uid):
    cur.execute("SELECT appid,apikey,apival,IFNULL(OPRT,'') FROM coode_apipool "
                "WHERE sysid=%s AND CRTOR=%s AND apicode LIKE %s AND STATUS=1 "
                "ORDER BY SNO DESC LIMIT 1", (SYSID, uid, 'qny%'))
    r = cur.fetchone()
    if not r:
        return None
    return <'bucket': r[0], 'ak': r[1], 'sk': r[2],
            'domain': r[3] or (str(r[0]) + '.divlovecss.com')>
⛔ pymysql 的坑:SQL 里别直接写 LIKE 'qny%', 那个 % 会被当成参数占位符报 not enough arguments for format string。用参数传值 LIKE %s + 'qny%'。

什么时候该用 apix

⛔ 别再为某个接口单独建一张表(coode_tjxqny 这类)。 要加接口就往 coode_apipool 插一条,用 sysid + CRTOR 区分。