mirror of
https://github.com/Kuingsmile/PicList.git
synced 2026-06-05 07:41:58 +08:00
🎨 Style(custom): format with prettier
This commit is contained in:
@@ -1,21 +1,11 @@
|
||||
<template>
|
||||
<el-form-item>
|
||||
<template #label>
|
||||
<span style="position:absolute;left: 0;">
|
||||
<span
|
||||
v-for="(segment, index) in segments"
|
||||
:key="index"
|
||||
:style="segment.style"
|
||||
>
|
||||
<span style="position: absolute; left: 0">
|
||||
<span v-for="(segment, index) in segments" :key="index" :style="segment.style">
|
||||
{{ segment.text }}
|
||||
</span>
|
||||
<el-tooltip
|
||||
:content="tooltip"
|
||||
effect="dark"
|
||||
placement="right"
|
||||
:persistent="false"
|
||||
teleported
|
||||
>
|
||||
<el-tooltip :content="tooltip" effect="dark" placement="right" :persistent="false" teleported>
|
||||
<el-icon>
|
||||
<InfoFilled />
|
||||
</el-icon>
|
||||
@@ -26,7 +16,7 @@
|
||||
v-model="value"
|
||||
:active-text="activeText"
|
||||
:inactive-text="inactiveText"
|
||||
style="--el-switch-on-color: #13ce66;--el-switch-off-color: #ff4949; position:absolute; right: 0;"
|
||||
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949; position: absolute; right: 0"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
@@ -35,12 +25,11 @@
|
||||
import { InfoFilled } from '@element-plus/icons-vue'
|
||||
|
||||
defineProps<{
|
||||
tooltip?: string,
|
||||
activeText?: string,
|
||||
inactiveText?: string,
|
||||
segments?: { text: string, style: string }[],
|
||||
tooltip?: string
|
||||
activeText?: string
|
||||
inactiveText?: string
|
||||
segments?: { text: string; style: string }[]
|
||||
}>()
|
||||
|
||||
const value = defineModel<boolean>()
|
||||
|
||||
</script>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,5 @@
|
||||
<template>
|
||||
<el-empty
|
||||
:description="$T('MANAGE_NO_DATA')"
|
||||
/>
|
||||
<el-empty :description="$T('MANAGE_NO_DATA')" />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
v-model="activeName"
|
||||
type="border-card"
|
||||
stretch
|
||||
style="height: calc(100vh - 50px);width: 100%;overflow-x: hidden;"
|
||||
style="height: calc(100vh - 50px); width: 100%; overflow-x: hidden"
|
||||
tab-position="left"
|
||||
lazy
|
||||
@tab-change="getExistingConfig(activeName)"
|
||||
@@ -12,7 +12,7 @@
|
||||
<el-tab-pane
|
||||
name="login"
|
||||
:label="$T('MANAGE_LOGIN_PAGE_PANE_NAME')"
|
||||
style="width: 100%;overflow-y: scroll;height: calc(100vh - 50px);"
|
||||
style="width: 100%; overflow-y: scroll; height: calc(100vh - 50px)"
|
||||
lazy
|
||||
>
|
||||
<el-alert
|
||||
@@ -25,53 +25,31 @@
|
||||
element-loading-svg-view-box="0, 0, 150, 150"
|
||||
/>
|
||||
<el-row>
|
||||
<el-col
|
||||
v-for="item in sortedAllConfigAliasMap"
|
||||
:key="item"
|
||||
:xs="24"
|
||||
:sm="12"
|
||||
:md="8"
|
||||
:lg="6"
|
||||
:xl="4"
|
||||
>
|
||||
<el-card
|
||||
class="box-card"
|
||||
style="margin: 10px 0;"
|
||||
shadow="hover"
|
||||
>
|
||||
<el-popover
|
||||
placement="top"
|
||||
:width="300"
|
||||
trigger="click"
|
||||
:persistent="false"
|
||||
teleported
|
||||
>
|
||||
<el-col v-for="item in sortedAllConfigAliasMap" :key="item" :xs="24" :sm="12" :md="8" :lg="6" :xl="4">
|
||||
<el-card class="box-card" style="margin: 10px 0" shadow="hover">
|
||||
<el-popover placement="top" :width="300" trigger="click" :persistent="false" teleported>
|
||||
<el-table
|
||||
:data="formObjToTableData(item.config)"
|
||||
style="width: 100%"
|
||||
size="small"
|
||||
:header-cell-style="{'text-align':'center'}"
|
||||
:cell-style="{'text-align':'center'}"
|
||||
:header-cell-style="{ 'text-align': 'center' }"
|
||||
:cell-style="{ 'text-align': 'center' }"
|
||||
>
|
||||
<el-table-column
|
||||
prop="key"
|
||||
:label="$T('MANAGE_LOGIN_PAGE_PANE_KEY_NAME')"
|
||||
width="100"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="value"
|
||||
:label="$T('MANAGE_LOGIN_PAGE_PANE_KEY_VALUE')"
|
||||
/>
|
||||
<el-table-column prop="key" :label="$T('MANAGE_LOGIN_PAGE_PANE_KEY_NAME')" width="100" />
|
||||
<el-table-column prop="value" :label="$T('MANAGE_LOGIN_PAGE_PANE_KEY_VALUE')" />
|
||||
</el-table>
|
||||
<template #reference>
|
||||
<el-button
|
||||
style="width: 100%; text-align: center;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;"
|
||||
style="
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
"
|
||||
>
|
||||
<template #icon>
|
||||
<img
|
||||
:src="require(`./assets/${item.picBedName}.webp`)"
|
||||
style="width: 25px; height: 25px;"
|
||||
>
|
||||
<img :src="require(`./assets/${item.picBedName}.webp`)" style="width: 25px; height: 25px" />
|
||||
</template>
|
||||
<el-tooltip
|
||||
effect="light"
|
||||
@@ -86,23 +64,13 @@
|
||||
</el-button>
|
||||
</template>
|
||||
</el-popover>
|
||||
<br>
|
||||
<br>
|
||||
<br />
|
||||
<br />
|
||||
<el-button-group>
|
||||
<el-button
|
||||
type="primary"
|
||||
:icon="Pointer"
|
||||
plain
|
||||
@click="handleConfigClick(item)"
|
||||
>
|
||||
<el-button type="primary" :icon="Pointer" plain @click="handleConfigClick(item)">
|
||||
{{ $T('MANAGE_LOGIN_PAGE_PANE_ENTER') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
type="warning"
|
||||
:icon="Delete"
|
||||
plain
|
||||
@click="handleConfigRemove(item.alias)"
|
||||
>
|
||||
<el-button type="warning" :icon="Delete" plain @click="handleConfigRemove(item.alias)">
|
||||
{{ $T('MANAGE_LOGIN_PAGE_PANE_DELETE') }}
|
||||
</el-button>
|
||||
</el-button-group>
|
||||
@@ -117,24 +85,13 @@
|
||||
:name="item.icon"
|
||||
class="tab-pane"
|
||||
lazy
|
||||
style="width: 100%;overflow-y: scroll;height: calc(100vh - 50px);"
|
||||
style="width: 100%; overflow-y: scroll; height: calc(100vh - 50px)"
|
||||
>
|
||||
<el-alert
|
||||
:title="item.explain"
|
||||
type="info"
|
||||
show-icon
|
||||
center
|
||||
:closable="false"
|
||||
/>
|
||||
<el-alert
|
||||
center
|
||||
:closable="false"
|
||||
>
|
||||
<el-alert :title="item.explain" type="info" show-icon center :closable="false" />
|
||||
<el-alert center :closable="false">
|
||||
<div>
|
||||
{{ item.referenceText }} <a
|
||||
style="color:blue;cursor:pointer"
|
||||
@click="handleReferenceClick(item.refLink)"
|
||||
>{{ item.refLink }}</a>
|
||||
{{ item.referenceText }}
|
||||
<a style="color: blue; cursor: pointer" @click="handleReferenceClick(item.refLink)">{{ item.refLink }}</a>
|
||||
</div>
|
||||
</el-alert>
|
||||
<el-form
|
||||
@@ -160,9 +117,7 @@
|
||||
:persistent="false"
|
||||
teleported
|
||||
>
|
||||
<el-icon
|
||||
color="#409EFF"
|
||||
>
|
||||
<el-icon color="#409EFF">
|
||||
<InfoFilled />
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
@@ -176,7 +131,7 @@
|
||||
<el-switch
|
||||
v-else-if="supportedPicBedList[item.icon].configOptions[option].type === 'boolean'"
|
||||
v-model="configResult[item.icon + '.' + option]"
|
||||
style="--el-switch-on-color: #13ce66;--el-switch-off-color: #ff4949;"
|
||||
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
|
||||
/>
|
||||
<el-input
|
||||
v-else-if="supportedPicBedList[item.icon].configOptions[option].type === 'number'"
|
||||
@@ -199,7 +154,7 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div style="margin: 0 auto;position: relative;left: 10%;right: 50%;">
|
||||
<div style="margin: 0 auto; position: relative; left: 10%; right: 50%">
|
||||
<el-dropdown
|
||||
split-button
|
||||
type="success"
|
||||
@@ -210,46 +165,25 @@
|
||||
>
|
||||
{{ $T('MANAGE_LOGIN_PAGE_PANE_IMPORT') }}
|
||||
<template #dropdown>
|
||||
<el-dropdown-item
|
||||
v-for="i in currentAliasList"
|
||||
:key="i"
|
||||
@click="handleConfigImport(i)"
|
||||
>
|
||||
<el-dropdown-item v-for="i in currentAliasList" :key="i" @click="handleConfigImport(i)">
|
||||
{{ i }}
|
||||
</el-dropdown-item>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<el-button
|
||||
type="primary"
|
||||
style="margin-left: 10vw"
|
||||
:icon="Edit"
|
||||
plain
|
||||
@click="handleConfigChange(item.icon)"
|
||||
>
|
||||
<el-button type="primary" style="margin-left: 10vw" :icon="Edit" plain @click="handleConfigChange(item.icon)">
|
||||
{{ $T('MANAGE_LOGIN_PAGE_PANE_SAVE') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
style="margin-left: 10vw"
|
||||
:icon="Delete"
|
||||
plain
|
||||
@click="handleConfigReset(item.icon)"
|
||||
>
|
||||
<el-button type="danger" style="margin-left: 10vw" :icon="Delete" plain @click="handleConfigReset(item.icon)">
|
||||
{{ $T('MANAGE_LOGIN_PAGE_PANE_RESET') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<br>
|
||||
<el-alert
|
||||
:title="$T('MANAGE_LOGIN_PAGE_PANE_TABLE_TITLE')"
|
||||
type="success"
|
||||
center
|
||||
:closable="false"
|
||||
/>
|
||||
<br />
|
||||
<el-alert :title="$T('MANAGE_LOGIN_PAGE_PANE_TABLE_TITLE')" type="success" center :closable="false" />
|
||||
<el-table
|
||||
:data="dataForTable"
|
||||
style="width: 100%;margin-top: 10px"
|
||||
:header-cell-style="{'text-align':'center'}"
|
||||
:cell-style="{'text-align':'center'}"
|
||||
style="width: 100%; margin-top: 10px"
|
||||
:header-cell-style="{ 'text-align': 'center' }"
|
||||
:cell-style="{ 'text-align': 'center' }"
|
||||
@cell-click="handleCellClick"
|
||||
>
|
||||
<el-table-column
|
||||
@@ -288,7 +222,7 @@ const router = useRouter()
|
||||
|
||||
const activeName = ref('login')
|
||||
|
||||
const configResult:IStringKeyMap = reactive({})
|
||||
const configResult: IStringKeyMap = reactive({})
|
||||
const existingConfiguration = reactive({} as IStringKeyMap)
|
||||
const dataForTable = reactive([] as any[])
|
||||
const allConfigAliasMap = reactive({} as IStringKeyMap)
|
||||
@@ -303,9 +237,9 @@ const sortedAllConfigAliasMap = computed(() => {
|
||||
|
||||
const importedNewConfig: IStringKeyMap = {}
|
||||
|
||||
function ruleMap (options: IStringKeyMap) {
|
||||
const rule:any = {}
|
||||
Object.keys(options).forEach((key) => {
|
||||
function ruleMap(options: IStringKeyMap) {
|
||||
const rule: any = {}
|
||||
Object.keys(options).forEach(key => {
|
||||
const item = options[key].options
|
||||
item.forEach((option: string) => {
|
||||
const configOptions = options[key].configOptions[option]
|
||||
@@ -321,13 +255,13 @@ function ruleMap (options: IStringKeyMap) {
|
||||
return rule
|
||||
}
|
||||
|
||||
function getDataForTable () {
|
||||
function getDataForTable() {
|
||||
for (const key in existingConfiguration) {
|
||||
dataForTable.push({ ...existingConfiguration[key] as IStringKeyMap })
|
||||
dataForTable.push({ ...(existingConfiguration[key] as IStringKeyMap) })
|
||||
}
|
||||
}
|
||||
|
||||
async function getExistingConfig (name:string) {
|
||||
async function getExistingConfig(name: string) {
|
||||
if (name === 'login') {
|
||||
getAllConfigAliasArray()
|
||||
return
|
||||
@@ -353,20 +287,22 @@ async function getExistingConfig (name:string) {
|
||||
handleConfigImport(currentAliasList[0])
|
||||
}
|
||||
|
||||
function getAliasList () {
|
||||
function getAliasList() {
|
||||
return Object.values(existingConfiguration).map(item => item.alias)
|
||||
}
|
||||
|
||||
async function handleConfigChange (name: string) {
|
||||
async function handleConfigChange(name: string) {
|
||||
const aliasList = getAliasList()
|
||||
const allKeys = Object.keys(supportedPicBedList[name].configOptions)
|
||||
const resultMap:IStringKeyMap = {}
|
||||
const resultMap: IStringKeyMap = {}
|
||||
const reg = /^[\p{Unified_Ideograph}_a-zA-Z0-9-]+$/u
|
||||
for (const key of allKeys) {
|
||||
const resultKey = name + '.' + key
|
||||
if (supportedPicBedList[name].configOptions[key].required) {
|
||||
if (supportedPicBedList[name].configOptions[key].type !== 'boolean' && !configResult[resultKey]) {
|
||||
ElMessage.error(`${$T('MANAGE_LOGIN_PAGE_PANE_CONFIG_CHANGE_MESSAGE_A')} ${supportedPicBedList[name].configOptions[key].description}`)
|
||||
ElMessage.error(
|
||||
`${$T('MANAGE_LOGIN_PAGE_PANE_CONFIG_CHANGE_MESSAGE_A')} ${supportedPicBedList[name].configOptions[key].description}`
|
||||
)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -374,11 +310,15 @@ async function handleConfigChange (name: string) {
|
||||
ElMessage.error($T('MANAGE_LOGIN_PAGE_PANE_CONFIG_CHANGE_ALIAS_MESSAGE'))
|
||||
return
|
||||
}
|
||||
if (key === 'itemsPerPage' && configResult[resultKey] !== undefined && (configResult[resultKey] < 20 || configResult[resultKey] > 1000)) {
|
||||
if (
|
||||
key === 'itemsPerPage' &&
|
||||
configResult[resultKey] !== undefined &&
|
||||
(configResult[resultKey] < 20 || configResult[resultKey] > 1000)
|
||||
) {
|
||||
ElMessage.error($T('MANAGE_LOGIN_PAGE_PANE_CONFIG_CHANGE_ITEMS_PER_PAGE_MESSAGE'))
|
||||
return
|
||||
}
|
||||
if ((key === 'customUrl') && configResult[resultKey] !== undefined && configResult[resultKey] !== '') {
|
||||
if (key === 'customUrl' && configResult[resultKey] !== undefined && configResult[resultKey] !== '') {
|
||||
if (name !== 'upyun') {
|
||||
if (!/^https?:\/\//.test(configResult[resultKey])) {
|
||||
ElMessage.error($T('MANAGE_LOGIN_PAGE_PANE_CONFIG_CHANGE_CUSTOM_URL_MESSAGE'))
|
||||
@@ -414,7 +354,12 @@ async function handleConfigChange (name: string) {
|
||||
[bucketName[i]]: {
|
||||
baseDir: baseDir && baseDir[i] ? baseDir[i] : '/',
|
||||
area: area && area[i] ? area[i] : '',
|
||||
customUrl: customUrl && customUrl[i] ? /^https?:\/\//.test(customUrl[i]) ? customUrl[i] : 'http://' + customUrl[i] : '',
|
||||
customUrl:
|
||||
customUrl && customUrl[i]
|
||||
? /^https?:\/\//.test(customUrl[i])
|
||||
? customUrl[i]
|
||||
: 'http://' + customUrl[i]
|
||||
: '',
|
||||
operator: operator && operator[i] ? operator[i] : '',
|
||||
password: password && password[i] ? password[i] : ''
|
||||
}
|
||||
@@ -431,33 +376,29 @@ async function handleConfigChange (name: string) {
|
||||
dataForTable.length = 0
|
||||
getDataForTable()
|
||||
if (aliasList.includes(resultMap.alias)) {
|
||||
ElNotification(
|
||||
{
|
||||
title: $T('MANAGE_LOGIN_PAGE_PANE_CONFIG_CHANGE_NOTICE_NAME'),
|
||||
message: `${$T('MANAGE_LOGIN_PAGE_PANE_CONFIG_CHANGE_NOTICE_MESSAGE')}${resultMap.alias}`,
|
||||
type: 'warning',
|
||||
duration: 500,
|
||||
customClass: 'notification',
|
||||
offset: 100
|
||||
}
|
||||
)
|
||||
ElNotification({
|
||||
title: $T('MANAGE_LOGIN_PAGE_PANE_CONFIG_CHANGE_NOTICE_NAME'),
|
||||
message: `${$T('MANAGE_LOGIN_PAGE_PANE_CONFIG_CHANGE_NOTICE_MESSAGE')}${resultMap.alias}`,
|
||||
type: 'warning',
|
||||
duration: 500,
|
||||
customClass: 'notification',
|
||||
offset: 100
|
||||
})
|
||||
} else {
|
||||
ElNotification(
|
||||
{
|
||||
title: $T('MANAGE_LOGIN_PAGE_PANE_CONFIG_CHANGE_NOTICE_NAME'),
|
||||
message: `${$T('MANAGE_LOGIN_PAGE_PANE_CONFIG_CHANGE_NOTICE_MESSAGE_B')}${resultMap.alias}`,
|
||||
type: 'success',
|
||||
duration: 2000,
|
||||
customClass: 'notification',
|
||||
offset: 100
|
||||
}
|
||||
)
|
||||
ElNotification({
|
||||
title: $T('MANAGE_LOGIN_PAGE_PANE_CONFIG_CHANGE_NOTICE_NAME'),
|
||||
message: `${$T('MANAGE_LOGIN_PAGE_PANE_CONFIG_CHANGE_NOTICE_MESSAGE_B')}${resultMap.alias}`,
|
||||
type: 'success',
|
||||
duration: 2000,
|
||||
customClass: 'notification',
|
||||
offset: 100
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const handleConfigReset = (name: string) => {
|
||||
const keys = Object.keys(configResult).filter((key) => key.startsWith(name))
|
||||
keys.forEach((key) => {
|
||||
const keys = Object.keys(configResult).filter(key => key.startsWith(name))
|
||||
keys.forEach(key => {
|
||||
const optionKey = key.split('.')[1]
|
||||
const configOption = supportedPicBedList[name]?.configOptions?.[optionKey]
|
||||
|
||||
@@ -468,11 +409,15 @@ const handleConfigReset = (name: string) => {
|
||||
}
|
||||
|
||||
const handleConfigRemove = (name: string) => {
|
||||
ElMessageBox.confirm($T('MANAGE_LOGIN_PAGE_PANE_DELETE_CONFIG_TITLE'), $T('MANAGE_LOGIN_PAGE_PANE_DELETE_CONFIG_TIP'), {
|
||||
confirmButtonText: $T('MANAGE_LOGIN_PAGE_PANE_DELETE_CONFIG_CONFIRM'),
|
||||
cancelButtonText: $T('MANAGE_LOGIN_PAGE_PANE_DELETE_CONFIG_CANCEL'),
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
ElMessageBox.confirm(
|
||||
$T('MANAGE_LOGIN_PAGE_PANE_DELETE_CONFIG_TITLE'),
|
||||
$T('MANAGE_LOGIN_PAGE_PANE_DELETE_CONFIG_TIP'),
|
||||
{
|
||||
confirmButtonText: $T('MANAGE_LOGIN_PAGE_PANE_DELETE_CONFIG_CONFIRM'),
|
||||
cancelButtonText: $T('MANAGE_LOGIN_PAGE_PANE_DELETE_CONFIG_CANCEL'),
|
||||
type: 'warning'
|
||||
}
|
||||
).then(async () => {
|
||||
const commonNoticeConfig = {
|
||||
title: $T('MANAGE_LOGIN_PAGE_PANE_CONFIG_CHANGE_NOTICE_NAME'),
|
||||
duration: 2000,
|
||||
@@ -481,25 +426,21 @@ const handleConfigRemove = (name: string) => {
|
||||
}
|
||||
try {
|
||||
removeConfig('picBed', name)
|
||||
ElNotification(
|
||||
{
|
||||
...commonNoticeConfig,
|
||||
message: `${$T('MANAGE_LOGIN_PAGE_PANE_CONFIG_CHANGE_NOTICE_MESSAGE_C')}${name}`,
|
||||
type: 'success',
|
||||
position: 'bottom-right'
|
||||
}
|
||||
)
|
||||
ElNotification({
|
||||
...commonNoticeConfig,
|
||||
message: `${$T('MANAGE_LOGIN_PAGE_PANE_CONFIG_CHANGE_NOTICE_MESSAGE_C')}${name}`,
|
||||
type: 'success',
|
||||
position: 'bottom-right'
|
||||
})
|
||||
manageStore.refreshConfig()
|
||||
getAllConfigAliasArray()
|
||||
} catch (error) {
|
||||
ElNotification(
|
||||
{
|
||||
...commonNoticeConfig,
|
||||
message: `${$T('MANAGE_LOGIN_PAGE_PANE_CONFIG_CHANGE_NOTICE_MESSAGE_D')}${name}${$T('MANAGE_LOGIN_PAGE_PANE_CONFIG_CHANGE_NOTICE_MESSAGE_E')}`,
|
||||
type: 'error',
|
||||
position: 'bottom-right'
|
||||
}
|
||||
)
|
||||
ElNotification({
|
||||
...commonNoticeConfig,
|
||||
message: `${$T('MANAGE_LOGIN_PAGE_PANE_CONFIG_CHANGE_NOTICE_MESSAGE_D')}${name}${$T('MANAGE_LOGIN_PAGE_PANE_CONFIG_CHANGE_NOTICE_MESSAGE_E')}`,
|
||||
type: 'error',
|
||||
position: 'bottom-right'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -519,7 +460,7 @@ const getAllConfigAliasArray = async () => {
|
||||
})
|
||||
}
|
||||
|
||||
const handleCellClick = (row:any, column:any) => {
|
||||
const handleCellClick = (row: any, column: any) => {
|
||||
navigator.clipboard.writeText(row[column.property])
|
||||
ElMessage.success(`${$T('MANAGE_LOGIN_PAGE_PANE_CONFIG_CHANGE_COPY_SUCCESS')}${row[column.property]}`)
|
||||
}
|
||||
@@ -542,7 +483,7 @@ const handleConfigClick = async (item: any) => {
|
||||
})
|
||||
}
|
||||
|
||||
function handleConfigImport (alias: string) {
|
||||
function handleConfigImport(alias: string) {
|
||||
const selectedConfig = existingConfiguration[alias]
|
||||
if (!selectedConfig) return
|
||||
|
||||
@@ -553,20 +494,36 @@ function handleConfigImport (alias: string) {
|
||||
})
|
||||
}
|
||||
|
||||
async function getCurrentConfigList () {
|
||||
async function getCurrentConfigList() {
|
||||
await manageStore.refreshConfig()
|
||||
const configList = await getPicBedsConfig<any>('uploader') ?? {}
|
||||
const pbList = ['aliyun', 'aws-s3', 'aws-s3-plist', 'github', 'imgur', 'local', 'qiniu', 'sftpplist', 'smms', 'tcyun', 'upyun', 'webdavplist']
|
||||
const configList = (await getPicBedsConfig<any>('uploader')) ?? {}
|
||||
const pbList = [
|
||||
'aliyun',
|
||||
'aws-s3',
|
||||
'aws-s3-plist',
|
||||
'github',
|
||||
'imgur',
|
||||
'local',
|
||||
'qiniu',
|
||||
'sftpplist',
|
||||
'smms',
|
||||
'tcyun',
|
||||
'upyun',
|
||||
'webdavplist'
|
||||
]
|
||||
|
||||
const filteredConfigList = pbList.flatMap((pb) => {
|
||||
const filteredConfigList = pbList.flatMap(pb => {
|
||||
const config = configList[pb]
|
||||
return config?.configList?.length ? config.configList.map((item: any) => ({ ...item, type: pb })) : []
|
||||
})
|
||||
|
||||
const autoImport = await getPicBedsConfig<boolean>('settings.autoImport') || false
|
||||
const autoImport = (await getPicBedsConfig<boolean>('settings.autoImport')) || false
|
||||
if (autoImport) {
|
||||
const autoImportPicBed = initArray(await getPicBedsConfig<string | string[]>('settings.autoImportPicBed') || '', [])
|
||||
await Promise.all(filteredConfigList.flatMap((config) => transUpToManage(config, config.type, autoImportPicBed)))
|
||||
const autoImportPicBed = initArray(
|
||||
(await getPicBedsConfig<string | string[]>('settings.autoImportPicBed')) || '',
|
||||
[]
|
||||
)
|
||||
await Promise.all(filteredConfigList.flatMap(config => transUpToManage(config, config.type, autoImportPicBed)))
|
||||
if (Object.keys(importedNewConfig).length > 0) {
|
||||
const oldConfig = await getConfig<any>('picBed')
|
||||
const newConfig = { ...oldConfig, ...importedNewConfig }
|
||||
@@ -578,25 +535,27 @@ async function getCurrentConfigList () {
|
||||
await getAllConfigAliasArray()
|
||||
}
|
||||
|
||||
function isImported (alias: string) {
|
||||
return Object.values(allConfigAliasMap).some((item) => item.alias === alias)
|
||||
function isImported(alias: string) {
|
||||
return Object.values(allConfigAliasMap).some(item => item.alias === alias)
|
||||
}
|
||||
|
||||
function initArray (arrayT: string | string[], defaultValue: string[]) {
|
||||
function initArray(arrayT: string | string[], defaultValue: string[]) {
|
||||
if (!Array.isArray(arrayT)) {
|
||||
arrayT = arrayT ? [arrayT] : defaultValue
|
||||
}
|
||||
return arrayT
|
||||
}
|
||||
|
||||
async function transUpToManage (config: IUploaderConfigListItem, picBedName: string, autoImportPicBed: string[]) {
|
||||
const alias = `${picBedName === 'webdavplist'
|
||||
? 'webdav'
|
||||
: picBedName === 'sftpplist'
|
||||
? 'sftp'
|
||||
: picBedName === 'aws-s3' || picBedName === 'aws-s3-plist'
|
||||
? 's3plist'
|
||||
: picBedName}-${config._configName ?? 'Default'}-imp`
|
||||
async function transUpToManage(config: IUploaderConfigListItem, picBedName: string, autoImportPicBed: string[]) {
|
||||
const alias = `${
|
||||
picBedName === 'webdavplist'
|
||||
? 'webdav'
|
||||
: picBedName === 'sftpplist'
|
||||
? 'sftp'
|
||||
: picBedName === 'aws-s3' || picBedName === 'aws-s3-plist'
|
||||
? 's3plist'
|
||||
: picBedName
|
||||
}-${config._configName ?? 'Default'}-imp`
|
||||
if (!autoImportPicBed.includes(picBedName) || isImported(alias)) return
|
||||
const commonConfig = {
|
||||
alias,
|
||||
@@ -622,13 +581,15 @@ async function transUpToManage (config: IUploaderConfigListItem, picBedName: str
|
||||
baseDir: '/',
|
||||
itemsPerPage: 50,
|
||||
isAutoCustomUrl: !config.customUrl,
|
||||
transformedConfig: JSON.stringify(config.customUrl
|
||||
? {
|
||||
[config.bucket]: {
|
||||
customUrl: config.customUrl
|
||||
}
|
||||
}
|
||||
: {})
|
||||
transformedConfig: JSON.stringify(
|
||||
config.customUrl
|
||||
? {
|
||||
[config.bucket]: {
|
||||
customUrl: config.customUrl
|
||||
}
|
||||
}
|
||||
: {}
|
||||
)
|
||||
})
|
||||
break
|
||||
case 'qiniu':
|
||||
@@ -654,13 +615,15 @@ async function transUpToManage (config: IUploaderConfigListItem, picBedName: str
|
||||
baseDir: '/',
|
||||
appId: config.appId,
|
||||
isAutoCustomUrl: !config.customUrl,
|
||||
transformedConfig: JSON.stringify(config.customUrl
|
||||
? {
|
||||
[config.bucket]: {
|
||||
customUrl: config.customUrl
|
||||
}
|
||||
}
|
||||
: {}),
|
||||
transformedConfig: JSON.stringify(
|
||||
config.customUrl
|
||||
? {
|
||||
[config.bucket]: {
|
||||
customUrl: config.customUrl
|
||||
}
|
||||
}
|
||||
: {}
|
||||
),
|
||||
itemsPerPage: 50
|
||||
})
|
||||
break
|
||||
@@ -795,10 +758,10 @@ async function transUpToManage (config: IUploaderConfigListItem, picBedName: str
|
||||
transformedConfig: JSON.stringify(
|
||||
config.urlPrefix
|
||||
? {
|
||||
[config.bucketName]: {
|
||||
customUrl: config.urlPrefix
|
||||
[config.bucketName]: {
|
||||
customUrl: config.urlPrefix
|
||||
}
|
||||
}
|
||||
}
|
||||
: {}
|
||||
)
|
||||
})
|
||||
@@ -822,10 +785,9 @@ async function transUpToManage (config: IUploaderConfigListItem, picBedName: str
|
||||
onMounted(() => {
|
||||
getCurrentConfigList()
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang='stylus'>
|
||||
<style lang="stylus">
|
||||
.layout
|
||||
background-color #fff
|
||||
position absolute
|
||||
|
||||
@@ -2,25 +2,16 @@
|
||||
<div class="layout">
|
||||
<div class="layout__menu">
|
||||
<div class="layout__menu__button">
|
||||
<span
|
||||
class="layout__menu__button__item"
|
||||
@click="openPicBedUrl"
|
||||
>
|
||||
<span class="layout__menu__button__item" @click="openPicBedUrl">
|
||||
<img
|
||||
:src="require(`./assets/${currentPagePicBedConfig.picBedName}.webp`)"
|
||||
class="layout__menu__button__item__icon"
|
||||
>
|
||||
/>
|
||||
{{ supportedPicBedList[currentPagePicBedConfig.picBedName].name }}
|
||||
</span>
|
||||
</div>
|
||||
<el-divider
|
||||
content-position="left"
|
||||
class="layout__menu__button__divider"
|
||||
border-style="none"
|
||||
>
|
||||
<span
|
||||
style="font-size: 14px;color: #909399;"
|
||||
>
|
||||
<el-divider content-position="left" class="layout__menu__button__divider" border-style="none">
|
||||
<span style="font-size: 14px; color: #909399">
|
||||
{{ menuTitleMap[currentPicBedName] }}
|
||||
<el-tooltip
|
||||
v-if="showNewIconList.includes(currentPicBedName)"
|
||||
@@ -34,7 +25,7 @@
|
||||
<el-icon
|
||||
class="layout__menu__button__divider__icon"
|
||||
color="red"
|
||||
style="top: 2px;"
|
||||
style="top: 2px"
|
||||
@click="openNewBucketDrawer()"
|
||||
>
|
||||
<CirclePlus />
|
||||
@@ -47,24 +38,22 @@
|
||||
v-loading="isLoadingBucketList"
|
||||
class="layout__menu__list"
|
||||
:default-active="getCurrentActiveBucket"
|
||||
style="width: 120px;"
|
||||
style="width: 120px"
|
||||
active-text-color="#409EFF"
|
||||
@select="handleSelectMenu"
|
||||
>
|
||||
<el-menu-item
|
||||
v-for="item of bucketNameList"
|
||||
:key="item"
|
||||
:index="item"
|
||||
>
|
||||
<el-menu-item v-for="item of bucketNameList" :key="item" :index="item">
|
||||
<span
|
||||
class="layout__menu__list__item"
|
||||
:style="{ color: item === currentSelectedBucket ? '#409EFF' : '#606266'}"
|
||||
:style="{
|
||||
color: item === currentSelectedBucket ? '#409EFF' : '#606266'
|
||||
}"
|
||||
>
|
||||
<el-icon
|
||||
v-if="currentSelectedBucket === item && currentPicBedName !== 'github'"
|
||||
class="layout__menu__list__item__icon"
|
||||
color="#409EFF"
|
||||
style="top: 2px;"
|
||||
style="top: 2px"
|
||||
>
|
||||
<FolderOpened />
|
||||
</el-icon>
|
||||
@@ -72,63 +61,42 @@
|
||||
v-else-if="currentPicBedName !== 'github'"
|
||||
class="layout__menu__list__item__icon"
|
||||
color="#606266"
|
||||
style="top: 2px;"
|
||||
style="top: 2px"
|
||||
>
|
||||
<Folder />
|
||||
</el-icon>
|
||||
{{ currentPicBedName === 'tcyun' ? item.slice(0, item.length - 11)
|
||||
: currentPicBedName === 'github'? item.length > 10 ? `${item.slice(0, 5)}..${item.slice(-5)}` : item
|
||||
: item }}
|
||||
{{
|
||||
currentPicBedName === 'tcyun'
|
||||
? item.slice(0, item.length - 11)
|
||||
: currentPicBedName === 'github'
|
||||
? item.length > 10
|
||||
? `${item.slice(0, 5)}..${item.slice(-5)}`
|
||||
: item
|
||||
: item
|
||||
}}
|
||||
</span>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
<el-menu
|
||||
class="layout__menu__setting"
|
||||
style="width: 120px;"
|
||||
>
|
||||
<el-menu-item
|
||||
index="changePicBed"
|
||||
style="height: 40px;"
|
||||
@click="switchPicBed('main')"
|
||||
>
|
||||
<span
|
||||
class="layout__menu__setting__item"
|
||||
>
|
||||
<el-icon
|
||||
class="layout__menu__setting__item__icon"
|
||||
>
|
||||
<el-menu class="layout__menu__setting" style="width: 120px">
|
||||
<el-menu-item index="changePicBed" style="height: 40px" @click="switchPicBed('main')">
|
||||
<span class="layout__menu__setting__item">
|
||||
<el-icon class="layout__menu__setting__item__icon">
|
||||
<HomeFilled />
|
||||
</el-icon>
|
||||
{{ $T('MANAGE_MAIN_PAGE_BACK_TO_HOME') }}
|
||||
</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item
|
||||
index="changePicBed"
|
||||
style="height: 40px;"
|
||||
@click="changePicBed"
|
||||
>
|
||||
<span
|
||||
class="layout__menu__setting__item"
|
||||
>
|
||||
<el-icon
|
||||
class="layout__menu__setting__item__icon"
|
||||
>
|
||||
<el-menu-item index="changePicBed" style="height: 40px" @click="changePicBed">
|
||||
<span class="layout__menu__setting__item">
|
||||
<el-icon class="layout__menu__setting__item__icon">
|
||||
<Switch />
|
||||
</el-icon>
|
||||
{{ $T('MANAGE_MAIN_PAGE_SWITCH_PICBED') }}
|
||||
</span>
|
||||
</el-menu-item>
|
||||
<el-menu-item
|
||||
index="bucketPageSetting"
|
||||
style="height: 40px;"
|
||||
@click="openBucketPageSetting"
|
||||
>
|
||||
<span
|
||||
class="layout__menu__setting__item"
|
||||
>
|
||||
<el-icon
|
||||
class="layout__menu__setting__item__icon"
|
||||
>
|
||||
<el-menu-item index="bucketPageSetting" style="height: 40px" @click="openBucketPageSetting">
|
||||
<span class="layout__menu__setting__item">
|
||||
<el-icon class="layout__menu__setting__item__icon">
|
||||
<Tools />
|
||||
</el-icon>
|
||||
{{ $T('MANAGE_MAIN_PAGE_SETTING') }}
|
||||
@@ -136,70 +104,39 @@
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
</div>
|
||||
<div
|
||||
class="layout__content"
|
||||
style="height: 100%;background-color: transparent;flex: 1;width: 0;"
|
||||
>
|
||||
<div class="layout__content" style="height: 100%; background-color: transparent; flex: 1; width: 0">
|
||||
<router-view />
|
||||
</div>
|
||||
<el-dialog
|
||||
v-model="picBedSwitchDialogVisible"
|
||||
top="30vh"
|
||||
append-to-body
|
||||
>
|
||||
<el-dialog v-model="picBedSwitchDialogVisible" top="30vh" append-to-body>
|
||||
<div
|
||||
class="choice-cos"
|
||||
style="display: flex;flex-direction: row;flex-wrap: wrap;justify-content: space-around;"
|
||||
style="display: flex; flex-direction: row; flex-wrap: wrap; justify-content: space-around"
|
||||
>
|
||||
<el-card
|
||||
shadow="hover"
|
||||
>
|
||||
<div
|
||||
style="text-align: center;display: flex;flex-direction: column;"
|
||||
@click="switchPicBed('main')"
|
||||
>
|
||||
<el-icon
|
||||
color="red"
|
||||
size="25px"
|
||||
style="margin: 0 auto;"
|
||||
>
|
||||
<el-card shadow="hover">
|
||||
<div style="text-align: center; display: flex; flex-direction: column" @click="switchPicBed('main')">
|
||||
<el-icon color="red" size="25px" style="margin: 0 auto">
|
||||
<ChromeFilled />
|
||||
</el-icon>
|
||||
<span
|
||||
style="font-size: 13px;margin-top: 5px;color: red;"
|
||||
>
|
||||
<span style="font-size: 13px; margin-top: 5px; color: red">
|
||||
{{ $T('MANAGE_MAIN_PAGE_BACK_TO_HOME') }}
|
||||
</span>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card
|
||||
v-for="item in allPicBedConfigure"
|
||||
:key="item"
|
||||
shadow="hover"
|
||||
>
|
||||
<div
|
||||
style="text-align: center;display: flex;flex-direction: column;"
|
||||
@click="switchPicBed(item.alias)"
|
||||
>
|
||||
<el-card v-for="item in allPicBedConfigure" :key="item" shadow="hover">
|
||||
<div style="text-align: center; display: flex; flex-direction: column" @click="switchPicBed(item.alias)">
|
||||
<el-image
|
||||
:src="require(`./assets/${item.picBedName}.webp`)"
|
||||
class="layout__addNewBucket__icon"
|
||||
style="width: 25px;height: 25px;margin: 0 auto;"
|
||||
style="width: 25px; height: 25px; margin: 0 auto"
|
||||
/>
|
||||
<span
|
||||
style="font-size: 13px;margin-top: 5px;color: cornflowerblue;"
|
||||
>
|
||||
<span style="font-size: 13px; margin-top: 5px; color: cornflowerblue">
|
||||
{{ item.alias }}
|
||||
</span>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<el-drawer
|
||||
v-model="nweBucketDrawerVisible"
|
||||
class="layout__addNewBucket"
|
||||
append-to-body
|
||||
>
|
||||
<el-drawer v-model="nweBucketDrawerVisible" class="layout__addNewBucket" append-to-body>
|
||||
<el-form
|
||||
label-position="top"
|
||||
require-asterisk-position="right"
|
||||
@@ -208,18 +145,14 @@
|
||||
:model="newBucketConfigResult"
|
||||
:rules="rules"
|
||||
>
|
||||
<div
|
||||
style="position: relative;height: 10vh;width: 100%;"
|
||||
>
|
||||
<div style="position: relative; height: 10vh; width: 100%">
|
||||
<el-image
|
||||
:src="require(`./assets/${currentPicBedName}.webp`)"
|
||||
class="layout__addNewBucket__icon"
|
||||
style="position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);"
|
||||
style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%)"
|
||||
/>
|
||||
</div>
|
||||
<el-divider
|
||||
border-style="none"
|
||||
/>
|
||||
<el-divider border-style="none" />
|
||||
<el-form-item
|
||||
v-for="option in newBucketConfig[currentPicBedName].options"
|
||||
:key="option"
|
||||
@@ -227,13 +160,19 @@
|
||||
:label="newBucketConfig[currentPicBedName].configOptions[option].description"
|
||||
>
|
||||
<el-input
|
||||
v-if="newBucketConfig[currentPicBedName].configOptions[option].component === 'input' && currentPicBedName !== 'tcyun'"
|
||||
v-model.trim="newBucketConfigResult[currentPicBedName+'.'+option]"
|
||||
v-if="
|
||||
newBucketConfig[currentPicBedName].configOptions[option].component === 'input' &&
|
||||
currentPicBedName !== 'tcyun'
|
||||
"
|
||||
v-model.trim="newBucketConfigResult[currentPicBedName + '.' + option]"
|
||||
:placeholder="newBucketConfig[currentPicBedName].configOptions[option].placeholder"
|
||||
/>
|
||||
<el-input
|
||||
v-if="currentPicBedName === 'tcyun' && newBucketConfig[currentPicBedName].configOptions[option].component === 'input'"
|
||||
v-model.trim="newBucketConfigResult[currentPicBedName+'.'+option]"
|
||||
v-if="
|
||||
currentPicBedName === 'tcyun' &&
|
||||
newBucketConfig[currentPicBedName].configOptions[option].component === 'input'
|
||||
"
|
||||
v-model.trim="newBucketConfigResult[currentPicBedName + '.' + option]"
|
||||
:placeholder="newBucketConfig[currentPicBedName].configOptions[option].placeholder"
|
||||
>
|
||||
<template #append>
|
||||
@@ -242,7 +181,7 @@
|
||||
</el-input>
|
||||
<el-select
|
||||
v-if="newBucketConfig[currentPicBedName].configOptions[option].component === 'select'"
|
||||
v-model="newBucketConfigResult[currentPicBedName+'.'+option]"
|
||||
v-model="newBucketConfigResult[currentPicBedName + '.' + option]"
|
||||
size="large"
|
||||
:persistent="false"
|
||||
teleported
|
||||
@@ -256,18 +195,16 @@
|
||||
</el-select>
|
||||
<el-switch
|
||||
v-if="newBucketConfig[currentPicBedName].configOptions[option].component === 'switch'"
|
||||
v-model="newBucketConfigResult[currentPicBedName+'.'+option]"
|
||||
v-model="newBucketConfigResult[currentPicBedName + '.' + option]"
|
||||
:active-value="true"
|
||||
:inactive-value="false"
|
||||
/>
|
||||
</el-form-item>
|
||||
<div
|
||||
style="position: relative;height: 10vh;width: 100%;z-index: 1;"
|
||||
>
|
||||
<div style="position: relative; height: 10vh; width: 100%; z-index: 1">
|
||||
<el-button
|
||||
:icon="SuccessFilled"
|
||||
type="primary"
|
||||
style="position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);"
|
||||
style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%)"
|
||||
@click="createNewBucket(currentPicBedName)"
|
||||
>
|
||||
{{ $T('MANAGE_MAIN_PAGE_SUBMIT') }}
|
||||
@@ -281,7 +218,16 @@
|
||||
<script lang="ts" setup>
|
||||
import { shell } from 'electron'
|
||||
import { ElNotification } from 'element-plus'
|
||||
import { CirclePlus, SuccessFilled, Folder, Switch, Tools, ChromeFilled, HomeFilled, FolderOpened } from '@element-plus/icons-vue'
|
||||
import {
|
||||
CirclePlus,
|
||||
SuccessFilled,
|
||||
Folder,
|
||||
Switch,
|
||||
Tools,
|
||||
ChromeFilled,
|
||||
HomeFilled,
|
||||
FolderOpened
|
||||
} from '@element-plus/icons-vue'
|
||||
import path from 'path'
|
||||
import { ref, reactive, computed, onBeforeMount, watch } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
@@ -312,7 +258,7 @@ const isLoadingBucketList = ref(false)
|
||||
const nweBucketDrawerVisible = ref(false)
|
||||
const picBedSwitchDialogVisible = ref(false)
|
||||
|
||||
watch(route, async (newRoute) => {
|
||||
watch(route, async newRoute => {
|
||||
if (newRoute.fullPath.split('?')[0] === '/main-page/manage-main-page') {
|
||||
currentAlias.value = newRoute.query.alias as string
|
||||
currentPicBedName.value = newRoute.query.picBedName as string
|
||||
@@ -322,9 +268,9 @@ watch(route, async (newRoute) => {
|
||||
}
|
||||
})
|
||||
|
||||
const getCurrentActiveBucket = computed(() => bucketNameList.value.length === 0 ? '' : bucketNameList.value[0])
|
||||
const getCurrentActiveBucket = computed(() => (bucketNameList.value.length === 0 ? '' : bucketNameList.value[0]))
|
||||
|
||||
const urlMap : IStringKeyMap = {
|
||||
const urlMap: IStringKeyMap = {
|
||||
aliyun: 'https://oss.console.aliyun.com',
|
||||
github: 'https://github.com',
|
||||
imgur: 'https://imgur.com',
|
||||
@@ -344,7 +290,7 @@ const bucketT = $T('MANAGE_MAIN_PAGE_BUCKET')
|
||||
const galleryT = $T('MANAGE_MAIN_PAGE_GALLERY')
|
||||
const repositoryT = $T('MANAGE_MAIN_PAGE_REPOSITORY')
|
||||
|
||||
const menuTitleMap:IStringKeyMap = {
|
||||
const menuTitleMap: IStringKeyMap = {
|
||||
aliyun: bucketT,
|
||||
qiniu: bucketT,
|
||||
tcyun: bucketT,
|
||||
@@ -362,7 +308,7 @@ const rules = ruleMap(newBucketConfig)
|
||||
|
||||
const openPicBedUrl = () => shell.openExternal(urlMap[currentPagePicBedConfig.picBedName])
|
||||
|
||||
function ruleMap (options: IStringKeyMap) {
|
||||
function ruleMap(options: IStringKeyMap) {
|
||||
return Object.keys(options).reduce((result, key) => {
|
||||
options[key].options.forEach((option: string) => {
|
||||
const keyName = `${key}.${option}`
|
||||
@@ -378,20 +324,23 @@ function ruleMap (options: IStringKeyMap) {
|
||||
}, {} as IStringKeyMap)
|
||||
}
|
||||
|
||||
function openNewBucketDrawer () {
|
||||
function openNewBucketDrawer() {
|
||||
nweBucketDrawerVisible.value = true
|
||||
}
|
||||
|
||||
function createNewBucket (picBedName: string) {
|
||||
function createNewBucket(picBedName: string) {
|
||||
const configOptions = newBucketConfig[picBedName].configOptions
|
||||
const resultMap: IStringKeyMap = Object.keys(configOptions).reduce((result, key) => {
|
||||
const resultKey = `${picBedName}.${key}`
|
||||
const defaultValue = configOptions[key].default
|
||||
const resultValue = newBucketConfigResult[resultKey]
|
||||
|
||||
result[key] = resultValue === '' && defaultValue !== undefined
|
||||
? defaultValue
|
||||
: resultValue === undefined ? defaultValue ?? '' : resultValue
|
||||
result[key] =
|
||||
resultValue === '' && defaultValue !== undefined
|
||||
? defaultValue
|
||||
: resultValue === undefined
|
||||
? defaultValue ?? ''
|
||||
: resultValue
|
||||
|
||||
return result
|
||||
}, {} as IStringKeyMap)
|
||||
@@ -420,7 +369,7 @@ function createNewBucket (picBedName: string) {
|
||||
})
|
||||
}
|
||||
|
||||
async function getBucketList () {
|
||||
async function getBucketList() {
|
||||
bucketList.value = {}
|
||||
bucketNameList.value = []
|
||||
isLoadingBucketList.value = true
|
||||
@@ -436,12 +385,17 @@ async function getBucketList () {
|
||||
}
|
||||
}
|
||||
|
||||
function transPathToUnix (filePath: string | undefined) {
|
||||
function transPathToUnix(filePath: string | undefined) {
|
||||
if (!filePath) return ''
|
||||
return process.platform === 'win32' ? filePath.split(path.sep).join(path.posix.sep).replace(/^\/+|\/+$/g, '') : filePath.replace(/^\/+|\/+$/g, '')
|
||||
return process.platform === 'win32'
|
||||
? filePath
|
||||
.split(path.sep)
|
||||
.join(path.posix.sep)
|
||||
.replace(/^\/+|\/+$/g, '')
|
||||
: filePath.replace(/^\/+|\/+$/g, '')
|
||||
}
|
||||
|
||||
function handleSelectMenu (bucketName: string) {
|
||||
function handleSelectMenu(bucketName: string) {
|
||||
const currentPicBedConfig = manageStore.config.picBed[currentAlias.value]
|
||||
const transformedConfig = JSON.parse(currentPicBedConfig.transformedConfig ?? '{}')
|
||||
|
||||
@@ -474,14 +428,16 @@ function handleSelectMenu (bucketName: string) {
|
||||
})
|
||||
}
|
||||
|
||||
function switchPicBed (picBedAlias:string) {
|
||||
function switchPicBed(picBedAlias: string) {
|
||||
if (picBedAlias === 'main') {
|
||||
router.push({
|
||||
path: '/main-page/manage-login-page'
|
||||
})
|
||||
return
|
||||
}
|
||||
if (route.fullPath.startsWith('/main-page/manage-main-page/manage-bucket-page') || route.fullPath.startsWith('/main-page/manage-main-page/manage-setting-page')
|
||||
if (
|
||||
route.fullPath.startsWith('/main-page/manage-main-page/manage-bucket-page') ||
|
||||
route.fullPath.startsWith('/main-page/manage-main-page/manage-setting-page')
|
||||
) {
|
||||
picBedSwitchDialogVisible.value = false
|
||||
router.push({
|
||||
@@ -503,11 +459,11 @@ function switchPicBed (picBedAlias:string) {
|
||||
}
|
||||
}
|
||||
|
||||
function changePicBed () {
|
||||
function changePicBed() {
|
||||
picBedSwitchDialogVisible.value = true
|
||||
}
|
||||
|
||||
function openBucketPageSetting () {
|
||||
function openBucketPageSetting() {
|
||||
router.push({
|
||||
path: '/main-page/manage-main-page/manage-setting-page'
|
||||
})
|
||||
|
||||
@@ -1,42 +1,19 @@
|
||||
<template>
|
||||
<div id="manage-setting">
|
||||
<el-row
|
||||
class="view-title"
|
||||
align="middle"
|
||||
justify="center"
|
||||
style="font-size: 20px;color: black;"
|
||||
>
|
||||
<el-row class="view-title" align="middle" justify="center" style="font-size: 20px; color: black">
|
||||
{{ $T('MANAGE_SETTING_TITLE') }}
|
||||
</el-row>
|
||||
<el-row
|
||||
class="setting-list"
|
||||
>
|
||||
<el-col
|
||||
:span="20"
|
||||
:offset="2"
|
||||
>
|
||||
<el-row
|
||||
style="width: 100%;"
|
||||
>
|
||||
<el-form
|
||||
label-position="left"
|
||||
label-width="50%"
|
||||
size="default"
|
||||
style="position: relative;width: 100%;"
|
||||
>
|
||||
<el-row class="setting-list">
|
||||
<el-col :span="20" :offset="2">
|
||||
<el-row style="width: 100%">
|
||||
<el-form label-position="left" label-width="50%" size="default" style="position: relative; width: 100%">
|
||||
<el-form-item>
|
||||
<template #label>
|
||||
<span
|
||||
style="position:absolute;left: 0;"
|
||||
>
|
||||
<span style="position: absolute; left: 0">
|
||||
<span>{{ $T('MANAGE_SETTING_CLEAR_CACHE_TITLE') }} </span>
|
||||
<span
|
||||
style="color: #ff4949;"
|
||||
>{{ formatFileSize(dbSize) === ''? 0 : formatFileSize(dbSize) }} </span>
|
||||
<span style="color: #ff4949">{{ formatFileSize(dbSize) === '' ? 0 : formatFileSize(dbSize) }} </span>
|
||||
<span> {{ $T('MANAGE_SETTING_CLEAR_CACHE_FREE_TITLE') }} </span>
|
||||
<span
|
||||
style="color: #ff4949;"
|
||||
>{{ dbSizeAvailableRate }} %</span>
|
||||
<span style="color: #ff4949">{{ dbSizeAvailableRate }} %</span>
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="$T('MANAGE_SETTING_CLEAR_CACHE_TIPS')"
|
||||
@@ -60,11 +37,7 @@
|
||||
@confirm="handleClearDb"
|
||||
>
|
||||
<template #reference>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
style="position:absolute;right: 0;"
|
||||
>
|
||||
<el-button type="primary" plain style="position: absolute; right: 0">
|
||||
{{ $T('MANAGE_SETTING_CLEAR_CACHE_BUTTON') }}
|
||||
</el-button>
|
||||
</template>
|
||||
@@ -82,7 +55,7 @@
|
||||
/>
|
||||
<el-link
|
||||
v-if="form.customRename"
|
||||
style="margin-top: 10px;margin-bottom: 10px;color: #409eff;"
|
||||
style="margin-top: 10px; margin-bottom: 10px; color: #409eff"
|
||||
:underline="false"
|
||||
>
|
||||
{{ $T('MANAGE_SETTING_CUSTOM_PATTERN_TITLE') }}
|
||||
@@ -91,25 +64,25 @@
|
||||
v-if="form.customRename"
|
||||
v-model="form.customRenameFormat"
|
||||
:placeholder="$T('MANAGE_SETTING_CUSTOM_PATTERN_TIPS')"
|
||||
style="width: 100%;"
|
||||
style="width: 100%"
|
||||
/>
|
||||
<el-table
|
||||
v-if="form.customRename"
|
||||
:data="customRenameFormatTable"
|
||||
style="width: 100%;margin-top: 10px;margin-left: 10%;"
|
||||
:header-cell-style="{'text-align':'center'}"
|
||||
:cell-style="{'text-align':'center'}"
|
||||
style="width: 100%; margin-top: 10px; margin-left: 10%"
|
||||
:header-cell-style="{ 'text-align': 'center' }"
|
||||
:cell-style="{ 'text-align': 'center' }"
|
||||
@cell-click="handleCellClick"
|
||||
>
|
||||
<el-table-column
|
||||
v-for="(prop) in ['placeholder', 'description', 'placeholderB', 'descriptionB']"
|
||||
v-for="prop in ['placeholder', 'description', 'placeholderB', 'descriptionB']"
|
||||
:key="prop"
|
||||
:prop="prop"
|
||||
:label="$T('MANAGE_SETTING_CUSTOM_PATTERN_TABLE_TITLE' as any)"
|
||||
width="150"
|
||||
/>
|
||||
</el-table>
|
||||
<br v-if="form.customRename">
|
||||
<br v-if="form.customRename" />
|
||||
<DynamicSwitch
|
||||
v-for="item in switchFieldsSpecialList"
|
||||
:key="item.configName"
|
||||
@@ -120,9 +93,7 @@
|
||||
/>
|
||||
<el-form-item>
|
||||
<template #label>
|
||||
<span
|
||||
style="position:absolute;left: 0;"
|
||||
>
|
||||
<span style="position: absolute; left: 0">
|
||||
{{ $T('MANAGE_SETTING_MAX_DOWNLOAD_FILE_SIZE_TITLE') }}
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
@@ -139,7 +110,7 @@
|
||||
</template>
|
||||
<el-input-number
|
||||
v-model="form.maxDownloadFileCount"
|
||||
style="position:absolute;right: 0;"
|
||||
style="position: absolute; right: 0"
|
||||
:placeholder="$T('MANAGE_SETTING_MAX_DOWNLOAD_FILE_SIZE_INPUT_TIPS')"
|
||||
:min="1"
|
||||
:max="9999"
|
||||
@@ -148,9 +119,7 @@
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<template #label>
|
||||
<span
|
||||
style="position:absolute;left: 0;"
|
||||
>
|
||||
<span style="position: absolute; left: 0">
|
||||
{{ $T('MANAGE_SETTING_PRESIGNED_URL_EXPIRE_TITLE') }}
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
@@ -167,33 +136,24 @@
|
||||
</template>
|
||||
<el-input-number
|
||||
v-model="form.PreSignedExpire"
|
||||
style="position:absolute;right: 0;"
|
||||
style="position: absolute; right: 0"
|
||||
:placeholder="$T('MANAGE_SETTING_PRESIGNED_URL_EXPIRE_TIPS')"
|
||||
:min="1"
|
||||
:step="1"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-link
|
||||
style="margin-top: 10px;margin-bottom: 10px;color: #409eff;"
|
||||
:underline="false"
|
||||
>
|
||||
<el-link style="margin-top: 10px; margin-bottom: 10px; color: #409eff" :underline="false">
|
||||
{{ $T('MANAGE_SETTING_CHOOSE_COPY_FORMAT_TITLE') }}
|
||||
</el-link>
|
||||
<br>
|
||||
<el-radio-group
|
||||
v-model="form.pasteFormat"
|
||||
>
|
||||
<el-radio
|
||||
v-for="item in pasteFormatList"
|
||||
:key="item"
|
||||
:value="item"
|
||||
>
|
||||
<br />
|
||||
<el-radio-group v-model="form.pasteFormat">
|
||||
<el-radio v-for="item in pasteFormatList" :key="item" :value="item">
|
||||
{{ $T(`MANAGE_SETTING_CHOOSE_COPY_FORMAT_${item.toUpperCase().replace(/-/g, '_')}` as any) }}
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
<el-link
|
||||
v-if="form.pasteFormat === 'custom'"
|
||||
style="margin-top: 10px;margin-bottom: 10px;color: #409eff;"
|
||||
style="margin-top: 10px; margin-bottom: 10px; color: #409eff"
|
||||
:underline="false"
|
||||
>
|
||||
{{ $T('MANAGE_SETTING_CUSTOM_COPY_FORMAT_TITLE') }}
|
||||
@@ -202,13 +162,10 @@
|
||||
v-if="form.pasteFormat === 'custom'"
|
||||
v-model="form.customPasteFormat"
|
||||
:placeholder="$T('MANAGE_SETTING_CUSTOM_COPY_FORMAT_TIPS')"
|
||||
style="width: 100%;"
|
||||
style="width: 100%"
|
||||
/>
|
||||
<div>
|
||||
<el-link
|
||||
style="margin-top: 10px;margin-bottom: 10px;color: #409eff;"
|
||||
:underline="false"
|
||||
>
|
||||
<el-link style="margin-top: 10px; margin-bottom: 10px; color: #409eff" :underline="false">
|
||||
{{ $T('MANAGE_SETTING_CHOOSE_DOWNLOAD_FOLDER_TITLE') }}
|
||||
</el-link>
|
||||
</div>
|
||||
@@ -216,13 +173,10 @@
|
||||
v-model="form.downloadDir"
|
||||
disabled
|
||||
:placeholder="$T('MANAGE_SETTING_CHOOSE_DOWNLOAD_FOLDER_TIPS')"
|
||||
style="width: 100%;margin-top: 10px;"
|
||||
style="width: 100%; margin-top: 10px"
|
||||
>
|
||||
<template #append>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handleDownloadDirClick"
|
||||
>
|
||||
<el-button type="primary" @click="handleDownloadDirClick">
|
||||
<el-icon>
|
||||
<Folder />
|
||||
</el-icon>
|
||||
@@ -231,9 +185,7 @@
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form>
|
||||
<el-divider
|
||||
border-style="none"
|
||||
/>
|
||||
<el-divider border-style="none" />
|
||||
</el-row>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -284,97 +236,128 @@ const dbSizeAvailableRate = ref('0')
|
||||
const pasteFormatList = ['markdown', 'markdown-with-link', 'rawurl', 'html', 'bbcode', 'custom']
|
||||
|
||||
settingsKeys.forEach(key => {
|
||||
watch(() => form.value[key], (newValue) => saveConfig({ [`settings.${key}`]: newValue }))
|
||||
watch(
|
||||
() => form.value[key],
|
||||
newValue => saveConfig({ [`settings.${key}`]: newValue })
|
||||
)
|
||||
})
|
||||
|
||||
const switchFieldsList = ['isAutoRefresh', 'isShowThumbnail', 'isShowList', 'isForceCustomUrlHttps', 'isEncodeUrl', 'isUploadKeepDirStructure', 'isIgnoreCase', 'timestampRename', 'randomStringRename', 'customRename']
|
||||
const switchFieldsList = [
|
||||
'isAutoRefresh',
|
||||
'isShowThumbnail',
|
||||
'isShowList',
|
||||
'isForceCustomUrlHttps',
|
||||
'isEncodeUrl',
|
||||
'isUploadKeepDirStructure',
|
||||
'isIgnoreCase',
|
||||
'timestampRename',
|
||||
'randomStringRename',
|
||||
'customRename'
|
||||
]
|
||||
const switchFieldsNoTipsList = ['isShowThumbnail', 'isShowList']
|
||||
const switchFieldsHasActiveTextList = ['isShowList']
|
||||
|
||||
const switchFieldsConfigList = switchFieldsList.map((item) => ({
|
||||
const switchFieldsConfigList = switchFieldsList.map(item => ({
|
||||
configName: item,
|
||||
segments: [{
|
||||
text: $T(`MANAGE_SETTING_${item.toUpperCase()}_TITLE` as any),
|
||||
style: 'color: black;'
|
||||
}],
|
||||
segments: [
|
||||
{
|
||||
text: $T(`MANAGE_SETTING_${item.toUpperCase()}_TITLE` as any),
|
||||
style: 'color: black;'
|
||||
}
|
||||
],
|
||||
tooltip: switchFieldsNoTipsList.includes(item) ? undefined : $T(`MANAGE_SETTING_${item.toUpperCase()}_TIPS` as any),
|
||||
activeText: switchFieldsHasActiveTextList.includes(item) ? $T(`MANAGE_SETTING_${item.toUpperCase()}_ON` as any) : undefined,
|
||||
inactiveText: switchFieldsHasActiveTextList.includes(item) ? $T(`MANAGE_SETTING_${item.toUpperCase()}_OFF` as any) : undefined
|
||||
activeText: switchFieldsHasActiveTextList.includes(item)
|
||||
? $T(`MANAGE_SETTING_${item.toUpperCase()}_ON` as any)
|
||||
: undefined,
|
||||
inactiveText: switchFieldsHasActiveTextList.includes(item)
|
||||
? $T(`MANAGE_SETTING_${item.toUpperCase()}_OFF` as any)
|
||||
: undefined
|
||||
}))
|
||||
|
||||
const switchFieldsSpecialList = [{
|
||||
configName: 'isDownloadFileKeepDirStructure',
|
||||
segments: [{
|
||||
text: $T('MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TITLE_A'),
|
||||
style: 'color: black;'
|
||||
}, {
|
||||
text: $T('MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TITLE_B'),
|
||||
style: 'color: orange;'
|
||||
}, {
|
||||
text: $T('MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TITLE_C'),
|
||||
style: 'color: black;'
|
||||
}],
|
||||
tooltip: $T('MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TIPS')
|
||||
}, {
|
||||
configName: 'isDownloadFolderKeepDirStructure',
|
||||
segments: [{
|
||||
text: $T('MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TITLE_A'),
|
||||
style: 'color: black;'
|
||||
const switchFieldsSpecialList = [
|
||||
{
|
||||
configName: 'isDownloadFileKeepDirStructure',
|
||||
segments: [
|
||||
{
|
||||
text: $T('MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TITLE_A'),
|
||||
style: 'color: black;'
|
||||
},
|
||||
{
|
||||
text: $T('MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TITLE_B'),
|
||||
style: 'color: orange;'
|
||||
},
|
||||
{
|
||||
text: $T('MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TITLE_C'),
|
||||
style: 'color: black;'
|
||||
}
|
||||
],
|
||||
tooltip: $T('MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TIPS')
|
||||
},
|
||||
{
|
||||
text: $T('MANAGE_SETTING_ISDOWNLOADFOLDERKEEPDIRSTRUCTURE_TITLE_D'),
|
||||
style: 'color: coral;'
|
||||
},
|
||||
{
|
||||
text: $T('MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TITLE_C'),
|
||||
style: 'color: black;'
|
||||
}],
|
||||
tooltip: $T('MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TIPS')
|
||||
}]
|
||||
configName: 'isDownloadFolderKeepDirStructure',
|
||||
segments: [
|
||||
{
|
||||
text: $T('MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TITLE_A'),
|
||||
style: 'color: black;'
|
||||
},
|
||||
{
|
||||
text: $T('MANAGE_SETTING_ISDOWNLOADFOLDERKEEPDIRSTRUCTURE_TITLE_D'),
|
||||
style: 'color: coral;'
|
||||
},
|
||||
{
|
||||
text: $T('MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TITLE_C'),
|
||||
style: 'color: black;'
|
||||
}
|
||||
],
|
||||
tooltip: $T('MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TIPS')
|
||||
}
|
||||
]
|
||||
|
||||
async function initData () {
|
||||
const config = await getConfig() as IStringKeyMap
|
||||
async function initData() {
|
||||
const config = (await getConfig()) as IStringKeyMap
|
||||
settingsKeys.forEach(key => {
|
||||
form.value[key] = config.settings[key] ?? form.value[key]
|
||||
})
|
||||
}
|
||||
|
||||
async function handleDownloadDirClick () {
|
||||
async function handleDownloadDirClick() {
|
||||
const result = await invokeToMain(selectDownloadFolder)
|
||||
if (result) {
|
||||
form.value.downloadDir = result
|
||||
}
|
||||
}
|
||||
|
||||
const handleCellClick = (row:any, column:any) => {
|
||||
const handleCellClick = (row: any, column: any) => {
|
||||
navigator.clipboard.writeText(row[column.property])
|
||||
ElMessage.success(`${$T('MANAGE_SETTING_COPY_MESSAGE')}${row[column.property]}`)
|
||||
}
|
||||
|
||||
function handleClearDb () {
|
||||
fileCacheDbInstance.delete().then(() => {
|
||||
getIndexDbSize()
|
||||
ElMessage.success($T('MANAGE_SETTING_CLEAR_CACHE_SUCCESS'))
|
||||
}).catch(() => {
|
||||
ElMessage.error($T('MANAGE_SETTING_CLEAR_CACHE_FAILED'))
|
||||
})
|
||||
function handleClearDb() {
|
||||
fileCacheDbInstance
|
||||
.delete()
|
||||
.then(() => {
|
||||
getIndexDbSize()
|
||||
ElMessage.success($T('MANAGE_SETTING_CLEAR_CACHE_SUCCESS'))
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage.error($T('MANAGE_SETTING_CLEAR_CACHE_FAILED'))
|
||||
})
|
||||
}
|
||||
|
||||
async function getIndexDbSize () {
|
||||
async function getIndexDbSize() {
|
||||
const size = (await navigator.storage.estimate()).usage ?? 0
|
||||
const quota = (await navigator.storage.estimate()).quota ?? 0
|
||||
dbSize.value = size
|
||||
dbSizeAvailableRate.value = (100 - size / quota * 100).toFixed(2)
|
||||
dbSizeAvailableRate.value = (100 - (size / quota) * 100).toFixed(2)
|
||||
}
|
||||
|
||||
onBeforeMount(() => {
|
||||
initData()
|
||||
getIndexDbSize()
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang='stylus'>
|
||||
<style lang="stylus">
|
||||
#manage-setting
|
||||
height 100%
|
||||
overflow-y auto
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import Dexie, { Table } from 'dexie'
|
||||
|
||||
/*
|
||||
* create a database for bucket file cache
|
||||
*database name: bucketFileDb
|
||||
*structure:
|
||||
* - table: picBedName
|
||||
* - key: alias-bucketName-prefix
|
||||
* - value: from fullList
|
||||
* - primaryKey: key
|
||||
*/
|
||||
* create a database for bucket file cache
|
||||
*database name: bucketFileDb
|
||||
*structure:
|
||||
* - table: picBedName
|
||||
* - key: alias-bucketName-prefix
|
||||
* - value: from fullList
|
||||
* - primaryKey: key
|
||||
*/
|
||||
|
||||
export interface IFileCache {
|
||||
key: string
|
||||
@@ -31,9 +31,21 @@ export class FileCacheDb extends Dexie {
|
||||
upyun: Table<IFileCache, string>
|
||||
webdavplist: Table<IFileCache, string>
|
||||
|
||||
constructor () {
|
||||
constructor() {
|
||||
super('bucketFileDb')
|
||||
const tableNames = ['aliyun', 'github', 'imgur', 'local', 'qiniu', 's3plist', 'sftp', 'smms', 'tcyun', 'upyun', 'webdavplist']
|
||||
const tableNames = [
|
||||
'aliyun',
|
||||
'github',
|
||||
'imgur',
|
||||
'local',
|
||||
'qiniu',
|
||||
's3plist',
|
||||
'sftp',
|
||||
'smms',
|
||||
'tcyun',
|
||||
'upyun',
|
||||
'webdavplist'
|
||||
]
|
||||
|
||||
const tableNamesMap = tableNames.reduce((acc, cur) => {
|
||||
acc[cur] = '&key, value'
|
||||
|
||||
@@ -9,8 +9,8 @@ export const useManageStore = defineStore('manageConfig', {
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
async refreshConfig () {
|
||||
this.config = await getConfig() ?? {}
|
||||
async refreshConfig() {
|
||||
this.config = (await getConfig()) ?? {}
|
||||
}
|
||||
},
|
||||
persist: true
|
||||
@@ -25,23 +25,23 @@ export const useFileTransferStore = defineStore('fileTransfer', {
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
refreshFileTransferList (newData: IStringKeyMap) {
|
||||
refreshFileTransferList(newData: IStringKeyMap) {
|
||||
this.fileTransferList = newData.fullList ?? []
|
||||
this.success = newData.success
|
||||
this.finished = newData.finished
|
||||
},
|
||||
resetFileTransferList () {
|
||||
resetFileTransferList() {
|
||||
this.fileTransferList = []
|
||||
this.success = false
|
||||
this.finished = false
|
||||
},
|
||||
getFileTransferList () {
|
||||
getFileTransferList() {
|
||||
return this.fileTransferList
|
||||
},
|
||||
isFinished () {
|
||||
isFinished() {
|
||||
return this.finished
|
||||
},
|
||||
isSuccess () {
|
||||
isSuccess() {
|
||||
return this.success
|
||||
}
|
||||
}
|
||||
@@ -56,23 +56,23 @@ export const useDownloadFileTransferStore = defineStore('downloadFileTransfer',
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
refreshDownloadFileTransferList (newData: IStringKeyMap) {
|
||||
refreshDownloadFileTransferList(newData: IStringKeyMap) {
|
||||
this.downloadFileTransferList = newData.fullList ?? []
|
||||
this.success = newData.success
|
||||
this.finished = newData.finished
|
||||
},
|
||||
resetDownloadFileTransferList () {
|
||||
resetDownloadFileTransferList() {
|
||||
this.downloadFileTransferList = []
|
||||
this.success = false
|
||||
this.finished = false
|
||||
},
|
||||
getDownloadFileTransferList () {
|
||||
getDownloadFileTransferList() {
|
||||
return this.downloadFileTransferList
|
||||
},
|
||||
isFinished () {
|
||||
isFinished() {
|
||||
return this.finished
|
||||
},
|
||||
isSuccess () {
|
||||
isSuccess() {
|
||||
return this.success
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,32 +7,34 @@ import { getConfig } from '@/manage/utils/dataSender'
|
||||
|
||||
import { handleUrlEncode, safeSliceF, isNeedToShorten } from '#/utils/common'
|
||||
|
||||
export function randomStringGenerator (length: number): string {
|
||||
export function randomStringGenerator(length: number): string {
|
||||
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
|
||||
return Array.from({ length }).map(() => chars.charAt(Math.floor(Math.random() * chars.length))).join('')
|
||||
return Array.from({ length })
|
||||
.map(() => chars.charAt(Math.floor(Math.random() * chars.length)))
|
||||
.join('')
|
||||
}
|
||||
|
||||
export function renameFileNameWithTimestamp (oldName: string): string {
|
||||
export function renameFileNameWithTimestamp(oldName: string): string {
|
||||
return `${Math.floor(Date.now() / 1000)}${randomStringGenerator(5)}${path.extname(oldName)}`
|
||||
}
|
||||
|
||||
export function renameFileNameWithRandomString (oldName: string, length: number = 5): string {
|
||||
export function renameFileNameWithRandomString(oldName: string, length: number = 5): string {
|
||||
return `${randomStringGenerator(length)}${path.extname(oldName)}`
|
||||
}
|
||||
|
||||
function renameFormatHelper (num: number): string {
|
||||
function renameFormatHelper(num: number): string {
|
||||
return num.toString().length === 1 ? `0${num}` : num.toString()
|
||||
}
|
||||
|
||||
function getMd5 (input: crypto.BinaryLike): string {
|
||||
function getMd5(input: crypto.BinaryLike): string {
|
||||
return crypto.createHash('md5').update(input).digest('hex')
|
||||
}
|
||||
|
||||
export function renameFileNameWithCustomString (oldName: string, customFormat: string, affixFileName?: string): string {
|
||||
export function renameFileNameWithCustomString(oldName: string, customFormat: string, affixFileName?: string): string {
|
||||
const date = new Date()
|
||||
const year = date.getFullYear().toString()
|
||||
const fileBaseName = path.basename(oldName, path.extname(oldName))
|
||||
const conversionMap : {[key: string]: () => string} = {
|
||||
const conversionMap: { [key: string]: () => string } = {
|
||||
'{Y}': () => year,
|
||||
'{y}': () => year.slice(2),
|
||||
'{m}': () => renameFormatHelper(date.getMonth() + 1),
|
||||
@@ -43,17 +45,24 @@ export function renameFileNameWithCustomString (oldName: string, customFormat: s
|
||||
'{ms}': () => date.getMilliseconds().toString().padStart(3, '0'),
|
||||
'{md5}': () => getMd5(fileBaseName),
|
||||
'{md5-16}': () => getMd5(fileBaseName).slice(0, 16),
|
||||
'{filename}': () => affixFileName ? path.basename(affixFileName, path.extname(affixFileName)) : path.basename(oldName, path.extname(oldName)),
|
||||
'{filename}': () =>
|
||||
affixFileName
|
||||
? path.basename(affixFileName, path.extname(affixFileName))
|
||||
: path.basename(oldName, path.extname(oldName)),
|
||||
'{uuid}': () => uuidv4().replace(/-/g, ''),
|
||||
'{timestamp}': () => date.getTime().toString()
|
||||
}
|
||||
if (customFormat === undefined || (!Object.keys(conversionMap).some(item => customFormat.includes(item)) && !customFormat.includes('{str-'))) {
|
||||
if (
|
||||
customFormat === undefined ||
|
||||
(!Object.keys(conversionMap).some(item => customFormat.includes(item)) && !customFormat.includes('{str-'))
|
||||
) {
|
||||
return oldName
|
||||
}
|
||||
const ext = path.extname(oldName)
|
||||
let newName = Object.keys(conversionMap).reduce((acc, cur) => {
|
||||
return acc.replace(new RegExp(cur, 'g'), conversionMap[cur]())
|
||||
}, customFormat) + ext
|
||||
let newName =
|
||||
Object.keys(conversionMap).reduce((acc, cur) => {
|
||||
return acc.replace(new RegExp(cur, 'g'), conversionMap[cur]())
|
||||
}, customFormat) + ext
|
||||
const strRegex = /{str-(\d+)}/gi
|
||||
newName = newName.replace(strRegex, (_, group1) => {
|
||||
const length = parseInt(group1, 10)
|
||||
@@ -62,7 +71,10 @@ export function renameFileNameWithCustomString (oldName: string, customFormat: s
|
||||
return newName
|
||||
}
|
||||
|
||||
export function renameFile ({ timestampRename, randomStringRename, customRename, customRenameFormat }: IStringKeyMap, oldName = ''): string {
|
||||
export function renameFile(
|
||||
{ timestampRename, randomStringRename, customRename, customRenameFormat }: IStringKeyMap,
|
||||
oldName = ''
|
||||
): string {
|
||||
switch (true) {
|
||||
case timestampRename:
|
||||
return renameFileNameWithTimestamp(oldName)
|
||||
@@ -75,8 +87,8 @@ export function renameFile ({ timestampRename, randomStringRename, customRename,
|
||||
}
|
||||
}
|
||||
|
||||
export async function formatLink (url: string, fileName: string, type: string, format?: string) : Promise<string> {
|
||||
const encodedUrl = await getConfig('settings.isEncodeUrl') ? handleUrlEncode(url) : url
|
||||
export async function formatLink(url: string, fileName: string, type: string, format?: string): Promise<string> {
|
||||
const encodedUrl = (await getConfig('settings.isEncodeUrl')) ? handleUrlEncode(url) : url
|
||||
switch (type) {
|
||||
case 'markdown':
|
||||
return ``
|
||||
@@ -98,35 +110,38 @@ export async function formatLink (url: string, fileName: string, type: string, f
|
||||
}
|
||||
}
|
||||
|
||||
export function getFileIconPath (fileName: string) {
|
||||
export function getFileIconPath(fileName: string) {
|
||||
const ext = path.extname(fileName).slice(1).toLowerCase()
|
||||
return availableIconList.includes(ext) ? `${ext}.webp` : 'unknown.webp'
|
||||
}
|
||||
|
||||
const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
|
||||
|
||||
export function formatFileSize (size: number) {
|
||||
export function formatFileSize(size: number) {
|
||||
if (size === 0) return ''
|
||||
const index = Math.floor(Math.log2(size) / 10)
|
||||
return `${(size / Math.pow(2, index * 10)).toFixed(2)} ${units[index]}`
|
||||
}
|
||||
|
||||
export function formatFileName (fileName: string, length: number = 20) {
|
||||
export function formatFileName(fileName: string, length: number = 20) {
|
||||
let ext = path.extname(fileName)
|
||||
ext = ext.length > 5 ? ext.slice(ext.length - 5) : ext
|
||||
const name = path.basename(fileName, ext)
|
||||
return isNeedToShorten(fileName, length) ? `${safeSliceF(name, length - 3 - ext.length)}...${ext}` : fileName
|
||||
}
|
||||
|
||||
export function formObjToTableData (obj: any) {
|
||||
export function formObjToTableData(obj: any) {
|
||||
const exclude = [undefined, null, '', 'transformedConfig']
|
||||
return Object.keys(obj).filter(key => !exclude.includes(obj[key])).map(key => ({
|
||||
key,
|
||||
value: typeof obj[key] === 'object' ? JSON.stringify(obj[key]) : obj[key]
|
||||
})).sort((a, b) => a.key.localeCompare(b.key))
|
||||
return Object.keys(obj)
|
||||
.filter(key => !exclude.includes(obj[key]))
|
||||
.map(key => ({
|
||||
key,
|
||||
value: typeof obj[key] === 'object' ? JSON.stringify(obj[key]) : obj[key]
|
||||
}))
|
||||
.sort((a, b) => a.key.localeCompare(b.key))
|
||||
}
|
||||
|
||||
export function isValidUrl (str: string) {
|
||||
export function isValidUrl(str: string) {
|
||||
try {
|
||||
return !!new URL(str)
|
||||
} catch (e) {
|
||||
@@ -145,7 +160,7 @@ export const svg = `
|
||||
" style="stroke-width: 4px; fill: rgba(0, 0, 0, 0)"/>
|
||||
`
|
||||
|
||||
export function customStrMatch (str: string, pattern: string) : boolean {
|
||||
export function customStrMatch(str: string, pattern: string): boolean {
|
||||
if (!str || !pattern) return false
|
||||
try {
|
||||
const reg = new RegExp(pattern, 'ug')
|
||||
@@ -156,7 +171,7 @@ export function customStrMatch (str: string, pattern: string) : boolean {
|
||||
}
|
||||
}
|
||||
|
||||
export function customStrReplace (str: string, pattern: string, replacement: string) : string {
|
||||
export function customStrReplace(str: string, pattern: string, replacement: string): string {
|
||||
if (!str || !pattern) return str
|
||||
replacement = replacement || ''
|
||||
let result = str
|
||||
|
||||
@@ -334,7 +334,16 @@ export const supportedPicBedList: IStringKeyMap = {
|
||||
}
|
||||
},
|
||||
explain: $T('MANAGE_CONSTANT_ALIYUN_EXPLAIN'),
|
||||
options: ['alias', 'accessKeyId', 'accessKeySecret', 'bucketName', 'baseDir', 'isAutoCustomUrl', 'paging', 'itemsPerPage'],
|
||||
options: [
|
||||
'alias',
|
||||
'accessKeyId',
|
||||
'accessKeySecret',
|
||||
'bucketName',
|
||||
'baseDir',
|
||||
'isAutoCustomUrl',
|
||||
'paging',
|
||||
'itemsPerPage'
|
||||
],
|
||||
refLink: 'https://piclist.cn/manage.html#%E9%98%BF%E9%87%8C%E4%BA%91oss',
|
||||
referenceText: $T('MANAGE_CONSTANT_ALIYUN_REFER_TEXT')
|
||||
},
|
||||
@@ -412,7 +421,17 @@ export const supportedPicBedList: IStringKeyMap = {
|
||||
}
|
||||
},
|
||||
explain: $T('MANAGE_CONSTANT_TENCENT_EXPLAIN'),
|
||||
options: ['alias', 'secretId', 'secretKey', 'appId', 'bucketName', 'baseDir', 'isAutoCustomUrl', 'paging', 'itemsPerPage'],
|
||||
options: [
|
||||
'alias',
|
||||
'secretId',
|
||||
'secretKey',
|
||||
'appId',
|
||||
'bucketName',
|
||||
'baseDir',
|
||||
'isAutoCustomUrl',
|
||||
'paging',
|
||||
'itemsPerPage'
|
||||
],
|
||||
refLink: 'https://piclist.cn/manage.html#%E8%85%BE%E8%AE%AF%E4%BA%91',
|
||||
referenceText: $T('MANAGE_CONSTANT_TENCENT_REFER_TEXT')
|
||||
},
|
||||
@@ -525,7 +544,18 @@ export const supportedPicBedList: IStringKeyMap = {
|
||||
}
|
||||
},
|
||||
explain: $T('MANAGE_CONSTANT_UPYUN_EXPLAIN'),
|
||||
options: ['alias', 'bucketName', 'operator', 'password', 'baseDir', 'customUrl', 'paging', 'itemsPerPage', 'antiLeechToken', 'expireTime'],
|
||||
options: [
|
||||
'alias',
|
||||
'bucketName',
|
||||
'operator',
|
||||
'password',
|
||||
'baseDir',
|
||||
'customUrl',
|
||||
'paging',
|
||||
'itemsPerPage',
|
||||
'antiLeechToken',
|
||||
'expireTime'
|
||||
],
|
||||
refLink: 'https://piclist.cn/manage.html#%E5%8F%88%E6%8B%8D%E4%BA%91',
|
||||
referenceText: $T('MANAGE_CONSTANT_UPYUN_REFER_TEXT')
|
||||
},
|
||||
@@ -680,7 +710,21 @@ export const supportedPicBedList: IStringKeyMap = {
|
||||
}
|
||||
},
|
||||
explain: $T('MANAGE_CONSTANT_S3_EXPLAIN'),
|
||||
options: ['alias', 'accessKeyId', 'secretAccessKey', 'endpoint', 'sslEnabled', 's3ForcePathStyle', 'proxy', 'aclForUpload', 'bucketName', 'baseDir', 'dogeCloudSupport', 'paging', 'itemsPerPage'],
|
||||
options: [
|
||||
'alias',
|
||||
'accessKeyId',
|
||||
'secretAccessKey',
|
||||
'endpoint',
|
||||
'sslEnabled',
|
||||
's3ForcePathStyle',
|
||||
'proxy',
|
||||
'aclForUpload',
|
||||
'bucketName',
|
||||
'baseDir',
|
||||
'dogeCloudSupport',
|
||||
'paging',
|
||||
'itemsPerPage'
|
||||
],
|
||||
refLink: 'https://piclist.cn/manage.html#s3',
|
||||
referenceText: $T('MANAGE_CONSTANT_S3_REFER_TEXT')
|
||||
},
|
||||
@@ -792,7 +836,19 @@ export const supportedPicBedList: IStringKeyMap = {
|
||||
}
|
||||
},
|
||||
explain: $T('MANAGE_CONSTANT_WEBDAV_EXPLAIN'),
|
||||
options: ['alias', 'endpoint', 'username', 'password', 'bucketName', 'baseDir', 'customUrl', 'webPath', 'proxy', 'sslEnabled', 'authType'],
|
||||
options: [
|
||||
'alias',
|
||||
'endpoint',
|
||||
'username',
|
||||
'password',
|
||||
'bucketName',
|
||||
'baseDir',
|
||||
'customUrl',
|
||||
'webPath',
|
||||
'proxy',
|
||||
'sslEnabled',
|
||||
'authType'
|
||||
],
|
||||
refLink: 'https://piclist.cn/manage.html#webdav',
|
||||
referenceText: $T('MANAGE_CONSTANT_WEBDAV_REFER_TEXT')
|
||||
},
|
||||
@@ -1003,7 +1059,21 @@ export const supportedPicBedList: IStringKeyMap = {
|
||||
}
|
||||
},
|
||||
explain: $T('MANAGE_CONSTANT_SFTP_EXPLAIN'),
|
||||
options: ['alias', 'host', 'port', 'username', 'password', 'privateKey', 'passphrase', 'fileMode', 'dirMode', 'baseDir', 'customUrl', 'bucketName', 'webPath'],
|
||||
options: [
|
||||
'alias',
|
||||
'host',
|
||||
'port',
|
||||
'username',
|
||||
'password',
|
||||
'privateKey',
|
||||
'passphrase',
|
||||
'fileMode',
|
||||
'dirMode',
|
||||
'baseDir',
|
||||
'customUrl',
|
||||
'bucketName',
|
||||
'webPath'
|
||||
],
|
||||
refLink: 'https://piclist.cn/manage.html#sftp',
|
||||
referenceText: $T('MANAGE_CONSTANT_SFTP_REFER_TEXT')
|
||||
}
|
||||
|
||||
@@ -2,17 +2,21 @@ import { ipcRenderer } from 'electron'
|
||||
|
||||
import { getRawData } from '@/utils/common'
|
||||
|
||||
import { PICLIST_MANAGE_GET_CONFIG, PICLIST_MANAGE_SAVE_CONFIG, PICLIST_MANAGE_REMOVE_CONFIG } from '~/manage/events/constants'
|
||||
import {
|
||||
PICLIST_MANAGE_GET_CONFIG,
|
||||
PICLIST_MANAGE_SAVE_CONFIG,
|
||||
PICLIST_MANAGE_REMOVE_CONFIG
|
||||
} from '~/manage/events/constants'
|
||||
|
||||
export function saveConfig (config: IObj | string, value?: any) {
|
||||
export function saveConfig(config: IObj | string, value?: any) {
|
||||
const configObj = typeof config === 'string' ? { [config]: value } : getRawData(config)
|
||||
ipcRenderer.send(PICLIST_MANAGE_SAVE_CONFIG, configObj)
|
||||
}
|
||||
|
||||
export async function getConfig<T> (key?: string): Promise<T | undefined> {
|
||||
export async function getConfig<T>(key?: string): Promise<T | undefined> {
|
||||
return await ipcRenderer.invoke(PICLIST_MANAGE_GET_CONFIG, key)
|
||||
}
|
||||
|
||||
export function removeConfig (key: string, propName: string) {
|
||||
export function removeConfig(key: string, propName: string) {
|
||||
ipcRenderer.send(PICLIST_MANAGE_REMOVE_CONFIG, key, propName)
|
||||
}
|
||||
|
||||
@@ -5,11 +5,17 @@ const AUTH_KEY_VALUE_RE = /(\w+)=["']?([^'"]{1,10000})["']?/
|
||||
let NC = 0
|
||||
const NC_PAD = '00000000'
|
||||
|
||||
function md5 (text: crypto.BinaryLike) {
|
||||
function md5(text: crypto.BinaryLike) {
|
||||
return crypto.createHash('md5').update(text).digest('hex')
|
||||
}
|
||||
|
||||
export function digestAuthHeader (method: string, uri: string, wwwAuthenticate: string, username: string, password: string) {
|
||||
export function digestAuthHeader(
|
||||
method: string,
|
||||
uri: string,
|
||||
wwwAuthenticate: string,
|
||||
username: string,
|
||||
password: string
|
||||
) {
|
||||
const parts = wwwAuthenticate.split(',')
|
||||
const opts = {} as IStringKeyMap
|
||||
for (let i = 0; i < parts.length; i++) {
|
||||
@@ -61,11 +67,9 @@ export function digestAuthHeader (method: string, uri: string, wwwAuthenticate:
|
||||
return authstring
|
||||
}
|
||||
|
||||
export async function getAuthHeader (method: string, host: string, uri: string, username: string, password: string) {
|
||||
export async function getAuthHeader(method: string, host: string, uri: string, username: string, password: string) {
|
||||
try {
|
||||
await axios.get(
|
||||
`${host}${uri}`
|
||||
)
|
||||
await axios.get(`${host}${uri}`)
|
||||
} catch (error: any) {
|
||||
if (error.response.status === 401 && error.response.headers['www-authenticate']) {
|
||||
return digestAuthHeader(method, uri, error.response.headers['www-authenticate'], username, password)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { AliyunAreaCodeName, QiniuAreaCodeName, TencentAreaCodeName } from '~/manage/utils/constants'
|
||||
import { T as $T } from '@/i18n'
|
||||
|
||||
export const newBucketConfig:IStringKeyMap = {
|
||||
export const newBucketConfig: IStringKeyMap = {
|
||||
tcyun: {
|
||||
name: $T('MANAGE_NEW_BUCKET_TCYUN_NAME'),
|
||||
icon: 'tcyun',
|
||||
|
||||
Reference in New Issue
Block a user