首页 > 其他分享 >团队项目冲刺-day2

团队项目冲刺-day2

时间:2024-11-17 19:07:04浏览次数:1  
标签:timi binding day2 冲刺 private fun import 团队 com

每天举行站立式会议

昨天已完成的工作

成员 任务
徐嘉炜 组织会议,说明项目进度,指导项目发展
陈祥意 参与会议,简要讲述应用程序测试的各个模块
林楦 参与会议,讲述有关功能界面的UI开发
陈大锴 参与会议,协调开发技术与实际需求,记录需求
蔡家显 参与会议,讲述测试时的注意事项
陈祖民 参与会议,讲述有关登录界面的UI开发
肖商 参与会议,详细讲述测试模块的测试用例

今天计划完成的工作

成员 任务
徐嘉炜 开发登录界面交互逻辑
陈祥意 测试网络API
林楦 开发注册UI界面
陈大锴 开发注册界面交互逻辑
蔡家显 汇总测试记录
陈祖民 开发登录UI界面
肖商 生成各个测试模块的测试案例

工作中遇到的困难

UI界面与交互逻辑开发需要同步,所以需要UI组付出比较大的努力。

项目燃尽图

适当的项目程序/模块的最新(运行)截图

最新模块的代码

package com.timi.music

import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContentView(R.layout.activity_main)
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
            insets
        }
    }
}






package com.timi.music

import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.View.OnClickListener
import android.view.ViewGroup
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.NavController
import androidx.navigation.Navigation
import com.google.android.material.snackbar.Snackbar
import com.timi.music.databinding.FragmentLoginBinding
import com.timi.utils.Logger
import com.timi.utils.isClickEffective
import com.timi.utils.makeToast


class LoginFragment : Fragment(), OnClickListener {

    companion object{
        private const val TAG = "LoginFragment"
    }
    private lateinit var binding: FragmentLoginBinding
    private lateinit var navController: NavController
    private val loginViewModel: LoginViewModel by lazy {
        ViewModelProvider(this)[LoginViewModel::class.java]
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragmentLoginBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        navController = Navigation.findNavController(view)

        observeChange()
        initListener()
        if (Logger.currentLevel < 5){
            binding.btnLoginFragmentTest.visibility = View.GONE
        }
    }

    /**
     * 检测LoginViewModel中变量的变化
     */
    private fun observeChange(){
        loginViewModel.apply {
            //验证码发送返回结果
            captchaCode.observe(viewLifecycleOwner){
                if (it != 0){
                    if (it == 200){
                        Logger.i(TAG, "登录验证码发送成功.")
                        makeToast("验证码发送成功!")
                    }else{
                        Logger.i(TAG, "验证码发送失败.")
                        makeToast("验证码发送失败!请检查你的手机号是否正确!")
                    }
                    captchaCode.value = 0   //重置变量
                }
            }
            //游客登陆返回结果
            touristData.observe(viewLifecycleOwner){
                it?.apply {
                   if (this.code == 200){
                       //登录后跳转至主程序
                       Logger.i(TAG, "游客登陆成功.")
                       makeToast("游客登陆成功!")
                       //携带cookie跳转至CentreActivity
                       startActivity(Intent(context, CentreActivity::class.java).apply {
                           //toString防止cookie为null引发空指针异常
                           putExtra("cookie", cookie.toString())
                       })
                   }else{
                       Logger.w(TAG, "游客登陆失败.")
                       makeToast("游客登陆失败")
                   }
                   touristData.value = null
                }
            }

        }
    }

    private fun initListener(){
        binding.apply {
            btnLoginFragmentLogin.setOnClickListener(this@LoginFragment)
            btnLoginFragmentRegister.setOnClickListener(this@LoginFragment)
            btnLoginFragmentSendCode.setOnClickListener(this@LoginFragment)
            btnLoginFragmentTouristLogin.setOnClickListener(this@LoginFragment)
            binding.btnLoginFragmentTest.setOnClickListener(this@LoginFragment)
        }
    }

