XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

STHApplication

【MAUI】寄当家——安卓端交易管理系统

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Globalization;
using System.Text.Json;
using JiDangJia.Contracts;
using JiDangJia.Services;

namespace JiDangJia.Views;

public sealed class ServicePublishPage : ContentPage
{
    private readonly string account=AuthClient.Current.AccountId,path;private readonly CommunityPost? editing;
    private readonly Picker category=new(){Title="服务分类"};private readonly Entry project=new(){Placeholder="服务项目 *",MaxLength=120},minimum=new(){Placeholder="最低 / 固定收费 *",Keyboard=Keyboard.Numeric},maximum=new(){Placeholder="最高收费(固定价可留空)",Keyboard=Keyboard.Numeric},unit=new(){Placeholder="计费单位,如件 / 次",MaxLength=24},city=new(){Placeholder="城市 *",MaxLength=60},address=new(){Placeholder="可公开的服务地址 *",MaxLength=200};
    private readonly Editor details=new(){Placeholder="详细说明 *",MaxLength=2000,HeightRequest=160};private readonly Switch buyback=new(){IsToggled=true,OnColor=Ui.Bronze};private readonly CommunityPhotos photos;private bool published;private string nonce=Guid.NewGuid().ToString("N"),attempt="";
    private readonly VerticalStackLayout media=Ui.Stack();
    private readonly PostingLocationField publishingLocation;
    private sealed record Draft(int Category,string Project,string Min,string Max,string Unit,bool Buyback,string Details,string City,string Address,List<CommunityPhotos.Photo> Photos,string CategoryKey="");
    public ServicePublishPage(CommunityPost? editing=null)
    {
        this.editing=editing;publishingLocation=new(editing);Title=editing is null?"发布服务卡片":"编辑服务卡片";path=Path.Combine(FileSystem.AppDataDirectory,"social-draft-"+account+"-SERVICE.json");Draft? saved=null;try{if(editing is null&&File.Exists(path))saved=JsonSerializer.Deserialize<Draft>(File.ReadAllText(path));}catch(Exception ex)when(ex is IOException or JsonException){}
        var service=editing?.Service;var legacyKeys=new[]{"LUXURY","TOBACCO_ALCOHOL","CAR","OTHER"};var draftKey=saved is null?"LUXURY":saved.CategoryKey.Length>0?saved.CategoryKey:legacyKeys.ElementAtOrDefault(saved.Category)??"LUXURY";
        category.ItemsSource=ServiceCatalog.Categories.Values.ToList();category.SelectedIndex=Math.Max(0,ServiceCatalog.Categories.Keys.ToList().IndexOf(service?.Category??draftKey));project.Text=service?.Project??saved?.Project??"奢侈品鉴定服务";minimum.Text=service?.FeeMin.ToString(CultureInfo.InvariantCulture)??saved?.Min;maximum.Text=service?.FeeMax.ToString(CultureInfo.InvariantCulture)??saved?.Max;unit.Text=service?.Unit??saved?.Unit??"件";details.Text=service?.Description??saved?.Details;buyback.IsToggled=service?.Buyback??saved?.Buyback??true;city.Text=editing?.City??saved?.City??CommunityLocation.City;address.Text=editing?.Address??saved?.Address??CommunityLocation.Address;
        string defaultProject=ServiceCatalog.Categories.Values.ElementAt(category.SelectedIndex)+"服务";category.SelectedIndexChanged+=(_,_)=>{var next=ServiceCatalog.Categories.Values.ElementAt(category.SelectedIndex)+"服务";if(editing is null&&(string.IsNullOrWhiteSpace(project.Text)||project.Text==defaultProject))project.Text=next;defaultProject=next;};photos=new(9,editing?.Media,saved?.Photos);
        SetMedia();category.SelectedIndexChanged+=(_,_)=>SetMedia();var body=Ui.Stack(Ui.Card(Ui.Stack(Ui.Section("服务项目与收费"),category,project,Ui.Text("固定收费填写最低价;区间收费填写最低与最高。",12,Ui.Muted),Ui.Spread(minimum,maximum),unit,Ui.Spread(Ui.Text("提供兜底回购服务"),buyback),details)),publishingLocation.View,Ui.Card(media),Ui.Text("服务以用户填写的项目、收费与详细说明为准;发布后直接展示。",12,Ui.Muted),Ui.Button(editing is null?"提交服务卡片":"保存修改",Publish));body.Padding=18;Content=new ScrollView{Content=body};
    }
    private bool SystemIcon=>category.SelectedIndex>=0&&ServiceCatalog.Categories.Keys.ElementAt(category.SelectedIndex)!="OTHER";
    private void SetMedia(){media.Clear();if(SystemIcon)media.Add(CommunityUi.SystemMark(ServiceCatalog.Categories.Values.ElementAt(category.SelectedIndex)));else{media.Add(Ui.Section("服务图片(选填,最多 9 张)"));media.Add(photos.View);}}
    private async Task Publish()
    {
        if(account!=AuthClient.Current.AccountId)throw new InvalidOperationException("账户已切换");if(!await CommunitySafetyUi.Write(this))return;
        if(!decimal.TryParse(minimum.Text,NumberStyles.Number,CultureInfo.InvariantCulture,out var min)||min<0)throw new ArgumentException("请填写非负收费金额");decimal max=min;if(!string.IsNullOrWhiteSpace(maximum.Text)&&!decimal.TryParse(maximum.Text,NumberStyles.Number,CultureInfo.InvariantCulture,out max))throw new ArgumentException("最高收费格式错误");
        var service=new ServiceCard(ServiceCatalog.Categories.Keys.ElementAt(Math.Max(0,category.SelectedIndex)),project.Text?.Trim()??"",min,max,unit.Text?.Trim()??"",buyback.IsToggled,details.Text?.Trim()??"");if(service.Project.Length==0||service.Description.Length==0)throw new ArgumentException("请填写项目与详细说明");
        var gps=await publishingLocation.Get();
        if(editing is null){var quota=await AuthClient.Current.CommunityRequest<SupplyQuota>("/supply/quota");if(quota.Active>=quota.Limit)throw new ArgumentException($"服务与供需合计已达上限({quota.Active}/{quota.Limit}),请先下架一张");}
        var ids=SystemIcon?new List<string>():await photos.Upload();var payload=JsonSerializer.Serialize(new{service,ids,city=city.Text,address=address.Text});if(payload!=attempt){attempt=payload;nonce=Guid.NewGuid().ToString("N");}await AuthClient.Current.CommunityRequest<CommunityPost>(editing is null?"/posts":$"/posts/{editing.Id}/edit",new PublishPostRequest(service.Project,service.Description,nonce,"SERVICE",gps?.City??editing?.City??"","",ids,null,service,gps));published=true;if(editing is null)File.Delete(path);await DisplayAlertAsync("已提交","服务卡片已发布,可在我的发布管理。","完成");await Navigation.PopAsync();
    }
    protected override async void OnAppearing(){base.OnAppearing();try{if(await CommunitySafetyUi.Write(this))await publishingLocation.Start();}catch(Exception ex){await DisplayAlertAsync("无法加载",ex.Message,"知道了");}}
    protected override void OnDisappearing(){if(!published&&editing is null&&!AccountDataClear.InProgress&&account==AuthClient.Current.AccountId)try{File.WriteAllText(path,JsonSerializer.Serialize(new Draft(category.SelectedIndex,project.Text??"",minimum.Text??"",maximum.Text??"",unit.Text??"",buyback.IsToggled,details.Text??"",city.Text??"",address.Text??"",photos.Draft(),ServiceCatalog.Categories.Keys.ElementAt(category.SelectedIndex))));}catch(IOException){}base.OnDisappearing();}
}