Compare commits
17
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
23149aa131 | ||
|
|
1092a7c43d | ||
|
|
0c0aba2aeb | ||
|
|
e81df4f55c | ||
|
|
07e0a1996f | ||
|
|
79f58a36e3 | ||
|
|
7c5278bc88 | ||
|
|
c995daf48d | ||
|
|
d95a00b8a9 | ||
|
|
13f893cd0c | ||
|
|
8eae8c2b3c | ||
|
|
532f840a78 | ||
|
|
21b9b03014 | ||
|
|
4047cd67d8 | ||
|
|
441d40b584 | ||
|
|
915e20cd23 | ||
|
|
d0fa46a8c8 |
Binary file not shown.
@@ -2,271 +2,472 @@
|
|||||||
"class_names": [
|
"class_names": [
|
||||||
"三黄鸡",
|
"三黄鸡",
|
||||||
"上海青WP2026020200041",
|
"上海青WP2026020200041",
|
||||||
|
"丝瓜WP2026032300114",
|
||||||
|
"乳瓜WP2026032000107",
|
||||||
|
"冬瓜WP2026032300115",
|
||||||
|
"冰糖",
|
||||||
"冰草WP2026020900054",
|
"冰草WP2026020900054",
|
||||||
"刀豆",
|
"刀豆",
|
||||||
"北豆腐WP2025111900007",
|
"北豆腐WP2025111900007",
|
||||||
|
"南瓜[倭瓜,番瓜]",
|
||||||
"味精WP2026013000034",
|
"味精WP2026013000034",
|
||||||
"圆生菜WP2026020900053",
|
"圆生菜WP2026020900053",
|
||||||
"圆白菜[卷心菜,包菜]WP2025111000063",
|
|
||||||
"基围虾WP2025110700019",
|
"基围虾WP2025110700019",
|
||||||
"多宝鱼WP2025112600011",
|
"多宝鱼WP2025112600011",
|
||||||
"大白菜(代表值)WP2026022800638",
|
"大白菜(代表值)WP2026031700085",
|
||||||
"大葱WP2026013000025",
|
"大葱WP2026013000026",
|
||||||
|
"大蒜(去皮)WP2026020200011",
|
||||||
|
"大蒜(带皮)WP2026020300046",
|
||||||
|
"奶白菜",
|
||||||
|
"姜(子姜)[嫩姜]",
|
||||||
"姜[黄姜]WP2026022800956",
|
"姜[黄姜]WP2026022800956",
|
||||||
"娃娃菜WP2026020200005",
|
"娃娃菜WP2026020200005",
|
||||||
"小白菜WP2026022800031",
|
"小白菜WP2026022800031",
|
||||||
"小米辣椒WP2026013000027",
|
"小米辣椒WP2026013000027",
|
||||||
"小葱WP2026013000029",
|
"小葱WP2026013000029",
|
||||||
|
"小鸡腿(带骨)",
|
||||||
"山药(带皮)WP2026020200008",
|
"山药(带皮)WP2026020200008",
|
||||||
"巨人笋",
|
"巨人笋",
|
||||||
|
"平菇[糙皮侧耳,青蘑]WP2026031700086",
|
||||||
"广东菜心WP2025120100014",
|
"广东菜心WP2025120100014",
|
||||||
|
"新世纪哈密瓜",
|
||||||
|
"明虾",
|
||||||
"木耳(干)[黑木耳,云耳]WP2026022801182",
|
"木耳(干)[黑木耳,云耳]WP2026022801182",
|
||||||
"杏鲍菇WP2026022700030",
|
"杏鲍菇WP2026022700030",
|
||||||
"松花蛋",
|
"松花蛋",
|
||||||
"松茸菌WP2025120100016",
|
"松茸菌WP2025120100016",
|
||||||
|
"槐花[洋槐花,豆槐花]",
|
||||||
|
"橙",
|
||||||
"沙葱",
|
"沙葱",
|
||||||
|
"油麦菜WP2026031200077",
|
||||||
"海带(浸)[江白菜,昆布]WP2026022800035",
|
"海带(浸)[江白菜,昆布]WP2026022800035",
|
||||||
|
"淀粉(马铃薯)",
|
||||||
|
"湿米线过桥米线",
|
||||||
|
"火龙果(带皮)",
|
||||||
|
"炒饼丝",
|
||||||
|
"牛肉(腹部肉)[牛腩]",
|
||||||
|
"牛肚",
|
||||||
"牛腩WP2025110700043",
|
"牛腩WP2025110700043",
|
||||||
"猪五花肉WP2026020300048",
|
"猪五花肉WP2026020300048",
|
||||||
"猪腿肉WP2025110700040",
|
"猪小排(带骨)",
|
||||||
|
"猪排(带骨)WP2026031200078",
|
||||||
|
"猪肉(瘦)",
|
||||||
|
"猪肉(腿)WP2026022800033",
|
||||||
|
"猪肉(里脊)WP2026021000025",
|
||||||
|
"猪肝(鲜)WP2026032000105",
|
||||||
|
"猪肾(fat8g)[猪腰子]",
|
||||||
"玉米WP2025120100017",
|
"玉米WP2025120100017",
|
||||||
"玉米糁(黄)WP2026022800038",
|
"玉米糁(黄)WP2026022800038",
|
||||||
|
"甜椒[灯笼椒,柿子椒]WP2026020500018",
|
||||||
|
"生菜(叶用莴苣)WP2026020500020",
|
||||||
|
"生蚝",
|
||||||
"番茄[西红柿]WP2026021000028",
|
"番茄[西红柿]WP2026021000028",
|
||||||
"白吉饼WP2026013000024",
|
"白吉饼WP2026013000024",
|
||||||
|
"白玉菇WP2026031100072",
|
||||||
|
"白菜薹[菜薹,菜心]WP2026031100068",
|
||||||
|
"白萝卜WP2026031200079",
|
||||||
|
"石斑鱼(整条鱼)",
|
||||||
"笋",
|
"笋",
|
||||||
"粉丝",
|
"粉丝",
|
||||||
"紫甘蓝",
|
"素鸡WP2026031700096",
|
||||||
"红心萝卜[心里美]WP2026022800368",
|
"红心萝卜[心里美]WP2026022800368",
|
||||||
"红提子WP2025111900006",
|
"红提子WP2025111900006",
|
||||||
"红椒WP2026030300055",
|
"红椒WP2026030300055",
|
||||||
"红洋葱WP2026030600054",
|
"红洋葱WP2026030600054",
|
||||||
"红美人椒WP2026020300049",
|
"红美人椒WP2026020300049",
|
||||||
"红薯",
|
"红薯",
|
||||||
|
"红薯粉条WP2026031700091",
|
||||||
"红薯粉条(袋)",
|
"红薯粉条(袋)",
|
||||||
|
"结球甘蓝(紫)[圆白菜]WP2026020500017",
|
||||||
|
"结球甘蓝(绿)[圆白菜]WP2026032300116",
|
||||||
|
"绿豆芽WP2026031100073",
|
||||||
"羊排WP2025120300021",
|
"羊排WP2025120300021",
|
||||||
"羊血WP2026013000038",
|
"羊血WP2026013000038",
|
||||||
"胡萝卜WP2025110600008",
|
"胡萝卜WP2025110600008",
|
||||||
|
"腰果(熟)",
|
||||||
"芋头",
|
"芋头",
|
||||||
|
"芥蓝[甘蓝菜,盖蓝菜]",
|
||||||
|
"芦笋(绿)[石刁柏,龙须菜]",
|
||||||
"花卷",
|
"花卷",
|
||||||
"芹菜WP2025111000065",
|
"花椒(粉)",
|
||||||
|
"花生仁(生)WP2026032000102",
|
||||||
|
"花螺",
|
||||||
|
"芹菜(茎)[旱芹,药芹]WP2026022800032",
|
||||||
"苦菊",
|
"苦菊",
|
||||||
|
"苹果(代表值)WP2026032300117",
|
||||||
"茄子(紫皮,长)WP2025110700024",
|
"茄子(紫皮,长)WP2025110700024",
|
||||||
"茼蒿WP2026020200045",
|
"茼蒿WP2026020200045",
|
||||||
|
"草鱼",
|
||||||
|
"荷兰豆WP2026032000104",
|
||||||
"莲藕(带皮)",
|
"莲藕(带皮)",
|
||||||
"莴笋(鲜)[莴苣]WP2026020200009",
|
"莴笋(鲜)[莴苣]WP2026020200009",
|
||||||
"菜花(白色)[花椰菜]",
|
"菜花(白色)[花椰菜]WP2026030600057",
|
||||||
"菠菜(鲜)[赤根菜]WP2026022800700",
|
"菠菜(鲜)[赤根菜]WP2026022800700",
|
||||||
"蒜WP2025111400003",
|
"菠萝[凤梨,地菠萝]",
|
||||||
"蒜苗WP2026013000028",
|
"蒜苗WP2026013000028",
|
||||||
"蒜薹(圆)",
|
"蒜薹(圆)",
|
||||||
"蒸鱼豉油WP2026013000032",
|
"蒸鱼豉油WP2026013000032",
|
||||||
|
"蕹菜[空心菜,藤藤菜]",
|
||||||
"薏米[薏仁米,苡米]WP2026022800037",
|
"薏米[薏仁米,苡米]WP2026022800037",
|
||||||
"西兰花[绿菜花]WP2025110700029",
|
"虫草花(干)WP2026032000108",
|
||||||
"西葫芦",
|
"蛏子",
|
||||||
"豆腐皮WP2025111000059",
|
"西兰花[绿菜花]WP2026031100071",
|
||||||
"豆角",
|
"西瓜(代表值)",
|
||||||
|
"西芹[西洋芹菜,美芹]WP2026031100069",
|
||||||
|
"西葫芦WP2026021000027",
|
||||||
|
"豆腐干(代表值)",
|
||||||
|
"豆腐皮WP2026031700097",
|
||||||
|
"豆角豇豆WP2026021000026",
|
||||||
|
"赤小豆[小豆,红小豆](干)WP2026032300118",
|
||||||
"辣椒(红,小)WP2025111000066",
|
"辣椒(红,小)WP2025111000066",
|
||||||
"辣椒(青,尖)WP2026022800504",
|
"辣椒(青,尖)WP2026030600056",
|
||||||
|
"辣椒段(干)",
|
||||||
"醪糟",
|
"醪糟",
|
||||||
"金针菇[(鲜)[智力菇]WP2026030600051",
|
"金针菇[(鲜)[智力菇]WP2026030600051",
|
||||||
"青线椒WP2026013000031",
|
"青线椒WP2026013000031",
|
||||||
|
"青美人椒辣椒(青,尖)",
|
||||||
|
"青花椒鲜花椒",
|
||||||
|
"面条(生,代表值)WP2026030600055",
|
||||||
|
"面条(生,炒细面",
|
||||||
"韭菜WP2026020200044",
|
"韭菜WP2026020200044",
|
||||||
|
"韭薹",
|
||||||
"韭黄",
|
"韭黄",
|
||||||
"馒头(代表值)WP2026030600056",
|
"馒头(代表值)WP2026030600056",
|
||||||
"香椿[香椿芽]WP2026022801086",
|
"香椿[香椿芽]WP2026022801086",
|
||||||
"香菇(鲜)[香蕈,冬菇]WP2026030600050",
|
"香菇(鲜)[香蕈,冬菇]WP2026030600050",
|
||||||
"香菜WP2026013000030",
|
"香菜WP2026013000030",
|
||||||
"马铃薯[土豆、洋芋]WP2026012900001",
|
"马铃薯[土豆、洋芋]WP2026012900001",
|
||||||
|
"鱿鱼(鲜,中国枪乌贼)[枪乌贼]",
|
||||||
|
"鲍鱼(带壳)",
|
||||||
|
"鲑鱼[大马哈鱼,三文鱼]",
|
||||||
|
"鲜猪精排",
|
||||||
"鸡全腿(带骨)",
|
"鸡全腿(带骨)",
|
||||||
"鸡翅(带骨)",
|
"鸡翅(带骨)",
|
||||||
|
"鸡胸脯肉WP2026022802698",
|
||||||
"鸡腿肉WP2025110700048",
|
"鸡腿肉WP2025110700048",
|
||||||
"鸡腿(带骨)",
|
|
||||||
"鸡蛋WP2026013000039",
|
"鸡蛋WP2026013000039",
|
||||||
"麦芹",
|
"鸭(均值)",
|
||||||
|
"鸭蛋黄",
|
||||||
"黄瓜(鲜)[胡瓜]WP2025110700031",
|
"黄瓜(鲜)[胡瓜]WP2025110700031",
|
||||||
|
"黄豆",
|
||||||
"黄豆芽WP2026020200042",
|
"黄豆芽WP2026020200042",
|
||||||
|
"黑米WP2026031200081",
|
||||||
"黑袋子",
|
"黑袋子",
|
||||||
"黑鱼(整条鱼)WP2025110600012"
|
"黑鱼(整条鱼)WP2025110600012"
|
||||||
],
|
],
|
||||||
"class_to_idx": {
|
"class_to_idx": {
|
||||||
"三黄鸡": 0,
|
"三黄鸡": 0,
|
||||||
"上海青WP2026020200041": 1,
|
"上海青WP2026020200041": 1,
|
||||||
"冰草WP2026020900054": 2,
|
"丝瓜WP2026032300114": 2,
|
||||||
"刀豆": 3,
|
"乳瓜WP2026032000107": 3,
|
||||||
"北豆腐WP2025111900007": 4,
|
"冬瓜WP2026032300115": 4,
|
||||||
"味精WP2026013000034": 5,
|
"冰糖": 5,
|
||||||
"圆生菜WP2026020900053": 6,
|
"冰草WP2026020900054": 6,
|
||||||
"圆白菜[卷心菜,包菜]WP2025111000063": 7,
|
"刀豆": 7,
|
||||||
"基围虾WP2025110700019": 8,
|
"北豆腐WP2025111900007": 8,
|
||||||
"多宝鱼WP2025112600011": 9,
|
"南瓜[倭瓜,番瓜]": 9,
|
||||||
"大白菜(代表值)WP2026022800638": 10,
|
"味精WP2026013000034": 10,
|
||||||
"大葱WP2026013000025": 11,
|
"圆生菜WP2026020900053": 11,
|
||||||
"姜[黄姜]WP2026022800956": 12,
|
"基围虾WP2025110700019": 12,
|
||||||
"娃娃菜WP2026020200005": 13,
|
"多宝鱼WP2025112600011": 13,
|
||||||
"小白菜WP2026022800031": 14,
|
"大白菜(代表值)WP2026031700085": 14,
|
||||||
"小米辣椒WP2026013000027": 15,
|
"大葱WP2026013000026": 15,
|
||||||
"小葱WP2026013000029": 16,
|
"大蒜(去皮)WP2026020200011": 16,
|
||||||
"山药(带皮)WP2026020200008": 17,
|
"大蒜(带皮)WP2026020300046": 17,
|
||||||
"巨人笋": 18,
|
"奶白菜": 18,
|
||||||
"广东菜心WP2025120100014": 19,
|
"姜(子姜)[嫩姜]": 19,
|
||||||
"木耳(干)[黑木耳,云耳]WP2026022801182": 20,
|
"姜[黄姜]WP2026022800956": 20,
|
||||||
"杏鲍菇WP2026022700030": 21,
|
"娃娃菜WP2026020200005": 21,
|
||||||
"松花蛋": 22,
|
"小白菜WP2026022800031": 22,
|
||||||
"松茸菌WP2025120100016": 23,
|
"小米辣椒WP2026013000027": 23,
|
||||||
"沙葱": 24,
|
"小葱WP2026013000029": 24,
|
||||||
"海带(浸)[江白菜,昆布]WP2026022800035": 25,
|
"小鸡腿(带骨)": 25,
|
||||||
"牛腩WP2025110700043": 26,
|
"山药(带皮)WP2026020200008": 26,
|
||||||
"猪五花肉WP2026020300048": 27,
|
"巨人笋": 27,
|
||||||
"猪腿肉WP2025110700040": 28,
|
"平菇[糙皮侧耳,青蘑]WP2026031700086": 28,
|
||||||
"玉米WP2025120100017": 29,
|
"广东菜心WP2025120100014": 29,
|
||||||
"玉米糁(黄)WP2026022800038": 30,
|
"新世纪哈密瓜": 30,
|
||||||
"番茄[西红柿]WP2026021000028": 31,
|
"明虾": 31,
|
||||||
"白吉饼WP2026013000024": 32,
|
"木耳(干)[黑木耳,云耳]WP2026022801182": 32,
|
||||||
"笋": 33,
|
"杏鲍菇WP2026022700030": 33,
|
||||||
"粉丝": 34,
|
"松花蛋": 34,
|
||||||
"紫甘蓝": 35,
|
"松茸菌WP2025120100016": 35,
|
||||||
"红心萝卜[心里美]WP2026022800368": 36,
|
"槐花[洋槐花,豆槐花]": 36,
|
||||||
"红提子WP2025111900006": 37,
|
"橙": 37,
|
||||||
"红椒WP2026030300055": 38,
|
"沙葱": 38,
|
||||||
"红洋葱WP2026030600054": 39,
|
"油麦菜WP2026031200077": 39,
|
||||||
"红美人椒WP2026020300049": 40,
|
"海带(浸)[江白菜,昆布]WP2026022800035": 40,
|
||||||
"红薯": 41,
|
"淀粉(马铃薯)": 41,
|
||||||
"红薯粉条(袋)": 42,
|
"湿米线过桥米线": 42,
|
||||||
"羊排WP2025120300021": 43,
|
"火龙果(带皮)": 43,
|
||||||
"羊血WP2026013000038": 44,
|
"炒饼丝": 44,
|
||||||
"胡萝卜WP2025110600008": 45,
|
"牛肉(腹部肉)[牛腩]": 45,
|
||||||
"芋头": 46,
|
"牛肚": 46,
|
||||||
"花卷": 47,
|
"牛腩WP2025110700043": 47,
|
||||||
"芹菜WP2025111000065": 48,
|
"猪五花肉WP2026020300048": 48,
|
||||||
"苦菊": 49,
|
"猪小排(带骨)": 49,
|
||||||
"茄子(紫皮,长)WP2025110700024": 50,
|
"猪排(带骨)WP2026031200078": 50,
|
||||||
"茼蒿WP2026020200045": 51,
|
"猪肉(瘦)": 51,
|
||||||
"莲藕(带皮)": 52,
|
"猪肉(腿)WP2026022800033": 52,
|
||||||
"莴笋(鲜)[莴苣]WP2026020200009": 53,
|
"猪肉(里脊)WP2026021000025": 53,
|
||||||
"菜花(白色)[花椰菜]": 54,
|
"猪肝(鲜)WP2026032000105": 54,
|
||||||
"菠菜(鲜)[赤根菜]WP2026022800700": 55,
|
"猪肾(fat8g)[猪腰子]": 55,
|
||||||
"蒜WP2025111400003": 56,
|
"玉米WP2025120100017": 56,
|
||||||
"蒜苗WP2026013000028": 57,
|
"玉米糁(黄)WP2026022800038": 57,
|
||||||
"蒜薹(圆)": 58,
|
"甜椒[灯笼椒,柿子椒]WP2026020500018": 58,
|
||||||
"蒸鱼豉油WP2026013000032": 59,
|
"生菜(叶用莴苣)WP2026020500020": 59,
|
||||||
"薏米[薏仁米,苡米]WP2026022800037": 60,
|
"生蚝": 60,
|
||||||
"西兰花[绿菜花]WP2025110700029": 61,
|
"番茄[西红柿]WP2026021000028": 61,
|
||||||
"西葫芦": 62,
|
"白吉饼WP2026013000024": 62,
|
||||||
"豆腐皮WP2025111000059": 63,
|
"白玉菇WP2026031100072": 63,
|
||||||
"豆角": 64,
|
"白菜薹[菜薹,菜心]WP2026031100068": 64,
|
||||||
"辣椒(红,小)WP2025111000066": 65,
|
"白萝卜WP2026031200079": 65,
|
||||||
"辣椒(青,尖)WP2026022800504": 66,
|
"石斑鱼(整条鱼)": 66,
|
||||||
"醪糟": 67,
|
"笋": 67,
|
||||||
"金针菇[(鲜)[智力菇]WP2026030600051": 68,
|
"粉丝": 68,
|
||||||
"青线椒WP2026013000031": 69,
|
"素鸡WP2026031700096": 69,
|
||||||
"韭菜WP2026020200044": 70,
|
"红心萝卜[心里美]WP2026022800368": 70,
|
||||||
"韭黄": 71,
|
"红提子WP2025111900006": 71,
|
||||||
"馒头(代表值)WP2026030600056": 72,
|
"红椒WP2026030300055": 72,
|
||||||
"香椿[香椿芽]WP2026022801086": 73,
|
"红洋葱WP2026030600054": 73,
|
||||||
"香菇(鲜)[香蕈,冬菇]WP2026030600050": 74,
|
"红美人椒WP2026020300049": 74,
|
||||||
"香菜WP2026013000030": 75,
|
"红薯": 75,
|
||||||
"马铃薯[土豆、洋芋]WP2026012900001": 76,
|
"红薯粉条WP2026031700091": 76,
|
||||||
"鸡全腿(带骨)": 77,
|
"红薯粉条(袋)": 77,
|
||||||
"鸡翅(带骨)": 78,
|
"结球甘蓝(紫)[圆白菜]WP2026020500017": 78,
|
||||||
"鸡腿肉WP2025110700048": 79,
|
"结球甘蓝(绿)[圆白菜]WP2026032300116": 79,
|
||||||
"鸡腿(带骨)": 80,
|
"绿豆芽WP2026031100073": 80,
|
||||||
"鸡蛋WP2026013000039": 81,
|
"羊排WP2025120300021": 81,
|
||||||
"麦芹": 82,
|
"羊血WP2026013000038": 82,
|
||||||
"黄瓜(鲜)[胡瓜]WP2025110700031": 83,
|
"胡萝卜WP2025110600008": 83,
|
||||||
"黄豆芽WP2026020200042": 84,
|
"腰果(熟)": 84,
|
||||||
"黑袋子": 85,
|
"芋头": 85,
|
||||||
"黑鱼(整条鱼)WP2025110600012": 86
|
"芥蓝[甘蓝菜,盖蓝菜]": 86,
|
||||||
|
"芦笋(绿)[石刁柏,龙须菜]": 87,
|
||||||
|
"花卷": 88,
|
||||||
|
"花椒(粉)": 89,
|
||||||
|
"花生仁(生)WP2026032000102": 90,
|
||||||
|
"花螺": 91,
|
||||||
|
"芹菜(茎)[旱芹,药芹]WP2026022800032": 92,
|
||||||
|
"苦菊": 93,
|
||||||
|
"苹果(代表值)WP2026032300117": 94,
|
||||||
|
"茄子(紫皮,长)WP2025110700024": 95,
|
||||||
|
"茼蒿WP2026020200045": 96,
|
||||||
|
"草鱼": 97,
|
||||||
|
"荷兰豆WP2026032000104": 98,
|
||||||
|
"莲藕(带皮)": 99,
|
||||||
|
"莴笋(鲜)[莴苣]WP2026020200009": 100,
|
||||||
|
"菜花(白色)[花椰菜]WP2026030600057": 101,
|
||||||
|
"菠菜(鲜)[赤根菜]WP2026022800700": 102,
|
||||||
|
"菠萝[凤梨,地菠萝]": 103,
|
||||||
|
"蒜苗WP2026013000028": 104,
|
||||||
|
"蒜薹(圆)": 105,
|
||||||
|
"蒸鱼豉油WP2026013000032": 106,
|
||||||
|
"蕹菜[空心菜,藤藤菜]": 107,
|
||||||
|
"薏米[薏仁米,苡米]WP2026022800037": 108,
|
||||||
|
"虫草花(干)WP2026032000108": 109,
|
||||||
|
"蛏子": 110,
|
||||||
|
"西兰花[绿菜花]WP2026031100071": 111,
|
||||||
|
"西瓜(代表值)": 112,
|
||||||
|
"西芹[西洋芹菜,美芹]WP2026031100069": 113,
|
||||||
|
"西葫芦WP2026021000027": 114,
|
||||||
|
"豆腐干(代表值)": 115,
|
||||||
|
"豆腐皮WP2026031700097": 116,
|
||||||
|
"豆角豇豆WP2026021000026": 117,
|
||||||
|
"赤小豆[小豆,红小豆](干)WP2026032300118": 118,
|
||||||
|
"辣椒(红,小)WP2025111000066": 119,
|
||||||
|
"辣椒(青,尖)WP2026030600056": 120,
|
||||||
|
"辣椒段(干)": 121,
|
||||||
|
"醪糟": 122,
|
||||||
|
"金针菇[(鲜)[智力菇]WP2026030600051": 123,
|
||||||
|
"青线椒WP2026013000031": 124,
|
||||||
|
"青美人椒辣椒(青,尖)": 125,
|
||||||
|
"青花椒鲜花椒": 126,
|
||||||
|
"面条(生,代表值)WP2026030600055": 127,
|
||||||
|
"面条(生,炒细面": 128,
|
||||||
|
"韭菜WP2026020200044": 129,
|
||||||
|
"韭薹": 130,
|
||||||
|
"韭黄": 131,
|
||||||
|
"馒头(代表值)WP2026030600056": 132,
|
||||||
|
"香椿[香椿芽]WP2026022801086": 133,
|
||||||
|
"香菇(鲜)[香蕈,冬菇]WP2026030600050": 134,
|
||||||
|
"香菜WP2026013000030": 135,
|
||||||
|
"马铃薯[土豆、洋芋]WP2026012900001": 136,
|
||||||
|
"鱿鱼(鲜,中国枪乌贼)[枪乌贼]": 137,
|
||||||
|
"鲍鱼(带壳)": 138,
|
||||||
|
"鲑鱼[大马哈鱼,三文鱼]": 139,
|
||||||
|
"鲜猪精排": 140,
|
||||||
|
"鸡全腿(带骨)": 141,
|
||||||
|
"鸡翅(带骨)": 142,
|
||||||
|
"鸡胸脯肉WP2026022802698": 143,
|
||||||
|
"鸡腿肉WP2025110700048": 144,
|
||||||
|
"鸡蛋WP2026013000039": 145,
|
||||||
|
"鸭(均值)": 146,
|
||||||
|
"鸭蛋黄": 147,
|
||||||
|
"黄瓜(鲜)[胡瓜]WP2025110700031": 148,
|
||||||
|
"黄豆": 149,
|
||||||
|
"黄豆芽WP2026020200042": 150,
|
||||||
|
"黑米WP2026031200081": 151,
|
||||||
|
"黑袋子": 152,
|
||||||
|
"黑鱼(整条鱼)WP2025110600012": 153
|
||||||
},
|
},
|
||||||
"idx_to_class": {
|
"idx_to_class": {
|
||||||
"0": "三黄鸡",
|
"0": "三黄鸡",
|
||||||
"1": "上海青WP2026020200041",
|
"1": "上海青WP2026020200041",
|
||||||
"2": "冰草WP2026020900054",
|
"2": "丝瓜WP2026032300114",
|
||||||
"3": "刀豆",
|
"3": "乳瓜WP2026032000107",
|
||||||
"4": "北豆腐WP2025111900007",
|
"4": "冬瓜WP2026032300115",
|
||||||
"5": "味精WP2026013000034",
|
"5": "冰糖",
|
||||||
"6": "圆生菜WP2026020900053",
|
"6": "冰草WP2026020900054",
|
||||||
"7": "圆白菜[卷心菜,包菜]WP2025111000063",
|
"7": "刀豆",
|
||||||
"8": "基围虾WP2025110700019",
|
"8": "北豆腐WP2025111900007",
|
||||||
"9": "多宝鱼WP2025112600011",
|
"9": "南瓜[倭瓜,番瓜]",
|
||||||
"10": "大白菜(代表值)WP2026022800638",
|
"10": "味精WP2026013000034",
|
||||||
"11": "大葱WP2026013000025",
|
"11": "圆生菜WP2026020900053",
|
||||||
"12": "姜[黄姜]WP2026022800956",
|
"12": "基围虾WP2025110700019",
|
||||||
"13": "娃娃菜WP2026020200005",
|
"13": "多宝鱼WP2025112600011",
|
||||||
"14": "小白菜WP2026022800031",
|
"14": "大白菜(代表值)WP2026031700085",
|
||||||
"15": "小米辣椒WP2026013000027",
|
"15": "大葱WP2026013000026",
|
||||||
"16": "小葱WP2026013000029",
|
"16": "大蒜(去皮)WP2026020200011",
|
||||||
"17": "山药(带皮)WP2026020200008",
|
"17": "大蒜(带皮)WP2026020300046",
|
||||||
"18": "巨人笋",
|
"18": "奶白菜",
|
||||||
"19": "广东菜心WP2025120100014",
|
"19": "姜(子姜)[嫩姜]",
|
||||||
"20": "木耳(干)[黑木耳,云耳]WP2026022801182",
|
"20": "姜[黄姜]WP2026022800956",
|
||||||
"21": "杏鲍菇WP2026022700030",
|
"21": "娃娃菜WP2026020200005",
|
||||||
"22": "松花蛋",
|
"22": "小白菜WP2026022800031",
|
||||||
"23": "松茸菌WP2025120100016",
|
"23": "小米辣椒WP2026013000027",
|
||||||
"24": "沙葱",
|
"24": "小葱WP2026013000029",
|
||||||
"25": "海带(浸)[江白菜,昆布]WP2026022800035",
|
"25": "小鸡腿(带骨)",
|
||||||
"26": "牛腩WP2025110700043",
|
"26": "山药(带皮)WP2026020200008",
|
||||||
"27": "猪五花肉WP2026020300048",
|
"27": "巨人笋",
|
||||||
"28": "猪腿肉WP2025110700040",
|
"28": "平菇[糙皮侧耳,青蘑]WP2026031700086",
|
||||||
"29": "玉米WP2025120100017",
|
"29": "广东菜心WP2025120100014",
|
||||||
"30": "玉米糁(黄)WP2026022800038",
|
"30": "新世纪哈密瓜",
|
||||||
"31": "番茄[西红柿]WP2026021000028",
|
"31": "明虾",
|
||||||
"32": "白吉饼WP2026013000024",
|
"32": "木耳(干)[黑木耳,云耳]WP2026022801182",
|
||||||
"33": "笋",
|
"33": "杏鲍菇WP2026022700030",
|
||||||
"34": "粉丝",
|
"34": "松花蛋",
|
||||||
"35": "紫甘蓝",
|
"35": "松茸菌WP2025120100016",
|
||||||
"36": "红心萝卜[心里美]WP2026022800368",
|
"36": "槐花[洋槐花,豆槐花]",
|
||||||
"37": "红提子WP2025111900006",
|
"37": "橙",
|
||||||
"38": "红椒WP2026030300055",
|
"38": "沙葱",
|
||||||
"39": "红洋葱WP2026030600054",
|
"39": "油麦菜WP2026031200077",
|
||||||
"40": "红美人椒WP2026020300049",
|
"40": "海带(浸)[江白菜,昆布]WP2026022800035",
|
||||||
"41": "红薯",
|
"41": "淀粉(马铃薯)",
|
||||||
"42": "红薯粉条(袋)",
|
"42": "湿米线过桥米线",
|
||||||
"43": "羊排WP2025120300021",
|
"43": "火龙果(带皮)",
|
||||||
"44": "羊血WP2026013000038",
|
"44": "炒饼丝",
|
||||||
"45": "胡萝卜WP2025110600008",
|
"45": "牛肉(腹部肉)[牛腩]",
|
||||||
"46": "芋头",
|
"46": "牛肚",
|
||||||
"47": "花卷",
|
"47": "牛腩WP2025110700043",
|
||||||
"48": "芹菜WP2025111000065",
|
"48": "猪五花肉WP2026020300048",
|
||||||
"49": "苦菊",
|
"49": "猪小排(带骨)",
|
||||||
"50": "茄子(紫皮,长)WP2025110700024",
|
"50": "猪排(带骨)WP2026031200078",
|
||||||
"51": "茼蒿WP2026020200045",
|
"51": "猪肉(瘦)",
|
||||||
"52": "莲藕(带皮)",
|
"52": "猪肉(腿)WP2026022800033",
|
||||||
"53": "莴笋(鲜)[莴苣]WP2026020200009",
|
"53": "猪肉(里脊)WP2026021000025",
|
||||||
"54": "菜花(白色)[花椰菜]",
|
"54": "猪肝(鲜)WP2026032000105",
|
||||||
"55": "菠菜(鲜)[赤根菜]WP2026022800700",
|
"55": "猪肾(fat8g)[猪腰子]",
|
||||||
"56": "蒜WP2025111400003",
|
"56": "玉米WP2025120100017",
|
||||||
"57": "蒜苗WP2026013000028",
|
"57": "玉米糁(黄)WP2026022800038",
|
||||||
"58": "蒜薹(圆)",
|
"58": "甜椒[灯笼椒,柿子椒]WP2026020500018",
|
||||||
"59": "蒸鱼豉油WP2026013000032",
|
"59": "生菜(叶用莴苣)WP2026020500020",
|
||||||
"60": "薏米[薏仁米,苡米]WP2026022800037",
|
"60": "生蚝",
|
||||||
"61": "西兰花[绿菜花]WP2025110700029",
|
"61": "番茄[西红柿]WP2026021000028",
|
||||||
"62": "西葫芦",
|
"62": "白吉饼WP2026013000024",
|
||||||
"63": "豆腐皮WP2025111000059",
|
"63": "白玉菇WP2026031100072",
|
||||||
"64": "豆角",
|
"64": "白菜薹[菜薹,菜心]WP2026031100068",
|
||||||
"65": "辣椒(红,小)WP2025111000066",
|
"65": "白萝卜WP2026031200079",
|
||||||
"66": "辣椒(青,尖)WP2026022800504",
|
"66": "石斑鱼(整条鱼)",
|
||||||
"67": "醪糟",
|
"67": "笋",
|
||||||
"68": "金针菇[(鲜)[智力菇]WP2026030600051",
|
"68": "粉丝",
|
||||||
"69": "青线椒WP2026013000031",
|
"69": "素鸡WP2026031700096",
|
||||||
"70": "韭菜WP2026020200044",
|
"70": "红心萝卜[心里美]WP2026022800368",
|
||||||
"71": "韭黄",
|
"71": "红提子WP2025111900006",
|
||||||
"72": "馒头(代表值)WP2026030600056",
|
"72": "红椒WP2026030300055",
|
||||||
"73": "香椿[香椿芽]WP2026022801086",
|
"73": "红洋葱WP2026030600054",
|
||||||
"74": "香菇(鲜)[香蕈,冬菇]WP2026030600050",
|
"74": "红美人椒WP2026020300049",
|
||||||
"75": "香菜WP2026013000030",
|
"75": "红薯",
|
||||||
"76": "马铃薯[土豆、洋芋]WP2026012900001",
|
"76": "红薯粉条WP2026031700091",
|
||||||
"77": "鸡全腿(带骨)",
|
"77": "红薯粉条(袋)",
|
||||||
"78": "鸡翅(带骨)",
|
"78": "结球甘蓝(紫)[圆白菜]WP2026020500017",
|
||||||
"79": "鸡腿肉WP2025110700048",
|
"79": "结球甘蓝(绿)[圆白菜]WP2026032300116",
|
||||||
"80": "鸡腿(带骨)",
|
"80": "绿豆芽WP2026031100073",
|
||||||
"81": "鸡蛋WP2026013000039",
|
"81": "羊排WP2025120300021",
|
||||||
"82": "麦芹",
|
"82": "羊血WP2026013000038",
|
||||||
"83": "黄瓜(鲜)[胡瓜]WP2025110700031",
|
"83": "胡萝卜WP2025110600008",
|
||||||
"84": "黄豆芽WP2026020200042",
|
"84": "腰果(熟)",
|
||||||
"85": "黑袋子",
|
"85": "芋头",
|
||||||
"86": "黑鱼(整条鱼)WP2025110600012"
|
"86": "芥蓝[甘蓝菜,盖蓝菜]",
|
||||||
|
"87": "芦笋(绿)[石刁柏,龙须菜]",
|
||||||
|
"88": "花卷",
|
||||||
|
"89": "花椒(粉)",
|
||||||
|
"90": "花生仁(生)WP2026032000102",
|
||||||
|
"91": "花螺",
|
||||||
|
"92": "芹菜(茎)[旱芹,药芹]WP2026022800032",
|
||||||
|
"93": "苦菊",
|
||||||
|
"94": "苹果(代表值)WP2026032300117",
|
||||||
|
"95": "茄子(紫皮,长)WP2025110700024",
|
||||||
|
"96": "茼蒿WP2026020200045",
|
||||||
|
"97": "草鱼",
|
||||||
|
"98": "荷兰豆WP2026032000104",
|
||||||
|
"99": "莲藕(带皮)",
|
||||||
|
"100": "莴笋(鲜)[莴苣]WP2026020200009",
|
||||||
|
"101": "菜花(白色)[花椰菜]WP2026030600057",
|
||||||
|
"102": "菠菜(鲜)[赤根菜]WP2026022800700",
|
||||||
|
"103": "菠萝[凤梨,地菠萝]",
|
||||||
|
"104": "蒜苗WP2026013000028",
|
||||||
|
"105": "蒜薹(圆)",
|
||||||
|
"106": "蒸鱼豉油WP2026013000032",
|
||||||
|
"107": "蕹菜[空心菜,藤藤菜]",
|
||||||
|
"108": "薏米[薏仁米,苡米]WP2026022800037",
|
||||||
|
"109": "虫草花(干)WP2026032000108",
|
||||||
|
"110": "蛏子",
|
||||||
|
"111": "西兰花[绿菜花]WP2026031100071",
|
||||||
|
"112": "西瓜(代表值)",
|
||||||
|
"113": "西芹[西洋芹菜,美芹]WP2026031100069",
|
||||||
|
"114": "西葫芦WP2026021000027",
|
||||||
|
"115": "豆腐干(代表值)",
|
||||||
|
"116": "豆腐皮WP2026031700097",
|
||||||
|
"117": "豆角豇豆WP2026021000026",
|
||||||
|
"118": "赤小豆[小豆,红小豆](干)WP2026032300118",
|
||||||
|
"119": "辣椒(红,小)WP2025111000066",
|
||||||
|
"120": "辣椒(青,尖)WP2026030600056",
|
||||||
|
"121": "辣椒段(干)",
|
||||||
|
"122": "醪糟",
|
||||||
|
"123": "金针菇[(鲜)[智力菇]WP2026030600051",
|
||||||
|
"124": "青线椒WP2026013000031",
|
||||||
|
"125": "青美人椒辣椒(青,尖)",
|
||||||
|
"126": "青花椒鲜花椒",
|
||||||
|
"127": "面条(生,代表值)WP2026030600055",
|
||||||
|
"128": "面条(生,炒细面",
|
||||||
|
"129": "韭菜WP2026020200044",
|
||||||
|
"130": "韭薹",
|
||||||
|
"131": "韭黄",
|
||||||
|
"132": "馒头(代表值)WP2026030600056",
|
||||||
|
"133": "香椿[香椿芽]WP2026022801086",
|
||||||
|
"134": "香菇(鲜)[香蕈,冬菇]WP2026030600050",
|
||||||
|
"135": "香菜WP2026013000030",
|
||||||
|
"136": "马铃薯[土豆、洋芋]WP2026012900001",
|
||||||
|
"137": "鱿鱼(鲜,中国枪乌贼)[枪乌贼]",
|
||||||
|
"138": "鲍鱼(带壳)",
|
||||||
|
"139": "鲑鱼[大马哈鱼,三文鱼]",
|
||||||
|
"140": "鲜猪精排",
|
||||||
|
"141": "鸡全腿(带骨)",
|
||||||
|
"142": "鸡翅(带骨)",
|
||||||
|
"143": "鸡胸脯肉WP2026022802698",
|
||||||
|
"144": "鸡腿肉WP2025110700048",
|
||||||
|
"145": "鸡蛋WP2026013000039",
|
||||||
|
"146": "鸭(均值)",
|
||||||
|
"147": "鸭蛋黄",
|
||||||
|
"148": "黄瓜(鲜)[胡瓜]WP2025110700031",
|
||||||
|
"149": "黄豆",
|
||||||
|
"150": "黄豆芽WP2026020200042",
|
||||||
|
"151": "黑米WP2026031200081",
|
||||||
|
"152": "黑袋子",
|
||||||
|
"153": "黑鱼(整条鱼)WP2025110600012"
|
||||||
},
|
},
|
||||||
"embedding_dim": 512,
|
"embedding_dim": 512,
|
||||||
"total_images": 2093,
|
"total_images": 3180,
|
||||||
"build_time": "2026-03-10T10:33:47.104848"
|
"build_time": "2026-04-27T14:13:11.594418"
|
||||||
}
|
}
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -41,10 +41,12 @@ object GlobalData {
|
|||||||
var unitTypeList: List<DictType> = arrayListOf()
|
var unitTypeList: List<DictType> = arrayListOf()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 具体业务baseurl
|
* 具体业务 BaseUrl
|
||||||
*/
|
*/
|
||||||
//var appBaseUrl: String = "http://192.168.1.201:14801"
|
const val TEST_BASE_URL = "http://192.168.1.201:14801"
|
||||||
var appBaseUrl: String = "https://dev.yixiong-tech.com:8081"
|
const val UAT_BASE_URL = "https://dev.yixiong-tech.com:8083"
|
||||||
|
const val PROD_BASE_URL = "https://api.dm.yixiong-tech.com:8443"
|
||||||
|
var appBaseUrl: String = ""
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设备id
|
* 设备id
|
||||||
@@ -66,4 +68,5 @@ object GlobalKey {
|
|||||||
const val KEY_TOKEN = "tokenKey"
|
const val KEY_TOKEN = "tokenKey"
|
||||||
const val KEY_USER_INFO = "userInfoKey"
|
const val KEY_USER_INFO = "userInfoKey"
|
||||||
const val KEY_USER_NAME = "userNameKey"
|
const val KEY_USER_NAME = "userNameKey"
|
||||||
|
const val KEY_BASE_URL = "baseUrlKey"
|
||||||
}
|
}
|
||||||
@@ -37,6 +37,8 @@ import com.sw.inbound.utils.BitmapSaver
|
|||||||
import com.sw.inbound.utils.CameraUtils
|
import com.sw.inbound.utils.CameraUtils
|
||||||
import com.sw.inbound.utils.ImageUploader
|
import com.sw.inbound.utils.ImageUploader
|
||||||
import com.sw.inbound.utils.ImageUtil
|
import com.sw.inbound.utils.ImageUtil
|
||||||
|
import com.sw.inbound.utils.LogSaveUtil
|
||||||
|
import com.sw.inbound.utils.NetworkUtils
|
||||||
import com.sw.inbound.utils.ext.addOnActionSearchListener
|
import com.sw.inbound.utils.ext.addOnActionSearchListener
|
||||||
import com.sw.inbound.utils.ext.clickWithDebounce
|
import com.sw.inbound.utils.ext.clickWithDebounce
|
||||||
import com.sw.inbound.utils.ext.dp
|
import com.sw.inbound.utils.ext.dp
|
||||||
@@ -48,6 +50,7 @@ import com.sw.inbound.utils.ext.toJsonString
|
|||||||
import com.sw.inbound.utils.ext.toast
|
import com.sw.inbound.utils.ext.toast
|
||||||
import com.sw.inbound.utils.ext.visible
|
import com.sw.inbound.utils.ext.visible
|
||||||
import com.sw.inbound.viewmodel.ReceiptViewModel
|
import com.sw.inbound.viewmodel.ReceiptViewModel
|
||||||
|
import com.sw.inbound.viewmodel.UserViewModel
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import io.objectbox.exception.DbException
|
import io.objectbox.exception.DbException
|
||||||
import io.objectbox.exception.FileCorruptException
|
import io.objectbox.exception.FileCorruptException
|
||||||
@@ -76,8 +79,8 @@ class FoodCollectionActivity : BaseActivity() {
|
|||||||
private lateinit var binding: ActivityFoodCollectionBinding
|
private lateinit var binding: ActivityFoodCollectionBinding
|
||||||
private lateinit var previewView: PreviewView
|
private lateinit var previewView: PreviewView
|
||||||
|
|
||||||
private val viewModel: ReceiptViewModel by viewModels()
|
private val receiptViewModel: ReceiptViewModel by viewModels()
|
||||||
|
val userViewModel: UserViewModel by viewModels()
|
||||||
private val cameraUtils: CameraUtils by lazy {
|
private val cameraUtils: CameraUtils by lazy {
|
||||||
CameraUtils(this)
|
CameraUtils(this)
|
||||||
}
|
}
|
||||||
@@ -213,6 +216,10 @@ class FoodCollectionActivity : BaseActivity() {
|
|||||||
|
|
||||||
},
|
},
|
||||||
confirmBlock = {
|
confirmBlock = {
|
||||||
|
if (NetworkUtils.isNetworkConnected(this).not()) {
|
||||||
|
toast("网络异常,请稍后重试")
|
||||||
|
return@WarnDialog
|
||||||
|
}
|
||||||
upload()
|
upload()
|
||||||
}
|
}
|
||||||
).show()
|
).show()
|
||||||
@@ -318,6 +325,7 @@ class FoodCollectionActivity : BaseActivity() {
|
|||||||
// uriToBitmap 返回 null 时关闭 loading,否则转圈永不消失
|
// uriToBitmap 返回 null 时关闭 loading,否则转圈永不消失
|
||||||
hideWaitingDialog()
|
hideWaitingDialog()
|
||||||
toast("图片读取失败,请重试")
|
toast("图片读取失败,请重试")
|
||||||
|
LogSaveUtil.saveLogFile("图片读取失败,请重试")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cropBitmap = withContext(Dispatchers.IO) {
|
cropBitmap = withContext(Dispatchers.IO) {
|
||||||
@@ -336,6 +344,7 @@ class FoodCollectionActivity : BaseActivity() {
|
|||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
hideWaitingDialog()
|
hideWaitingDialog()
|
||||||
toast("操作失败")
|
toast("操作失败")
|
||||||
|
LogSaveUtil.saveLogFile("操作失败:${e.message}")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Timber.tag(TAG).d("向量:${imageVector.toJsonString()}")
|
Timber.tag(TAG).d("向量:${imageVector.toJsonString()}")
|
||||||
@@ -355,6 +364,7 @@ class FoodCollectionActivity : BaseActivity() {
|
|||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
toast("数据库异常,请稍后重试")
|
toast("数据库异常,请稍后重试")
|
||||||
|
LogSaveUtil.saveLogFile("数据库异常,请稍后重试:${e.message}")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val filterList =
|
val filterList =
|
||||||
@@ -362,6 +372,7 @@ class FoodCollectionActivity : BaseActivity() {
|
|||||||
if (filterList.isNotEmpty()) {
|
if (filterList.isNotEmpty()) {
|
||||||
hideWaitingDialog()
|
hideWaitingDialog()
|
||||||
toast("当前物品可能被袋子遮挡,请检查后重试")
|
toast("当前物品可能被袋子遮挡,请检查后重试")
|
||||||
|
LogSaveUtil.saveLogFile("当前物品可能被袋子遮挡,请检查后重试")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 图片保存为磁盘 I/O,切换到 IO 线程
|
// 图片保存为磁盘 I/O,切换到 IO 线程
|
||||||
@@ -398,8 +409,10 @@ class FoodCollectionActivity : BaseActivity() {
|
|||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
toast("请重试")
|
toast("请重试")
|
||||||
|
LogSaveUtil.saveLogFile("请重试:${e.message}")
|
||||||
} else {
|
} else {
|
||||||
toast("程序异常$errMsg")
|
toast("程序异常$errMsg")
|
||||||
|
LogSaveUtil.saveLogFile("程序异常$errMsg:${e.message}")
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
// 无论成功、失败还是提前返回,均在此回收 bitmap,彻底消除内存泄漏
|
// 无论成功、失败还是提前返回,均在此回收 bitmap,彻底消除内存泄漏
|
||||||
@@ -505,7 +518,7 @@ class FoodCollectionActivity : BaseActivity() {
|
|||||||
// 取消上一次未完成的搜索,避免并发竞争导致结果乱序
|
// 取消上一次未完成的搜索,避免并发竞争导致结果乱序
|
||||||
searchJob?.cancel()
|
searchJob?.cancel()
|
||||||
searchJob = lifecycleScope.launch {
|
searchJob = lifecycleScope.launch {
|
||||||
val records = viewModel.searchGoodsInfoList2(
|
val records = receiptViewModel.searchGoodsInfoList2(
|
||||||
goodsName = searchName,
|
goodsName = searchName,
|
||||||
pageNo = pageNo,
|
pageNo = pageNo,
|
||||||
pageSize = pageSize
|
pageSize = pageSize
|
||||||
@@ -537,7 +550,7 @@ class FoodCollectionActivity : BaseActivity() {
|
|||||||
totalList = collectList,
|
totalList = collectList,
|
||||||
uploadImage = { batch ->
|
uploadImage = { batch ->
|
||||||
val files = batch.map { it.imageFile }
|
val files = batch.map { it.imageFile }
|
||||||
viewModel.uploadMultipleImages(files = files, params)
|
receiptViewModel.uploadMultipleImages(files = files, params)
|
||||||
},
|
},
|
||||||
onProgress = { count, batch ->
|
onProgress = { count, batch ->
|
||||||
// lifecycleScope 默认在主线程执行,无需 runOnUiThread
|
// lifecycleScope 默认在主线程执行,无需 runOnUiThread
|
||||||
@@ -573,7 +586,7 @@ class FoodCollectionActivity : BaseActivity() {
|
|||||||
pageSize: Int = 10
|
pageSize: Int = 10
|
||||||
): List<SearchGoodsInfo.Record> {
|
): List<SearchGoodsInfo.Record> {
|
||||||
// 统一使用类顶部声明的 viewModel,避免重复创建 ViewModel 实例
|
// 统一使用类顶部声明的 viewModel,避免重复创建 ViewModel 实例
|
||||||
return viewModel.searchGoodsInfoList2(goodsName, pageNo, pageSize)
|
return receiptViewModel.searchGoodsInfoList2(goodsName, pageNo, pageSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var mDialogWaiting: CustomDialog? = null
|
private var mDialogWaiting: CustomDialog? = null
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ abstract class GoodsListActivity : BaseActivity() {
|
|||||||
private const val TAG = "GoodsListActivity"
|
private const val TAG = "GoodsListActivity"
|
||||||
public const val ID = "id"
|
public const val ID = "id"
|
||||||
public const val SUPPLIER_ID = "supplierId"
|
public const val SUPPLIER_ID = "supplierId"
|
||||||
|
public const val PUR_CODE = "purCode"
|
||||||
|
|
||||||
public const val IS_RECEIPT_PAGE = "isReceiptPage"
|
public const val IS_RECEIPT_PAGE = "isReceiptPage"
|
||||||
// public const val IS_NEW_RECEIPT = "isNewReceipt"
|
// public const val IS_NEW_RECEIPT = "isNewReceipt"
|
||||||
@@ -91,6 +92,7 @@ abstract class GoodsListActivity : BaseActivity() {
|
|||||||
// var isNewReceipt: Boolean = false
|
// var isNewReceipt: Boolean = false
|
||||||
var id: String = ""
|
var id: String = ""
|
||||||
var supplierId: String = ""
|
var supplierId: String = ""
|
||||||
|
var purCode: String = ""
|
||||||
lateinit var binding: ActivityGoodsListBinding
|
lateinit var binding: ActivityGoodsListBinding
|
||||||
val receiptViewModel: ReceiptViewModel by viewModels()
|
val receiptViewModel: ReceiptViewModel by viewModels()
|
||||||
val userViewModel: UserViewModel by viewModels()
|
val userViewModel: UserViewModel by viewModels()
|
||||||
@@ -116,6 +118,7 @@ abstract class GoodsListActivity : BaseActivity() {
|
|||||||
//isNewReceipt = intent.getBooleanExtra(IS_NEW_RECEIPT, false)
|
//isNewReceipt = intent.getBooleanExtra(IS_NEW_RECEIPT, false)
|
||||||
id = intent.getStringExtra(ID) ?: ""
|
id = intent.getStringExtra(ID) ?: ""
|
||||||
supplierId = intent.getStringExtra(SUPPLIER_ID) ?: ""
|
supplierId = intent.getStringExtra(SUPPLIER_ID) ?: ""
|
||||||
|
purCode = intent.getStringExtra(PUR_CODE) ?: ""
|
||||||
|
|
||||||
replaceIncludeContent()
|
replaceIncludeContent()
|
||||||
initRecyclerView()
|
initRecyclerView()
|
||||||
@@ -210,13 +213,13 @@ abstract class GoodsListActivity : BaseActivity() {
|
|||||||
binding.tvTotalWeight.text = "重量:${weight}克"
|
binding.tvTotalWeight.text = "重量:${weight}克"
|
||||||
}
|
}
|
||||||
if (weight < 200) {
|
if (weight < 200) {
|
||||||
if (weight < 10) {
|
if (weight < 20) {
|
||||||
// val clazzName = DialogManager.getDialogList()
|
// val clazzName = DialogManager.getDialogList()
|
||||||
// .map { it.javaClass.simpleName }
|
// .map { it.javaClass.simpleName }
|
||||||
// .joinToString(",")
|
// .joinToString(",")
|
||||||
// Timber.tag(TAG).d(clazzName)
|
// Timber.tag(TAG).d(clazzName)
|
||||||
if (DialogManager.getDialogList().size == 1 &&
|
// 无其他弹窗正在显示时(过滤幽灵条目),自动关闭识别弹窗
|
||||||
DialogManager.contains("GoodsRecognizeDialog") &&
|
if (DialogManager.getDialogList().none { it.isShowing && it != goodsRecognizeDialog } &&
|
||||||
goodsRecognizeDialog?.isShowing == true
|
goodsRecognizeDialog?.isShowing == true
|
||||||
) {
|
) {
|
||||||
goodsRecognizeDialog?.dismiss()
|
goodsRecognizeDialog?.dismiss()
|
||||||
@@ -253,8 +256,9 @@ abstract class GoodsListActivity : BaseActivity() {
|
|||||||
searchFood(uri)
|
searchFood(uri)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
Loading.dismiss()
|
||||||
}
|
}
|
||||||
}.start()
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val delayHandler by lazy {
|
private val delayHandler by lazy {
|
||||||
@@ -395,19 +399,22 @@ abstract class GoodsListActivity : BaseActivity() {
|
|||||||
// readBitmap(it)
|
// readBitmap(it)
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
ImageUtil.uriToBitmap(this, uri)?.let { bitmap ->
|
val bitmap = ImageUtil.uriToBitmap(this, uri)
|
||||||
val newBmp = BitmapCropper.cropCenter(
|
if (bitmap == null) {
|
||||||
original = bitmap,
|
Loading.dismiss()
|
||||||
targetWidth = 1000, targetHeight = 1300,
|
return
|
||||||
offsetX = 30, offsetY = 100
|
}
|
||||||
)
|
val newBmp = BitmapCropper.cropCenter(
|
||||||
readBitmap(newBmp)
|
original = bitmap,
|
||||||
if (newBmp.isRecycled.not()) {
|
targetWidth = 1000, targetHeight = 1300,
|
||||||
newBmp.recycle()
|
offsetX = 30, offsetY = 100
|
||||||
}
|
)
|
||||||
if (bitmap.isRecycled.not()) {
|
readBitmap(newBmp)
|
||||||
bitmap.recycle()
|
if (newBmp.isRecycled.not()) {
|
||||||
}
|
newBmp.recycle()
|
||||||
|
}
|
||||||
|
if (bitmap.isRecycled.not()) {
|
||||||
|
bitmap.recycle()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -643,11 +650,12 @@ abstract class GoodsListActivity : BaseActivity() {
|
|||||||
val uploadInfo = UploadInfo(
|
val uploadInfo = UploadInfo(
|
||||||
id = id,
|
id = id,
|
||||||
supplierId = supplierId,
|
supplierId = supplierId,
|
||||||
|
purCode = purCode,
|
||||||
receiveGoodsInfos = goodsList
|
receiveGoodsInfos = goodsList
|
||||||
)
|
)
|
||||||
logInfo("receiptSubmit确认收货提交数据:${uploadInfo.toJsonString()}")
|
logInfo("receiptSubmit确认收货提交数据:${uploadInfo.toJsonString()}")
|
||||||
showWaitingDialog2("加载中")
|
showWaitingDialog2("加载中")
|
||||||
receiptViewModel.confirmReceipt(uploadInfo) { success ->
|
receiptViewModel.confirmReceipt(uploadInfo) { success, msg ->
|
||||||
hideWaitingDialog()
|
hideWaitingDialog()
|
||||||
if (success) {
|
if (success) {
|
||||||
userViewModel.deleteKey(localGoodsKey)
|
userViewModel.deleteKey(localGoodsKey)
|
||||||
@@ -656,7 +664,7 @@ abstract class GoodsListActivity : BaseActivity() {
|
|||||||
finish()
|
finish()
|
||||||
}, 200)
|
}, 200)
|
||||||
} else {
|
} else {
|
||||||
toast("确认收货失败")
|
toast("确认收货失败:$msg")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -686,7 +694,7 @@ abstract class GoodsListActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
logInfo("selfProcurementSubmit自采入库提交数据:${submitData.toJsonString()}")
|
logInfo("selfProcurementSubmit自采入库提交数据:${submitData.toJsonString()}")
|
||||||
showWaitingDialog2("加载中")
|
showWaitingDialog2("加载中")
|
||||||
receiptViewModel.addToWarehouse(submitData) { success ->
|
receiptViewModel.addToWarehouse(submitData) { success, msg ->
|
||||||
hideWaitingDialog()
|
hideWaitingDialog()
|
||||||
if (success) {
|
if (success) {
|
||||||
toast("提交入库成功")
|
toast("提交入库成功")
|
||||||
@@ -695,7 +703,7 @@ abstract class GoodsListActivity : BaseActivity() {
|
|||||||
finish()
|
finish()
|
||||||
}, 200)
|
}, 200)
|
||||||
} else {
|
} else {
|
||||||
toast("提交入库失败")
|
toast("提交入库失败:$msg")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,11 @@ import androidx.lifecycle.Lifecycle
|
|||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.lifecycle.repeatOnLifecycle
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import com.sw.inbound.databinding.ActivityHomeBinding
|
import com.sw.inbound.databinding.ActivityHomeBinding
|
||||||
|
import com.sw.inbound.dialog.EnvSwitchDialog
|
||||||
|
import com.sw.inbound.dialog.Loading
|
||||||
import com.sw.inbound.model.response.User
|
import com.sw.inbound.model.response.User
|
||||||
import com.sw.inbound.objbox.FoodModule
|
import com.sw.inbound.objbox.FoodModule
|
||||||
|
import com.sw.inbound.objbox.ObjectBox
|
||||||
import com.sw.inbound.sdk.SensorScaleUtils
|
import com.sw.inbound.sdk.SensorScaleUtils
|
||||||
import com.sw.inbound.utils.DateTimeUtils
|
import com.sw.inbound.utils.DateTimeUtils
|
||||||
import com.sw.inbound.utils.ThreadUtils
|
import com.sw.inbound.utils.ThreadUtils
|
||||||
@@ -78,10 +81,20 @@ class HomeActivity : BaseActivity() {
|
|||||||
startActivity<FoodCollectionActivity>()
|
startActivity<FoodCollectionActivity>()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 时间点击:跳转趣味页面
|
// 时间点击:打开环境切换弹窗
|
||||||
// binding.tvTime.setOnClickListener {
|
binding.tvTime.setOnClickListener { v ->
|
||||||
// startActivity<FunActivity>()
|
EnvSwitchDialog(context = this, onEnvChanged = {
|
||||||
// }
|
Loading.show(this)
|
||||||
|
lifecycleScope.launch {
|
||||||
|
ObjectBox.removeAll()
|
||||||
|
FoodModule.init(this@HomeActivity)
|
||||||
|
v.postDelayed({
|
||||||
|
Loading.dismiss()
|
||||||
|
toast("服务重置完成")
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
}).show()
|
||||||
|
}
|
||||||
|
|
||||||
// 采购单入库入口
|
// 采购单入库入口
|
||||||
binding.ivOrderPurchase.setOnClickListener {
|
binding.ivOrderPurchase.setOnClickListener {
|
||||||
|
|||||||
@@ -8,9 +8,12 @@ import android.os.Looper
|
|||||||
import android.os.SystemClock
|
import android.os.SystemClock
|
||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import android.view.animation.RotateAnimation
|
import android.view.animation.RotateAnimation
|
||||||
|
import com.sw.inbound.GlobalData
|
||||||
|
import com.sw.inbound.GlobalKey
|
||||||
import com.sw.inbound.base.BaseActivity
|
import com.sw.inbound.base.BaseActivity
|
||||||
import com.sw.inbound.databinding.ActivityInitBinding
|
import com.sw.inbound.databinding.ActivityInitBinding
|
||||||
import com.sw.inbound.utils.NetworkUtils
|
import com.sw.inbound.utils.NetworkUtils
|
||||||
|
import com.sw.inbound.utils.SPUtil
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化页面 Activity
|
* 初始化页面 Activity
|
||||||
@@ -65,6 +68,10 @@ class InitActivity : BaseActivity() {
|
|||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
|
if (NetworkUtils.isNetworkConnected(this)) {
|
||||||
|
navigateToHome()
|
||||||
|
return
|
||||||
|
}
|
||||||
startCountdown()
|
startCountdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,6 +140,21 @@ class InitActivity : BaseActivity() {
|
|||||||
* 跳转到 HomeActivity
|
* 跳转到 HomeActivity
|
||||||
*/
|
*/
|
||||||
private fun navigateToHome() {
|
private fun navigateToHome() {
|
||||||
|
// 优先读取用户手动切换后持久化的 url
|
||||||
|
val savedUrl = SPUtil.getInstance().get(GlobalKey.KEY_BASE_URL, "")
|
||||||
|
if (!savedUrl.isNullOrEmpty()) {
|
||||||
|
GlobalData.appBaseUrl = savedUrl
|
||||||
|
} else {
|
||||||
|
// 未保存过则使用默认逻辑:特定设备走测试环境,其余走 UAT
|
||||||
|
GlobalData.appBaseUrl = GlobalData.PROD_BASE_URL
|
||||||
|
val list = listOf(
|
||||||
|
//"5a41a2cf-3cee-3731-911d-a28b10164f7a",
|
||||||
|
"f0bcabbb-0d58-3b14-8bed-9863b7ec61ef"
|
||||||
|
)
|
||||||
|
if (list.contains(GlobalData.deviceId)) {
|
||||||
|
GlobalData.appBaseUrl = GlobalData.TEST_BASE_URL
|
||||||
|
}
|
||||||
|
}
|
||||||
val intent = Intent(this, HomeActivity::class.java)
|
val intent = Intent(this, HomeActivity::class.java)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
finish()
|
finish()
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.sw.inbound.activity
|
package com.sw.inbound.activity
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.app.Dialog
|
import android.app.Dialog
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
@@ -9,11 +10,11 @@ import android.view.ViewGroup
|
|||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import androidx.core.graphics.drawable.toDrawable
|
import androidx.core.graphics.drawable.toDrawable
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.sw.inbound.base.BaseActivity
|
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import coil.load
|
import coil.load
|
||||||
import com.chad.library.adapter4.BaseQuickAdapter
|
import com.chad.library.adapter4.BaseQuickAdapter
|
||||||
import com.chad.library.adapter4.viewholder.QuickViewHolder
|
import com.chad.library.adapter4.viewholder.QuickViewHolder
|
||||||
|
import com.sw.inbound.base.BaseActivity
|
||||||
import com.sw.inbound.databinding.ActivityLocalImagePreviewBinding
|
import com.sw.inbound.databinding.ActivityLocalImagePreviewBinding
|
||||||
import com.sw.inbound.databinding.DialogImageFullPreviewBinding
|
import com.sw.inbound.databinding.DialogImageFullPreviewBinding
|
||||||
import com.sw.inbound.databinding.ListItemImagePreviewBinding
|
import com.sw.inbound.databinding.ListItemImagePreviewBinding
|
||||||
@@ -23,6 +24,8 @@ import kotlinx.coroutines.delay
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
class LocalImagePreviewActivity : BaseActivity() {
|
class LocalImagePreviewActivity : BaseActivity() {
|
||||||
|
|
||||||
@@ -57,7 +60,7 @@ class LocalImagePreviewActivity : BaseActivity() {
|
|||||||
val nameWithoutExt = it.nameWithoutExtension
|
val nameWithoutExt = it.nameWithoutExtension
|
||||||
// 兼容 IMG_CROP_{时间戳} 和其他命名格式
|
// 兼容 IMG_CROP_{时间戳} 和其他命名格式
|
||||||
val displayName = if (nameWithoutExt.startsWith("IMG_CROP_")) {
|
val displayName = if (nameWithoutExt.startsWith("IMG_CROP_")) {
|
||||||
nameWithoutExt.removePrefix("IMG_CROP_")
|
df.format(Date(nameWithoutExt.removePrefix("IMG_CROP_").toLong()))
|
||||||
} else {
|
} else {
|
||||||
nameWithoutExt
|
nameWithoutExt
|
||||||
}
|
}
|
||||||
@@ -74,6 +77,9 @@ class LocalImagePreviewActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SimpleDateFormat")
|
||||||
|
private val df = SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
/** 弹出全屏大图预览 Dialog,支持左右切换 */
|
/** 弹出全屏大图预览 Dialog,支持左右切换 */
|
||||||
private fun showFullImagePreview(startPosition: Int) {
|
private fun showFullImagePreview(startPosition: Int) {
|
||||||
var currentIndex = startPosition
|
var currentIndex = startPosition
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ class PurchaseOrderActivity : BaseActivity() {
|
|||||||
startActivity<ReceiptActivity> {
|
startActivity<ReceiptActivity> {
|
||||||
putExtra(GoodsListActivity.ID, item.id)
|
putExtra(GoodsListActivity.ID, item.id)
|
||||||
putExtra(GoodsListActivity.SUPPLIER_ID, item.supplierId)
|
putExtra(GoodsListActivity.SUPPLIER_ID, item.supplierId)
|
||||||
|
putExtra(GoodsListActivity.PUR_CODE, item.purCode)
|
||||||
putExtra(GoodsListActivity.IS_RECEIPT_PAGE, true)
|
putExtra(GoodsListActivity.IS_RECEIPT_PAGE, true)
|
||||||
//putExtra(GoodsListActivity.IS_NEW_RECEIPT, false)
|
//putExtra(GoodsListActivity.IS_NEW_RECEIPT, false)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,12 +8,13 @@ import androidx.core.graphics.toColorInt
|
|||||||
import com.chad.library.adapter4.BaseQuickAdapter
|
import com.chad.library.adapter4.BaseQuickAdapter
|
||||||
import com.chad.library.adapter4.viewholder.QuickViewHolder
|
import com.chad.library.adapter4.viewholder.QuickViewHolder
|
||||||
import com.sw.inbound.databinding.ListItemCollectSearchBinding
|
import com.sw.inbound.databinding.ListItemCollectSearchBinding
|
||||||
|
import com.sw.inbound.model.response.CollectedFoodInfo
|
||||||
import com.sw.inbound.model.response.SearchGoodsInfo
|
import com.sw.inbound.model.response.SearchGoodsInfo
|
||||||
import com.sw.inbound.utils.ext.dp
|
import com.sw.inbound.utils.ext.dp
|
||||||
import com.sw.inbound.utils.ext.setShapeDrawable
|
import com.sw.inbound.utils.ext.setShapeDrawable
|
||||||
|
|
||||||
class CollectSearchAdapter(var list: MutableList<SearchGoodsInfo.Record>) :
|
class CollectSearchAdapter(var list: MutableList<CollectedFoodInfo>) :
|
||||||
BaseQuickAdapter<SearchGoodsInfo.Record, CollectSearchAdapter.VH>(list) {
|
BaseQuickAdapter<CollectedFoodInfo, CollectSearchAdapter.VH>(list) {
|
||||||
|
|
||||||
inner class VH(var binding: ListItemCollectSearchBinding) : QuickViewHolder(binding.root)
|
inner class VH(var binding: ListItemCollectSearchBinding) : QuickViewHolder(binding.root)
|
||||||
|
|
||||||
@@ -23,19 +24,20 @@ class CollectSearchAdapter(var list: MutableList<SearchGoodsInfo.Record>) :
|
|||||||
return VH(binding)
|
return VH(binding)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: VH, position: Int, item: SearchGoodsInfo.Record?) {
|
override fun onBindViewHolder(holder: VH, position: Int, item: CollectedFoodInfo?) {
|
||||||
holder.binding.let {
|
holder.binding.let {
|
||||||
var goodsName = item!!.goodsName?.split("WP")?.get(0)
|
val goodsName = item!!.foodName.split("WP")[0]
|
||||||
// if (goodsName?.contains("\n") == true) {
|
// if (goodsName?.contains("\n") == true) {
|
||||||
// goodsName = goodsName?.split("\n")?.get(0)
|
// goodsName = goodsName?.split("\n")?.get(0)
|
||||||
// }
|
// }
|
||||||
it.tvGoodsName.run {
|
it.tvGoodsName.run {
|
||||||
text = Html.fromHtml(goodsName)
|
text = Html.fromHtml(goodsName)
|
||||||
setTextColor(if (item!!.isSelected) "#FF0032C8".toColorInt() else "#FF666666".toColorInt())
|
setTextColor(if (item.isSelected) "#FF0032C8".toColorInt() else "#FF666666".toColorInt())
|
||||||
//setTextColor("#FF666666".toColorInt())
|
//setTextColor("#FF666666".toColorInt())
|
||||||
}
|
}
|
||||||
|
it.tvGoodsNum.text = "已采集${item.foodNum}"
|
||||||
it.root.run {
|
it.root.run {
|
||||||
if (item!!.isSelected) {
|
if (item.isSelected) {
|
||||||
setShapeDrawable(
|
setShapeDrawable(
|
||||||
solidColor = "#FFEAF0FF",
|
solidColor = "#FFEAF0FF",
|
||||||
strokeColor = "#FF0033CC",
|
strokeColor = "#FF0033CC",
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.sw.inbound.di
|
package com.sw.inbound.di
|
||||||
|
|
||||||
|
import com.google.gson.GsonBuilder
|
||||||
import com.sw.inbound.MyApp
|
import com.sw.inbound.MyApp
|
||||||
import com.sw.inbound.network.api.ApiService
|
import com.sw.inbound.network.api.ApiService
|
||||||
import com.sw.inbound.network.interceptor.RequestInterceptor
|
import com.sw.inbound.network.interceptor.RequestInterceptor
|
||||||
@@ -51,11 +52,15 @@ object NetworkModule {
|
|||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
|
fun provideRetrofit(okHttpClient: OkHttpClient): Retrofit {
|
||||||
|
val gson = GsonBuilder()
|
||||||
|
.setLenient()
|
||||||
|
.create()
|
||||||
|
|
||||||
return Retrofit.Builder()
|
return Retrofit.Builder()
|
||||||
// .baseUrl(DEVICE_BASE_URL)
|
// .baseUrl(DEVICE_BASE_URL)
|
||||||
.baseUrl(BASE_URL)
|
.baseUrl(BASE_URL)
|
||||||
.client(okHttpClient)
|
.client(okHttpClient)
|
||||||
.addConverterFactory(GsonConverterFactory.create())
|
.addConverterFactory(GsonConverterFactory.create(gson))
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ import android.content.Context
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.core.widget.addTextChangedListener
|
import androidx.core.widget.addTextChangedListener
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.sw.inbound.R
|
import com.sw.inbound.R
|
||||||
@@ -13,6 +15,7 @@ import com.sw.inbound.activity.FoodCollectionActivity
|
|||||||
import com.sw.inbound.adapter.CollectSearchAdapter
|
import com.sw.inbound.adapter.CollectSearchAdapter
|
||||||
import com.sw.inbound.databinding.DialogCollectSearchBinding
|
import com.sw.inbound.databinding.DialogCollectSearchBinding
|
||||||
import com.sw.inbound.databinding.LayoutEmptySearchBinding
|
import com.sw.inbound.databinding.LayoutEmptySearchBinding
|
||||||
|
import com.sw.inbound.model.response.CollectedFoodInfo
|
||||||
import com.sw.inbound.model.response.SearchGoodsInfo
|
import com.sw.inbound.model.response.SearchGoodsInfo
|
||||||
import com.sw.inbound.objbox.ObjectBox
|
import com.sw.inbound.objbox.ObjectBox
|
||||||
import com.sw.inbound.utils.ext.addOnActionSearchListener
|
import com.sw.inbound.utils.ext.addOnActionSearchListener
|
||||||
@@ -28,6 +31,32 @@ class CollectSearchDialog(
|
|||||||
private lateinit var inflater: LayoutInflater
|
private lateinit var inflater: LayoutInflater
|
||||||
private var emptyBinding: LayoutEmptySearchBinding? = null
|
private var emptyBinding: LayoutEmptySearchBinding? = null
|
||||||
private lateinit var binding: DialogCollectSearchBinding
|
private lateinit var binding: DialogCollectSearchBinding
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收集 searchFoodState
|
||||||
|
*/
|
||||||
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
|
private fun initObserver() {
|
||||||
|
activity?.run {
|
||||||
|
lifecycleScope.launch {
|
||||||
|
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
|
userViewModel.collectedFoodListState.collect { items ->
|
||||||
|
binding.rvSearch.layoutManager =
|
||||||
|
GridLayoutManager(activity, 2, LinearLayoutManager.VERTICAL, false)
|
||||||
|
list.clear()
|
||||||
|
list.addAll(items)
|
||||||
|
searchAdapter.notifyDataSetChanged()
|
||||||
|
finishRefresh()
|
||||||
|
binding.root.hideKeyboard()
|
||||||
|
if (items.isEmpty()) {
|
||||||
|
loadEmptyView()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun getRootView(): View {
|
override fun getRootView(): View {
|
||||||
inflater = LayoutInflater.from(context)
|
inflater = LayoutInflater.from(context)
|
||||||
binding = DialogCollectSearchBinding.inflate(inflater)
|
binding = DialogCollectSearchBinding.inflate(inflater)
|
||||||
@@ -82,23 +111,14 @@ class CollectSearchDialog(
|
|||||||
this@CollectSearchDialog.clickIndex = -1
|
this@CollectSearchDialog.clickIndex = -1
|
||||||
val searchName = binding.etInputGoods.text.toString().trim()
|
val searchName = binding.etInputGoods.text.toString().trim()
|
||||||
getCollectGoods(searchName)
|
getCollectGoods(searchName)
|
||||||
}
|
|
||||||
//it.setOnLoadMoreListener {
|
|
||||||
// searchGoods()
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
getCollectGoods()
|
|
||||||
//binding.root.clickWithDebounce {
|
|
||||||
// Thread {
|
|
||||||
// FoodModule.initDefFoodData(activity!!) {
|
|
||||||
// activity?.runOnUiThread {
|
|
||||||
// activity?.toast("添加完成")
|
|
||||||
// getCollectGoods()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }.start()
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
binding.root.postDelayed({
|
||||||
|
finishRefresh()
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
initObserver()
|
||||||
|
getCollectGoods()
|
||||||
}
|
}
|
||||||
|
|
||||||
private var pageNo = 1
|
private var pageNo = 1
|
||||||
@@ -118,17 +138,17 @@ class CollectSearchDialog(
|
|||||||
|
|
||||||
private var clickIndex = -1
|
private var clickIndex = -1
|
||||||
|
|
||||||
private val list: MutableList<SearchGoodsInfo.Record> = mutableListOf()
|
private val list: MutableList<CollectedFoodInfo> = mutableListOf()
|
||||||
private val searchAdapter by lazy {
|
private val searchAdapter by lazy {
|
||||||
CollectSearchAdapter(list).apply {
|
CollectSearchAdapter(list).apply {
|
||||||
isStateViewEnable = true
|
isStateViewEnable = true
|
||||||
setOnItemClickListener { _, _, position ->
|
// setOnItemClickListener { _, _, position ->
|
||||||
activity?.lifecycleScope?.launch {
|
// activity?.lifecycleScope?.launch {
|
||||||
val goodsName = list[position].goodsName?:""
|
// val goodsName = list[position].goodsName?:""
|
||||||
val count = ObjectBox.countNameField(goodsName)
|
// val count = ObjectBox.countNameField(goodsName)
|
||||||
activity?.toast("已采集数据${count}条")
|
// activity?.toast("已采集数据${count}条")
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
addOnItemChildClickListener(R.id.ivDelete) { _, _, position ->
|
addOnItemChildClickListener(R.id.ivDelete) { _, _, position ->
|
||||||
this@CollectSearchDialog.clickIndex = position
|
this@CollectSearchDialog.clickIndex = position
|
||||||
list.forEach { item ->
|
list.forEach { item ->
|
||||||
@@ -144,46 +164,24 @@ class CollectSearchDialog(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun showDeleteDialog(position: Int, deleteAction: () -> Unit = {}) {
|
private fun showDeleteDialog(position: Int, deleteAction: () -> Unit = {}) {
|
||||||
|
val foodName = list[position].foodName
|
||||||
WarnDialog(
|
WarnDialog(
|
||||||
context = context,
|
context = context,
|
||||||
content = "请确认是否删除物品:${list[position].goodsName?.split("WP")?.get(0)}?",
|
content = "请确认是否删除物品:${foodName.split("WP").first()}?",
|
||||||
cancelBlock = {
|
cancelBlock = {
|
||||||
this@CollectSearchDialog.clickIndex = -1
|
this@CollectSearchDialog.clickIndex = -1
|
||||||
list[position].isSelected = false
|
list[position].isSelected = false
|
||||||
searchAdapter.notifyItemChanged(position)
|
searchAdapter.notifyItemChanged(position)
|
||||||
},
|
},
|
||||||
confirmBlock = {
|
confirmBlock = {
|
||||||
// Thread {
|
activity?.userViewModel?.removeCollectedFood(
|
||||||
// }.start()
|
foodName = foodName,
|
||||||
activity?.lifecycleScope?.launch {
|
nameFilter = binding.etInputGoods.text.toString().trim()
|
||||||
deleteGoods(position, deleteAction)
|
)
|
||||||
}
|
deleteAction()
|
||||||
}).show()
|
}).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun deleteGoods(position: Int, deleteAction: () -> Unit = {}) {
|
|
||||||
activity?.runOnUiThread {
|
|
||||||
Loading.show(activity!!)
|
|
||||||
}
|
|
||||||
val name = list[position].goodsName ?: ""
|
|
||||||
// val filterIdList = box?.all?.filter { it.name == name }?.map { it.id }
|
|
||||||
// ObjectBox.boxStore.runInTx {
|
|
||||||
// box?.removeByIds(filterIdList)
|
|
||||||
// }
|
|
||||||
ObjectBox.remove(name)
|
|
||||||
activity?.runOnUiThread {
|
|
||||||
Loading.dismiss()
|
|
||||||
//list.remove(list[position])
|
|
||||||
//searchAdapter.notifyDataSetChanged()
|
|
||||||
searchAdapter.removeAt(position)
|
|
||||||
activity?.toast("删除成功")
|
|
||||||
if (list.isEmpty()) {
|
|
||||||
loadEmptyView()
|
|
||||||
}
|
|
||||||
deleteAction()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun finishRefresh() {
|
private fun finishRefresh() {
|
||||||
binding.refreshLayout.let {
|
binding.refreshLayout.let {
|
||||||
if (pageNo == 1) {
|
if (pageNo == 1) {
|
||||||
@@ -197,27 +195,8 @@ class CollectSearchDialog(
|
|||||||
// private var box: Box<Food>? = null
|
// private var box: Box<Food>? = null
|
||||||
|
|
||||||
@SuppressLint("NotifyDataSetChanged")
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
private fun getCollectGoods(searchName: String? = null) = activity?.lifecycleScope?.launch {
|
private fun getCollectGoods(name: String? = null) {
|
||||||
// if (box == null) {
|
activity?.userViewModel?.loadCollectedFoodList(nameFilter = name)
|
||||||
// box = ObjectBox.boxStore.boxFor(Food::class)
|
|
||||||
// }
|
|
||||||
list.clear()
|
|
||||||
// var queryList = box?.all?.distinctBy { it.name }
|
|
||||||
// if (searchName.isNullOrBlank().not()) {
|
|
||||||
// queryList = queryList?.filter { it.name?.contains(searchName!!) == true }
|
|
||||||
// }
|
|
||||||
val queryList = ObjectBox.filter(searchName)
|
|
||||||
queryList?.forEach {
|
|
||||||
list.add((SearchGoodsInfo.Record(goodsName = it.name)))
|
|
||||||
}
|
|
||||||
binding.rvSearch.layoutManager =
|
|
||||||
GridLayoutManager(activity, 2, LinearLayoutManager.VERTICAL, false)
|
|
||||||
searchAdapter.notifyDataSetChanged()
|
|
||||||
if (list.isEmpty()) {
|
|
||||||
loadEmptyView()
|
|
||||||
}
|
|
||||||
finishRefresh()
|
|
||||||
binding.root.hideKeyboard()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// fun test() {
|
// fun test() {
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
package com.sw.inbound.dialog
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.WindowManager
|
||||||
|
import com.sw.inbound.GlobalData
|
||||||
|
import com.sw.inbound.GlobalKey
|
||||||
|
import com.sw.inbound.databinding.DialogEnvSwitchBinding
|
||||||
|
import com.sw.inbound.utils.SPUtil
|
||||||
|
import com.sw.inbound.utils.ext.dp
|
||||||
|
import com.sw.inbound.utils.ext.toast
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 环境切换弹窗
|
||||||
|
*
|
||||||
|
* 提供 TEST / UAT / PROD 三套环境的切换功能,
|
||||||
|
* 初始化时自动根据 [GlobalData.appBaseUrl] 选中当前环境,
|
||||||
|
* 确认后更新 [GlobalData.appBaseUrl] 并通过 [onEnvChanged] 回调通知外部。
|
||||||
|
*
|
||||||
|
* @param context 上下文
|
||||||
|
* @param onEnvChanged 确认切换后的回调,参数为新的 baseUrl
|
||||||
|
*/
|
||||||
|
class EnvSwitchDialog(
|
||||||
|
context: Context,
|
||||||
|
private val onEnvChanged: (newBaseUrl: String) -> Unit = {}
|
||||||
|
) : BaseDialog(
|
||||||
|
context,
|
||||||
|
defWidth = 600.dp,
|
||||||
|
defHeight = WindowManager.LayoutParams.WRAP_CONTENT
|
||||||
|
) {
|
||||||
|
|
||||||
|
private lateinit var binding: DialogEnvSwitchBinding
|
||||||
|
|
||||||
|
override fun getRootView(): View {
|
||||||
|
binding = DialogEnvSwitchBinding.inflate(LayoutInflater.from(context))
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun initView() {
|
||||||
|
// 根据当前 appBaseUrl 预选对应 RadioButton,不匹配则不选
|
||||||
|
when (GlobalData.appBaseUrl) {
|
||||||
|
GlobalData.TEST_BASE_URL -> binding.rbTest.isChecked = true
|
||||||
|
GlobalData.UAT_BASE_URL -> binding.rbUat.isChecked = true
|
||||||
|
GlobalData.PROD_BASE_URL -> binding.rbProd.isChecked = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消按钮
|
||||||
|
binding.btnCancel.setOnClickListener { dismiss() }
|
||||||
|
|
||||||
|
// 确认按钮
|
||||||
|
binding.btnConfirm.setOnClickListener {
|
||||||
|
// 未选中任何选项时提示用户
|
||||||
|
if (binding.rgEnv.checkedRadioButtonId == -1) {
|
||||||
|
context.toast("请选择环境")
|
||||||
|
return@setOnClickListener
|
||||||
|
}
|
||||||
|
val newUrl = when (binding.rgEnv.checkedRadioButtonId) {
|
||||||
|
binding.rbTest.id -> GlobalData.TEST_BASE_URL
|
||||||
|
binding.rbUat.id -> GlobalData.UAT_BASE_URL
|
||||||
|
binding.rbProd.id -> GlobalData.PROD_BASE_URL
|
||||||
|
else -> return@setOnClickListener
|
||||||
|
}
|
||||||
|
GlobalData.appBaseUrl = newUrl
|
||||||
|
SPUtil.getInstance().put(GlobalKey.KEY_BASE_URL, newUrl)
|
||||||
|
onEnvChanged(newUrl)
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -357,27 +357,28 @@ class GoodsStoreDialog(
|
|||||||
context.toast("入库金额不能为0")
|
context.toast("入库金额不能为0")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (funcType == 1) {
|
// if (funcType == 1) {
|
||||||
activity?.let { Loading.show(it) }
|
//无论是否识别到物品,都上传图片增加样本数据
|
||||||
cameraUtils.takePhoto { uri ->
|
activity?.let { Loading.show(it) }
|
||||||
//imageUri = uri
|
cameraUtils.takePhoto { uri ->
|
||||||
collectGoodsVector(uri) {
|
//imageUri = uri
|
||||||
activity?.uploadImage(goods.id!!, goods.goodsName!!, imageFile)
|
collectGoodsVector(uri) {
|
||||||
}
|
activity?.uploadImage(goods.id!!, goods.goodsName!!, imageFile)
|
||||||
binding.root.postDelayed({
|
|
||||||
Loading.dismiss()
|
|
||||||
confirm(unitName, count, price, totalPrice)
|
|
||||||
}, 500)
|
|
||||||
}
|
}
|
||||||
cameraUtils.addFailCallback {
|
binding.root.postDelayed({
|
||||||
binding.root.postDelayed({
|
Loading.dismiss()
|
||||||
Loading.dismiss()
|
confirm(unitName, count, price, totalPrice)
|
||||||
confirm(unitName, count, price, totalPrice)
|
}, 500)
|
||||||
}, 500)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
confirm(unitName, count, price, totalPrice)
|
|
||||||
}
|
}
|
||||||
|
cameraUtils.addFailCallback {
|
||||||
|
binding.root.postDelayed({
|
||||||
|
Loading.dismiss()
|
||||||
|
confirm(unitName, count, price, totalPrice)
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
// } else {
|
||||||
|
// confirm(unitName, count, price, totalPrice)
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun confirm(unitName: String, count: Double, price: Double, totalPrice: Double?) {
|
private fun confirm(unitName: String, count: Double, price: Double, totalPrice: Double?) {
|
||||||
@@ -423,7 +424,7 @@ class GoodsStoreDialog(
|
|||||||
|
|
||||||
override fun show() {
|
override fun show() {
|
||||||
super.show()
|
super.show()
|
||||||
if (funcType == 1) {
|
// if (funcType == 1) {
|
||||||
takePhotoBinding?.let {
|
takePhotoBinding?.let {
|
||||||
cameraUtils.setPreviewController(previewView)
|
cameraUtils.setPreviewController(previewView)
|
||||||
cameraUtils.bind()
|
cameraUtils.bind()
|
||||||
@@ -433,7 +434,7 @@ class GoodsStoreDialog(
|
|||||||
}, 1000)
|
}, 1000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
// }
|
||||||
binding.root.postDelayed({
|
binding.root.postDelayed({
|
||||||
SensorScaleUtils.startScale()
|
SensorScaleUtils.startScale()
|
||||||
}, 2600)
|
}, 2600)
|
||||||
@@ -454,7 +455,7 @@ class GoodsStoreDialog(
|
|||||||
private var imagePreviewBinding: LayoutImagePreviewBinding? = null
|
private var imagePreviewBinding: LayoutImagePreviewBinding? = null
|
||||||
private fun addChildToContainer() {
|
private fun addChildToContainer() {
|
||||||
val inflater = LayoutInflater.from(context)
|
val inflater = LayoutInflater.from(context)
|
||||||
if (funcType == 1) {
|
// if (funcType == 1) {
|
||||||
//预览及拍照
|
//预览及拍照
|
||||||
takePhotoBinding = LayoutTakePhotoBinding.inflate(inflater, binding.flContainer, true)
|
takePhotoBinding = LayoutTakePhotoBinding.inflate(inflater, binding.flContainer, true)
|
||||||
activity?.unBindCamera()
|
activity?.unBindCamera()
|
||||||
@@ -474,19 +475,19 @@ class GoodsStoreDialog(
|
|||||||
// cameraUtils.takePhoto(takePhotoCallback)
|
// cameraUtils.takePhoto(takePhotoCallback)
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
return
|
if(funcType != 1){
|
||||||
}
|
//只显示原始图片
|
||||||
//只显示原始图片
|
imagePreviewBinding = LayoutImagePreviewBinding.inflate(inflater, binding.flContainer)
|
||||||
imagePreviewBinding = LayoutImagePreviewBinding.inflate(inflater, binding.flContainer)
|
imagePreviewBinding?.imageView?.load(goods.relativeUrl) {
|
||||||
imagePreviewBinding?.imageView?.load(goods.relativeUrl) {
|
transformations(RoundedCornersTransformation(radius = 10.dp.toFloat()))
|
||||||
transformations(RoundedCornersTransformation(radius = 10.dp.toFloat()))
|
}
|
||||||
}
|
binding.flContainer.let {
|
||||||
binding.flContainer.let {
|
it.setBackgroundResource(R.drawable.bg_white_radius10_stroke2)
|
||||||
it.setBackgroundResource(R.drawable.bg_white_radius10_stroke2)
|
it.updateLayoutParams<LinearLayout.LayoutParams> {
|
||||||
it.updateLayoutParams<LinearLayout.LayoutParams> {
|
width = 488.dp
|
||||||
width = 488.dp
|
height = 356.dp
|
||||||
height = 356.dp
|
bottomMargin = 35.dp
|
||||||
bottomMargin = 35.dp
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.sw.inbound.model.request
|
package com.sw.inbound.model.request
|
||||||
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import com.sw.inbound.model.response.BaseBean
|
|
||||||
import com.sw.inbound.model.response.GoodsInfo
|
import com.sw.inbound.model.response.GoodsInfo
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
@@ -19,6 +18,10 @@ data class UploadInfo(
|
|||||||
* 供应商id
|
* 供应商id
|
||||||
*/
|
*/
|
||||||
var supplierId: String? = null,
|
var supplierId: String? = null,
|
||||||
|
/**
|
||||||
|
* 采购单号
|
||||||
|
*/
|
||||||
|
var purCode: String? = null,
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* 物品信息 【全部收货使用】
|
* 物品信息 【全部收货使用】
|
||||||
@@ -90,6 +93,6 @@ private data class UploadGoodsInfo(
|
|||||||
|
|
||||||
// 已调整
|
// 已调整
|
||||||
var isAdjusted: Boolean = false
|
var isAdjusted: Boolean = false
|
||||||
) : Parcelable, BaseBean() {
|
) : Parcelable {
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
package com.sw.inbound.model.response
|
|
||||||
|
|
||||||
open class BaseBean() {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.sw.inbound.model.response
|
||||||
|
|
||||||
|
data class CollectedFoodInfo(
|
||||||
|
var foodName: String,
|
||||||
|
var foodNum: Int,
|
||||||
|
var isSelected: Boolean = false
|
||||||
|
)
|
||||||
@@ -117,7 +117,7 @@ data class GoodsInfo(
|
|||||||
var buyToInventoryValue:String?="",
|
var buyToInventoryValue:String?="",
|
||||||
|
|
||||||
//--------------------------------------------------------
|
//--------------------------------------------------------
|
||||||
) : Parcelable, BaseBean() {
|
) : Parcelable {
|
||||||
|
|
||||||
val goodNameStr: String
|
val goodNameStr: String
|
||||||
get() {
|
get() {
|
||||||
|
|||||||
@@ -31,6 +31,6 @@ data class PurchaseInfo(
|
|||||||
var receiveGoodsInfoList: List<GoodsInfo> = emptyList<GoodsInfo>(),
|
var receiveGoodsInfoList: List<GoodsInfo> = emptyList<GoodsInfo>(),
|
||||||
// 自用
|
// 自用
|
||||||
var warehouseName: String = "选择仓库"
|
var warehouseName: String = "选择仓库"
|
||||||
) : BaseBean() {
|
) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -209,11 +209,40 @@ object ObjectBox {
|
|||||||
} ?: emptyList()
|
} ?: emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按名称分组统计采集数量
|
||||||
|
* 使用属性查询只加载 name 字段,不加载 foodVector,节省大量内存
|
||||||
|
* @param nameFilter 名称过滤关键词,为空时查询全部
|
||||||
|
* @return 按名称分组后的 (名称, 数量) 列表,按名称排序
|
||||||
|
*/
|
||||||
|
suspend fun queryFoodNameCounts(nameFilter: String? = null) = safeDbOp {
|
||||||
|
val box = getBox<Food>() ?: return@safeDbOp emptyList<Pair<String, Int>>()
|
||||||
|
val query = if (!nameFilter.isNullOrBlank()) {
|
||||||
|
box.query(Food_.name.contains(nameFilter)).build()
|
||||||
|
} else {
|
||||||
|
box.query().build()
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// 只查 name 字段,完全不加载 foodVector
|
||||||
|
query.property(Food_.name).findStrings()
|
||||||
|
.groupingBy { it }
|
||||||
|
.eachCount()
|
||||||
|
.map { (name, count) -> Pair(name, count) }
|
||||||
|
.sortedBy { it.first }
|
||||||
|
} finally {
|
||||||
|
query.close()
|
||||||
|
}
|
||||||
|
} ?: emptyList()
|
||||||
|
|
||||||
// 使用 QueryBuilder 在数据库层删除,避免全量加载到内存
|
// 使用 QueryBuilder 在数据库层删除,避免全量加载到内存
|
||||||
suspend fun remove(name: String) = safeDbOp {
|
suspend fun remove(name: String) = safeDbOp {
|
||||||
getBox<Food>()?.query(Food_.name.equal(name))?.build()?.remove()
|
getBox<Food>()?.query(Food_.name.equal(name))?.build()?.remove()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun removeAll() = safeDbOp {
|
||||||
|
getBox<Food>()?.removeAll()
|
||||||
|
}
|
||||||
|
|
||||||
private val dbMutex = Mutex() // 协程并发锁,保证写入操作原子性
|
private val dbMutex = Mutex() // 协程并发锁,保证写入操作原子性
|
||||||
private const val DB_DIR_NAME = "objectbox" // ObjectBox 默认数据库目录
|
private const val DB_DIR_NAME = "objectbox" // ObjectBox 默认数据库目录
|
||||||
private const val BACKUP_DIR_NAME = "objectbox_backup" // 备份目录
|
private const val BACKUP_DIR_NAME = "objectbox_backup" // 备份目录
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.sw.inbound.repository
|
|||||||
|
|
||||||
import com.google.gson.JsonParseException
|
import com.google.gson.JsonParseException
|
||||||
import com.sw.inbound.model.response.ApiResponse
|
import com.sw.inbound.model.response.ApiResponse
|
||||||
|
import com.sw.inbound.utils.LogSaveUtil
|
||||||
import retrofit2.HttpException
|
import retrofit2.HttpException
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
@@ -15,7 +16,7 @@ abstract class BaseRepository {
|
|||||||
apiCall()
|
apiCall()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Timber.e("safeApiCall Exception: ${e.stackTraceToString()}")
|
Timber.e("safeApiCall Exception: ${e.stackTraceToString()}")
|
||||||
|
LogSaveUtil.saveLogFile("safeApiCall Exception: ${e.stackTraceToString()}")
|
||||||
when (e) {
|
when (e) {
|
||||||
is HttpException -> {
|
is HttpException -> {
|
||||||
// 对于HTTP异常,尝试从响应体中获取错误信息
|
// 对于HTTP异常,尝试从响应体中获取错误信息
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import android.os.Bundle
|
|||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
|
import android.view.TouchDelegate
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.inputmethod.EditorInfo
|
import android.view.inputmethod.EditorInfo
|
||||||
import android.view.inputmethod.InputMethodManager
|
import android.view.inputmethod.InputMethodManager
|
||||||
@@ -270,3 +271,24 @@ fun String.copyText(context: Context, showToast: Boolean = true) {
|
|||||||
Toast.makeText(context, "文本已复制到剪贴板", Toast.LENGTH_SHORT).show()
|
Toast.makeText(context, "文本已复制到剪贴板", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 扩大 View 的点击区域
|
||||||
|
* @param horizontal 水平方向扩大距离(dp)→ 左右各扩大一半
|
||||||
|
* @param vertical 垂直方向扩大距离(dp)→ 上下各扩大一半
|
||||||
|
*/
|
||||||
|
fun View.expandClickArea(horizontal: Int, vertical: Int) {
|
||||||
|
val density = resources.displayMetrics.density
|
||||||
|
val hPx = (horizontal * density).toInt()
|
||||||
|
val vPx = (vertical * density).toInt()
|
||||||
|
|
||||||
|
post {
|
||||||
|
val rect = android.graphics.Rect()
|
||||||
|
getHitRect(rect)
|
||||||
|
|
||||||
|
// 扩大区域:负值 = 向外扩大
|
||||||
|
rect.inset(-hPx, -vPx)
|
||||||
|
//rect.bottom += downPx // 只往下扩大
|
||||||
|
(parent as View).touchDelegate = TouchDelegate(rect, this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import androidx.lifecycle.ViewModel
|
|||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.google.gson.reflect.TypeToken
|
import com.google.gson.reflect.TypeToken
|
||||||
import com.sw.inbound.GlobalData
|
import com.sw.inbound.GlobalData
|
||||||
|
import com.sw.inbound.MyApp
|
||||||
import com.sw.inbound.model.response.ApiResponse
|
import com.sw.inbound.model.response.ApiResponse
|
||||||
import com.sw.inbound.model.response.DictType
|
import com.sw.inbound.model.response.DictType
|
||||||
import com.sw.inbound.model.response.EquipmentInfo
|
import com.sw.inbound.model.response.EquipmentInfo
|
||||||
@@ -16,6 +17,7 @@ import com.sw.inbound.repository.RemoteRepository
|
|||||||
import com.sw.inbound.utils.SPUtil
|
import com.sw.inbound.utils.SPUtil
|
||||||
//import com.sw.inbound.utils.ToastUtils
|
//import com.sw.inbound.utils.ToastUtils
|
||||||
import com.sw.inbound.utils.ext.toType
|
import com.sw.inbound.utils.ext.toType
|
||||||
|
import com.sw.inbound.utils.ext.toast
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
@@ -102,7 +104,8 @@ abstract class BaseViewModel(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
Timber.d("msg = ${response.msg}, code = ${response.code}")
|
Timber.d("msg = ${response.msg}, code = ${response.code}")
|
||||||
//ToastUtils.showToast("${response.msg}(${response.code})")
|
// ToastUtils.showToast("${response.msg}(${response.code})")
|
||||||
|
MyApp.instance?.toast("${response.msg}(${response.code})")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,17 +212,25 @@ abstract class BaseViewModel(
|
|||||||
callback: (List<SearchGoodsInfo.Record>) -> Unit
|
callback: (List<SearchGoodsInfo.Record>) -> Unit
|
||||||
) {
|
) {
|
||||||
launch {
|
launch {
|
||||||
if (nameList.isNullOrEmpty() && scoreList.isNullOrEmpty()) return@launch
|
try {
|
||||||
val paramList = if (nameList.isNullOrEmpty()) scoreList!!.map { it.name } else nameList
|
if (nameList.isNullOrEmpty() && scoreList.isNullOrEmpty()) {
|
||||||
val response = repository.recognizeGoodsList(paramList)
|
callback(listOf())
|
||||||
val list = if (parseResponse(response)) response.data ?: listOf() else listOf()
|
return@launch
|
||||||
if (scoreList.isNullOrEmpty().not()) {
|
|
||||||
list.forEach { record ->
|
|
||||||
val item = scoreList.firstOrNull { it.name == record.goodsName }
|
|
||||||
record.score = ((1 - (item?.score ?: 0.0)) * 10000).roundToInt()
|
|
||||||
}
|
}
|
||||||
|
val paramList = if (nameList.isNullOrEmpty()) scoreList!!.map { it.name } else nameList
|
||||||
|
val response = repository.recognizeGoodsList(paramList)
|
||||||
|
val list = if (parseResponse(response)) response.data ?: listOf() else listOf()
|
||||||
|
if (scoreList.isNullOrEmpty().not()) {
|
||||||
|
list.forEach { record ->
|
||||||
|
val item = scoreList.firstOrNull { it.name == record.goodsName }
|
||||||
|
record.score = ((1 - (item?.score ?: 0.0)) * 10000).roundToInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback(list)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Timber.e(e)
|
||||||
|
callback(listOf())
|
||||||
}
|
}
|
||||||
callback(list)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -323,17 +323,17 @@ class ReceiptViewModel @Inject constructor(
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
fun confirmReceipt(uploadInfo: UploadInfo, callback: (Boolean) -> Unit) {
|
fun confirmReceipt(uploadInfo: UploadInfo, callback: (Boolean, String) -> Unit) {
|
||||||
launchWithLoading {
|
launchWithLoading {
|
||||||
val resp = repository.confirmReceipt(uploadInfo)
|
val resp = repository.confirmReceipt(uploadInfo)
|
||||||
callback(resp.data == true)
|
callback(resp.isSuccess(), resp.msg?:"")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addToWarehouse(list: List<PurchaseWarehouseParam>, callback: (Boolean) -> Unit) {
|
fun addToWarehouse(list: List<PurchaseWarehouseParam>, callback: (Boolean, String) -> Unit) {
|
||||||
launchWithLoading {
|
launchWithLoading {
|
||||||
val resp = repository.selfPurchaseWarehousing(list)
|
val resp = repository.selfPurchaseWarehousing(list)
|
||||||
callback(resp.data == true)
|
callback(resp.isSuccess(), resp.msg?:"")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -409,11 +409,7 @@ class ReceiptViewModel @Inject constructor(
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
val resp = repository.uploadMultipleImages(fileList = fileList, params = params)
|
val resp = repository.uploadMultipleImages(fileList = fileList, params = params)
|
||||||
// if (!parseResponse(resp)) {
|
return parseResponse(resp)
|
||||||
// callback(false)
|
|
||||||
// return@launchWithLoading
|
|
||||||
// }
|
|
||||||
return resp.code == "00000"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,17 +1,23 @@
|
|||||||
package com.sw.inbound.viewmodel
|
package com.sw.inbound.viewmodel
|
||||||
|
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.sw.inbound.GlobalData
|
import com.sw.inbound.GlobalData
|
||||||
import com.sw.inbound.GlobalKey
|
import com.sw.inbound.GlobalKey
|
||||||
import com.sw.inbound.model.request.LoginParam
|
import com.sw.inbound.model.request.LoginParam
|
||||||
|
import com.sw.inbound.model.response.CollectedFoodInfo
|
||||||
import com.sw.inbound.model.response.User
|
import com.sw.inbound.model.response.User
|
||||||
|
import com.sw.inbound.objbox.ObjectBox
|
||||||
import com.sw.inbound.repository.RemoteRepository
|
import com.sw.inbound.repository.RemoteRepository
|
||||||
import com.sw.inbound.utils.GsonUtils
|
import com.sw.inbound.utils.GsonUtils
|
||||||
import com.sw.inbound.utils.SPUtil
|
import com.sw.inbound.utils.SPUtil
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import kotlin.collections.remove
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class UserViewModel @Inject constructor(
|
class UserViewModel @Inject constructor(
|
||||||
@@ -64,6 +70,39 @@ class UserViewModel @Inject constructor(
|
|||||||
SPUtil.getInstance().remove(GlobalKey.KEY_TOKEN)
|
SPUtil.getInstance().remove(GlobalKey.KEY_TOKEN)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已采集食材列表 UI 状态流
|
||||||
|
* 元素为按名称分组后的(名称,数量)数据
|
||||||
|
*/
|
||||||
|
private val _collectedFoodListState = MutableStateFlow<List<CollectedFoodInfo>>(emptyList())
|
||||||
|
val collectedFoodListState: StateFlow<List<CollectedFoodInfo>> = _collectedFoodListState.asStateFlow()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载已采集食材列表,按名称分组统计数量
|
||||||
|
* 使用属性查询只读 name 字段,不加载 foodVector,节省内存
|
||||||
|
* @param nameFilter 名称过滤关键词,为空时加载全部
|
||||||
|
*/
|
||||||
|
fun loadCollectedFoodList(nameFilter: String? = null) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
val result = ObjectBox.queryFoodNameCounts(nameFilter)
|
||||||
|
_collectedFoodListState.value = result.map { (name, count) ->
|
||||||
|
CollectedFoodInfo(foodName = name, foodNum = count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除指定名称的所有采集记录,删除完成后刷新列表
|
||||||
|
* @param foodName 食材名称
|
||||||
|
* @param nameFilter 当前搜索关键词,用于删除后刷新列表
|
||||||
|
*/
|
||||||
|
fun removeCollectedFood(foodName: String, nameFilter: String? = null) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
ObjectBox.remove(foodName)
|
||||||
|
loadCollectedFoodList(nameFilter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun handleSensorScale(weight: Double) {
|
override fun handleSensorScale(weight: Double) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="240dp"
|
||||||
|
android:height="240dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
|
||||||
|
<!-- 由小到大排列的圆点,构成旋转加载指示器 -->
|
||||||
|
<path
|
||||||
|
android:fillColor="#262626"
|
||||||
|
android:pathData="M876.864,782.592c3.264,0 6.272,-3.2 6.272,-6.656c0,-3.456 -3.008,-6.592 -6.272,-6.592c-3.264,0 -6.272,3.2 -6.272,6.592c0,3.456 3.008,6.656 6.272,6.656z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#262626"
|
||||||
|
android:pathData="M736.32,935.936c2.304,2.432 5.568,3.84 8.768,3.84a12.16,12.16 0,0 0,8.832 -3.84a13.76,13.76 0,0 0,0 -18.56a12.224,12.224 0,0 0,-8.832 -3.84a12.16,12.16 0,0 0,-8.768 3.84a13.696,13.696 0,0 0,0 18.56z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#262626"
|
||||||
|
android:pathData="M552.32,1018.24c3.456,3.648 8.32,5.76 13.184,5.76a18.368,18.368 0,0 0,13.184 -5.76a20.608,20.608 0,0 0,0 -27.968a18.368,18.368 0,0 0,-13.184 -5.824a18.368,18.368 0,0 0,-13.184 5.76a20.608,20.608 0,0 0,0 28.032z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#262626"
|
||||||
|
android:pathData="M353.984,1012.48c4.608,4.8 11.072,7.68 17.6,7.68a24.448,24.448 0,0 0,17.536 -7.68a27.456,27.456 0,0 0,0 -37.248a24.448,24.448 0,0 0,-17.536 -7.68a24.448,24.448 0,0 0,-17.6 7.68a27.52,27.52 0,0 0,0 37.184z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#262626"
|
||||||
|
android:pathData="M178.304,920.64c5.76,6.08 13.824,9.6 21.952,9.6a30.592,30.592 0,0 0,22.016 -9.6a34.368,34.368 0,0 0,0 -46.592a30.592,30.592 0,0 0,-22.016 -9.6a30.592,30.592 0,0 0,-21.952 9.6a34.368,34.368 0,0 0,0 46.592z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#262626"
|
||||||
|
android:pathData="M57.152,761.28c6.912,7.36 16.64,11.648 26.368,11.648a36.736,36.736 0,0 0,26.432 -11.584a41.28,41.28 0,0 0,0 -55.936a36.736,36.736 0,0 0,-26.432 -11.584a36.8,36.8 0,0 0,-26.368 11.52a41.28,41.28 0,0 0,0 56z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#262626"
|
||||||
|
android:pathData="M12.736,564.672a42.88,42.88 0,0 0,30.784 13.44a42.88,42.88 0,0 0,30.784 -13.44a48.128,48.128 0,0 0,0 -65.216a42.88,42.88 0,0 0,-30.72 -13.44a42.88,42.88 0,0 0,-30.848 13.44a48.128,48.128 0,0 0,0 65.216z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#262626"
|
||||||
|
android:pathData="M52.544,369.28a48.96,48.96 0,0 0,35.2 15.36a48.96,48.96 0,0 0,35.2 -15.36a54.976,54.976 0,0 0,0 -74.56a48.96,48.96 0,0 0,-35.2 -15.424a48.96,48.96 0,0 0,-35.2 15.424a54.976,54.976 0,0 0,0 74.56z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#262626"
|
||||||
|
android:pathData="M168.32,212.48c10.368,11.008 24.96,17.408 39.68,17.408c14.592,0 29.184,-6.4 39.552,-17.408a61.888,61.888 0,0 0,0 -83.84a55.104,55.104 0,0 0,-39.616 -17.408c-14.656,0 -29.248,6.4 -39.616,17.408a61.888,61.888 0,0 0,0 83.84z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#262626"
|
||||||
|
android:pathData="M337.344,124.8c11.52,12.16 27.712,19.264 43.968,19.264c16.256,0 32.448,-7.04 43.968,-19.264a68.672,68.672 0,0 0,0 -93.184a61.248,61.248 0,0 0,-43.968 -19.264a61.248,61.248 0,0 0,-43.968 19.264a68.736,68.736 0,0 0,0 93.184z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#262626"
|
||||||
|
android:pathData="M526.976,123.712c12.672,13.44 30.528,21.248 48.448,21.248s35.712,-7.808 48.384,-21.248a75.584,75.584 0,0 0,0 -102.464A67.392,67.392 0,0 0,575.36 0c-17.92,0 -35.776,7.808 -48.448,21.248a75.584,75.584 0,0 0,0 102.464z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#262626"
|
||||||
|
android:pathData="M700.8,210.304c13.824,14.592 33.28,23.104 52.736,23.104c19.584,0 39.04,-8.512 52.8,-23.104a82.432,82.432 0,0 0,0 -111.744a73.472,73.472 0,0 0,-52.8 -23.168c-19.52,0 -38.912,8.512 -52.736,23.168a82.432,82.432 0,0 0,0 111.744z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#262626"
|
||||||
|
android:pathData="M824.832,368.832c14.976,15.872 36.032,25.088 57.216,25.088c21.12,0 42.24,-9.216 57.152,-25.088a89.344,89.344 0,0 0,0 -121.088a79.616,79.616 0,0 0,-57.152 -25.088c-21.184,0 -42.24,9.216 -57.216,25.088a89.344,89.344 0,0 0,0 121.088z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#262626"
|
||||||
|
android:pathData="M875.264,572.864c16.128,17.088 38.784,27.008 61.632,27.008c22.784,0 45.44,-9.92 61.568,-27.008a96.256,96.256 0,0 0,0 -130.432a85.76,85.76 0,0 0,-61.568 -27.072c-22.848,0 -45.44,9.984 -61.632,27.072a96.192,96.192 0,0 0,0 130.432z" />
|
||||||
|
|
||||||
|
</vector>
|
||||||
@@ -38,6 +38,7 @@
|
|||||||
android:id="@+id/tvTime"
|
android:id="@+id/tvTime"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingVertical="10dp"
|
||||||
android:textColor="@color/black"
|
android:textColor="@color/black"
|
||||||
android:textSize="24sp"
|
android:textSize="24sp"
|
||||||
android:visibility="visible"
|
android:visibility="visible"
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
android:id="@+id/ivLoading"
|
android:id="@+id/ivLoading"
|
||||||
android:layout_width="160dp"
|
android:layout_width="160dp"
|
||||||
android:layout_height="160dp"
|
android:layout_height="160dp"
|
||||||
android:src="@drawable/loading_spinner"
|
android:src="@drawable/loading"
|
||||||
android:contentDescription="加载中" />
|
android:contentDescription="加载中" />
|
||||||
|
|
||||||
<!-- 倒计时文字 -->
|
<!-- 倒计时文字 -->
|
||||||
|
|||||||
@@ -0,0 +1,106 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="600dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/bg_white_radius12"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingHorizontal="40dp"
|
||||||
|
android:paddingVertical="36dp">
|
||||||
|
|
||||||
|
<!-- 标题 -->
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="环境切换"
|
||||||
|
android:textColor="#ff141428"
|
||||||
|
android:textSize="36sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<!-- 分割线 -->
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="2dp"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:background="#FFDCDCF0" />
|
||||||
|
|
||||||
|
<!-- 环境选项 -->
|
||||||
|
<RadioGroup
|
||||||
|
android:id="@+id/rgEnv"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rbTest"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="72dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:paddingStart="16dp"
|
||||||
|
android:text="测试环境"
|
||||||
|
android:textColor="#ff141428"
|
||||||
|
android:textSize="28sp" />
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rbUat"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="72dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:paddingStart="16dp"
|
||||||
|
android:text="UAT 环境"
|
||||||
|
android:textColor="#ff141428"
|
||||||
|
android:textSize="28sp" />
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rbProd"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="72dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:paddingStart="16dp"
|
||||||
|
android:text="生产环境"
|
||||||
|
android:textColor="#ff141428"
|
||||||
|
android:textSize="28sp" />
|
||||||
|
|
||||||
|
</RadioGroup>
|
||||||
|
|
||||||
|
<!-- 分割线 -->
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="2dp"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:background="#FFDCDCF0" />
|
||||||
|
|
||||||
|
<!-- 底部按钮 -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="88dp"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnCancel"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginEnd="20dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@drawable/bg_white_radius10_stroke2"
|
||||||
|
android:text="取消"
|
||||||
|
android:textColor="#ff141428"
|
||||||
|
android:textSize="28sp" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btnConfirm"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@drawable/bg_blue_radius10"
|
||||||
|
android:text="确认"
|
||||||
|
android:textColor="#ffffff"
|
||||||
|
android:textSize="28sp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="82dp"
|
android:layout_height="100dp"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_marginVertical="10dp"
|
android:layout_marginVertical="10dp"
|
||||||
android:layout_marginHorizontal="20dp"
|
android:layout_marginHorizontal="20dp"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
@@ -11,23 +12,41 @@
|
|||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tvGoodsName"
|
android:id="@+id/tvGoodsName"
|
||||||
android:layout_width="0dp"
|
android:layout_width="wrap_content"
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
|
||||||
tools:text="高杆白菜"
|
tools:text="高杆白菜"
|
||||||
android:textColor="#ff666666"
|
android:textColor="#ff333333"
|
||||||
android:textSize="30sp"
|
android:textSize="30sp"
|
||||||
|
app:layout_constraintVertical_chainStyle="packed"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/tvGoodsNum"
|
||||||
android:layout_marginStart="30dp"
|
android:layout_marginStart="30dp"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:layout_marginHorizontal="10dp"
|
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvGoodsNum"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:text="已采集100"
|
||||||
|
app:layout_constraintStart_toStartOf="@id/tvGoodsName"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/tvGoodsName"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
android:textColor="#ff666666"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:ellipsize="end" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/ivDelete"
|
android:id="@+id/ivDelete"
|
||||||
android:layout_width="80dp"
|
android:layout_width="80dp"
|
||||||
android:layout_height="80dp"
|
android:layout_height="80dp"
|
||||||
android:padding="25dp"
|
android:padding="25dp"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
android:src="@mipmap/ic_close"/>
|
android:src="@mipmap/ic_close"/>
|
||||||
</LinearLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
+3
-3
@@ -28,9 +28,9 @@ buildscript {
|
|||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
plugins {
|
//plugins {
|
||||||
alias(libs.plugins.kotlin.compose) apply false
|
// alias(libs.plugins.kotlin.compose) apply false
|
||||||
}
|
//}
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
|
|||||||
Reference in New Issue
Block a user