Capítulo 7: Adición de funcionalidades á aplicación
Kiana e Maria están encantadas de mostrarlle a aplicación de xestión de inventario a Caleb, o técnico de campo. Gústalle, pero suxire engadir algunha funcionalidade adicional de interface de usuario para que sexa máis doada de usar. En concreto, a Caleb gustaríalle poder:
Engadir unha fotografía do traballo realizado nunha caldeira ou unidade de aire acondicionado e engadila aos detalles da cita na pantalla Editar cita. Esta imaxe pode resultar útil como proba documental das reparacións realizadas. A pantalla Editar cita permite ao usuario engadir unha imaxe á cita, pero a imaxe non se garda xa que esta función aínda non se implementou completamente. O motivo desta omisión é que Kiana e Preeti precisan determinar o mellor lugar para almacenar os datos de imaxe. A Caleb gustaríalle que esta funcionalidade se engadise canto antes.
Consultar un historial de citas completo para un cliente, para realizar un seguimento das reparacións que se solicitaron e supervisar os problemas en curso que poidan requirir que os técnicos sexan chamados repetidamente.
Encargar pezas desde a pantalla Detalles da peza.
Ademais, o control de imaxe na pantalla Detalles da peza mostra as imaxes almacenadas nun URL especificado. Actualmente os URL dos datos son simplemente marcadores de posición. Do mesmo xeito que as fotografías da pantalla de citas, Kiana e Preeti precisan determinar o mellor lugar para gardar as imaxes para que estean dispoñibles para a aplicación.
Engadir unha fotografía a unha cita
As fotografías deben gardarse nalgún lugar accesible pola aplicación. Por razóns de rendemento e seguridade, Preeti non quere que se garden fotografías en OneDrive nin en Azure SQL Database. Pola contra, ela e Kiana deciden usar Azure Blob Storage. O almacenamento de BLOB está optimizado para manter obxectos binarios grandes e é robusto, con seguridade incorporada. Power Apps ten un conector que permite o acceso ao almacenamento de BLOB. María suxire engadir unha nova pantalla para facer fotos, o cal mellora a experiencia de usuario de Caleb.
Máis información: Azure Blob Storage
Preeti crea a conta do almacenamento de BLOB desde o portal de Azure seguindo estes pasos:
No portal de Azure, na páxina Inicio, seleccionar + Crear un recurso. Na caixa Buscar no Marketplace, inserir a Conta de almacenamento e, a continuación, seleccionar Intro.

Na páxina Conta de almacenamento, seleccionar Crear.
Na páxina Crear unha conta de almacenamento, introducir os seguintes detalles e logo seleccionar Revisar + crear:
- Subscrición: Seleccione a súa subscrición
- Grupo de recursos: webapi_rg
- Nome da conta de almacenamento: proporcionar un nome exclusivo a nivel mundial e anotalo para máis tarde
- Localización: seleccionar a súa situación máis próxima
- Rendemento: Estándar
- Tipo de conta: BlobStorage
- Replicación: RA-GRS

Na páxina de validación, seleccionar Crear e agardar a que se subministre a conta de almacenamento.
Ir á páxina da nova conta de almacenamento.
Na páxina Visión xeral, seleccionar Contedores.

Na páxina Contedores, seleccionar + Contedor. Crear un novo contedor chamado fotos e, a continuación, seleccionar Crear. Cambiar Nivel de acceso público a Blob.

De volta na páxina Visión xeral da conta de almacenamento, en Configuración, seleccionar Chaves de acceso. Na páxina Chaves de acceso, seleccionar Mostrar claves. Anotar o valor da clave para clave1.

Preeti dálle o nome e a clave da conta de almacenamento a Kiana, que usa esta información para crear un conector personalizado para a aplicación seguindo estes pasos:
Inicie sesión en Power Apps.
No panel da esquerda, expandir Datos e seleccionar Conexións. Deben enumerarse as conexións existentes empregadas pola aplicación. Seleccione + Nova conexión.

Na páxina Nova conexión, desprazarse cara abaixo, seleccione Conexións, seleccionar Azure Blob Storage e, a continuación, seleccionar Crear.

No diálogo Azure Blob Storage, introducir o nome da conta de almacenamento e a clave de acceso que proporcionou Preeti e logo seleccionar Crear.

Agardar mentres se crea a nova conexión. Debe aparecer na lista de conexións.
María pode usar esta conexión co almacenamento de BLOB na aplicación para gardar e recuperar imaxes fotográficas. A súa primeira tarefa é engadir a conexión á aplicación seguindo estes pasos:
Abrir a aplicación VanArsdelApp para editar en Power Apps Studio.
No panel Datos, seleccionar Engadir datos, buscar o conector de Azure Blob Storage e logo seleccionar o conector.

No diálogo Azure Blob Storage, seleccionar o conector de Azure Blob Storage para engadilo á súa aplicación.

A seguinte tarefa de María é engadir unha pantalla que permita a un técnico ou enxeñeiro gardar unha fotografía. María decide engadir unha nova pantalla cun control de imaxe. Cando a aplicación se executa nun dispositivo móbil, este control pode integrarse coa cámara para permitir ao técnico facer unha fotografía. Noutros dispositivos, este control solicita ao usuario que cargue un ficheiro de imaxe. Engade unha ligazón a esta nova pantalla desde a pantalla EditAppointment seguindo estes pasos:
No menú Inserir, seleccionar Nova pantalla e, a continuación, seleccionar o modelo Desprazable.

