日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

『Java课设』JavaSwing+MySQL实现医院智慧点餐系统

發(fā)布時(shí)間:2024/1/8 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 『Java课设』JavaSwing+MySQL实现医院智慧点餐系统 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

👨?🎓作者簡(jiǎn)介:一位喜歡寫作,計(jì)科專業(yè)大三菜鳥

🏡個(gè)人主頁(yè):starry陸離

如果文章有幫到你的話記得點(diǎn)贊👍+收藏💗支持一下哦

『Java課設(shè)』JavaSwing+MySQL實(shí)現(xiàn)醫(yī)院智慧點(diǎn)餐系統(tǒng)

  • 1.功能介紹
  • 2.項(xiàng)目包結(jié)構(gòu)
  • 3.數(shù)據(jù)庫(kù)設(shè)計(jì)
  • 4.JDBC數(shù)據(jù)庫(kù)連接類
  • 5.登錄選擇界面(系統(tǒng)入口)
  • 6.管理員頁(yè)面
  • 7.用戶選餐界面

1.功能介紹

這個(gè)是大二的Java的課程設(shè)計(jì)的完整版,功能相對(duì)之前發(fā)的半成品稍稍豐富些。一開始我們還是按照MVC結(jié)構(gòu)寫的,寫著寫著就視圖,用戶操作邏輯,數(shù)據(jù)庫(kù)數(shù)據(jù)操作就都寫在一起了,比如管理員操作界面(View層)就嵌入了SQL語(yǔ)句直接操作數(shù)據(jù)庫(kù)了,好在是一個(gè)學(xué)習(xí)過程。

  • 系統(tǒng)角色分為用戶與管理員

  • 用戶登錄系統(tǒng)可以選購(gòu)餐品并支付

  • 管理員可以登陸系統(tǒng)管理所有的菜品(增刪改查)

  • 管理所有的訂單信息(未完成)

  • 2.項(xiàng)目包結(jié)構(gòu)

    3.數(shù)據(jù)庫(kù)設(shè)計(jì)

    數(shù)據(jù)庫(kù)設(shè)計(jì)了5個(gè)表,分別是用戶信息表,管理員信息表,菜品信息表,訂單信息表,訂單詳情表

    4.JDBC數(shù)據(jù)庫(kù)連接類

    不同數(shù)據(jù)庫(kù)的連接方式的大同小異,根據(jù)開發(fā)場(chǎng)景靈活變動(dòng)就好,我這里用的MySQL8.0所以使用如下兩行配置。

    private static final String USER = "root";//數(shù)據(jù)庫(kù)用戶名,一般是rootprivate static final String PWD = "lx0411";//數(shù)據(jù)庫(kù)密碼 // 連接mysql5.7 // private static final String URL="jdbc:mysql://localhost:3306/studentgrade"; // private static final String DRIVER="com.mysql.jdbc.Driver"; //mysql5.7 // 如果用的是mysql8.0,private static final String DRIVER="com.mysql.cj.jdbc.Driver";private static final String URL= "jdbc:mysql://localhost:3306/catersystem?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true"; // 如果用的sqlServer數(shù)據(jù)庫(kù)連接 // private static final String URL="jdbc:sqlserver://localhost:1433;DataBaseName=StudentGrade"; // private static final String DRIVER="com.microsoft.sqlserver.jdbc.SQLServerDriver"; // private static final String USER="sa"; // private static final String PWD="lxloveth0411";

    5.登錄選擇界面(系統(tǒng)入口)

    package view;import java.awt.AWTException; import java.awt.Dimension; import java.awt.Font; import java.awt.GridLayout; import java.awt.SystemTray; import java.awt.TrayIcon; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.net.URL;import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel;import handler.LoginChoiceHandler;public class LoginChoiceView extends JFrame{/*** */private static final long serialVersionUID = 1L;JLabel titleNameLabel=new JLabel("醫(yī)院智慧選餐系統(tǒng)",JLabel.CENTER);JPanel jp1=new JPanel();JPanel jp2=new JPanel(new GridLayout(5,1));JButton userBtn=new JButton ("用戶 登錄");JButton adminBtn=new JButton("管理員登錄");//聲明桌面系統(tǒng)托盤SystemTraypublic SystemTray systemTray;public TrayIcon trayIcon;LoginChoiceHandler loginChoiceHandler;public LoginChoiceView() {super("醫(yī)院智慧選餐系統(tǒng)");loginChoiceHandler=new LoginChoiceHandler(this);//設(shè)置標(biāo)題的字體,格式,大小titleNameLabel.setFont(new Font("華文行楷",Font.PLAIN,40));titleNameLabel.setPreferredSize(new Dimension(0,80));Font centerFont=new Font("楷體",Font.PLAIN,20);userBtn.setFont(centerFont);adminBtn.setFont(centerFont);jp1.add(userBtn);jp1.add(new JPanel());jp1.add(adminBtn);jp2.add(new JPanel());jp2.add(titleNameLabel);jp2.add(new JPanel());jp2.add(jp1);jp2.add(new JPanel());this.add(jp2);userBtn.addActionListener(loginChoiceHandler);adminBtn.addActionListener(loginChoiceHandler);//判斷當(dāng)前系統(tǒng)是否支持系統(tǒng)托盤if(SystemTray.isSupported()){systemTray=SystemTray.getSystemTray();//初始化系統(tǒng)托盤URL imgUrl = UserLoginView.class.getClassLoader().getResource("LoginView.jpg");trayIcon=new TrayIcon(new ImageIcon(imgUrl).getImage());//初始化托盤圖標(biāo)trayIcon.setImageAutoSize(true);//托盤圖標(biāo)可以自動(dòng)縮放大小try {systemTray.add(trayIcon);//將托盤圖標(biāo)加入到系統(tǒng)托盤組件中,并拋出異常} catch (AWTException e) {e.printStackTrace();}//創(chuàng)建一個(gè)事件響應(yīng),最小化時(shí)銷毀資源this.addWindowListener(new WindowAdapter() {@Overridepublic void windowIconified(WindowEvent e) {LoginChoiceView.this.dispose();}});//托盤事件監(jiān)聽(鼠標(biāo)單擊一次托盤,窗口將會(huì)正常顯示)trayIcon.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {int clickCont=e.getClickCount();if(clickCont==1){LoginChoiceView.this.setExtendedState(JFrame.NORMAL);}LoginChoiceView.this.setVisible(true);}});}//設(shè)置窗口圖片URL imgUrl=UserLoginView.class.getClassLoader().getResource("LoginView.jpg");setIconImage(new ImageIcon(imgUrl).getImage());//設(shè)置窗口基本參數(shù)setSize(600,400);setDefaultCloseOperation(EXIT_ON_CLOSE);setLocationRelativeTo(null);setResizable(false);setVisible(true);}public static void main(String[] args) {// TODO Auto-generated method stubnew LoginChoiceView();}}

    6.管理員頁(yè)面

    package view;import javax.swing.*;import ext.MainViewTable; import ext.MainViewTableModel; import handler.AdminMainHandler; import req.UserRequest; import res.TableDTO; import service.FoodService; import service.FoodServiceImpl; import util.DBUtil; import util.DimensionUtil;import java.awt.*; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.Vector;public class AdminOperateFrame extends JFrame {/*** */private static final long serialVersionUID = 1L;String adminName;String adminId;public String lastPressKey;JLabel adminNameLabel = new JLabel("管理員名:", JLabel.CENTER);JPanel centerPanel = new JPanel(new BorderLayout());JPanel panel1 = new JPanel();JPanel panel2 = new JPanel();JPanel panel3 = new JPanel();JPanel panel4 = new JPanel();//增刪改查按鈕public JButton btnAdd = new JButton("增加菜品");public JButton btnSave = new JButton("保存菜品");JButton btnDelete = new JButton("刪除菜品");JButton btnAlter = new JButton("更改菜品");JButton btnSearch_Food = new JButton("查看菜品");//JButton btnSearch_Order = new JButton("查看訂單");//設(shè)置字體大小Font font=new Font("楷體",Font.PLAIN,20);Dimension dimension = new Dimension(130,30);//創(chuàng)建一個(gè)MainViewTable對(duì)象public MainViewTable mianViewTable=new MainViewTable();public MainViewTableModel mainViewTableModel;//創(chuàng)建一個(gè)MainOrderTable訂單table對(duì)象public MainViewTable mianOrderTable=new MainViewTable();public MainViewTableModel mainOrderTableModel;//聲明一個(gè)MainHandler對(duì)象AdminMainHandler adminMainHandler;private int pageNow=1;//默認(rèn)顯示第一頁(yè)private int pageSize=10;//默認(rèn)每頁(yè)顯示十條記錄//搜索框與搜索按鈕public JTextField searchField = new JTextField();JButton searchBt = new JButton("搜索");JButton exitBt = new JButton("退出");public AdminOperateFrame(String adminId) {setTitle("醫(yī)院營(yíng)養(yǎng)配餐系統(tǒng)");this.adminId=adminId;adminMainHandler = new AdminMainHandler(this);layNorth(adminId);layCenter();layEast();laySouth();centerPanel.add(panel1, BorderLayout.NORTH);centerPanel.add(panel2, BorderLayout.CENTER);centerPanel.add(panel3, BorderLayout.EAST);centerPanel.add(panel4, BorderLayout.SOUTH);add(centerPanel);init();}private void init() {setSize(600, 400);setLocationRelativeTo(null);setBounds(DimensionUtil.getBounds());//設(shè)置窗體完全充滿整個(gè)屏幕setExtendedState(JFrame.MAXIMIZED_BOTH);setDefaultCloseOperation(EXIT_ON_CLOSE);setVisible(true);}private void laySouth() {exitBt.setFont(font);exitBt.setPreferredSize(new Dimension(200,50));panel4.add(exitBt);exitBt.addActionListener(adminMainHandler);}private void layEast() {panel3.setLayout(new FlowLayout());panel3.setPreferredSize(new Dimension(200,100));btnAdd.setFont(font);btnAdd.setPreferredSize(dimension);btnSave.setFont(font);btnSave.setPreferredSize(dimension);btnDelete.setFont(font);btnDelete.setPreferredSize(dimension);btnAlter.setFont(font);btnAlter.setPreferredSize(dimension);btnSearch_Food.setFont(font);btnSearch_Food.setPreferredSize(dimension);//btnSearch_Order.setFont(font);//btnSearch_Order.setPreferredSize(dimension);panel3.add(btnAdd);panel3.add(btnSave);btnSave.setVisible(false);panel3.add(btnDelete);panel3.add(btnAlter);panel3.add(btnSearch_Food);//panel3.add(btnSearch_Order);btnAdd.addActionListener(adminMainHandler);btnSave.addActionListener(adminMainHandler);btnDelete.addActionListener(adminMainHandler);btnAlter.addActionListener(adminMainHandler);btnSearch_Food.addActionListener(adminMainHandler);//btnSearch_Order.addActionListener(adminMainHandler);}private void layNorth(String adminId) {panel1.setLayout(new BorderLayout());selectAdminName(adminId);adminNameLabel.setText("管理員名:"+adminName);adminNameLabel.setFont(font);searchField.setFont(font);searchField.setPreferredSize(dimension);searchBt.setFont(font);searchBt.setPreferredSize(new Dimension(200,50));panel1.add(adminNameLabel, BorderLayout.WEST);panel1.add(searchField, BorderLayout.CENTER);panel1.add(searchBt, BorderLayout.EAST);searchBt.addActionListener(adminMainHandler);}private void layCenter() {//調(diào)用數(shù)據(jù)庫(kù)數(shù)據(jù),創(chuàng)建一個(gè)FoodService和UserRequest實(shí)例//獲取從數(shù)據(jù)庫(kù)中查詢到的data與totalCountFoodService foodService=new FoodServiceImpl();UserRequest request=new UserRequest();request.setPageNow(pageNow);request.setPageSize(pageSize);request.setSearchKey(searchField.getText().trim());TableDTO tableDTO = foodService.retrieveFoods(request);Vector<Vector<Object>> data = tableDTO.getData();//自定義的MainViewTableModelmainViewTableModel=MainViewTableModel.assembleModel(data);//將Table與TableModel關(guān)聯(lián)mianViewTable.setModel(mainViewTableModel);//設(shè)置渲染方式mianViewTable.renderRule();JScrollPane jScrollPane = new JScrollPane(mianViewTable);panel2.setLayout(new BorderLayout());panel2.add(jScrollPane, BorderLayout.CENTER);}private void selectAdminName(String adminId) {String sql = "select manaName from managerInfo where manaId = ?";Connection conn=null;PreparedStatement ps=null;ResultSet rs=null;try {//連接數(shù)據(jù)庫(kù),獲取數(shù)據(jù)庫(kù)連接,getConn()方法已經(jīng)提前在DBUtil中寫好conn = DBUtil.getConn();System.out.println("數(shù)據(jù)庫(kù)連接成功");//如果連接失敗,則返回falseif(conn==null) {System.out.println("數(shù)據(jù)庫(kù)連接失敗");}ps = conn.prepareStatement(sql);ps.setString(1, adminId);rs = ps.executeQuery();//查詢遍歷while(rs.next()) {adminName = rs.getString(1);}} catch (Exception e) {e.printStackTrace();}finally {//關(guān)閉資源DBUtil.closeRs(rs);DBUtil.closeConn(conn);DBUtil.closePs(ps);}}public void setPageNow(int pageNow) {this.pageNow = pageNow;}public int getPageSize() {return pageSize;}public void setPageSize(int pageSize) {this.pageSize = pageSize;}public int getPageNow() {return pageNow;}public void reloadTable() {/**調(diào)用數(shù)據(jù)庫(kù)數(shù)據(jù),創(chuàng)建一個(gè)FoodService和UserRequest實(shí)例*獲取從數(shù)據(jù)庫(kù)中查詢到的data與totalCount*查詢完后要更新Model的數(shù)據(jù)*/FoodService foodService=new FoodServiceImpl();UserRequest request=new UserRequest();request.setPageNow(pageNow);request.setPageSize(pageSize);request.setSearchKey(searchField.getText().trim());TableDTO tableDTO = foodService.retrieveFoods(request);Vector<Vector<Object>> data = tableDTO.getData();// 更新調(diào)用updataModel實(shí)現(xiàn)更新ModelMainViewTableModel.uptadaModel(data);// 設(shè)置渲染方式mianViewTable.renderRule();}public static void main(String[] args) {new AdminOperateFrame("202016");} }

    7.用戶選餐界面

    室友在這里做了一個(gè)有趣的處理,點(diǎn)擊支付的時(shí)候彈出他的微信收款碼😁。如果用戶想白嫖不支付就退出系統(tǒng)還會(huì)有窗口提示(當(dāng)然并不是真正的需要支付money才能退出系統(tǒng),你任務(wù)管理器一殺我們也沒轍,只是考慮了這個(gè)場(chǎng)景就實(shí)現(xiàn)了這個(gè)邏輯)

    package view; /** 待解決問題:* 1.關(guān)閉窗口提示還沒支付* 2.同一用戶可以選同一個(gè)菜品* 3.list沒有實(shí)現(xiàn)更新* 4.table里的庫(kù)存量沒有實(shí)現(xiàn)更新* 5.沒有選餐應(yīng)提示不能實(shí)現(xiàn)支付*/ import javax.swing.*;import ext.MainViewTable; import ext.MainViewTableModel; import handler.UserMainHandler; import req.UserRequest; import res.TableDTO; import service.FoodService; import service.FoodServiceImpl; import util.DBUtil; import util.DimensionUtil;import java.awt.*;import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.Vector;public class UserSelectionFrame extends JFrame {/*** */private static final long serialVersionUID = 1L;public String userName;public int totalMoney;public int selId = 1;public String userId;JLabel userNameLabel = new JLabel("用戶名:", JLabel.CENTER);JPanel centerPanel = new JPanel(new BorderLayout());JPanel panel1 = new JPanel();JPanel panel2 = new JPanel();JPanel panel3 = new JPanel();JPanel panel4 = new JPanel();JPanel panel5 = new JPanel();//創(chuàng)建一個(gè)MainViewTable對(duì)象public MainViewTable mianViewTable=new MainViewTable();public MainViewTableModel mainViewTableModel;//聲明一個(gè)MainHandler對(duì)象UserMainHandler userMainHandler;private int pageNow=1;//默認(rèn)顯示第一頁(yè)private int pageSize=10;//默認(rèn)每頁(yè)顯示十條記錄JButton btSelect = new JButton("選購(gòu)");//搜索框與搜索按鈕Font centerFont=new Font("楷體",Font.PLAIN,20);Dimension dimension = new Dimension(200,50);JTextField searchField = new JTextField();JButton searchBt = new JButton("搜索");public DefaultListModel<Object> listModel = new DefaultListModel<Object>();public JList<Object> selectedList = new JList<Object>(listModel);JLabel selectedLabel = new JLabel("已選菜品:",JLabel.CENTER);public JLabel totalPriceLabel = new JLabel("總價(jià): 0");JButton payBt = new JButton("支付");public UserSelectionFrame(String userId) {setTitle("醫(yī)院營(yíng)養(yǎng)配餐系統(tǒng)");this.userId = userId;userMainHandler = new UserMainHandler(this);//根據(jù)用戶Id查詢出用戶名userName,顯示在userNameLabel上selectUesrName(userId);layNorth();layCenter();layWest();laySouth();init();}private void selectUesrName(String userId) {String sql = "select userName from userInfo where userId = ?";Connection conn=null;PreparedStatement ps=null;ResultSet rs=null;try {//連接數(shù)據(jù)庫(kù),獲取數(shù)據(jù)庫(kù)連接,getConn()方法已經(jīng)提前在DBUtil中寫好conn = DBUtil.getConn();System.out.println("數(shù)據(jù)庫(kù)連接成功");//如果連接失敗,則返回falseif(conn==null) {System.out.println("數(shù)據(jù)庫(kù)連接失敗");}ps = conn.prepareStatement(sql);ps.setString(1, userId);rs = ps.executeQuery();//查詢遍歷while(rs.next()) {userName = rs.getString(1);}} catch (Exception e) {e.printStackTrace();}finally {//關(guān)閉資源DBUtil.closeRs(rs);DBUtil.closeConn(conn);DBUtil.closePs(ps);}}private void init() {add(centerPanel);setSize(600, 400);setLocationRelativeTo(null);setBounds(DimensionUtil.getBounds());//設(shè)置窗體完全充滿整個(gè)屏幕setExtendedState(JFrame.MAXIMIZED_BOTH);setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);//在關(guān)閉窗口的時(shí)候強(qiáng)制支付,應(yīng)該改成提示“暫時(shí)還沒支付”addWindowListener(new UserMainHandler(this));setVisible(true);}private void layNorth() {panel1.setLayout(new BorderLayout());userNameLabel.setText("用戶名:"+userName);panel1.add(userNameLabel, BorderLayout.WEST);userNameLabel.setPreferredSize(dimension);userNameLabel.setFont(centerFont);panel1.add(searchField, BorderLayout.CENTER);searchField.setPreferredSize(dimension);searchField.setFont(centerFont);panel1.add(searchBt, BorderLayout.EAST);searchBt.setPreferredSize(new Dimension(200,50));searchBt.setFont(centerFont);centerPanel.add(panel1, BorderLayout.NORTH);searchBt.addActionListener(userMainHandler);}private void layCenter() {//調(diào)用數(shù)據(jù)庫(kù)數(shù)據(jù),創(chuàng)建一個(gè)FoodService和UserRequest實(shí)例//獲取從數(shù)據(jù)庫(kù)中查詢到的data與totalCountFoodService foodService=new FoodServiceImpl();UserRequest request=new UserRequest();request.setPageNow(pageNow);request.setPageSize(pageSize);request.setSearchKey(searchField.getText().trim());TableDTO tableDTO = foodService.retrieveFoods(request);Vector<Vector<Object>> data = tableDTO.getData();showPreNext(tableDTO.getTotalCount());panel2.setLayout(new BorderLayout());//自定義的MainViewTableModelmainViewTableModel=MainViewTableModel.assembleModel(data);//將Table與TableModel關(guān)聯(lián)mianViewTable.setModel(mainViewTableModel);//設(shè)置渲染方式mianViewTable.renderRule();JScrollPane jScrollPane = new JScrollPane(mianViewTable);panel2.add(jScrollPane,BorderLayout.CENTER);btSelect.setPreferredSize(new Dimension(150,50));btSelect.setFont(centerFont);panel5.add(btSelect);panel2.add(panel5, BorderLayout.EAST);centerPanel.add(panel2, BorderLayout.CENTER);btSelect.addActionListener(userMainHandler);}private void layWest() {panel3.setLayout(new BorderLayout());selectedList.setPreferredSize(dimension);selectedList.setFont(centerFont);panel3.add(selectedLabel, BorderLayout.NORTH);selectedLabel.setPreferredSize(dimension);selectedLabel.setFont(centerFont);panel3.add(selectedList, BorderLayout.CENTER);centerPanel.add(panel3, BorderLayout.WEST);}private void laySouth() {totalPriceLabel.setFont(centerFont);panel4.add(totalPriceLabel);payBt.setFont(centerFont);panel4.add(payBt);centerPanel.add(panel4, BorderLayout.SOUTH);payBt.addActionListener(userMainHandler);}private void showPreNext(int totalCount) {if(totalCount%pageSize==0) {}else {}}public void setPageNow(int pageNow) {this.pageNow = pageNow;}public int getPageSize() {return pageSize;}public void setPageSize(int pageSize) {this.pageSize = pageSize;}public int getPageNow() {return pageNow;}public void reloadTable() {/**調(diào)用數(shù)據(jù)庫(kù)數(shù)據(jù),創(chuàng)建一個(gè)FoodService和UserRequest實(shí)例*獲取從數(shù)據(jù)庫(kù)中查詢到的data與totalCount*查詢完后要更新Model的數(shù)據(jù)*/FoodService foodService=new FoodServiceImpl();UserRequest request=new UserRequest();request.setPageNow(pageNow);request.setPageSize(pageSize);request.setSearchKey(searchField.getText().trim());TableDTO tableDTO = foodService.retrieveFoods(request);Vector<Vector<Object>> data = tableDTO.getData();// 更新調(diào)用updataModel實(shí)現(xiàn)更新ModelMainViewTableModel.uptadaModel(data);// 設(shè)置渲染方式mianViewTable.renderRule();// 調(diào)用上一頁(yè)與下一頁(yè)按鈕是否可見showPreNext(tableDTO.getTotalCount());} }{return pageNow;}public void reloadTable() {/**調(diào)用數(shù)據(jù)庫(kù)數(shù)據(jù),創(chuàng)建一個(gè)FoodService和UserRequest實(shí)例*獲取從數(shù)據(jù)庫(kù)中查詢到的data與totalCount*查詢完后要更新Model的數(shù)據(jù)*/FoodService foodService=new FoodServiceImpl();UserRequest request=new UserRequest();request.setPageNow(pageNow);request.setPageSize(pageSize);request.setSearchKey(searchField.getText().trim());TableDTO tableDTO = foodService.retrieveFoods(request);Vector<Vector<Object>> data = tableDTO.getData();// 更新調(diào)用updataModel實(shí)現(xiàn)更新ModelMainViewTableModel.uptadaModel(data);// 設(shè)置渲染方式mianViewTable.renderRule();// 調(diào)用上一頁(yè)與下一頁(yè)按鈕是否可見showPreNext(tableDTO.getTotalCount());} }

    總結(jié)

    以上是生活随笔為你收集整理的『Java课设』JavaSwing+MySQL实现医院智慧点餐系统的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。