<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>https://wiki.3dtank.net/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3ABatchDelete.js</id>
	<title>MediaWiki:BatchDelete.js - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.3dtank.net/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3ABatchDelete.js"/>
	<link rel="alternate" type="text/html" href="https://wiki.3dtank.net/index.php?title=MediaWiki:BatchDelete.js&amp;action=history"/>
	<updated>2026-10-14T04:29:14Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>https://wiki.3dtank.net/index.php?title=MediaWiki:BatchDelete.js&amp;diff=21030&amp;oldid=prev</id>
		<title>2026年10月4日 (日) 16:00 Wiki-editor-3dtank</title>
		<link rel="alternate" type="text/html" href="https://wiki.3dtank.net/index.php?title=MediaWiki:BatchDelete.js&amp;diff=21030&amp;oldid=prev"/>
		<updated>2026-10-04T16:00:00Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;zh-Hans-CN&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;←上一版本&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;2026年10月4日 (日) 16:00的版本&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l144&quot;&gt;第144行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第144行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             function unsafePage(p) {&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;             function unsafePage(p) {&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 if ([&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;6, &lt;/del&gt;7, 8, 9].indexOf(p.ns) !== -1) {&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 if ([7, 8, 9].indexOf(p.ns) !== -1) {&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     return &#039;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;安全限制：不批量删除文件、文件讨论、界面及界面讨论页面。&lt;/del&gt;&#039;;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     return &#039;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;安全限制：不批量删除文件讨论、界面及界面讨论页面。&lt;/ins&gt;&#039;;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 if (p.ns === 4 &amp;amp;&amp;amp; p.title.slice(p.title.indexOf(&amp;#039;:&amp;#039;) + 1) === &amp;#039;批量删除&amp;#039;) {&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 if (p.ns === 4 &amp;amp;&amp;amp; p.title.slice(p.title.indexOf(&amp;#039;:&amp;#039;) + 1) === &amp;#039;批量删除&amp;#039;) {&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key wiki_db:diff:1.41:old-19145:rev-21030:php=table --&gt;
&lt;/table&gt;</summary>
		<author><name>Wiki-editor-3dtank</name></author>
	</entry>
	<entry>
		<id>https://wiki.3dtank.net/index.php?title=MediaWiki:BatchDelete.js&amp;diff=19145&amp;oldid=prev</id>
		<title>2026年9月18日 (五) 02:03 Wiki-editor-3dtank</title>
		<link rel="alternate" type="text/html" href="https://wiki.3dtank.net/index.php?title=MediaWiki:BatchDelete.js&amp;diff=19145&amp;oldid=prev"/>
		<updated>2026-09-18T02:03:23Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;zh-Hans-CN&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;←上一版本&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;2026年9月18日 (五) 02:03的版本&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot;&gt;第1行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第1行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;/* Wiki 批量删除工具 v1.&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;0 &lt;/del&gt;— 放入 MediaWiki:BatchDelete.js&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;/* Wiki 批量删除工具 v1.&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;1 &lt;/ins&gt;— 放入 MediaWiki:BatchDelete.js&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  * 入口：Project:批量删除。使用当前登录账号及本站 API，不发送数据至外站。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  * 入口：Project:批量删除。使用当前登录账号及本站 API，不发送数据至外站。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  * 只删除人工输入并经预检、二次确认的页面；不递归删除链接、子页面或文件实体。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;  * 只删除人工输入并经预检、二次确认的页面；不递归删除链接、子页面或文件实体。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l244&quot;&gt;第244行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第244行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                                 var result = await request({ action: &amp;#039;delete&amp;#039;, pageid: r.pageid, reason: reason,&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                                 var result = await request({ action: &amp;#039;delete&amp;#039;, pageid: r.pageid, reason: reason,&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                                     assert: &amp;#039;user&amp;#039;, assertuser: account.name, watchlist: &amp;#039;nochange&amp;#039;, formatversion: 2, maxlag: 5 }, true);&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                                     assert: &amp;#039;user&amp;#039;, assertuser: account.name, watchlist: &amp;#039;nochange&amp;#039;, formatversion: 2, maxlag: 5 }, true);&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                                 &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;if (!&lt;/del&gt;result.delete || &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;result&lt;/del&gt;.&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;delete&lt;/del&gt;.pageid !== r.&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;pageid&lt;/del&gt;) {&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                                 &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;// MediaWiki 1.43 returns title + reason + logid, NOT pageid.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                                     throw { code: &#039;unexpected-response&#039;, info: &#039;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;未收到可核实的删除成功响应，请检查本站删除日志。&lt;/del&gt;&#039; };&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;                                // Large deletions may return scheduled:true instead of a log ID.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;                                var deletion = result &amp;amp;&amp;amp; &lt;/ins&gt;result.delete&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;                                var scheduled = deletion &amp;amp;&amp;amp; deletion.scheduled === true;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;                                var logId = deletion &amp;amp;&amp;amp; Number(deletion.logid);&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;                                var hasLog = Number.isSafeInteger(logId) &amp;amp;&amp;amp; logId &amp;gt; 0;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;                                var optionalPageIdOK = deletion &amp;amp;&amp;amp; (deletion.pageid === undefined &lt;/ins&gt;|| &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Number(deletion&lt;/ins&gt;.&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;pageid) === r&lt;/ins&gt;.pageid&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;);&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;                                if (!deletion || deletion.title &lt;/ins&gt;!== r.&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;title || !optionalPageIdOK || (!scheduled &amp;amp;&amp;amp; !hasLog)&lt;/ins&gt;) {&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                                     throw { code: &#039;unexpected-response&#039;, info: &#039;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;响应未包含匹配的页面标题及删除日志 ID 或后台任务确认，请检查本站删除日志，不要直接重试。&#039; };&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;                                }&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;                                if (scheduled) {&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;                                    r.status = &#039;已提交后台&lt;/ins&gt;&#039;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;                                    r.detail = &#039;服务器已接受后台删除任务，尚不代表完成。请稍后核对页面和删除日志，不要重复提交。&#039;;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;                                &lt;/ins&gt;} &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;else {&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;                                    r.status = &#039;已删除&#039;;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;                                    r.detail = &#039;删除成功；&#039; + deletion.title + &#039;；日志 ID &#039; + logId&lt;/ins&gt;;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                                 }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                                 }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;                                r.status = &#039;已删除&#039;; r.detail = &#039;删除成功；&#039; + (result.delete.title || r.title);&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;                                if (result.delete.logid) { r.detail += &#039;；日志 ID &#039; + result.delete.logid; }&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                             }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                             }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                         } catch (e) {&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                         } catch (e) {&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l274&quot;&gt;第274行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第286行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     el(&amp;#039;agree&amp;#039;).checked = false; el(&amp;#039;confirm&amp;#039;).value = &amp;#039;&amp;#039;;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     el(&amp;#039;agree&amp;#039;).checked = false; el(&amp;#039;confirm&amp;#039;).value = &amp;#039;&amp;#039;;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     render(); updateButtons();&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     render(); updateButtons();&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     if (!stopping) { status(&#039;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;本批次处理完成。建议下载日志留档。再次执行需要重新预检。&lt;/del&gt;&#039;); }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     if (!stopping) {&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;                        var queued = jobs.filter(function (r) { return r.status === &#039;已提交后台&#039;; }).length;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;                        &lt;/ins&gt;status(&#039;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;本批次请求处理完成。&#039; + (queued ? &#039;其中 &#039; + queued + &#039; 页已提交后台，尚未确认删除完成，请稍后核对，勿重复提交。&#039; : &#039;&#039;) + &#039;建议下载日志留档。再次执行需要重新预检。&lt;/ins&gt;&#039;);&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;                    &lt;/ins&gt;}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     else { status(el(&amp;#039;status&amp;#039;).textContent + &amp;#039;\n批次已停止。已完成的删除未撤销；请下载日志。&amp;#039;); }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                     else { status(el(&amp;#039;status&amp;#039;).textContent + &amp;#039;\n批次已停止。已完成的删除未撤销；请下载日志。&amp;#039;); }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 }&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;                 }&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Wiki-editor-3dtank</name></author>
	</entry>
	<entry>
		<id>https://wiki.3dtank.net/index.php?title=MediaWiki:BatchDelete.js&amp;diff=19142&amp;oldid=prev</id>
		<title>Wiki-editor-3dtank：​创建页面，内容为“/* Wiki 批量删除工具 v1.0 — 放入 MediaWiki:BatchDelete.js  * 入口：Project:批量删除。使用当前登录账号及本站 API，不发送数据至外站。  * 只删除人工输入并经预检、二次确认的页面；不递归删除链接、子页面或文件实体。  */ (function () {     &#039;use strict&#039;;     if (mw.config.get(&#039;wgNamespaceNumber&#039;) !== 4 || mw.config.get(&#039;wgTitle&#039;) !== &#039;批量删除&#039; ||         mw.config.get(&#039;wgAction&#039;) !== &#039;view…”</title>
		<link rel="alternate" type="text/html" href="https://wiki.3dtank.net/index.php?title=MediaWiki:BatchDelete.js&amp;diff=19142&amp;oldid=prev"/>
		<updated>2026-09-18T01:53:28Z</updated>

		<summary type="html">&lt;p&gt;创建页面，内容为“&lt;span class=&quot;autocomment&quot;&gt;Wiki 批量删除工具 v1.0 — 放入 MediaWiki:BatchDelete.js  * 入口：Project:批量删除。使用当前登录账号及本站 API，不发送数据至外站。  * 只删除人工输入并经预检、二次确认的页面；不递归删除链接、子页面或文件实体。：​&lt;/span&gt; (function () {     &amp;#039;use strict&amp;#039;;     if (mw.config.get(&amp;#039;wgNamespaceNumber&amp;#039;) !== 4 || mw.config.get(&amp;#039;wgTitle&amp;#039;) !== &amp;#039;批量删除&amp;#039; ||         mw.config.get(&amp;#039;wgAction&amp;#039;) !== &amp;#039;view…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;/* Wiki 批量删除工具 v1.0 — 放入 MediaWiki:BatchDelete.js&lt;br /&gt;
 * 入口：Project:批量删除。使用当前登录账号及本站 API，不发送数据至外站。&lt;br /&gt;
 * 只删除人工输入并经预检、二次确认的页面；不递归删除链接、子页面或文件实体。&lt;br /&gt;
 */&lt;br /&gt;
(function () {&lt;br /&gt;
    &amp;#039;use strict&amp;#039;;&lt;br /&gt;
    if (mw.config.get(&amp;#039;wgNamespaceNumber&amp;#039;) !== 4 || mw.config.get(&amp;#039;wgTitle&amp;#039;) !== &amp;#039;批量删除&amp;#039; ||&lt;br /&gt;
        mw.config.get(&amp;#039;wgAction&amp;#039;) !== &amp;#039;view&amp;#039;) { return; }&lt;br /&gt;
    if (window.wikiBatchDeleteLoaded) { return; }&lt;br /&gt;
    window.wikiBatchDeleteLoaded = true;&lt;br /&gt;
&lt;br /&gt;
    mw.loader.using([&amp;#039;mediawiki.api&amp;#039;, &amp;#039;mediawiki.util&amp;#039;]).then(function () {&lt;br /&gt;
        $(function () {&lt;br /&gt;
            var root = document.getElementById(&amp;#039;wiki-batch-delete&amp;#039;);&lt;br /&gt;
            if (!root) {&lt;br /&gt;
                root = document.createElement(&amp;#039;div&amp;#039;);&lt;br /&gt;
                (document.getElementById(&amp;#039;mw-content-text&amp;#039;) || document.body).appendChild(root);&lt;br /&gt;
            }&lt;br /&gt;
            var api = new mw.Api(), account = null, rightsOK = false;&lt;br /&gt;
            var busy = false, running = false, stopping = false, ready = false;&lt;br /&gt;
            var records = [], activeJob = null;&lt;br /&gt;
            var LIMIT = 500;&lt;br /&gt;
&lt;br /&gt;
            mw.util.addCSS(&lt;br /&gt;
                &amp;#039;#wiki-batch-delete{font-size:14px;line-height:1.6;max-width:1100px;color:inherit}&amp;#039; +&lt;br /&gt;
                &amp;#039;#wiki-batch-delete *{box-sizing:border-box}&amp;#039; +&lt;br /&gt;
                &amp;#039;#wiki-batch-delete .bd-card{border:1px solid #a2a9b1;border-radius:8px;padding:20px;margin:14px 0}&amp;#039; +&lt;br /&gt;
                &amp;#039;#wiki-batch-delete .bd-warning{border-left:4px solid #d33;padding:12px 16px;background:#fff4f3;color:#202122}&amp;#039; +&lt;br /&gt;
                &amp;#039;#wiki-batch-delete label{display:block;font-weight:bold;margin:12px 0 6px}&amp;#039; +&lt;br /&gt;
                &amp;#039;#wiki-batch-delete textarea,#wiki-batch-delete input[type=text]{display:block;width:100%;padding:9px;border:1px solid #72777d;border-radius:4px;background:#fff;color:#202122;font:inherit}&amp;#039; +&lt;br /&gt;
                &amp;#039;#wiki-batch-delete textarea{min-height:210px;font-family:monospace}&amp;#039; +&lt;br /&gt;
                &amp;#039;#wiki-batch-delete button{padding:8px 14px;margin:6px 8px 6px 0;border:1px solid #72777d;border-radius:4px;cursor:pointer;background:#f8f9fa;color:#202122;font:inherit}&amp;#039; +&lt;br /&gt;
                &amp;#039;#wiki-batch-delete button.bd-primary{background:#36c;border-color:#36c;color:#fff}&amp;#039; +&lt;br /&gt;
                &amp;#039;#wiki-batch-delete button.bd-danger{background:#b32424;border-color:#b32424;color:#fff}&amp;#039; +&lt;br /&gt;
                &amp;#039;#wiki-batch-delete button:disabled{opacity:.45;cursor:not-allowed}&amp;#039; +&lt;br /&gt;
                &amp;#039;#wiki-batch-delete .bd-help{color:#54595d;font-size:13px}&amp;#039; +&lt;br /&gt;
                &amp;#039;#wiki-batch-delete .bd-scroll{overflow:auto;max-height:520px}&amp;#039; +&lt;br /&gt;
                &amp;#039;#wiki-batch-delete table{border-collapse:collapse;width:100%;font-size:13px}&amp;#039; +&lt;br /&gt;
                &amp;#039;#wiki-batch-delete th,#wiki-batch-delete td{border-bottom:1px solid #a2a9b1;padding:9px;text-align:left;vertical-align:top;overflow-wrap:anywhere}&amp;#039; +&lt;br /&gt;
                &amp;#039;#wiki-batch-delete th{background:#eaecf0;color:#202122;position:sticky;top:0}&amp;#039; +&lt;br /&gt;
                &amp;#039;#wiki-batch-delete progress{width:100%;height:18px}&amp;#039; +&lt;br /&gt;
                &amp;#039;#wiki-batch-delete .bd-check{font-weight:normal;display:flex;align-items:flex-start;gap:8px}&amp;#039; +&lt;br /&gt;
                &amp;#039;#wiki-batch-delete .bd-check input{margin-top:6px}&amp;#039; +&lt;br /&gt;
                &amp;#039;#wiki-batch-delete .bd-status{white-space:pre-wrap}&amp;#039;&lt;br /&gt;
            );&lt;br /&gt;
            root.innerHTML =&lt;br /&gt;
                &amp;#039;&amp;lt;h2&amp;gt;批量删除页面&amp;lt;/h2&amp;gt;&amp;#039; +&lt;br /&gt;
                &amp;#039;&amp;lt;div class=&amp;quot;bd-warning&amp;quot;&amp;gt;&amp;lt;b&amp;gt;此操作会删除页面及其修订历史。&amp;lt;/b&amp;gt;通常可由具有恢复权限的管理员恢复，但请先备份。&amp;#039; +&lt;br /&gt;
                &amp;#039;本工具不清理缓存、关联图片、入链或子页面，也不会绕过站点权限。&amp;lt;/div&amp;gt;&amp;#039; +&lt;br /&gt;
                &amp;#039;&amp;lt;p id=&amp;quot;bd-permission&amp;quot; role=&amp;quot;status&amp;quot;&amp;gt;正在检查当前账号权限……&amp;lt;/p&amp;gt;&amp;#039; +&lt;br /&gt;
                &amp;#039;&amp;lt;div class=&amp;quot;bd-card&amp;quot;&amp;gt;&amp;#039; +&lt;br /&gt;
                &amp;#039;&amp;lt;label for=&amp;quot;bd-titles&amp;quot;&amp;gt;页面名称 · 每行一个&amp;lt;/label&amp;gt;&amp;#039; +&lt;br /&gt;
                &amp;#039;&amp;lt;textarea id=&amp;quot;bd-titles&amp;quot; placeholder=&amp;quot;示例页面一\n示例页面二\n模板:示例模板&amp;quot; spellcheck=&amp;quot;false&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;&amp;#039; +&lt;br /&gt;
                &amp;#039;&amp;lt;p class=&amp;quot;bd-help&amp;quot;&amp;gt;最多 500 个不重复名称。输入完整页面名称，不要输入网址、[[链接语法]]或 #章节。&amp;#039; +&lt;br /&gt;
                &amp;#039;空行和重复名称自动忽略；重定向只删除重定向页本身。文件及其讨论页、MediaWiki 界面页及其讨论页、本工具入口受到安全限制。&amp;lt;/p&amp;gt;&amp;#039; +&lt;br /&gt;
                &amp;#039;&amp;lt;label for=&amp;quot;bd-reason&amp;quot;&amp;gt;删除理由（必填，会进入公开删除日志）&amp;lt;/label&amp;gt;&amp;#039; +&lt;br /&gt;
                &amp;#039;&amp;lt;input id=&amp;quot;bd-reason&amp;quot; type=&amp;quot;text&amp;quot; maxlength=&amp;quot;150&amp;quot; placeholder=&amp;quot;例如：清理不适用于国服的外服赛事及平台内容&amp;quot;&amp;gt;&amp;#039; +&lt;br /&gt;
                &amp;#039;&amp;lt;button id=&amp;quot;bd-preview&amp;quot; class=&amp;quot;bd-primary&amp;quot; disabled&amp;gt;① 检查并预览&amp;lt;/button&amp;gt;&amp;#039; +&lt;br /&gt;
                &amp;#039;&amp;lt;button id=&amp;quot;bd-export&amp;quot; disabled&amp;gt;下载 CSV 日志&amp;lt;/button&amp;gt;&amp;#039; +&lt;br /&gt;
                &amp;#039;&amp;lt;/div&amp;gt;&amp;#039; +&lt;br /&gt;
                &amp;#039;&amp;lt;div class=&amp;quot;bd-card&amp;quot;&amp;gt;&amp;#039; +&lt;br /&gt;
                &amp;#039;&amp;lt;p id=&amp;quot;bd-summary&amp;quot; role=&amp;quot;status&amp;quot;&amp;gt;尚未检查页面。&amp;lt;/p&amp;gt;&amp;#039; +&lt;br /&gt;
                &amp;#039;&amp;lt;progress id=&amp;quot;bd-progress&amp;quot; max=&amp;quot;1&amp;quot; value=&amp;quot;0&amp;quot;&amp;gt;&amp;lt;/progress&amp;gt;&amp;#039; +&lt;br /&gt;
                &amp;#039;&amp;lt;div class=&amp;quot;bd-scroll&amp;quot;&amp;gt;&amp;lt;table&amp;gt;&amp;lt;thead&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt;#&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;页面&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;状态&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;详情&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/thead&amp;gt;&amp;lt;tbody id=&amp;quot;bd-rows&amp;quot;&amp;gt;&amp;lt;/tbody&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/div&amp;gt;&amp;#039; +&lt;br /&gt;
                &amp;#039;&amp;lt;/div&amp;gt;&amp;#039; +&lt;br /&gt;
                &amp;#039;&amp;lt;div class=&amp;quot;bd-card&amp;quot;&amp;gt;&amp;#039; +&lt;br /&gt;
                &amp;#039;&amp;lt;label class=&amp;quot;bd-check&amp;quot;&amp;gt;&amp;lt;input id=&amp;quot;bd-agree&amp;quot; type=&amp;quot;checkbox&amp;quot;&amp;gt;&amp;#039; +&lt;br /&gt;
                &amp;#039;&amp;lt;span&amp;gt;我已检查以上列表并做好备份，同意删除所有标记为“待删除”的页面及其历史修订。&amp;lt;/span&amp;gt;&amp;lt;/label&amp;gt;&amp;#039; +&lt;br /&gt;
                &amp;#039;&amp;lt;label for=&amp;quot;bd-confirm&amp;quot;&amp;gt;输入“确认删除”&amp;lt;/label&amp;gt;&amp;lt;input id=&amp;quot;bd-confirm&amp;quot; type=&amp;quot;text&amp;quot; autocomplete=&amp;quot;off&amp;quot;&amp;gt;&amp;#039; +&lt;br /&gt;
                &amp;#039;&amp;lt;button id=&amp;quot;bd-delete&amp;quot; class=&amp;quot;bd-danger&amp;quot; disabled&amp;gt;② 执行批量删除&amp;lt;/button&amp;gt;&amp;#039; +&lt;br /&gt;
                &amp;#039;&amp;lt;button id=&amp;quot;bd-stop&amp;quot; disabled&amp;gt;停止后续删除&amp;lt;/button&amp;gt;&amp;#039; +&lt;br /&gt;
                &amp;#039;&amp;lt;p class=&amp;quot;bd-help&amp;quot;&amp;gt;逐页串行执行，约每秒处理一页。停止不会撤销已完成的删除，也不能取消已经发送的请求。&amp;#039; +&lt;br /&gt;
                &amp;#039;预检后有新修订或页面 ID 变化的页面会跳过；发生结果不明或权限错误时自动停止。失败后请核实删除日志，再重新预检，不自动重试。&amp;lt;/p&amp;gt;&amp;#039; +&lt;br /&gt;
                &amp;#039;&amp;lt;p id=&amp;quot;bd-status&amp;quot; class=&amp;quot;bd-status&amp;quot; role=&amp;quot;status&amp;quot; aria-live=&amp;quot;polite&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;#039; +&lt;br /&gt;
                &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
            function el(id) { return root.querySelector(&amp;#039;#bd-&amp;#039; + id); }&lt;br /&gt;
            function text(id, value) { el(id).textContent = value; }&lt;br /&gt;
            function pending() { return records.filter(function (r) { return r.status === &amp;#039;待删除&amp;#039;; }); }&lt;br /&gt;
            function status(message) { text(&amp;#039;status&amp;#039;, message); }&lt;br /&gt;
            function updateButtons() {&lt;br /&gt;
                el(&amp;#039;preview&amp;#039;).disabled = busy || !rightsOK;&lt;br /&gt;
                el(&amp;#039;titles&amp;#039;).disabled = busy;&lt;br /&gt;
                el(&amp;#039;reason&amp;#039;).disabled = busy;&lt;br /&gt;
                el(&amp;#039;agree&amp;#039;).disabled = busy || !ready;&lt;br /&gt;
                el(&amp;#039;confirm&amp;#039;).disabled = busy || !ready;&lt;br /&gt;
                el(&amp;#039;delete&amp;#039;).disabled = busy || !ready || !rightsOK || !pending().length ||&lt;br /&gt;
                    !el(&amp;#039;reason&amp;#039;).value.trim() || !el(&amp;#039;agree&amp;#039;).checked || el(&amp;#039;confirm&amp;#039;).value.trim() !== &amp;#039;确认删除&amp;#039;;&lt;br /&gt;
                el(&amp;#039;stop&amp;#039;).disabled = !running || stopping;&lt;br /&gt;
                el(&amp;#039;export&amp;#039;).disabled = !records.length;&lt;br /&gt;
            }&lt;br /&gt;
            function invalidate() {&lt;br /&gt;
                if (busy) { return; }&lt;br /&gt;
                ready = false;&lt;br /&gt;
                el(&amp;#039;agree&amp;#039;).checked = false;&lt;br /&gt;
                el(&amp;#039;confirm&amp;#039;).value = &amp;#039;&amp;#039;;&lt;br /&gt;
                status(&amp;#039;输入已变更，请重新检查并预览。&amp;#039;);&lt;br /&gt;
                updateButtons();&lt;br /&gt;
            }&lt;br /&gt;
            function request(params, write) {&lt;br /&gt;
                return new Promise(function (resolve, reject) {&lt;br /&gt;
                    var q = write ? api.postWithToken(&amp;#039;csrf&amp;#039;, params) : api.post(params);&lt;br /&gt;
                    q.then(resolve, function (code, result) {&lt;br /&gt;
                        var detail = result &amp;amp;&amp;amp; result.error &amp;amp;&amp;amp; result.error.info;&lt;br /&gt;
                        if (!detail &amp;amp;&amp;amp; result &amp;amp;&amp;amp; result.textStatus) { detail = result.textStatus; }&lt;br /&gt;
                        reject({ code: String(code || &amp;#039;unknown&amp;#039;), info: String(detail || code || &amp;#039;请求失败&amp;#039;) });&lt;br /&gt;
                    });&lt;br /&gt;
                });&lt;br /&gt;
            }&lt;br /&gt;
            function identity() {&lt;br /&gt;
                return request({ action: &amp;#039;query&amp;#039;, meta: &amp;#039;userinfo&amp;#039;, uiprop: &amp;#039;rights&amp;#039;, formatversion: 2 }).then(function (data) {&lt;br /&gt;
                    var u = data.query &amp;amp;&amp;amp; data.query.userinfo;&lt;br /&gt;
                    if (!u || !u.id || (u.rights || []).indexOf(&amp;#039;delete&amp;#039;) === -1) {&lt;br /&gt;
                        throw { code: &amp;#039;permissiondenied&amp;#039;, info: &amp;#039;当前账号未登录或没有 delete（删除页面）权限。界面管理员身份不一定包含此权限。&amp;#039; };&lt;br /&gt;
                    }&lt;br /&gt;
                    if (account &amp;amp;&amp;amp; account.id !== u.id) {&lt;br /&gt;
                        throw { code: &amp;#039;accountchanged&amp;#039;, info: &amp;#039;登录账号发生变化，请刷新本页面后重试。&amp;#039; };&lt;br /&gt;
                    }&lt;br /&gt;
                    return u;&lt;br /&gt;
                });&lt;br /&gt;
            }&lt;br /&gt;
            function render() {&lt;br /&gt;
                var body = el(&amp;#039;rows&amp;#039;);&lt;br /&gt;
                body.textContent = &amp;#039;&amp;#039;;&lt;br /&gt;
                records.forEach(function (r, i) {&lt;br /&gt;
                    var tr = document.createElement(&amp;#039;tr&amp;#039;);&lt;br /&gt;
                    [String(i + 1), r.title, r.status, r.detail || &amp;#039;&amp;#039;].forEach(function (s, j) {&lt;br /&gt;
                        var td = document.createElement(&amp;#039;td&amp;#039;);&lt;br /&gt;
                        if (j === 1 &amp;amp;&amp;amp; r.pageid) {&lt;br /&gt;
                            var a = document.createElement(&amp;#039;a&amp;#039;);&lt;br /&gt;
                            a.href = mw.util.getUrl(r.title);&lt;br /&gt;
                            a.target = &amp;#039;_blank&amp;#039;;&lt;br /&gt;
                            a.rel = &amp;#039;noopener noreferrer&amp;#039;;&lt;br /&gt;
                            a.textContent = s;&lt;br /&gt;
                            td.appendChild(a);&lt;br /&gt;
                        } else { td.textContent = s; }&lt;br /&gt;
                        tr.appendChild(td);&lt;br /&gt;
                    });&lt;br /&gt;
                    body.appendChild(tr);&lt;br /&gt;
                });&lt;br /&gt;
                var counts = {};&lt;br /&gt;
                records.forEach(function (r) { counts[r.status] = (counts[r.status] || 0) + 1; });&lt;br /&gt;
                text(&amp;#039;summary&amp;#039;, &amp;#039;共 &amp;#039; + records.length + &amp;#039; 页 · &amp;#039; + Object.keys(counts).map(function (k) { return k + &amp;#039; &amp;#039; + counts[k]; }).join(&amp;#039; / &amp;#039;));&lt;br /&gt;
            }&lt;br /&gt;
            function unsafePage(p) {&lt;br /&gt;
                if ([6, 7, 8, 9].indexOf(p.ns) !== -1) {&lt;br /&gt;
                    return &amp;#039;安全限制：不批量删除文件、文件讨论、界面及界面讨论页面。&amp;#039;;&lt;br /&gt;
                }&lt;br /&gt;
                if (p.ns === 4 &amp;amp;&amp;amp; p.title.slice(p.title.indexOf(&amp;#039;:&amp;#039;) + 1) === &amp;#039;批量删除&amp;#039;) {&lt;br /&gt;
                    return &amp;#039;安全限制：不能删除本工具入口。&amp;#039;;&lt;br /&gt;
                }&lt;br /&gt;
                return &amp;#039;&amp;#039;;&lt;br /&gt;
            }&lt;br /&gt;
            function collect() {&lt;br /&gt;
                var seen = Object.create(null), result = [];&lt;br /&gt;
                el(&amp;#039;titles&amp;#039;).value.split(/\r?\n/).forEach(function (line) {&lt;br /&gt;
                    var s = line.trim().replace(/_/g, &amp;#039; &amp;#039;);&lt;br /&gt;
                    if (!s || seen[s]) { return; }&lt;br /&gt;
                    seen[s] = true;&lt;br /&gt;
                    var r = { input: s, title: s, status: &amp;#039;待检查&amp;#039;, detail: &amp;#039;&amp;#039;, pageid: null, revid: null, time: &amp;#039;&amp;#039;, reason: &amp;#039;&amp;#039; };&lt;br /&gt;
                    if (/[\[\]#|&amp;lt;&amp;gt;\u0000-\u001f]/.test(s) || /^(?:[a-z][a-z0-9+.-]*:)?\/\//i.test(s)) {&lt;br /&gt;
                        r.status = &amp;#039;输入无效&amp;#039;; r.detail = &amp;#039;请填写页面名称，不要填写网址、链接语法、章节或控制字符。&amp;#039;;&lt;br /&gt;
                    }&lt;br /&gt;
                    result.push(r);&lt;br /&gt;
                });&lt;br /&gt;
                return result;&lt;br /&gt;
            }&lt;br /&gt;
            async function preview() {&lt;br /&gt;
                if (busy) { return; }&lt;br /&gt;
                var next = collect();&lt;br /&gt;
                if (!next.length) { status(&amp;#039;请至少输入一个页面名称。&amp;#039;); return; }&lt;br /&gt;
                if (next.length &amp;gt; LIMIT) { status(&amp;#039;一次最多检查 500 页，请分批执行。&amp;#039;); return; }&lt;br /&gt;
                if (!el(&amp;#039;reason&amp;#039;).value.trim()) { status(&amp;#039;请填写删除理由。&amp;#039;); return; }&lt;br /&gt;
                records = next; busy = true; ready = false;&lt;br /&gt;
                el(&amp;#039;agree&amp;#039;).checked = false; el(&amp;#039;confirm&amp;#039;).value = &amp;#039;&amp;#039;;&lt;br /&gt;
                el(&amp;#039;progress&amp;#039;).max = records.length; el(&amp;#039;progress&amp;#039;).value = 0;&lt;br /&gt;
                records.forEach(function (r) { r.reason = el(&amp;#039;reason&amp;#039;).value.trim(); });&lt;br /&gt;
                updateButtons(); render(); status(&amp;#039;正在预检，尚未执行任何删除……&amp;#039;);&lt;br /&gt;
                try {&lt;br /&gt;
                    await identity();&lt;br /&gt;
                    var list = records.filter(function (r) { return r.status === &amp;#039;待检查&amp;#039;; });&lt;br /&gt;
                    var seenIds = Object.create(null);&lt;br /&gt;
                    for (var i = 0; i &amp;lt; list.length; i += 50) {&lt;br /&gt;
                        var batch = list.slice(i, i + 50);&lt;br /&gt;
                        var data = await request({ action: &amp;#039;query&amp;#039;, prop: &amp;#039;info&amp;#039;, titles: batch.map(function (r) { return r.title; }).join(&amp;#039;|&amp;#039;),&lt;br /&gt;
                            assert: &amp;#039;user&amp;#039;, formatversion: 2 });&lt;br /&gt;
                        var q = data.query || {}, aliases = Object.create(null), pages = q.pages || [];&lt;br /&gt;
                        (q.normalized || []).concat(q.converted || []).forEach(function (n) { aliases[n.from] = n.to; });&lt;br /&gt;
                        function canonical(title) {&lt;br /&gt;
                            var visited = Object.create(null);&lt;br /&gt;
                            while (aliases[title] &amp;amp;&amp;amp; !visited[title]) { visited[title] = true; title = aliases[title]; }&lt;br /&gt;
                            return title;&lt;br /&gt;
                        }&lt;br /&gt;
                        batch.forEach(function (r) {&lt;br /&gt;
                            r.title = canonical(r.title);&lt;br /&gt;
                            var p = pages.find(function (x) { return x.title === r.title; });&lt;br /&gt;
                            if (!p) { r.status = &amp;#039;跳过&amp;#039;; r.detail = &amp;#039;未找到本站页面信息（可能为跨站名称）。&amp;#039;; return; }&lt;br /&gt;
                            if (p.invalid || p.ns &amp;lt; 0) { r.status = &amp;#039;输入无效&amp;#039;; r.detail = p.invalidreason || &amp;#039;无效或特殊页面。&amp;#039;; return; }&lt;br /&gt;
                            if (p.missing || !p.pageid) { r.status = &amp;#039;不存在&amp;#039;; r.detail = &amp;#039;无需删除。&amp;#039;; return; }&lt;br /&gt;
                            r.pageid = p.pageid; r.revid = p.lastrevid; r.title = p.title;&lt;br /&gt;
                            var blocked = unsafePage(p);&lt;br /&gt;
                            if (blocked) { r.status = &amp;#039;跳过&amp;#039;; r.detail = blocked; return; }&lt;br /&gt;
                            if (seenIds[p.pageid]) { r.status = &amp;#039;重复页面&amp;#039;; r.detail = &amp;#039;规范化后与其他输入相同，不重复操作。&amp;#039;; return; }&lt;br /&gt;
                            seenIds[p.pageid] = true;&lt;br /&gt;
                            r.status = &amp;#039;待删除&amp;#039;;&lt;br /&gt;
                            r.detail = &amp;#039;页面 ID &amp;#039; + p.pageid + &amp;#039;；最新修订 &amp;#039; + p.lastrevid + (p.redirect ? &amp;#039;；这是重定向页，只删除此页。&amp;#039; : &amp;#039;&amp;#039;);&lt;br /&gt;
                        });&lt;br /&gt;
                        el(&amp;#039;progress&amp;#039;).value = Math.min(records.length, i + batch.length);&lt;br /&gt;
                        render();&lt;br /&gt;
                    }&lt;br /&gt;
                    ready = true; el(&amp;#039;progress&amp;#039;).value = records.length;&lt;br /&gt;
                    status(&amp;#039;预检完成。请核对列表，再勾选确认并输入“确认删除”。&amp;#039;);&lt;br /&gt;
                } catch (e) {&lt;br /&gt;
                    ready = false;&lt;br /&gt;
                    records.forEach(function (r) { if (r.status === &amp;#039;待检查&amp;#039;) { r.status = &amp;#039;检查失败&amp;#039;; r.detail = e.info || String(e); } });&lt;br /&gt;
                    status(&amp;#039;预检未完成，禁止执行删除：&amp;#039; + (e.info || String(e)));&lt;br /&gt;
                } finally { busy = false; render(); updateButtons(); }&lt;br /&gt;
            }&lt;br /&gt;
            function sleep(ms) { return new Promise(function (resolve) { setTimeout(resolve, ms); }); }&lt;br /&gt;
            async function execute() {&lt;br /&gt;
                if (el(&amp;#039;delete&amp;#039;).disabled || busy) { return; }&lt;br /&gt;
                var jobs = pending().slice(), reason = el(&amp;#039;reason&amp;#039;).value.trim();&lt;br /&gt;
                if (!window.confirm(&amp;#039;最后确认：以“&amp;#039; + account.name + &amp;#039;”删除 &amp;#039; + jobs.length + &amp;#039; 个页面及其修订历史？\n\n理由：&amp;#039; + reason + &amp;#039;\n\n已完成的删除不会因点击停止而撤销。&amp;#039;)) { return; }&lt;br /&gt;
                busy = true; running = true; stopping = false; ready = false;&lt;br /&gt;
                el(&amp;#039;progress&amp;#039;).max = jobs.length; el(&amp;#039;progress&amp;#039;).value = 0;&lt;br /&gt;
                updateButtons();&lt;br /&gt;
                var processed = 0;&lt;br /&gt;
                try {&lt;br /&gt;
                    await identity();&lt;br /&gt;
                    for (var i = 0; i &amp;lt; jobs.length; i++) {&lt;br /&gt;
                        if (stopping) { break; }&lt;br /&gt;
                        var r = jobs[i]; activeJob = r; r.status = &amp;#039;核对中&amp;#039;; render();&lt;br /&gt;
                        status(&amp;#039;正在处理 &amp;#039; + (i + 1) + &amp;#039; / &amp;#039; + jobs.length + &amp;#039;：&amp;#039; + r.title);&lt;br /&gt;
                        var sentDelete = false;&lt;br /&gt;
                        try {&lt;br /&gt;
                            // Preflight by title: a move/recreation/revision change since preview is skipped.&lt;br /&gt;
                            var check = await request({ action: &amp;#039;query&amp;#039;, titles: r.title, prop: &amp;#039;info&amp;#039;, formatversion: 2, assert: &amp;#039;user&amp;#039; });&lt;br /&gt;
                            var p = check.query &amp;amp;&amp;amp; check.query.pages &amp;amp;&amp;amp; check.query.pages[0];&lt;br /&gt;
                            if (stopping) { r.status = &amp;#039;未执行&amp;#039;; r.detail = &amp;#039;已停止，未发送删除请求。&amp;#039;; break; }&lt;br /&gt;
                            if (!p || p.missing || p.invalid || p.pageid !== r.pageid || p.lastrevid !== r.revid || p.title !== r.title) {&lt;br /&gt;
                                r.status = &amp;#039;变化跳过&amp;#039;; r.detail = &amp;#039;预检后页面已改动、移动、重建或删除。请重新检查。&amp;#039;;&lt;br /&gt;
                            } else {&lt;br /&gt;
                                r.status = &amp;#039;删除中&amp;#039;; render(); sentDelete = true;&lt;br /&gt;
                                var result = await request({ action: &amp;#039;delete&amp;#039;, pageid: r.pageid, reason: reason,&lt;br /&gt;
                                    assert: &amp;#039;user&amp;#039;, assertuser: account.name, watchlist: &amp;#039;nochange&amp;#039;, formatversion: 2, maxlag: 5 }, true);&lt;br /&gt;
                                if (!result.delete || result.delete.pageid !== r.pageid) {&lt;br /&gt;
                                    throw { code: &amp;#039;unexpected-response&amp;#039;, info: &amp;#039;未收到可核实的删除成功响应，请检查本站删除日志。&amp;#039; };&lt;br /&gt;
                                }&lt;br /&gt;
                                r.status = &amp;#039;已删除&amp;#039;; r.detail = &amp;#039;删除成功；&amp;#039; + (result.delete.title || r.title);&lt;br /&gt;
                                if (result.delete.logid) { r.detail += &amp;#039;；日志 ID &amp;#039; + result.delete.logid; }&lt;br /&gt;
                            }&lt;br /&gt;
                        } catch (e) {&lt;br /&gt;
                            var code = e.code || &amp;#039;unknown&amp;#039;;&lt;br /&gt;
                            var uncertain = sentDelete &amp;amp;&amp;amp; [&amp;#039;http&amp;#039;, &amp;#039;unknown&amp;#039;, &amp;#039;unexpected-response&amp;#039;, &amp;#039;timeout&amp;#039;, &amp;#039;abort&amp;#039;].indexOf(code) !== -1;&lt;br /&gt;
                            r.status = uncertain ? &amp;#039;结果待核实&amp;#039; : &amp;#039;失败&amp;#039;;&lt;br /&gt;
                            r.detail = code + &amp;#039;：&amp;#039; + (e.info || String(e));&lt;br /&gt;
                            // Do not retry deletion. Stop on any exception; user must verify current state first.&lt;br /&gt;
                            stopping = true;&lt;br /&gt;
                            status(&amp;#039;已暂停：&amp;#039; + r.title + &amp;#039;\n&amp;#039; + r.detail + &amp;#039;\n请检查页面和本站删除日志，再重新预检。&amp;#039;);&lt;br /&gt;
                        } finally {&lt;br /&gt;
                            r.time = new Date().toISOString(); r.reason = reason;&lt;br /&gt;
                            processed++; el(&amp;#039;progress&amp;#039;).value = processed; render();&lt;br /&gt;
                        }&lt;br /&gt;
                        activeJob = null;&lt;br /&gt;
                        if (!stopping &amp;amp;&amp;amp; i &amp;lt; jobs.length - 1) { await sleep(1000); }&lt;br /&gt;
                    }&lt;br /&gt;
                } catch (e) {&lt;br /&gt;
                    stopping = true; status(&amp;#039;无法继续：&amp;#039; + (e.info || String(e)));&lt;br /&gt;
                } finally {&lt;br /&gt;
                    jobs.forEach(function (r) {&lt;br /&gt;
                        if (r.status === &amp;#039;待删除&amp;#039; || r.status === &amp;#039;核对中&amp;#039;) { r.status = &amp;#039;未执行&amp;#039;; r.detail = &amp;#039;批次停止，未发送删除请求。&amp;#039;; }&lt;br /&gt;
                    });&lt;br /&gt;
                    activeJob = null; busy = false; running = false; ready = false;&lt;br /&gt;
                    el(&amp;#039;agree&amp;#039;).checked = false; el(&amp;#039;confirm&amp;#039;).value = &amp;#039;&amp;#039;;&lt;br /&gt;
                    render(); updateButtons();&lt;br /&gt;
                    if (!stopping) { status(&amp;#039;本批次处理完成。建议下载日志留档。再次执行需要重新预检。&amp;#039;); }&lt;br /&gt;
                    else { status(el(&amp;#039;status&amp;#039;).textContent + &amp;#039;\n批次已停止。已完成的删除未撤销；请下载日志。&amp;#039;); }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            function csvCell(value) {&lt;br /&gt;
                var s = String(value == null ? &amp;#039;&amp;#039; : value);&lt;br /&gt;
                // Protect spreadsheet formula injection, including page names beginning with =,+,-,@.&lt;br /&gt;
                if (/^[\s]*[=+\-@]/.test(s)) { s = &amp;quot;&amp;#039;&amp;quot; + s; }&lt;br /&gt;
                return &amp;#039;&amp;quot;&amp;#039; + s.replace(/&amp;quot;/g, &amp;#039;&amp;quot;&amp;quot;&amp;#039;) + &amp;#039;&amp;quot;&amp;#039;;&lt;br /&gt;
            }&lt;br /&gt;
            function exportLog() {&lt;br /&gt;
                var rows = [[&amp;#039;序号&amp;#039;, &amp;#039;输入名称&amp;#039;, &amp;#039;规范页面名&amp;#039;, &amp;#039;页面ID&amp;#039;, &amp;#039;预检修订ID&amp;#039;, &amp;#039;状态&amp;#039;, &amp;#039;详情&amp;#039;, &amp;#039;删除理由&amp;#039;, &amp;#039;处理时间UTC&amp;#039;, &amp;#039;操作账号&amp;#039;]];&lt;br /&gt;
                records.forEach(function (r, i) { rows.push([i + 1, r.input, r.title, r.pageid, r.revid, r.status, r.detail, r.reason, r.time, account ? account.name : &amp;#039;&amp;#039;]); });&lt;br /&gt;
                var csv = &amp;#039;\uFEFF&amp;#039; + rows.map(function (row) { return row.map(csvCell).join(&amp;#039;,&amp;#039;); }).join(&amp;#039;\r\n&amp;#039;);&lt;br /&gt;
                var url = URL.createObjectURL(new Blob([csv], { type: &amp;#039;text/csv;charset=utf-8&amp;#039; }));&lt;br /&gt;
                var a = document.createElement(&amp;#039;a&amp;#039;); a.href = url;&lt;br /&gt;
                a.download = &amp;#039;Wiki批量删除日志-&amp;#039; + new Date().toISOString().replace(/[:.]/g, &amp;#039;-&amp;#039;) + &amp;#039;.csv&amp;#039;;&lt;br /&gt;
                document.body.appendChild(a); a.click(); a.remove();&lt;br /&gt;
                setTimeout(function () { URL.revokeObjectURL(url); }, 30000);&lt;br /&gt;
            }&lt;br /&gt;
            el(&amp;#039;titles&amp;#039;).addEventListener(&amp;#039;input&amp;#039;, invalidate);&lt;br /&gt;
            el(&amp;#039;reason&amp;#039;).addEventListener(&amp;#039;input&amp;#039;, invalidate);&lt;br /&gt;
            el(&amp;#039;agree&amp;#039;).addEventListener(&amp;#039;change&amp;#039;, updateButtons);&lt;br /&gt;
            el(&amp;#039;confirm&amp;#039;).addEventListener(&amp;#039;input&amp;#039;, updateButtons);&lt;br /&gt;
            el(&amp;#039;preview&amp;#039;).addEventListener(&amp;#039;click&amp;#039;, preview);&lt;br /&gt;
            el(&amp;#039;delete&amp;#039;).addEventListener(&amp;#039;click&amp;#039;, execute);&lt;br /&gt;
            el(&amp;#039;stop&amp;#039;).addEventListener(&amp;#039;click&amp;#039;, function () {&lt;br /&gt;
                stopping = true; updateButtons();&lt;br /&gt;
                status(&amp;#039;已请求停止。&amp;#039; + (activeJob ? &amp;#039;等待当前步骤返回：&amp;#039; + activeJob.title : &amp;#039;不再开始下一页。&amp;#039;));&lt;br /&gt;
            });&lt;br /&gt;
            el(&amp;#039;export&amp;#039;).addEventListener(&amp;#039;click&amp;#039;, exportLog);&lt;br /&gt;
            window.addEventListener(&amp;#039;beforeunload&amp;#039;, function (event) {&lt;br /&gt;
                if (busy) { event.preventDefault(); event.returnValue = &amp;#039;&amp;#039;; }&lt;br /&gt;
            });&lt;br /&gt;
            identity().then(function (u) {&lt;br /&gt;
                account = { id: u.id, name: u.name }; rightsOK = true;&lt;br /&gt;
                text(&amp;#039;permission&amp;#039;, &amp;#039;当前账号：&amp;#039; + u.name + &amp;#039; · 已具备删除页面权限。&amp;#039;);&lt;br /&gt;
                updateButtons();&lt;br /&gt;
            }).catch(function (e) {&lt;br /&gt;
                rightsOK = false; text(&amp;#039;permission&amp;#039;, e.info || String(e)); updateButtons();&lt;br /&gt;
            });&lt;br /&gt;
            updateButtons();&lt;br /&gt;
        });&lt;br /&gt;
    }).catch(function () {&lt;br /&gt;
        var root = document.getElementById(&amp;#039;wiki-batch-delete&amp;#039;);&lt;br /&gt;
        if (root) { root.textContent = &amp;#039;批量删除工具加载失败，请刷新页面或检查浏览器控制台。&amp;#039;; }&lt;br /&gt;
    });&lt;br /&gt;
}());&lt;/div&gt;</summary>
		<author><name>Wiki-editor-3dtank</name></author>
	</entry>
</feed>