[go学习笔记.第十一章.项目案例] 1.家庭收支记账软件项目

news2025/2/21 19:33:43

一.基本介绍

1.项目开发流程说明

 

2.项目需求说明

目标:

模拟实现一个基于文本界面的<<家庭记账软件>>

掌握初步的编程技巧和调试技巧

主要涉及以下知识点 :

(1).局部变量和基本数据类型

(2).循环语句

(3).分支语句

(4).简单的屏幕输出格式控制

(5).进阶:面向对象编程使用

需求说明

模拟实现基于文本界面的 《 家庭记账软件 》

该软件能够记录家庭的收入、支出,并能够打印收支明细表 

项目采用分级菜单方式,主菜单如下:

3.项目界面

(1).收支明细界面

(2).登记收入界面 

(3).登记支出界面 

 (4).退出界面

二.代码实现

1. 实现基本功能(先使用面向过程,后面改成面向对象)

功能1:   

        先完成可以显示主菜单,并且可以退出

思路分析: 

        显示给出的主界面,主菜单的显示,当用户输入 4 时,就退出该程序

功能2:

        完成可以显示明细和登记收入的功能

思路分析:

        (1).因为需要显示明细,我们定义一个变量details来记录

        (2).还需要定义变量来记录余额(balance)、每次收支的金额(money),每次收支的说明(note)

功能 3:

        完成登记支出的功能

思路分析:

        登记支出的功能和登录收入的功能类似,做些修改即可

功能1:   先完成可以显示主菜单,并且可以退出

package main

import (
    "fmt"
)

func main() {
    //声明一个变量,保存接收用户输入的选项
    key := ""
    //声明一个变量,控制是否退出for
    loop := true
    //显示主菜单
    for {
        fmt.Println("----------------家庭收支记账软件------------------")
        fmt.Println("                1.收支明细")
        fmt.Println("                2.登记收入")
        fmt.Println("                3.登记支出")
        fmt.Println("                4.退出软件")
        fmt.Println("请选择(1~4):")
        fmt.Scanln(&key)

        switch key {
        case "1":
            fmt.Println("----------------当前收支明细------------------")
        case "2":
        case "3":
            fmt.Println("登记支出")
        case "4":
            loop = false
        default :
            fmt.Println("请输入正确的选项")       
        }

        if !loop {
            break
        }
    }

    fmt.Println("你退出了家庭收支记账软件的使用")
}

功能2: 完成可以显示明细和登记收入的功能

package main

import (
    "fmt"
)

func main() {
    //声明一个变量,保存接收用户输入的选项
    key := ""
    //声明一个变量,控制是否退出for
    loop := true
    //定义账户余额
    balance := 10000.0
    //每次收支的金额
    money := 0.0
    //每次收支的说明
    note := ""
    //收支的详情使用字符串来记录
    //当有收支时,只需要对details进行拼接处理即可
    details := "收支\t账号余额\t收支金额\t说   明"
    //显示主菜单
    for {
        fmt.Println("\n----------------家庭收支记账软件------------------")
        fmt.Println("                1.收支明细")
        fmt.Println("                2.登记收入")
        fmt.Println("                3.登记支出")
        fmt.Println("                4.退出软件")
        fmt.Println("请选择(1~4):")
        fmt.Scanln(&key)

        switch key {
        case "1":
            fmt.Println("----------------当前收支明细------------------")
            fmt.Println(details)
        case "2":
            fmt.Println("本次收入金额:")
            fmt.Scanln(&money)
            balance += money    //修改账户余额
            fmt.Println("本次收入说明:")
            fmt.Scanln(&note)
            //将这个收入情况,拼接到details变量
            //收入 11000 1000 有人发红包
            details += fmt.Sprintf("\n收入\t%v\t\t%v\t\t%v",balance, money, note)

        case "3":
            fmt.Println("登记支出")
        case "4":
            loop = false
        default :
            fmt.Println("请输入正确的选项") 
        }

        if !loop {
            break
        }
    }

    fmt.Println("你退出了家庭收支记账软件的使用")
}

功能 3:  完成登记支出的功能

package main

import (
    "fmt"
)

