添加信号源时可以选择远程文件的功能

This commit is contained in:
fangxiang 2021-08-20 16:46:41 +08:00
parent a66658e62f
commit 470724fb57
4 changed files with 224 additions and 43 deletions

View File

@ -13,7 +13,10 @@ declare module "@vue/runtime-core" {
// good idea to move this instance creation inside of the
// "export default () => {}" function below (which runs individually
// for each client)
const api = axios.create({ baseURL: "https://api.example.com" });
const api = axios.create({
baseURL: "https://" + window.location.hostname,
timeout: 10000,
});
api.defaults.headers.common["X-Product-Name"] = "RK_3568";
export default boot(({ app }) => {

View File

@ -32,16 +32,17 @@
<div class="q-pa-md q-gutter-sm">
<q-breadcrumbs separator="/">
<q-breadcrumbs-el
:disable="status == 'uploading'"
:disable="uploading"
icon="home"
:label="default_path_label"
to="#"
@click="path = ''"
@click="path = default_path"
/>
<q-breadcrumbs-el
v-for="(item, index) of paths.slice(1)"
:key="index"
:label="item.name"
:disable="status == 'uploading'"
:disable="uploading"
to="#"
@click="path = item.path"
/>
@ -50,10 +51,34 @@
</div>
<q-separator />
<div class="row">
<q-btn-dropdown
stretch
flat
:label="default_path_label"
:disable="uploading"
class="q-mr-sm"
>
<q-list>
<q-item
v-for="(item, index) of disk_options"
:key="index"
clickable
v-close-popup
@click="default_path = item.value"
>
<q-item-section avatar>
<q-icon
:name="item.label == $t('local disk') ? 'desktop_mac' : 'usb'"
/>
</q-item-section>
<q-item-section> {{ item.label }} </q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
<q-btn
flat
icon="arrow_back"
:disable="path.trim() == '' || status == 'uploading'"
:disable="path.trim() == '' || uploading"
@click="backToParentPath"
:label="$t('back')"
>
@ -64,9 +89,7 @@
<q-btn
flat
icon="arrow_forward"
:disable="
prev_path == '' || path == prev_path || status == 'uploading'
"
:disable="prev_path == '' || path == prev_path || uploading"
@click="(path = prev_path) && (prev_path = '')"
:label="$t('forward')"
>
@ -78,7 +101,7 @@
flat
icon="refresh"
@click="refresh_file_list"
:disable="status == 'uploading'"
:disable="uploading"
:label="$t('refresh')"
>
<q-tooltip>
@ -89,7 +112,7 @@
flat
icon="create_new_folder"
@click="onCreateNewFolder"
:disable="loading"
:disable="loading || uploading"
:label="$t('create folder')"
>
<q-tooltip>
@ -98,10 +121,10 @@
</q-btn>
<q-btn
flat
v-if="status != 'uploading'"
v-if="!uploading"
icon="upload"
:label="$t('upload file')"
@click="status = 'uploading'"
@click="uploading = true"
>
<q-tooltip>
{{ $t("upload file") }}
@ -110,9 +133,9 @@
<q-btn
flat
icon="block"
v-if="status == 'uploading'"
v-if="uploading"
:label="$t('cancel upload file')"
@click="status = 'normal'"
@click="uploading = false"
>
<q-tooltip>
{{ $t("cancel upload file") }}
@ -127,7 +150,7 @@
>
<q-table
style="height: 69vh"
v-show="status != 'uploading'"
v-show="!uploading"
:rows="files"
:columns="columns"
virtual-scroll
@ -150,8 +173,8 @@
style="color: #ffbe4a; font-size: 2.5em"
></q-icon>
{{
props.value.length > 23
? props.value.substr(0, 23) + "..."
props.value.length > 60
? props.value.substr(0, 60) + "..."
: props.value
}}
<q-tooltip> {{ props.value }} </q-tooltip>
@ -160,30 +183,46 @@
{{ props.value }}
</div>
<div v-else>
<div v-if="props.row.can_write">
<a href="#" @click="(evt) => renameFile(props.row)">
{{ $t("rename") }}
<q-tooltip> {{ $t("click") }}{{ $t("rename") }} </q-tooltip>
</a>
&nbsp;&nbsp;&nbsp;&nbsp;
<a href="#" @click="(evt) => deleteFile(props.row)">
{{ $t("delete") }}
<q-tooltip> {{ $t("click") }}{{ $t("delete") }} </q-tooltip>
<div v-if="status != 'select'">
<div v-if="props.row.can_write">
<a href="#" @click="(evt) => renameFile(props.row)">
{{ $t("rename") }}
<q-tooltip>
{{ $t("click") }}{{ $t("rename") }}
</q-tooltip>
</a>
&nbsp;&nbsp;&nbsp;&nbsp;
<a href="#" @click="(evt) => deleteFile(props.row)">
{{ $t("delete") }}
<q-tooltip>
{{ $t("click") }}{{ $t("delete") }}
</q-tooltip>
</a>
</div>
</div>
<div v-else-if="!props.row.is_directory">
<a href="#" @click="(evt) => selectFile(props.row)">
{{ $t("select file") }}
<q-tooltip>
{{ $t("click") }}{{ $t("select file") }}
</q-tooltip>
</a>
</div>
</div>
</q-td>
</template>
</q-table>
<div v-show="status == 'uploading'" class="row q-ma-sm">
<div v-show="uploading" class="row q-ma-sm">
<q-space />
<q-uploader
ref="uploader"
style="height: 69vh; width: 70%"
:url="getUrl"
method="post"
:headers="generatorFileUploadHeaders"
:label="$t('select file') + ':'"
accept="*"
@start="onStartUpload"
@uploaded="onUploaded"
@failed="onFailed"
>
@ -202,12 +241,12 @@
@click="(evt) => copyStringToClipboard(current_file.name)"
>
<q-item-section avatar><q-icon name="file_copy" /></q-item-section>
<q-item-section>{{ $t("copy file name") }}</q-item-section>
<q-item-section>{{ $t("copy name") }}</q-item-section>
</q-item>
<q-item
clickable
v-close-popup
v-if="current_file && current_file.can_write"
v-if="current_file && current_file.can_write && status != 'select'"
@click="(evt) => renameFile(current_file)"
>
<q-item-section avatar><q-icon name="edit" /></q-item-section>
@ -216,7 +255,7 @@
<q-item
clickable
v-close-popup
v-if="current_file && current_file.can_write"
v-if="current_file && current_file.can_write && status != 'select'"
@click="(evt) => deleteFile(current_file)"
>
<q-item-section avatar
@ -224,6 +263,15 @@
/></q-item-section>
<q-item-section>{{ $t("delete") }}</q-item-section>
</q-item>
<q-item
clickable
v-close-popup
v-if="status == 'select' && !current_file.is_directory"
@click="(evt) => selectFile(current_file)"
>
<q-item-section avatar><q-icon name="attach_file" /></q-item-section>
<q-item-section>{{ $t("select file") }}</q-item-section>
</q-item>
</q-list>
</q-menu>
</div>
@ -296,15 +344,34 @@ export default defineComponent({
let show_dialog = ref(false);
let loading = ref(false);
let uploading = ref(false);
let files = ref(<FileEntity[]>[]);
let show_context_menu = ref(false);
let target_dom: any = ref(document.body.children[0]);
let current_file = ref(new FileEntity());
let path = ref("");
let default_path_label = ref($t.t("local disk"));
let default_path = ref("media");
let path = ref(default_path.value);
let prev_path = ref("");
let paths = ref([new _BreadcrumbItem("root", "")]);
let status = ref("normal");
let upload_url = ref("");
let uploader: any = ref(null);
let resolve: any = null;
let resolve_value: any = null;
const disk_options = ref([
{
label: $t.t("local disk"),
value: "media",
},
]);
for (let i = 1; i < 8; ++i) {
disk_options.value.push({
label: $t.t("usb") + i.toString(),
value: "/usb" + i.toString(),
});
}
const columns = [
{
@ -409,42 +476,107 @@ export default defineComponent({
refresh_file_list_async();
};
const selectFile = async (file: FileEntity) => {
resolve_value = {
file,
path: path.value,
};
show_dialog.value = false;
};
watch(
() => path.value,
(newValue: string) => {
(newValue: string, oldValue: string) => {
if (!newValue) {
path.value = oldValue ?? default_path.value;
return;
}
paths.value = [];
let parent_item = new _BreadcrumbItem("root", "");
let parent_item = null;
for (let item of newValue.split("/")) {
let temp = new _BreadcrumbItem(item, parent_item.path + "/" + item);
if (item.trim() == "") {
continue;
}
let temp: _BreadcrumbItem = new _BreadcrumbItem(
item,
(parent_item
? parent_item.path + "/"
: newValue.length > 0
? newValue[0] == "/" || "\\"
? "/"
: ""
: "") + item
);
paths.value.push(temp);
parent_item = temp;
}
if (paths.value.length < 1) {
paths.value.push(new _BreadcrumbItem("root", ""));
paths.value.push(new _BreadcrumbItem("local disk", "media"));
}
refresh_file_list();
}
);
watch(
() => status.value,
(newValue: string) => {
switch (newValue) {
case "normal":
case "select":
break;
default:
console.log("status error!", status.value);
status.value = "normal";
}
}
);
watch(
() => default_path.value,
(newValue: string) => {
let item = disk_options.value.find((item) => item.value == newValue);
if (item && item.value && item.label) {
default_path_label.value = item.label;
path.value = default_path.value;
}
}
);
return {
show_dialog,
loading,
uploading,
files,
columns,
show_context_menu,
default_path,
default_path_label,
path,
prev_path,
paths,
target_dom,
upload_url,
uploader,
disk_options,
current_file,
refresh_file_list,
refresh_file_list_async,
status,
showDialog() {
showDialog(in_status: string) {
status.value = in_status;
refresh_file_list();
show_dialog.value = true;
},
showDialogAsync(in_status: string) {
return new Promise((_resolve, _reject) => {
status.value = in_status;
refresh_file_list();
show_dialog.value = true;
resolve = _resolve;
});
},
generatorFileUploadHeaders(files: File[]) {
if (files.length > 0) {
return [
@ -466,6 +598,10 @@ export default defineComponent({
path.value = "";
status.value = "normal";
upload_url.value = "";
if (resolve) {
resolve(resolve_value);
}
resolve_value = null;
},
async onCreateNewFolder() {
let url = GlobalData.getInstance().createCurrentRequestUrl();
@ -513,6 +649,7 @@ export default defineComponent({
});
}
},
selectFile,
async deleteFile(file: FileEntity) {
let url = GlobalData.getInstance().createCurrentRequestUrl();
if (url) {
@ -623,6 +760,8 @@ export default defineComponent({
onTableItemDBClick(evt: PointerEvent, row: FileEntity, index: number) {
if (row && row.is_directory) {
path.value += "/" + row.name;
} else if (status.value == "select" && !row.is_directory) {
selectFile(row);
}
},
backToParentPath() {
@ -642,7 +781,12 @@ export default defineComponent({
}
return "#";
},
onStartUpload() {
loading.value = true;
},
onUploaded() {
uploading.value = false;
uploader.value.reset();
refresh_file_list();
$q.notify({
@ -651,6 +795,7 @@ export default defineComponent({
position: "top",
timeout: 1500,
});
loading.value = false;
},
onFailed(info: any) {
console.log(info);
@ -661,6 +806,7 @@ export default defineComponent({
timeout: 1500,
});
loading.value = false;
loading.value = false;
},
};
},

View File

@ -103,7 +103,7 @@
>
<template v-if="item_data.name" v-slot:append>
<q-icon
item_data.name="cancel"
name="cancel"
@click.stop="item_data.name = null"
class="cursor-pointer"
/>
@ -142,13 +142,22 @@
:loading="loading"
:disable="loading"
filled
@dblclick="doSelectFile"
v-model="item_data.media_url"
:label="media_url_label"
:hint="$t('please input') + media_url_label"
:hint="
$t('please input') +
media_url_label.substr(0, media_url_label.length - 2) +
',' +
$t('dbclick select file')
"
lazy-rules
:rules="[
(val) =>
(val && val.length > 0) || $t('Please type something'),
(val && val.length > 0) ||
$t('Please type something') +
',' +
$t('dbclick select file'),
]"
@keydown="
(evt) => {
@ -159,7 +168,7 @@
>
<template v-if="item_data.media_url" v-slot:append>
<q-icon
item_data.media_url="cancel"
name="cancel"
@click.stop="item_data.media_url = null"
class="cursor-pointer"
/>
@ -192,7 +201,7 @@
>
<template v-if="item_data.user_name" v-slot:append>
<q-icon
item_data.user_name="cancel"
name="cancel"
@click.stop="item_data.user_name = null"
class="cursor-pointer"
/>
@ -225,7 +234,7 @@
>
<template v-if="item_data.password" v-slot:append>
<q-icon
item_data.password="cancel"
name="cancel"
@click.stop="item_data.password = null"
class="cursor-pointer"
/>
@ -257,6 +266,7 @@
</q-card-actions>
</q-form>
</q-card>
<file-manage-dialog ref="file_manage_dialog" />
</q-dialog>
</template>
@ -286,8 +296,12 @@ import {
SignalSourceTreeItemEntity,
} from "src/entities/SignalSourceEntity";
import FileManageDialog from "src/components/FileManageDialog.vue";
import FileEntity from "src/entities/FileEntity";
export default defineComponent({
name: "ComponentSignalSourceDialog",
components: { FileManageDialog },
setup() {
let $store = useStore();
@ -301,6 +315,7 @@ export default defineComponent({
item_data.window_type = "EwindowType::Multimedia";
const selected: any = ref(null);
let loading = ref(false);
let file_manage_dialog: any = ref(null);
let suppored_window_types = new Set<string>([
"EwindowType::Multimedia",
@ -413,6 +428,7 @@ export default defineComponent({
selected,
loading,
tree_nodes,
file_manage_dialog,
showDialog(options: any) {
if (options) {
type.value = options.type ?? 1;
@ -455,6 +471,19 @@ export default defineComponent({
} catch {}
loading.value = false;
},
async doSelectFile() {
const obj = await file_manage_dialog.value.showDialogAsync("select");
if (obj) {
interface __I {
path: string;
file: FileEntity;
}
let { path, file }: __I = obj;
if (path && file) {
item_data.media_url = path + "/" + file.name;
}
}
},
};
},
});

View File

@ -96,7 +96,7 @@ export default {
"last edit time": "修改时间",
"file size": "文件大小",
"file name": "文件名",
"copy file name": "拷贝文件名",
"copy name": "拷贝",
"can true": "是",
"can false": "否",
"can exec": "可执行",
@ -114,4 +114,7 @@ export default {
"delete file": "文件删除",
"create folder": "新建文件夹",
"input folder name": "输入文件夹名称",
"dbclick select file": "双击选择文件",
"local disk": "本地磁盘",
usb: "U盘",
};