No panel Vista en árbore, seleccionar a nova pantalla e renomeala como TakePhoto.
Cambiar a propiedade de Texto do control LblAppNameXnesta pantalla a Facer unha fotografía.
Eliminar o control CanvasX da pantalla.
No menú Inserir, desde a lista despregable Elementos multimedia, seleccionar Engadir imaxe para crear un novo control de imaxe.

Nota
O control de imaxe é realmente un compoñente personalizado composto que permite ao usuario engadir unha imaxe á pantalla e amosar os resultados.
Cambiar o tamaño e recolocar o control da imaxe para ocupar o corpo da pantalla.
No panel Vista en árbore, seleccionar o control IconBackarrowX na pantalla Detalles da cita e logo seleccionar Copiar.

No menú Vista en árbore, facer clic co botón dereito na pantalla TakePhoto e logo seleccionar Pegar. O control IconBackArrowX engadirase á pantalla.

Mover o control IconBackArrowX á parte superior esquerda da barra de cabeceira.
No panel Vista en árbore, seleccionar o control IconBackArrowX na pantalla TakePhoto. No panel dereito, no separador Avanzado, modificar a propiedade da acción OnSelect a Navigate(EditAppointment, ScreenTransition.None).
Engadir un novo control de icona de Gardar na parte superior dereita da barra de cabeceira. Configurar a propiedade Visible deste control en If(IsBlank(AddMediaButton1.Media), false, true).
Esta configuración fai a icona Gardar invisible se o usuario non seleccionou unha imaxe.

Cambiar a fórmula na propiedade de acción OnSelect do control da icona Gardar ao seguinte.
Set(ImageID, GUID() & ".jpg"); AzureBlobStorage.CreateFile("photos", ImageID, AddMediaButton1.Media); Patch(appointmentsCollection, LookUp(appointmentsCollection,id=BrowseAppointmentsGallery.Selected.id), {imageUrl:"https://myappphotos.blob.core.windows.net/photos/" & ImageID}); Navigate(EditAppointment,ScreenTransition.Cover);Substituír <storage account name> polo nome da conta de almacenamento de Azure que creou Preeti.
Este código carga a imaxe no contedor de fotos no almacenamento de BLOB. Cada imaxe recibe un nome de ficheiro único. A función Patch actualiza a propiedade imageUrl no rexistro de citas co URL da imaxe no almacenamento de BLOB.
No panel Vista en árbore, expandir o control AddMediaWithImageX. Modificar a propiedade Imaxe do control UploadedImageX e configuralo en AppointmentImage.
AppointmentImage é unha variable que se encherá cunha imaxe cargada polo usuario ou como resultado de facer unha fotografía. Inicializará esta variable na pantalla EditAppointment máis tarde.
No panel Vista en árbore, seleccionar o control AddMediaButtonX. Configurar a propeidade UseMobileCamera deste control en verdadeiro. Configurar a propiedade de acción OnChange do control ao seguinte.
Set(AppointmentImage, AddMediaButton1.Media)Esta fórmula cambia a variable AppointmentImage para facer referencia á nova imaxe. O control UploadedImageX amosará esta imaxe.
No panel Visualización en árbore, seleccionar a pantalla EditAppointment.
Expandir o control EditFormX. No control Image_DataCardX, eliminar o control AddPictureX.

Seleccionar o control ImageX. Cambiar as seguintes propiedades:
- Imaxe: Parent.Default
- X: 30
- Y: DataCardKey X.Y + DataCardKey X.Height + 150 (onde DataCardKeyX é a tarxeta de datos que contén o control ImageX)
- Ancho: Parent.Width - 60
- Altura: 400
Nota
O control da imaxe caerá debaixo da parte inferior da pantalla, pero engadirase automaticamente unha barra de desprazamento para permitir a visualización da imaxe.
Engadir unha icona de Cámara na tarxeta de datos e logo colocala entre a etiqueta Imaxe e o control ImageX. Cambiar o nome do control a CameraIcon.
Nota
Asegúrese de seleccionar o control da icona da cámara, non o control de elementos multimedia da cámara.