func main() {
    //声明一个变量,保存接收用户输入的选项
    key := ""
    //声明一个变量,控制是否退出for
    loop := true
    //定义账户余额
    balance := 10000.0
    //每次收支的金额
    money := 0.0
    //每次收支的说明
    note := ""
    //收支的详情使用字符串来记录
    //当有收支时,只需要对details进行拼接处理即可
    details := "收支\t账号余额\t收支金额\t说   明"
    //显示主菜单
    for {
        fmt.Println("\n----------------家庭收支记账软件------------------")
        fmt.Println("                1.收支明细")
        fmt.Println("                2.登记收入")
        fmt.Println("                3.登记支出")
        fmt.Println("                4.退出软件")
        fmt.Println("请选择(1~4):")
        fmt.Scanln(&key)

        switch key {
        case "1":
            fmt.Println("----------------当前收支明细------------------")
            fmt.Println(details)
        case "2":
            fmt.Println("本次收入金额:")
            fmt.Scanln(&money)
            balance += money    //修改账户余额
            fmt.Println("本次收入说明:")
            fmt.Scanln(&note)
            //将这个收入情况,拼接到details变量
            //收入 11000 1000 有人发红包
            details += fmt.Sprintf("\n收入\t%v\t\t%v\t\t%v",balance, money, note)
        case "3":
            fmt.Println("本次支出金额:")
            fmt.Scanln(&money)
            //这里需要做一个判断
            if money > balance {
                fmt.Println("支出的余额不足")
                break
            }
            balance -= money    //修改账户余额
            fmt.Println("本次支出说明:")
            fmt.Scanln(&note)
            //将这个支出情况,拼接到details变量
            //支出 11000 1000 吃中午饭
            details += fmt.Sprintf("\n支出\t%v\t\t%v\t\t%v",balance, money, note)
        case "4":
            loop = false
        default :
            fmt.Println("请输入正确的选项")  
        }

        if !loop {
            break
        }
    }

    fmt.Println("你退出了家庭收支记账软件的使用")
}

2.项目代码改进

(1).用户输入 4 退出时,给出提示”你确定要退出吗? y / n " ,必须输入正确的 y / n 指令,否则循环输入,直到输入 y 或者 n 

(2).当没有任何收支明细时,提示”当前没有收支明细 … 来一笔吧!"

(3).在支出时,判断余额是否够,并给出相应的提示

package main

import (
    "fmt"
)

func main() {
    //声明一个变量,保存接收用户输入的选项
    key := ""
    //声明一个变量,控制是否退出for
    loop := true
    //定义账户余额
    balance := 10000.0
    //每次收支的金额
    money := 0.0
    //每次收支的说明
    note := ""
    //定义一个变量,记录是否有收支的行为
    flag := false
    //收支的详情使用字符串来记录
    //当有收支时,只需要对details进行拼接处理即可
    details := "收支\t账号余额\t收支金额\t说   明"
    //显示主菜单
    for {
        fmt.Println("\n----------------家庭收支记账软件------------------")
        fmt.Println("                1.收支明细")
        fmt.Println("                2.登记收入")
        fmt.Println("                3.登记支出")
        fmt.Println("                4.退出软件")
        fmt.Println("请选择(1~4):")
        fmt.Scanln(&key)

        switch key {
        case "1":
            fmt.Println("----------------当前收支明细------------------")
            if flag {
                fmt.Println(details)
            } else {
                fmt.Println("当前没有收支明细,来一笔")
            }
        case "2":
            fmt.Println("本次收入金额:")
            fmt.Scanln(&money)
            balance += money    //修改账户余额
            fmt.Println("本次收入说明:")
            fmt.Scanln(&note)
            //将这个收入情况,拼接到details变量
            //收入 11000 1000 有人发红包
            details += fmt.Sprintf("\n收入\t%v\t\t%v\t\t%v",balance, money, note)
            flag = true
        case "3":
            fmt.Println("本次支出金额:")
            fmt.Scanln(&money)
            //这里需要做一个判断
            if money > balance {
                fmt.Println("支出的余额不足")
                break
            }
            balance -= money    //修改账户余额
            fmt.Println("本次支出说明:")
            fmt.Scanln(&note)
            //将这个支出情况,拼接到details变量
            //支出 11000 1000 吃中午饭
            details += fmt.Sprintf("\n支出\t%v\t\t%v\t\t%v",balance, money, note)
            flag = true
        case "4":
            fmt.Println("你确定要退出吗? y/n")
            choice := ""
            for {
                fmt.Scanln(&choice)
                if choice == "y" || choice == "n" {
                    break
                }
                fmt.Println("你输入有误,请重新输入 y/n")  
            }
            if choice == "y" {
                loop = false
            }
        
        default :
            fmt.Println("请输入正确的选项")
        }

        if !loop {
            break
        }
    }

    fmt.Println("你退出了家庭收支记账软件的使用")
}

