2026-2-28开发记录:目录树系统修改记录日志
<h3>初始问题</h3><p>在讨论如何实现 <code></code> 段落配置对帖子进行排序,具体需求是:</p>
<ul>
<li>有 5 个帖子(tid:1,2,3,4,5)都在"技术手册"目录下</li>
<li>需要在"技术手册"目录下对这些帖子进行排序</li>
</ul>
<h3>实际问题诊断</h3>
<p>通过调试发现实际问题是:</p>
<ol>
<li>配置帖中使用了传统文字路径格式(<code>开发维护/社创开发</code>)</li>
<li>帖子标签只使用了单层名称(<code>#目录_社创开发</code>)</li>
<li>标签名与配置路径无法正确匹配,导致帖子无法归入目录</li>
</ol>
<hr />
<h2>修改过程时间线</h2>
<h3>阶段一:问题诊断</h3>
<h4>1.1 添加 SQL 调试代码</h4>
<p><strong>问题</strong>:初始调试时 <code>$_G['fid']</code> 变量为空,导致 SQL 语法错误</p>
<pre><code>错误信息:
1064) You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version
for the right syntax to use near 'AND tag.tagname LIKE...'
</code></pre>
<p><strong>修改内容</strong>:</p>
<ul>
<li>修复变量访问:使用 <code>$fid</code> 参数代替 <code>$_G['fid']</code></li>
<li>添加 <code>intval()</code> 确保类型正确</li>
<li>添加 fallback 逻辑,从全局变量获取 fid</li>
</ul>
<p><strong>文件</strong>:</p>
<ul>
<li><code>template/xmyc_doc/php/directory_tree.php</code></li>
<li><code>template/xmyc_touch_doc/touch/php/directory_tree.php</code></li>
</ul>
<h4>1.2 调试输出结果</h4>
<pre><code>当前 fid: 23
所有带目录标签的帖子:
tid:118 subject:2025-12-26 开发记录 tags:目录_社创开发
tid:135 subject:社创行动派交流论坛介绍 tags:目录_开发维护
tid:137 subject:2026 年 1 月开发记录 tags:目录_社创开发
tid:140 subject:文档模式前端模板解析目录的开发 tags:目录_社创开发
目录配置:
directories:
[开发维护] => Array( => 网站开发维护 => 98)
[开发维护/社创开发] => Array( => 社创官网和社区开发 => 1)
posts:
[社创开发] => Array( => 118 => 140 => 137)
</code></pre>
<h4>1.3 问题定位</h4>
<ul>
<li>配置路径:<code>开发维护/社创开发</code></li>
<li>帖子标签:<code>社创开发</code>(单层)</li>
<li>匹配函数 <code>find_dir_path_by_name()</code> 只能匹配路径最后一级</li>
</ul>
<hr />
<h3>阶段二:修复路径匹配</h3>
<h4>2.1 修改匹配逻辑</h4>
<p><strong>修改内容</strong>:</p>
<ul>
<li>修复 <code></code> 排序查找逻辑,使用标签名 <code>$dir_name</code> 代替完整路径 <code>$dir_path</code></li>
<li>添加调试输出,显示帖子与目录的匹配过程</li>
</ul>
<p><strong>代码变更</strong>:</p>
<pre><code class="language-php">// 原代码
if(isset($directory_config['posts'][$dir_path])) {
$tid_index = array_search($_thread['tid'], $directory_config['posts'][$dir_path]);
}
// 修改后
if(isset($directory_config['posts'][$dir_name])) {
$tid_index = array_search($_thread['tid'], $directory_config['posts'][$dir_name]);
}
</code></pre>
<hr />
<h3>阶段三:方案优化讨论</h3>
<h4>3.1 用户需求确认</h4>
<p>用户提出新方案需求:</p>
<ul>
<li>置顶帖路径配置格式:<code>数字序号 = 标签名称 = 目录树名称</code></li>
<li>目录树层级直接解析数字序号来匹配完成</li>
<li>帖子只需要单层标签即可</li>
</ul>
<p><strong>配置格式示例</strong>:</p>
<pre><code>1 = 开发维护 = 网站的开发维护
1-1 = 社创开发 = 社创行动派开发
1-1-1 = 文档开发 = 文档类内容展示逻辑开发
</code></pre>
<h4>3.2 方案设计</h4>
<p><strong>新格式特点</strong>:</p>
<ol>
<li>序号决定层级关系(<code>1</code> → <code>1-1</code> → <code>1-1-1</code>)</li>
<li>标签名保持单层(<code>#目录_社创开发</code>)</li>
<li>配置更清晰,维护更简单</li>
</ol>
<hr />
<h3>阶段四:新格式实现</h3>
<h4>4.1 配置解析函数重写</h4>
<p><strong>函数</strong>:<code>parse_config_message()</code></p>
<p><strong>新增新格式解析</strong>:</p>
<pre><code class="language-php">// 新格式:序号 = 标签名 = 目录名
preg_match_all('/^([\d\-]+)\s*=\s*([^=]+)\s*=\s*(.+)$/m', $content, $new_matches);
if($new_matches) {
foreach($new_matches as $index => $num_path) {
$num_path = trim($new_matches[$index]);
$tag_name = trim($new_matches[$index]);
$dir_name = trim($new_matches[$index]);
$config['directories'][$num_path] = array(
'tag_name' => $tag_name,
'name' => $dir_name,
'sort_order' => $index,
'is_new_format' => true
);
}
}
</code></pre>
<p><strong>保留旧格式兼容</strong>:</p>
<pre><code class="language-php">// 旧格式:序号 = 目录名。权重
preg_match_all('/^([^=\n]+)\s*=\s*([^.\n]+)\.(\d+)/m', $content, $dir_matches);
</code></pre>
<h4>4.2 新增辅助函数</h4>
<p><strong>函数</strong>:<code>find_num_path_by_tag()</code></p>
<pre><code class="language-php">function find_num_path_by_tag($directory_config, $tag_name) {
foreach($directory_config['directories'] as $num_path => $config) {
if($config['tag_name'] == $tag_name) {
return $num_path;
}
}
return '';
}
</code></pre>
<h4>4.3 新增目录节点创建函数</h4>
<p><strong>函数</strong>:<code>create_directory_node_new()</code></p>
<pre><code class="language-php">function create_directory_node_new(&$choices, $num_path, $name) {
// 将 1-1-1 转换为数组
$parts = explode('-', $num_path);
$current = &$choices;
$key_path = '';
$num_path_dot = '';
foreach($parts as $index => $part) {
$key_path .= ($key_path ? '-' : '') . $part;
$num_path_dot .= ($num_path_dot ? '.' : '') . $part;
if(!isset($current[$num_path_dot])) {
$current[$num_path_dot] = array(
'key' => $key_path,
'num' => $num_path_dot,
'level' => $index + 1,
'name' => $name,
'type' => 'directory',
'href' => generate_dir_link($num_path_dot),
'list' => array(),
'sort_order' => $index
);
}
$current = &$current[$num_path_dot]['list'];
}
}
</code></pre>
<h4>4.4 新增帖子添加函数</h4>
<p><strong>函数</strong>:<code>add_thread_to_directory_new()</code></p>
<pre><code class="language-php">function add_thread_to_directory_new(&$choices, $num_path, $thread, $sort_order = 0) {
$parts = explode('-', $num_path);
$current = &$choices;
$num_path_dot = implode('.', $parts);
// 导航到最后的目录
foreach($parts as $index => $part) {
$path = implode('.', array_slice($parts, 0, $index + 1));
if(isset($current[$path])) {
$current = &$current[$path]['list'];
} else {
return; // 目录不存在,跳过
}
}
// 添加帖子
$thread_key = 'tid_' . $thread['tid'];
if(!isset($current[$thread_key])) {
$current[$thread_key] = array(
'key' => $thread_key,
'num' => $thread['tid'],
'name' => $thread['subject'],
'type' => 'thread',
'href' => generate_thread_link($thread['tid']),
'list' => array(),
'sort_order' => $sort_order
);
}
}
</code></pre>
<h4>4.5 主逻辑流程控制</h4>
<pre><code class="language-php">// 检查是否使用新格式
$is_new_format = false;
foreach($directory_config['directories'] as $num_path => $config) {
if(!empty($config['is_new_format'])) {
$is_new_format = true;
break;
}
}
if($is_new_format) {
// 新格式处理
foreach($directory_config['directories'] as $num_path => $config) {
create_directory_node_new($flquery['choices'], $num_path, $config['name']);
}
foreach($_tagged_threads as $_thread) {
$tag_names = extract_directory_tags($_thread['tags']);
foreach($tag_names as $tag_name) {
$num_path = find_num_path_by_tag($directory_config, $tag_name);
if($num_path) {
$sort_order = 0;
if(isset($directory_config['posts'][$tag_name])) {
$tid_index = array_search($_thread['tid'], $directory_config['posts'][$tag_name]);
if($tid_index !== false) {
$sort_order = $tid_index;
}
}
add_thread_to_directory_new($flquery['choices'], $num_path, $_thread, $sort_order);
}
}
}
} else {
// 旧格式处理(兼容)
}
</code></pre>
<hr />
<h2>修改文件清单</h2>
<table>
<thead>
<tr>
<th>文件</th>
<th>修改类型</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>template/xmyc_doc/php/directory_tree.php</code></td>
<td>重写</td>
<td>PC 版目录树生成核心</td>
</tr>
<tr>
<td><code>template/xmyc_touch_doc/touch/php/directory_tree.php</code></td>
<td>重写</td>
<td>移动版目录树生成核心</td>
</tr>
</tbody>
</table>
<hr />
<h2>函数变更清单</h2>
<h3>新增函数</h3>
<table>
<thead>
<tr>
<th>函数名</th>
<th>用途</th>
<th>版本</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>find_num_path_by_tag()</code></td>
<td>根据标签名查找序号路径</td>
<td>新格式专用</td>
</tr>
<tr>
<td><code>create_directory_node_new()</code></td>
<td>创建序号目录节点</td>
<td>新格式专用</td>
</tr>
<tr>
<td><code>add_thread_to_directory_new()</code></td>
<td>添加帖子到序号目录</td>
<td>新格式专用</td>
</tr>
</tbody>
</table>
<h3>修改函数</h3>
<table>
<thead>
<tr>
<th>函数名</th>
<th>修改内容</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>parse_config_message()</code></td>
<td>新增新格式解析逻辑,保留旧格式兼容</td>
</tr>
<tr>
<td><code>extract_directory_tags()</code></td>
<td>简化,移除路径转换逻辑</td>
</tr>
<tr>
<td><code>get_directory_threads()</code></td>
<td>移除调试代码,优化 SQL</td>
</tr>
</tbody>
</table>
<h3>保留函数(旧格式兼容)</h3>
<table>
<thead>
<tr>
<th>函数名</th>
<th>用途</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>build_directory_tree()</code></td>
<td>旧格式目录树构建</td>
</tr>
<tr>
<td><code>find_dir_path_by_name()</code></td>
<td>旧格式路径匹配</td>
</tr>
</tbody>
</table>
<hr />
<h2>配置格式对比</h2>
<h3>旧格式</h3>
<pre><code>
开发维护 = 网站开发维护.98
开发维护/社创开发 = 社创官网和社区开发.1
开发维护/利智官网 = 北京利智官网.2
社创开发 = tid:118,tid:140,tid:137
</code></pre>
<h3>新格式</h3>
<pre><code>
1 = 开发维护 = 网站开发维护
1-1 = 社创开发 = 社创官网和社区开发
1-2 = 利智官网 = 北京利智官网
社创开发 = tid:118,tid:140,tid:137
</code></pre>
<hr />
<h2>技术要点</h2>
<h3>1. 序号路径解析</h3>
<pre><code>输入:1-1-1
解析:explode('-', '1-1-1') →
层级:level=3
路径:1.1.1(内部存储格式)
KEY: 1-1-1(用于前端)
</code></pre>
<h3>2. 标签匹配逻辑</h3>
<pre><code>帖子标签:#目录_社创开发
配置查找:遍历 directories 数组,匹配 tag_name
返回序号:1-1
目录路径:1.1(内部)
</code></pre>
<h3>3. 目录树结构</h3>
<pre><code class="language-php">$flquery['choices'] = array(
'1' => array(
'key' => '1',
'num' => '1',
'level' => 1,
'name' => '开发维护',
'type' => 'directory',
'href' => '...&dir=1',
'list' => array(
'1.1' => array(
'key' => '1-1',
'num' => '1.1',
'level' => 2,
'name' => '社创官网和社区开发',
'type' => 'directory',
'list' => array(
'tid_118' => array(
'key' => 'tid_118',
'num' => 118,
'name' => '2025-12-26 开发记录',
'type' => 'thread',
'href' => '...tid=118',
'sort_order' => 0
)
)
)
)
)
);
</code></pre>
<hr />
<h2>测试验证</h2>
<h3>测试场景</h3>
<table>
<thead>
<tr>
<th>场景</th>
<th>预期结果</th>
<th>状态</th>
</tr>
</thead>
<tbody>
<tr>
<td>新格式配置解析</td>
<td>正确解析序号、标签名、目录名</td>
<td>✓</td>
</tr>
<tr>
<td>旧格式配置解析</td>
<td>向后兼容,正常解析</td>
<td>✓</td>
</tr>
<tr>
<td>标签匹配序号</td>
<td>单层标签匹配到正确序号路径</td>
<td>✓</td>
</tr>
<tr>
<td>多层目录构建</td>
<td>1-1-1 正确构建三级目录</td>
<td>✓</td>
</tr>
<tr>
<td>帖子排序</td>
<td> 配置生效</td>
<td>✓</td>
</tr>
<tr>
<td>Ajax 请求</td>
<td>getdirectory=true 返回 JSON</td>
<td>✓</td>
</tr>
</tbody>
</table>
<hr />
<h2>遇到的问题及解决方案</h2>
<h3>问题 1:fid 变量为空</h3>
<p><strong>现象</strong>:SQL 报错 <code>WHERE t.fid= AND...</code></p>
<p><strong>原因</strong>:<code>$_G['fid']</code> 在函数作用域内不可用</p>
<p><strong>解决</strong>:</p>
<pre><code class="language-php">$fid = intval($fid);
if(empty($fid)) {
global $_G;
$fid = intval($_G['fid']);
}
</code></pre>
<h3>问题 2:标签与路径不匹配</h3>
<p><strong>现象</strong>:帖子无法归入目录</p>
<p><strong>原因</strong>:配置使用完整路径 <code>开发维护/社创开发</code>,标签只有 <code>社创开发</code></p>
<p><strong>临时解决</strong>:修改匹配逻辑,使用标签名查找 <code></code> 配置</p>
<p><strong>最终解决</strong>:引入新格式,序号配置 + 单层标签</p>
<hr />
<h2>后续建议</h2>
<h3>功能增强</h3>
<ol>
<li><strong>自动序号生成</strong>:配置时可省略序号,自动生成</li>
<li><strong>目录权限控制</strong>:支持按目录设置访问权限</li>
<li><strong>目录统计信息</strong>:显示每个目录下的文档数量</li>
<li><strong>批量标签管理</strong>:提供批量修改帖子标签的工具</li>
</ol>
<h3>性能优化</h3>
<ol>
<li><strong>缓存机制</strong>:目录树结果缓存,减少数据库查询</li>
<li><strong>Ajax 加载</strong>:大目录树分步加载</li>
<li><strong>索引优化</strong>:为标签表添加组合索引</li>
</ol>
<h3>用户体验</h3>
<ol>
<li><strong>配置可视化</strong>:提供配置帖生成工具</li>
<li><strong>目录预览</strong>:编辑配置帖时实时预览目录结构</li>
<li><strong>错误提示</strong>:配置错误时给出明确提示</li>
</ol>
<hr />
<h2>总结</h2>
<p>本次修改完成了目录树系统从文字路径配置到序号路径配置的升级,主要成果:</p>
<ol>
<li><strong>新格式更简洁</strong>:<code>序号 = 标签名 = 目录名</code> 三要素清晰明了</li>
<li><strong>标签更简单</strong>:帖子只需单层标签,降低维护成本</li>
<li><strong>层级更清晰</strong>:序号直接体现目录层级关系</li>
<li><strong>向后兼容</strong>:保留旧格式支持,平滑迁移</li>
</ol>
<p>核心改进点:</p>
<ul>
<li>配置解析支持新旧两种格式</li>
<li>新增序号路径匹配和目录构建函数</li>
<li>简化了帖子标签要求</li>
<li>优化了目录树生成逻辑</li>
</ul>
<hr />
<p><em>日志版本:1.0</em><br />
<em>记录日期:2026-02-28</em><br />
<em>记录人:蜗牛</em></p>
页:
[1]