mirror of
				https://gitee.com/dromara/mayfly-go
				synced 2025-11-04 00:10:25 +08:00 
			
		
		
		
	Compare commits
	
		
			4 Commits
		
	
	
		
			4ac57cd140
			...
			dev
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					4836a770c4 | ||
| 
						 | 
					e6c89fad1b | ||
| 
						 | 
					dba19b1e66 | ||
| 
						 | 
					4e30bdb7cc | 
@@ -11,14 +11,14 @@
 | 
			
		||||
    },
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "@element-plus/icons-vue": "^2.3.2",
 | 
			
		||||
        "@logicflow/core": "^2.1.2",
 | 
			
		||||
        "@logicflow/extension": "^2.1.3",
 | 
			
		||||
        "@logicflow/core": "^2.1.3",
 | 
			
		||||
        "@logicflow/extension": "^2.1.5",
 | 
			
		||||
        "@vueuse/core": "^13.9.0",
 | 
			
		||||
        "@xterm/addon-fit": "^0.10.0",
 | 
			
		||||
        "@xterm/addon-search": "^0.15.0",
 | 
			
		||||
        "@xterm/addon-web-links": "^0.11.0",
 | 
			
		||||
        "@xterm/xterm": "^5.5.0",
 | 
			
		||||
        "asciinema-player": "^3.11.0",
 | 
			
		||||
        "asciinema-player": "^3.11.1",
 | 
			
		||||
        "axios": "^1.6.2",
 | 
			
		||||
        "clipboard": "^2.0.11",
 | 
			
		||||
        "crypto-js": "^4.2.0",
 | 
			
		||||