(4).将面向过程的代码修改成面向对象的方法,编写myFamilyAccount.go,并使用 testMyFamilyAccount.go 去完测试

思路分析:

        把记账软件的功能,封装到一个结构体中,然后调用该结构体的方法,来实现记账,显示明细。结构体的名字 FamilyAccount,在通过main方法中,创建一个结构体FamilyAccount实例,实现记账即可,码不需要重写,只需要重写组织一下

myFamilyAccount.go

package utils

import (
    "fmt"
)

type FamilyAccount struct {
    //声明必要的字段
    //声明一个字段,保存接收用户输入的选项
    key string
    //声明一个字段,控制是否退出for
    loop bool
    //定义账户余额
    balance float64
    //每次收支的金额
    money float64
    //每次收支的说明
    note string
    //定义一个字段,记录是否有收支的行为
    flag bool
    //收支的详情使用字符串来记录
    //当有收支时,只需要对details进行拼接处理即可
    details string
} 

//编写一个工厂模式的构造方法,返回一个*FamilyAccount实例
func NewFamilyAccount() *FamilyAccount  {
    return &FamilyAccount {
        key : "",
        loop : true,
        balance : 10000.0,
        money : 0.0,
        note : "",
        details : "收支\t账号余额\t收支金额\t说    明",
    }
}
//将显示明细写成一个方法
func (this *FamilyAccount) showDetails() {
    fmt.Println("----------------当前收支明细------------------")
    if this.flag {
        fmt.Println(this.details)
    } else {
        fmt.Println("当前没有收支明细,来一笔")
    }
}

//将登记收入写成一个方法,绑定到*FamilyAccount结构体
func (this *FamilyAccount) income()  {
    fmt.Println("本次收入金额:")
    fmt.Scanln(&this.money)
    this.balance += this.money  //修改账户余额
    fmt.Println("本次收入说明:")
    fmt.Scanln(&this.note)
    //将这个收入情况,拼接到details变量
    //收入 11000 1000 有人发红包
    this.details += fmt.Sprintf("\n收入\t%v\t\t%v\t\t%v", this.balance, this.money, this.note)
    this.flag = true
}

//将登记支出写成一个方法,绑定到*FamilyAccount结构体
func (this *FamilyAccount) pay()  {
    fmt.Println("本次支出金额:")
    fmt.Scanln(&this.money)
    //这里需要做一个判断
    if this.money > this.balance {
        fmt.Println("支出的余额不足")
    }
    this.balance -= this.money  //修改账户余额
    fmt.Println("本次支出说明:")
    fmt.Scanln(&this.note)
    //将这个支出情况,拼接到details变量
    //支出 11000 1000 吃中午饭
    this.details += fmt.Sprintf("\n支出\t%v\t\t%v\t\t%v", this.balance, this.money, this.note)
    this.flag = true
}

//将退出写成一个方法,绑定到*FamilyAccount结构体
func (this *FamilyAccount) exit()  {
    fmt.Println("你确定要退出吗? y/n")
    choice := ""
    for {
        fmt.Scanln(&choice)
        if choice == "y" || choice == "n" {
            break
        }
        fmt.Println("你输入有误,请重新输入 y/n")  
    }
    if choice == "y" {
        this.loop = false
    }
}

//给结构体绑定方法
//显示主菜单
func (this *FamilyAccount) MainMenu() {
    for {
        fmt.Println("\n----------------家庭收支记账软件------------------")
        fmt.Println("                1.收支明细")
        fmt.Println("                2.登记收入")
        fmt.Println("                3.登记支出")
        fmt.Println("                4.退出软件")
        fmt.Println("请选择(1~4):")
        fmt.Scanln(&this.key)

        switch this.key {
        case "1":
            this.showDetails()
        case "2":
            this.income()
        case "3":
            this.pay()
        case "4":
            this.exit()
        default :
            fmt.Println("请输入正确的选项") 
        }

        if !this.loop {
            break
        }
    }
    fmt.Println("你退出了家庭收支记账软件的使用")
}

