iT邦幫忙

2021 iThome 鐵人賽

DAY 28
3
自我挑戰組

【Side Project】 系列 第 28

【Side Project】 (老闆)訂單清單-與資料庫交換資料

上一篇中,我們已經處理完前端每份餐點、每張訂單的狀態都處理完了。
順帶一提,如果要在使用返回按鍵時保留原本餐點的狀態時,
我們可以在undo_order()中增加以下兩行程式碼:

cb_id = `cb_${head.uid}_${item.uid}`
$(`#${cb_id}`).prop('checked', item.itemDone)

https://ithelp.ithome.com.tw/upload/images/20211011/20115941lvs7PNyGlq.jpg

這篇開始我們會將前端的清單資料,
與後台資料庫中的資料做交換。
這邊會分成幾個部份去處理:

  1. 將資料傳到後台
  2. 取得後台新的資料
  3. 更新渲染畫面
  4. 交換資料的時機

資料交換

  1. 打開 Proprietor.cshtml
  2. ajax建立與後台的連線
function Exchange(is_init) {
        //第一次進網頁則刪除原本的localStorage
        if (is_init) {
            localStorage.removeItem('done_data')
            localStorage.removeItem('undo_data')
            
        }

        var done_data = localStorage.getItem('done_data') === null ? [] : JSON.parse(localStorage.getItem("done_data"))
        var undo_data = localStorage.getItem("undo_data") === null ? [] : JSON.parse(localStorage.getItem("undo_data"))
        var data = undo_data
        done_data.forEach((item) => {
            data[data.length] = item
        })
        var data_string = JSON.stringify(data)
        
        $.ajax({
        url: "@Url.Action("ExchangeData")",
            type: "post",
            data: {
                "data": data_string
            },
            dataType: "json",
            success: function (new_data) {
                var done_data = localStorage.getItem('done_data') === null ? [] : JSON.parse(localStorage.getItem("done_data"))
                var undo_data = localStorage.getItem("undo_data") === null ? [] : JSON.parse(localStorage.getItem("undo_data"))
                
                new_data.forEach((item) => {
                    
                    if (item.head.orderDone) {
                        done_order(item.head, item.bodys)
                        done_data[done_data.length] = item
                    }
                    else {
                        undo_order(item.head, item.bodys)
                        undo_data[undo_data.length] = item
                    }
                })
                localStorage.setItem("undo_data", JSON.stringify(undo_data))
                localStorage.setItem("done_data", JSON.stringify(done_data))

        },
        error: function (xhr, ajaxOptions, thrownError) {
            alert("status: " + xhr.status);
            alert(xhr.responseText);
            alert(thrownError);
        },
        complete: function () {}

        })
    }
  1. 設定觸發時機
<script>
    //初始化
    Exchange(true)
    // 固定時間交換資料
    setInterval(Exchange, 10000,false);
</script>
  1. 打開HomeController.cs 新增 ExchangeData()
[HttpPost]
        public IActionResult ExchangeData(string data)
        {
            Console.WriteLine("data:" + data);
            
            var proprietor = ProprietorModel.proprietor;
            //更新資料
            bool successful = proprietor.UpdateOrder(_config, data);
            //取得今天的訂單清單
            var orders = proprietor.SelectOrder(_config);
            //比對出新的資料
            var new_orders = proprietor.DataCompare(orders, data);
            //自動轉成json格式
            return Json(new_orders);
        }
  1. 打開 ProprietorModel.cs
  2. 新增 UpdateOrder()
public bool UpdateOrder(IConfiguration config,string orders_string)
        {
            var successful = false;
            var orders = JsonConvert.DeserializeObject<List<Order>>(orders_string);
            //連線設定
            SqlSugarClient db = new SqlSugarClient(new ConnectionConfig()
            {
                //連線字串
                ConnectionString = config.GetValue<string>("WebmenuConnectionString"),
                DbType = DbType.SqlServer,//連線類型
                IsAutoCloseConnection = true //自動關閉連線
            });


            try
            {

                //當執行時,觸發事件
                db.Aop.OnLogExecuting = (sql, pars) =>
                {
                    Console.WriteLine(sql);//查看SQL語法
                };
                //begin tran
                db.BeginTran();
                //取得菜單表頭,並排序(正序)
                foreach(var order in orders)
                {
                    //更新表頭中的訂單狀態
                    var result_h = db.Updateable(order.head).UpdateColumns(head => new { head.OrderDone }).ExecuteCommand();
                    //更新表身中的餐點狀態
                    var result_b = db.Updateable(order.bodys).UpdateColumns(body => new { body.ItemDone }).ExecuteCommand();
                }
                db.CommitTran();
                successful = true;
            }
            catch
            {
                successful = false;
                db.RollbackTran();//rollback
                throw;
            }
            return successful;
        }
  1. 新增SelectOrder()
