软件工程课设——学生财务管理系统源码

本项目是一款基于Java Swing的记账应用,具备新建、查询、统计等功能,通过图形界面方便用户进行日常收支管理。支持按日期、类型查询及统计,采用数据库存储数据。

本人小菜鸟一只~这是我大三下学期软件工程课设的项目,都是自己写的哦~答辩成绩A~

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.sql.*;
public class Account 
{
	JFrame frame=new JFrame("记账簿");
	JFrame jf=new JFrame("新建");
	JFrame jj=new JFrame("统计");
	JFrame jf1 =new JFrame("查询");
	JLabel jl=new JLabel("请输入日期(如2013-03-08)");
	JTextField jt=new JTextField(18);	    
	JButton jb=new JButton("确定");
	JLabel date=new JLabel("日期");
	JLabel item=new JLabel("项目");
	JLabel type=new JLabel("类型");
	JLabel type1=new JLabel("类型");
	JLabel  pay=new JLabel("支出");
	JLabel month=new JLabel("月份");
	JLabel year=new JLabel("年份");	
	JLabel year1=new JLabel("年份");
	JLabel a=new JLabel("年");
	JLabel b=new JLabel("月");
	JLabel c=new JLabel("日");
	
	JTextField jt1=new JTextField(18);
	JTextField jt2=new JTextField(18);
	JTextField jt3=new JTextField(18);
	JTextField jt4=new JTextField(18);
	Box  y=Box.createVerticalBox();
    Box x1=Box.createHorizontalBox();
    Box x2=Box.createHorizontalBox();
    Box x3=Box.createHorizontalBox();
    Box x4=Box.createHorizontalBox();
    Box x5=Box.createHorizontalBox();
	JButton ok=new JButton("确定");
	JButton ok1=new JButton("确定");
	JButton ok2=new JButton("确定");
	JButton add=new JButton("添加");
	JButton query=new JButton("查询");
	JButton sum=new JButton("统计");
	JButton back=new JButton("返回");
	JMenuBar menubar=new JMenuBar();
	JMenu file=new JMenu("文件");
	JMenu look=new JMenu("查看");
	JMenuItem create=new JMenuItem("新建");
	JMenuItem save1=new JMenuItem("保存");
	JMenuItem result=new JMenuItem("本月总支出");
	JMenuItem search=new JMenuItem("查询");
	private JScrollPane scrollPane;
	private ResultSetTableModel model;
	private ResultSet rs;
	private Connection conn;
	private Statement stmt;
	JPanel p=new JPanel();
	JPanel jp=new JPanel();
	private JComboBox<String> jc1=new JComboBox<>();
	private JComboBox<String> jc2=new JComboBox<>();
	private JComboBox<String> jc3=new JComboBox<>();
	private JComboBox<String> jc4=new JComboBox<>();
	private JComboBox<String> jc5=new JComboBox<>();
	private JComboBox<String> jc6=new JComboBox<>();
	private JComboBox<String> jc7=new JComboBox<>();
	private JComboBox<String> jc8=new JComboBox<>();
	private JComboBox<String> jc9=new JComboBox<>();
void init() throws ClassNotFoundException, IOException
{ 
	
	jc1.addItem("01");	
	jc1.addItem("02");	
	jc1.addItem("03");	
	jc1.addItem("04");	
	jc1.addItem("05");	
	jc1.addItem("06");	
	jc1.addItem("07");	
	jc1.addItem("08");	
	jc1.addItem("09");	
	jc1.addItem("10");	
	jc1.addItem("11");	
	jc1.addItem("12");	
	jc7.addItem("01");	
	jc7.addItem("02");	
	jc7.addItem("03");	
	jc7.addItem("04");	
	jc7.addItem("05");	
	jc7.addItem("06");	
	jc7.addItem("07");	
	jc7.addItem("08");	
	jc7.addItem("09");	
	jc7.addItem("10");	
	jc7.addItem("11");	
	jc7.addItem("12");	
	jc8.addItem("01");	
	jc8.addItem("02");	
	jc8.addItem("03");	
	jc8.addItem("04");	
	jc8.addItem("05");	
	jc8.addItem("06");	
	jc8.addItem("07");	
	jc8.addItem("08");	
	jc8.addItem("09");
	
	jc9.addItem("伙食饭费");	
	jc9.addItem("零食饮料");	
	jc9.addItem("学习用品");	
	jc9.addItem("娱乐活动");
	jc9.addItem("医疗保健");	
	jc9.addItem("网上购物");	
	jc9.addItem("服装鞋袜");	
	jc9.addItem("洗澡理发");
	jc3.addItem("合计");
	jc3.addItem("伙食饭费");	
	jc3.addItem("零食饮料");	
	jc3.addItem("学习用品");	
	jc3.addItem("娱乐活动");
	jc3.addItem("医疗保健");	
	jc3.addItem("网上购物");	
	jc3.addItem("服装鞋袜");	
	jc3.addItem("洗澡理发");
	jc4.addItem("合计");
	jc4.addItem("伙食饭费");	
	jc4.addItem("零食饮料");	
	jc4.addItem("学习用品");	
	jc4.addItem("娱乐活动");
	jc4.addItem("医疗保健");	
	jc4.addItem("网上购物");	
	jc4.addItem("服装鞋袜");	
	jc4.addItem("洗澡理发");
	for(int i=10;i<=31;i++)
	{
		jc8.addItem(String.valueOf(i));
	}
	for(int i=1949;i<=2013;i++)
	{
		jc2.addItem(String.valueOf(i));
	}
	for(int i=1949;i<=2013;i++)
	{
		jc5.addItem(String.valueOf(i));
	}
	for(int i=1949;i<=2013;i++)
	{
		jc6.addItem(String.valueOf(i));
	}
	
	show();
	jp.add(add);
	jp.add(query);
	jp.add(sum);
	jp.add(back);
	
	frame.add(jp,BorderLayout.NORTH);
	frame.pack();
	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	frame.setVisible(true);
	initFrame();

	add.addActionListener(new ActionListener()
	{
	  public void actionPerformed(ActionEvent e)
		{ 		  
		    Box  y=Box.createVerticalBox();
		    Box x1=Box.createHorizontalBox();
		    Box x2=Box.createHorizontalBox();
		    Box x3=Box.createHorizontalBox();
		    Box x4=Box.createHorizontalBox();
		    Box x5=Box.createHorizontalBox();
		    x1.add(date);
			x1.add(jc6);
			x1.add(a);
			x1.add(jc7);
			x1.add(b);
			x1.add(jc8);
			x1.add(c);
			x2.add(item);
			x2.add(jt2);
			x3.add(type);
			x3.add(jc9);
			x4.add(pay);
			x4.add(jt4);
			x5.add(ok);
			y.add(Box.createVerticalStrut(6));
			y.add(x1);
			y.add(Box.createVerticalStrut(16));
			y.add(x2);
			y.add(Box.createVerticalStrut(16));
			y.add(x3);
			y.add(Box.createVerticalStrut(16));
			y.add(x4);
			y.add(Box.createVerticalStrut(16));
			y.add(x5);
			y.add(Box.createVerticalStrut(16));
			jf.add(y);
			jf.pack();
			jf.setBounds(616, 288, 240, 236);
			jf.setVisible(true);
		}
	});
	ok.addActionListener(new ActionListener()
	{		
		 public void actionPerformed(ActionEvent e)
		 { 	
			
			String year=(String)jc6.getSelectedItem();
			String month=(String)jc7.getSelectedItem();
			String day=(String)jc8.getSelectedItem();
			String item=jt2.getText();			
			String type=(String)jc9.getSelectedItem();
			String cost=jt4.getText();
			
			
			
	  try{
		  if(item.equals(""))
		  {			
			  JOptionPane.showMessageDialog(frame, "项目不能 为空!请输入项目!");
			  
		  }
		  else if(cost.equals(""))
		  {
			  JOptionPane.showMessageDialog(frame,"支出不能为空!");	
			 
		  }
		  else if(!(cost.matches("^[0-9]+$")))
		  {
			  JOptionPane.showMessageDialog(frame,"支出必须为数字!");			  
			  jt4.setText("");
		  }
		  else
		  {
			  stmt.executeUpdate("insert into account"+
					  "(日期,项目,类型,支出) values"
					  +"('"+year+"-"+month+"-"+day+"','"+item+"','"+type+"','"+cost+"')");
			  JOptionPane.showMessageDialog(frame, "添加成功!");
		  }
		  try
		{
			// 如果装载JTable的JScrollPane不为空
			if (scrollPane != null)
			{
				// 从主窗口中删除表格
				frame.remove(scrollPane);
			}
			
			String query = "select * from account ";
			// 查询用户选择的数据表
			rs = stmt.executeQuery(query);
			
			// 使用查询到的ResultSet创建TableModel对象
			model = new ResultSetTableModel(rs);
		    rs.last();
			// 使用TableModel创建JTable,并将对应表格添加到窗口中
			JTable table = new JTable(model);
			scrollPane = new JScrollPane(table);
			
			frame.add(scrollPane, BorderLayout.CENTER);
			frame.validate();
			jf.setVisible(false);
			
		}
		catch (SQLException e2)
		{
			e2.printStackTrace();
		}
		
	  
	  }
      catch (SQLException e1)
		{
    	  //e1.printStackTrace();
    	  JOptionPane.showMessageDialog(frame,"添加失败,请检查输入!");	
    	   	
		}
	 }
		 
	});
    query.addActionListener(new ActionListener()
		{
		    public void actionPerformed(ActionEvent e)
			{		    	
		    	Box  y=Box.createVerticalBox();
			    Box x1=Box.createHorizontalBox();
			    Box x2=Box.createHorizontalBox();
			    x1.add(jl);
			    x1.add(jt);
			    x2.add(jb);
			    y.add(Box.createVerticalStrut(16));
			    y.add(x1);
			    y.add(Box.createVerticalStrut(16));
			    y.add(x2);
			    y.add(Box.createVerticalStrut(16));
			    jf1.add(y);
			    jf1.pack();
			    jf1.setVisible(true);		    
    	}

		});
    jb.addActionListener(new ActionListener()
    {
    	public void actionPerformed(ActionEvent e)
    	{
    		String date1=jt.getText();
    		jt.setText("");
    		jf1.setVisible(false);
	try	
	{
		
		// 如果装载JTable的JScrollPane不为空
		if (scrollPane != null)
		{
			// 从主窗口中删除表格
			frame.remove(scrollPane);
			
		}
		String query1 = "select * from account where 日期='"+date1+"'";
		
		
		// 查询用户选择的数据表
		ResultSet rst=stmt.executeQuery(query1);
		
		if(rst.next())
		{	
	    // 使用查询到的ResultSet创建TableModel对象
		
		model = new ResultSetTableModel(rst);
		
		JTable table = new JTable(model);
		scrollPane = new JScrollPane(table);
		
		frame.add(scrollPane, BorderLayout.CENTER);
		frame.validate();		
		}
		else
			{
				show();   
				JOptionPane.showMessageDialog(frame, "无查询结果!请输入有效日期!");
		    	
		    	Box  y=Box.createVerticalBox();
			    Box x1=Box.createHorizontalBox();
			    Box x2=Box.createHorizontalBox();
			    x1.add(jl);
			    x1.add(jt);
			    x2.add(jb);
			    y.add(Box.createVerticalStrut(16));
			    y.add(x1);
			    y.add(Box.createVerticalStrut(16));
			    y.add(x2);
			    y.add(Box.createVerticalStrut(16));
			    jf1.add(y);
			    jf1.pack();
			    jf1.setVisible(true);		
			}
			
	}
	catch (SQLException | ClassNotFoundException | IOException e3)
	{
		e3.printStackTrace();
		JOptionPane.showMessageDialog(frame, "请重新输入!");
		
	}
    	}
    });
    sum.addActionListener(new ActionListener()
	{
		public void actionPerformed(ActionEvent e)
		{
			Box  y=Box.createVerticalBox();
		    Box x1=Box.createHorizontalBox();
		    Box x2=Box.createHorizontalBox();		   
		    x1.add(year1);
		    x1.add(Box.createHorizontalStrut(10));
		    x1.add(jc5);
		    x1.add(Box.createHorizontalStrut(10));
		    x1.add(month);
		    x1.add(Box.createHorizontalStrut(10));
		    x1.add(jc1);
		    x1.add(Box.createHorizontalStrut(10));
		    x1.add(type);
		    x1.add(Box.createHorizontalStrut(10));
		    x1.add(jc3);
		    x1.add(Box.createHorizontalStrut(10));
		    x1.add(ok1);
		    x1.add(Box.createHorizontalStrut(10));
		    x2.add(year);
		    x2.add(Box.createHorizontalStrut(10));
		    x2.add(jc2);
		    x2.add(Box.createHorizontalStrut(10));
		    x2.add(type1);
		    x2.add(Box.createHorizontalStrut(10));
		    x2.add(jc4);
		    x2.add(Box.createHorizontalStrut(10));
		    x2.add(ok2);
		    x2.add(Box.createHorizontalStrut(10));
			y.add(Box.createVerticalStrut(16));
			y.add(x1);
			y.add(Box.createVerticalStrut(16));
			y.add(x2);
			y.add(Box.createVerticalStrut(16));
			jj.add(y);
			jj.setVisible(true);
			jj.pack();
			
		}
		});
    ok1.addActionListener(new ActionListener()
    {
    	public void actionPerformed(ActionEvent e)
    	{
    		try
    		{
    			String year=(String)jc5.getSelectedItem();
    			String month=(String)jc1.getSelectedItem();
    			String type=(String)jc3.getSelectedItem();
    			// 如果装载JTable的JScrollPane不为空
    			if (scrollPane != null)
    			{
    				// 从主窗口中删除表格
    				frame.remove(scrollPane);
    			}
    			String query1;
    			String query2="select * from account where 日期  like'"+year+"-"+month+"%'";
				if(type=="合计")
    			    query1="select sum(支出) 共消费(元)  from account where 日期  like'"+year+"-"+month+"%' ";
    			else 
    				query1 = "select sum(支出) 共消费(元)  from account where 日期  like'"+year+"-"+month+"%' and 类型='"+type+"'";
    			

    			// 查询用户选择的数据表
				ResultSet rstt=stmt.executeQuery(query2);
    			
    			if(!rstt.next())
           		JOptionPane.showMessageDialog(frame, "无查询结果!");
    			ResultSet rst=stmt.executeQuery(query1);
    			// 使用查询到的ResultSet创建TableModel对象
    			model = new ResultSetTableModel(rst);
    			
    			JTable table = new JTable(model);
    			scrollPane = new JScrollPane(table);
    			
    			frame.add(scrollPane, BorderLayout.CENTER);
    			frame.validate();
    		}
    		catch (SQLException e3)
    		{
    			e3.printStackTrace();
    		}
        	}
    	});
    ok2.addActionListener(new ActionListener()
    {
    	public void actionPerformed(ActionEvent e)
    	{
    		try
    		{
    			String year=(String)jc2.getSelectedItem();
    			
    			String type=(String)jc4.getSelectedItem();
    			// 如果装载JTable的JScrollPane不为空
    			if (scrollPane != null)
    			{
    				// 从主窗口中删除表格
    				frame.remove(scrollPane);
    			}
    			String query1;
    			
    			String query3="select * from account where 日期  like'"+year+"%' ";
				if(type=="合计")
    			    query1="select sum(支出) 共消费(元)  from account where 日期  like'"+year+"%'";
    			else 
    				query1 = "select sum(支出) 共消费(元) from account where 日期  like'"+year+"%' and 类型='"+type+"'";

    			// 查询用户选择的数据表
              
    			ResultSet rstp=stmt.executeQuery(query3);  
    			if(!rstp.next())
               		JOptionPane.showMessageDialog(frame, "无查询结果!");
    			ResultSet rst=stmt.executeQuery(query1);
    			
    			// 使用查询到的ResultSet创建TableModel对象
    			model = new ResultSetTableModel(rst);
    			
    			JTable table = new JTable(model);
    			scrollPane = new JScrollPane(table);
    			
    			frame.add(scrollPane, BorderLayout.CENTER);
    			frame.validate();
    		}
    		catch (SQLException e3)
    		{
    			e3.printStackTrace();
    		}
    	}
    });
    back.addActionListener(new ActionListener()
    {
    	public void actionPerformed(ActionEvent e)
    	{
    		try 
    		{
				show();
			} 
    		catch (ClassNotFoundException e1) 
    		{
				e1.printStackTrace();
			} 
    		catch (IOException e1) 
    		{				
				e1.printStackTrace();
			}
    	}
    });
	frame.addWindowListener(new WindowAdapter()
	{
		public void windowClosing(WindowEvent event)
		{
			try
			{
				if (conn != null) conn.close();
			}
			catch (SQLException e)
			{
				e.printStackTrace();
			}
		}
	});
	frame.pack();
	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	frame.setVisible(true);
}


public void show() throws ClassNotFoundException, IOException
{
	try
	{
		// 如果装载JTable的JScrollPane不为空
		if (scrollPane != null)
		{
			// 从主窗口中删除表格
			frame.remove(scrollPane);
		}
		
		// 如果结果集不为空,则关闭结果集
		if (rs != null)
		{
			rs.close();
		}
		String query = "select * from account";
		// 获取数据库连接
		conn = JDBC.getConnection();
		
				// 创建Statement
				stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE
					, ResultSet.CONCUR_UPDATABLE);
		// 查询用户选择的数据表
		rs = stmt.executeQuery(query);
		// 使用查询到的ResultSet创建TableModel对象
		model = new ResultSetTableModel(rs);
		
		// 使用TableModel创建JTable,并将对应表格添加到窗口中
		JTable table = new JTable(model);
		scrollPane = new JScrollPane(table);
		
		frame.add(scrollPane, BorderLayout.CENTER);
		frame.validate();
	}
	catch (SQLException e)
	{
		e.printStackTrace();
	}
}
public void initFrame()
         {    
			JLabel jlpic = new JLabel(); 
			ImageIcon icon = new ImageIcon("D:\\scenery.jpg");   
			icon.setImage(icon.getImage().getScaledInstance(icon.getIconWidth(),   
			icon.getIconHeight(), Image.SCALE_DEFAULT));              
			jlpic.setBounds(0, 0, 100, 100);   
			jlpic.setHorizontalAlignment(0);   
			jlpic.setIcon(icon);   
			frame.setSize(1366, 888);   
			frame.add(jlpic,BorderLayout.SOUTH);   
          
         }  