main.go

package main

import (
    "fmt"
    "go_code/familyAccount/utils"
)

func main() {
    fmt.Println("面向对象方式实现")
    utils.NewFamilyAccount().MainMenu()
}

对项目的扩展功能:

        1.对上面的项目完成一个转账功能

        2.使用该软件前,有一个登录功能,只有输入正确的用户名,密码才能操作

 myFamilyAccount.go

package utils

import (
    "fmt"
)

type FamilyAccount struct {
    //声明必要的字段
    //声明一个字段,保存接收用户输入的选项
    key string
    //声明一个字段,控制是否退出for
    loop bool
    //定义账户余额
    balance float64
    //每次收支的金额
    money float64
    //每次收支的说明
    note string
    //定义一个字段,记录是否有收支的行为
    flag bool
    //收支的详情使用字符串来记录
    //当有收支时,只需要对details进行拼接处理即可
    details string

    //定义用户名
    name string
    //定义用户密码
    pwd string
} 

//编写一个工厂模式的构造方法,返回一个*FamilyAccount实例
func NewFamilyAccount() *FamilyAccount  {
    return &FamilyAccount {
        key : "",
        loop : true,
        balance : 10000.0,
        money : 0.0,
        note : "",
        details : "收支\t账号余额\t收支金额\t说    明",
    }
}

//将显示明细写成一个方法
func (this *FamilyAccount) showDetails() {
    fmt.Println("----------------当前收支明细------------------")
    if this.flag {
        fmt.Println(this.details)
    } else {
        fmt.Println("当前没有收支明细,来一笔")
    }
}

//将登记收入写成一个方法,绑定到*FamilyAccount结构体
func (this *FamilyAccount) income()  {
    fmt.Println("本次收入金额:")
    fmt.Scanln(&this.money)
    this.balance += this.money  //修改账户余额
    fmt.Println("本次收入说明:")
    fmt.Scanln(&this.note)
    //将这个收入情况,拼接到details变量
    //收入 11000 1000 有人发红包
    this.details += fmt.Sprintf("\n收入\t%v\t\t%v\t\t%v", this.balance, this.money, this.note)
    this.flag = true
}

//将登记支出写成一个方法,绑定到*FamilyAccount结构体
func (this *FamilyAccount) pay()  {
    fmt.Println("本次支出金额:")
    fmt.Scanln(&this.money)
    //这里需要做一个判断
    if this.money > this.balance {
        fmt.Println("支出的余额不足")
    }
    this.balance -= this.money  //修改账户余额
    fmt.Println("本次支出说明:")
    fmt.Scanln(&this.note)
    //将这个支出情况,拼接到details变量
    //支出 11000 1000 吃中午饭
    this.details += fmt.Sprintf("\n支出\t%v\t\t%v\t\t%v", this.balance, this.money, this.note)
    this.flag = true
}

//将退出写成一个方法,绑定到*FamilyAccount结构体
func (this *FamilyAccount) exit()  {
    fmt.Println("你确定要退出吗? y/n")
    choice := ""
    for {
        fmt.Scanln(&choice)
        if choice == "y" || choice == "n" {
            break
        }
        fmt.Println("你输入有误,请重新输入 y/n")  
    }
    if choice == "y" {
        this.loop = false
    }
}

//将判断用户登录写成一个方法,绑定到*FamilyAccount结构体
func (this *FamilyAccount) login() {
    for {
        fmt.Println("请输入用户名:")
        fmt.Scanln(&this.name)
        fmt.Println("请输入密码:")
        fmt.Scanln(&this.pwd)
        if this.name == "root" && this.pwd == "123456" {
            break 
        }
        fmt.Println("用户名或密码错误,请重新输入")
    }
}

//给结构体绑定方法
//显示主菜单
func (this *FamilyAccount) MainMenu() {
    this.login() 
    for {
        fmt.Println("\n----------------家庭收支记账软件------------------")
        fmt.Println("                1.收支明细")
        fmt.Println("                2.登记收入")
        fmt.Println("                3.登记支出")
        fmt.Println("                4.退出软件")
        fmt.Println("请选择(1~4):")
        fmt.Scanln(&this.key)

        switch this.key {
        case "1":
            this.showDetails()
        case "2":
            this.income()
        case "3":
            this.pay()
        case "4":
            this.exit()
        default :
            fmt.Println("请输入正确的选项")    
        }

        if !this.loop {
            break
        }
    }
    fmt.Println("你退出了家庭收支记账软件的使用")
}