    override fun onClick(v: View?) {
        when(v){
            binding.btnLoginFragmentLogin -> {
                if (checkInput()){
//                    if (tryLogin()){
//
//                    }
                }
            }
            binding.btnLoginFragmentRegister -> navController.navigate(R.id.action_loginFragment_to_registerFragment)
            binding.btnLoginFragmentSendCode -> getCode()
            binding.btnLoginFragmentTouristLogin -> {
                if (v.isClickEffective()) loginViewModel.touristLoginRequest()
            }
            binding.btnLoginFragmentTest -> {
                if (v.isClickEffective()){
                    startActivity(Intent(context, CentreActivity::class.java).apply {
                        putExtra("cookie", "")
                    })
                }
            }
        }
    }

    private fun getCode(){
        if (binding.edtLoginFragmentPhoneNumber.text.length != 11){
            //如果输入格式不满足要求,无法获取验证码
            makeToast("请输入11位手机号!")
        }else{
            loginViewModel.codeRequest(binding.edtLoginFragmentPhoneNumber.text.toString())
        }
    }

    private fun checkInput(): Boolean{
        return if (binding.edtLoginFragmentPhoneNumber.text.toString().isNotEmpty()){
            if (binding.edtLoginFragmentCode.text.toString().isNotEmpty()){
                true
            }else{
                Snackbar.make(requireView(), "请输入验证码!", Snackbar.LENGTH_SHORT).show()
                false
            }
        }else{
            Snackbar.make(requireView(), "请输入手机号!", Snackbar.LENGTH_SHORT).show()
            false
        }
    }

//    private fun tryLogin(): Boolean{
//
//    }
}




package com.timi.music


import com.timi.music.bean.Captcha
import com.timi.music.bean.CaptchaService
import com.timi.music.bean.Tourist
import com.timi.music.bean.TouristService
import com.timi.utils.Logger
import com.timi.utils.ServiceBuilder
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response

class LoginModel {

    private val TAG = "LoginModel"

    /**
     * 发出获取验证码请求
     */
    fun codeRequest(
        loginVM: LoginViewModel,
        phoneNumber: String
    ){
        val captchaService = ServiceBuilder.create(CaptchaService::class.java)
        captchaService.getCaptchaData(phoneNumber).enqueue(object : Callback {
            override fun onResponse(call: Call, response: Response) {
                response.body()?.apply {
                    Logger.i(TAG, "注册验证码请求:$this")
                    loginVM.captchaCode.value = this.code
                }
            }
            override fun onFailure(call: Call, t: Throwable) {
                t.printStackTrace()
            }
        })
    }

    /**
     * 进行游客登陆
     */
    fun touristLoginRequest(loginVM: LoginViewModel){
        val touristService = ServiceBuilder.create(TouristService::class.java)
        touristService.getTouristData().enqueue(object : Callback{
            override fun onResponse(call: Call, response: Response) {
                response.body()?.apply {
                    Logger.i(TAG, "游客登陆请求:$this")
                    loginVM.touristData.value = this
                }
            }
            override fun onFailure(call: Call, t: Throwable) {
                t.printStackTrace()
            }
        })
    }
}




package com.timi.music

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.timi.music.bean.Tourist

class LoginViewModel: ViewModel() {

    private val TAG = "LoginViewModel"
    private val loginModel: LoginModel by lazy { LoginModel() }

    val captchaCode = MutableLiveData()        //验证码发送返回结果
    val touristData = MutableLiveData<tourist?>()        //游客登陆返回结果

    init {
        captchaCode.value = 0
        touristData.value = null
    }

    /**
     * 发出获取验证码请求
     */
    fun codeRequest(phoneNumber: String){
        loginModel.codeRequest(this, phoneNumber)
    }

    fun touristLoginRequest(){
        loginModel.touristLoginRequest(this)
    }
}




package com.timi.music

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.View.OnClickListener
import android.view.ViewGroup
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.NavController
import androidx.navigation.Navigation
import com.timi.music.databinding.FragmentRegisterBinding
import com.timi.utils.Logger
import com.timi.utils.makeToast