Configurar a propiedade de acción OnSelect do control CameraIcon ao seguinte.
Set(AppointmentImage, SampleImage); Navigate(TakePhoto, ScreenTransition.None);Cando o usuario seleccione esta icona, dirixirase á pantalla TakePhoto, onde pode facer unha foto ou cargar unha imaxe. A imaxe inicial mostrada será a imaxe de mostra predeterminada.
Para probar a aplicación, faga o seguinte:
No panel Visualización en árbore, seleccione a pantalla Inicio.
Seleccione F5 para previsualizar a aplicación.
Na pantalla de Inicio, seleccione Citas.
Na pantalla de exploración, seleccione calquera cita.
Na pantalla de detalles da cita, seleccione a icona de edición na cabeceira da pantalla.
Na pantalla de edición, seleccione a icona de Cámara da imaxe.
Verifique que a pantalla Facer unha fotografía aparece.
Seleccione Cambiar imaxe e cargue unha foto que escolla (ou faga unha fotografía, se está a executar a aplicación nun dispositivo móbil).
Seleccione Gardar. Comprobe que a imaxe aparece na páxina de detalles e seleccione a icona de marca para gardar os cambios na base de datos.
Peche a xanela de vista previa e volva a Power Apps Studio.
Amosar imaxes de pezas
Unha vez determinado que o almacenamento de BLOB é un lugar ideal para gardar imaxes asociadas ás citas, Preeti e Kiana deciden que deben empregar o mesmo enfoque para gardar as imaxes das pezas. Unha vantaxe clave deste enfoque é que non require modificacións na aplicación. A aplicación reutiliza a mesma conta de almacenamento e a mesma conexión. Como exercicio de migración separado, poden facer o seguinte:
Crear un novo contedor de almacenamento de BLOB.
Cargar as imaxes da peza neste contedor.
Cambiar as referencias de ImageUrl na táboa Pezas na base de datos InventoryDB co URL de cada imaxe.
A aplicación recollerá automaticamente o novo URL para cada imaxe da peza e o control de Imaxe na pantalla PartDetails amosará a imaxe.
Seguimento do historial de citas dun cliente
María pensa que poder ver rapidamente todo o historial das visitas do técnico anterior dun cliente podería engadirse á aplicación creando un compoñente personalizado. Traballando con Caleb sobre a información que queren ver, María esbozou un deseño sinxelo que inclúe as notas e a data de cada visita.

Mirando os datos, María cre que un control de galería é a mellor forma de amosar os datos da táboa nunha pantalla.
María crea o compoñente personalizado do seguinte xeito:
Usando Power Apps Studio, no panel Vista en árbore, selecciona Compoñentes e, a continuación, selecciona + Novo compoñente.

Un novo compoñente en branco chamado Compoñente1 créase. Cambia o nome do compoñente a DateHistoryComponent.

No menú Inserir, selecciona Galería e, a continuación, escolle o modelo de galería Altura flexible en branco.

Move o control da galería e redimensiona para encher o compoñente personalizado.
Selecciona o panel Engadir un elemento desde o panel de inserción e logo selecciona Etiqueta de texto.

No panel Vista en árbore, renomea o control de etiqueta como NotesLabel. Configura a propieade Desbordamento en Overflow.Scroll. Esta configuración permite que o control mostre varias liñas de texto e permite ao usuario desprazalo. Estableza as seguintes propiedades para que poida situar e dimensionar o control:
- LineHeight: 2
- X: 28
- Y: 18
- Largura: 574
- Altura: 140
Engade unha segunda etiqueta de texto ao control. Cambia o nome deste control a DataLabel e configura as seguintes propiedades:
- LineHeight: 2
- X: 28
- Y: 174
- Largura: 574
- Altura: 70
Para ver como quedará o control cando se insire na aplicación e se mostre co seu tema, no panel Vista en árbore, selecciona DataHistoryComponent. No panel dereito, no separador Avanzado, seleccione o campo Encher e cambie a cor a RGBA(0, 0, 0, 1).

No panel Inserir, expanda Formas e engada un control Rectángulo ao compoñente personalizado. Estableza as seguintes propiedades para este control:
- X: 0
- Y: 273
- Ancho: Parent.Width
- Altura: 2
Este control actúa como separador entre os rexistros mostrados na galería.

María sabe como engadir controis ás pantallas e crear aplicacións con Power Apps. Non obstante, os compoñentes reutilizables non funcionan do mesmo xeito. Kiana describiulle a María que, para poder usar datos nun compoñente personalizado, debe engadir algunhas propiedades de entrada personalizadas adicionais. Kiana tamén explicou que Maria necesita proporcionar datos de exemplo para estas propiedades, para permitirlle facer referencia aos campos de datos nos controis do seu compoñente, do seguinte xeito:
No panel Visualización en árbore, seleccione DateHistoryComponent. No panel dereito, no separador Propiedades, seleccione Nova propiedade personalizada.

No diálogo Nova propiedade personalizada, especifique os seguintes valores e logo seleccione Crear:
- Nome para mostrar: Datas
- Nome: Datos
- Descrición: A táboa de citas dun cliente, que mostra as notas e as datas
- Tipo de propiedade: Entrada
- Tipo de datos: Táboa
- Aumentar OnReset cando o valor cambie: deixar en branco

Para cambiar os datos de mostra mostrados polo control, seleccione o novo a propiedade personalizada Datos. No campo da fórmula, introduza Table({Notes: "Exemplo de texto do campo de notas", 'Appointment Date': Text(Today())}).

No panel de Vista en árbore, seleccione o control GalleryX en DateHistoryComponent e renoméeo como AppointmentHistory.
No panel dereito, no separador Avanzado, configure a propiedade Elementos do control de galería AppointmentHistory a Parents.Data.

Seleccione o control NotesLabel. No panel dereito do separador Avanzado, cambie a propiedade de Texto a ThisItem.Notes e cambie a propiedade de Tamaño a 20.
Nota
A propiedade de Tamaño especifica o tamaño da letra para o texto mostrado polo control.
Seleccione o control DataLabel para cambiar a propiedade de Texto a ThisItem.'Appointment Date' e cambia a propiedade de Tamaño a 20. Os campos do compoñente personalizado deben mostrar os datos de mostra.

O compoñente personalizado está completo. María crea unha nova pantalla para amosar o historial de citas dun cliente usando este compoñente, do seguinte xeito:
No panel Visualización en árbore, seleccione o separador Pantallas.
Amplíe a pantalla BrowseAppointments, despregue o control BrowseAppointmentsGallery e seleccione o control Body1_1. No menú Inserir, seleccione Iconas e, a continuación, seleccione a icona Lista de detalles.

Cambie o nome do control da icona a ViewAppointments.
No menú Vista en árbore, seleccione o control BrowseAppointmentsGallery. No panel dereito, no separador Avanzado, cambie a propiedade TemplateSize a 220. Ao aumentar esta propiedade amplíase o espazo dispoñible na galería.
Mova a icona TemplateSize no espazo baleiro debaixo do nome do cliente.

Seleccione o control da icona ViewAppointments. Configure a propiedade de acción OnSelect na seguinte fórmula.
ClearCollect(customerAppointmentsCollection, FieldEngineerAPI.getapicustomeridappointments(ThisItem.customerId)); Navigate(AppointmentsHistoryScreen, ScreenTransition.Fade)Esta fórmula enche unha colección chamada customerAppointmentsCollection coas citas do cliente seleccionado e despois móvese a AppointmentHistoryScreen para amosalas. Creará esta pantalla nos seguintes pasos.
No menú Inserir, seleccionar Nova pantalla e, a continuación, seleccionar o modelo Desprazable.

Cambie o nome da nova pantalla a AppointmentHistoryScreen.
Elimine o control CanvasX que se engadiu a esta pantalla.

Seleccione o control LblAppNameX nesta pantalla. No panel dereito, no separador Avanzado, cambie a propiedade Texto ao seguinte.
"Appointments History for " & BrowseAppointmentsGallery.Selected.customer.nameEstableza as seguintes propiedades para o control LblAppNameX para axustar a posición e o tamaño:
- X: 90
- Y: 0
- Largura: 550
- Altura: 140
Seleccione o control RectQuickActionBarX e configure a propiedade de Altura en 140.
Engada un control de Icona esquerda á cabeceira da pantalla, á esquerda do título. Configure a propiedade de acción OnSelect deste control en Navigate(BrowseAppointments, Transition.None).

No menú Inserir, seleccione Personalizado e, a continuación, seleccione DateHistoryComponent.

Mova e redimensione o compoñente para que ocupe o corpo da pantalla, debaixo do título.

Estableza as seguintes propiedades para este compoñente:
- Datos: customerAppointmentsCollection
- Data da cita: startDateTime
- Notas: notas
Gardar a aplicación
Para probar a aplicación, faga o seguinte:
No panel Visualización en árbore, seleccione a pantalla Inicio.
Seleccione F5 para previsualizar a aplicación.
Na pantalla de Inicio, seleccione Citas.
Na pantalla de exploración, seleccione a icona Lista de detalles para calquera cita.
Verifique que a pantalla Historial de citas aparece para o cliente seleccionado.
Peche a xanela de vista previa e volva a Power Apps Studio.
Pedido de pezas
Un requisito fundamental do sistema é permitir que un técnico poida encargar as pezas necesarias mentres visita un cliente. Se as pezas están en stock, debería ser posible programar outra visita para completar a reparación na próxima data conveniente para o cliente. Se as pezas están esgotadas actualmente e hai que solicitalas, o técnico pode avisar ao cliente. Malik pode concertar unha cita co cliente cando María reciba o aviso de que as pezas chegaron ao almacén.
A parte de reservas da aplicación usa as táboas da base de datos InventoryDB mostrada na seguinte imaxe. A táboa Pedidos contén información sobre pedidos feitos de pezas. A táboa Reservas lista as solicitudes de reserva que os técnicos e os enxeñeiros fixeron para as pezas. A táboa Enxeñeiros proporciona o nome e o número de contacto do enxeñeiro que realizou a reserva, o que facilita a consulta de María, se é necesario, a xestora do inventario.

