mirror of
https://gitee.com/goploy/goploy.git
synced 2024-12-01 19:57:34 +08:00
A 1.12.2
This commit is contained in:
parent
72a8143fc3
commit
2754e63af5
@ -437,3 +437,15 @@ export class ServerExecScript extends Request {
|
||||
this.param = param
|
||||
}
|
||||
}
|
||||
|
||||
export class ServerRemoteCrontabList extends Request {
|
||||
readonly url = '/server/getRemoteCrontabList'
|
||||
readonly method = 'get'
|
||||
public param: {
|
||||
serverId: number
|
||||
}
|
||||
constructor(param: ServerRemoteCrontabList['param']) {
|
||||
super()
|
||||
this.param = param
|
||||
}
|
||||
}
|
||||
|
1
web/src/icons/svg/crontabManage.svg
Normal file
1
web/src/icons/svg/crontabManage.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1667293457240" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2299" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M831.825 63.94H191.94c-70.692 0-128 57.308-128 128v639.885c0 70.692 57.308 128 128 128h639.885c70.692 0 128-57.308 128-128V191.94c0-70.692-57.308-128-128-128zM895.885 832a63.835 63.835 0 0 1-63.973 63.886H192.088c-17.112 0-33.27-6.575-45.372-18.676s-18.836-28.098-18.836-45.21V192a64.236 64.236 0 0 1 64.208-64.12h639.824A64.038 64.038 0 0 1 895.885 192V832z" p-id="2300"></path><path d="M791.998 351.852H536a31.97 31.97 0 0 0 0 63.94h256a31.97 31.97 0 0 0 0-63.94z m0 256.121H536a31.97 31.97 0 0 0 0 63.94h256a31.97 31.97 0 0 0 0-63.94z m-447.996-79.975c-61.856 0-111.986 50.144-111.986 111.985S282.16 751.97 344.002 751.97s111.985-50.144 111.985-111.986-50.13-111.985-111.985-111.985z m33.982 145.982a48.045 48.045 0 1 1 14.088-33.982 47.746 47.746 0 0 1-14.088 33.986z m39.412-376.586L311.999 402.787l-41.391-41.395a31.97 31.97 0 1 0-45.213 45.213l63.997 64.002a31.97 31.97 0 0 0 45.214 0l128-128a31.97 31.97 0 0 0-45.21-45.213z" p-id="2301"></path></svg>
|
After Width: | Height: | Size: 1.3 KiB |
1
web/src/icons/svg/sftpManage.svg
Normal file
1
web/src/icons/svg/sftpManage.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1667293561564" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4447" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M1016.128 812.992 891.648 100.096c-6.72-44.16-43.776-78.144-89.536-79.936L221.952 20.16C175.552 22.016 137.728 56.96 131.968 102.208l-124.16 710.848C3.136 827.328 0 842.304 0 858.112c0 80.512 65.536 145.728 146.24 145.728l731.456 0c80.704 0 146.304-65.216 146.304-145.728C1024 842.24 1020.8 827.328 1016.128 812.992zM402.24 384.384c0-60.288 49.152-109.312 109.76-109.312s109.696 49.024 109.696 109.312c40.448 0 73.152 32.64 73.152 72.96s-32.704 72.96-73.152 72.96L402.24 530.304c-40.32 0-73.088-32.64-73.088-72.96S361.92 384.384 402.24 384.384zM877.696 931.008 146.24 931.008c-40.256 0-73.088-32.64-73.088-72.896 0-40.128 32.832-72.832 73.088-72.832l731.456 0c40.32 0 73.152 32.704 73.152 72.832C950.848 898.368 918.016 931.008 877.696 931.008zM841.152 821.76c-20.224 0-36.544 16.32-36.544 36.352 0 20.16 16.384 36.416 36.544 36.416s36.544-16.256 36.544-36.416C877.696 838.08 861.312 821.76 841.152 821.76z" p-id="4448"></path></svg>
|
After Width: | Height: | Size: 1.2 KiB |
@ -142,8 +142,7 @@
|
||||
"serverAgent": "Monitor",
|
||||
"serverScript": "Script",
|
||||
"serverProcess": "Process",
|
||||
"template": "Template",
|
||||
"crontab": "Crontab",
|
||||
"serverCrontab": "Crontab UI",
|
||||
"serverCron": "Cron",
|
||||
"namespace": "Namespace",
|
||||
"namespaceSetting": "NS setting",
|
||||
|
@ -142,8 +142,8 @@
|
||||
"serverAgent": "服务器监控",
|
||||
"serverScript": "执行脚本",
|
||||
"serverProcess": "进程管理",
|
||||
"serverCrontab": "Crontab UI",
|
||||
"serverCron": "定时任务",
|
||||
"crontab": "Crontab管理",
|
||||
"namespace": "空间管理",
|
||||
"namespaceSetting": "空间设置",
|
||||
"roleSetting": "角色设置",
|
||||
|
@ -13,6 +13,7 @@
|
||||
<el-input-number
|
||||
v-model="password.length"
|
||||
:min="1"
|
||||
:max="40"
|
||||
placeholder="Please enter the password length"
|
||||
/>
|
||||
<el-button type="primary" @click="createPassword">Gen</el-button>
|
||||
|
@ -111,7 +111,7 @@ export default <RouteRecordRaw[]>[
|
||||
component: () => import('@/views/server/sftp/index.vue'),
|
||||
meta: {
|
||||
title: 'serverSFTP',
|
||||
icon: 'ftp',
|
||||
icon: 'sftpManage',
|
||||
permissions: [permission.ShowSftpFilePage],
|
||||
},
|
||||
},
|
||||
@ -135,6 +135,16 @@ export default <RouteRecordRaw[]>[
|
||||
permissions: [permission.ShowServerProcessPage],
|
||||
},
|
||||
},
|
||||
// {
|
||||
// path: 'crontab',
|
||||
// name: 'ServerCrontab',
|
||||
// component: () => import('@/views/server/crontab.vue'),
|
||||
// meta: {
|
||||
// title: 'serverCrontab',
|
||||
// icon: 'crontabManage',
|
||||
// permissions: [permission.ShowServerProcessPage],
|
||||
// },
|
||||
// },
|
||||
{
|
||||
path: 'cron',
|
||||
name: 'ServerCron',
|
||||
|
538
web/src/views/server/crontab.vue
Normal file
538
web/src/views/server/crontab.vue
Normal file
@ -0,0 +1,538 @@
|
||||
<template>
|
||||
<el-row class="app-container">
|
||||
<el-row class="app-bar" type="flex" justify="space-between">
|
||||
<el-col :span="8">
|
||||
<el-select
|
||||
v-model="serverId"
|
||||
placeholder="Select server"
|
||||
style="width: 160px"
|
||||
filterable
|
||||
@change="selectServer"
|
||||
>
|
||||
<el-option
|
||||
v-for="server in serverOption"
|
||||
:key="server.id"
|
||||
:label="server.label"
|
||||
:value="server.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col v-if="serverId !== ''" :span="16" style="text-align: right">
|
||||
<el-button
|
||||
:loading="tableLoading"
|
||||
type="primary"
|
||||
:icon="Plus"
|
||||
@click="handleAdd"
|
||||
>
|
||||
New
|
||||
</el-button>
|
||||
<el-button
|
||||
:loading="tableLoading"
|
||||
type="primary"
|
||||
:icon="Film"
|
||||
@click="refresList"
|
||||
>
|
||||
Backup
|
||||
</el-button>
|
||||
<el-button
|
||||
:loading="tableLoading"
|
||||
type="warning"
|
||||
:icon="Download"
|
||||
@click="refresList"
|
||||
>
|
||||
Import
|
||||
</el-button>
|
||||
<el-button
|
||||
:loading="tableLoading"
|
||||
type="warning"
|
||||
:icon="Upload"
|
||||
@click="refresList"
|
||||
>
|
||||
Export
|
||||
</el-button>
|
||||
<el-button
|
||||
:loading="tableLoading"
|
||||
type="success"
|
||||
:icon="Refresh"
|
||||
@click="getRemoteCrontabList"
|
||||
>
|
||||
Get from crontab
|
||||
</el-button>
|
||||
<el-button
|
||||
:loading="tableLoading"
|
||||
type="success"
|
||||
:icon="Document"
|
||||
@click="refresList"
|
||||
>
|
||||
Save to crontab
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row class="app-table">
|
||||
<el-table
|
||||
v-loading="tableLoading"
|
||||
height="100%"
|
||||
highlight-current-row
|
||||
:data="tablePage.list"
|
||||
>
|
||||
<el-table-column prop="id" label="ID" width="100" />
|
||||
<el-table-column
|
||||
prop="expression"
|
||||
:label="$t('expression')"
|
||||
min-width="120"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column
|
||||
prop="description"
|
||||
:label="$t('description')"
|
||||
min-width="120"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column
|
||||
prop="insertTime"
|
||||
:label="$t('insertTime')"
|
||||
width="155"
|
||||
align="center"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="updateTime"
|
||||
:label="$t('updateTime')"
|
||||
width="155"
|
||||
align="center"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="operation"
|
||||
:label="$t('op')"
|
||||
width="130"
|
||||
align="center"
|
||||
:fixed="$store.state.app.device === 'mobile' ? false : 'right'"
|
||||
>
|
||||
<template #default="scope">
|
||||
<Button
|
||||
type="primary"
|
||||
:icon="Edit"
|
||||
:permissions="[pms.EditCron]"
|
||||
@click="handleEdit(scope.row)"
|
||||
/>
|
||||
<Button
|
||||
type="danger"
|
||||
:icon="Delete"
|
||||
:permissions="[pms.DeleteCron]"
|
||||
@click="handleRemove(scope.row)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-row>
|
||||
<el-row type="flex" justify="end" class="app-page">
|
||||
<el-pagination
|
||||
:total="tablePage.total"
|
||||
:page-size="pagination.rows"
|
||||
background
|
||||
layout="total, prev, pager, next"
|
||||
@current-change="handlePageChange"
|
||||
/>
|
||||
</el-row>
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
:fullscreen="$store.state.app.device === 'mobile'"
|
||||
:title="$t('setting')"
|
||||
>
|
||||
<el-form
|
||||
ref="form"
|
||||
v-loading="formProps.loading"
|
||||
:rules="formRules"
|
||||
:model="formData"
|
||||
label-width="120px"
|
||||
:label-position="
|
||||
$store.state.app.device === 'desktop' ? 'right' : 'top'
|
||||
"
|
||||
>
|
||||
<el-form-item :label="$t('command')" prop="command">
|
||||
<el-input v-model="formData.command" autocomplete="off" />
|
||||
</el-form-item>
|
||||
<el-form-item label="Quick Schedule">
|
||||
<el-row style="width: 100%">
|
||||
<el-button type="primary" @click="handleQuickSet('startup')">
|
||||
Startup
|
||||
</el-button>
|
||||
<el-button type="primary" @click="handleQuickSet('hourly')">
|
||||
Hourly
|
||||
</el-button>
|
||||
<el-button type="primary" @click="handleQuickSet('daily')">
|
||||
Daily
|
||||
</el-button>
|
||||
<el-button type="primary" @click="handleQuickSet('weekly')">
|
||||
Weekly
|
||||
</el-button>
|
||||
<el-button type="primary" @click="handleQuickSet('monthly')">
|
||||
Monthly
|
||||
</el-button>
|
||||
<el-button type="primary" @click="handleQuickSet('yearly')">
|
||||
Yearly
|
||||
</el-button>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-row style="width: 100%" align="bottom">
|
||||
<el-row style="width: 60px; margin-right: 10px">
|
||||
<span>Minute</span>
|
||||
<el-input v-model="formData.minute" />
|
||||
</el-row>
|
||||
<el-row style="width: 60px; margin-right: 10px">
|
||||
<span>Hour</span>
|
||||
<el-input v-model="formData.hour" />
|
||||
</el-row>
|
||||
<el-row style="width: 60px; margin-right: 10px">
|
||||
<span>Day</span>
|
||||
<el-input v-model="formData.day" />
|
||||
</el-row>
|
||||
<el-row style="width: 60px; margin-right: 10px">
|
||||
<span>Month</span>
|
||||
<el-input v-model="formData.month" />
|
||||
</el-row>
|
||||
<el-row style="width: 60px; margin-right: 10px">
|
||||
<span>Week</span>
|
||||
<el-input v-model="formData.week" />
|
||||
</el-row>
|
||||
<el-button
|
||||
:disabled="
|
||||
formData.minute == '' ||
|
||||
formData.hour == '' ||
|
||||
formData.day == '' ||
|
||||
formData.month == '' ||
|
||||
formData.week == ''
|
||||
"
|
||||
type="primary"
|
||||
@click="handleSetTime"
|
||||
>
|
||||
Set
|
||||
</el-button>
|
||||
</el-row>
|
||||
<span>{{ formProps.dateLocale }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('expression')" prop="expression">
|
||||
<el-input v-model="formData.expression" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('description')">
|
||||
<el-input v-model="formData.description" autocomplete="off" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="dialogVisible = false">
|
||||
{{ $t('cancel') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
:disabled="formProps.disabled"
|
||||
type="primary"
|
||||
@click="submit"
|
||||
>
|
||||
{{ $t('confirm') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</el-row>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
export default { name: 'ServerCron' }
|
||||
</script>
|
||||
<script lang="ts" setup>
|
||||
import pms from '@/permission'
|
||||
import Button from '@/components/Permission/Button.vue'
|
||||
import {
|
||||
Film,
|
||||
Upload,
|
||||
Download,
|
||||
Document,
|
||||
Refresh,
|
||||
Plus,
|
||||
Edit,
|
||||
Delete,
|
||||
} from '@element-plus/icons-vue'
|
||||
import cronstrue from 'cronstrue/i18n'
|
||||
import { ServerRemoteCrontabList, ServerOption } from '@/api/server'
|
||||
import { CronList, CronAdd, CronEdit, CronRemove, CronData } from '@/api/cron'
|
||||
import type { ElForm } from 'element-plus'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { ref, computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
const { locale, t } = useI18n({ useScope: 'global' })
|
||||
const serverId = ref('')
|
||||
const dialogVisible = ref(false)
|
||||
const serverOption = ref<ServerOption['datagram']['list']>([])
|
||||
const tableLoading = ref(false)
|
||||
const tableData = ref<CronList['datagram']['list']>([])
|
||||
const pagination = ref({ page: 1, rows: 20 })
|
||||
const form = ref<InstanceType<typeof ElForm>>()
|
||||
const tempFormData = {
|
||||
id: 0,
|
||||
serverId: 0,
|
||||
name: '',
|
||||
command: '/bin/sh /data/sh/hello.sh',
|
||||
minute: '*/1',
|
||||
hour: '*',
|
||||
day: '*',
|
||||
month: '*',
|
||||
week: '*',
|
||||
expression: '',
|
||||
description: '',
|
||||
}
|
||||
const formData = ref(tempFormData)
|
||||
const formProps = ref({
|
||||
loading: false,
|
||||
disabled: false,
|
||||
dateLocale: '',
|
||||
})
|
||||
const formRules: InstanceType<typeof ElForm>['rules'] = {
|
||||
expression: [
|
||||
{
|
||||
required: true,
|
||||
validator: (_, value) => {
|
||||
if (value.trim().split(/\s+/).length != 6) {
|
||||
return new Error('6 parts are required.')
|
||||
}
|
||||
try {
|
||||
cronstrue.toString(value)
|
||||
return true
|
||||
} catch (error) {
|
||||
if (typeof error === 'string') {
|
||||
return new Error(error)
|
||||
} else if (error instanceof Error) {
|
||||
return error
|
||||
}
|
||||
}
|
||||
},
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
command: [{ required: true, message: 'Command required', trigger: 'blur' }],
|
||||
}
|
||||
|
||||
getServerOption()
|
||||
|
||||
function selectServer() {
|
||||
getList()
|
||||
}
|
||||
|
||||
function getServerOption() {
|
||||
new ServerOption().request().then((response) => {
|
||||
serverOption.value = response.data.list
|
||||
})
|
||||
}
|
||||
|
||||
function getRemoteCrontabList() {
|
||||
tableLoading.value = true
|
||||
tableData.value = []
|
||||
new ServerRemoteCrontabList({ serverId: Number(serverId.value) })
|
||||
.request()
|
||||
.then((response) => {
|
||||
console.log(response)
|
||||
})
|
||||
.finally(() => {
|
||||
tableLoading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
function getList() {
|
||||
tableLoading.value = true
|
||||
tableData.value = []
|
||||
new CronList({ serverId: Number(serverId.value) })
|
||||
.request()
|
||||
.then((response) => {
|
||||
tableData.value = response.data.list
|
||||
})
|
||||
.finally(() => {
|
||||
tableLoading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
const tablePage = computed(() => {
|
||||
let _tableData = tableData.value
|
||||
return {
|
||||
list: _tableData.slice(
|
||||
(pagination.value.page - 1) * pagination.value.rows,
|
||||
pagination.value.page * pagination.value.rows
|
||||
),
|
||||
total: _tableData.length,
|
||||
}
|
||||
})
|
||||
|
||||
function refresList() {
|
||||
pagination.value.page = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
function handleAdd() {
|
||||
restoreFormData()
|
||||
formData.value.serverId = Number(serverId.value)
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
function handleEdit(data: CronData) {
|
||||
formData.value = data
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
function handleRemove(data: CronData) {
|
||||
ElMessageBox.confirm(
|
||||
t('serverPage.deleteTips', { name: data.command }),
|
||||
t('tips'),
|
||||
{
|
||||
confirmButtonText: t('confirm'),
|
||||
cancelButtonText: t('cancel'),
|
||||
type: 'warning',
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
new CronRemove({ id: data.id }).request().then(() => {
|
||||
getList()
|
||||
ElMessage.success('Success')
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage.info('Cancel')
|
||||
})
|
||||
}
|
||||
|
||||
function handleQuickSet(schedule: string) {
|
||||
switch (schedule) {
|
||||
case 'startup':
|
||||
formData.value.expression = `@reboot ${formData.value.command}`
|
||||
formData.value.minute = ''
|
||||
formData.value.hour = ''
|
||||
formData.value.day = ''
|
||||
formData.value.month = ''
|
||||
formData.value.week = ''
|
||||
onExpressionChange()
|
||||
break
|
||||
case 'hourly':
|
||||
formData.value.minute = '0'
|
||||
formData.value.hour = '*'
|
||||
formData.value.day = '*'
|
||||
formData.value.month = '*'
|
||||
formData.value.week = '*'
|
||||
handleSetTime()
|
||||
break
|
||||
case 'daily':
|
||||
formData.value.minute = '0'
|
||||
formData.value.hour = '0'
|
||||
formData.value.day = '*'
|
||||
formData.value.month = '*'
|
||||
formData.value.week = '*'
|
||||
handleSetTime()
|
||||
break
|
||||
case 'monthly':
|
||||
formData.value.minute = '0'
|
||||
formData.value.hour = '0'
|
||||
formData.value.day = '1'
|
||||
formData.value.month = '*'
|
||||
formData.value.week = '*'
|
||||
handleSetTime()
|
||||
break
|
||||
case 'weekly':
|
||||
formData.value.minute = '0'
|
||||
formData.value.hour = '0'
|
||||
formData.value.day = '*'
|
||||
formData.value.month = '*'
|
||||
formData.value.week = '0'
|
||||
handleSetTime()
|
||||
break
|
||||
case 'yearly':
|
||||
formData.value.minute = '0'
|
||||
formData.value.hour = '0'
|
||||
formData.value.day = '1'
|
||||
formData.value.month = '1'
|
||||
formData.value.week = '*'
|
||||
handleSetTime()
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
function handleSetTime() {
|
||||
formData.value.expression = `${formData.value.minute} ${formData.value.hour} ${formData.value.day} ${formData.value.month} ${formData.value.week} ${formData.value.command}`
|
||||
onExpressionChange()
|
||||
}
|
||||
|
||||
function onExpressionChange() {
|
||||
if (formData.value.expression.startsWith('@reboot')) {
|
||||
formProps.value.dateLocale = 'Startup'
|
||||
} else {
|
||||
formProps.value.dateLocale = cronstrue.toString(
|
||||
`${formData.value.minute} ${formData.value.hour} ${formData.value.day} ${formData.value.month} ${formData.value.week}`,
|
||||
{
|
||||
use24HourTimeFormat: true,
|
||||
locale: getLocale(),
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function handlePageChange(val = 1) {
|
||||
pagination.value.page = val
|
||||
}
|
||||
|
||||
function submit() {
|
||||
form.value?.validate((valid) => {
|
||||
formData.value.expression = formData.value.expression.trim()
|
||||
if (valid) {
|
||||
if (formData.value.id === 0) {
|
||||
add()
|
||||
} else {
|
||||
edit()
|
||||
}
|
||||
return Promise.resolve(true)
|
||||
} else {
|
||||
return Promise.reject(false)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function add() {
|
||||
formProps.value.disabled = true
|
||||
new CronAdd(formData.value)
|
||||
.request()
|
||||
.then(() => {
|
||||
getList()
|
||||
ElMessage.success('Success')
|
||||
})
|
||||
.finally(() => {
|
||||
formProps.value.disabled = dialogVisible.value = false
|
||||
})
|
||||
}
|
||||
|
||||
function edit() {
|
||||
formProps.value.disabled = true
|
||||
new CronEdit(formData.value)
|
||||
.request()
|
||||
.then(() => {
|
||||
getList()
|
||||
ElMessage.success('Success')
|
||||
})
|
||||
.finally(() => {
|
||||
formProps.value.disabled = dialogVisible.value = false
|
||||
})
|
||||
}
|
||||
|
||||
function getLocale() {
|
||||
if (locale.value === 'zh-cn') {
|
||||
return 'zh_CN'
|
||||
}
|
||||
return locale.value
|
||||
}
|
||||
|
||||
function restoreFormData() {
|
||||
formData.value = { ...tempFormData }
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/styles/mixin.scss';
|
||||
.template-dialog {
|
||||
padding-right: 10px;
|
||||
height: 400px;
|
||||
overflow-y: auto;
|
||||
@include scrollBar();
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue
Block a user