class RegisterFragment : Fragment(), OnClickListener{

    companion object {
        private const val TAG = "RegisterFragment"
    }

    private lateinit var binding: FragmentRegisterBinding
    private lateinit var navigationController: NavController
    private val registerViewModel: RegisterViewModel by lazy {
        ViewModelProvider(this)[RegisterViewModel::class.java]
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragmentRegisterBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        navigationController = Navigation.findNavController(view)

        observeChange()
        initListener()
    }

    /**
     * 检测RegisterViewModel中变量的变化
     */
    private fun observeChange(){
        registerViewModel.apply {
            captchaCode.observe(viewLifecycleOwner){
                if (it != 0){
                    if (it == 200){
                        Logger.i(TAG, "注册验证码发送成功.")
                        makeToast("验证码发送成功!")
                    }else{
                        Logger.i(TAG, "验证码发送失败.")
                        makeToast("验证码发送失败!请检查你的手机号是否正确!")
                    }
                    captchaCode.value = 0   //重置变量
                }
            }
        }
    }

    private fun initListener(){
        binding.ivRegisterFragmentBack.setOnClickListener(this)
        binding.btnRegisterFragmentGetCode.setOnClickListener(this)
    }

    override fun onClick(v: View?) {
        when(v){
            binding.ivRegisterFragmentBack -> navigationController.navigateUp() //返回到LoginFragment
            binding.btnRegisterFragmentGetCode -> getCode()     //请求发送注册验证码
        }
    }

    /**
     * 获取手机验证码
     */
    private fun getCode(){
        if (binding.edtRegisterFragmentPhoneNumber.text.length != 11){
            //如果输入格式不满足要求,无法获取验证码
            makeToast("请输入11位手机号!")
        }else{
            registerViewModel.codeRequest(binding.edtRegisterFragmentPhoneNumber.text.toString())
        }
    }
}




package com.timi.music

import android.util.Log
import com.timi.music.bean.Captcha
import com.timi.music.bean.CaptchaService
import com.timi.utils.ServiceBuilder
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response

class RegisterModel {

    private val TAG = "RegisterModel"

    /**
     * 发出获取验证码请求
     */
    fun codeRequest(
        registerVM: RegisterViewModel,
        phoneNumber: String
    ){
        val captchaService = ServiceBuilder.create(CaptchaService::class.java)
        captchaService.getCaptchaData(phoneNumber).enqueue(object : Callback{
            override fun onFailure(call: Call, t: Throwable) {
                t.printStackTrace()
            }
            override fun onResponse(call: Call, response: Response) {
                response.body()?.apply {
                    Log.i(TAG, "注册验证码请求:${this}")
                    registerVM.captchaCode.value = this.code
                }
            }
        })
    }
}




package com.timi.music

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel

class RegisterViewModel: ViewModel() {
    private val registerModel: RegisterModel by lazy { RegisterModel() }

    val captchaCode = MutableLiveData()        //验证码发送返回的结果

    init {
        captchaCode.value = 0
    }

    /**
     * 发出获取验证码请求
     */
    fun codeRequest(phoneNumber: String){
        registerModel.codeRequest(this, phoneNumber)
    }
}

运行结果的截图


每日每人总结

成员 总结
徐嘉炜 登录注册模块已经做得比较完善,团队各个小组都发挥了各自的优势
陈祥意 测试模块已经全部通过,可以进行下一个模块的测试
林楦 基础的UI界面已经定好,可以在不改变数据对象的前提下继续美化UI界面
陈大锴 代码在逻辑上基本没有问题,也说是有一点成就,希望下一个模块的开发也顺顺利利。
蔡家显 在测试的方式上,可以写一些自动化脚本进行测试,但是手写测试案例还是有用的,希望能够学到更多的测试方法
陈祖民 UI界面的交互比较简洁明了,是一个有点,可以往简约风格方面发展,期待主功能界面的UI界面开发
肖商 测试用例发送和接收的报文均为有效报文,测试成功的喜悦促使着我们进一步开发下一个模块

