Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions agent/app/dto/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ type AppDatabase struct {
DbUser string `json:"PANEL_DB_USER"`
Password string `json:"PANEL_DB_USER_PASSWORD"`
DatabaseName string `json:"DATABASE_NAME"`
Format string `json:"format"`
Collation string `json:"collation"`
}

type AuthParam struct {
Expand Down
3 changes: 2 additions & 1 deletion agent/app/service/app_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,10 +300,11 @@ func createLink(ctx context.Context, installTask *task.Task, app model.App, appI
createMysql.Name = dbConfig.DbName
createMysql.Username = dbConfig.DbUser
createMysql.Database = database.Name
createMysql.Format = "utf8mb4"
createMysql.Format = dbConfig.Format
createMysql.Permission = "%"
createMysql.Password = dbConfig.Password
createMysql.From = database.From
createMysql.Collation = dbConfig.Collation
mysqldb, err := NewIMysqlService().Create(ctx, createMysql)
if err != nil {
return err
Expand Down
4 changes: 2 additions & 2 deletions agent/init/migration/migrations/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -728,8 +728,8 @@ var AddGPUMonitor = &gormigrate.Migration{
}

var UpdateDatabaseMysql = &gormigrate.Migration{
ID: "20251124-update-database-mysql",
ID: "20251125-update-database-mysql",
Migrate: func(tx *gorm.DB) error {
return tx.AutoMigrate(&model.Database{})
return tx.AutoMigrate(&model.DatabaseMysql{})
},
}
1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
"vite-plugin-compression": "^0.5.1",
"vite-plugin-eslint": "^1.8.1",
"vite-plugin-html": "^3.2.2",
"vite-plugin-monaco-editor": "^1.1.0",
"vite-plugin-vue-setup-extend": "^0.4.0",
"vite-svg-loader": "^5.1.0",
"vue-tsc": "^0.29.8"
Expand Down
1 change: 1 addition & 0 deletions frontend/src/views/app-store/detail/form/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ const formRules = ref<FormRules>({
memoryLimit: [Rules.requiredInput, checkNumberRange(0, 9999999999)],
specifyIP: [Rules.ipv4orV6],
restartPolicy: [Rules.requiredSelect],
format: [Rules.requiredInput],
});

const initFormData = () => ({
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/views/app-store/detail/install/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ const formData = ref({
taskID: '',
gpuConfig: false,
specifyIP: '',
format: 'utf8mb4',
collation: '',
});

const handleClose = () => {
Expand Down
39 changes: 38 additions & 1 deletion frontend/src/views/app-store/detail/params/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,17 @@
</div>
<span class="input-help" v-if="p.description">{{ getDescription(p) }}</span>
</el-form-item>
<el-form-item v-if="form[p.envKey] == 'mysql'" :label="$t('database.format')" prop="format">
<el-select filterable v-model="form.format" @change="loadCollations()">
<el-option v-for="item of formatOptions" :key="item.format" :label="item.format" :value="item.format" />
</el-select>
</el-form-item>
<el-form-item v-if="form[p.envKey] == 'mysql'" :label="$t('database.collation')" prop="collation">
<el-select filterable v-model="form.collation">
<el-option v-for="item of collationOptions" :key="item" :label="item" :value="item" />
</el-select>
<span class="input-help">{{ $t('database.collationHelper', [form.format]) }}</span>
</el-form-item>
</div>
</template>
<script lang="ts" setup>
Expand All @@ -128,6 +139,7 @@ import { Rules } from '@/global/form-rules';
import { App } from '@/api/interface/app';
import { getDBName, getLabel, getDescription } from '@/utils/util';
import { getPathByType } from '@/api/modules/files';
import { loadFormatCollations } from '@/api/modules/database';

interface ParamObj extends App.FromField {
services: App.AppService[];
Expand Down Expand Up @@ -163,7 +175,9 @@ const props = defineProps({
},
});

const form = reactive({});
const form = reactive({
format: '',
});
let rules = reactive({});
const params = computed({
get() {
Expand Down Expand Up @@ -241,6 +255,10 @@ const handleParams = () => {

const getServices = async (childKey: string, key: string | undefined, pObj: ParamObj | undefined) => {
pObj.services = [];
appKey.value = key || '';
if (appKey.value == 'mysql') {
form.format = 'utf8mb4';
}
await getAppService(key).then((res) => {
pObj.services = res.data || [];
form[childKey] = '';
Expand Down Expand Up @@ -268,13 +286,32 @@ const changeService = (value: string, services: App.AppService[]) => {
});
}
});
if (appKey.value == 'mysql') {
loadOptions(value);
}
updateParam();
};

const toPage = (key: string) => {
window.location.href = '/apps/all?install=' + key;
};

const formatOptions = ref();
const collationOptions = ref();
const appKey = ref('');

const loadOptions = async (database: string) => {
const defaultOptions = [{ format: 'utf8mb4' }, { format: 'utf8mb3' }, { format: 'gbk' }, { format: 'big5' }];
await loadFormatCollations(database).then((res) => {
formatOptions.value = res.data || defaultOptions;
loadCollations();
});
};

const loadCollations = async () => {
collationOptions.value = formatOptions.value?.find((item) => item.format === form.format)?.collations || [];
};

onMounted(() => {
handleParams();
});
Expand Down
23 changes: 12 additions & 11 deletions frontend/src/views/app-store/installed/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -417,10 +417,6 @@
</template>

<script lang="ts" setup>
import { searchAppInstalled, installedOp, appInstalledDeleteCheck, getAppIconUrl } from '@/api/modules/app';
import { onMounted, onUnmounted, reactive, ref } from 'vue';
import i18n from '@/lang';
import { ElMessageBox } from 'element-plus';
import Backups from '@/components/backup/index.vue';
import Uploads from '@/components/upload/index.vue';
import PortJumpDialog from '@/components/port-jump/index.vue';
Expand All @@ -429,20 +425,25 @@ import AppDelete from './delete/index.vue';
import AppParams from './detail/index.vue';
import AppUpgrade from './upgrade/index.vue';
import AppIgnore from './ignore/index.vue';
import Status from '@/components/status/index.vue';
import TaskLog from '@/components/log/task/index.vue';
import Detail from '@/views/app-store/detail/index.vue';
import Tags from '@/views/app-store/components/tag.vue';
import SvgIcon from '@/components/svg-icon/svg-icon.vue';
import MainDiv from '@/components/main-div/index.vue';
import ComposeLogs from '@/components/log/compose/index.vue';
import IgnoreApp from '@/views/app-store/installed/ignore/create/index.vue';
import TerminalDialog from '@/views/container/container/terminal/index.vue';

import { searchAppInstalled, installedOp, appInstalledDeleteCheck, getAppIconUrl } from '@/api/modules/app';
import { onMounted, onUnmounted, reactive, ref } from 'vue';
import i18n from '@/lang';
import { ElMessageBox } from 'element-plus';
import { App } from '@/api/interface/app';
import Status from '@/components/status/index.vue';
import { getAge, jumpToPath, toLink } from '@/utils/util';
import { useRouter } from 'vue-router';
import { MsgSuccess } from '@/utils/message';
import TaskLog from '@/components/log/task/index.vue';
import Detail from '@/views/app-store/detail/index.vue';
import IgnoreApp from '@/views/app-store/installed/ignore/create/index.vue';
import { getAgentSettingByKey } from '@/api/modules/setting';
import Tags from '@/views/app-store/components/tag.vue';
import SvgIcon from '@/components/svg-icon/svg-icon.vue';
import MainDiv from '@/components/main-div/index.vue';
import { routerToFileWithPath, routerToNameWithQuery } from '@/utils/router';
import { useGlobalStore } from '@/composables/useGlobalStore';
const { currentNode, isMaster, currentNodeAddr } = useGlobalStore();
Expand Down
7 changes: 4 additions & 3 deletions frontend/src/views/app-store/installed/upgrade/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@
<TaskLog ref="taskLogRef" />
</template>
<script lang="ts" setup>
import Diff from './diff/index.vue';
import TaskLog from '@/components/log/task/index.vue';
import CodemirrorPro from '@/components/codemirror-pro/index.vue';

import { App } from '@/api/interface/app';
import { getAppUpdateVersions, ignoreUpgrade, installedOp } from '@/api/modules/app';
import { getAppStoreConfig } from '@/api/modules/setting';
Expand All @@ -87,10 +91,7 @@ import { ElMessageBox, FormInstance } from 'element-plus';
import { reactive, ref, onBeforeUnmount } from 'vue';
import { MsgSuccess } from '@/utils/message';
import { Rules } from '@/global/form-rules';
import Diff from './diff/index.vue';
import bus from '@/global/bus';
import CodemirrorPro from '@/components/codemirror-pro/index.vue';
import TaskLog from '@/components/log/task/index.vue';
import { v4 as uuidv4 } from 'uuid';

const composeDiffRef = ref();
Expand Down
21 changes: 12 additions & 9 deletions frontend/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import Components from 'unplugin-vue-components/vite';
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
import svgLoader from 'vite-svg-loader';

const prefix = `monaco-editor/esm/vs`;
import monacoEditorPlugin from 'vite-plugin-monaco-editor';

const { dependencies, devDependencies, name, version } = pkg;
const __APP_INFO__ = {
Expand Down Expand Up @@ -44,14 +44,16 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
scss: {
additionalData: `@use "@/styles/var.scss" as *;`,
silenceDeprecations: ['legacy-js-api'],
api: 'modern',
},
},
},
server: {
port: viteEnv.VITE_PORT,
open: viteEnv.VITE_OPEN,
host: '0.0.0.0',
sourcemapIgnoreList: (sourcePath) => {
return sourcePath.includes('node_modules');
},
proxy: {
'/api/v2': {
target: 'http://localhost:9999/',
Expand Down Expand Up @@ -95,12 +97,16 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
svgLoader({
defaultImport: 'url',
}),
monacoEditorPlugin({
languageWorkers: ['editorWorkerService', 'typescript', 'json', 'html', 'css'],
}),
],
esbuild: {
pure: viteEnv.VITE_DROP_CONSOLE ? ['console.log'] : [],
drop: viteEnv.VITE_DROP_CONSOLE && process.env.NODE_ENV === 'production' ? ['debugger'] : [],
},
build: {
sourcemap: false,
outDir: '../core/cmd/server/web',
minify: 'esbuild',
target: 'esnext',
Expand All @@ -110,15 +116,12 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
chunkFileNames: 'assets/js/[name]-[hash].js',
entryFileNames: 'assets/js/[name]-[hash].js',
assetFileNames: 'assets/[ext]/[name]-[hash].[ext]',
manualChunks: {
jsonWorker: [`${prefix}/language/json/json.worker`],
cssWorker: [`${prefix}/language/css/css.worker`],
htmlWorker: [`${prefix}/language/html/html.worker`],
tsWorker: [`${prefix}/language/typescript/ts.worker`],
editorWorker: [`${prefix}/editor/editor.worker`],
},
},
},
},
optimizeDeps: {
include: ['monaco-editor/esm/vs/editor/editor.api'],
exclude: ['monaco-editor'],
},
};
});
Loading