Как построить архитектура мобильного приложения в котором сложная иерархия данных которые обновляются?

многопользовательское приложения, в каждого пользователя есть список товаров и складов, в товара есть остатки по складам, в свою очередь у складов есть остатки по товарам (по сути те же самые объекты остатки), в любой момент работы, может прилететь обновления по остаткам, как реализовать такую структуру в коде, логику обновления
  • Вопрос задан
  • 96 просмотров
Пригласить эксперта
Ответы на вопрос 2
sabramovskikh
@sabramovskikh
Так же как и любой интернет магазин. Есть back-end с базой данных, в которой все хранится. Приложением делает аякс запросы к бэку и получает актуальные данные.
В бэке делаются различные импорты-экспорты с нужными вам системами (1С или что там у вас).
Ваше приложением это по сути фронт сайта (интернет магазина)
Ответ написан
firedragon
@firedragon
Senior .NET developer
Примерно так:
1 api
---------------------------
2 сайт использующий это апи
-------------------------------------
3 общие дата классы вынесенные в отдельную библиотеку
-----------------------------------------------------------------------
4 мобильное приложение использующее это апи

вот пример дата адаптера.
using EggCloudApp.Models;
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace EggCloudApp.Code
{
    public class DataCient<TReq, TRes> where TRes : class
    {
        // https://test.online/
        public DataCient(string lang = CountryModel.RuLanguage)
        {
            if (lang == CountryModel.RuLanguage) BaseUrl = "https://test.ru";
            else BaseUrl = "https://test.online";

        }
        public string BaseUrl { get; }

        public int Status { get; private set; }
        public string Message { get; set; }
        public TRes Result { get; private set; }
        public async Task<TRes> Post(string url, string bearer, TReq req)
        {
            var apiUrl = BaseUrl + url;
            using var client = GetClient(bearer, apiUrl);
            var jsonInString = JsonSerializer.Serialize<TReq>(req, Options);
            HttpResponseMessage response;
            if (jsonInString == "\"\"")
                response = await client.PostAsync(apiUrl, null);
            else
                response = await client.PostAsync(apiUrl, new StringContent(jsonInString, Encoding.UTF8, "application/json"));

            if (response.IsSuccessStatusCode)
            {
                var buff = await response.Content.ReadAsStringAsync();
                if (string.IsNullOrEmpty(buff))
                {
                    Result = null;
                    Status = 200;
                    return Result;
                }
                var result = JsonSerializer.Deserialize<TRes>(buff, Options);
                Result = result;
                Status = 200;
                return result;

            }
            throw new ArgumentOutOfRangeException("Failed to fetch");
        }

        private JsonSerializerOptions Options => new JsonSerializerOptions()
        {
            PropertyNameCaseInsensitive = true

        };
        private async Task<TRes> Get(string uri, string bearer)
        {
            var apiUrl = BaseUrl + uri;
            using var client = GetClient(bearer, apiUrl);



            // var jsonInString = JsonSerializer.Serialize<TReq>(req, options);
            var response = await client.GetAsync(apiUrl);

            if (response.IsSuccessStatusCode)
            {
                var buff = await response.Content.ReadAsStringAsync();
                // AuthData
                // var mm = JsonConvert.DeserializeObject<AuthData>(buff);
                var result = JsonSerializer.Deserialize<TRes>(buff, Options);
                Result = result;
                Status = 200;
                return result;

            }
            throw new ArgumentOutOfRangeException("Failed to fetch");
        }
        public async Task<TRes> GetRates(string bearer)
        {
            var resu = await Get("/api/shop", bearer);
            return resu;
        }
        public async Task<TRes> GetUserInfo(string bearer)
        {
            var resu = await Get("/api/user", bearer);
            return resu;
        }
        public async Task<TRes> Login(TReq req)
        {
            try
            {
                return await GetToken(req);
            }
            catch (ArgumentOutOfRangeException ex)
            {
                throw new ArgumentException(ex.Message);
            }
        }
        private async Task<TRes> GetToken(TReq req)
        {
            var apiUrl = BaseUrl + "/api/auth/login";
            using var client = new HttpClient();
            client.BaseAddress = new Uri(apiUrl);
            client.DefaultRequestHeaders.Accept.Clear();
            var jsonInString = JsonSerializer.Serialize<TReq>(req, Options);
            var response = await client.PostAsync(apiUrl, new StringContent(jsonInString, Encoding.UTF8, "application/json"));

            if (response.IsSuccessStatusCode)
            {
                var buff = await response.Content.ReadAsStringAsync();
                // AuthData
                // var mm = JsonConvert.DeserializeObject<AuthData>(buff);
                var result = JsonSerializer.Deserialize<TRes>(buff, Options);
                Result = result;
                Status = 200;
                return result;

            }
            throw new ArgumentOutOfRangeException("Failed to login");
        }

        public void UpdateProfile(TReq model, string bearer)
        {
            try
            {
                Post("/api/user", bearer, model);
            }
            catch (ArgumentOutOfRangeException ex)
            {
                throw new ArgumentException(ex.Message);
            }
        }

        public async Task<TRes> GetContacts(string bearer)
        {
            return await Get("/api/contacts/", bearer);
        }

        HttpClient GetClient(string bearer, string apiUrl)
        {
            var client = new HttpClient
            {
                BaseAddress = new Uri(apiUrl)
            };
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", bearer);
            return client;

        }
        // Task<TRes> Post(string url, string bearer, TReq req)
        public async Task<TRes> Put(string uri, string bearer, TReq model)
        {
            var apiUrl = BaseUrl + uri;
            using var client = GetClient(bearer, apiUrl);



            var jsonInString = JsonSerializer.Serialize<TReq>(model, Options);
            HttpResponseMessage response;
            if (jsonInString == "\"\"")
                response = await client.PutAsync(apiUrl, null);
            else
                response = await client.PutAsync(apiUrl, new StringContent(jsonInString, Encoding.UTF8, "application/json"));

            if (response.IsSuccessStatusCode)
            {
                var buff = await response.Content.ReadAsStringAsync();
                if (string.IsNullOrEmpty(buff))
                {
                    Result = null;
                    Status = 200;
                    return Result;
                }
                var result = JsonSerializer.Deserialize<TRes>(buff, Options);
                Result = result;
                Status = 200;
                return result;

            }
            throw new ArgumentOutOfRangeException("Failed to fetch");
        }

        public async Task<TRes> Delete(string url, string bearer, TReq model)
        {
            var apiUrl = BaseUrl + url;
            using var client = GetClient(bearer, apiUrl);




            HttpResponseMessage response;

            response = await client.DeleteAsync(apiUrl);

            if (response.IsSuccessStatusCode)
            {
                var buff = await response.Content.ReadAsStringAsync();
                if (string.IsNullOrEmpty(buff))
                {
                    Result = null;
                    Status = 200;
                    return Result;
                }
                var result = JsonSerializer.Deserialize<TRes>(buff, Options);
                Result = result;
                Status = 200;
                return result;

            }
            throw new ArgumentOutOfRangeException("Failed to fetch");
        }

        public async Task<TRes> GetStors(string bearer)
        {
            return await Get( "/api/store/", bearer);
        }
    }
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы