新增将我的列表保存为TXT、CSV格式

This commit is contained in:
lyswhut
2021-12-05 21:36:46 +08:00
parent 7f6e1c25e9
commit 0dc7815e35
8 changed files with 547 additions and 421 deletions
+2 -2
View File
@@ -104,7 +104,7 @@ export default {
message: Buffer.from('e69cace8bdafe4bbb6e5ae8ce585a8e5858de8b4b9e4b894e5bc80e6ba90efbc8ce5a682e69e9ce4bda0e698afe88ab1e992b1e8b4ade4b9b0e79a84efbc8ce8afb7e79bb4e68ea5e7bb99e5b7aee8af84efbc810a0a5468697320736f667477617265206973206672656520616e64206f70656e20736f757263652e', 'hex').toString(),
confirmButtonText: Buffer.from('e5a5bde79a8420284f4b29', 'hex').toString(),
})
}, 2000)
}, 2e3)
},
handleClose(isExit) {
if (isExit) return rendererSend(NAMES.mainWindow.close, true)
@@ -116,7 +116,7 @@ export default {
startTimeout() {
setTimeout(() => {
if (--this.time > 0) this.startTimeout()
}, 1000)
}, 1e3)
},
},
}
+37 -37
View File
@@ -11,50 +11,50 @@ const defaultOptions = {
confirmButtonText: '',
}
const dialog = {
install(Vue, options) {
const dialog = function(options) {
const { message, showCancel, cancelButtonText, confirmButtonText } =
Object.assign({}, defaultOptions, typeof options == 'string' ? { message: options } : options || {})
return new Promise((resolve, reject) => {
let app = createApp(Dialog, {
afterLeave() {
app?.unmount()
app = null
},
}).use(i18n).use(store)
export const dialog = function(options) {
const { message, showCancel, cancelButtonText, confirmButtonText } =
Object.assign({}, defaultOptions, typeof options == 'string' ? { message: options } : options || {})
return new Promise((resolve, reject) => {
let app = createApp(Dialog, {
afterLeave() {
app?.unmount()
app = null
},
}).use(i18n).use(store)
let instance = app.mount(document.createElement('div'))
let instance = app.mount(document.createElement('div'))
// 属性设置
instance.visible = true
instance.message = message
instance.showCancel = showCancel
instance.cancelButtonText = cancelButtonText
instance.confirmButtonText = confirmButtonText
// 属性设置
instance.visible = true
instance.message = message
instance.showCancel = showCancel
instance.cancelButtonText = cancelButtonText
instance.confirmButtonText = confirmButtonText
// 挂载
document.getElementById('container').appendChild(instance.$el)
// 挂载
document.getElementById('container').appendChild(instance.$el)
instance.handleCancel = () => {
instance.visible = false
resolve(false)
}
instance.handleComfirm = () => {
instance.visible = false
resolve(true)
}
})
instance.handleCancel = () => {
instance.visible = false
resolve(false)
}
dialog.confirm = options => dialog(
typeof options == 'string'
? { message: options, showCancel: true }
: { ...options, showCancel: true },
)
instance.handleComfirm = () => {
instance.visible = false
resolve(true)
}
})
}
dialog.confirm = options => dialog(
typeof options == 'string'
? { message: options, showCancel: true }
: { ...options, showCancel: true },
)
const dialogPlugin = {
install(Vue, options) {
Vue.config.globalProperties.$dialog = dialog
},
}
export default dialog
export default dialogPlugin
+11
View File
@@ -3,6 +3,7 @@ import path from 'path'
import { shell, clipboard } from 'electron'
import crypto from 'crypto'
import { rendererSend, rendererInvoke, NAMES } from '@common/ipc'
import { log } from '@common/utils'
import iconv from 'iconv-lite'
import { gzip, gunzip } from 'zlib'
import { proxy, qualityList } from '@renderer/core/share'
@@ -480,6 +481,16 @@ export const readLxConfigFile = async path => {
return data
}
export const saveStrToFile = (path, str) => new Promise((resolve, reject) => {
fs.writeFile(path, str, err => {
if (err) {
log.error(err)
reject(err)
return
}
resolve()
})
})
const fileNameRxp = /[\\/:*?#"<>|]/g
export const filterFileName = name => name.replace(fileNameRxp, '')
@@ -12,6 +12,11 @@ dd
div
base-btn.btn.gap-left(min @click="handleImportAllData") {{$t('setting__backup_all_import')}}
base-btn.btn.gap-left(min @click="handleExportAllData") {{$t('setting__backup_all_export')}}
dd
h3#backup_other {{$t('setting__backup_other')}}
div
base-btn.btn.gap-left(min @click="handleExportPlayListToText") {{$t('setting__backup_other_export_list_text')}}
base-btn.btn.gap-left(min @click="handleExportPlayListToCsv") {{$t('setting__backup_other_export_list_csv')}}
</template>
<script>
@@ -26,9 +31,14 @@ import {
readLxConfigFile,
selectDir,
openSaveDir,
filterFileName,
saveStrToFile,
} from '@renderer/utils'
import { currentStting } from '../setting'
import { getList } from '@renderer/core/share/utils'
import path from 'path'
import { dialog } from '@renderer/plugins/Dialog'
import iconv from 'iconv-lite'
export default {
name: 'SettingUpdate',
@@ -214,6 +224,106 @@ export default {
})
}
const exportPlayListToText = async(savePath, isMerge) => {
const lists = JSON.parse(JSON.stringify([
{ ...toRaw(defaultList), list: toRaw(getList(defaultList.id)) },
{ ...toRaw(loveList), list: toRaw(getList(loveList.id)) },
...userLists.map(l => ({ ...toRaw(l), list: toRaw(getList(l.id)) })),
]))
for await (const list of lists) {
for await (const item of list.list) {
if (item.otherSource) delete item.otherSource
}
}
if (isMerge) {
saveStrToFile(savePath, iconv.encode(lists.map(l => l.list.map(m => `${m.name} ${m.singer} ${m.albumName}`).join('\n')).join('\n\n'), 'utf8', { addBOM: true }))
} else {
for await (const list of lists) {
await saveStrToFile(path.join(savePath, `lx_list_${filterFileName(list.name)}.txt`), iconv.encode(list.list.map(m => `${m.name} ${m.singer} ${m.albumName}`).join('\n'), 'utf8', { addBOM: true }))
}
}
}
const handleExportPlayListToText = async() => {
const confirm = await dialog.confirm({
message: t('setting__backup_other_export_list_text_confirm'),
cancelButtonText: t('cancel_button_text'),
confirmButtonText: t('confirm_button_text'),
})
if (confirm) {
openSaveDir({
title: t('setting__backup_other_export_dir'),
defaultPath: 'lx_list_all.txt',
}).then(result => {
if (result.canceled) return
let path = result.filePath
if (!path.endsWith('.txt')) path += '.txt'
exportPlayListToText(path, true)
})
} else {
selectDir({
title: t('setting__backup_other_export_dir'),
defaultPath: currentStting.value.download.savePath,
properties: ['openDirectory'],
}).then(result => {
if (result.canceled) return
exportPlayListToText(result.filePaths[0], false)
})
}
}
const exportPlayListToCsv = async(savePath, isMerge) => {
const lists = JSON.parse(JSON.stringify([
{ ...toRaw(defaultList), list: toRaw(getList(defaultList.id)) },
{ ...toRaw(loveList), list: toRaw(getList(loveList.id)) },
...userLists.map(l => ({ ...toRaw(l), list: toRaw(getList(l.id)) })),
]))
for await (const list of lists) {
for await (const item of list.list) {
if (item.otherSource) delete item.otherSource
}
}
const filterStr = str => {
if (!str) return ''
str = str.replace(/"/g, '""')
if (/,/.test(str)) str = `"${str}"`
return str
}
if (isMerge) {
saveStrToFile(savePath, iconv.encode(lists.map(l => l.list.map(m => `${filterStr(m.name)},${filterStr(m.singer)},${filterStr(m.albumName)}`).join('\n')).join('\n'), 'utf8', { addBOM: true }))
} else {
for await (const list of lists) {
await saveStrToFile(path.join(savePath, `lx_list_${filterFileName(list.name)}.csv`), iconv.encode(list.list.map(m => `${filterStr(m.name)},${filterStr(m.singer)},${filterStr(m.albumName)}`).join('\n'), 'utf8', { addBOM: true }))
}
}
}
const handleExportPlayListToCsv = async() => {
const confirm = await dialog.confirm({
message: t('setting__backup_other_export_list_text_confirm'),
cancelButtonText: t('cancel_button_text'),
confirmButtonText: t('confirm_button_text'),
})
if (confirm) {
openSaveDir({
title: t('setting__backup_other_export_dir'),
defaultPath: 'lx_list_all.csv',
}).then(result => {
if (result.canceled) return
let path = result.filePath
if (!path.endsWith('.csv')) path += '.csv'
exportPlayListToCsv(path, true)
})
} else {
selectDir({
title: t('setting__backup_other_export_dir'),
defaultPath: currentStting.value.download.savePath,
properties: ['openDirectory'],
}).then(result => {
if (result.canceled) return
exportPlayListToCsv(result.filePaths[0], false)
})
}
}
window.eventHub.on(eventBaseName.set_config, handleUpdateSetting)
onBeforeUnmount(() => {
@@ -228,6 +338,8 @@ export default {
handleImportSetting,
handleExportAllData,
handleImportAllData,
handleExportPlayListToText,
handleExportPlayListToCsv,
}
},
}