public static void main(String[] args) throws Exception
{
	new LoginFrame().initial();
}
}



import java.sql.*;
import java.io.*;
import java.util.*;
class JDBC 
{
	
    static Connection getConnection()
		throws SQLException, IOException , ClassNotFoundException
	{
		
		Properties props = new Properties();
		FileInputStream in = new FileInputStream("account.ini");
		props.load(in);
		in.close();
		String driver=props.getProperty("driver");
		String url = props.getProperty("url");
		String user = props.getProperty("user");
		String pass = props.getProperty("pass");
		// 加载数据库驱动
		Class.forName(driver);
		// 取得数据库连接
		return DriverManager.getConnection(url, user, pass);
	}
}

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.sql.*;

public class LoginFrame 
{	
	// 登录界面的GUI组件
	private JFrame jf = new JFrame("登录");
	private JLabel use = new JLabel("账户");
	private JLabel pas = new JLabel("密码");
	private JTextField userField = new JTextField(20);
	private JPasswordField passField = new JPasswordField(20);
	private JButton loginButton = new JButton("登录");
public void initial()throws Exception
{
	
	// 为登录按钮添加事件监听器
	loginButton.addActionListener(new ActionListener()
	{
		@SuppressWarnings("deprecation")
		public void actionPerformed(ActionEvent e)
		{
			// 登录成功则显示"登录成功"
			if (validate(userField.getText(), passField.getText()))
			{
				try 
				{
					new Account().init();
				} 
				catch (ClassNotFoundException e1) 
				{
					e1.printStackTrace();
				} 
				catch (IOException e1) 
				{
					e1.printStackTrace();
				}
				jf.setVisible(false);
				
			}
			// 否则显示"登录失败"
			else
			{
				JOptionPane.showMessageDialog(jf, "账号或密码错误,请重新登录");
			}
		}
	});
	char ch=new Character('*');
	passField.setEchoChar(ch);
	JPanel p=new JPanel();
	p.add(use);
	p.add(userField);
	JPanel pp=new JPanel();
	pp.add(pas);
	pp.add(passField);
	jf.add(p , BorderLayout.NORTH);
	jf.add(pp);
	jf.add(loginButton , BorderLayout.SOUTH);
	jf.pack();
	jf.setVisible(true);
	
}


private boolean validate(String userName, String userPass)
{
try(
	Connection conn = JDBC.getConnection();
	PreparedStatement pstmt = conn.prepareStatement(
		"select * from id where id=? and pass=?"))
{
	pstmt.setString(1, userName);
	pstmt.setString(2, userPass);
	try(
		ResultSet rs = pstmt.executeQuery())
	{
		//如果查询的ResultSet里有超过一条的记录,则登录成功
		if (rs.next())
		{
			return true;
		}
	}
}
catch(Exception e)
{
	e.printStackTrace();
}
return false;

}

}