public List<Order> SelectOrder(IConfiguration config)
        {
            var order_list = new List<Order>();
            //連線設定
            SqlSugarClient db = new SqlSugarClient(new ConnectionConfig()
            {
                //連線字串
                ConnectionString = config.GetValue<string>("WebmenuConnectionString"),
                DbType = DbType.SqlServer,//連線類型
                IsAutoCloseConnection = true //自動關閉連線
            });


            try
            {

                //當執行時,觸發事件
                db.Aop.OnLogExecuting = (sql, pars) =>
                {
                    Console.WriteLine(sql);//查看SQL語法
                };
                //begin tran
                db.BeginTran();
                //取得菜單表頭,並排序(正序)
                var list_h = db.Queryable<Menulisth>().Where(head => head.Createtime >= DateTime.Today).OrderBy(head => head.Createtime, OrderByType.Asc).ToList();
                var list_b = db.Queryable<Menulistb, Menulisth>((body, head) => new JoinQueryInfos(JoinType.Left, head.Uid == body.H_uid))
                    .Where((body, head) => head.Createtime >= DateTime.Today)
                    .OrderBy((body, head) => head.Createtime, OrderByType.Asc)
                    .Select<Menulistb>().ToList();
                //將表頭加入到表身資料寫入
                foreach (var head in list_h)
                {
                    head.Formnum = head.Formnum.Replace(" ", "").Trim();
                    var order = new Order();
                    //加入表頭
                    order.head = head;
                    //加入表身
                    foreach (var body in list_b)
                    {
                        if (body.H_uid == head.Uid)
                        {
                            body.Item = body.Item.Replace(" ", "").Trim();
                            order.bodys.Add(body);
                        }
                    }
                    order_list.Add(order);

                }

                db.CommitTran();
            }
            catch
            {
                db.RollbackTran();//rollback
                throw;
            }
            return order_list;
        }
  1. 新增 DataCompare()
public List<Order> DataCompare(List<Order> db_orders, string data)
        {
            var client_orders = JsonConvert.DeserializeObject<List<Order>>(data);
            var order_Enumable = from db in db_orders
                        where !(from client in client_orders
                                select client.head.Uid)
                                .Contains(db.head.Uid)
                        select db;
            var orders = order_Enumable.ToList();
            return orders;
        }

這樣就完成了。來看一下完整的Proprietor.cshtml 中script語法
https://ithelp.ithome.com.tw/upload/images/20211011/20115941ETV0g3Go9m.jpg
9. 成果
https://i.imgur.com/2BGc63y.gif

結語

前面做的時候分成未完成清單、和已完成清單兩個部分來實作。
當開發到後面的時候會發現,其實這兩段程式碼有非常多重覆的地方。
像是這樣的情形在開發中很常會發生,
我們可以透過不斷的CodeReview,來精簡程式碼。
這樣久而久之就能撰寫出更加優美的程式碼。


上一篇
【Side Project】 (老闆)訂單清單UX功能實作2-ChcekBox
下一篇
【Side Project】 (老闆)訂單清單-未完成餐點提示
系列文
【Side Project】 30

1 則留言

0
wesleybabytw
iT邦新手 5 級 ‧ 2021-11-08 10:45:06

執行後,返回無法保留狀態,也無法定時做交換。
不清楚是什麼步驟有異常。

手動完成或返回,資料庫資料(itemDone)皆不會有異動

修正第21篇寫法後,就正常了

kyminjob iT邦新手 5 級 ‧ 2021-11-09 16:44:43 檢舉

恭喜~~

我要留言

立即登入留言