@@ -40,7 +40,7 @@
 | 
			
		||||
        "uuid": "^13.0.0",
 | 
			
		||||
        "vue": "^v3.5.22",
 | 
			
		||||
        "vue-i18n": "^11.1.12",
 | 
			
		||||
        "vue-router": "^4.5.1",
 | 
			
		||||
        "vue-router": "^4.6.3",
 | 
			
		||||
        "vuedraggable": "^4.1.0"
 | 
			
		||||
    },
 | 
			
		||||
    "devDependencies": {
 | 
			
		||||
 
 | 
			
		||||
@@ -155,6 +155,7 @@ const defaultOptions = {
 | 
			
		||||
    scrollBeyondLastLine: false,
 | 
			
		||||
    lineNumbers: 'on',
 | 
			
		||||
    lineNumbersMinChars: 3,
 | 
			
		||||
    fixedOverflowWidgets: true, // 使弹出层不被容器限制
 | 
			
		||||
} as editor.IStandaloneEditorConstructionOptions;
 | 
			
		||||
 | 
			
		||||
const monacoTextareaRef: Ref<any> = useTemplateRef('monacoTextareaRef');
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
export default {
 | 
			
		||||
    es: {
 | 
			
		||||
        keywordPlaceholder: 'host / name / code',
 | 
			
		||||
        protocol: 'Protocol',
 | 
			
		||||
        port: 'Port',
 | 
			
		||||
        size: 'size',
 | 
			
		||||
        docs: 'docs',
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
export default {
 | 
			
		||||
    es: {
 | 
			
		||||
        keywordPlaceholder: 'host / 名称 / 编号',
 | 
			
		||||
        protocol: '协议',
 | 
			
		||||
        port: '端口',
 | 
			
		||||
        size: '存储大小',
 | 
			
		||||
        docs: '文档数',
 | 
			
		||||
 
 | 
			
		||||
@@ -138,9 +138,8 @@ onBeforeRouteUpdate((to) => {
 | 
			
		||||
.horizontal-menu :deep(.el-sub-menu__title) {
 | 
			
		||||
    margin: 0 5px !important;
 | 
			
		||||
    justify-content: center;
 | 
			
		||||
    max-width: 150px;
 | 
			
		||||
    min-width: 120px; // 统一最小宽度
 | 
			
		||||
    width: fit-content;
 | 
			
		||||
    text-align: center; // 使文字居中对齐
 | 
			
		||||
    padding: 0 8px !important; // 统一内边距
 | 
			
		||||
    padding: 0 16px !important; // 统一内边距
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
 
 | 
			
		||||
@@ -88,7 +88,7 @@
 | 
			
		||||
                            </template>
 | 
			
		||||
 | 
			
		||||
                            <el-row>
 | 
			
		||||
                                <span v-if="dt.hasUpdatedFileds" class="mt-1">
 | 
			
		||||
                                <span v-if="dt.hasUpdatedFields" class="mt-1">
 | 
			
		||||
                                    <span>
 | 
			
		||||
                                        <el-link type="success" underline="never" @click="submitUpdateFields(dt)"
 | 
			
		||||
                                            ><span style="font-size: 12px">{{ $t('common.submit') }}</span></el-link
 | 
			
		||||
@@ -200,7 +200,7 @@ class ExecResTab {
 | 
			
		||||
    /**
 | 
			
		||||
     * 是否有更新字段
 | 
			
		||||
     */
 | 
			
		||||
    hasUpdatedFileds: boolean;
 | 
			
		||||
    hasUpdatedFields: boolean;
 | 
			
		||||
 | 
			
		||||
    errorMsg: string;
 | 
			
		||||
 | 
			
		||||
@@ -783,7 +783,7 @@ const getUploadSqlFileUrl = () => {
 | 
			
		||||
 | 
			
		||||
const changeUpdatedField = (updatedFields: any, dt: ExecResTab) => {
 | 
			
		||||
    // 如果存在要更新字段,则显示提交和取消按钮
 | 
			
		||||
    dt.hasUpdatedFileds = updatedFields && updatedFields.size > 0;
 | 
			
		||||
    dt.hasUpdatedFields = updatedFields && updatedFields.size > 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,13 @@
 | 
			
		||||
                <el-form-item prop="version" :label="t('common.version')">
 | 
			
		||||
                    <el-input v-model.trim="form.version" auto-complete="off" disabled></el-input>
 | 
			
		||||
                </el-form-item>
 | 
			
		||||
                <!-- 增加协议下拉框 http和https,默认http-->
 | 
			
		||||
                 <el-form-item prop="protocol" :label="t('es.protocol')">
 | 
			
		||||
                    <el-select v-model="form.protocol" placeholder="http">
 | 
			
		||||
                        <el-option label="http" value="http"></el-option>
 | 
			
		||||
                        <el-option label="https" value="https"></el-option>
 | 
			
		||||
                    </el-select>
 | 
			
		||||
                </el-form-item>
 | 
			
		||||
 | 
			
		||||
                <el-form-item prop="host" label="Host" required>
 | 
			
		||||
                    <el-col :span="18">
 | 
			
		||||
@@ -105,6 +112,7 @@ const DefaultForm = {
 | 
			
		||||
    id: null,
 | 
			
		||||
    code: '',
 | 
			
		||||
    name: null,
 | 
			
		||||
    protocol: 'http',
 | 
			
		||||
    host: '',
 | 
			
		||||
    version: '',
 | 
			
		||||
    port: 9200,
 | 
			
		||||
 
 | 
			
		||||
@@ -34,8 +34,8 @@ require (
 | 
			
		||||
	github.com/tidwall/gjson v1.18.0
 | 
			
		||||
	github.com/veops/go-ansiterm v0.0.5
 | 
			
		||||
	go.mongodb.org/mongo-driver/v2 v2.3.0 // mongo
 | 
			
		||||
	golang.org/x/crypto v0.42.0 // ssh
 | 
			
		||||
	golang.org/x/oauth2 v0.31.0
 | 
			
		||||
	golang.org/x/crypto v0.43.0 // ssh
 | 
			
		||||
	golang.org/x/oauth2 v0.32.0
 | 
			
		||||
	golang.org/x/sync v0.17.0
 | 
			
		||||
	gopkg.in/natefinch/lumberjack.v2 v2.2.1
 | 
			
		||||
	gopkg.in/yaml.v3 v3.0.1
 | 
			
		||||
@@ -118,9 +118,9 @@ require (
 | 
			
		||||
	golang.org/x/exp v0.0.0-20251002181428-27f1f14c8bb9 // indirect
 | 
			
		||||
	golang.org/x/image v0.31.0 // indirect
 | 
			
		||||
	golang.org/x/mod v0.28.0 // indirect
 | 
			
		||||
	golang.org/x/net v0.44.0 // indirect
 | 
			
		||||
	golang.org/x/sys v0.36.0 // indirect
 | 
			
		||||
	golang.org/x/text v0.29.0 // indirect
 | 
			
		||||
	golang.org/x/net v0.45.0 // indirect
 | 
			
		||||
	golang.org/x/sys v0.37.0 // indirect
 | 
			
		||||
	golang.org/x/text v0.30.0 // indirect
 | 
			
		||||
	golang.org/x/tools v0.37.0 // indirect
 | 
			
		||||
	google.golang.org/protobuf v1.36.10 // indirect
 | 
			
		||||
	modernc.org/libc v1.66.10 // indirect
 | 
			
		||||
 
 | 
			
		||||
@@ -209,7 +209,7 @@ func (d *dbAppImpl) GetDbConnByInstanceId(ctx context.Context, instanceId uint64
 | 
			
		||||
		return nil, errorx.NewBiz("failed to get database list")
 | 
			
		||||
	}
 | 
			
		||||
	if len(dbs) == 0 {
 | 
			
		||||
		return nil, errorx.NewBiz("DB instance [%d] database is not configured, please configure it first", instanceId)
 | 
			
		||||
		return nil, errorx.NewBizf("DB instance [%d] database is not configured, please configure it first", instanceId)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 使用该实例关联的已配置数据库中的第一个库进行连接并返回
 | 
			
		||||
@@ -308,7 +308,7 @@ func (d *dbAppImpl) DumpDb(ctx context.Context, reqParam *dto.DumpDb) error {
 | 
			
		||||
		}
 | 
			
		||||
		if len(tbs) <= 0 {
 | 
			
		||||
			log(fmt.Sprintf("failed to get table [%s] information: No table information was retrieved", tableName))
 | 
			
		||||
			return errorx.NewBiz("Failed to get table information: %s", tableName)
 | 
			
		||||
			return errorx.NewBizf("Failed to get table information: %s", tableName)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		tableInfo := tbs[0]
 | 
			
		||||
 
 | 
			
		||||
@@ -114,7 +114,7 @@ func (app *dataSyncAppImpl) Run(ctx context.Context, id uint64) error {
 | 
			
		||||
	}
 | 
			
		||||
	updateStateTask.Id = id
 | 
			
		||||
	if err := app.UpdateById(ctx, updateStateTask); err != nil {
 | 
			
		||||
		return errorx.NewBiz("failed to update task running state: %s", err.Error())
 | 
			
		||||
		return errorx.NewBizf("failed to update task running state: %s", err.Error())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 标记该任务运行中
 | 
			
		||||
@@ -184,20 +184,20 @@ func (app *dataSyncAppImpl) doDataSync(ctx context.Context, sql string, task *en
 | 
			
		||||
	srcConn, err := app.dbApp.GetDbConn(ctx, uint64(task.SrcDbId), task.SrcDbName)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return errorx.NewBiz("failed to connect to the source database: %s", err.Error())
 | 
			
		||||
		return errorx.NewBizf("failed to connect to the source database: %s", err.Error())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 获取目标数据库连接
 | 
			
		||||
	targetConn, err := app.dbApp.GetDbConn(ctx, uint64(task.TargetDbId), task.TargetDbName)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return errorx.NewBiz("failed to connect to the target database: %s", err.Error())
 | 
			
		||||
		return errorx.NewBizf("failed to connect to the target database: %s", err.Error())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// task.FieldMap为json数组字符串 [{"src":"id","target":"id"}],转为map
 | 
			
		||||
	var fieldMap []map[string]string
 | 
			
		||||
	err = json.Unmarshal([]byte(task.FieldMap), &fieldMap)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return errorx.NewBiz("there was an error parsing the field map json: %s", err.Error())
 | 
			
		||||
		return errorx.NewBizf("there was an error parsing the field map json: %s", err.Error())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 记录本次同步数据总数
 | 
			
		||||
@@ -213,7 +213,7 @@ func (app *dataSyncAppImpl) doDataSync(ctx context.Context, sql string, task *en
 | 
			
		||||
 | 
			
		||||
	targetTableColumns, err := targetConn.GetMetadata().GetColumns(task.TargetTableName)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return errorx.NewBiz("failed to get target table columns: %s", err.Error())
 | 
			
		||||
		return errorx.NewBizf("failed to get target table columns: %s", err.Error())
 | 
			
		||||
	}
 | 
			
		||||
	targetColumnName2Column := collx.ArrayToMap(targetTableColumns, func(column dbi.Column) string {
 | 
			
		||||
		return column.ColumnName
 | 
			
		||||
@@ -300,7 +300,7 @@ func (app *dataSyncAppImpl) srcData2TargetDb(srcRes []map[string]any, fieldMap [
 | 
			
		||||
	// 开启本批次执行事务
 | 
			
		||||
	targetDbTx, err := targetDbConn.Begin()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return errorx.NewBiz("failed to start the target database transaction: %s", err.Error())
 | 
			
		||||
		return errorx.NewBizf("failed to start the target database transaction: %s", err.Error())
 | 
			
		||||
	}
 | 
			
		||||
	defer func() {
 | 
			
		||||
		if r := recover(); r != nil {
 | 
			
		||||
@@ -320,7 +320,7 @@ func (app *dataSyncAppImpl) srcData2TargetDb(srcRes []map[string]any, fieldMap [
 | 
			
		||||
	// 如果是mssql,暂不手动提交事务,否则报错 mssql: The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION.
 | 
			
		||||
	if err := targetDbTx.Commit(); err != nil {
 | 
			
		||||
		if targetDbConn.Info.Type != dbi.ToDbType("mssql") {
 | 
			
		||||
			return errorx.NewBiz("data synchronization - The target database transaction failed to commit: %s", err.Error())
 | 
			
		||||
			return errorx.NewBizf("data synchronization - The target database transaction failed to commit: %s", err.Error())
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -300,7 +300,7 @@ func (d *dbSqlExecAppImpl) FlowBizHandle(ctx context.Context, bizHandleParam *fl
 | 
			
		||||
 | 
			
		||||
	execSqlBizForm, err := jsonx.To[*FlowDbExecSqlBizForm](procinst.BizForm)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, errorx.NewBiz("failed to parse the business form information: %s", err.Error())
 | 
			
		||||
		return nil, errorx.NewBizf("failed to parse the business form information: %s", err.Error())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dbConn, err := d.dbApp.GetDbConn(ctx, execSqlBizForm.DbId, execSqlBizForm.DbName)
 | 
			
		||||
@@ -471,7 +471,7 @@ func (d *dbSqlExecAppImpl) doUpdate(ctx context.Context, sqlExecParam *sqlExecPa
 | 
			
		||||
		nowRec++
 | 
			
		||||
		res = append(res, row)
 | 
			
		||||
		if nowRec == maxRec {
 | 
			
		||||
			return errorx.NewBiz("update SQL - the maximum number of updated queries is exceeded: %d", maxRec)
 | 
			
		||||
			return errorx.NewBizf("update SQL - the maximum number of updated queries is exceeded: %d", maxRec)
 | 
			
		||||
		}
 | 
			
		||||
		return nil
 | 
			
		||||
	})
 | 
			
		||||
 
 | 
			
		||||
@@ -122,12 +122,12 @@ func (app *dbTransferAppImpl) InitCronJob() {
 | 
			
		||||
 | 
			
		||||
func (app *dbTransferAppImpl) Run(ctx context.Context, taskId uint64) (uint64, error) {
 | 
			
		||||
	if app.IsRunning(taskId) {
 | 
			
		||||
		return 0, errorx.NewBiz("the db transfer task [%d] is running, please do not repeat the operation", taskId)
 | 
			
		||||
		return 0, errorx.NewBizf("the db transfer task [%d] is running, please do not repeat the operation", taskId)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	task, err := app.GetById(taskId)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, errorx.NewBiz("db transfer task [%d] not found", taskId)
 | 
			
		||||
		return 0, errorx.NewBizf("db transfer task [%d] not found", taskId)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	logId, _ := app.CreateLog(ctx, taskId)
 | 
			
		||||
 
 | 
			
		||||
@@ -41,6 +41,15 @@ func (d *DbConn) Close() error {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *DbConn) Ping() error {
 | 
			
		||||
	// 首先检查d是否为nil
 | 
			
		||||
	if d == nil {
 | 
			
		||||
		return fmt.Errorf("d is nil")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 然后检查d.db是否为nil,这是避免空指针异常的关键
 | 
			
		||||
	if d.db == nil {
 | 
			
		||||
		return fmt.Errorf("db is nil")
 | 
			
		||||
	}
 | 
			
		||||
	return d.db.Ping()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -70,13 +70,13 @@ func (di *DbInfo) Conn(ctx context.Context, meta Meta) (*DbConn, error) {
 | 
			
		||||
	conn, err := meta.GetSqlDb(ctx, di)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logx.Errorf("db connection failed: %s:%d/%s, err:%s", di.Host, di.Port, database, err.Error())
 | 
			
		||||
		return nil, errorx.NewBiz("db connection failed: %s", err.Error())
 | 
			
		||||
		return nil, errorx.NewBizf("db connection failed: %s", err.Error())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = conn.Ping()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logx.Errorf("db ping failed: %s:%d/%s, err:%s", di.Host, di.Port, database, err.Error())
 | 
			
		||||
		return nil, errorx.NewBiz("db connection failed: %s", err.Error())
 | 
			
		||||
		return nil, errorx.NewBizf("db connection failed: %s", err.Error())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dbc := &DbConn{Id: GetDbConnId(di.Id, database), Info: di}
 | 
			
		||||
 
 | 
			
		||||
@@ -134,7 +134,7 @@ func (dd *DMMetadata) GetPrimaryKey(tablename string) (string, error) {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	if len(columns) == 0 {
 | 
			
		||||
		return "", errorx.NewBiz("[%s] 表不存在", tablename)
 | 
			
		||||
		return "", errorx.NewBizf("[%s] 表不存在", tablename)
 | 
			
		||||
	}
 | 
			
		||||
	for _, v := range columns {
 | 
			
		||||
		if v.IsPrimaryKey {
 | 
			
		||||
 
 | 
			
		||||
@@ -129,7 +129,7 @@ func (md *MssqlMetadata) GetPrimaryKey(tablename string) (string, error) {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	if len(columns) == 0 {
 | 
			
		||||
		return "", errorx.NewBiz("[%s] 表不存在", tablename)
 | 
			
		||||
		return "", errorx.NewBizf("[%s] 表不存在", tablename)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, v := range columns {
 | 
			
		||||
 
 | 
			
		||||
@@ -125,7 +125,7 @@ func (md *MysqlMetadata) GetPrimaryKey(tablename string) (string, error) {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	if len(columns) == 0 {
 | 
			
		||||
		return "", errorx.NewBiz("[%s] 表不存在", tablename)
 | 
			
		||||
		return "", errorx.NewBizf("[%s] 表不存在", tablename)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, v := range columns {
 | 
			
		||||
 
 | 
			
		||||
@@ -148,7 +148,7 @@ func (od *OracleMetadata) GetPrimaryKey(tablename string) (string, error) {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	if len(columns) == 0 {
 | 
			
		||||
		return "", errorx.NewBiz("[%s] 表不存在", tablename)
 | 
			
		||||
		return "", errorx.NewBizf("[%s] 表不存在", tablename)
 | 
			
		||||
	}
 | 
			
		||||
	for _, v := range columns {
 | 
			
		||||
		if v.IsPrimaryKey {
 | 
			
		||||
 
 | 
			
		||||
@@ -124,7 +124,7 @@ func (pd *PgsqlMetadata) GetPrimaryKey(tablename string) (string, error) {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	if len(columns) == 0 {
 | 
			
		||||
		return "", errorx.NewBiz("[%s] 表不存在", tablename)
 | 
			
		||||
		return "", errorx.NewBizf("[%s] 表不存在", tablename)
 | 
			
		||||
	}
 | 
			
		||||
	for _, v := range columns {
 | 
			
		||||
		if v.IsPrimaryKey {
 | 
			
		||||
 
 | 
			
		||||
@@ -148,14 +148,14 @@ func (d *Container) ContainerCreate(rc *req.Ctx) {
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		_ = cli.DockerClient.ContainerRemove(ctx, containerCreate.Name, container.RemoveOptions{RemoveVolumes: true, Force: true})
 | 
			
		||||
		panic(errorx.NewBiz("create container failed, err: %v", err))
 | 
			
		||||
		panic(errorx.NewBizf("create container failed, err: %v", err))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	logx.Infof("create container %s successful! now check if the container is started and delete the container information if it is not.", containerCreate.Name)
 | 
			
		||||
 | 
			
		||||
	if err := cli.DockerClient.ContainerStart(ctx, con.ID, container.StartOptions{}); err != nil {
 | 
			
		||||
		_ = cli.DockerClient.ContainerRemove(ctx, containerCreate.Name, container.RemoveOptions{RemoveVolumes: true, Force: true})
 | 
			
		||||
		panic(errorx.NewBiz("create successful but start failed, err: %v", err))
 | 
			
		||||
		panic(errorx.NewBizf("create successful but start failed, err: %v", err))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@ import (
 | 
			
		||||
 | 
			
		||||
type InstanceForm struct {
 | 
			
		||||
	Id                 uint64  `json:"id"`
 | 
			
		||||
	Protocol           string  `binding:"required" json:"protocol"`
 | 
			
		||||
	Name               string  `binding:"required" json:"name"`
 | 
			
		||||
	Host               string  `binding:"required" json:"host"`
 | 
			
		||||
	Port               int     `binding:"required" json:"port"`
 | 
			
		||||
 
 | 
			
		||||
@@ -9,13 +9,14 @@ type InstanceListVO struct {
 | 
			
		||||
	tagentity.AuthCerts // 授权凭证信息
 | 
			
		||||
	tagentity.ResourceTags
 | 
			
		||||
 | 
			
		||||
	Id      *int64  `json:"id"`
 | 
			
		||||
	Code    string  `json:"code"`
 | 
			
		||||
	Name    *string `json:"name"`
 | 
			
		||||
	Host    *string `json:"host"`
 | 
			
		||||
	Port    *int    `json:"port"`
 | 
			
		||||
	Version *string `json:"version"`
 | 
			
		||||
	Remark  *string `json:"remark"`
 | 
			
		||||
	Id       *int64  `json:"id"`
 | 
			
		||||
	Code     string  `json:"code"`
 | 
			
		||||
	Name     *string `json:"name"`
 | 
			
		||||
	Protocol *string `json:"protocol"`
 | 
			
		||||
	Host     *string `json:"host"`
 | 
			
		||||
	Port     *int    `json:"port"`
 | 
			
		||||
	Version  *string `json:"version"`
 | 
			
		||||
	Remark   *string `json:"remark"`
 | 
			
		||||
 | 
			
		||||
	CreateTime *time.Time `json:"createTime"`
 | 
			
		||||
	Creator    *string    `json:"creator"`
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,7 @@ type EsInstance struct {
 | 
			
		||||
 | 
			
		||||
	Code               string  `json:"code" gorm:"size:32;not null;"`
 | 
			
		||||
	Name               string  `json:"name" gorm:"size:32;not null;"`
 | 
			
		||||
	Protocol           string  `json:"protocol" gorm:"size:10;not null;"`
 | 
			
		||||
	Host               string  `json:"host" gorm:"size:255;not null;"`
 | 
			
		||||
	Port               int     `json:"port"`
 | 
			
		||||
	Network            string  `json:"network" gorm:"size:20;"`
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
package esi
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"crypto/tls"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"mayfly-go/internal/machine/mcm"
 | 
			
		||||
	"mayfly-go/pkg/logx"
 | 
			
		||||
@@ -27,6 +28,15 @@ func (d *EsConn) Close() error {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *EsConn) Ping() error {
 | 
			
		||||
	// 首先检查d是否为nil
 | 
			
		||||
	if d == nil {
 | 
			
		||||
		return fmt.Errorf("es connection is nil")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 然后检查d.Info是否为nil,这是避免空指针异常的关键
 | 
			
		||||
	if d.Info == nil {
 | 
			
		||||
		return fmt.Errorf("es Info is nil")
 | 
			
		||||
	}
 | 
			
		||||
	_, err := d.Info.Ping()
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
@@ -43,6 +53,16 @@ func (d *EsConn) StartProxy() error {
 | 
			
		||||
	d.proxy = httputil.NewSingleHostReverseProxy(targetURL)
 | 
			
		||||
	// 设置 proxy buffer pool
 | 
			
		||||
	d.proxy.BufferPool = NewBufferPool()
 | 
			
		||||
 | 
			
		||||
	// Configure TLS to skip certificate verification for non-compliant certificates
 | 
			
		||||
	if targetURL.Scheme == "https" {
 | 
			
		||||
		d.proxy.Transport = &http.Transport{
 | 
			
		||||
			TLSClientConfig: &tls.Config{
 | 
			
		||||
				InsecureSkipVerify: true,
 | 
			
		||||
			},
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,7 @@ type EsInfo struct {
 | 
			
		||||
	InstanceId uint64 // 实例id
 | 
			
		||||
	Name       string
 | 
			
		||||
 | 
			
		||||
	Protocol string // 协议,默认http
 | 
			
		||||
	Host     string
 | 
			
		||||
	Port     int
 | 
			
		||||
	Network  string
 | 
			
		||||
@@ -58,14 +59,14 @@ func (di *EsInfo) Conn(ctx context.Context) (*EsConn, map[string]any, error) {
 | 
			
		||||
	err := di.IfUseSshTunnelChangeIpPort(ctx)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logx.Errorf("es ssh failed: %s, err:%s", di.baseUrl, err.Error())
 | 
			
		||||
		return nil, nil, errorx.NewBiz("es ssh failed: %s", err.Error())
 | 
			
		||||
		return nil, nil, errorx.NewBizf("es ssh failed: %s", err.Error())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 尝试获取es版本信息,调用接口:get /
 | 
			
		||||
	res, err := di.Ping()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logx.Errorf("es ping failed: %s, err:%s", di.baseUrl, err.Error())
 | 
			
		||||
		return nil, nil, errorx.NewBiz("es ping failed: %s", err.Error())
 | 
			
		||||
		return nil, nil, errorx.NewBizf("es ping failed: %s", err.Error())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	esc := &EsConn{Id: di.InstanceId, Info: di}
 | 
			
		||||
@@ -90,7 +91,14 @@ func (di *EsInfo) Ping() (map[string]any, error) {
 | 
			
		||||
 | 
			
		||||
// ExecApi 执行api
 | 
			
		||||
func (di *EsInfo) ExecApi(method, path string, data any, timeoutSecond ...int) (map[string]any, error) {
 | 
			
		||||
	request := httpx.NewReq(di.baseUrl + path)
 | 
			
		||||
	var request *httpx.Req
 | 
			
		||||
	// Use insecure TLS client for HTTPS connections to handle non-compliant certificates
 | 
			
		||||
	if di.Protocol == "https" {
 | 
			
		||||
		request = httpx.NewReqWithInsecureTLS(di.baseUrl + path)
 | 
			
		||||
	} else {
 | 
			
		||||
		request = httpx.NewReq(di.baseUrl + path)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if di.authorization != "" {
 | 
			
		||||
		request.Header("Authorization", di.authorization)
 | 
			
		||||
	}
 | 
			
		||||
@@ -111,12 +119,17 @@ func (di *EsInfo) ExecApi(method, path string, data any, timeoutSecond ...int) (
 | 
			
		||||
		return request.PutObj(data).BodyToMap()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil, errorx.NewBiz("不支持的请求方法: %s", method)
 | 
			
		||||
	return nil, errorx.NewBizf("不支持的请求方法: %s", method)
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 如果使用了ssh隧道,将其host port改变其本地映射host port
 | 
			
		||||
func (di *EsInfo) IfUseSshTunnelChangeIpPort(ctx context.Context) error {
 | 
			
		||||
	// 设置默认协议
 | 
			
		||||
	if di.Protocol == "" {
 | 
			
		||||
		di.Protocol = "http"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 开启ssh隧道
 | 
			
		||||
	if di.SshTunnelMachineId > 0 {
 | 
			
		||||
		stm, err := GetSshTunnel(ctx, di.SshTunnelMachineId)
 | 
			
		||||
@@ -130,9 +143,9 @@ func (di *EsInfo) IfUseSshTunnelChangeIpPort(ctx context.Context) error {
 | 
			
		||||
		di.Host = exposedIp
 | 
			
		||||
		di.Port = exposedPort
 | 
			
		||||
		di.useSshTunnel = true
 | 
			
		||||
		di.baseUrl = fmt.Sprintf("http://%s:%d", exposedIp, exposedPort)
 | 
			
		||||
		di.baseUrl = fmt.Sprintf("%s://%s:%d", di.Protocol, exposedIp, exposedPort)
 | 
			
		||||
	} else {
 | 
			
		||||
		di.baseUrl = fmt.Sprintf("http://%s:%d", di.Host, di.Port)
 | 
			
		||||
		di.baseUrl = fmt.Sprintf("%s://%s:%d", di.Protocol, di.Host, di.Port)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -312,10 +312,10 @@ func (m *machineAppImpl) ToMachineInfoById(machineId uint64) (*mcm.MachineInfo,
 | 
			
		||||
func (m *machineAppImpl) getMachineAndAuthCert(machineId uint64) (*entity.Machine, *tagentity.ResourceAuthCert, error) {
 | 
			
		||||
	me, err := m.GetById(machineId)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, nil, errorx.NewBiz("[%d] machine not found", machineId)
 | 
			
		||||
		return nil, nil, errorx.NewBizf("[%d] machine not found", machineId)
 | 
			
		||||
	}
 | 
			
		||||
	if me.Status != entity.MachineStatusEnable && me.Protocol == 1 {
 | 
			
		||||
		return nil, nil, errorx.NewBiz("[%s] machine has been disable", me.Code)
 | 
			
		||||
		return nil, nil, errorx.NewBizf("[%s] machine has been disable", me.Code)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	authCert, err := m.resourceAuthCertApp.GetResourceAuthCert(tagentity.TagTypeMachine, me.Code)
 | 
			
		||||
 
 | 
			
		||||
@@ -180,7 +180,7 @@ func (m *machineFileAppImpl) GetDirSize(ctx context.Context, opParam *dto.Machin
 | 
			
		||||
		//du: cannot access ‘/proc/19087/fdinfo/3’: No such file or directory\n
 | 
			
		||||
		//18G     /\n
 | 
			
		||||
		if res == "" {
 | 
			
		||||
			return "", errorx.NewBiz("failed to get directory size: %s", err.Error())
 | 
			
		||||
			return "", errorx.NewBizf("failed to get directory size: %s", err.Error())
 | 
			
		||||
		}
 | 
			
		||||
		strs := strings.Split(res, "\n")
 | 
			
		||||
		res = strs[len(strs)-2]
 | 
			
		||||
@@ -247,7 +247,7 @@ func (m *machineFileAppImpl) CreateFile(ctx context.Context, opParam *dto.Machin
 | 
			
		||||
	}
 | 
			
		||||
	file, err := sftpCli.Create(path)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, errorx.NewBiz("failed to create file: %s", err.Error())
 | 
			
		||||
		return nil, errorx.NewBizf("failed to create file: %s", err.Error())
 | 
			
		||||
	}
 | 
			
		||||
	defer file.Close()
 | 
			
		||||
	return mi, err
 | 
			
		||||
 
 | 
			
		||||
@@ -63,7 +63,7 @@ func (m *machineTermOpAppImpl) TermConn(ctx context.Context, cli *mcm.Cli, wsCon
 | 
			
		||||
 | 
			
		||||
		fileKey, wc, saveFileFunc, err := m.fileApp.NewWriter(ctx, "", fmt.Sprintf("mto_%d_%s.cast", termOpRecord.MachineId, timex.TimeNo()))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return errorx.NewBiz("failed to create a terminal playback log file: %v", err)
 | 
			
		||||
			return errorx.NewBizf("failed to create a terminal playback log file: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
		defer saveFileFunc(&err)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -63,7 +63,7 @@ func (c *Cli) GetSftpCli() (*sftp.Client, error) {
 | 
			
		||||
	if sftpclient == nil {
 | 
			
		||||
		sc, serr := sftp.NewClient(c.sshClient)
 | 
			
		||||
		if serr != nil {
 | 
			
		||||
			return nil, errorx.NewBiz("failed to obtain the sftp client: %s", serr.Error())
 | 
			
		||||
			return nil, errorx.NewBizf("failed to obtain the sftp client: %s", serr.Error())
 | 
			
		||||
		}
 | 
			
		||||
		sftpclient = sc
 | 
			
		||||
		c.sftpClient = sftpclient
 | 
			
		||||
 
 | 
			
		||||
@@ -56,7 +56,7 @@ func (mi *MachineInfo) Conn(ctx context.Context) (*Cli, error) {
 | 
			
		||||
	// 如果使用了ssh隧道,则修改机器ip port为暴露的ip port
 | 
			
		||||
	err := mi.IfUseSshTunnelChangeIpPort(ctx, false)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, errorx.NewBiz("ssh tunnel connection failed: %s", err.Error())
 | 
			
		||||
		return nil, errorx.NewBizf("ssh tunnel connection failed: %s", err.Error())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cli := &Cli{Info: mi}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ package mgm
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"mayfly-go/pkg/logx"
 | 
			
		||||
 | 
			
		||||
	"go.mongodb.org/mongo-driver/v2/mongo"
 | 
			
		||||
@@ -28,5 +29,14 @@ func (mc *MongoConn) Close() error {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (mc *MongoConn) Ping() error {
 | 
			
		||||
	// 首先检查mc是否为nil
 | 
			
		||||
	if mc == nil {
 | 
			
		||||
		return fmt.Errorf("mc connection is nil")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 然后检查mc.Cli是否为nil,这是避免空指针异常的关键
 | 
			
		||||
	if mc.Cli == nil {
 | 
			
		||||
		return fmt.Errorf("mc client is nil")
 | 
			
		||||
	}
 | 
			
		||||
	return mc.Cli.Ping(context.Background(), nil)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -254,7 +254,7 @@ func (r *redisAppImpl) FlowBizHandle(ctx context.Context, bizHandleParam *flowap
 | 
			
		||||
 | 
			
		||||
	runCmdParam, err := jsonx.To[*FlowRedisRunCmdBizForm](procinst.BizForm)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, errorx.NewBiz("failed to parse the business form information: %s", err.Error())
 | 
			
		||||
		return nil, errorx.NewBizf("failed to parse the business form information: %s", err.Error())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	redisConn, err := r.GetRedisConn(ctx, runCmdParam.Id, runCmdParam.Db)
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ package rdm
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"mayfly-go/pkg/errorx"
 | 
			
		||||
	"mayfly-go/pkg/logx"
 | 
			
		||||
 | 
			
		||||
@@ -41,7 +42,19 @@ func (r *RedisConn) Close() error {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *RedisConn) Ping() error {
 | 
			
		||||
	_, err := r.Cli.Ping(context.Background()).Result()
 | 
			
		||||
	// 首先检查r是否为nil
 | 
			
		||||
	if r == nil {
 | 
			
		||||
		return fmt.Errorf("redis connection is nil")
 | 
			
		||||
	}
 | 
			
		||||
	// 然后检查r.Cli是否为nil,这是避免空指针异常的关键
 | 
			
		||||
	if r.Cli == nil {
 | 
			
		||||
		return fmt.Errorf("redis client is nil")
 | 
			
		||||
	}
 | 
			
		||||
	cmd := r.Cli.Ping(context.Background())
 | 
			
		||||
	if cmd == nil {
 | 
			
		||||
		return fmt.Errorf("the ping cmd is nil")
 | 
			
		||||
	}
 | 
			
		||||
	_, err := cmd.Result()
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -70,7 +70,7 @@ func (re *RedisInfo) connStandalone() (*RedisConn, error) {
 | 
			
		||||
	_, e := cli.Ping(context.Background()).Result()
 | 
			
		||||
	if e != nil {
 | 
			
		||||
		cli.Close()
 | 
			
		||||
		return nil, errorx.NewBiz("redis standalone connection failed: %s", e.Error())
 | 
			
		||||
		return nil, errorx.NewBizf("redis standalone connection failed: %s", e.Error())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	logx.Infof("redis standalone connection: %s/%d", re.Host, re.Db)
 | 
			
		||||
@@ -95,7 +95,7 @@ func (re *RedisInfo) connCluster() (*RedisConn, error) {
 | 
			
		||||
	_, e := cli.Ping(context.Background()).Result()
 | 
			
		||||
	if e != nil {
 | 
			
		||||
		cli.Close()
 | 
			
		||||
		return nil, errorx.NewBiz("redis cluster connection failed: %s", e.Error())
 | 
			
		||||
		return nil, errorx.NewBizf("redis cluster connection failed: %s", e.Error())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	logx.Infof("redis cluster connection: %s/%d", re.Host, re.Db)
 | 
			
		||||
@@ -128,7 +128,7 @@ func (re *RedisInfo) connSentinel() (*RedisConn, error) {
 | 
			
		||||
	_, e := cli.Ping(context.Background()).Result()
 | 
			
		||||
	if e != nil {
 | 
			
		||||
		cli.Close()
 | 
			
		||||
		return nil, errorx.NewBiz("redis sentinel connection failed: %s", e.Error())
 | 
			
		||||
		return nil, errorx.NewBizf("redis sentinel connection failed: %s", e.Error())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	logx.Infof("redis sentinel connection: %s/%d", re.Host, re.Db)
 | 
			
		||||
 
 | 
			
		||||
@@ -121,7 +121,7 @@ func (r *resourceAuthCertAppImpl) RelateAuthCert(ctx context.Context, params *dt
 | 
			
		||||
 | 
			
		||||
		existNameAc := &entity.ResourceAuthCert{Name: addAcName}
 | 
			
		||||
		if r.GetByCond(existNameAc) == nil && existNameAc.ResourceCode != resourceCode {
 | 
			
		||||
			return errorx.NewBiz("The name of the authorization credential cannot be repeated: [%s]", addAcName)
 | 
			
		||||
			return errorx.NewBizf("The name of the authorization credential cannot be repeated: [%s]", addAcName)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		addAuthCerts = append(addAuthCerts, addAc)
 | 
			
		||||
 
 | 
			
		||||
@@ -210,7 +210,7 @@ func (p *tagTreeAppImpl) RelateTagsByCodeAndType(ctx context.Context, param *dto
 | 
			
		||||
 | 
			
		||||
	if len(parentTagCodePaths) == 0 {
 | 
			
		||||
		// 不满足满足条件的标签
 | 
			
		||||
		return errorx.NewBiz("There is no tag that satisfies [type=%d, code=%s]", parentTagType, parentTagCode)
 | 
			
		||||
		return errorx.NewBizf("There is no tag that satisfies [type=%d, code=%s]", parentTagType, parentTagCode)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, tag := range param.Tags {
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,7 @@ func V1_10() []*gormigrate.Migration {
 | 
			
		||||
	migrations = append(migrations, V1_10_1()...)
 | 
			
		||||
	migrations = append(migrations, V1_10_2()...)
 | 
			
		||||
	migrations = append(migrations, V1_10_3()...)
 | 
			
		||||
	migrations = append(migrations, V1_10_4()...)
 | 
			
		||||
	return migrations
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -326,3 +327,28 @@ func V1_10_3() []*gormigrate.Migration {
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func V1_10_4() []*gormigrate.Migration {
 | 
			
		||||
	return []*gormigrate.Migration{
 | 
			
		||||
		{
 | 
			
		||||
			ID: "20251023-v1.10.4",
 | 
			
		||||
			Migrate: func(tx *gorm.DB) error {
 | 
			
		||||
				// 给EsInstance表添加protocol列,默认值为http, 20251023,fudawei
 | 
			
		||||
				if !tx.Migrator().HasColumn(&esentity.EsInstance{}, "protocol") {
 | 
			
		||||
					// 先添加可为空的列
 | 
			
		||||
					if err := tx.Exec("ALTER TABLE t_es_instance ADD COLUMN protocol VARCHAR(10) DEFAULT 'http'").Error; err != nil {
 | 
			
		||||
						return err
 | 
			
		||||
					}
 | 
			
		||||
					// 更新所有现有记录为默认值http
 | 
			
		||||
					if err := tx.Exec("UPDATE t_es_instance SET protocol = 'http' WHERE protocol IS NULL OR protocol = ''").Error; err != nil {
 | 
			
		||||
						return err
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				return nil
 | 
			
		||||
			},
 | 
			
		||||
			Rollback: func(tx *gorm.DB) error {
 | 
			
		||||
				return nil
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@ func ErrIsNil(err error, msgAndParams ...any) {
 | 
			
		||||
			panic(errorx.NewBiz(err.Error()))
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		panic(errorx.NewBiz(msgAndParams[0].(string), msgAndParams[1:]...))
 | 
			
		||||
		panic(errorx.NewBizf(msgAndParams[0].(string), msgAndParams[1:]...))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -43,7 +43,7 @@ func ErrIsNilI(ctx context.Context, err error, msgId i18n.MsgId, attrs ...any) {
 | 
			
		||||
 | 
			
		||||
func ErrNotNil(err error, msg string, params ...any) {
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		panic(errorx.NewBiz(msg, params...))
 | 
			
		||||
		panic(errorx.NewBizf(msg, params...))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -53,7 +53,7 @@ func ErrNotNil(err error, msg string, params ...any) {
 | 
			
		||||
//	biz.ErrIsNilAppendErr(err, "xxxx: %s")
 | 
			
		||||
func ErrIsNilAppendErr(err error, msg string) {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(errorx.NewBiz(msg, err.Error()))
 | 
			
		||||
		panic(errorx.NewBizf(msg, err.Error()))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -63,13 +63,13 @@ func ErrIsNilAppendErr(err error, msg string) {
 | 
			
		||||
//	biz.ErrIsNilAppendErr(err, "xxxx: %s")
 | 
			
		||||
func ErrIsNilAppendErrI(ctx context.Context, err error, msgId i18n.MsgId) {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(errorx.NewBiz(i18n.TC(ctx, msgId), err.Error()))
 | 
			
		||||
		panic(errorx.NewBizf(i18n.TC(ctx, msgId), err.Error()))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IsTrue(exp bool, msg string, params ...any) {
 | 
			
		||||
	if !exp {
 | 
			
		||||
		panic(errorx.NewBiz(msg, params...))
 | 
			
		||||
		panic(errorx.NewBizf(msg, params...))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -87,19 +87,19 @@ func IsTrueBy(exp bool, err *errorx.BizError) {
 | 
			
		||||
 | 
			
		||||
func NotEmpty(str string, msg string, params ...any) {
 | 
			
		||||
	if str == "" {
 | 
			
		||||
		panic(errorx.NewBiz(msg, params...))
 | 
			
		||||
		panic(errorx.NewBizf(msg, params...))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NotNil(data any, msg string, params ...any) {
 | 
			
		||||
	if reflect.ValueOf(data).IsNil() {
 | 
			
		||||
		panic(errorx.NewBiz(msg, params...))
 | 
			
		||||
		panic(errorx.NewBizf(msg, params...))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NotBlank(data any, msg string, params ...any) {
 | 
			
		||||
	if anyx.IsBlank(data) {
 | 
			
		||||
		panic(errorx.NewBiz(msg, params...))
 | 
			
		||||
		panic(errorx.NewBizf(msg, params...))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -35,8 +35,13 @@ func (e BizError) String() string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewBiz 创建业务逻辑错误结构体,默认为业务逻辑错误
 | 
			
		||||
func NewBiz(msg string, formatValues ...any) *BizError {
 | 
			
		||||
	return &BizError{code: BizErr.code, err: fmt.Sprintf(msg, formatValues...)}
 | 
			
		||||
func NewBiz(msg string) *BizError {
 | 
			
		||||
	return &BizError{code: BizErr.code, err: msg}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewBizf 创建业务逻辑错误结构体,可设置格式化参数
 | 
			
		||||
func NewBizf(format string, formatValues ...any) *BizError {
 | 
			
		||||
	return NewBiz(fmt.Sprintf(format, formatValues...))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewBizI 使用i18n的msgId创建业务逻辑错误结构体,默认为业务逻辑错误 (使用ctx中的国际化语言)
 | 
			
		||||
@@ -47,7 +52,12 @@ func NewBizI(ctx context.Context, msgId i18n.MsgId, attrs ...any) *BizError {
 | 
			
		||||
	return &BizError{code: BizErr.code, err: i18n.TC(ctx, msgId, attrs...)}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 创建业务逻辑错误结构体,可设置指定错误code
 | 
			
		||||
func NewBizCode(code int16, msg string, formats ...any) *BizError {
 | 
			
		||||
	return &BizError{code: code, err: fmt.Sprintf(msg, formats...)}
 | 
			
		||||
// NewBizCode 创建业务逻辑错误结构体,可设置指定错误code
 | 
			
		||||
func NewBizCode(code int16, msg string) *BizError {
 | 
			
		||||
	return &BizError{code: code, err: msg}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewBizCodef 创建业务逻辑错误结构体,可设置指定错误code,并且支持格式化参数
 | 
			
		||||
func NewBizCodef(code int16, format string, formats ...any) *BizError {
 | 
			
		||||
	return NewBizCode(code, fmt.Sprintf(format, formats...))
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ package httpx
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"crypto/tls"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
@@ -41,6 +42,16 @@ func NewReq(url string) *Req {
 | 
			
		||||
	return &Req{url: url, client: http.Client{}}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 创建一个请求(不验证TLS证书)
 | 
			
		||||
func NewReqWithInsecureTLS(url string) *Req {
 | 
			
		||||
	transport := &http.Transport{
 | 
			
		||||
		TLSClientConfig: &tls.Config{
 | 
			
		||||
			InsecureSkipVerify: true,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	return &Req{url: url, client: http.Client{Transport: transport}}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r *Req) Url(url string) *Req {
 | 
			
		||||
	r.url = url
 | 
			
		||||
	return r
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user