Browse Source

style: 修改网站样式

pull/105/head
zhengkunwang223 2 years ago committed by zhengkunwang223
parent
commit
e82b40f5b7
  1. 2
      apps/wordpress/versions/6.0.1/config.json
  2. 2
      apps/wordpress/versions/6.0.2/config.json
  3. 2
      cmd/server/nginx_conf/ssl.conf
  4. 1
      cmd/server/nginx_conf/website_default.conf
  5. 8
      frontend/src/components/app-layout/footer/index.scss
  6. 18
      frontend/src/components/app-layout/footer/index.vue
  7. 9
      frontend/src/components/app-status/index.vue
  8. 11
      frontend/src/components/back-button/index.vue
  9. 2
      frontend/src/components/container-log/index.vue
  10. 19
      frontend/src/components/drawer-header/index.vue
  11. 10
      frontend/src/config/nprogress.ts
  12. 5
      frontend/src/lang/modules/zh.ts
  13. 5
      frontend/src/layout/index.scss
  14. 14
      frontend/src/layout/index.vue
  15. 69
      frontend/src/layout/layout-content.vue
  16. 8
      frontend/src/layout/layout-view.vue
  17. 14
      frontend/src/styles/common.scss
  18. 2
      frontend/src/styles/var.scss
  19. 20
      frontend/src/views/website/ssl/index.vue
  20. 70
      frontend/src/views/website/website/backup/index.vue
  21. 4
      frontend/src/views/website/website/config/basic/index.vue
  22. 60
      frontend/src/views/website/website/config/index.vue
  23. 2
      frontend/src/views/website/website/config/log/index.vue
  24. 2
      frontend/src/views/website/website/config/log/log-fiile/index.vue
  25. 10
      frontend/src/views/website/website/config/resource/index.vue
  26. 2
      frontend/src/views/website/website/config/resource/nginx/index.vue
  27. 2
      frontend/src/views/website/website/config/safety/index.vue
  28. 62
      frontend/src/views/website/website/create/index.vue
  29. 16
      frontend/src/views/website/website/group/index.vue
  30. 271
      frontend/src/views/website/website/index.vue
  31. 53
      frontend/src/views/website/website/nginx/index.vue
  32. 102
      frontend/src/views/website/website/nginx/performance/index.vue
  33. 2
      frontend/src/views/website/website/nginx/source/index.vue
  34. 59
      frontend/src/views/website/website/status/index.vue
  35. 122
      frontend/src/views/website/website/upload/index.vue

2
apps/wordpress/versions/6.0.1/config.json