[上一节]go学习笔记.第十章.面向对象编程] 12.类型断言引出和基本使用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/3716.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

刷题日记【第九篇】-笔试必刷题【杨辉三角的变形+计算某字符出现的次数+字符串通配符+统计每个月兔子的总数】

下列sql语句中哪条语句可为用户zhangsan分配数据库userdb表userinfo的查询和插入数据权限&#xff08;A&#xff09;。 常用的管理权限的命令为&#xff1a; grant select/insert/update/delete on 数据库名.表名 to 用户名‘该用户允许访问的ip’ 在oracle中&#xff0c;下面哪…

世界上只有一种共识算法,那就是Paxos

分布式系统原理系列目录 分布式系统的麻烦副本与一致性为什么需要一个分布式共识算法世界上只有一种共识算法&#xff0c;那就是PaxosCAP定理&#xff0c;说起来一句话&#xff0c;实际坑不少BASE&#xff0c;可用性高于强一致性分布式事务方案那么多&#xff0c;到底该选哪一…

计算机毕业设计(附源码)python智慧灭火器管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

大数据学习3.1 Hadoop环境准备

Hadoop环境Hadoop集群拓扑1、集群拓扑2、角色分配一、虚拟机安装二、虚拟机克隆1、克隆类型&#xff08;1&#xff09;完整克隆&#xff08;2&#xff09;链接克隆2、克隆步骤&#xff08;1&#xff09;克隆出master虚拟机&#xff08;2&#xff09;克隆出slave1虚拟机&#xf…

深入理解Linux文件描述符

>> Linux基础IO系列文章 1. Linux文件操作系统接口的学习使用 一、前言 在上一篇博客中&#xff0c;我们初步学习了Linux文件操作的系统接口&#xff0c;不难发现的是&#xff0c;这些系统函数都与文件描述符密切相关&#xff1a;open函数返回值是一个文件描述符&#…

Python编程挑战赛

题1&#xff1a;给小朋友分糖&#xff0c;每人分到糖的数量不同&#xff0c;输入小朋友的数量&#xff0c;计算至少需要多少糖&#xff1f; 思路&#xff1a;第1个小朋友1颗糖&#xff0c;第2个小朋友2颗糖&#xff0c;第3个小朋友3颗糖&#xff0c;……第n个小朋友n颗糖&#…

[数据结构]实现双向链表

作者&#xff1a; 华丞臧. 专栏&#xff1a;【数据结构】 各位读者老爷如果觉得博主写的不错&#xff0c;请诸位多多支持(点赞收藏关注)。如果有错误的地方&#xff0c;欢迎在评论区指出。 文章目录一、带头双向循环链表二、带头双向循环链表接口实现2.1 双向链表的初始化、打…

动态规划算法的题到底应该怎么做?思路教给你自己写

本文是我通过做题和借鉴一些前人总结的套路而得出的思路和方法&#xff0c;刚好这次CSDN第八周的周赛上出了三道动态规划的题目&#xff0c;我会结合题目对我的思路进行一个输出&#xff0c;会从最简单的一维dp开始讲解到二维dp&#xff0c;希望对你有帮助&#xff0c;有错误希…

MySQL数据库基础知识

今天是更新数据库的第一篇&#xff0c;关于数据库环境搭建问题博主先不在这里介绍了&#xff0c;博主今天是直接讲知识了&#xff0c;等以后的博客&#xff0c;博主再更新数据库搭建问题。在这里我们使用命令行式客户端&#xff0c;先不使用windows下的图形化界面&#xff0c;使…

ReadingTime-十一月

CV文章浅读_not_everday0x1105.CAViT for video object re-id 2022_中科院这个月主要是要学习pytorch和一些CV baseline的复现&#xff0c;搞搞毕设雏形&#x1f199; 以后还是把笔记写纸上要么写博客&#xff0c;不放本地了&#x1f628; 网页版小绿鲸zen好用 &#x1f603; …

峰会实录 | 基于StarRocks和腾讯云EMR构建云上Lakehouse

