🔨 修改 sftp 样式.
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
:unmount-on-close="true"
|
||||
:ok-button-props="{ disabled: loading }"
|
||||
:cancel-button-props="{ disabled: loading }"
|
||||
:on-before-ok="handlerOk"
|
||||
:on-before-ok="handleOk"
|
||||
@cancel="handleClose">
|
||||
<a-spin class="full form-container" :loading="loading">
|
||||
<a-form :model="formModel"
|
||||
@@ -14,6 +14,13 @@
|
||||
label-align="right"
|
||||
:auto-label-width="true"
|
||||
:rules="bookmarkFormRules">
|
||||
<!-- 类型 -->
|
||||
<a-form-item field="type" label="类型" hide-asterisk>
|
||||
<a-radio-group v-model="formModel.type"
|
||||
type="button"
|
||||
class="full-radio-group usn"
|
||||
:options="toRadioOptions(pathBookmarkTypeKey)" />
|
||||
</a-form-item>
|
||||
<!-- 名称 -->
|
||||
<a-form-item field="name" label="名称">
|
||||
<a-input v-model="formModel.name"
|
||||
@@ -24,13 +31,6 @@
|
||||
<a-form-item field="groupId" label="分组">
|
||||
<path-bookmark-group-selector v-model="formModel.groupId" />
|
||||
</a-form-item>
|
||||
<!-- 类型 -->
|
||||
<a-form-item field="type" label="类型">
|
||||
<a-select v-model="formModel.type"
|
||||
:options="toOptions(pathBookmarkTypeKey)"
|
||||
placeholder="请选择类型"
|
||||
allow-clear />
|
||||
</a-form-item>
|
||||
<!-- 文件路径 -->
|
||||
<a-form-item field="path" label="路径">
|
||||
<a-textarea v-model="formModel.path"
|
||||
@@ -51,22 +51,24 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { PathBookmarkUpdateRequest } from '@/api/terminal/path-bookmark';
|
||||
import type { FormHandle } from '@/types/form';
|
||||
import { ref } from 'vue';
|
||||
import useLoading from '@/hooks/loading';
|
||||
import useVisible from '@/hooks/visible';
|
||||
import { assignOmitRecord } from '@/utils';
|
||||
import { createPathBookmark, updatePathBookmark } from '@/api/terminal/path-bookmark';
|
||||
import { bookmarkFormRules } from '../../types/form.rules';
|
||||
import { pathBookmarkTypeKey, PathBookmarkType } from '../../types/const';
|
||||
import { useDictStore } from '@/store';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { pathBookmarkTypeKey, PathBookmarkType } from '../../types/const';
|
||||
import { bookmarkFormRules } from '../../types/form.rules';
|
||||
import PathBookmarkGroupSelector from '@/components/terminal/bookmark-path/group/selector/index.vue';
|
||||
|
||||
const { visible, setVisible } = useVisible();
|
||||
const { loading, setLoading } = useLoading();
|
||||
const { toOptions } = useDictStore();
|
||||
const { toRadioOptions } = useDictStore();
|
||||
|
||||
const title = ref<string>();
|
||||
const isAddHandle = ref<boolean>(true);
|
||||
const formHandle = ref<FormHandle>('add');
|
||||
|
||||
const defaultForm = (): PathBookmarkUpdateRequest => {
|
||||
return {
|
||||
@@ -86,28 +88,23 @@
|
||||
// 打开新增
|
||||
const openAdd = () => {
|
||||
title.value = '添加路径书签';
|
||||
isAddHandle.value = true;
|
||||
renderForm({ ...defaultForm() });
|
||||
formHandle.value = 'add';
|
||||
formModel.value = assignOmitRecord({ ...defaultForm() });
|
||||
setVisible(true);
|
||||
};
|
||||
|
||||
// 打开修改
|
||||
const openUpdate = (record: any) => {
|
||||
title.value = '修改路径书签';
|
||||
isAddHandle.value = false;
|
||||
renderForm({ ...defaultForm(), ...record });
|
||||
formHandle.value = 'update';
|
||||
formModel.value = assignOmitRecord({ ...defaultForm(), ...record });
|
||||
setVisible(true);
|
||||
};
|
||||
|
||||
// 渲染表单
|
||||
const renderForm = (record: any) => {
|
||||
formModel.value = Object.assign({}, record);
|
||||
};
|
||||
|
||||
defineExpose({ openAdd, openUpdate });
|
||||
|
||||
// 确定
|
||||
const handlerOk = async () => {
|
||||
const handleOk = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
// 验证参数
|
||||
@@ -115,7 +112,7 @@
|
||||
if (error) {
|
||||
return false;
|
||||
}
|
||||
if (isAddHandle.value) {
|
||||
if (formHandle.value === 'add') {
|
||||
// 新增
|
||||
const { data: id } = await createPathBookmark(formModel.value);
|
||||
formModel.value.id = id;
|
||||
@@ -127,8 +124,8 @@
|
||||
Message.success('修改成功');
|
||||
emits('updated', formModel.value);
|
||||
}
|
||||
// 清空
|
||||
handlerClear();
|
||||
handleClose();
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
} finally {
|
||||
@@ -138,11 +135,12 @@
|
||||
|
||||
// 关闭
|
||||
const handleClose = () => {
|
||||
handlerClear();
|
||||
handleClear();
|
||||
setVisible(false);
|
||||
};
|
||||
|
||||
// 清空
|
||||
const handlerClear = () => {
|
||||
const handleClear = () => {
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
<a-form-item field="path"
|
||||
disabled
|
||||
label="文件路径">
|
||||
<a-input v-model="formModel.path"
|
||||
placeholder="原始路径" />
|
||||
<a-textarea v-model="formModel.path"
|
||||
placeholder="原始路径"
|
||||
:auto-size="{ minRows: 3, maxRows: 3 }" />
|
||||
</a-form-item>
|
||||
<!-- 文件权限 -->
|
||||
<a-form-item field="mod"
|
||||
@@ -56,7 +57,6 @@
|
||||
|
||||
const { visible, setVisible } = useVisible();
|
||||
|
||||
const sessionKey = ref();
|
||||
const modRef = ref();
|
||||
const formRef = ref();
|
||||
const formModel = ref({
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
<a-form-item field="path"
|
||||
:label="`${touch ? '文件' : '文件夹'}路径`"
|
||||
:rules="[{ required: true, message: `请输入${touch ? '文件' : '文件夹'}路径` }]">
|
||||
<a-input ref="pathRef"
|
||||
v-model="formModel.path"
|
||||
:placeholder="`请输入${touch ? '文件' : '文件夹'}路径`" />
|
||||
<a-textarea ref="pathRef"
|
||||
v-model="formModel.path"
|
||||
:placeholder="`请输入${touch ? '文件' : '文件夹'}路径`"
|
||||
:auto-size="{ minRows: 3, maxRows: 3 }" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
|
||||
@@ -15,17 +15,19 @@
|
||||
<a-form-item field="path"
|
||||
disabled
|
||||
label="原始路径">
|
||||
<a-input v-model="formModel.path"
|
||||
placeholder="原始路径" />
|
||||
<a-textarea v-model="formModel.path"
|
||||
placeholder="原始路径"
|
||||
:auto-size="{ minRows: 3, maxRows: 3 }" />
|
||||
</a-form-item>
|
||||
<!-- 目标路径 -->
|
||||
<a-form-item field="target"
|
||||
label="目标路径"
|
||||
extra="目标路径可以是绝对路径/相对路径/名称 (可以包含 ./ ../)"
|
||||
:rules="[{ required: true, message: '请输入目标路径' }]">
|
||||
<a-input ref="targetRef"
|
||||
v-model="formModel.target"
|
||||
placeholder="请输入目标路径" />
|
||||
<a-textarea ref="targetRef"
|
||||
v-model="formModel.target"
|
||||
placeholder="请输入目标路径"
|
||||
:auto-size="{ minRows: 3, maxRows: 3 }" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
|
||||
@@ -8,67 +8,73 @@
|
||||
:align-center="false"
|
||||
:mask-closable="false"
|
||||
:unmount-on-close="true"
|
||||
:on-before-ok="handlerOk"
|
||||
:on-before-ok="handleOk"
|
||||
@cancel="handleClose">
|
||||
<div class="upload-container">
|
||||
<a-form :model="formModel"
|
||||
ref="formRef"
|
||||
label-align="right"
|
||||
:auto-label-width="true">
|
||||
<!-- 上传目录 -->
|
||||
<div class="item-wrapper">
|
||||
<div class="form-item">
|
||||
<span class="item-label">上传至文件夹</span>
|
||||
<a-input class="item-input"
|
||||
v-model="parentPath"
|
||||
placeholder="上传目录" />
|
||||
<a-form-item field="parentPath"
|
||||
label="上传目录"
|
||||
:rules="[{ required: true, message: '请输入文件上传目录' }]">
|
||||
<a-textarea ref="pathRef"
|
||||
v-model="formModel.parentPath"
|
||||
placeholder="上传目录"
|
||||
:auto-size="{ minRows: 3, maxRows: 3 }" />
|
||||
</a-form-item>
|
||||
<!-- 选择文件 -->
|
||||
<a-form-item class="mb0" hide-asterisk>
|
||||
<div class="button-container">
|
||||
<!-- 选择文件 -->
|
||||
<a-upload v-model:file-list="fileList"
|
||||
:auto-upload="false"
|
||||
:show-file-list="false"
|
||||
:multiple="true">
|
||||
<template #upload-button>
|
||||
<a-button type="primary" long>选择文件</a-button>
|
||||
</template>
|
||||
</a-upload>
|
||||
<!-- 选择文件夹 -->
|
||||
<a-upload v-model:file-list="fileList"
|
||||
:auto-upload="false"
|
||||
:show-file-list="false"
|
||||
:directory="true">
|
||||
<template #upload-button>
|
||||
<a-button type="primary" long>选择文件夹</a-button>
|
||||
</template>
|
||||
</a-upload>
|
||||
</div>
|
||||
</div>
|
||||
<a-space>
|
||||
<!-- 选择文件 -->
|
||||
<a-upload v-model:file-list="fileList"
|
||||
:auto-upload="false"
|
||||
:show-file-list="false"
|
||||
:multiple="true">
|
||||
<template #upload-button>
|
||||
<a-button type="primary">选择文件</a-button>
|
||||
</template>
|
||||
</a-upload>
|
||||
<!-- 选择文件夹 -->
|
||||
<a-upload v-model:file-list="fileList"
|
||||
:auto-upload="false"
|
||||
:show-file-list="false"
|
||||
:directory="true">
|
||||
<template #upload-button>
|
||||
<a-button type="primary">选择文件夹</a-button>
|
||||
</template>
|
||||
</a-upload>
|
||||
</a-space>
|
||||
<!-- 文件列表 -->
|
||||
<a-upload v-if="fileList.length"
|
||||
class="file-list-uploader"
|
||||
v-model:file-list="fileList"
|
||||
:auto-upload="false"
|
||||
:show-file-list="true">
|
||||
<template #upload-button />
|
||||
<template #file-name="{ fileItem }">
|
||||
<div class="file-name-wrapper">
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<!-- 文件列表 -->
|
||||
<a-upload v-if="fileList.length"
|
||||
class="file-list-uploader"
|
||||
v-model:file-list="fileList"
|
||||
:auto-upload="false"
|
||||
:show-file-list="true">
|
||||
<template #upload-button />
|
||||
<template #file-name="{ fileItem }">
|
||||
<div class="file-name-wrapper">
|
||||
<!-- 文件名称 -->
|
||||
<a-tooltip position="left"
|
||||
:mini="true"
|
||||
:auto-fix-position="false"
|
||||
content-class="terminal-tooltip-content"
|
||||
arrow-class="terminal-tooltip-content"
|
||||
:content="fileItem.file.webkitRelativePath || fileItem.file.name">
|
||||
<!-- 文件名称 -->
|
||||
<a-tooltip position="left"
|
||||
:mini="true"
|
||||
:auto-fix-position="false"
|
||||
content-class="terminal-tooltip-content"
|
||||
arrow-class="terminal-tooltip-content"
|
||||
:content="fileItem.file.webkitRelativePath || fileItem.file.name">
|
||||
<!-- 文件名称 -->
|
||||
<span class="file-name text-ellipsis">
|
||||
{{ fileItem.file.webkitRelativePath || fileItem.file.name }}
|
||||
</span>
|
||||
</a-tooltip>
|
||||
<!-- 文件大小 -->
|
||||
<span class="file-size span-blue">
|
||||
{{ getFileSize(fileItem.file.size) }}
|
||||
<span class="file-name text-ellipsis">
|
||||
{{ fileItem.file.webkitRelativePath || fileItem.file.name }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</a-upload>
|
||||
</div>
|
||||
</a-tooltip>
|
||||
<!-- 文件大小 -->
|
||||
<span class="file-size span-blue">
|
||||
{{ getFileSize(fileItem.file.size) }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</a-upload>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
@@ -81,12 +87,11 @@
|
||||
<script lang="ts" setup>
|
||||
import type { FileItem } from '@arco-design/web-vue';
|
||||
import type { ITerminalSession } from '@/views/terminal/interfaces';
|
||||
import { ref } from 'vue';
|
||||
import { ref, nextTick } from 'vue';
|
||||
import { useTerminalStore } from '@/store';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { getFileSize } from '@/utils/file';
|
||||
import useVisible from '@/hooks/visible';
|
||||
import useLoading from '@/hooks/loading';
|
||||
|
||||
const props = defineProps<{
|
||||
session?: ITerminalSession;
|
||||
@@ -94,24 +99,31 @@
|
||||
const emits = defineEmits(['closed']);
|
||||
|
||||
const { visible, setVisible } = useVisible();
|
||||
const { loading, setLoading } = useLoading();
|
||||
const { transferManager } = useTerminalStore();
|
||||
|
||||
const parentPath = ref('');
|
||||
const pathRef = ref();
|
||||
const formRef = ref();
|
||||
const formModel = ref({
|
||||
parentPath: ''
|
||||
});
|
||||
const fileList = ref<FileItem[]>([]);
|
||||
|
||||
// 打开
|
||||
const open = (parent: string) => {
|
||||
parentPath.value = parent;
|
||||
formModel.value.parentPath = parent;
|
||||
setVisible(true);
|
||||
nextTick(() => {
|
||||
pathRef.value?.focus();
|
||||
});
|
||||
};
|
||||
|
||||
defineExpose({ open });
|
||||
|
||||
// 确定
|
||||
const handlerOk = async () => {
|
||||
if (!parentPath.value) {
|
||||
Message.error('请输入上传目录');
|
||||
const handleOk = async () => {
|
||||
// 验证参数
|
||||
const error = await formRef.value.validate();
|
||||
if (error) {
|
||||
return false;
|
||||
}
|
||||
if (!fileList.value.length) {
|
||||
@@ -120,20 +132,19 @@
|
||||
}
|
||||
// 获取上传的文件
|
||||
const files = fileList.value.map(s => s.file as File);
|
||||
// 普通上传
|
||||
await transferManager.sftp.addUpload(props.session as ITerminalSession, parentPath.value, files);
|
||||
// 清空
|
||||
handlerClear();
|
||||
await transferManager.sftp.addUpload(props.session as ITerminalSession, formModel.value.parentPath, files);
|
||||
handleClose();
|
||||
return true;
|
||||
};
|
||||
|
||||
// 关闭
|
||||
const handleClose = () => {
|
||||
handlerClear();
|
||||
handleClear();
|
||||
setVisible(false);
|
||||
};
|
||||
|
||||
// 清空
|
||||
const handlerClear = () => {
|
||||
const handleClear = () => {
|
||||
fileList.value = [];
|
||||
emits('closed');
|
||||
};
|
||||
@@ -142,49 +153,24 @@
|
||||
|
||||
<style lang="less" scoped>
|
||||
@file-size-width: 82px;
|
||||
@item-label: 104px;
|
||||
|
||||
.upload-container {
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.item-wrapper {
|
||||
margin-bottom: 24px;
|
||||
.button-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
gap: 12px;
|
||||
|
||||
.form-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.item-label {
|
||||
width: @item-label;
|
||||
padding-right: 8px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
user-select: none;
|
||||
|
||||
&:after {
|
||||
content: ':';
|
||||
margin-left: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.item-input {
|
||||
width: 376px;
|
||||
}
|
||||
|
||||
.form-help {
|
||||
margin: 4px 0 0 @item-label;
|
||||
font-size: 12px;
|
||||
color: var(--color-text-2);
|
||||
:deep(.arco-upload) {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.file-list-uploader {
|
||||
margin-top: 24px;
|
||||
margin-top: 16px;
|
||||
|
||||
:deep(.arco-upload) {
|
||||
display: none;
|
||||
@@ -192,7 +178,7 @@
|
||||
|
||||
:deep(.arco-upload-list) {
|
||||
padding: 0 12px 0 0;
|
||||
max-height: calc(100vh - 496px);
|
||||
max-height: calc(100vh - 536px);
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user