@ -35,7 +35,7 @@
},
{
"type": "number",
"labelZh": "端口",
"labelZh": "应用端口",
"labelEn": "Port",
"required": true,
"default": 8080,

2
apps/wordpress/versions/6.0.2/config.json

@ -35,7 +35,7 @@
},
{
"type": "number",
"labelZh": "端口",
"labelZh": "应用端口",
"labelEn": "Port",
"required": true,
"default": 8080,

2
cmd/server/nginx_conf/ssl.conf

@ -6,4 +6,4 @@ ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
add_header Strict-Transport-Security "max-age=31536000";
error_page 497 https://$host$request_uri;
error_page 497 https://$host$request_uri;

1
cmd/server/nginx_conf/website_default.conf

@ -8,7 +8,6 @@ server {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

8
frontend/src/components/app-layout/footer/index.scss

@ -1,5 +1,5 @@
.footer {
height: 30px;
height: 45px;
background: #ffffff;
border-top: 1px solid #e4e7ed;
a {
@ -8,4 +8,10 @@
text-decoration: none;
letter-spacing: 0.5px;
}
span {
font-size: 14px;
color: #858585;
text-decoration: none;
letter-spacing: 0.5px;
}
}

18
frontend/src/components/app-layout/footer/index.vue

@ -2,11 +2,25 @@
<div>
<slot></slot>
</div>
<div class="footer flx-center">
<a href="http://www.spicyboy.cn/" target="_blank">2023 © 1Panel By 飞致云.</a>
<div class="footer flx-justify-between">
<div class="footer-left">
<a href="https://fit2cloud.com/" target="_blank">杭州飞致云信息科技有限公司</a>
</div>
<div class="footer-right">
<span>Version V1</span>
</div>
</div>
</template>
<style scoped lang="scss">
@import './index.scss';
.footer-left {
margin-left: 20px;
}
.footer-right {
float: right;
margin-right: 20px;
}
</style>

9
frontend/src/components/app-status/index.vue

@ -32,7 +32,14 @@
<el-divider direction="vertical" />
<el-button type="primary" link @click="onOperate('restart')">{{ $t('app.restart') }}</el-button>
<el-divider direction="vertical" />
<el-button type="primary" link @click="setting">{{ $t('commons.button.set') }}</el-button>
<el-button
type="primary"
link
@click="setting"
:disabled="data.status !== 'Running' && data.app === 'OpenResty'"
>
{{ $t('commons.button.set') }}
</el-button>
</el-col>
</el-row>
</el-card>

11
frontend/src/components/back-button/index.vue

@ -1,10 +1,17 @@
<template>
<el-page-header :content="header" @back="jump" />
<el-page-header :content="header" @back="jump">
<template v-if="slots.buttons" #content>
<span>{{ header }}</span>
<el-divider direction="vertical" />
<slot name="buttons"></slot>
</template>
</el-page-header>
</template>
<script setup lang="ts">
import { inject } from 'vue';
import { inject, useSlots } from 'vue';
import { useRouter } from 'vue-router';
const slots = useSlots();
const router = useRouter();
const props = defineProps({
path: String,

2
frontend/src/components/container-log/index.vue

@ -17,7 +17,7 @@
placeholder="None data"
:indent-with-tab="true"
:tabSize="4"
style="margin-top: 10px; max-height: 500px"
style="margin-top: 10px; max-height: 700px"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"

19
frontend/src/components/drawer-header/index.vue

@ -0,0 +1,19 @@
<template>
<el-page-header :content="header" @back="props.back">
<template v-if="slots.buttons" #content>
<span>{{ header }}</span>
<el-divider direction="vertical" />
<slot name="buttons"></slot>
</template>
</el-page-header>
</template>
<script lang="ts" setup>
import { useSlots } from 'vue';
const slots = useSlots();
const props = defineProps({
header: String,
back: Function,
});
</script>

10
frontend/src/config/nprogress.ts

@ -2,10 +2,10 @@ import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
NProgress.configure({
easing: 'ease', // 动画方式
speed: 500, // 递增进度条的速度
showSpinner: true, // 是否显示加载ico
trickleSpeed: 200, // 自动递增间隔
minimum: 0.3, // 初始化时的最小百分比
easing: 'ease',
speed: 300,
showSpinner: true,
trickleSpeed: 200,
minimum: 0.3,
});
export default NProgress;

5
frontend/src/lang/modules/zh.ts

@ -35,6 +35,7 @@ export default {
verify: '验证',
saveAndEnable: '保存并启用',
import: '导入',
search: '搜索',
},
search: {
timeStart: '开始时间',
@ -1003,6 +1004,10 @@ export default {
defaulServer: '默认站点',
noDefaulServer: '未设置',
defaulServerHelper: '设置默认站点后,所有未绑定的域名和IP都被定向到默认站点\n可有效防止恶意解析',
websiteDeploymentHelper: '使用从 1Panel 部署的应用创建网站',
websiteStatictHelper: '在主机上创建网站目录',
websiteProxyHelper:
'代理已有服务,例如本机已安装使用 8080 端口的 halo 服务那么代理地址为 http://127.0.0.1:8080',
},
nginx: {
serverNamesHashBucketSizeHelper: '服务器名字的hash表大小',

5
frontend/src/layout/index.scss

@ -14,11 +14,10 @@
}
.el-main {
box-sizing: border-box;
padding: 10px 13px;
padding: 20px 33px;
/* 防止切换出现横向滚动条 */
overflow-x: hidden;
// background-color: #f0f2f5;
background-color: #f4f4f4;
// background: #f0f2f5;
.main-box {
box-sizing: border-box;

14
frontend/src/layout/index.vue

@ -12,15 +12,17 @@
</Header>
</el-header>
<el-main>
<Content>
<!-- <Content> -->
<div>
<View></View>
</Content>
</div>
<!-- </Content> -->
</el-main>
<!-- <el-footer v-if="themeConfig.footer">
<el-footer>
<Footer>
<slot name="footer"></slot>
</Footer>
</el-footer> -->
</el-footer>
</el-container>
</el-container>
</template>
@ -29,9 +31,9 @@
// import { computed } from 'vue';
import Menu from './layout-menu.vue';
import Header from './layout-header.vue';
// import Footer from './layout-footer.vue';
import Footer from './layout-footer.vue';
import View from './layout-view.vue';
import Content from './layout-content.vue';
// import Content from './layout-content.vue';
// import { GlobalStore } from '@/store';
// const globalStore = GlobalStore();
// const themeConfig = computed(() => globalStore.themeConfig);

69
frontend/src/layout/layout-content.vue

@ -1,19 +1,10 @@
<template>
<div class="main-box">
<div class="content-container__header" v-if="slots.header || header">
<slot name="header">
<back-button
:path="backPath"
:name="backName"
:to="backTo"
:header="header"
:reload="reload"
v-if="showBack"
></back-button>
<!-- <el-page-header @back="reload" v-if="showBack" :content="header"></el-page-header> -->
<span v-else>{{ header }}</span>
<el-divider />
</slot>
<div class="content-container__header" v-if="slots.header">
<slot name="header"></slot>
</div>
<div class="content-container__app" v-if="slots.app">
<slot name="app"></slot>
</div>
<div class="content-container__toolbar" v-if="slots.toolbar">
<slot name="toolbar"></slot>
@ -25,6 +16,36 @@
</form-button>
</slot>
</div>
<div class="content-container__main" v-if="slots.main">
<el-card>
<div class="content-container__title" v-if="slots.title || title">
<slot name="title">
<back-button
:path="backPath"
:name="backName"
:to="backTo"
:header="title"
:reload="reload"
v-if="showBack"
>
<template v-if="slots.buttons" #buttons>
<slot name="buttons"></slot>
</template>
</back-button>
<span v-else>
{{ title }}
<el-divider v-if="slots.buttons" direction="vertical" />
<slot v-if="slots.buttons" name="buttons"></slot>
</span>
</slot>
</div>
<div v-if="slots.prompt">
<slot name="prompt"></slot>
</div>
<slot name="main"></slot>
</el-card>
</div>
<slot></slot>
</div>
</template>
@ -36,7 +57,7 @@ import FormButton from './form-button.vue';
defineOptions({ name: 'LayoutContent' }); //
const slots = useSlots();
const prop = defineProps({
header: String,
title: String,
backPath: String,
backName: String,
backTo: Object,
@ -53,13 +74,23 @@ const showBack = computed(() => {
@use '@/styles/mixins.scss' as *;
.content-container__header {
}
.content-container__app {
}
.content-container__search {
margin-top: 20px;
}
.content-container__title {
font-weight: 700;
font-size: 18px;
}
.content-container__toolbar {
@include flex-row(space-between, center);
margin-bottom: 10px;
// @include flex-row(space-between, center);
margin-top: 30px;
}
.content-container_form {
@ -71,6 +102,10 @@ const showBack = computed(() => {
}
}
.content-container__main {
margin-top: 20px;
}
.el-divider--horizontal {
display: block;
height: 1px;

8
frontend/src/layout/layout-view.vue

@ -1,5 +1,5 @@
<template>
<router-view v-slot="{ Component, route }">
<router-view v-slot="{ Component, route }" :key="key">
<transition appear name="fade-transform" mode="out-in">
<keep-alive :include="cacheRouter">
<component :is="Component" :key="route.path"></component>
@ -10,4 +10,10 @@
<script setup lang="ts">
import cacheRouter from '@/routers/cache-router';
import { useRoute } from 'vue-router';
import { computed } from 'vue';
const key = computed(() => {
return useRoute().path + Math.random();
});
</script>

14
frontend/src/styles/common.scss

@ -1,4 +1,3 @@
/* 常用 flex */
.flx-center {
display: flex;
align-items: center;
@ -14,7 +13,6 @@
align-items: center;
}
/* 清除浮动 */
.clearfix::after {
display: block;
height: 0;
@ -23,14 +21,12 @@
content: '';
}
/* 文字单行省略号 */
.sle {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* 文字多行省略号 */
.mle {
display: -webkit-box;
overflow: hidden;
@ -38,13 +34,11 @@
-webkit-line-clamp: 2;
}
/* 文字多了自動換行 */
.break-word {
word-break: break-all;
word-wrap: break-word;
}
/* fade-transform */
.fade-transform-leave-active,
.fade-transform-enter-active {
transition: all 0.2s;
@ -75,7 +69,6 @@
z-index: -1;
}
/* scroll bar */
::-webkit-scrollbar {
width: 8px;
height: 8px;
@ -99,7 +92,6 @@
}
}
/* nprogress样式 */
#nprogress .bar {
background: $primary-color !important;
}
@ -192,6 +184,10 @@
margin-right: 5px;
}
.button-left {
float: left;
}
.topRouterCard {
.el-card__body {
--el-card-border-color: var(--el-border-color-light);
@ -224,4 +220,4 @@
font-size: var(--el-font-size-base);
border-radius: 0;
}
}
}

2
frontend/src/styles/var.scss

@ -1,2 +1,2 @@
/* 全局 css 变量 */
$primary-color: var(--el-color-primary);
$primary-color: #005eeb;

20
frontend/src/views/website/ssl/index.vue

@ -1,11 +1,13 @@
<template>
<el-card>
<LayoutContent :header="$t('website.ssl')">
<LayoutContent :title="$t('website.ssl')">
<template #prompt>
<el-alert type="info" :closable="false">
<template #default>
<span><span v-html="$t('website.encryptHelper')"></span></span>
</template>
</el-alert>
</template>
<template #main>
<br />
<ComplexTable :data="data" :pagination-config="paginationConfig" @search="search()">
<template #toolbar>
@ -55,13 +57,13 @@
fix
/>
</ComplexTable>
<DnsAccount ref="dnsAccountRef"></DnsAccount>
<AcmeAccount ref="acmeAccountRef"></AcmeAccount>
<Create ref="sslCreateRef" @close="search()"></Create>
<Renew ref="renewRef" @close="search()"></Renew>
<Detail ref="detailRef"></Detail>
</LayoutContent>
</el-card>
</template>
<DnsAccount ref="dnsAccountRef"></DnsAccount>
<AcmeAccount ref="acmeAccountRef"></AcmeAccount>
<Create ref="sslCreateRef" @close="search()"></Create>
<Renew ref="renewRef" @close="search()"></Renew>
<Detail ref="detailRef"></Detail>
</LayoutContent>
</template>
<script lang="ts" setup>

70
frontend/src/views/website/website/backup/index.vue

@ -1,40 +1,35 @@
<template>
<div>
<el-dialog v-model="backupVisiable" :destroy-on-close="true" :close-on-click-modal="false" width="50%">
<template #header>
<div class="card-header">
<span>{{ $t('database.backup') }} - {{ websiteName }}</span>
</div>
<el-drawer v-model="backupVisiable" size="50%" :show-close="false">
<template #header>
<Header :header="$t('database.backup') + ' - ' + websiteName" :back="handleClose"></Header>
</template>
<ComplexTable
v-loading="loading"
:pagination-config="paginationConfig"
v-model:selects="selects"
@search="search"
:data="data"
>
<template #toolbar>
<el-button type="primary" @click="onBackup()">
{{ $t('database.backup') }}
</el-button>
<el-button type="danger" plain :disabled="selects.length === 0" @click="onBatchDelete(null)">
{{ $t('commons.button.delete') }}
</el-button>
</template>
<ComplexTable
v-loading="loading"
:pagination-config="paginationConfig"
v-model:selects="selects"
@search="search"
:data="data"
>
<template #toolbar>
<el-button type="primary" @click="onBackup()">
{{ $t('database.backup') }}
</el-button>
<el-button type="danger" plain :disabled="selects.length === 0" @click="onBatchDelete(null)">
{{ $t('commons.button.delete') }}
</el-button>
</template>
<el-table-column type="selection" fix />
<el-table-column :label="$t('commons.table.name')" prop="fileName" show-overflow-tooltip />
<el-table-column :label="$t('database.source')" prop="backupType" />
<el-table-column
prop="createdAt"
:label="$t('commons.table.date')"
:formatter="dateFromat"
show-overflow-tooltip
/>
<fu-table-operations :buttons="buttons" :label="$t('commons.table.operate')" fix />
</ComplexTable>
</el-dialog>
</div>
<el-table-column type="selection" fix />
<el-table-column :label="$t('commons.table.name')" prop="fileName" show-overflow-tooltip />
<el-table-column :label="$t('database.source')" prop="backupType" />
<el-table-column
prop="createdAt"
:label="$t('commons.table.date')"
:formatter="dateFromat"
show-overflow-tooltip
/>
<fu-table-operations :buttons="buttons" :label="$t('commons.table.operate')" fix />
</ComplexTable>
</el-drawer>
</template>
<script lang="ts" setup>
@ -47,6 +42,7 @@ import { ElMessage } from 'element-plus';
import { deleteBackupRecord, downloadBackupRecord, searchBackupRecords } from '@/api/modules/backup';
import { Backup } from '@/api/interface/backup';
import { BackupWebsite, RecoverWebsite } from '@/api/modules/website';
import Header from '@/components/drawer-header/index.vue';
const selects = ref<any>([]);
const loading = ref(false);
@ -76,6 +72,10 @@ const acceptParams = (params: DialogProps): void => {
search();
};
const handleClose = () => {
backupVisiable.value = false;
};
const search = async () => {
let params = {
page: paginationConfig.currentPage,

4
frontend/src/views/website/website/config/basic/index.vue

@ -1,5 +1,6 @@
<template>
<el-tabs tab-position="left" type="border-card" v-model="tabIndex">
<!-- <div style="border: 1px solid #6495ed"> -->
<el-tabs tab-position="left" v-model="tabIndex">
<el-tab-pane :label="$t('website.domainConfig')">
<Doamin :id="id" v-if="tabIndex == '0'"></Doamin>
</el-tab-pane>
@ -19,6 +20,7 @@
<Other :id="id" v-if="tabIndex == '5'"></Other>
</el-tab-pane>
</el-tabs>
<!-- </div> -->
</template>
<script lang="ts" setup name="Basic">

60
frontend/src/views/website/website/config/index.vue

@ -1,22 +1,34 @@
<template>
<el-card>
<LayoutContent :header="$t('website.websiteConfig')" :back-name="'Website'">
<el-tabs v-model="index">
<el-tab-pane :label="$t('website.basic')" name="basic">
<Basic :id="id" v-if="index === 'basic'"></Basic>
</el-tab-pane>
<el-tab-pane :label="$t('website.security')" name="safety">
<Safety :id="id" v-if="index === 'safety'"></Safety>
</el-tab-pane>
<el-tab-pane :label="$t('website.log')" name="log">
<Log :id="id" v-if="index === 'log'"></Log>
</el-tab-pane>
<el-tab-pane :label="$t('website.source')" name="resource">
<Resource :id="id" v-if="index === 'resource'"></Resource>
</el-tab-pane>
</el-tabs>
</LayoutContent>
</el-card>
<LayoutContent :title="$t('website.websiteConfig')" :back-name="'Website'" v-loading="loading">
<template #app>
<WebsiteStatus
v-if="website.id > 0"
:primary-domain="website.primaryDomain"
:status="website.status"
:expire-date="website.expireDate"
/>
</template>
<template #buttons>
<el-button type="primary" :plain="index !== 'basic'" @click="changeTab('basic')">
{{ $t('website.basic') }}
</el-button>
<el-button type="primary" :plain="index !== 'safety'" @click="changeTab('safety')">
{{ $t('website.security') }}
</el-button>
<el-button type="primary" :plain="index !== 'log'" @click="changeTab('log')">
{{ $t('website.log') }}
</el-button>
<el-button type="primary" :plain="index !== 'resource'" @click="changeTab('resource')">
{{ $t('website.source') }}
</el-button>
</template>
<template #main>
<Basic :id="id" v-if="index === 'basic'"></Basic>
<Safety :id="id" v-if="index === 'safety'"></Safety>
<Log :id="id" v-if="index === 'log'"></Log>
<Resource :id="id" v-if="index === 'resource'"></Resource>
</template>
</LayoutContent>
</template>
<script setup lang="ts">
@ -27,6 +39,8 @@ import Safety from './safety/index.vue';
import Resource from './resource/index.vue';
import Log from './log/index.vue';
import router from '@/routers';
import WebsiteStatus from '@/views/website/website/status/index.vue';
import { GetWebsite } from '@/api/modules/website';
const props = defineProps({
id: {
@ -41,6 +55,8 @@ const props = defineProps({
let id = ref(0);
let index = ref('basic');
let website = ref<any>({});
let loading = ref(false);
watch(index, (curr, old) => {
if (curr != old) {
@ -55,5 +71,13 @@ const changeTab = (index: string) => {
onMounted(() => {
index.value = props.tab;
id.value = Number(props.id);
loading.value = true;
GetWebsite(id.value)
.then((res) => {
website.value = res.data;
})
.finally(() => {
loading.value = false;
});
});
</script>

2
frontend/src/views/website/website/config/log/index.vue

@ -1,5 +1,5 @@
<template>
<el-tabs tab-position="left" type="border-card" v-model="index">
<el-tabs tab-position="left" v-model="index">
<el-tab-pane :label="$t('website.accessLog')" name="0">
<LogFile :id="id" :log-type="'access.log'" v-if="index == '0'"></LogFile>
</el-tab-pane>

2
frontend/src/views/website/website/config/log/log-fiile/index.vue

@ -20,7 +20,7 @@
</div>
<br />
<codemirror
style="max-height: 500px; width: 100%; min-height: 200px"
style="max-height: 800px; width: 100%"
:autofocus="true"
:placeholder="$t('website.noLog')"
:indent-with-tab="true"

10
frontend/src/views/website/website/config/resource/index.vue

@ -1,13 +1,9 @@
<template>
<el-tabs tab-position="left" type="border-card" v-model="index">
<el-tab-pane :label="'Nginx'">
<Nginx :id="id"></Nginx>
</el-tab-pane>
</el-tabs>
<Nginx :id="id"></Nginx>
</template>
<script lang="ts" setup>
import { computed, ref } from 'vue';
import { computed } from 'vue';
import Nginx from './nginx/index.vue';
const props = defineProps({
@ -20,6 +16,4 @@ const props = defineProps({
const id = computed(() => {
return props.id;
});
let index = ref('0');
</script>

2
frontend/src/views/website/website/config/resource/nginx/index.vue

@ -5,7 +5,7 @@
placeholder="None data"
:indent-with-tab="true"
:tabSize="4"
style="margin-top: 10px; max-height: 500px"
style="margin-top: 10px; max-height: 700px"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"

2
frontend/src/views/website/website/config/safety/index.vue

@ -1,5 +1,5 @@
<template>
<el-tabs tab-position="left" type="border-card" v-model="index">
<el-tabs tab-position="left" v-model="index">
<el-tab-pane :label="$t('firewall.ccDeny')" name="cc">
<CCDeny :id="id" v-if="index == 'cc'"></CCDeny>
</el-tab-pane>

62
frontend/src/views/website/website/create/index.vue

@ -1,28 +1,53 @@
<template>
<el-dialog
v-model="open"
:close-on-click-modal="false"
:title="$t('website.create')"
width="40%"
:before-close="handleClose"
>
<el-drawer v-model="open" :size="'50%'" :show-close="false">
<template #header>
<Header :header="$t('website.create')" :back="handleClose">
<template #buttons>
<el-button
type="primary"
:plain="website.type !== 'deployment'"
@click="website.type = 'deployment'"
>
{{ $t('website.deployment') }}
</el-button>
<el-button type="primary" :plain="website.type !== 'static'" @click="website.type = 'static'">
{{ $t('website.static') }}
</el-button>
<el-button type="primary" :plain="website.type !== 'proxy'" @click="website.type = 'proxy'">
{{ $t('website.proxy') }}
</el-button>
</template>
</Header>
</template>
<el-row>
<el-col :span="22" :offset="1">
<el-alert
v-if="website.type == 'deployment'"
:title="$t('website.websiteDeploymentHelper')"
type="info"
:closable="false"
/>
<el-alert
v-if="website.type == 'static'"
:title="$t('website.websiteStatictHelper')"
type="info"
:closable="false"
/>
<el-alert
v-if="website.type == 'proxy'"
:title="$t('website.websiteProxyHelper')"
type="info"
:closable="false"
/>
<br />
<el-form
ref="websiteForm"
label-position="right"
label-position="top"
:model="website"
label-width="125px"
:rules="rules"
:validate-on-rule-change="false"
>
<el-form-item :label="$t('website.type')" prop="type">
<el-select v-model="website.type">
<el-option :label="$t('website.deployment')" value="deployment"></el-option>
<el-option :label="$t('website.static')" value="static"></el-option>
<el-option :label="$t('website.proxy')" value="proxy"></el-option>
</el-select>
</el-form-item>
<el-form-item :label="$t('website.group')" prop="webSiteGroupId">
<el-select v-model="website.webSiteGroupId">
<el-option
@ -131,7 +156,7 @@
</el-col>
</el-row>
<template #footer>
<span class="dialog-footer">
<span>
<el-button @click="handleClose" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button>
<el-button type="primary" @click="submit(websiteForm)" :loading="loading">
{{ $t('commons.button.confirm') }}
@ -139,7 +164,7 @@
</span>
</template>
<Check ref="preCheckRef"></Check>
</el-dialog>
</el-drawer>
</template>
<script lang="ts" setup name="CreateWebSite">
@ -149,10 +174,11 @@ import { GetApp, GetAppDetail, SearchApp, GetAppInstalled } from '@/api/modules/
import { CreateWebsite, ListGroups, PreCheck } from '@/api/modules/website';
import { Rules } from '@/global/form-rules';
import i18n from '@/lang';
import { ElDialog, ElForm, FormInstance, ElMessage } from 'element-plus';
import { ElForm, FormInstance, ElMessage } from 'element-plus';
import { reactive, ref } from 'vue';
import Params from '@/views/app-store/detail/params/index.vue';
import Check from '../check/index.vue';
import Header from '@/components/drawer-header/index.vue';
const websiteForm = ref<FormInstance>();
const website = ref({

16
frontend/src/views/website/website/group/index.vue

@ -1,12 +1,9 @@
<template>
<el-dialog
v-model="open"
:destroy-on-close="true"
:close-on-click-modal="false"
:title="$t('website.groupSetting')"
width="40%"
:before-close="handleClose"
>
<el-drawer v-model="open" size="50%" :show-close="false" :before-close="handleClose">
<template #header>
<Header :header="$t('website.groupSetting')" :back="handleClose"></Header>
</template>
<ComplexTable :data="data" @search="search()">
<template #toolbar>
<el-button type="primary" icon="Plus" @click="openCreate">{{ $t('commons.button.create') }}</el-button>
@ -48,7 +45,7 @@
</template>
</el-table-column>
</ComplexTable>
</el-dialog>
</el-drawer>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
@ -56,6 +53,7 @@ import i18n from '@/lang';
import ComplexTable from '@/components/complex-table/index.vue';
import { ListGroups, CreateGroup, DeleteGroup, UpdateGroup } from '@/api/modules/website';
import { ElMessage } from 'element-plus';
import Header from '@/components/drawer-header/index.vue';
interface groupData {
id: number;

271
frontend/src/views/website/website/index.vue

@ -1,140 +1,138 @@
<template>
<div v-loading="loading">
<AppStatus :app-key="'nginx'" @setting="setting" v-model:loading="loading" @is-exist="checkExist"></AppStatus>
<div v-if="nginxIsExist" :class="{ mask: nginxStatus != 'Running' }">
<LayoutContent>
<br />
<el-card v-if="!openNginxConfig">
<LayoutContent :header="$t('website.website')">
<ComplexTable :pagination-config="paginationConfig" :data="data" @search="search()">
<template #toolbar>
<el-row>
<el-col :span="10">
<el-button type="primary" icon="Plus" @click="openCreate">
{{ $t('commons.button.create') }}
</el-button>
<el-button type="primary" plain @click="openGroup">
{{ $t('website.group') }}
</el-button>
<el-button type="primary" plain @click="openDefault">
{{ $t('website.defaulServer') }}
</el-button>
</el-col>
<el-col :span="14">
<div style="float: right">
<div class="table-button">
<el-select v-model="req.websiteGroupId" @change="search()">
<el-option :label="$t('website.allGroup')" :value="0"></el-option>
<el-option
v-for="(group, index) in groups"
:key="index"
:label="group.name"
:value="group.id"
></el-option>
</el-select>
</div>
<el-input
class="table-button"
v-model="req.name"
clearable
@clear="search()"
></el-input>
<el-button type="primary" icon="Search" @click="search()">
{{ $t('app.search') }}
</el-button>
</div>
</el-col>
</el-row>
</template>
<el-table-column
:label="$t('commons.table.name')"
fix
show-overflow-tooltip
prop="primaryDomain"
>
<template #default="{ row }">
<el-link type="primary" @click="openConfig(row.id)">
{{ row.primaryDomain }}
</el-link>
</template>
</el-table-column>
<el-table-column :label="$t('commons.table.type')" fix prop="type">
<template #default="{ row }">
{{ $t('website.' + row.type) }}
</template>
</el-table-column>
<el-table-column :label="$t('commons.table.status')" prop="status">
<template #default="{ row }">
<el-button
v-if="row.status === 'Running'"
link
type="success"
@click="opWebsite('stop', row.id)"
>
{{ $t('commons.status.running') }}
</el-button>
<el-button v-else link type="danger" @click="opWebsite('start', row.id)">
{{ $t('commons.status.stopped') }}
</el-button>
</template>
</el-table-column>
<el-table-column :label="$t('website.remark')" prop="remark"></el-table-column>
<el-table-column :label="$t('website.protocol')" prop="protocol"></el-table-column>
<el-table-column :label="$t('website.expireDate')">
<template #default="{ row, $index }">
<div v-show="row.showdate">
<el-date-picker
v-model="row.expireDate"
type="date"
:disabled-date="checkDate"
:shortcuts="shortcuts"
:clearable="false"
:default-value="setDate(row.expireDate)"
:ref="(el) => setdateRefs(el, $index)"
@change="submitDate(row)"
@visible-change="(visibility:boolean) => pickerVisibility(visibility, row)"
size="small"
></el-date-picker>
</div>
<div v-show="!row.showdate">
<span v-if="isEver(row.expireDate)" @click="openDatePicker(row, $index)">
{{ $t('website.neverExpire') }}
</span>
<span v-else @click="openDatePicker(row, $index)">
{{ dateFromatSimple(row.expireDate) }}
</span>
</div>
</template>
</el-table-column>
<fu-table-operations
:ellipsis="10"
width="260px"
:buttons="buttons"
:label="$t('commons.table.operate')"
fixed="right"
fix
/>
</ComplexTable>
</LayoutContent>
</el-card>
<CreateWebSite ref="createRef" @close="search"></CreateWebSite>
<DeleteWebsite ref="deleteRef" @close="search"></DeleteWebsite>
<WebSiteGroup ref="groupRef"></WebSiteGroup>
<UploadDialog ref="uploadRef" />
<BackupRecords ref="dialogBackupRef" />
<DefaultServer ref="defaultRef" />
</LayoutContent>
</div>
<div v-if="nginxIsExist">
<el-card width="30%" v-if="nginxStatus != 'Running' && !loading" class="mask-prompt">
<LayoutContent :title="$t('website.website')" v-loading="loading">
<template #app>
<AppStatus
:app-key="'nginx'"
@setting="setting"
v-model:loading="loading"
@is-exist="checkExist"
></AppStatus>
</template>
<template v-if="!openNginxConfig" #toolbar>
<el-row :class="{ mask: nginxStatus != 'Running' }">
<el-col :span="10">
<el-button type="primary" icon="Plus" @click="openCreate">
{{ $t('commons.button.create') }}
</el-button>
<el-button type="primary" plain @click="openGroup">
{{ $t('website.group') }}
</el-button>
<el-button type="primary" plain @click="openDefault">
{{ $t('website.defaulServer') }}
</el-button>
</el-col>
<el-col :span="14">
<div style="float: right">
<el-input
class="table-button"
v-model="req.name"
clearable
@clear="search()"
suffix-icon="Search"
@keyup.enter="search()"
@blur="search()"
:placeholder="$t('commons.button.search')"
></el-input>
</div>
</el-col>
</el-row>
</template>
<template v-if="!openNginxConfig" #search>
<div :class="{ mask: nginxStatus != 'Running' }">
<el-select v-model="req.websiteGroupId" @change="search()">
<el-option :label="$t('website.allGroup')" :value="0"></el-option>
<el-option
v-for="(group, index) in groups"
:key="index"
:label="group.name"
:value="group.id"
></el-option>
</el-select>
</div>
</template>
<template v-if="nginxIsExist && !openNginxConfig" #main>
<ComplexTable
:pagination-config="paginationConfig"
:data="data"
@search="search()"
:class="{ mask: nginxStatus != 'Running' }"
>
<el-table-column :label="$t('commons.table.name')" fix show-overflow-tooltip prop="primaryDomain">
<template #default="{ row }">
<el-link type="primary" @click="openConfig(row.id)">
{{ row.primaryDomain }}
</el-link>
</template>
</el-table-column>
<el-table-column :label="$t('commons.table.type')" fix prop="type">
<template #default="{ row }">
{{ $t('website.' + row.type) }}
</template>
</el-table-column>
<el-table-column :label="$t('commons.table.status')" prop="status">
<template #default="{ row }">
<el-button
v-if="row.status === 'Running'"
link
type="success"
@click="opWebsite('stop', row.id)"
>
{{ $t('commons.status.running') }}
</el-button>
<el-button v-else link type="danger" @click="opWebsite('start', row.id)">
{{ $t('commons.status.stopped') }}
</el-button>
</template>
</el-table-column>
<el-table-column :label="$t('website.remark')" prop="remark"></el-table-column>
<el-table-column :label="$t('website.protocol')" prop="protocol"></el-table-column>
<el-table-column :label="$t('website.expireDate')">
<template #default="{ row, $index }">
<div v-show="row.showdate">
<el-date-picker
v-model="row.expireDate"
type="date"
:disabled-date="checkDate"
:shortcuts="shortcuts"
:clearable="false"
:default-value="setDate(row.expireDate)"
:ref="(el) => setdateRefs(el, $index)"
@change="submitDate(row)"
@visible-change="(visibility:boolean) => pickerVisibility(visibility, row)"
size="small"
></el-date-picker>
</div>
<div v-show="!row.showdate">
<span v-if="isEver(row.expireDate)" @click="openDatePicker(row, $index)">
{{ $t('website.neverExpire') }}
</span>
<span v-else @click="openDatePicker(row, $index)">
{{ dateFromatSimple(row.expireDate) }}
</span>
</div>
</template>
</el-table-column>
<fu-table-operations
:ellipsis="10"
width="260px"
:buttons="buttons"
:label="$t('commons.table.operate')"
fixed="right"
fix
/>
</ComplexTable>
<el-card width="30%" v-if="nginxStatus != 'Running'" class="mask-prompt">
<span style="font-size: 14px">{{ $t('commons.service.serviceNotStarted', ['OpenResty']) }}</span>
</el-card>
</div>
<el-card v-if="openNginxConfig">
<NginxConfig :containerName="containerName" :status="nginxStatus"></NginxConfig>
</el-card>
</div>
</template>
</LayoutContent>
<NginxConfig v-if="openNginxConfig" v-loading="loading" :containerName="containerName" :status="nginxStatus" />
<CreateWebSite ref="createRef" @close="search" />
<DeleteWebsite ref="deleteRef" @close="search" />
<WebSiteGroup ref="groupRef" />
<UploadDialog ref="uploadRef" />
<BackupRecords ref="dialogBackupRef" />
<DefaultServer ref="defaultRef" />
</template>
<script lang="ts" setup>
@ -236,7 +234,7 @@ const isBeforeNow = (time: string) => {
const setDate = (time: string) => {
if (isEver(time)) {
return new Date().toLocaleDateString();
return new Date();
} else {
return new Date(time);
}
@ -348,7 +346,7 @@ const checkExist = (data: App.CheckInstalled) => {
const checkDate = (date: Date) => {
const now = new Date();
return date < now;
return date.getTime() < now.getTime();
};
const opWebsite = (op: string, id: number) => {
@ -369,6 +367,7 @@ onMounted(() => {
</script>
<style lang="scss">
.table-button {
border-radius: 20px;
display: inline;
margin-right: 5px;
}

53
frontend/src/views/website/website/nginx/index.vue

@ -1,26 +1,32 @@
<template>
<LayoutContent :header="$t('nginx.nginxConfig')" :reload="true">
<el-collapse v-model="activeName" accordion>
<el-collapse-item :title="$t('nginx.configResource')" name="1">
<Source v-if="activeName === '1'"></Source>
</el-collapse-item>
<el-collapse-item :title="$t('nginx.status')" name="2">
<Status v-if="activeName === '2'" :status="status" />
</el-collapse-item>
<el-collapse-item :title="$t('website.nginxPer')" name="3">
<NginxPer v-if="activeName === '3'" />
</el-collapse-item>
<el-collapse-item :title="$t('website.log')" name="4">
<ContainerLog ref="dialogContainerLogRef" />
</el-collapse-item>
</el-collapse>
<LayoutContent :title="$t('nginx.nginxConfig')" :reload="true">
<template #buttons>
<el-button type="primary" :plain="activeName !== '1'" @click="changeTab('1')">
{{ $t('nginx.configResource') }}
</el-button>
<el-button type="primary" :plain="activeName !== '2'" @click="changeTab('2')">
{{ $t('nginx.status') }}
</el-button>
<el-button type="primary" :plain="activeName !== '3'" @click="changeTab('3')">
{{ $t('website.nginxPer') }}
</el-button>
<el-button type="primary" :plain="activeName !== '4'" @click="changeTab('4')">
{{ $t('website.log') }}
</el-button>
</template>
<template #main>
<Source v-if="activeName === '1'"></Source>
<Status v-if="activeName === '2'" :status="status" />
<NginxPer v-if="activeName === '3'" />
<ContainerLog v-if="activeName === '4'" ref="dialogContainerLogRef" />
</template>
</LayoutContent>
</template>
<script lang="ts" setup>
import LayoutContent from '@/layout/layout-content.vue';
import Source from './source/index.vue';
import { ref, watch } from 'vue';
import { nextTick, ref } from 'vue';
import ContainerLog from '@/components/container-log/index.vue';
import NginxPer from './performance/index.vue';
import Status from './status/index.vue';
@ -38,17 +44,16 @@ const props = defineProps({
default: 'Running',
},
});
const changeTab = (index: string) => {
activeName.value = index;
watch(
activeName,
(newvalue) => {
if (newvalue === '4') {
if (index === '4') {
nextTick(() => {
dialogContainerLogRef.value!.acceptParams({
containerID: props.containerName,
container: props.containerName,
});
}
},
{ immediate: true },
);
});
}
};
</script>

102
frontend/src/views/website/website/nginx/performance/index.vue

@ -1,57 +1,55 @@
<template>
<div>
<el-card>
<el-form :model="form" :rules="variablesRules" ref="nginxFormRef" label-width="160px">
<el-row>
<el-col :span="1"><br /></el-col>
<el-col :span="9">
<el-form-item label="server_names_hash_bucket_size" prop="server_names_hash_bucket_size">
<el-input clearable v-model.number="form.server_names_hash_bucket_size"></el-input>
<span class="input-help">{{ $t('nginx.serverNamesHashBucketSizeHelper') }}</span>
</el-form-item>
<el-form-item label="client_header_buffer_size" prop="client_header_buffer_size">
<el-input clearable v-model.number="form.client_header_buffer_size">
<template #append>K</template>
</el-input>
<span class="input-help">{{ $t('nginx.clientHeaderBufferSizeHelper') }}</span>
</el-form-item>
<el-form-item label="client_max_body_size" prop="client_max_body_size">
<el-input clearable v-model.number="form.client_max_body_size">
<template #append>MB</template>
</el-input>
<span class="input-help">{{ $t('nginx.clientMaxBodySizeHelper') }}</span>
</el-form-item>
<el-form-item label="keepalive_timeout" prop="keepalive_timeout">
<el-input clearable v-model.number="form.keepalive_timeout"></el-input>
<span class="input-help">{{ $t('nginx.keepaliveTimeoutHelper') }}</span>
</el-form-item>
</el-col>
<el-col :span="1"><br /></el-col>
<el-col :span="9">
<el-form-item label="gzip" prop="gzip">
<el-select v-model="form.gzip">
<el-option :label="'on'" :value="'on'"></el-option>
<el-option :label="'off'" :value="'off'"></el-option>
</el-select>
<span class="input-help">{{ $t('nginx.gzipHelper') }}</span>
</el-form-item>
<el-form-item label="gzip_min_length" prop="gzip_min_length">
<el-input clearable v-model.number="form.gzip_min_length">
<template #append>KB</template>
</el-input>
<span class="input-help">{{ $t('nginx.gzipMinLengthHelper') }}</span>
</el-form-item>
<el-form-item label="gzip_comp_level" prop="gzip_comp_level">
<el-input clearable v-model.number="form.gzip_comp_level"></el-input>
<span class="input-help">{{ $t('nginx.gzipCompLevelHelper') }}</span>
</el-form-item>
</el-col>
</el-row>
</el-form>
<el-button type="primary" @click="submit(nginxFormRef)" :loading="loading">
{{ $t('commons.button.save') }}
</el-button>
</el-card>
<el-form :model="form" :rules="variablesRules" ref="nginxFormRef" label-width="160px">
<el-row>
<el-col :span="1"><br /></el-col>
<el-col :span="9">
<el-form-item label="server_names_hash_bucket_size" prop="server_names_hash_bucket_size">
<el-input clearable v-model.number="form.server_names_hash_bucket_size"></el-input>
<span class="input-help">{{ $t('nginx.serverNamesHashBucketSizeHelper') }}</span>
</el-form-item>
<el-form-item label="client_header_buffer_size" prop="client_header_buffer_size">
<el-input clearable v-model.number="form.client_header_buffer_size">
<template #append>K</template>
</el-input>
<span class="input-help">{{ $t('nginx.clientHeaderBufferSizeHelper') }}</span>
</el-form-item>
<el-form-item label="client_max_body_size" prop="client_max_body_size">
<el-input clearable v-model.number="form.client_max_body_size">
<template #append>MB</template>
</el-input>
<span class="input-help">{{ $t('nginx.clientMaxBodySizeHelper') }}</span>
</el-form-item>
<el-form-item label="keepalive_timeout" prop="keepalive_timeout">
<el-input clearable v-model.number="form.keepalive_timeout"></el-input>
<span class="input-help">{{ $t('nginx.keepaliveTimeoutHelper') }}</span>
</el-form-item>
</el-col>
<el-col :span="1"><br /></el-col>
<el-col :span="9">
<el-form-item label="gzip" prop="gzip">
<el-select v-model="form.gzip">
<el-option :label="'on'" :value="'on'"></el-option>
<el-option :label="'off'" :value="'off'"></el-option>
</el-select>
<span class="input-help">{{ $t('nginx.gzipHelper') }}</span>
</el-form-item>
<el-form-item label="gzip_min_length" prop="gzip_min_length">
<el-input clearable v-model.number="form.gzip_min_length">
<template #append>KB</template>
</el-input>
<span class="input-help">{{ $t('nginx.gzipMinLengthHelper') }}</span>
</el-form-item>
<el-form-item label="gzip_comp_level" prop="gzip_comp_level">
<el-input clearable v-model.number="form.gzip_comp_level"></el-input>
<span class="input-help">{{ $t('nginx.gzipCompLevelHelper') }}</span>
</el-form-item>
</el-col>
</el-row>
</el-form>
<el-button type="primary" @click="submit(nginxFormRef)" :loading="loading">
{{ $t('commons.button.save') }}
</el-button>
</div>
</template>
<script lang="ts" setup>

2
frontend/src/views/website/website/nginx/source/index.vue

@ -5,7 +5,7 @@
placeholder="None data"
:indent-with-tab="true"
:tabSize="4"
style="margin-top: 10px; max-height: 500px"
style="max-height: 700px"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"

59
frontend/src/views/website/website/status/index.vue

@ -0,0 +1,59 @@
<template>
<el-card>
<el-row :gutter="20">
<el-col :lg="3" :xl="2">
<div>
<el-tag effect="dark" type="success">{{ props.primaryDomain }}</el-tag>
</div>
</el-col>
<el-col :lg="4" :xl="2">
<div class="span-font">
{{ $t('commons.table.status') }}:
<el-tag type="info">
<Status class="span-font" :key="props.status" :status="props.status"></Status>
</el-tag>
</div>
</el-col>
<el-col :lg="4" :xl="4">
<div class="span-font">
{{ $t('website.expireDate') }}:
<el-tag type="info">
<span v-if="isEver(props.expireDate)">
{{ $t('website.neverExpire') }}
</span>
<span v-else>{{ dateFromatSimple(props.expireDate) }}</span>
</el-tag>
</div>
</el-col>
</el-row>
</el-card>
</template>
<script lang="ts" setup>
import Status from '@/components/status/index.vue';
import { dateFromatSimple } from '@/utils/util';
const props = defineProps({
primaryDomain: {
type: String,
default: '',
},
status: {
type: String,
default: '',
},
expireDate: {
type: String,
default: '',
},
});
const isEver = (time: string) => {
const expireDate = new Date(time);
return expireDate < new Date('1970-01-02');
};
</script>
<style lang="scss">
.span-font {
font-size: 14px;
}
</style>

122
frontend/src/views/website/website/upload/index.vue

@ -1,68 +1,64 @@
<template>
<div :v-loading="loading">
<el-dialog v-model="upVisiable" :destroy-on-close="true" :close-on-click-modal="false" width="70%">
<template #header>
<div class="card-header">
<span>{{ $t('commons.button.import') }}</span>
</div>
</template>
<div v-loading="loading">
<el-upload
ref="uploadRef"
:on-change="fileOnChange"
:before-upload="beforeAvatarUpload"
class="upload-demo"
:auto-upload="false"
>
<template #trigger>
<el-button type="primary" plain>{{ $t('database.selectFile') }}</el-button>
</template>
<el-button style="margin-left: 10px" icon="Upload" @click="onSubmit">
{{ $t('commons.button.upload') }}
<el-drawer v-model="upVisiable" size="50%" :show-close="false">
<template #header>
<Header :header="$t('commons.button.import') + ' - ' + websiteName" :back="handleClose"></Header>
</template>
<div v-loading="loading">
<el-upload
ref="uploadRef"
:on-change="fileOnChange"
:before-upload="beforeAvatarUpload"
class="upload-demo"
:auto-upload="false"
>
<template #trigger>
<el-button type="primary" plain>{{ $t('database.selectFile') }}</el-button>
</template>
<el-button style="margin-left: 10px" icon="Upload" @click="onSubmit">
{{ $t('commons.button.upload') }}
</el-button>
</el-upload>
<div style="margin-left: 10px">
<span class="input-help">{{ $t('website.supportUpType') }}</span>
<span class="input-help">
{{ $t('website.zipFormat') }}
</span>
</div>
<el-divider />
<ComplexTable :pagination-config="paginationConfig" v-model:selects="selects" :data="data">
<template #toolbar>
<el-button
style="margin-left: 10px"
type="danger"
plain
:disabled="selects.length === 0"
@click="onBatchDelete(null)"
>
{{ $t('commons.button.delete') }}
</el-button>
</el-upload>
<div style="margin-left: 10px">
<span class="input-help">{{ $t('website.supportUpType') }}</span>
<span class="input-help">
{{ $t('website.zipFormat') }}
</span>
</div>
<el-divider />
<ComplexTable :pagination-config="paginationConfig" v-model:selects="selects" :data="data">
<template #toolbar>
<el-button
style="margin-left: 10px"
type="danger"
plain
:disabled="selects.length === 0"
@click="onBatchDelete(null)"
>
{{ $t('commons.button.delete') }}
</el-button>
</template>
<el-table-column type="selection" fix />
<el-table-column :label="$t('commons.table.name')" show-overflow-tooltip prop="name" />
<el-table-column :label="$t('file.size')" prop="size">
<template #default="{ row }">
{{ computeSize(row.size) }}
</template>
<el-table-column type="selection" fix />
<el-table-column :label="$t('commons.table.name')" show-overflow-tooltip prop="name" />
<el-table-column :label="$t('file.size')" prop="size">
<template #default="{ row }">
{{ computeSize(row.size) }}
</template>
</el-table-column>
<el-table-column :label="$t('commons.table.createdAt')" min-width="80" fix>
<template #default="{ row }">
{{ dateFromat(0, 0, row.modTime) }}
</template>
</el-table-column>
<fu-table-operations
width="300px"
:buttons="buttons"
:ellipsis="10"
:label="$t('commons.table.operate')"
fix
/>
</ComplexTable>
</div>
</el-dialog>
</div>
</el-table-column>
<el-table-column :label="$t('commons.table.createdAt')" min-width="80" fix>
<template #default="{ row }">
{{ dateFromat(0, 0, row.modTime) }}
</template>
</el-table-column>
<fu-table-operations
width="300px"
:buttons="buttons"
:ellipsis="10"
:label="$t('commons.table.operate')"
fix
/>
</ComplexTable>
</div>
</el-drawer>
</template>
<script lang="ts" setup>
@ -76,6 +72,7 @@ import { File } from '@/api/interface/file';
import { BatchDeleteFile, GetFilesList, UploadFileData } from '@/api/modules/files';
import { RecoverWebsiteByUpload } from '@/api/modules/website';
import { loadBaseDir } from '@/api/modules/setting';
import Header from '@/components/drawer-header/index.vue';
const selects = ref<any>([]);
const baseDir = ref();
@ -152,6 +149,7 @@ const fileOnChange = (_uploadFile: UploadFile, uploadFiles: UploadFiles) => {
const handleClose = () => {
uploadRef.value!.clearFiles();
upVisiable.value = false;
};
const onSubmit = () => {

Loading…
Cancel
Save