10. Realization of Logic Function of Multi-Seller Tool Group Reminder in ABPZero Series Tutorials

Class libraries have been encapsulated in the previous article, and now we continue to implement functions to achieve a complete function on the basis of the ABP Zero framework.

Redis cache

Before writing the function, install Redis on the machine. You need to use Redis as a cache. Here are two Windows installation Redis tutorials.

Blog Garden: http://www.cnblogs.com/mzws/p/redis1.html

My note: http://note.youdao.com/noteshare?Id=a25fc319c5a38285ab7cab2e81857b31&sub=675165188B214E6CA0660B8EEB0A1C35 (please remember to collect it in time, it may expire someday)

Core project

Create a new Pdd directory under the Core project, and continue to create new Entities and IRepositories directories under the Pdd directory.

 

Next, create a new PddMall entity class under the Entities directory. The code is as follows:

/// <summary>
    /// shop
    /// </summary>
    public class PddMall : FullAuditedEntity
    {
        /// <summary>
        /// shop id
        /// </summary>
        public string MallId { get; set; }

        /// <summary>
        /// Shop name
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// logo
        /// </summary>
        public string Logo { get; set; }

        /// <summary>
        /// describe
        /// </summary>
        public string Desc { get; set; }

        /// <summary>
        /// Refund address
        /// </summary>
        public string RefundAddress { get; set; }

        /// <summary>
        /// Sales volume
        /// </summary>
        public long Sales { get; set; }

        /// <summary>
        /// Quantity of commodities
        /// </summary>
        public int GoodNum { get; set; }
    }

 

Continue to create a new IMallRepository repository interface under the IRepositories directory, code as follows:

public interface IMallRepository : IRepository<PddMall>
{
}

 

Entity Framework Project

Open the AbpZeroTemplate DbContext. CS file and add the following code:

File path: D: abpweb PddSellerAssistant PddSellerAssistant. EntityFramework EntityFramework EntityFramework AbpZeroTemplate DbContext.cs

/************Put together a lot of relevant *******************************************************************************/
public virtual IDbSet<PddMall> PddMalls { get; set; }
/************Put together a lot of relevant *******************************************************************************/

Open the package management console of VS and select the. Entity Framework project as the default project in the package management console. Then execute the following commands in the console:

Add-Migration "Add_PddMall"

 

Seeing the Yellow hint in the above figure indicates that the migration file was created successfully.

At the same time, there is one more file in the Migrations directory, which is the migration file just created.

Now you can use the following commands to create a database:

Update-Database

 

The command was successfully executed and the corresponding tables were created by viewing the database (as follows):

 

Then create a new Pdd directory under the Entity Framework project, and then create a Repositories directory with the following structure:

Create a new Mall Repository repository implementation class under the Repositories directory. The code is as follows:

public class MallRepository : AbpZeroTemplateRepositoryBase<PddMall>, IMallRepository
    {
        public MallRepository(IDbContextProvider<AbpZeroTemplateDbContext> dbContextProvider) : base(dbContextProvider)
        {
        }
    }

 

 

Application Project

First refer to the class library PddTool

 

Similarly, create a new Pdd directory, and create MallApp and ProductApp under this directory. These two directories create Dto directories respectively. The effect is as follows:

 

New IMallAppService interface under MallApp directory, code as follows:

public interface IMallAppService : IApplicationService
    {
        void CreateByMallId(CreateMallInput input);
        /// <summary>
        /// Get store information, return store number, store name
        /// 
        /// </summary>
        /// <returns></returns>
        MallOutput GetMallInfo(int id);

        /// <summary>
        /// Get a list of stores
        /// </summary>
        /// <returns></returns>
        GetMallsOutput GetMalls();

        
    }

 

 

At this point, the Input and Output classes will report errors, and then create these classes in the Dto directory, as follows:

public class CreateMallInput
    {
        [Required]
        public string MallId { get; set; }
    }

 

 

public class MallOutput
    {
        public int Id { get; set; }

        /// <summary>
        /// Shop name
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// shop id
        /// </summary>
        public string MallId { get; set; }
    }

 

 

public class GetMallsOutput
    {
        public List<MallOutput> Items { get; set; }
    }

 

 

Create a new MallAppService class under the MallApp directory. The code is as follows:

public class MallAppService : AbpZeroTemplateAppServiceBase, IMallAppService
    {
        private readonly IMallRepository _mallRepository;
        private readonly ICacheManager _cacheManager;
        public MallAppService(IMallRepository mallRepository, ICacheManager cacheManager)
        {
            _mallRepository = mallRepository;
            _cacheManager = cacheManager;
        }

        /// <summary>
        /// Access to store information
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public MallOutput GetMallInfo(int id)
        {

            var mall = _mallRepository.Get(id);
            return new MallOutput()
            {
                Id = mall.Id,
                MallId = mall.MallId,
                Name = mall.Name
            };
        }

        /// <summary>
        /// Add shop
        /// </summary>
        /// <param name="input"></param>
        public void CreateByMallId(CreateMallInput input)
        {
            try
            {
                var mall = MallTool.GetInfo(input.MallId);
                var entity = new PddMall()
                {
                    Name = mall.mall_name,
                    Desc = mall.mall_desc,
                    GoodNum = mall.goods_num,
                    Logo = mall.logo,
                    MallId = input.MallId,
                    RefundAddress = mall.refund_address,
                    Sales = mall.mall_sales,
                };
                //By store id Search store information
                var count = _mallRepository.Count(a => a.MallId.Equals(input.MallId) && a.CreatorUserId == AbpSession.UserId);
                if (count != 0)
                {
                    //Update if database exists
                    var m = _mallRepository.Single(a => a.MallId.Equals(input.MallId) && a.CreatorUserId == AbpSession.UserId);
                    m.Name = entity.Name;
                    m.Desc = entity.Desc;
                    m.GoodNum = entity.GoodNum;
                    m.Logo = entity.Logo;
                    m.MallId = entity.MallId;
                    m.RefundAddress = entity.RefundAddress;
                    m.Sales = entity.Sales;
                    _mallRepository.Update(m);
                }
                else
                {
                    //If the database does not exist, the store will use API Obtain
                    _mallRepository.Insert(entity);
                }

            }
            catch (Exception ex)
            {
                throw new UserFriendlyException(ex.Message);
            }
        }

        /// <summary>
        /// Get a list of stores from the database
        /// </summary>
        /// <returns></returns>
        public GetMallsOutput GetMalls()
        {
            var list = _mallRepository.GetAllList(a => a.CreatorUserId == AbpSession.UserId);
            //Create mapping
            return new GetMallsOutput()
            {
                Items = Mapper.Map<List<MallOutput>>(list)
            };
        }
        
    }

 

 

The catalogue structure is as follows:

 

Continue to create new I ProductApp Service interface under the Product App directory, code as follows:

public interface IProductAppService : IApplicationService
    {
        
        Task<PagedResultDto<KaiTuanProductOutput>> GetKaiTuanProductsAsync(GetProductsInput input);

        /// <summary>
        /// According to commodity id Get all the information about this merchandise.
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        //[HttpGet]
        PagedResultDto<ProductOutput> GetAllKaiTuansByGoodId(GetAllKaiTuansInput input);
    }

 

 

Next, create a new ProductAppService class with the following code:

public class ProductAppService : AbpZeroTemplateAppServiceBase, IProductAppService
    {
        /// <summary>
        /// Cache management
        /// </summary>
        private readonly ICacheManager _cacheManager;
        private string key;    //cache key
        public ProductAppService(ICacheManager cacheManager)
        {
            _cacheManager = cacheManager;
        }
        /// <summary>
        ///According to the shop id, Acquire goods with a consortium
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<KaiTuanProductOutput>> GetKaiTuanProductsAsync(GetProductsInput input)
        {
            //Number of group members who have access to all commodities
            var list = MallTool.GetKaiTuanList(input.MallId);
            //Clear cache
            key = string.Format("{0}_{1}_KaiTuan", AbpSession.UserId, input.MallId);
            _cacheManager.GetCache(key).Clear();
            #region data conversion
            var items = new List<KaiTuanProductOutput>();
            foreach (var localGroupItem in list)
            {
                var item = new KaiTuanProductOutput()
                {
                    GoodId = localGroupItem.GoodId,
                    Name = localGroupItem.Name,
                    KaiTuanCount = localGroupItem.KaiTuanCount,
                    Img = localGroupItem.Img,

                };
                items.Add(item);
            }
            #endregion
            int totalCount = list.Count;

            #region Processing sequencing
            if (input.Sorting.Equals("goodId ASC"))
            {
                items = items.OrderBy(a => a.GoodId).ToList();
            }
            else if (input.Sorting.Equals("goodId DESC"))
            {
                items = items.OrderByDescending(a => a.GoodId).ToList();
            }
            if (input.Sorting.Equals("name ASC"))
            {
                items = items.OrderBy(a => a.Name).ToList();
            }
            else if (input.Sorting.Equals("name DESC"))
            {
                items = items.OrderByDescending(a => a.Name).ToList();
            }
            if (input.Sorting.Equals("kaiTuanCount ASC"))
            {
                items = items.OrderBy(a => a.KaiTuanCount).ToList();
            }
            else if (input.Sorting.Equals("kaiTuanCount DESC"))
            {
                items = items.OrderByDescending(a => a.KaiTuanCount).ToList();
            }
            #endregion

            return new PagedResultDto<KaiTuanProductOutput>(totalCount, items);
        }

        /// <summary>
        /// According to commodity id,Get all of this merchandise to start a group
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public PagedResultDto<ProductOutput> GetAllKaiTuansByGoodId(GetAllKaiTuansInput input)
        {
            #region Use redis cache
            key = string.Format("{0}_{1}_KaiTuan", AbpSession.UserId, input.MallId);
            var list = _cacheManager.GetCache<string, List<KaiTuan>>(key).Get("GetAllKaiTuanByGoodId." + input.GoodId, () => MallTool.GetAllKaiTuanByGoodId(input.MallId, input.GoodId));

            #endregion
            #region data conversion
            List<ProductOutput> productOutputs = Mapper.Map<List<ProductOutput>>(list);

            #endregion
            #region Processing sequencing
            if (input.Sorting.Equals("timeLeft ASC"))
            {
                productOutputs = productOutputs.OrderBy(a => a.TimeLeft).ToList();
            }
            else if (input.Sorting.Equals("timeLeft DESC"))
            {
                productOutputs = productOutputs.OrderByDescending(a => a.TimeLeft).ToList();
            }
            #endregion

            int total = productOutputs.Count;
            #region Processing paging
            productOutputs = productOutputs.Skip(input.SkipCount).Take(input.MaxResultCount).ToList();
            #endregion
            return new PagedResultDto<ProductOutput>(total, productOutputs);
        }
    }

 

