Greasy Fork is available in English.

百度网盘 - 更高级的重命名

你不知道的百度网盘重命名姿势~支持批量替换重命名、手动批量修改后一次提交、智能重命名,拒绝转圈圈!

Cài đặt script này?
Script được tác giả gợi ý

Bạn có thế thích 喜马拉雅专辑下载器

Cài đặt script này
// ==UserScript==
// @name            百度网盘 - 更高级的重命名
// @version         1.0.5
// @description     你不知道的百度网盘重命名姿势~支持批量替换重命名、手动批量修改后一次提交、智能重命名,拒绝转圈圈!
// @author          Priate
// @match           https://pan.baidu.com/*
// @grant           GM_setValue
// @grant           GM_getValue
// @grant           GM_addStyle
// @icon            https://nd-static.bdstatic.com/m-static/v20-main/favicon-main.ico
// @require         https://unpkg.com/vue@2
// @require         https://unpkg.com/sweetalert@2.1.2/dist/sweetalert.min.js
// @require         https://unpkg.com/jquery@3.2.1/dist/jquery.min.js
// @require         https://greasyfork.org/scripts/435476-priatelib/code/PriateLib.js?version=1202493
// @supportURL      https://greasyfork.org/scripts/443771/feedback
// @homepageURL     https://greasyfork.org/scripts/443771
// @contributionURL https://afdian.net/@cyberubbish
// @license         MIT
// @namespace       https://greasyfork.org/users/219866
// ==/UserScript==

