|
@@ -2,7 +2,7 @@
|
|
|
<div class="magic-resource" @contextmenu.prevent="e => displayBlankContextMenu(e)">
|
|
|
<div class="magic-resource-header">
|
|
|
<magic-icon icon="search" size="14px"/>
|
|
|
- <magic-input v-model:value="keyword" placeholder="输入关键字搜索" width="auto"/>
|
|
|
+ <magic-input v-model:value="keyword" :placeholder="$i('message.searchText')" width="auto"/>
|
|
|
<ul>
|
|
|
<template v-for="(button, index) in buttons" :key="index" >
|
|
|
<li v-if="!button.show || button.show()" :title="button.name || ''" @click="button.onClick&&button.onClick()" :class="{ separator: button.separator}">
|
|
@@ -11,7 +11,7 @@
|
|
|
</template>
|
|
|
</ul>
|
|
|
</div>
|
|
|
- <magic-empty v-if="!data || data.length === 0" :text="`暂无${title}信息`"/>
|
|
|
+ <magic-empty v-if="!data || data.length === 0" :text="$i('message.empty', title)"/>
|
|
|
<!-- 树形菜单 -->
|
|
|
<magic-tree ref="treeObj" v-else :data="tree" @itemClick="onItemClick" @contextmenu="onContextMenu" :draggable="true" :sort="true" :descending="descending" :onMove="onMove" :filter="keyword" :filter-text="filterText" :selected="selectedItem">
|
|
|
<template v-slot:folder="{ item }">
|
|
@@ -29,24 +29,24 @@
|
|
|
</template>
|
|
|
</magic-tree>
|
|
|
<!-- 创建&修改对话框 -->
|
|
|
- <magic-dialog :title="`${modeText}${title}分组`" v-model:value="showGroupDialog">
|
|
|
+ <magic-dialog :title="modeText" v-model:value="showGroupDialog" width="350px">
|
|
|
<!-- 表单项 -->
|
|
|
<ul class="magic-create-group">
|
|
|
- <li><label>分组名称:</label><magic-input v-model:value="groupObj.name" :placeholder="`请输入${title}分组名称`"/></li>
|
|
|
- <li v-if="requirePath"><label>分组路径:</label><magic-input v-model:value="groupObj.path" :placeholder="`请输入${title}分组路径`"/></li>
|
|
|
+ <li><label>{{ $i('resource.form.groupName') }}:</label><magic-input v-model:value="groupObj.name" :placeholder="$i('resource.form.placeholder.name', title)"/></li>
|
|
|
+ <li v-if="requirePath"><label>{{ $i('resource.form.groupPath') }}:</label><magic-input v-model:value="groupObj.path" :placeholder="$i('resource.form.placeholder.path', title)"/></li>
|
|
|
</ul>
|
|
|
<magic-button-group align="right" style="padding: 5px 0">
|
|
|
<magic-button :value="modeText" type="active" @onClick="saveGroup()"/>
|
|
|
- <magic-button value="取消" @onClick="showGroupDialog = false"/>
|
|
|
+ <magic-button :value="$i('message.cancel')" @onClick="showGroupDialog = false"/>
|
|
|
</magic-button-group>
|
|
|
</magic-dialog>
|
|
|
<!-- 复制分组对话框 -->
|
|
|
- <magic-dialog v-model:value="showCopyGroup" title="复制分组" :shade="false" padding="0" width="400px" overflow="hidden">
|
|
|
+ <magic-dialog v-model:value="showCopyGroup" :title="$i('resource.copyGroup')" :shade="false" padding="0" width="400px" overflow="hidden">
|
|
|
<magic-resource-choose ref="chooseGroup" v-model:value="chooseGroupItem" :file="false" :type="type" :single="true" />
|
|
|
<magic-button-group align="right" style="margin-right:5px;margin-bottom:5px;">
|
|
|
- <magic-button value="展开" @onClick="$refs.chooseGroup.expand(true)"></magic-button>
|
|
|
- <magic-button value="收缩" @onClick="$refs.chooseGroup.expand(false)"></magic-button>
|
|
|
- <magic-button type="active" value="复制" @onClick="doCopyGroup"></magic-button>
|
|
|
+ <magic-button :value="$i('message.expand')" @onClick="$refs.chooseGroup.expand(true)"></magic-button>
|
|
|
+ <magic-button :value="$i('message.collapse')" @onClick="$refs.chooseGroup.expand(false)"></magic-button>
|
|
|
+ <magic-button type="active" :value="$i('message.copy')" @onClick="doCopyGroup"></magic-button>
|
|
|
</magic-button-group>
|
|
|
</magic-dialog>
|
|
|
</div>
|
|
@@ -56,6 +56,7 @@ import { ref, toRaw, computed, getCurrentInstance, reactive, inject, nextTick, o
|
|
|
import bus from '../../../scripts/bus.js'
|
|
|
import constants from '../../../scripts/constants.js'
|
|
|
import request from '../../../scripts/request.js'
|
|
|
+import $i from '../../../scripts/i18n.js'
|
|
|
import Message from '../../../scripts/constants/message.js'
|
|
|
import { replaceURL, processTree, download, copyToClipboard } from '../../../scripts/utils.js'
|
|
|
const props = defineProps({
|
|
@@ -83,7 +84,7 @@ const srcGroupId = ref('')
|
|
|
// 选择分组对话框中的分组
|
|
|
const chooseGroupItem = ref(null)
|
|
|
const activateUserFiles = inject('activateUserFiles')
|
|
|
-const modeText = computed(() => mode.value ? '创建' : '修改')
|
|
|
+const modeText = computed(() => mode.value ? $i('resource.createGroup') : $i('resource.updateGroup'))
|
|
|
// 排序
|
|
|
const descending = ref(true)
|
|
|
// 当前打开的
|
|
@@ -99,7 +100,7 @@ const emits = defineEmits(['close', 'onLoad'])
|
|
|
// 搜索条的按钮
|
|
|
const buttons = ref([
|
|
|
{
|
|
|
- name: '新建分组',
|
|
|
+ name: $i('resource.createGroup'),
|
|
|
icon: 'group-add',
|
|
|
onClick:() => {
|
|
|
groupObj.value = {
|
|
@@ -110,18 +111,18 @@ const buttons = ref([
|
|
|
showGroupDialog.value = true
|
|
|
}
|
|
|
},
|
|
|
- { name: '全部展开', icon: 'expand-all', onClick: () => processTree(tree.value, it => it.opened = true) },
|
|
|
- { name: '全部折叠', icon: 'collapse-all', onClick: () => processTree(tree.value, it => it.opened = false) },
|
|
|
- { name: '按字母降序', icon: 'descending', show: () => descending.value, onClick: () => descending.value = false },
|
|
|
- { name: '按字母升序', icon: 'ascending', show: () => !descending.value, onClick: () => descending.value = true },
|
|
|
+ { name: $i('resource.header.expand'), icon: 'expand-all', onClick: () => processTree(tree.value, it => it.opened = true) },
|
|
|
+ { name: $i('resource.header.collapse'), icon: 'collapse-all', onClick: () => processTree(tree.value, it => it.opened = false) },
|
|
|
+ { name: $i('resource.header.desc'), icon: 'descending', show: () => descending.value, onClick: () => descending.value = false },
|
|
|
+ { name: $i('resource.header.asc'), icon: 'ascending', show: () => !descending.value, onClick: () => descending.value = true },
|
|
|
{ separator: true },
|
|
|
- { name: '定位当前文件', icon: 'position', onClick: () => {
|
|
|
+ { name: $i('resource.header.position'), icon: 'position', onClick: () => {
|
|
|
if(treeObj.value && selectedItem.value){
|
|
|
bus.$emit(Message.SELECT_NAVBAR_BY_ITEM, selectedItem.value)
|
|
|
treeObj.value.scrollIntoView(selectedItem.value)
|
|
|
}
|
|
|
} },
|
|
|
- { name: '隐藏', icon: 'minimize', onClick:() => emits('close')},
|
|
|
+ { name: $i('message.hide'), icon: 'minimize', onClick:() => emits('close')},
|
|
|
|
|
|
])
|
|
|
const deepFind = (itemOrId, array, nameStack, pathStack, folderStack) => {
|
|
@@ -197,28 +198,39 @@ const saveGroup = () => {
|
|
|
delete group.opened
|
|
|
delete group.folder
|
|
|
request.sendJson('/resource/folder/save', group).success(id => {
|
|
|
- const msg = `保存${props.title}分组`
|
|
|
+ const msg = `resource.saveGroup`
|
|
|
+ const path = getFullPath(group)
|
|
|
if(id){
|
|
|
- console.log(tree.value)
|
|
|
updateNode({...toRaw(groupObj.value), folder: true, id})
|
|
|
- bus.status(`${msg}「${getFullPath(group)}」成功`)
|
|
|
+ bus.status('resource.saveGroupSuccess', true, props.title, path)
|
|
|
showGroupDialog.value = false
|
|
|
bus.report(`group-save`)
|
|
|
}else{
|
|
|
- bus.status('${msg}失败', false)
|
|
|
- proxy.$alert('${msg}失败', `保存${props.title}分组`)
|
|
|
+ bus.status('resource.saveGroupFailed', false, props.title, path)
|
|
|
+ proxy.$alert($i('resource.saveGroupFailed', props.title, path))
|
|
|
}
|
|
|
|
|
|
})
|
|
|
}
|
|
|
const onMove = (src, target) => new Promise(reslove => request.send('/resource/move', { src: src.id, groupId: target.groupId || target.id }).success(r => {
|
|
|
- const msg = `移动${src.folder ? `${props.title}分组`: ''}「${getFullPath(src)}」`
|
|
|
+ const msgId = src.folder ? 'resource.moveGroup' : 'resource.moveResource'
|
|
|
+ const path = getFullPath(src)
|
|
|
if(r){
|
|
|
+ if(src.folder){
|
|
|
+ bus.status(msgId + 'Success', true, props.title, path)
|
|
|
+ } else {
|
|
|
+ bus.status(msgId + 'Success', true, path)
|
|
|
+ }
|
|
|
src[src.folder ? 'parentId' : 'groupId'] = target.groupId || target.id
|
|
|
- bus.status(`${msg}成功`)
|
|
|
+
|
|
|
}else{
|
|
|
- proxy.$alert(`${msg}失败`)
|
|
|
- bus.status(`${msg}失败`, false)
|
|
|
+ if(src.folder){
|
|
|
+ bus.status(msgId + 'Failed', false, props.title, path)
|
|
|
+ proxy.$alert($i(msgId + 'Failed', props.title, path))
|
|
|
+ } else {
|
|
|
+ bus.status(msgId + 'Failed', false, path)
|
|
|
+ proxy.$alert($i(msgId + 'Failed', path))
|
|
|
+ }
|
|
|
}
|
|
|
reslove(r)
|
|
|
}))
|
|
@@ -271,12 +283,12 @@ const onContextMenu = (item, event) => {
|
|
|
const menus = []
|
|
|
if(item.folder) {
|
|
|
menus.push.apply(menus, [{
|
|
|
- label: `新建${props.title}`,
|
|
|
+ label: $i('resource.contextmenu.newFile', props.title),
|
|
|
icon: 'plus',
|
|
|
onClick(){
|
|
|
const info = {
|
|
|
groupId: item.id,
|
|
|
- name: '未定义名称',
|
|
|
+ name: $i('message.untitled'),
|
|
|
script: 'hello',
|
|
|
path: config.requirePath ? '' : undefined
|
|
|
}
|
|
@@ -284,7 +296,7 @@ const onContextMenu = (item, event) => {
|
|
|
onItemClick(info)
|
|
|
}
|
|
|
},{
|
|
|
- label: `新建分组`,
|
|
|
+ label: $i('resource.createGroup'),
|
|
|
icon: 'group-add',
|
|
|
onClick(){
|
|
|
mode.value = true
|
|
@@ -295,7 +307,7 @@ const onContextMenu = (item, event) => {
|
|
|
showGroupDialog.value = true
|
|
|
}
|
|
|
},{
|
|
|
- label: `修改分组`,
|
|
|
+ label: $i('resource.updateGroup'),
|
|
|
icon: 'update',
|
|
|
onClick(){
|
|
|
mode.value = false
|
|
@@ -305,25 +317,25 @@ const onContextMenu = (item, event) => {
|
|
|
showGroupDialog.value = true
|
|
|
}
|
|
|
},{
|
|
|
- label: `复制分组`,
|
|
|
+ label: $i('resource.copyGroup'),
|
|
|
icon: 'copy',
|
|
|
onClick(){
|
|
|
srcGroupId.value = item.id
|
|
|
showCopyGroup.value = true
|
|
|
}
|
|
|
},{
|
|
|
- label: `删除分组`,
|
|
|
+ label: $i('resource.contextmenu.deleteGroup'),
|
|
|
icon: 'delete',
|
|
|
onClick() {
|
|
|
- proxy.$confirm(`删除分组`, `是否要删除分组「${getFullPath(item)}」`, ()=> {
|
|
|
+ proxy.$confirm($i('resource.contextmenu.deleteGroup'), $i('resource.deleteGroupConfirm', props.title, getFullPath(item)), ()=> {
|
|
|
if(item.id) {
|
|
|
request.send('/resource/delete', { id: item.id }).success(ret => {
|
|
|
if(!ret) {
|
|
|
- proxy.$alert(`删除${props.title}分组「${getFullPath(item)}」失败`)
|
|
|
- bus.status(`删除${props.title}分组「${getFullPath(item)}」失败`, false)
|
|
|
+ proxy.$alert('resource.deleteGroupFailed', props.title, getFullPath(item))
|
|
|
+ bus.status('resource.deleteGroupFailed', false, props.title, getFullPath(item))
|
|
|
bus.report(`group-delete`)
|
|
|
}else{
|
|
|
- bus.status(`删除${props.title}分组「${getFullPath(item)}」成功`)
|
|
|
+ bus.status('resource.deleteGroupSuccess', true, props.title, getFullPath(item))
|
|
|
deleteNode(item)
|
|
|
}
|
|
|
})
|
|
@@ -333,28 +345,28 @@ const onContextMenu = (item, event) => {
|
|
|
})
|
|
|
}
|
|
|
},{
|
|
|
- label: `导出`,
|
|
|
+ label: $i('resource.contextmenu.exportGroup'),
|
|
|
icon: 'download',
|
|
|
onClick() {
|
|
|
request.send(`/download?groupId=${item.id}`, null, { headers: { 'Content-Type': 'application/json' }, responseType: 'blob' }).success(blob => {
|
|
|
download(blob, `${item.name}.zip`)
|
|
|
- bus.$emit('status', `分组「${item.name}」相关${props.title}已导出`)
|
|
|
+ bus.status('resource.groupExport', true, item.name, props.title)
|
|
|
bus.report(`group-export`)
|
|
|
})
|
|
|
}
|
|
|
}])
|
|
|
if(item.parentId !== '0'){
|
|
|
menus.push({
|
|
|
- label: `移动到根节点`,
|
|
|
+ label: $i('resource.contextmenu.moveToRoot'),
|
|
|
icon: 'move',
|
|
|
onClick() {
|
|
|
- proxy.$confirm(`移动分组`, `是否要将分组「${getFullPath(item)}」移动至根节点`, ()=> {
|
|
|
+ proxy.$confirm($i('resource.moveGroup'), $i('resource.moveRootGroupConfirm', getFullPath(item)), ()=> {
|
|
|
request.send('/resource/move', { src: item.id, groupId: '0' }).success(ret => {
|
|
|
if(!ret) {
|
|
|
- proxy.$alert(`移动${props.title}分组「${getFullPath(item)}」至根节点失败`)
|
|
|
- bus.status(`移动${props.title}分组「${getFullPath(item)}」至根节点失败`, false)
|
|
|
+ proxy.$alert($i('resource.moveRootFailed', props.title, getFullPath(item)))
|
|
|
+ bus.status('resource.moveRootFailed', false, props.title, getFullPath(item))
|
|
|
}else{
|
|
|
- bus.status(`移动${props.title}分组「${getFullPath(item)}」至根节点成功`)
|
|
|
+ bus.status('resource.moveRootSuccess', true, props.title, getFullPath(item))
|
|
|
item.parentId = '0'
|
|
|
deleteNode(item)
|
|
|
updateNode(item)
|
|
@@ -367,13 +379,13 @@ const onContextMenu = (item, event) => {
|
|
|
}
|
|
|
} else {
|
|
|
menus.push.apply(menus, [{
|
|
|
- label: `复制${props.title}`,
|
|
|
+ label: $i('resource.contextmenu.copy', props.title),
|
|
|
icon: 'copy',
|
|
|
divided: true,
|
|
|
onClick: () => {
|
|
|
request.send(`/resource/file/${item.id}`).success(res => {
|
|
|
res.id = `copy${parseInt(Math.random() * 10000000000)}`
|
|
|
- res.name = res.name + '(复制)'
|
|
|
+ res.name = res.name + `(${$i('message.copy')})`
|
|
|
if(config.requirePath){
|
|
|
res.path = res.path + '_copy'
|
|
|
}
|
|
@@ -385,42 +397,42 @@ const onContextMenu = (item, event) => {
|
|
|
if(config.requirePath){
|
|
|
if(props.type === 'api'){
|
|
|
menus.push({
|
|
|
- label: `复制路径`,
|
|
|
+ label: $i('resource.contextmenu.copyWithPath'),
|
|
|
icon: 'copy',
|
|
|
onClick: () => {
|
|
|
let path = getFullPath(item, true)
|
|
|
if(path){
|
|
|
path = replaceURL(constants.SERVER_URL + '/' + path)
|
|
|
if(copyToClipboard(path)){
|
|
|
- bus.status(`${props.title}路径「${path}」复制成功`)
|
|
|
+ bus.status('resource.copyPathSuccess', true, props.title, path)
|
|
|
}else{
|
|
|
- bus.status(`${props.title}路径「${path}」复制失败,请手动复制`)
|
|
|
+ bus.status('resource.copyPathFailed', false, props.title, path)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
})
|
|
|
}
|
|
|
menus.push.apply(menus, [{
|
|
|
- label: `复制相对路径`,
|
|
|
+ label: $i('resource.contextmenu.copyRelativePath'),
|
|
|
icon: 'copy',
|
|
|
divided: true,
|
|
|
onClick: () => {
|
|
|
const path = getFullPath(item, true)
|
|
|
if(path){
|
|
|
if(copyToClipboard(path)){
|
|
|
- bus.status(`${props.title}相对路径「${path}」复制成功`)
|
|
|
+ bus.status('resource.copyRelativePathSuccess', true, props.title, path)
|
|
|
}else{
|
|
|
- bus.status(`${props.title}相对路径「${path}」复制失败,请手动复制`)
|
|
|
+ bus.status('resource.copyRelativePathFailed', false, props.title, path)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}])
|
|
|
if(item.lock === constants.LOCKED){
|
|
|
menus.push({
|
|
|
- label: '解锁',
|
|
|
+ label: $i('resource.contextmenu.unlock'),
|
|
|
icon: 'unlock',
|
|
|
onClick: () => request.sendPost('/resource/unlock', { id: item.id}).success(ret => {
|
|
|
- bus.status(`${props.title}「${getFullPath(item)}」解锁${ret ? '成功' : '失败'}`, ret)
|
|
|
+ bus.status(ret ? 'message.unlockSuccess' : 'message.unlockFailed', ret, getFullPath(item))
|
|
|
if(ret) {
|
|
|
item.lock = constants.UNLOCK
|
|
|
bus.report(`resource-unlock`)
|
|
@@ -429,10 +441,10 @@ const onContextMenu = (item, event) => {
|
|
|
})
|
|
|
} else {
|
|
|
menus.push({
|
|
|
- label: '锁定',
|
|
|
+ label: $i('resource.contextmenu.lock'),
|
|
|
icon: 'lock',
|
|
|
onClick: () => request.sendPost('/resource/lock', { id: item.id}).success(ret => {
|
|
|
- bus.status(`${props.title}「${getFullPath(item)}」锁定${ret ? '成功' : '失败'}`, ret)
|
|
|
+ bus.status(ret ? 'message.lockSuccess' : 'message.lockFailed', ret, getFullPath(item))
|
|
|
if(ret) {
|
|
|
item.lock = constants.LOCKED
|
|
|
bus.report(`resource-lock`)
|
|
@@ -442,28 +454,28 @@ const onContextMenu = (item, event) => {
|
|
|
}
|
|
|
}
|
|
|
menus.push.apply(menus, [{
|
|
|
- label: `刷新`,
|
|
|
+ label: $i('message.refresh'),
|
|
|
icon: 'refresh'
|
|
|
},{
|
|
|
- label: `删除`,
|
|
|
+ label: $i('resource.contextmenu.delete'),
|
|
|
icon: 'delete',
|
|
|
onClick: () => {
|
|
|
- const msg = `删除${props.title}「${getFullPath(item)}」`
|
|
|
- proxy.$confirm(`删除${props.title}`, `是否要删除${props.title}「${getFullPath(item)}」`, ()=> {
|
|
|
+ const msg = `${props.title}「${getFullPath(item)}」`
|
|
|
+ proxy.$confirm($i('message.deleteTips', props.title), $i('message.deleteConfirm', msg), ()=> {
|
|
|
if(item.id && !item.id.startsWith('copy')){
|
|
|
request.send('/resource/delete', { id: item.id }).success(ret => {
|
|
|
if(!ret) {
|
|
|
- bus.status(`${msg}失败`, false)
|
|
|
- proxy.$alert(`${msg}失败`)
|
|
|
+ bus.status('message.deleteFailed', false, msg)
|
|
|
+ proxy.$alert($i('message.deleteFailed', msg))
|
|
|
}else{
|
|
|
- bus.status(`${msg}成功`)
|
|
|
+ bus.status('message.deleteSuccess', true, msg)
|
|
|
deleteNode(item)
|
|
|
bus.$emit(Message.DELETE_FILE, item)
|
|
|
bus.report(`resource-delete`)
|
|
|
}
|
|
|
})
|
|
|
}else{
|
|
|
- bus.status(`${msg}成功`)
|
|
|
+ bus.status('message.deleteSuccess', true, msg)
|
|
|
deleteNode(item)
|
|
|
bus.$emit(Message.DELETE_FILE, item)
|
|
|
}
|