三层架构的开发(转)

       r_%e4%b8%89%e5%b1%82%e6%a8%a1%e5%bc%8f.jpg
         对于B/S架构的三层架构的开发,可能很多的人都已经了解的是比较清楚的。这里用的是最简单的三层架构: ui+bll+dal+dbsqlhelp+model 
         从VS05出来以后由于功能明显比VS03夸张了很多,所以在开发的时候也就很方便。其中以数据的显示最为明显。通过sqldatasource可以几乎一行代码都不需要写,就能在GridView中显示出来数据,并且进行增删查改的操作,但是我个人总感觉这样做是有问题的。因为使用sqldatasource,就明显的破坏了3层架构的基本改变。哪么微软在VS05当中,很重点的推出了 objectdatasource这个东西,就是专门用来结合三层架构开发的一个数据源绑定控件。 在层次之间传递的也是object,这样相对来说就比较好一些。
         代码在具体的下边,其实主要就是DataList稍微麻烦一点,别的几个控件都可以自动 实现增删查改的功能,所以基本没什么写太多的代码。!
         在这里主要是DataList的代码,以操作Jobs表为示例。
DbSqlHelp
None.gifusing System;
None.gif
using System.Collections.Generic;
None.gif
using System.Text;
None.gif
using System.Data;
None.gif
using System.Data.SqlClient;
None.gif
namespace DbSqlHelp
ExpandedBlockStart.gifContractedBlock.gifdot.gif
dot.gif{
InBlock.gif    
public abstract class DbSqlHelp
ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif
dot.gif{
InBlock.gif        
static string StrConn = @"User ID=sa;Password=perishryu;Initial Catalog=pubs;Data Source=OATHRYUSQL2005";
InBlock.gif        
static SqlDataAdapter da;
InBlock.gif        
static SqlCommand cmd;
InBlock.gif        
static SqlConnection conn;
InBlock.gif        
static DataSet ds;
InBlock.gif
InBlock.gif        
public static  DataSet Search(string sql)
ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif
dot.gif{
InBlock.gif            
using (da = new SqlDataAdapter(sql, StrConn))
ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif
dot.gif{
InBlock.gif                
using (ds = new DataSet())
ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif
dot.gif{
InBlock.gif                    da.Fill(ds);
InBlock.gif                    
return ds;
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
public static bool Make(string sql)
ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif
dot.gif{
InBlock.gif            
using (conn = new SqlConnection(StrConn))
ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif
dot.gif{
InBlock.gif                
using (cmd = new SqlCommand(sql, conn))
ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif
dot.gif{
InBlock.gif                    
if (conn.State != ConnectionState.Closed)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    dot.gif
dot.gif{
InBlock.gif                        conn.Close();
ExpandedSubBlockEnd.gif                    }

InBlock.gif                    
try
ExpandedSubBlockStart.gifContractedSubBlock.gif                    dot.gif
dot.gif{
InBlock.gif                        conn.Open();
InBlock.gif                        cmd.ExecuteNonQuery();
InBlock.gif                        
return false;
ExpandedSubBlockEnd.gif                    }

InBlock.gif                    
catch(System.Exception ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    dot.gif
dot.gif{
InBlock.gif                        
throw ex;
ExpandedSubBlockEnd.gif                    }

InBlock.gif                    
finally
ExpandedSubBlockStart.gifContractedSubBlock.gif                    dot.gif
dot.gif{
InBlock.gif                        conn.Close();
ExpandedSubBlockEnd.gif                    }

ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

Model
None.gifusing  System;
None.gif
using
 System.Collections.Generic;
None.gif
using
 System.Text;
None.gif
None.gif
namespace
 Model
ExpandedBlockStart.gifContractedBlock.gifdot.gif
dot.gif
{
InBlock.gif    
public class
 Job_Model
ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif
dot.gif
{
InBlock.gif        
public
 Job_Model()
ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif
dot.gif
{
ExpandedSubBlockEnd.gif                       }

InBlock.gif        
public Job_Model(int id, string desc, int min, int max)
ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif
dot.gif
{
InBlock.gif            
this.job_desc =
 desc;
InBlock.gif            
this.job_id =
 id;
InBlock.gif            
this.min_lvl =
 min;
InBlock.gif            
this.max_lvl =
 max;
ExpandedSubBlockEnd.gif                       }

InBlock.gif        
int job_id;
InBlock.gif
InBlock.gif        
public int
 Job_id
ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif
dot.gif
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get dot.gifdot.gifreturn job_id; }

ExpandedSubBlockStart.gifContractedSubBlock.gif            
set dot.gifdot.gif{ job_id = value; }
ExpandedSubBlockEnd.gif                       }

InBlock.gif        
string job_desc;
InBlock.gif
InBlock.gif        
public string
 Job_desc
ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif
dot.gif
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get dot.gifdot.gifreturn job_desc; }

ExpandedSubBlockStart.gifContractedSubBlock.gif            
set dot.gifdot.gif{ job_desc = value; }
ExpandedSubBlockEnd.gif                       }

InBlock.gif        
int min_lvl;
InBlock.gif
InBlock.gif        
public int
 Min_lvl
ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif
dot.gif
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get dot.gifdot.gifreturn min_lvl; }

ExpandedSubBlockStart.gifContractedSubBlock.gif            
set dot.gifdot.gif{ min_lvl = value; }
ExpandedSubBlockEnd.gif                       }

InBlock.gif        
int max_lvl;
InBlock.gif
InBlock.gif        
public int
 Max_lvl
ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif
dot.gif
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get dot.gifdot.gifreturn max_lvl; }

ExpandedSubBlockStart.gifContractedSubBlock.gif            
set dot.gifdot.gif{ max_lvl = value; }
ExpandedSubBlockEnd.gif                       }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif


DAL
None.gifusing System;
None.gif
using System.Collections.Generic;
None.gif
using System.Text;
None.gif
using System.Data;
None.gif
namespace DAL
ExpandedBlockStart.gifContractedBlock.gifdot.gif
dot.gif{
InBlock.gif    
public class Job_DAL
ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif
dot.gif{
InBlock.gif        
string sql;
InBlock.gif        
public DataSet Select_Job_Dal(string jobid)
ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif
dot.gif{
InBlock.gif            sql 
= "select * from jobs where job_id='" +jobid + "'";
InBlock.gif            
return DbSqlHelp.DbSqlHelp.Search(sql);
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif        
public DataSet Select_Job_Dal()
ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif
dot.gif{
InBlock.gif            sql 
= "select * from jobs";
InBlock.gif            
return DbSqlHelp.DbSqlHelp.Search(sql);
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public bool Update_Job_Dal(Model.Job_Model job)
ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif
dot.gif{
InBlock.gif            sql 
= "update jobs set job_desc='" + job.Job_desc + "',min_lvl='" + job.Min_lvl + "',max_lvl='" + job.Max_lvl + "' where job_id='" + job.Job_id + "'";
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif
dot.gif{
InBlock.gif                
return DbSqlHelp.DbSqlHelp.Make(sql);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch(System.Exception ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif
dot.gif{
InBlock.gif                
throw ex;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
public bool Insert_Job_Dal(Model.Job_Model job)
ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif
dot.gif{
InBlock.gif            sql 
= "insert into jobs values('" + job.Job_desc + "','" + job.Min_lvl + "','" + job.Max_lvl + "')";
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif
dot.gif{
InBlock.gif                
return DbSqlHelp.DbSqlHelp.Make(sql);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch (System.Exception ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif
dot.gif{
InBlock.gif                
throw ex;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
ExpandedSubBlockEnd.gif        }

InBlock.gif        
public bool Delete_Job_Dal(Model.Job_Model job)
ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif
dot.gif{
InBlock.gif            sql 
= "delete from jobs where job_id='" + job.Job_id + "'";
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif
dot.gif{
InBlock.gif                
return DbSqlHelp.DbSqlHelp.Make(sql);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch (System.Exception ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif
dot.gif{
InBlock.gif                
throw ex;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

BLL

None.gif using  System;
None.gif
using  System.Collections.Generic;
None.gif
using  System.Text;
None.gif
using  System.Data;
None.gif
namespace  BLL
ExpandedBlockStart.gifContractedBlock.gifdot.gif
dot.gif {
InBlock.gif    
public class Job_BLL
ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif
dot.gif{
InBlock.gif        DAL.Job_DAL jobdal;
InBlock.gif        
public DataSet Select_BLL()
ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif
dot.gif{
InBlock.gif            jobdal 
= new DAL.Job_DAL();
ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif
dot.gif{
InBlock.gif                
return jobdal.Select_Job_Dal();
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
public DataSet Select_BLL(string jobid)
ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif
dot.gif{
InBlock.gif            jobdal 
= new DAL.Job_DAL();
ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif
dot.gif{
InBlock.gif                
return jobdal.Select_Job_Dal(jobid);
ExpandedSubBlockEnd.gif            }

InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif        
public bool Update_BLL(Model.Job_Model job)
ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif
dot.gif{
InBlock.gif            jobdal 
= new DAL.Job_DAL();
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif
dot.gif{
InBlock.gif                
return jobdal.Update_Job_Dal(job);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch (System.Exception ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif
dot.gif{
InBlock.gif                
throw ex;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
public bool Insert_BLL(Model.Job_Model job)
ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif
dot.gif{
InBlock.gif            jobdal 
= new DAL.Job_DAL();
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif
dot.gif{
InBlock.gif                
return jobdal.Insert_Job_Dal(job);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch(System.Exception ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif
dot.gif{
InBlock.gif                
throw ex;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
public bool Delete_BLL(Model.Job_Model job)
ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif
dot.gif{
InBlock.gif            jobdal 
= new DAL.Job_DAL();
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif
dot.gif{
InBlock.gif                
return jobdal.Delete_Job_Dal(job);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch(System.Exception ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif
dot.gif{
InBlock.gif                
throw ex;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif


UI   aspx页面
ExpandedBlockStart.gifContractedBlock.gif<%dot.gif@ Page Language="C#" AutoEventWireup="true" CodeFile="DataListDemo.aspx.cs" Inherits="DataListDemo" %>
None.gif
None.gif
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
None.gif
None.gif
<html xmlns="http://www.w3.org/1999/xhtml" >
None.gif
<head runat="server">
None.gif    
<title>无标题页</title>
None.gif
</head>
None.gif
<body>
None.gif    
<form id="form1" runat="server">
None.gif    
<div>
None.gif        
<asp:DataList ID="DataList1" runat="server" DataSourceID="ObjectDataSource1" RepeatColumns="4" RepeatDirection="Horizontal" Width="720px" DataKeyField="job_id" OnCancelCommand="DataList1_CancelCommand" OnEditCommand="DataList1_EditCommand" OnUpdateCommand="DataList1_UpdateCommand" OnDeleteCommand="DataList1_DeleteCommand">
None.gif            
<ItemTemplate>
None.gif                job_id:
<asp:Literal ID="Literal1" runat="server" Text='<%#Eval("job_id") %>'></asp:Literal><br />
None.gif                job_desc:
<asp:Literal ID="Literal2" runat="server" Text='<%#Eval("job_desc") %>'></asp:Literal><br />
None.gif                min_lvl:
<asp:Literal ID="Literal3" runat="server" Text='<%#Eval("min_lvl") %>'></asp:Literal><br />
None.gif                max_lvl:
<asp:Literal ID="Literal4" runat="server" Text='<%#Eval("max_lvl") %>'></asp:Literal><br />
None.gif                
<asp:LinkButton ID="LinkButton1" runat="server" CommandName="Edit">编辑</asp:LinkButton>&nbsp;&nbsp;&nbsp;&nbsp;
None.gif                
<asp:LinkButton ID="LinkButton2" runat="server" CommandName="delete">删除</asp:LinkButton>
None.gif            
</ItemTemplate>
None.gif            
<EditItemTemplate>
None.gif                job_id:
<asp:Literal ID="Literal1" runat="server" Text='<%#Eval("job_id") %>'></asp:Literal><br />
None.gif                job_desc:
<asp:TextBox ID="TextBox1" runat="server" Text='<%#Bind("job_desc") %>'></asp:TextBox><br />
None.gif                min_lvl:
<asp:TextBox ID="TextBox2" runat="server" Text='<%#Bind("min_lvl") %>'></asp:TextBox><br />
None.gif                max_lvl:
<asp:TextBox ID="TextBox3" runat="server" Text='<%#Bind("max_lvl") %>'></asp:TextBox><br />
None.gif                
<asp:LinkButton ID="LinkButton3" runat="server" CommandName="update">更新</asp:LinkButton>
None.gif                
<asp:LinkButton ID="LinkButton4" runat="server" CommandName="cancel">取消</asp:LinkButton>
None.gif            
</EditItemTemplate>
None.gif           
None.gif        
</asp:DataList><asp:ObjectDataSource ID="ObjectDataSource1" runat="server" DataObjectTypeName="Model.Job_Model"
None.gif            DeleteMethod
="Delete_BLL" InsertMethod="Insert_BLL" SelectMethod="Select_BLL"
None.gif            TypeName
="BLL.Job_BLL" UpdateMethod="Update_BLL" OnUpdating="ObjectDataSource1_Updating" OnDeleting="ObjectDataSource1_Deleting" OnUpdated="ObjectDataSource1_Updated"></asp:ObjectDataSource>
None.gif        
<asp:Label ID="Label1" runat="server" Text="Label" Width="280px"></asp:Label>
None.gif        
&nbsp;&nbsp;
None.gif    
</div>
None.gif    
</form>
None.gif
</body>
None.gif
</html>
None.gif


UI   CS代码
None.gifusing System;
None.gif
using System.Data;
None.gif
using System.Configuration;
None.gif
using System.Collections;
None.gif
using System.Web;
None.gif
using System.Web.Security;
None.gif
using System.Web.UI;
None.gif
using System.Web.UI.WebControls;
None.gif
using System.Web.UI.WebControls.WebParts;
None.gif
using System.Web.UI.HtmlControls;
None.gif
using System.ComponentModel;
None.gif
None.gif
public partial class DataListDemo : System.Web.UI.Page
ExpandedBlockStart.gifContractedBlock.gifdot.gif
dot.gif{
InBlock.gif    
protected void Page_Load(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif
dot.gif{
ExpandedSubBlockEnd.gif    }

InBlock.gif    
protected void DataList1_EditCommand(object source, DataListCommandEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif
dot.gif{
InBlock.gif        
this.DataList1.EditItemIndex = e.Item.ItemIndex;
InBlock.gif        DataBind();
ExpandedSubBlockEnd.gif    }

InBlock.gif    
protected void DataList1_CancelCommand(object source, DataListCommandEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif
dot.gif{
InBlock.gif        
this.DataList1.EditItemIndex = -1;
InBlock.gif        DataBind();
ExpandedSubBlockEnd.gif    }

InBlock.gif    
protected void ObjectDataSource1_Updating(object sender, ObjectDataSourceMethodEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif
dot.gif{
InBlock.gif        ((Model.Job_Model)(e.InputParameters[
0])).Job_id = job.Job_id;
InBlock.gif        ((Model.Job_Model)(e.InputParameters[
0])).Job_desc = job.Job_desc;
InBlock.gif        ((Model.Job_Model)(e.InputParameters[
0])).Min_lvl = job.Min_lvl;
InBlock.gif        ((Model.Job_Model)(e.InputParameters[
0])).Max_lvl = job.Max_lvl;
InBlock.gif        
this.DataList1.EditItemIndex = -1;
InBlock.gif        DataBind();
ExpandedSubBlockEnd.gif    }

InBlock.gif    Model.Job_Model job;
InBlock.gif    
protected void DataList1_UpdateCommand(object source, DataListCommandEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif
dot.gif{
InBlock.gif        job 
= new Model.Job_Model();
InBlock.gif        job.Job_id 
= Convert.ToInt32(((Literal)(this.DataList1.Items[e.Item.ItemIndex].FindControl("Literal1"))).Text);
InBlock.gif        job.Job_desc 
= ((TextBox)(this.DataList1.Items[e.Item.ItemIndex].FindControl("TextBox1"))).Text;
InBlock.gif        job.Min_lvl 
= Convert.ToInt32(((TextBox)(this.DataList1.Items[e.Item.ItemIndex].FindControl("TextBox2"))).Text);
InBlock.gif        job.Max_lvl 
= Convert.ToInt32(((TextBox)(this.DataList1.Items[e.Item.ItemIndex].FindControl("TextBox3"))).Text);
InBlock.gif        ObjectDataSource1.Update();
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif    
protected void DataList1_DeleteCommand(object source, DataListCommandEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif
dot.gif{
InBlock.gif        job 
= new Model.Job_Model();
InBlock.gif        job.Job_id 
= Convert.ToInt32(((Literal)(this.DataList1.Items[e.Item.ItemIndex].FindControl("Literal1"))).Text);
InBlock.gif        ObjectDataSource1.Delete();
InBlock.gif
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif    
protected void ObjectDataSource1_Deleting(object sender, ObjectDataSourceMethodEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif
dot.gif{
InBlock.gif        ((Model.Job_Model)(e.InputParameters[
0])).Job_id = job.Job_id;
InBlock.gif        DataBind();
ExpandedSubBlockEnd.gif    }

InBlock.gif    
protected void ObjectDataSource1_Updated(object sender, ObjectDataSourceStatusEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif
dot.gif{
InBlock.gif        
if (e.Exception != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif
dot.gif{
InBlock.gif            e.ExceptionHandled 
= true;
InBlock.gif            
this.Label1.Text = e.Exception.Message;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

         其他的数据绑定控件(DetailsView,FormView,GridView),代码大同小异,他们都可以自动完成增删改查的功能,所以再这里就不写了。如果有朋友有更好的办法或者建议,可以留言交流一下。需要完整代码的朋友,可以留下EMAIL。

转载于:https://www.cnblogs.com/hackerxxw/archive/2008/06/09/1216375.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值