ImageVerifierCode 换一换
格式:DOCX , 页数:16 ,大小:31.22KB ,
资源ID:8921686      下载积分:10 金币
验证码下载
登录下载
邮箱/手机:
图形码:
验证码: 获取验证码
温馨提示:
支付成功后,系统会自动生成账号(用户名为邮箱或者手机号,密码是验证码),方便下次登录下载和查询订单;
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

开通VIP
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.zixin.com.cn/docdown/8921686.html】到电脑端继续下载(重复下载【60天内】不扣币)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

开通VIP折扣优惠下载文档

            查看会员权益                  [ 下载后找不到文档?]

填表反馈(24小时):  下载求助     关注领币    退款申请

开具发票请登录PC端进行申请。


权利声明

1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:4009-655-100;投诉/维权电话:18658249818。

注意事项

本文(创建业务逻辑层步骤.docx)为本站上传会员【xrp****65】主动上传,咨信网仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知咨信网(发送邮件至1219186828@qq.com、拔打电话4009-655-100或【 微信客服】、【 QQ客服】),核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载【60天内】不扣币。 服务填表

创建业务逻辑层步骤.docx

1、 n 更多企业学院: 《中小企业管理全能版》 183套讲座+89700份资料 《总经理、高层管理》 49套讲座+16388份资料 《中层管理学院》 46套讲座+6020份资料  《国学智慧、易经》 46套讲座 《人力资源学院》 56套讲座+27123份资料 《各阶段员工培训学院》 77套讲座+ 324份资料 《员工管理企业学院》 67套讲座+ 8720份资料 《工厂生产管理学院》 52套讲座+ 13920份资料 《财务管理学院》 53套讲座+ 17945份资料  《销售经理学院》 56套讲

2、座+ 14350份资料 《销售人员培训学院》 72套讲座+ 4879份资料 简介 在教程一中创建的数据访问层 (DAL) 将数据访问逻辑与表示逻辑清晰地分离开来。然而,尽管 DAL 从表示层中清晰地分离出数据访问层细节,它却并没有实施任何可能采用的业务规则。例如,我们想让我们的应用程序在 Discontinued 字段设为 1 时禁止对 Products 表的 CategoryID 或 SupplierID 字段的修改,还有,我们可能想实施一些资历规则以便禁止发生这样的情况:雇员被其后入职的另一雇员所管理。另一种常见的情形是授权 – 可能只有处于特定职位的用户可以删除产品或

3、更改 UnitPrice 值。 通过本教程,我们可以了解怎样将业务规则集中到在表示层与DAL 之间充当数据交互中介的业务逻辑层 (BLL) 中。在真实的应用程序中,BLL 应作为一个单独的类库项目而实现。然而,为了简化项目结构,在这些教程中,我们以 App_Code 文件夹下的一系列的类来实现 BLL 。图 1 展示了表示层、BLL 和 DAL 之间的结构关系。 图1 :BLL 将表示层与数据访问层分隔开来并且实施业务规则。 步骤1 :创建 BLL 类 我们的BLL 将由四个类组成,分别对应 DAL 中不同的 TableAdapter 。每个 BLL 类都具有一些方法,这些方法可以

4、从 DAL 中该类对应的 TableAdapter 中检索、插入、更新或删除数据并应用相应的业务规则。 为了更清楚地区分 DAL 的相关类与 BLL 的相关类,我们在 App_Code 文件夹下创建两个子文件夹:DAL 和 BLL 。创建时,只需右健单击 Solution Explorer 中的 App_Code 文件夹并选择 New Folder 。创建了这两个文件夹后,将教程一中创建的 Typed DataSet 移动到 DAL 子文件夹中。 然后,在BLL 子文件夹中创建四个 BLL 类文件。为此,右键单击 BLL 子文件夹,选择 Add a New Item ,然后选择 Class

5、 模板。将这四个类分别命名为 ProductsBLL 、 CategoriesBLL 、 SuppliersBLL 和 EmployeesBLL 。 图2 :在App_Code 文件夹中添加四个新类 接下来让我们在每个类中添加一些方法,这些方法只是简单地封装教程一中为TableAdapters 定义的方法。目前,这些方法只是对 DAL 中内容的直接调用,稍后我们会返回到这些方法中来添加任何所需的业务逻辑。 注意: 如果您当前使用的是Visual Studio Standard Edition 或以上版本 ( 即,当前使用的不是Visual Web Developer ),您可以使用 