标签:timi,binding,day2,冲刺,private,fun,import,团队,com
From: https://www.cnblogs.com/CuteDucK/p/18550926

相关文章

  • 实习冲刺练习 第二十三天
    每日一题回文链表.-力扣(LeetCode)classSolution{public:boolisPalindrome(ListNode*head){if(head==nullptr)returnfalse;vector<int>v;while(head!=nullptr){//将链表的值存入数组中v.push_back(head->val);......
  • Scrum 冲刺博客-day2
    一、每天会议昨天完成的任务与今天计划完成任务成员昨天已完成任务今天计划完成任务董雯霖组织会议,确立各自工作用户注册页面陈金星参会,发表意见用户登录页面邱列圻参会,发表意见用户模块的接口开发李嘉远参会,发表意见页面测试詹洛熙参会,发表意见......
  • 第4篇Scrum冲刺博客
    1.站立式会议1.1会议照片1.2会议内容昨天已完成的工作:已初步完成主界面设计和数据库编写记录今天计划完成的工作项目模块需要实现的功能负责人预计用时数据库模块数据库记录的备份、恢复和退出王伊若2h主界面模块账目记录的增删改功能及界面王伊若6h......
  • Python学习从0到1 day28 Python 高阶技巧 ⑥ Socket服务端开发
    我们终将上岸,阳光万里                        ——24.11.13一、Socketsocket(简称套接字)是进程之间通信一个工具,好比现实生活中的插座,所有的家用电器要想工作都是基于插座进行。进程之间想要进行网络通信需要socket。Socket负责进程之间的网......
  • 团队项目4——项目冲刺-7
    每日站立式会议昨天已完成的工作:杨睿:完成住户物业报修页面木萨江:完成住户车位查询页面巴音才次克:对接车位管理接口李佳聪:测试报修相关接口今天计划完成的工作:杨睿:对接人员管理接口木萨江:处理物业报修模块bug巴音才次克:处理车位查询模块bug李佳聪:......
  • 爱码单车队-冲刺集合
    冲刺集合:日志名称日期当天完成工作量(一个量化指标)剩余工作量已完成工作量占总工作量百分比冲刺日志1(https://www.cnblogs.com/aaaauv/p/18550348)2024-11-1152516.67%冲刺日志2(https://www.cnblogs.com/aaaauv/p/18550688)2024-11-12101550.00%冲刺日志3......
  • 第二篇Scrum冲刺博客
    1站立式会议1.1会议照片1.2会议内容昨天已完成的工作:已明确分配的任务,并进行了环境配置,特别是mysql的配置.今天计划完成的工作项目模块需要实现的功能负责人预计用时初始化模块环境搭建王伊若4h登录模块用户注册、登录黄锐7h登录模块数据库连接......
  • 冲刺计划
    总结与反思回顾之前的团队任务,我们小组已经完成了SpeakwithAI的原型设计,以及各个UML图设计,同时还完成了数据库的部署,之前的任务大家分工明确,执行起来有条不紊,最终将每一环节都简洁高效地呈现在大家面前,这是大家做的好的地方,值得表扬,但是接下来我们将具体实现所有功能以及测试......
  • 爱码单车队-冲刺计划第六天
    会议记录:第一次测试应用的时候到了,出乎意料的是,前后端在已做好的功能性测试上,并没有出现太大的瑕疵,主要是页面太简洁,让整体的交互设计看上去十分简陋,前端美观这点还是需要加强;相比之下,在测试中,后端没有出现明显问题,只有数据库开发设计这点还需要微做调整,其他的功能实现的很......
  • 爱码单车队-冲刺日志第三天
    会议记录:下面是我们的前端页面效果展示图在第三天,团队在前端界面搭建方面取得了显著进展。使用Vue框架搭建的登录页面和主页界面基本完成,登录页面包含手机号注册和微信登录选项,主页界面框架涵盖个人信息、场景选择等模块。然而,目前仍存在一些不足,几个前端设计部分分隔开,还......