Similarly, Input and Output error reporting can be done by creating the following classes in Dto:

public class KaiTuanProductOutput
    {
        public int Id { get; set; }

        public int GoodId { get; set; }

        /// <summary>
        /// Trade name
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// Commodity pictures
        /// </summary>
        public string Img { get; set; }

        /// <summary>
        /// Number of persons opening
        /// </summary>
        public int KaiTuanCount { get; set; }
    }

 

 

public class GetProductsInput : PagedAndSortedInputDto, IShouldNormalize
    {
        /// <summary>
        /// shop id
        /// </summary>
        public string MallId { get; set; }

        /// <summary>
        /// Reminder interval (minutes)
        /// </summary>
        public int Interval { get; set; }
        public void Normalize()
        {
            if (string.IsNullOrEmpty(Sorting))
            {
                Sorting = "Name";
            }
        }
    }

 

 

public class ProductOutput
    {
        /// <summary>
        /// commodity id
        /// </summary>
        public int Id { get; set; }

        /// <summary>
        /// Nickname?
        /// </summary>
        public string  NickName { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string SKU { get; set; }

        /// <summary>
        /// Order number
        /// </summary>
        public string OrderNum { get; set; }

        /// <summary>
        /// Remaining time
        /// </summary>
        public double TimeLeft { get; set; }

        /// <summary>
        /// Group number
        /// </summary>
        public string KaiTuanOrderNum { get; set; }
    }

 

 

public class GetAllKaiTuansInput : PagedAndSortedInputDto, IShouldNormalize
    {
        /// <summary>
        /// shop id
        /// </summary>
        public int MallId { get; set; }
        /// <summary>
        /// commodity id
        /// </summary>
        public int GoodId { get; set; }

public void Normalize() { if (string.IsNullOrEmpty(Sorting)) { Sorting = "timeLeft ASC"; } } }

 

 

Open CustomDtoMapper.cs and add the following code (convention mapping):

File path: D: ABP version aspnet-zero-3.4.0 aspnet-zero-3.4.0 src MyCompanyName. AbpZerolate. Application CustomDtoMapper.cs

private static void CreateMappingsInternal(IMapperConfigurationExpression mapper)
        {
            mapper.CreateMap<User, UserEditDto>()
                .ForMember(dto => dto.Password, options => options.Ignore())
                .ReverseMap()
                .ForMember(user => user.Password, options => options.Ignore());
            /**********************Put together a lot of relevant ****************************************************************************/
            mapper.CreateMap<PddMall, MallOutput>();
            mapper.CreateMap<KaiTuan, ProductOutput>();
        }

 

 

The above business logic is completed, and the Pdd directory structure in the Application project is as follows:

 

Generate solution, browser opens framework background login.

The browser then opens http://localhost:8088/swagger/ui/index for api testing.

According to the method mentioned in the previous article, find a shop number: 1227314 to test the functions just written.

At present, only store information will be saved to the database, and merchandise information or group information will be saved to the cache.

The content of this article is more, page implementation moved to the next one.

 

 Return to the General Directory

Keywords: ASP.NET Database Redis Windows

Added by steven fullman on Sat, 18 May 2019 19:20:04 +0300