6、以可视的方式随意设计自己的类。有关 Visual Studio 中该新特性的详细信息,请参见 。 对于ProductsBLL 类,总共需要添加七个方法 : · GetProducts() – 返回所有产品。 · GetProductByProductID(productID) – 返回具有指定产品 ID 的产品。 · GetProductsByCategoryID(categoryID) – 返回指定 种类 中的所有产品。 · GetProductsBySupplier(supplierID) – 返回来自指定供应商的所有产品。 · AddProduct(productName,

7、supplierID, categoryID, quantityPerUnit, unitPrice, unitsInStock, unitsOnOrder, reorderLevel, discontinued) – 通过传入值将一个新产品插入到数据库中 ; 返回新插入记录的 ProductID 值。 · UpdateProduct(productName, supplierID, categoryID, quantityPerUnit, unitPrice, unitsInStock, unitsOnOrder, reorderLevel, discontinued, productID

8、) – 通过传入值更新数据库中的一个现有产品 ; 如果正好更新了一行则返回 true , 否则返回 false 。 · DeleteProduct(productID) – 从数据库中删除指定产品。 ProductsBLL.cs using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.We

9、b.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using NorthwindTableAdapters; [System.ComponentModel.DataObject] public class ProductsBLL { private ProductsTableAdapter _productsAdapter = null; protected ProductsTableAdapter Adapter { get { if

10、 (_productsAdapter == null) _productsAdapter = new ProductsTableAdapter(); return _productsAdapter; } } [System.ComponentModel.DataObjectMethodAttribute (System.ComponentModel.DataObjectMethodType.Select, true)] public Northwind.Pr

11、oductsDataTable GetProducts() { return Adapter.GetProducts(); } [System.ComponentModel.DataObjectMethodAttribute (System.ComponentModel.DataObjectMethodType.Select, false)] public Northwind.ProductsDataTable GetProductByProductID(int productID) {

12、 return Adapter.GetProductByProductID(productID); } [System.ComponentModel.DataObjectMethodAttribute (System.ComponentModel.DataObjectMethodType.Select, false)] public Northwind.ProductsDataTable GetProductsByCategoryID(int categoryID) { return Adapter.GetProd

13、uctsByCategoryID(categoryID); } [System.ComponentModel.DataObjectMethodAttribute (System.ComponentModel.DataObjectMethodType.Select, false)] public Northwind.ProductsDataTable GetProductsBySupplierID(int supplierID) { return Adapter.GetProductsBySupplierID(sup

14、plierID); } [System.ComponentModel.DataObjectMethodAttribute (System.ComponentModel.DataObjectMethodType.Insert, true)] public bool AddProduct(string productName, int? supplierID, int? categoryID, string quantityPerUnit, decimal? unitPrice, short? unitsInStock,

15、 short? unitsOnOrder, short? reorderLevel, bool discontinued) { // Create a new ProductRow instance Northwind.ProductsDataTable products = new Northwind.ProductsDataTable(); Northwind.ProductsRow product = products.NewProductsRow(); product.ProductName

16、 productName; if (supplierID == null) product.SetSupplierIDNull(); else product.SupplierID = supplierID.Value; if (categoryID == null) product.SetCategoryIDNull(); else product.CategoryID = categoryID.Value; if (quantityPerUnit == null) product.SetQu

17、antityPerUnitNull(); else product.QuantityPerUnit = quantityPerUnit; if (unitPrice == null) product.SetUnitPriceNull(); else product.UnitPrice = unitPrice.Value; if (unitsInStock == null) product.SetUnitsInStockNull(); else product.UnitsInStock = un

18、itsInStock.Value; if (unitsOnOrder == null) product.SetUnitsOnOrderNull(); else product.UnitsOnOrder = unitsOnOrder.Value; if (reorderLevel == null) product.SetReorderLevelNull(); else product.ReorderLevel = reorderLevel.Value; product.Discontinued =

19、discontinued; // Add the new product products.AddProductsRow(product); int rowsAffected = Adapter.Update(products); // Return true if precisely one row was inserted, // otherwise false return rowsAffected == 1; } [System.Component

20、Model.DataObjectMethodAttribute (System.ComponentModel.DataObjectMethodType.Update, true)] public bool UpdateProduct(string productName, int? supplierID, int? categoryID, string quantityPerUnit, decimal? unitPrice, short? unitsInStock, short? unitsOnOrder, short? reor

21、derLevel, bool discontinued, int productID) { Northwind.ProductsDataTable products = Adapter.GetProductByProductID(productID); if (products.Count == 0) // no matching record found, return false return false; Northwind.ProductsRow product =

22、products[0]; product.ProductName = productName; if (supplierID == null) product.SetSupplierIDNull(); else product.SupplierID = supplierID.Value; if (categoryID == null) product.SetCategoryIDNull(); else product.CategoryID = categoryID.Value;

23、 if (quantityPerUnit == null) product.SetQuantityPerUnitNull(); else product.QuantityPerUnit = quantityPerUnit; if (unitPrice == null) product.SetUnitPriceNull(); else product.UnitPrice = unitPrice.Value; if (unitsInStock == null) product.SetUnitsInStockNull(

24、); else product.UnitsInStock = unitsInStock.Value; if (unitsOnOrder == null) product.SetUnitsOnOrderNull(); else product.UnitsOnOrder = unitsOnOrder.Value; if (reorderLevel == null) product.SetReorderLevelNull(); else product.ReorderLevel = reorderL

25、evel.Value; product.Discontinued = discontinued; // Update the product record int rowsAffected = Adapter.Update(product); // Return true if precisely one row was updated, // otherwise false return rowsAffected == 1; } [System.Comp

26、onentModel.DataObjectMethodAttribute (System.ComponentModel.DataObjectMethodType.Delete, true)] public bool DeleteProduct(int productID) { int rowsAffected = Adapter.Delete(productID); // Return true if precisely one row was deleted, // otherwise false

27、 return rowsAffected == 1; } } 这些方法 —GetProducts 、GetProductByProductID 、GetProductsByCategoryID 和 GetProductBySuppliersID ,只是返回数据,它们相当直接、简单,因为它们只是向下调用 DAL 中的内容。在一些场合下,可能会有一些业务规则需要在此层实现(例如基于当前已登录用户或用户所处职位的授权规则,可以访问不同的数据),但在这里我们只是保留这些方法不变。因此,对于这些方法, BLL 只是充当了一个代理的作用,表示层通过这个代理来访问数据访问层中