import javax.swing.table.*;

import java.sql.*;



@SuppressWarnings("serial")
class ResultSetTableModel extends AbstractTableModel {
	
	
	private ResultSet rs;
	private ResultSetMetaData rsmd;
	// 构造器,初始化rs和rsmd两个属性
	public ResultSetTableModel(ResultSet aResultSet)
	{
		rs = aResultSet;
		try
		{
			rsmd = rs.getMetaData();
		}
		catch (SQLException e)
		{
			e.printStackTrace();
		}
	}
	// 重写getColumnName方法,用于为该TableModel设置列名
	public String getColumnName(int c)
	{
		try
		{
			return rsmd.getColumnName(c + 1);
		}
		catch (SQLException e)
		{
			e.printStackTrace();
			return "";
		}
	}
	// 重写getColumnCount方法,用于设置该TableModel的列数
	public int getColumnCount()
	{
		try
		{
			return rsmd.getColumnCount();
		}
		catch (SQLException e)
		{
			e.printStackTrace();
			return 0;
		}
	}
	// 重写getValueAt方法,用于设置该TableModel指定单元格的值
	public Object getValueAt(int r, int c)
	{
		try
		{
			rs.absolute(r + 1);
			return rs.getObject(c + 1);
		}
		catch(SQLException e)
		{
			e.printStackTrace();
			return null;
		}
	}
	// 重写getColumnCount方法,用于设置该TableModel的行数
	public int getRowCount()
	{
		try
		{
			rs.last();
			return rs.getRow();
		}
		catch(SQLException e)
		{
			e.printStackTrace();
			return 0;
		}
	}
	// 重写isCellEditable返回true,让每个单元格可编辑
	public boolean isCellEditable(int rowIndex, int columnIndex)
	{
		return true;
	}
	// 重写setValueAt()方法,当用户编辑单元格时,将会触发该方法
	public void setValueAt(Object aValue , int row,int column)
	{
		try
		{
			// 结果集定位到对应的行数
			rs.absolute(row + 1);
			// 修改单元格多对应的值
			rs.updateObject(column + 1 , aValue);
			// 提交修改
			rs.updateRow();
			// 触发单元格的修改事件
			fireTableCellUpdated(row, column);
		}
		catch (SQLException evt)
		{
			evt.printStackTrace();
		}
	}
}