作者&#xff1a;腾讯云EMR业务负责人陈龙&#xff08;本文为作者在 StarRocks Summit Asia 2022 上的分享&#xff09; 我目前负责腾讯云EMR 的研发工作&#xff0c;此前先后在百度、支付宝做后端研发。2011年加入腾讯&#xff0c;先后参与了腾讯云Redis、腾讯云云数据库、Ap…

小米 Civi 2 (ziyi) 机型解锁bl 获取root权限教程 +其他机型参数对比+救砖

*********机型优点与其他机型参数对比***************** 小米 Civi 2 (ziyi) 国行版机型前置由3200万主摄3200万超广角组成的双摄是它最大的亮点&#xff0c;配有4颗柔光灯。自拍相当不错。他的后置主摄采用5000万像素相机&#xff0c;IMX766传感器&#xff0c;1/1.56英寸感光…

【MybatisPlus】CRUD操作,映射匹配兼容性,ID生成策略,逻辑删除,乐观锁

文章目录MybatisPlus简介一、数据层基本的开发1. 引入jar包2. 配置数据源3. 编写实体类4. 创建Dao接口5. 测试二、CRUD使用1. 查询2. 添加3. 删除4. 修改5. 分页查询三、条件查询1. 条件查询的方式2. 多条件查询四、映射匹配兼容性1. 表字段与编码属性设计不同步2. 编码中添加了…

矩阵理论复习(二)

内积空间的定义 模与内积 向量x和y的夹角 正交向量、正交组和正交矩阵 度量矩阵 基向量内积、度量矩阵、任意向量内积之间的关系 欧式空间的两个基对应的度量矩阵彼此合同 度量矩阵的行列式的几何问题 正交补子空间 内积空间子空间U与U的正交补子空间的直和 …

LeetCode 138. 复制带随机指针的链表

难度 中等 题目链接 示例&#xff1a; 解题思路&#xff1a; 首先&#xff0c;大家肯定会这样想&#xff1a;定义一个cur循环遍历&#xff0c;每次遍历一个&#xff0c;就malloc一个。 当遍历后面的时候&#xff0c;就开始尾插。 但现在有一个问题是&#xff1a;这个random指…

通信直放站基础知识

直放站的定义 直放站&#xff08;中继器&#xff09;属于同频放大设备&#xff0c;是指在无线通信传输过程中起到信号增强的一种无线电发射中转设备。直放站的基本功能就是一个射频信号功率增强器。直放站在下行链路中&#xff0c;由施主天线从现有的覆盖区域中拾取信号&#x…

《嵌入式 - 嵌入式大杂烩》CoreMark性能测试

1 CoreMark简介 CoreMark是由EEMBC(Embedded Microprocessor Benchmark Consortium)的Shay Gla-On于2009年提出的一项基准测试程序&#xff0c;CoreMark的主要目标是简化操作&#xff0c;并提供一套测试单核处理器核心的方法。测试标准是在配置参数的组合下单位时间内运行的Co…

【树莓派不吃灰系列】快速导航

目录1. 通用篇2. Python篇3. 编程IO篇❤️ 博客主页 单片机菜鸟哥&#xff0c;一个野生非专业硬件IOT爱好者 ❤️❤️ 本篇创建记录 2022-11-06 ❤️❤️ 本篇更新记录 2022-11-06 ❤️&#x1f389; 欢迎关注 &#x1f50e;点赞 &#x1f44d;收藏 ⭐️留言 &#x1f4dd;&…

Slave_IO_Running: No 的解决

原因&#xff1a; 两台主从数据库的uuid相同了&#xff08;没猜错的话&#xff0c;各位的第二台虚拟机都是克隆了第一台&#xff0c;然后就改了个ip对吧&#xff09;。 解决办法&#xff1a; 必须跟着步骤来&#xff0c;一步也不能多&#xff0c;更不能少&#xff0c;请仔细…

arcgis 生成切片并发布服务

需要准备&#xff1a; 1、需要进行切割的tif文件&#xff1b; 2、切片方案文件 需要确认&#xff1a; 1、tif文件的数据源坐标系&#xff1b; 2、现有切片方案能否满足需求&#xff1b; 3、部署的地图引擎是经纬度投影还是墨卡托投影&#xff1b; 具体操作流程&#xff1a; 1…