28、的底层数据。 AddProduct 和 UpdateProduct 方法将产品各字段的值以参数形式传入,它们的作用分别是:添加一个新产品,更新一个现有产品。由于 Product 表的许多列,如 CategoryID 、 SupplierID 和 UnitPrice ,都可接受 NULL 值, AddProduct 和 UpdateProduct 中与这样的列相对应的输入参数使用 。 Nullable 类型对于 .NET 2.0 来说是新类型,利用该类型所提供的技术,我们可以指示一个值类型是否可以是空类型。在 C# 中,可以通过在类型后加问号 ? 将一个值类型标记为 nullable 类型(例

29、如 int? x; )。有关详情,请参见 中的  一节。 这三个方法均返回布尔值,该值指示是否成功的插入、更新或删除了一行。返回该值的原因是,方法的操作并不一定会影响到一行。例如,如果页面开发人员调用 DeleteProduct 时传入的 ProductID 并非一个现有产品的 ID ,则发给数据库的 DELETE 语句不会产生任何影响,因而 DeleteProduct 方法会返回 false。 请注意,当添加一个新产品或更新一个现有产品时,我们将新的或更改的产品的字段值用一组数值传入,而不是为此接受一个ProductsRow 实例。选择该方式的原因是, ProductsRow 类派生于

30、ADO.NET DataRow 类,而后者并没有一个默认的无参数构造函数。为了创建一个新的 ProductsRow 实例,首先要创建一个 ProductsDataTable 实例,然后调用它的 NewProductRow() 方法(就像我们在AddProduct方法中作的那样)。当我们使用 ObjectDataSource 插入或更新产品时,其缺陷就会暴露出来。简言之, ObjectDataSource 会尝试为输入的参数创建一个实例。如果 BLL 方法期待的是一个 ProductsRow 实例,则 ObjectDataSource 会尝试创建一个这样的实例,但是,由于缺少默认的无参数构造函数