Para admitir esta función, Kiana ten que actualizar a API web cun método que obtén o número de elementos reservados para unha peza especificada, do seguinte xeito:
Abra o proxecto da API web FieldEngineerApi en Visual Studio Code.
Engada un ficheiro chamado Order.cs ao cartafol Modelos. Engada o seguinte código a este ficheiro. A clase Pedidos rastrexa os detalles dos pedidos realizados para as pezas.
using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace FieldEngineerApi.Models { public class Order { [Key] public long Id { get; set; } public long BoilerPartId { get; set; } public BoilerPart BoilerPart { get; set; } public long Quantity { get; set; } [Column(TypeName = "money")] public decimal TotalPrice { get; set; } [Display(Name = "OrderedDate")] [DataType(DataType.DateTime)] [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")] public DateTime OrderedDateTime { get; set; } public bool Delivered { get; set; } [Display(Name = "DeliveredDate")] [DataType(DataType.DateTime)] [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")] public DateTime? DeliveredDateTime { get; set; } } }Engada outro ficheiro novo chamado Reservation.cs ao cartafol Modelos e engada o seguinte código a este ficheiro. A clase Reserva contén información sobre o número de elementos dunha peza determinada que están actualmente reservados para outros clientes.
using System; using System.ComponentModel.DataAnnotations; namespace FieldEngineerApi.Models { public class Reservation { [Key] public long Id { get; set; } public long BoilerPartId { get; set; } public BoilerPart BoilerPart { get; set; } public int NumberToReserve { get; set; } public string EngineerId { get; set; } public InventoryEngineer Engineer { get; set; } } }Engada un ficheiro máis, chamado InventoryEngineer.cs, ao cartafol Modelos, co seguinte código. A clase InventoryEngineer rexistra que enxeñeiros fixeron que reservas.
using System.ComponentModel.DataAnnotations; using System.Collections.Generic; namespace FieldEngineerApi.Models { public class InventoryEngineer { [Key] public string Id { get; set; } [Required] public string Name { get; set; } public string ContactNumber { get; set; } public List<Reservation> Reservations { get; set; } } }Abra o ficheiro InventoryContext.cs no cartafol Modelos e engada as seguintes instrucións á clase InventoryContext.
public class InventoryContext : DbContext { public InventoryContext(DbContextOptions\<InventoryContext\> options) : base(options) { } public DbSet<BoilerPart> BoilerParts { get; set; } public DbSet<InventoryEngineer> Engineers { get; set; } public DbSet<Order> Orders { get; set; } public DbSet<Reservation> Reservations { get; set; } }Na xanela Terminal en Visual Studio Code, execute os seguintes comandos para crear controladores para xestionar pedidos e reservas.
dotnet aspnet-codegenerator controller ^ -name OrdersController -async -api ^ -m Order ^ -dc InventoryContext -outDir Controllers dotnet aspnet-codegenerator controller ^ -name ReservationsController -async -api ^ -m Reservation ^ -dc InventoryContext -outDir ControllersAbra o ficheiro BoilerPartController.cs no cartafol Controladores e engada o seguinte método GetTotalReservations para a clase BoilerPartsController.
public class BoilerPartsController : ControllerBase { private readonly InventoryContext _context; public BoilerPartsController(InventoryContext context) { _context = context; } ... // GET: api/BoilerParts/5/Reserved [HttpGet("{id}/Reserved")] public async Task<ActionResult<object>> GetTotalReservations(long id) { var reservations = await _context .Reservations .Where(r => r.BoilerPartId == id) .ToListAsync(); int totalReservations = 0; foreach(Reservation reservation in reservations) { totalReservations += reservation.NumberToReserve; } return new {id, totalReservations}; } ... }Edite o ficheiro OrdersController.cs e modifique o metodo PostOrder na clase OrdersController como mostra o seguinte.
[HttpPost] public async Task<ActionResult<Order>> PostOrder(long boilerPartId, int quantity) { var part = await _context.BoilerParts.FindAsync(boilerPartId); Order order = new Order { BoilerPartId = boilerPartId, Quantity = quantity, OrderedDateTime = DateTime.Now, TotalPrice = quantity * part.Price }; _context.Orders.Add(order); await _context.SaveChangesAsync(); return CreatedAtAction("GetOrder", new { id = order.Id }, order); }Edite o ficheiro ReservationsController.cs. Modifique o método PostReservation na clase ReservationsController, do seguinte xeito.
[HttpPost] public async Task<ActionResult<Reservation>> PostReservation(long boilerPartId, string engineerId, int quantityToReserve) { Reservation reservation = new Reservation { BoilerPartId = boilerPartId, EngineerId = engineerId, NumberToReserve = quantityToReserve }; _context.Reservations.Add(reservation); await _context.SaveChangesAsync(); return CreatedAtAction("GetReservation", new { id = reservation.Id }, reservation); }Na xanela Terminal, execute os seguintes comandos para crear e publicar a API web lista para o seu despregamento.
dotnet build dotnet publish -c Release -o ./publishEn Visual Studio Code, faga clic co botón dereito do rato no cartafol publicar e logo seleccione Implementar na aplicación web.
Preeti agora pode actualizar o servizo de xestión da API utilizado pola aplicación VanArsdel para reflectir a API web actualizada. Este é un cambio non desestabilizador; as operacións existentes seguirán funcionando, a diferenza son os novos controladores e as operacións para facer reservas e facer pedidos. Preeti realiza as seguintes tarefas:
Nota
Preeti podería optar por eliminar a API do enxeñeiro de campo existente e substituíla por unha nova versión, pero ese enfoque corre o risco de desestabilizar as aplicacións existentes que estean a usar actualmente a API. É mellor deixar o API existente no lugar e engadir as modificacións como revisión.
No portal de Azure, vaia ao servizo de xestión da API.
Na páxina Servizo de xestión de API, no panel esquerdo baixo API, seleccione API.
Seleccione oa API de enxeñeiro de campo, seleccione o menú de puntos suspensivos e, a continuación, seleccione Engadir revisión.

No diálogo Crear unha nova revisión da API do enxeñeiro de campo, introduza a descrición Engadíronse operacións GET e operacións POST para reservas de pezas e pedidos e, a continuación, seleccione Crear.

Na páxina REVISIÓN 2, seleccione Deseñar.

Na páxina Deseñar, seleccione Engadir operación. No panel FrontEnd, configure as seguintes propiedade e seleccione Gardar. Esta operación úsase para recuperar o número de elementos reservados para unha determinada peza de caldeira:
- Nome de visualización: api/BoilerParts/{id}/Reserved
- Nome: api-boilerparts-id-reserved
- URL: GET api/BoilerParts/{id}/Reserved

No separador Proba da nova operación, configure o parámetro id válido (o exemplo da imaxe usa a peza 1) e logo seleccione Enviar.

Verifique que a proba ten éxito. A operación debería completarse cunha resposta HTTP 200 e un corpo que mostre o número de reservas do produto.

Na páxina Deseñar, seleccione Engadir operación. No panel FrontEnd, configure as seguintes propiedades (esta operación define as solicitudes POST para crear novos pedidos):
- Nome de visualización: api/Orders - POST
- Nome: api-orders-post
- URL: POST api/Orders
No consulta Consulta, seleccione + Engadir parámetro, engada os seguintes parámetros e logo seleccione Gardar:
- Nome: boilerPartId, descrición : ID da peza da caldeira, tipo: longo
- Nome: cantidade, Descrición : Cantidade, Tipo: núm. enteiro

Seleccione Engadir operación de novo no panel FrontEnd e configure as seguintes propiedades (esta operación define as solicitudes POST para crear novas reservas):
- Nome de visualización: api/Reservations - POST
- Nome de visualización: api-reservations-post
- URL: POST api/Reservations
No separador Consulta, engada os seguintes parámetros e logo seleccione Gardar:
- Nome: boilerPartId, descrición: ID da peza da caldeira, tipo: longo
- Nome: engineerId, Descrición: Identificación de enxeñeiro, Tipo: cadea
- Nome: quantityToReserve, Descrición: Cantidade que se vai reservar, Tipo: núm. enteiro
No separador Revisións, seleccione a nova versión. No menú de puntos suspensivos desta versión, seleccione Facer actual.

No diálogo Facer revisión actual, seleccione Gardar.
Abra outra páxina no navegador web e vaia ao URL https://<APIM name>.azure-api.net/api/boilerparts/1/reserved onde <APIM name> é o nome do seu servizo de API. Verifique que obtén unha resposta similar á seguinte.
{"id":1,"totalReservations":5}
A API web actualizada xa está dispoñible. En teoría, Kiana podería crear un novo conector personalizado para a API web actualizada e engadilo á aplicación. A aplicación podería entón implementar a súa propia lóxica para determinar cantos elementos do produto especificado están actualmente en stock, cantos están reservados, comparar os resultados co número de artigos necesarios, realizar un pedido para máis stock se é necesario ou reservar artigos do stock existente. Non obstante, este tipo de lóxica está mellor implementado nunha aplicación lóxica de Azure. Power Apps pode chamar a aplicación lóxica a través dun conector personalizado cando un técnico desexe reservar ou pedir unha peza.
Para crear a aplicación lóxica, Kiana segue os seguintes pasos:
Nota
Para simplificar as cousas, a aplicación lóxica creada neste exemplo non é transaccional. É posible que entre comprobar a dispoñibilidade dunha peza e facer unha reserva, un usuario simultáneo poida facer unha reserva conflitiva. Pode implementar a semántica transaccional substituíndo parte da lóxica desta aplicación lóxica por un procedemento almacenado na base de datos InventoryDB.
No portal de Azure, na páxina Inicio, seleccionar + Crear un recurso.
Na caixa Buscar no Marketplace, insera a Aplicación lóxica e, a continuación, seleccione Intro.
Na páxina Aplicación lóxica, seleccione Crear.

Na páxina Crear unha aplicación lóxica, introduza os seguintes vañpres e logo seleccione Revisar + crear:
- Subscrición: Seleccione a súa subscrición de Azure
- Grupo de recursos: webapi_rg
- Nome da aplicación lóxica: FieldEngineerPartsOrdering
- Rexión: seleccione a mesma situación que utilizou para a API web
- Asociar ao contorno do servizo de integración: déixeo en branco
- Activar a análise de rexistros: déixeo en branco
Na páxina de verificación, seleccione Crear e agarde mentres se desprega a aplicación lóxica.
Cando finalice o despregamento, seleccione Ir ao recurso.
Na páxina Deseñador de aplicacións lóxicas, desprácese ata a páxina Modelos e logo seleccione Aplicación lóxica en branco.

No separador Todo, na caixa de texto Buscar conectores e disparadores, seleccione Solicitude.

No separador Disparadores, seleccione Cando se recibe unha solicitude HTTP.

Na caixa Solicitar esquema JSON do corpo, introduza o seguinte esquema e seleccione + Novo paso.
{ "type": "object", "properties": { "boilerPartId": { "type": "integer" }, "numberToReserve": { "type": "integer" }, "engineerId": { "type": "string" } } }
Este esquema define o contido da solicitude HTTP que espera a aplicación lóxica. O corpo da solicitude comprende o identificador dunha peza de caldeira, o número de elementos que hai que reservar e p identificador do enxeñeiro que realiza a solicitude. A aplicación enviará esta solicitude cando un enxeñeiro queira reservar unha peza.
Na caixa Escoller unha operación, seleccione Todo e, a continuación, seleccione HTTP.

A aplicación lóxica chamará a operación BoilerParts{id} da API web para recuperar información sobre a peza da caldeira proporcionada pola solicitude da aplicación.
No panel Accións, seleccione a acción HTTP.

Na caixa de acción HTTP, no menú de puntos suspensivos, seleccione Cambiar o nome e cambie o nome da acción a CheckBoilerPart.

Estableza as propiedades da acción HTTP do seguinte xeito e logo seleccione + Novo Paso:
- Método: GET
- URI: https://<APIM name>.azure-api.net/api/boilerparts/, onde <APIM name>_ é o nome do seu servizo de xestión de API. Na caixa _ Contido dinámico deste URI, no separador Contido dinámico, seleccione boilerPartId

Na caixa Escoller unha operación, na caixa Buscar conectores e accións, insira Analizar JSON e, a continuación, seleccione a acción Analizar JSON.

Usando o menú de puntos suspensivos da acción Analizar JSON, renomee a acción como ParseBoilerPart.
Na caixa Contido da acción ParseBoilerPart, na caixa Contido dinámico, seleccione Corpo. Na caixa Esquema, introduza o seguinte esquema JSON e seleccione + Novo paso.
{ "type": "object", "properties": { "id": { "type": "integer" }, "name": { "type": "string" }, "categoryId": { "type": "string" }, "price": { "type": "number" }, "overview": { "type": "string" }, "numberInStock": { "type": "integer" }, "imageUrl": { "type": "string" }, } }
Esta acción analiza a mensaxe de resposta devolta pola solicitude getBoilerParts/{id}. A resposta contén os detalles da peza da caldeira, incluído o número actualmente en stock.
Na caixa Escoller unha operación do novo paso, seleccione o conector HTTP.
No separador Accións, seleccione a acción HTTP.
Usando o menú de puntos suspensivos da operación, renomee a operación como CheckReservations.
Estableza as propiedades seguintes desta operación e logo seleccione + Novo paso:
- Método: GET
- URI: https://<APIM name>.azure-api.net/api/boilerparts/. Como antes, na caixa Contido dinámico deste URI, no separador Contido dinámico, seleccione boilerPartId. No campo URI, engada o texto /reservado tras o marcador de posición boilerPartId

Na caixa Escoller unha operación da nova acción, na caixa Buscar conectores e accións, insira Analizar JSON e, a continuación, seleccione a acción Analizar JSON.
Cambie o nome da operación a ParseReservacións.
Configure a propiedade Contido en Corpo.
Introduza a seguinte esquema e, a seguir, seleccione + Novo paso.
{ "type": "object", "properties": { "id": { "type": "integer" }, "totalReservations": { "type": "integer" } } }
Na caixa Escoller unha operación da nova acción, na caixa Buscar conectores e accións, insira Condición e, a continuación, seleccione a acción Control da condición.

Cambie o nome da operación a CompareStock.
Seleccionea caixa Escoller un valor. Na caixa Engadir contido dinámico, no separador Expresión, introduza a seguinte expresión e logo seleccione Aceptar.
add(body('ParseReservations')?['totalReservations'], triggerBody()?['numberToReserve'])Esta expresión calcula a suma do número de elementos da peza da caldeira especificada que están actualmente reservados e o número solicitado polo enxeñeiro.

No cadro de lista despregable de condicións, seleccione é maior que.
Na caixa restante Escoller un valor, na caixa Contido dinámico, no separador Contido dinámico, baixo ParseBoilerPart, seleccione numberInStock.

Se o número de artigos requiridos mais o número reservado é maior que o stock, a aplicación debe realizar un pedido para repoñer o inventario. Na póla Verdadeiro da acción CompareStock, seleccione Engadir unha acción.
No separador Todo da nova operación, seleccione HTTP e, a continuación, seleccione a acción HTTP.
Cambie o nome da operación a PostOrder.
Estableza as seguintes propiedades da operación PostOrder:
- Método: POST
- URI: https://<APIM name>.azure-api.net/api/orders
- Na táboa Consultas, na primeira fila, introduza a clave boilerPartId. Para o valor da caixa Engadir contido dinámico, no separador Contido dinámico, seleccione boilerPartId
- Na seguinda fila da táboa Consultas, introduza a clave cantidade. No campo de valores, introduza 50.

A aplicación lóxica pedirá automaticamente 50 elementos da peza especificada cando o stock estea esgotado.
Nota
A aplicación lóxica supón que o enxeñeiro non intentará reservar máis de 50 elementos dunha peza especificada nunha soa solicitude.
Deixe a póla Falso da acción CompareStock baleira.
Debaixo da acción CompareStock, seleccione + Novo paso.
No separador Todo da nova operación, seleccione HTTP e, a continuación, seleccione a acción HTTP.
Cambie o nome da operación a PostReservation.
Estableza as seguintes propiedades da operación PostReservation:
- Método: POST
- URI: https://<APIM name>.azure-api.net/api/reservations
- Na táboa Consultas, na primeira fila, introduza a clave boilerPartId. Para o valor da caixa Engadir contido dinámico, no separador Contido dinámico, seleccione boilerPartId.
- Na segunda fila, introduza a clave enxeñeiroId. Para o valor da caixa Engadir contido dinámico, no separador Contido dinámico, seleccione engineerId.
- Na terceira fila, introduza a clave quantityToReserve. Para o valor da caixa Engadir contido dinámico, no separador Contido dinámico, seleccione numberToReserve.
Seleccione + Novo paso. Na caixa Escoller unha operación, busque e seleccione a acción Resposta.
Estableza as propiedades seguintes da acción de resposta:
- Código de estado: 200
- Cabeceiras: clave - content-type, valor - application/json
- Corpo: na caixa Contido dinámico, seleccione o elemento Corpo da solicitude PostReservation. Este é o corpo devolto cando se fai a reserva.

Na parte superior esquerda da páxina Deseñador de aplicacións lóxicas, seleccione Gardar. Comprobe que a aplicación lóxica se pode gardar sen erros.
Para crear o conector personalizado que Power Apps pode usar para activar a aplicación lóxica, Kiana realiza os seguintes pasos mentres aínda está no portal de Azure:
Na páxina Visión xeral da aplicación lóxica, seleccione Exportar.

No panel Exportar a Power Apps, nomee o conector PartsOrderingConnector, seleccione o seu ambiente de Power Apps e seleccione Aceptar.

Inicie sesión en Power Apps.
No seu contorno, baixo Datos, seleccione Conectores personalizados e comprobe que o PartsOrderingConnector está listado.

María agora pode modificar a aplicación VanArsdel para que un técnico poida pedir pezas mentres asista a un sitio do cliente. Ela engade un botón de Pedir botón para a pantalla PartDetails, do seguinte xeito:
Inicie sesión en Power Apps (se aínda non está conectado).
Baixo Aplicacións, seleccione a aplicación VanArsdelApp. No menú de puntos suspensivos da aplicación, seleccione Editar.
No panel Datos, seleccione Engadir datos, busque o conector PartsOrderingConnector e engada unha nova conexión usando ese conector.

No panel Vista en árbore, expanda a pantalla PartDetails e, a continuación, expanda o formulario DetailForm1.
No panel de propiedades á dereita, seleccione Editar campos. No panel Campos no menú de puntos suspensivos, seleccione Engadir unha tarxeta personalizada.

No panel Vista en árbore renomee a nova tarxeta de DataCard1 a ReserveCard. Na ventá Deseñar vista, redimensione a tarxeta para que ocupe a parte inferior da pantalla, debaixo do control Image_DataCard1.

No menú Inserir, desde o submenú Entrada, engada un control de Entrada de texto, un control de Botón e un control de Etiqueta ao control ReserveCard.
Redimensione e coloca os controis de xeito que estean adxacentes, co control de Botón á dereita do control de Entrada de texto e o control de Etiqueta debaixo do control de Botón.
No panel de Propiedades do control de Entrada de texto, borre a propiedade Predeterminado.
No panel de Propiedades do control de botón, configure a propiedade de texto en Reservar.

Cambie o nome do control de Entrada de texto a NumberToReserve, renomee o control de Botón como Reservar e renomee o control de Etiqueta como Mensaxe.
No panel Propiedades do control Mensaxe, configure a propiedade de Texto en Pezas reservadas e configure a propiedade Visible en MessageIsVisible.
Nota
MessageIsVisible é unha variable á que inicializará en falso cando se amose a pantalla, pero cambiarase a certo se o usuario selecciona o botón Reservar.
Configure a propiedade OnSelect do botón Reservar na seguinte fórmula.
FieldEngineerPartsOrdering.manualinvoke({boilerPartId:ThisItem.id, engineerId:"ab9f4790-05f2-4cc3-9f01-8dfa7d848179", numberToReserve:NumberToReserve.Text}); Set(MessageIsVisible, true);Nota
Esta fórmula usa un ID de enxeñeiro codificado para representar ao técnico que está executando a aplicación. O capítulo 8 describe como recuperar o ID do usuario con sesión iniciada.
Ademais, a aplicación non realiza ningunha comprobación de erros; asume que a solicitude de reserva de pezas sempre ten éxito. Para obter máis información sobre o tratamento de erros, vaia a Función de erros en Power Apps.
Configure a propiedade OnVisible da pantalla PartDetails en Set(MessageIsVisible, false).
Para probar a aplicación, faga o seguinte:
No panel Visualización en árbore, seleccione a pantalla Inicio.
Seleccione F5 para previsualizar a aplicación.
Na pantalla de Inicio, seleccione Pezas.
Na pantalla de exploración, seleccione calquera peza.
Na pantalla Detalles da peza, desprácese ata a sección de reservas, introduza un valor enteiro positivo e seleccione Reservar. Verifique que a mensaxe Pezas reservadas aparece.

Peche a xanela de vista previa e volva a Power Apps Studio.
No portal de Azure, vaia á páxina da Base de datos SQL InventoryDB.
Seleccione o Editor de consultas e inicie sesión como sqladmin co seu contrasinal.
No panel Consulta 1, introduza a seguinte consulta e seleccione Executar. Verifique que apareza a reserva que fixo na aplicación VanArsdel.
SELECT * FROM [dbo].[Reservations]
Comentarios
Enviar e ver os comentarios