(function() {
	'use strict';

	function initSetting() {
		var setting;
		if (!GM_getValue('priate_script_bdwp_data')) {
			GM_setValue('priate_script_bdwp_data', {
				left: 20,
				top: 100,
			})
		}
		setting = GM_getValue('priate_script_bdwp_data')
		GM_setValue('priate_script_bdwp_data', setting)
	}

	function injectDiv() {
		var priate_script_div = document.createElement("div")
		priate_script_div.innerHTML = `
<div id="priate_script_div">
<b style='font-size:30px; font-weight:300; margin: 10px 20px'>更高级的重命名</b>
<p id='priate_script_setting' style='margin: 0 0'>
❤️ by <a @click='openDonate' style='color:#337ab7'>Priate</a> |
v <a href="//greasyfork.org/scripts/443771" target="_blank" style='color:#ff6666'>{{version}}</a> |
<a @click="switchDrag">📌</a> | <a @click="recoverText">♻️</a> | <a v-show="data.length > 0" @click="smartRename">🤖️ |</a> <a @click="clearData">❌</a>
<br>
文件夹重命名 : <a @click='todo' :style='"color:" + (false ? "#00947e" : "#CC0F35")'> 关闭 </a> |
正则 : <a @click='todo' :style='"color:" + (false ? "#00947e" : "#CC0F35")'> 关闭 </a>
<div v-show="data.length">
<a style='color:#946C00;' @click="changeOriginText" v-show="showOriginText">{{'【' + originText + '】'}}</a>
<textarea class="replaceArea" ref="originTextInput" v-show="!showOriginText" @blur="recoverOriginText" type="text" v-model="originText" ></textarea>
<a @click="autoRename">➡️ ➡️ ➡️</a>
<a style='color:#00947e' @click="changeReplaceText" v-show="showReplaceText">{{'【' + replaceText + '】' }}</a>
<textarea class="replaceArea" ref="replaceTextInput" v-show="!showReplaceText" @blur="recoverReplaceText" type="text" v-model="replaceText" ></textarea>
</div>
</p>
<button @click="loadData">{{data.length > 0 ? '重载数据' : '加载数据'}}</button>
<button @click="postRename" v-show="musicList.length > 0"> 确定修改 </button>
</br>
<table v-show="data.length > 0">
<thead><tr><th></th><th>原始文件名</th><th>修改后文件名</th></tr></thead>
<tbody id="priate_script_table">
<tr v-for="(item, index) in data" :key="index">
<td><input class="checkMusicBox" v-model="musicList" :value='item' type="checkbox" :disabled="item.replace == item.origin"></td>
<td><a @click="originText = item.origin" style='color:#337ab7'>{{item.origin}}</a></td>
<td><a v-show="!item.isChanging" @click="manualRename(item)" style='color:#C01D07'>{{item.replace}}</a><textarea class="replaceArea" :ref="item.id" @blur="modifyReplace(item)" v-show="item.isChanging" v-model="item.replace"></textarea></td>
</tr>
</tbody>
</table>
</div>
`
		GM_addStyle(`
#priate_script_div{
font-size : 15px;
position: fixed;
background-color: rgb(240, 223, 175);
color : #660000;
text-align : center;
padding: 10px;
z-index : 9999;
border-radius : 20px;
border:2px solid #660000;
font-weight: 300;
text-stroke: 0.5px;
box-shadow: 5px 15px 15px rgba(0,0,0,0.4);
user-select : none;
-webkit-user-select : none;
-moz-user-select : none;
-ms-user-select:none;
}
#priate_script_div:hover{
box-shadow: 5px 15px 15px rgba(0,0,0,0.8);
transition: box-shadow 0.3s;
}

#priate_script_div a{
margin-bottom: 2px !important;
}
.priate_script_hide{
padding: 0 !important;
border:none !important;
}
a{
cursor : pointer;
text-decoration : none;
}
/*表格样式*/
#priate_script_div table{
text-align: center;
// border:2px solid #660000;
margin: 5px auto;
padding: 2px;
border-collapse: collapse;
display: block;
height : 400px;
overflow-y: scroll;
}
/*表格框样式*/
#priate_script_div td{
border:2px solid #660000;
padding: 8px 12px;
max-width : 300px;
word-wrap : break-word;
}
/*表头样式*/
#priate_script_div th{
border:2px solid #660000;
padding: 8px 12px;
font-weight: 300;
-webkit-text-stroke: 0.5px;
text-stroke: 0.5px;
}

/*脚本按钮样式*/
#priate_script_div button{
display: inline-block;
border-radius: 4px;
border: 1px solid #660000;
background-color: transparent;
color: #660000;
text-decoration: none;
padding: 5px 10px;
margin : 5px 10px;
font-weight: 300;
-webkit-text-stroke: 0.5px;
text-stroke: 0.5px;
}
/*脚本按钮悬浮样式*/
#priate_script_div button:hover{
cursor : pointer;
color: rgb(240, 223, 175);
background-color: #660000;
transition: background-color 0.2s;
}
/*设置区域 p 标签*/
#priate_script_setting{
user-select : none;
-webkit-user-select : none;
-moz-user-select : none;
-ms-user-select:none;
}
/*swal按钮*/
.swal-button--1{
background-color: #FFFAEB !important;
color: #946C00;
}
.swal-button--2{
background-color: #ebfffc !important;
color: #00947e;
}
.swal-button--3{
background-color: #ECF6FD !important;
color: #55ACEE;
}
.checkMusicBox{
transform: scale(1.7,1.7);
cursor: pointer;
}
.replaceArea{
height : 100%;
width : 100%;
background-color: #fff;
border:1px solid #000000;
padding: 4px;
border-radius: 4px;
}
.replaceInput{
height : 100%;
width : 40%;
background-color: #fff;
border:1px solid #000000;
padding: 4px;
border-radius: 4px;
}
`);
		document.querySelector("html").appendChild(priate_script_div)
		var setting = GM_getValue('priate_script_bdwp_data')
		document.getElementById("priate_script_div").style.left = (setting.left || 20) + "px";
		document.getElementById("priate_script_div").style.top = (setting.top || 100) + "px";
	}

	function dragFunc(id) {
		var Drag = document.getElementById(id);
		var setting = GM_getValue('priate_script_bdwp_data')
		Drag.onmousedown = function(event) {
			var ev = event || window.event;
			event.stopPropagation();
			var disX = ev.clientX - Drag.offsetLeft;
			var disY = ev.clientY - Drag.offsetTop;
			document.onmousemove = function(event) {
				var ev = event || window.event;
				setting.left = ev.clientX - disX
				Drag.style.left = setting.left + "px";
				setting.top = ev.clientY - disY
				Drag.style.top = setting.top + "px";
				Drag.style.cursor = "move";
				GM_setValue('priate_script_bdwp_data', setting)
			};
		};
		Drag.onmouseup = function() {
			document.onmousemove = null;
			this.style.cursor = "default";
		};
	};

	function unDragFunc(id) {
		var Drag = document.getElementById(id);
		Drag.onmousedown = function(event) {
			var ev = event || window.event;
			event.stopPropagation();
		};
		Drag.onmouseup = function() {};
		Drag.onmousemove = function() {};
	};

	//初始化脚本设置
	initSetting()
	//注入脚本div
	injectDiv()

	function getToken() {
		return document.querySelector(".nd-main-list, .nd-new-main-list").__vue__.yunData.bdstoken;
	}

	function getLogid() {
		let ut = unsafeWindow.require("system-core:context/context.js").instanceForSystem.tools.baseService;
		return ut.base64Encode(base.getCookie("BAIDUID"));
	}

	function getPath() {
		var nowPath = location.href.match(/path=(.+?)(?:&|$)/);
		var pathValue;
		if (nowPath)
			pathValue = decodeURIComponent(nowPath[1]);
		else
			pathValue = "/";
		if (pathValue.charAt(0) !== "/")
			pathValue = "/" + pathValue; // 补齐路径前缀斜杠
		if (pathValue.charAt(pathValue.length - 1) !== "/")
			pathValue += "/"
		return pathValue
	}

	function reloadList() {
		document.querySelector(".nd-main-list, .nd-new-main-list").__vue__.reloadList();
	}

	// 处理数据等逻辑
	var vm = new Vue({
		el: '#priate_script_div',
		data: {
			version: "1.0.5",
			setting: GM_getValue('priate_script_bdwp_data'),
			data: [],
			musicList: [],
			showOriginText: true,
			showReplaceText: true,
			originText: "需要替换的内容",
			replaceText: "",
			path: '/',
			isDrag: true,
		},
		methods: {
			loadData() {
				const path = getPath()
				this.path = path
				const all_tr = document.querySelectorAll('table.wp-s-pan-table__body-table tbody>tr');
				var result = [];
				var _this = this
				all_tr.forEach((item) => {
					const type = item.querySelector('img[alt]') ? item.querySelector('img[alt]').getAttribute('alt') : 'unknow'
					if (!item.querySelector('a')) return
					const music = {
						id: item.getAttribute('data-id'),
						origin: item.querySelector('a').getAttribute('title'),
						replace: item.querySelector('a').getAttribute('title'),
						isChanging: false,
						type,
						isFolder: type == 'folder',
					}
					result.push(music)
				})
				// 如果仍未获取到数据
				if (result.length == 0) {
					swal("未获取到数据,请确认此目录下有文件或文件夹!", {
						icon: "error",
						buttons: false,
						timer: 3000,
					});
				}
				this.data = result
				this.musicList = []
			},
			clearData() {
				if (this.data.length == 0) swal(`已经是最简形态了!`, {
					buttons: false,
					timer: 2000,
				});
				this.data = []
				this.musicList = []
			},
			openDonate() {
				showDonate()
			},
			async manualRename(item) {
				this.unDrag()
				item.isChanging = true
				await Sleep(0.01)
				this.$refs[item.id][0].focus();
			},
			modifyReplace(item) {
				this.drag()
				item.isChanging = false
				item.replace = item.replace.trim()
				if (item.replace != item.origin) {
					if (!this.musicList.find(el => el.id == item.id)) {
						this.musicList.push(item)
					}
				} else {
					this.musicList = this.musicList.filter(el => el.id != item.id)
				}

			},
			autoRename() {
				var _this = this
				const origin = this.originText
				const replace = this.replaceText
				var hasChanged = false
				var hasEmpty = false
				this.data.forEach(item => {
					item.replace = item.replace.replace(origin, replace).trim()
					if (item.replace !== item.origin) {
						hasChanged = true
					}
					if (item.replace == "") {
						hasEmpty = true
						item.replace = item.origin
					}
					_this.modifyReplace(item)
				})
				if (!hasChanged) swal(`没有匹配到任何需要修改的文件!`, {
					icon: "error",
					buttons: false,
					timer: 3000,
				});
				if (hasEmpty) swal(`替换后某个文件名为空!`, {
					icon: "error",
					buttons: false,
					timer: 3000,
				});
			},
			async postRename() {
				var _this = this
				const token = getToken()
				// const logid = getLogid()
				const data = this.musicList.map(item => {
					return {
						id: item.id,
						path: `${_this.path}${item.origin}`,
						newname: item.replace,
					}
				})
				$.ajax(`https://pan.baidu.com/api/filemanager?async=2&onnest=fail&opera=rename&bdstoken=${getToken()}&clienttype=0&app_id=250528&web=1`, {
					type: 'post',
					data: {
						filelist: JSON.stringify(data)
					},
					complete: function(res) {
						const resp = res.responseJSON
						if (resp['errno'] == 0) {
							swal(`重命名已完成!\n如部分文件显示未修改请点击 ♻️ 按钮手动刷新!`, {
								icon: "success",
								buttons: false,
								timer: 3000,
							});
						} else {
							swal(`重命名失败!`, {
								icon: "error",
								buttons: false,
								timer: 3000,
							});
						}
						_this.clearData()
					}
				});
				await Sleep(3)
				reloadList()
			},
			switchDrag() {
				if (this.isDrag) {
					this.unDrag()
					swal(`悬浮窗已固定`, {
						buttons: false,
						timer: 2000,
					});
				} else {
					this.drag()
					swal(`悬浮窗可以拖动了`, {
						buttons: false,
						timer: 2000,
					});
				}
			},
			unDrag() {
				this.isDrag = false
				unDragFunc("priate_script_div")
			},
			drag() {
				this.isDrag = true
				dragFunc("priate_script_div")
			},
			async changeOriginText() {
				this.unDrag()
				this.showOriginText = false
				await Sleep(0.01)
				this.$refs.originTextInput.focus();
			},
			async changeReplaceText() {
				this.unDrag()
				this.showReplaceText = false
				await Sleep(0.01)
				this.$refs.replaceTextInput.focus();
			},
			recoverOriginText() {
				this.drag()
				this.showOriginText = true
			},
			recoverReplaceText() {
				this.drag()
				this.showReplaceText = true
			},
			recoverText() {
				reloadList()
			},
			smartRename() {
				var _this = this
				var hasChanged = false
				var hasEmpty = false
				var lengthStatistics = {}
				var maxLength = 0
				this.data.forEach(item => {
					const suffix = item.origin.split('.').length > 1 ? '.' + item.origin.split('.')[item.origin.split('.').length - 1] : ''
					item.numArr = item.origin.replace(suffix, '').match(/\d+/g) || []
					// 寻找出现次数最多的匹配项
					if (lengthStatistics[item.numArr.length] == undefined) lengthStatistics[item.numArr.length] = 1
					else lengthStatistics[item.numArr.length] += 1
				})
				for (var i in lengthStatistics) {
					maxLength = lengthStatistics[i] > maxLength ? i : maxLength
				}
				var seq = -1
				for (var index = 0; index < maxLength; index++) {
					const tempList = this.data.map(item => {
						if (item.numArr.length == maxLength) {
							return item.numArr[index]
						}
					}).filter(l => l != undefined)
					// 判断是否有重复元素
					if (Array.from(new Set(tempList)).length == tempList.length) {
						seq = index
						break
					}
				}
				if (seq < 0) return swal(`智能重命名失败,找不到唯一的数字序号!`, {
					icon: "error",
					buttons: false,
					timer: 3000,
				});
				this.data.forEach(item => {
					if (item.numArr.length == maxLength) {
						const suffix = item.origin.split('.').length > 1 ? '.' + item.origin.split('.')[item.origin.split('.').length - 1] : ''
						item.replace = `${item.numArr[seq]}${suffix}`.trim()
					}
					if (item.replace !== item.origin) {
						hasChanged = true
					}
					if (item.replace == "") {
						hasEmpty = true
						item.replace = item.origin
					}
					_this.modifyReplace(item)
				})

				if (!hasChanged) swal(`没有匹配到任何需要修改的文件!`, {
					icon: "error",
					buttons: false,
					timer: 3000,
				});
				if (hasEmpty) swal(`替换后某个文件名为空!`, {
					icon: "error",
					buttons: false,
					timer: 3000,
				});
			},
			todo() {
				swal(`🈲️🈲️🈲️ 此功能暂不可用,请等待版本更新 🔞🔞🔞`, {
					buttons: false,
					timer: 2000,
				});
			}
		},
		computed: {},
		mounted() {}
	})
	//设置div可拖动
	dragFunc("priate_script_div");
})();