第一章 A可行性研究报告 1 引言 2 可行性研究的前提 3 对现有系统的分析 4所建议的系统…………………………………………………… 5 5投资及效益分析………………………………………………… 6 6社会因素方面的可行性…………………………………………… 6 7结论……………………………………………………………… 7 第二章 B需求分析说明书 ……………………………………… 7 1 引言 …………………………………………………………… 7 2系统概述 ……………………………………………………… 7 3需求规定………………………………………………………… 8 第三章 C概要计说明书………………………………………… 9 1引言……………………………………………………………… 9 2总体计………………………………………………………… 10 3接口计………………………………………………………… 10 4数据结构计……………………………………………………… 11 5数据字典………………………………………………………… 12 6系统安全………………………………………………………… 13 第四章 D详细计说明书…………………………………………13 1引言……………………………………………………………… 13 2程序系统结构…………………………………………………… 14 3管理系统其中的3个模块的详细计………………………… 15 4程序(标识符)计说明……………………………………… 22 第五章 E测试分析报告………………………………………… 27 1引言……………………………………………………………… 27 2测试概要………………………………………………………… 28 3测试结果及发现………………………………………………… 28 4测试计划………………………………………………………… 28 5对软件功能的结论……………………………………………… 29 6分析摘要………………………………………………………… 29
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值