31、该尝试失败。有关该问题的详细信息,请参见以下两个 ASP.NET 论坛:、 。 另外,AddProduct 和 UpdateProduct 中的代码都会创建一个ProductsRow 实例并以刚传入的值对该实例进行赋值。当向 DataRow 的一些 DataColumn 赋值时,可发生各种字段级的验证检查。因此,将传入的值进行一下人工的验证有助于确保传递给 BLL 方法的数据的有效性。不幸的是, Visual Studio 生成的强类型的 DataRow 类并不使用 nullable 类型。而为了给 DataRow 中的特定 DataColumn 赋数据库空值,我们必须使用 SetColu

32、mnNameNull() 方法。 在UpdateProduct 中,我们 首先用 GetProductByProductID(productID) 载入要更新的产品。尽管这看似是一次不必要的对数据库的操作,在将来的介绍并发优化的教程中,该往返将会被证明是值得的。并发优化技术可确保两个同时对同一数据进行操作的用户不会在不经意间覆盖彼此所作的更改。获取整个记录还使以下事情变得容易:在 BLL 中创建更新方法,使该方法只修改 DataRow 的所有列的一个子集。当我们研究 SuppliersBLL 类时,我们会看到这样一个例子。 最后,请注意对ProductsBLL 类使用了  ( 接近文件开头

33、 , 类声明语句前面的 [System.ComponentModel.DataObject] 标签 ), 而其方法有 。 DataObject 属性将该类标记为一个适合绑定到  的对象,而 DataObjectMethodAttribute 属性则指示该方法的用途。在将来的教程中可以看到, ASP.NET 2.0 的 ObjectDataSource 使得以声明的方式从类中访问数据变得容易。默认情况下,在 ObjectDataSource 向导的下拉列表中只显示出标记为 DataObject 的那些类,这样有助于在该向导中筛选出可绑定的那些类。 ProductsBLL 类没有这些属性一样会工作

34、良好,但是,加入这些属性可以使得在 ObjectDataSource 向导下的工作更为轻松。 添加其它类 在完成 ProductsBLL 类的编写后,我们还需要添加一些处理种类、供应商及雇员数据的类。我们花一些时间用上面例子中的概念来创建下面的类和方法: · CategoriesBLL.cs o GetCategories() o GetCategoryByCategoryID(categoryID) · SuppliersBLL.cs o GetSuppliers() o GetSupplierBySupplierID(supplierID) o GetSuppliersB

35、yCountry(country) o UpdateSupplierAddress(supplierID, address, city, country) · EmployeesBLL.cs o GetEmployees() o GetEmployeeByEmployeeID(employeeID) o GetEmployeesByManager(managerID) 值得注意的一个方法是 SuppliersBLL 类的UpdateSupplierAddress 方法。该方法提供了一个接口以便只更新供应商的地址信息。在内部实现上,该方法读取指定supplierID 的 Suppli

36、erDataRow 对象(使用GetSupplierBySupplierID 来读取),设置其相关地址属性,然后向下调用SupplierDataTable 的更新方法。UpdateSupplierAddress 方法如下: [System.ComponentModel.DataObjectMethodAttribute (System.ComponentModel.DataObjectMethodType.Update, true)] public bool UpdateSupplierAddress (int supplierID, string address, s

37、tring city, string country) { Northwind.SuppliersDataTable suppliers = Adapter.GetSupplierBySupplierID(supplierID); if (suppliers.Count == 0) // no matching record found, return false return false; else { Northwind.SuppliersRow supplier = supp

38、liers[0]; if (address == null) supplier.SetAddressNull(); else supplier.Address = address; if (city == null) supplier.SetCityNull(); else supplier.City = city; if (country == null) supplier.SetCountryNull(); else supplier.Country = countr

39、y; // Update the supplier Address-related information int rowsAffected = Adapter.Update(supplier); // Return true if precisely one row was updated, // otherwise false return rowsAffected == 1; } } 步骤 2:通过 BLL 类访问 Typed DataSets 在教程一中我们看到了直接使用

40、Typed DataSet 的编程例子。而现在我们已添加了一些 BLL 类,因此表示层应转而基于 BLL 而工作。教程一的 AllProducts.aspx 例子使用了 ProductsTableAdapter 来将产品列表绑定到一个 GridView,见下面的代码: ProductsTableAdapter productsAdapter = new ProductsTableAdapter(); GridView1.DataSource = productsAdapter.GetProducts(); GridView1.DataBind(); 要使用 BLL 类,只需改变代码的第

41、一行 – 只需用 ProductBLL 对象代替 ProductsTableAdapter 对象: ProductsBLL productLogic = new ProductsBLL(); GridView1.DataSource = productLogic.GetProducts(); GridView1.DataBind(); 也可以使用 ObjectDataSource 以声明的方式来访问BLL 类(如同 Typed DataSet )。我们将在后续教程中更为详细地讨论ObjectDataSource 。 图3 : 产品列表显示于GridView 中 步骤3 :向 D

42、ataRow 类添加字段级验证 字段级验证是进行插入或更新操作时针对业务对象的属性值而进行的检查。下面是对产品的一些字段级验证规则: · ProductName 字段的长度不能超过 40 个字符。 · QuantityPerUnit 字段的长度不能超过 20 个字符。 · ProductID 、ProductName 和 Discontinued 字段是必需的,但所有其它字段是可选的。 · UnitPrice 、UnitsInStock 、UnitsOnOrder 和 ReorderLevel 字段必须大于等于零。 这些规则可以并且应该在数据库级表达出来。Products 表的相应

43、列的数据类型可反映对 ProductName 和 QuantityPerUnit 字段的字符数限制(分别为 nvarchar(40) 和nvarchar(20) )。对字段是可选还是必需的表达是这样的:数据库表列允许还是不允许NULL 。四个 的存在确保只有大于等于零的值才可赋值给UnitPrice 、UnitsInStock 、UnitsOnOrder 和 ReorderLevel 列。 这些规则除了在数据库级实施外还应在DataSet 级实施。事实上,字段长度以及某值是必需的还是可选的,已被DataTable 的 DataColumn 集定义。要查看现有的自动提供的字段级验证,可转到Da

44、taSet 设计器,从其中一个DataTable 中选择一个域,然后转至 Properties 窗口。如图 4 所示,ProductsDataTable 中的 QuantityPerUnit DataColumn 允许的最大长度是 20 个字符,并且允许 NULL 值。如果我们试图将 ProductsDataRow 的 QuantityPerUnit 属性设置为一个超过 20 个字符的字符串值,系统会抛出 ArgumentException 异常 。 图4 :DataColumn 提供基本域级验证 不幸的是,我们不能通过 Properties 窗口指定边界检查,如,UnitPrice

45、必须大于等于零这样的检查。为了提供此类字段级验证,需要创建一个针对DataTable 的 事件的Event Handler。如 所述,Typed DataSet 创建的 DataSet 、DataTables 和 DataRow 对象可以通过使用部分类来扩展。利用该技术我们可以为ProductsDataTable 类创建一个 ColumnChanging 事件的Event Handler。首先,在 App_Code 文件夹下创建一个名为 ProductsDataTable.ColumnChanging.cs 的类。 图5 :在App_Code 文件夹中添加一个新类 其次,创建一个针对

46、ColumnChanging 事件的Event Handler以确保UnitPrice 、UnitsInStock 、UnitsOnOrder 和 ReorderLevel 列的值(如果不是 NULL )大于等于零。其中任何一列超出范围,系统都会给出ArgumentException 。 ProductsDataTable.ColumnChanging.cs public partial class Northwind { public partial class ProductsDataTable { public override void Be

47、ginInit() { this.ColumnChanging += ValidateColumn; } void ValidateColumn(object sender, DataColumnChangeEventArgs e) { if(e.Column.Equals(this.UnitPriceColumn)) { if(!Convert.IsDBNull(e.Propo

48、sedValue) && (decimal)e.ProposedValue < 0) { throw new ArgumentException( "UnitPrice cannot be less than zero", "UnitPrice"); } } else if (e.Column.Equals(this.UnitsInStockColumn) |

49、 e.Column.Equals(this.UnitsOnOrderColumn) || e.Column.Equals(this.ReorderLevelColumn)) { if (!Convert.IsDBNull(e.ProposedValue) && (short)e.ProposedValue < 0) { throw

50、 new ArgumentException(string.Format( "{0} cannot be less than zero", e.Column.ColumnName), e.Column.ColumnName); } } } } } 步骤 4:向 BLL 类添加定制的业务规则 除了字段级验证外,可能还有高级定制的业务规则,这些规则涉及不同的实体,或者涉及到不能在单个列中表达的概念,例如:

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服