棉花app新增页面

This commit is contained in:
czz
2025-06-03 09:34:31 +08:00
parent 79a9f165e1
commit 7e0dfa7494
112 changed files with 18479 additions and 73 deletions

3
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"cmake.sourceDirectory": "D:/flutter/vbvs_app-1/linux"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 645 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="32.814453125" height="32.814697265625" viewBox="0 0 32.814453125 32.814697265625"><g><g><ellipse cx="16.407336235046387" cy="16.407336235046387" rx="15.407336235046387" ry="15.407336235046387" fill-opacity="0" stroke-opacity="1" stroke="#929699" fill="none" stroke-width="2" stroke-linecap="ROUND"/></g><g><g><path d="M16.4072271875,19.62646484375L12.6826171875,19.62646484375Q12.4146841875,19.62646484375,12.1826431875,19.76042484375Q12.0973461875,19.80966784375,12.0232941875,19.87460484375Q11.9492421875,19.93954284375,11.8892821875,20.01767984375Q11.8293221875,20.09581684375,11.7857581875,20.18414884375Q11.7421931875,20.27248184375,11.7166991875,20.36761684375Q11.6912051875,20.46275184375,11.6847601875,20.56103174375Q11.6783171875,20.65931204375,11.6911681875,20.75696084375Q11.7040211875,20.85461084375,11.7356771875,20.94787584375Q11.7673331875,21.04114084375,11.8165771875,21.12643884375L13.6788981875,24.352294843750002L15.5412071875,27.57788484375Q15.675177187500001,27.80993484375,15.9072271875,27.94390484375Q15.992517187499999,27.99314484375,16.0857871875,28.02480484375Q16.1790471875,28.05646484375,16.276697187499998,28.06932484375Q16.3743471875,28.08218484375,16.4726271875,28.07573484375Q16.5709071875,28.06929484375,16.6660471875,28.04380484375Q16.7611771875,28.018314843749998,16.849507187500002,27.97475484375Q16.9378471875,27.93119484375,17.015987187500002,27.87123484375Q17.0941271875,27.81127484375,17.1590671875,27.73722484375Q17.2240071875,27.66317484375,17.2732471875,27.57788484375L19.1355171875,24.35236484375L20.9983071875,21.12653684375Q21.1323271875,20.89445884375,21.1323271875,20.62646484375Q21.1323271875,20.52797344375,21.1131071875,20.43137484375Q21.093897187499998,20.33477584375,21.0562071875,20.24378184375Q21.0185071875,20.15278684375,20.9637871875,20.07089484375Q20.9090771875,19.98900184375,20.8394271875,19.91935784375Q20.7697871875,19.84971384375,20.6878971875,19.79499584375Q20.6059971875,19.74027684375,20.5150071875,19.70258584375Q20.4240071875,19.664894843749998,20.3274171875,19.64567984375Q20.2308171875,19.62646484375,20.1323271875,19.62646484375L16.4072271875,19.62646484375ZM14.4146071875,21.62646484375L15.4109471875,23.352294843750002L16.4072271875,25.077894843750002L17.4035471875,23.35222484375L18.400107187499998,21.62646484375L14.4146071875,21.62646484375Z" fill-rule="evenodd" fill="#929699" fill-opacity="1"/></g><g><path d="M16.4072271875,13.187992265624999L20.1323271875,13.187992265624999Q20.4003171875,13.187992265624999,20.6323971875,13.053972265625Q20.804647187500002,12.954502265624999,20.9257271875,12.796682265625Q21.0468071875,12.638862265625,21.0982671875,12.446722265624999Q21.1497371875,12.254582265625,21.1237571875,12.057382265625Q21.0977771875,11.860172265625,20.9983071875,11.687912265625L19.135557187499998,8.462152265625L17.2732471875,5.236570265625Q17.1392771875,5.004522265625,16.9072271875,4.870548265625Q16.7349671875,4.7710912656249995,16.5377571875,4.7451282656250005Q16.3405471875,4.719162265625,16.1484071875,4.770646265625Q15.9562771875,4.822127265625,15.7984671875,4.943217265625Q15.6406571875,5.064307265625,15.5412071875,5.236570265625L13.6788811875,8.462182265625L11.8165771875,11.688012265625Q11.6826171875,11.920052265625,11.6826171875,12.187992265624999Q11.6826171875,12.286482265625,11.701832187499999,12.383082265625Q11.7210471875,12.479672265625,11.7587381875,12.570672265625Q11.7964291875,12.661662265625,11.8511481875,12.743552265625Q11.9058661875,12.825452265625,11.9755101875,12.895092265625Q12.0451541875,12.964742265625,12.1270471875,13.019452265624999Q12.2089391875,13.074172265625,12.2999341875,13.111862265625Q12.3909281875,13.149562265625,12.4875271875,13.168772265625Q12.5841257875,13.187992265624999,12.6826171875,13.187992265624999L16.4072271875,13.187992265624999ZM18.400107187499998,11.187992265624999L17.4035071875,9.462162265625L16.4072271875,7.736562265625L15.410967187499999,9.462132265625L14.4146071875,11.187992265624999L18.400107187499998,11.187992265624999Z" fill-rule="evenodd" fill="#929699" fill-opacity="1"/></g></g></g></svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 37.32 32.47">
<path d="M18.49,4.76l.15.15.15-.15C23.61.2,29.14.09,33,3.83L33.1,4a10.08,10.08,0,0,1,.11,14.37L19.63,30.93a1.45,1.45,0,0,1-2,0L4.07,18.32l-.05,0a10.16,10.16,0,0,1,.2-14.35C8,.06,13.63.14,18.49,4.76Z"
fill="none" stroke="#929699" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.3"/>
<polyline points="10.27 14.98 14.13 14.98 16.55 10.39 20.39 18.63 23.18 14.72 26.78 14.72"
fill="none" stroke="#929699" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.3"/>
</svg>

After

Width:  |  Height:  |  Size: 579 B

View File

@@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 29.92 33.75">
<title>资源 485</title>
<g id="图层_2" data-name="图层 2">
<g id="图层_1-2" data-name="图层 1">
<path
d="M28.92,13,14.83,1,1,13V29.44a3.31,3.31,0,0,0,3.31,3.31h21.3a3.31,3.31,0,0,0,3.31-3.31Z"
style="fill:none;stroke:#929699;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px;" />
<line
x1="14.83" y1="28.08" x2="14.83" y2="18.58"
style="fill:none;stroke:#929699;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px;" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 591 B

View File

@@ -0,0 +1,22 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 33.71 34.07">
<title>资源 486</title>
<g id="图层_2" data-name="图层 2">
<g id="图层_1-2" data-name="图层 1">
<path
d="M22.05,15.18a8,8,0,1,0-10.39,0"
style="fill:none;stroke:#929699;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px;" />
<path
d="M32.43,33.07a15.63,15.63,0,0,0,.28-2.92,15.87,15.87,0,0,0-10.66-15"
style="fill:none;stroke:#929699;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px;" />
<path
d="M11.66,15.18A15.87,15.87,0,0,0,1,30.15a15.63,15.63,0,0,0,.28,2.92"
style="fill:none;stroke:#929699;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px;" />
<line
x1="23.6" y1="33.07" x2="1.28" y2="33.07"
style="fill:none;stroke:#929699;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px;" />
<line
x1="16.86" y1="18.9" x2="16.86" y2="27.83"
style="fill:none;stroke:#929699;stroke-linecap:round;stroke-linejoin:round;stroke-width:2px;" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
assets/images/bed_name.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

11
assets/images/edit.svg Normal file
View File

@@ -0,0 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.96 16.7">
<title>资源 494 </title>
<g id="图层_2" data-name="图层 2">
<g id="图层_1-2" data-name="图层 1">
<line x1="6.77" y1="9.8" x2="15.16" y2="1.4"
style="fill:none;stroke:#fff;stroke-linecap:round;stroke-miterlimit:10;stroke-width:1.6px;"/>
<path d="M9.51.8H2.66A1.86,1.86,0,0,0,.8,2.66V14A1.86,1.86,0,0,0,2.66,15.9h9.16A1.86,1.86,0,0,0,13.68,14V8.85"
style="fill:none;stroke:#fff;stroke-linecap:round;stroke-miterlimit:10;stroke-width:1.6px;"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 576 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

BIN
assets/images/new_empty.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="40" height="40" viewBox="0 0 40 40"><g><g></g><g><g><path d="M24.048341076965333,30.67284805114746C23.77539107696533,30.67284805114746,23.50146107696533,30.57909805114746,23.278321076965334,30.38769805114746C23.278321076965334,30.38769805114746,17.26464907696533,25.217778051147462,17.26464907696533,25.217778051147462C16.76953157696533,24.79296805114746,16.71337907696533,24.04687505114746,17.137696076965334,23.551758051147463C17.56347707696533,23.05761705114746,18.309571076965334,23.00097605114746,18.80371107696533,23.42578105114746C18.80371107696533,23.42578105114746,24.81836107696533,28.59570805114746,24.81836107696533,28.59570805114746C25.312501076965333,29.02050805114746,25.369631076965334,29.76659805114746,24.944331076965334,30.26171805114746C24.71045107696533,30.53320805114746,24.380371076965332,30.67284805114746,24.048341076965333,30.67284805114746C24.048341076965333,30.67284805114746,24.048341076965333,30.67284805114746,24.048341076965333,30.67284805114746C24.048341076965333,30.67284805114746,24.048341076965333,30.67284805114746,24.048341076965333,30.67284805114746Z" fill="#FFFFFF" fill-opacity="1"/></g><g><path d="M24.085449539794922,30.67285827407837C23.823730539794923,30.67285827407837,23.56054653979492,30.58595827407837,23.341308539794923,30.40725827407837C22.83544883979492,29.99705827407837,22.75878853979492,29.252958274078367,23.17040953979492,28.74705827407837C23.17040953979492,28.74705827407837,32.22362953979492,17.61621127407837,32.22362953979492,17.61621127407837C32.634769539794924,17.11035147407837,33.37845953979492,17.033203274078367,33.88475953979492,17.44531227407837C34.390659539794925,17.85742227407837,34.467759539794926,18.601558274078368,34.055659539794924,19.10741827407837C34.055659539794924,19.10741827407837,25.003419539794923,30.23635827407837,25.003419539794923,30.23635827407837C24.76952953979492,30.52345827407837,24.42968953979492,30.67285827407837,24.085449539794922,30.67285827407837C24.085449539794922,30.67285827407837,24.085449539794922,30.67285827407837,24.085449539794922,30.67285827407837C24.085449539794922,30.67285827407837,24.085449539794922,30.67285827407837,24.085449539794922,30.67285827407837Z" fill="#FFFFFF" fill-opacity="1"/></g><g><g><rect x="5.67919921875" y="9.861328125" width="22.933929443359375" height="3" rx="0" fill="#FFFFFF" fill-opacity="1"/></g></g><g><g><rect x="5.67919921875" y="17.3671875" width="18.406814575195312" height="3" rx="0" fill="#FFFFFF" fill-opacity="1"/></g></g><g><g><rect x="5.67919921875" y="24.8740234375" width="9.02734375" height="3" rx="0" fill="#FFFFFF" fill-opacity="1"/></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="42" height="42" viewBox="0 0 42 42">
<g>
<g></g>
<g>
<path
d="M11.817383954467774,30.1592234375C11.193363954467774,30.1592234375,10.583983954467774,29.9062234375,10.145995954467773,29.4648234375C9.699218954467774,29.0219234375,9.446289434467774,28.4111234375,9.449219125667774,27.7871234375C9.449219125667774,27.7871234375,9.449219125667774,24.1802234375,9.449219125667774,24.1802234375C9.447266004467773,23.5532234375,9.701171954467773,22.9419234375,10.143066954467773,22.5019234375C10.143066954467773,22.5019234375,23.142093954467775,9.5009764375,23.142093954467775,9.5009764375C23.706993954467773,8.9350584375,24.457993954467774,8.6240234375,25.257293954467773,8.6240234375C26.066393954467774,8.6240234375,26.837393954467775,8.9428714375,27.392093954467775,9.5000004375C27.392093954467775,9.5000004375,30.086393954467773,12.1928734375,30.086393954467773,12.1928734375C30.653293954467774,12.7568334375,30.976093954467775,13.5380834375,30.974093954467772,14.3369134375C30.976093954467775,15.1381834375,30.653293954467774,15.918943437500001,30.088393954467772,16.4819334375C30.088393954467772,16.4819334375,17.104983954467773,29.4619234375,17.104983954467773,29.4619234375C16.665043954467773,29.9062234375,16.056153954467774,30.1592234375,15.433103954467773,30.1592234375C15.433103954467773,30.1592234375,11.817383954467774,30.1592234375,11.817383954467774,30.1592234375ZM11.223143954467773,23.9448234375C11.223143954467773,23.9448234375,11.235353954467774,28.3740234375,11.235353954467774,28.3740234375C11.235353954467774,28.3740234375,15.685063954467774,28.3740234375,15.685063954467774,28.3740234375C15.685063954467774,28.3740234375,24.586393954467773,19.4648234375,24.586393954467773,19.4648234375C24.586393954467773,19.4648234375,20.172393954467772,14.995113437499999,20.172393954467772,14.995113437499999C20.172393954467772,14.995113437499999,11.223143954467773,23.9448234375,11.223143954467773,23.9448234375ZM25.266093954467774,10.4038134375C24.945293954467772,10.4038134375,24.630393954467774,10.5351534375,24.402293954467773,10.7641634375C24.402293954467773,10.7641634375,21.433093954467772,13.732913437499999,21.433093954467772,13.732913437499999C21.433093954467772,13.732913437499999,25.845193954467774,18.205073437499998,25.845193954467774,18.205073437499998C25.845193954467774,18.205073437499998,28.827193954467774,15.2221634375,28.827193954467774,15.2221634375C29.060093954467774,14.9892534375,29.193393954467773,14.6660134375,29.191393954467774,14.3359334375C29.194293954467774,14.0122034375,29.060093954467774,13.6879834375,28.824193954467773,13.4531234375C28.824193954467773,13.4531234375,26.133293954467774,10.7631834375,26.133293954467774,10.7631834375C25.904293954467775,10.5322234375,25.598193954467774,10.4038134375,25.270993954467773,10.4038134375C25.270993954467773,10.4038134375,25.266093954467774,10.4038134375,25.266093954467774,10.4038134375Z"
style="fill:#FFFFFF; fill-opacity:1"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="30" height="30" viewBox="0 0 30 30"><g><g><g><g transform="matrix(0,-1,1,0,-30,30)"></g></g><g><g><g><path d="M18.657226875,15.000118593749999C18.657226875,15.128538593750001,18.608396875,15.25646859375,18.510746875,15.35314859375C18.510746875,15.35314859375,12.195312875,21.66955859375,12.195312875,21.66955859375C11.999999875,21.864358593749998,11.684569875,21.864358593749998,11.488280875,21.66955859375C11.292968775,21.47425859375,11.292968775,21.15735859375,11.488280875,20.96255859375C11.488280875,20.96255859375,17.450196875,15.000118593749999,17.450196875,15.000118593749999C17.450196875,15.000118593749999,11.488280875,9.03820759375,11.488280875,9.03820759375C11.292968775,8.84338359375,11.292968775,8.52648959375,11.488280875,8.33117659375C11.684569875,8.13635249375,11.999999875,8.13635249375,12.195312875,8.33117659375C12.195312875,8.33117659375,18.510746875,14.64611859375,18.510746875,14.64611859375C18.608396875,14.74425859375,18.657226875,14.87218859375,18.657226875,15.000118593749999C18.657226875,15.000118593749999,18.657226875,15.000118593749999,18.657226875,15.000118593749999Z" fill="#FFFFFF" fill-opacity="1"/></g></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 37.18 37.18">
<title>资源 530</title>
<g id="图层_2" data-name="图层 2">
<g id="图层_1-2" data-name="图层 1">
<path style="fill:#fff;" d="M18.59,37.18A18.59,18.59,0,1,1,37.18,18.59,18.61,18.61,0,0,1,18.59,37.18ZM18.59,2A16.59,16.59,0,1,0,35.18,18.59,16.61,16.61,0,0,0,18.59,2Z"/>
<path style="fill:#fff;" d="M26.5,23.28a1.06,1.06,0,0,1-.42-.09L18.17,19.5A1,1,0,1,1,19,17.68l7.92,3.69a1,1,0,0,1-.43,1.91Z"/>
<path style="fill:#fff;" d="M18.59,19.59a1,1,0,0,1-1-1V6.43a1,1,0,0,1,2,0V18.59A1,1,0,0,1,18.59,19.59Z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 625 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="42" height="42" viewBox="0 0 42 42"><g><g><g><g></g></g><g><g><g><path d="M20.9999515625,6.734619140625C13.1210915625,6.734619140625,6.7353515625,13.121579140625,6.7353515625,21.000519140625002C6.7353515625,28.878619140625,13.1210915625,35.265619140625,20.9999515625,35.265619140625C28.8784515625,35.265619140625,35.2651515625,28.878619140625,35.2651515625,21.000519140625002C35.2651515625,13.121579140625,28.8784515625,6.734619140625,20.9999515625,6.734619140625C20.9999515625,6.734619140625,20.9999515625,6.734619140625,20.9999515625,6.734619140625ZM20.9999515625,33.227519140625C14.2470715625,33.227519140625,8.7724615625,27.752719140625,8.7724615625,21.000519140625002C8.7724615625,14.247559140625,14.2470715625,8.772459140625,20.9999515625,8.772459140625C27.7534515625,8.772459140625,33.2270515625,14.247559140625,33.2270515625,21.000519140625002C33.2270515625,27.752719140625,27.7534515625,33.227519140625,20.9999515625,33.227519140625C20.9999515625,33.227519140625,20.9999515625,33.227519140625,20.9999515625,33.227519140625Z" fill="#FFFFFF" fill-opacity="1"/></g><g><path d="M30.34522328643799,26.69066796875C29.474123286437987,25.00366796875,28.161123286437988,23.58156796875,26.547323286437987,22.57766796875C25.99312328643799,22.23266796875,25.408223286437988,21.94166796875,24.800323286437987,21.70556796875C26.22312328643799,20.58666796875,27.137223286437987,18.84862796875,27.137223286437987,16.89745796875C27.137223286437987,13.52148796875,24.400423286437988,10.78466796875,21.02441328643799,10.78466796875C17.64746328643799,10.78466796875,14.910153286437989,13.52148796875,14.910153286437989,16.89745796875C14.910153286437989,18.84350796875,15.819333286437988,20.57665796875,17.235353286437988,21.695567968749998C16.623043286437987,21.93166796875,16.034183286437987,22.22366796875,15.476073286437988,22.56956796875C13.865233286437988,23.56766796875,12.552246286437988,24.983667968749998,11.679199286437989,26.66356796875C11.421386286437988,27.16066796875,11.614257686437988,27.77466796875,12.112304286437988,28.03246796875C12.609373286437988,28.29146796875,13.223143286437988,28.09766796875,13.481443286437989,27.60056796875C14.947263286437988,24.78046796875,17.830073286437987,23.02856796875,21.005373286437987,23.02856796875C24.19042328643799,23.02856796875,27.078123286437986,24.78856796875,28.54002328643799,27.62256796875C28.72022328643799,27.97166796875,29.07522328643799,28.17256796875,29.443323286437987,28.17256796875C29.60542328643799,28.17256796875,29.76412328643799,28.13356796875,29.908223286437988,28.05856796875C30.40622328643799,27.80146796875,30.602023286437987,27.18946796875,30.34522328643799,26.69066796875C30.34522328643799,26.69066796875,30.34522328643799,26.69066796875,30.34522328643799,26.69066796875ZM21.02441328643799,12.83862796875C23.26612328643799,12.83862796875,25.08302328643799,14.65551796875,25.08302328643799,16.89745796875C25.08302328643799,19.14062796875,23.26612328643799,20.95756796875,21.02441328643799,20.95756796875C18.78222328643799,20.95756796875,16.964353286437987,19.14062796875,16.964353286437987,16.89745796875C16.964353286437987,14.65551796875,18.78222328643799,12.83862796875,21.02441328643799,12.83862796875C21.02441328643799,12.83862796875,21.02441328643799,12.83862796875,21.02441328643799,12.83862796875Z" fill="#FFFFFF" fill-opacity="1"/></g></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="42" height="42" viewBox="0 0 42 42"><g><g></g><g><path d="M12.667875625,22.060642968750003L27.211315624999997,36.603642968749995L29.332615625000003,34.48224296875L15.849855625,20.99994296875L29.332615625000003,7.51720296875L27.211315624999997,5.39588296875L12.667835625,19.939342968749997Q12.615735625,19.99144296875,12.568985625,20.048442968750003Q12.522235625,20.105442968749998,12.481295625,20.16664296875Q12.440355625,20.22794296875,12.405625625,20.292942968749998Q12.370885625,20.357942968750002,12.342685625,20.42604296875Q12.314485625,20.49404296875,12.293095625,20.56464296875Q12.271705625,20.63514296875,12.257335625,20.707342968749998Q12.242955625,20.77964296875,12.235735625,20.85304296875Q12.228515625,20.92634296875,12.228515625,21.00004296875Q12.228515625,21.07374296875,12.235745625,21.14704296875Q12.242965625,21.22034296875,12.257345625,21.292642968750002Q12.271715625,21.36494296875,12.293115625,21.43544296875Q12.314505625,21.50594296875,12.342705625,21.57404296875Q12.370905625,21.64214296875,12.405645625,21.70714296875Q12.440385625,21.77214296875,12.481325625,21.83334296875Q12.522265625,21.89464296875,12.569015625,21.95164296875Q12.615765625,22.00854296875,12.667875625,22.060642968750003Z" fill-rule="evenodd" fill="#FFFFFF" fill-opacity="1"/></g></g></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

@@ -1,5 +1,3 @@
class FitTool { class FitTool {
static double rpx = 0; static double rpx = 0;
static bool isInit = false; static bool isInit = false;
@@ -9,7 +7,8 @@ class FitTool {
} }
if (isInit == false) { if (isInit == false) {
isInit = true; isInit = true;
rpx = v / 750.0; // rpx = v / 750.0;
rpx=v/1624.0;
} }
} }

View File

@@ -2,10 +2,12 @@ import 'dart:async';
import 'package:ef/ef.dart'; import 'package:ef/ef.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import 'package:vbvs_app/common/color/app_uri_status.dart'; import 'package:vbvs_app/common/color/app_uri_status.dart';
import 'package:vbvs_app/common/util/FitTool.dart'; import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/controller/setting/language/language_controller.dart'; import 'package:vbvs_app/controller/setting/language/language_controller.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart'; import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
import 'package:vbvs_app/language/AppLanguage.dart'; import 'package:vbvs_app/language/AppLanguage.dart';
@@ -361,6 +363,37 @@ var returnIconButtom = IconButton(
icon: Icon(Icons.navigate_before, size: 60.rpx), icon: Icon(Icons.navigate_before, size: 60.rpx),
); );
var returnIconButtomNew = ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.transparent,
padding: EdgeInsets.only(right: 0),
onTap: () => Get.back(),
child: Container(
// height: 42.rpx,
// width: 42.rpx,
child: SvgPicture.asset(
'assets/img/icon/return_buttom.svg',
width: 42.rpx,
height: 42.rpx,
),
// SvgPicture.asset(
// 'assets/img/icon/expand.svg',
// color: Colors.white,
// )
));
// IconButton(
// padding: EdgeInsets.zero, // 去除默认 padding
// constraints: BoxConstraints(), // 去除最小尺寸限制
// onPressed: () => Get.back(),
// icon: SvgPicture.asset(
// 'assets/img/icon/return_buttom.svg',
// width: 42.rpx,
// height: 42.rpx,
// ),
// );
var returnIconButtomAddCallback = (returnCallBack) {
var returnIconButtomAddCallback = ( var returnIconButtomAddCallback = (
VoidCallback? returnCallBack, { VoidCallback? returnCallBack, {
bool enableBack = true, bool enableBack = true,

View File

@@ -0,0 +1,77 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import '../../controller/mh/apply_repair_controller.dart';
class ImgPreviewDefaultWidget extends GetView {
ApplyRepairController applyRepairController;
ImgPreviewDefaultWidget({required this.applyRepairController}) {}
@override
Widget build(BuildContext context) {
return InkWell(
// onTap: applyRepairController.uploadImg,
onTap: ()async{},
child: Container(
width: MediaQuery.sizeOf(context).width * 0.25,
height: MediaQuery.sizeOf(context).height * 0.15,
constraints: BoxConstraints(
minHeight: 152,
),
decoration: BoxDecoration(
color: Colors.white,
),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 0.116,
constraints: BoxConstraints(
minHeight: 152,
),
decoration: BoxDecoration(
color: Color(0xFFF3F5F6),
borderRadius: BorderRadius.circular(16),
),
child: Align(
alignment: AlignmentDirectional(0, 0),
child: Container(
width: 35,
height: 35,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.cover,
image: Image.asset(
'assets/images/camera.png',
).image,
),
),
),
),
),
),
Align(
alignment: AlignmentDirectional(0, 0),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(0, 8, 0, 13),
child: Text(
' ',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Readex Pro',
color: Color(0xFF9EA4B7),
fontSize: 11,
letterSpacing: 0,
),
),
),
),
],
),
),
);
}
}

View File

@@ -0,0 +1,23 @@
import 'package:ef/ef.dart';
import 'package:json_annotation/json_annotation.dart';
part 'img_preview_controller.g.dart';
@JsonSerializable()
class ImgPreviewModel {
//版本id
String? url; //图片地址
ImgPreviewModel();
static ImgPreviewModel fromJson(Map<String, dynamic> json) =>
_$ImgPreviewModelFromJson(json);
Map<String, dynamic> toJson() => _$ImgPreviewModelToJson(this);
}
class ImgPreviewController extends GetControllerEx<ImgPreviewModel> {
ImgPreviewController() {
attr = GetModel(ImgPreviewModel()).obs;
}
}

View File

@@ -0,0 +1,15 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'img_preview_controller.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
ImgPreviewModel _$ImgPreviewModelFromJson(Map<String, dynamic> json) =>
ImgPreviewModel()..url = json['url'] as String?;
Map<String, dynamic> _$ImgPreviewModelToJson(ImgPreviewModel instance) =>
<String, dynamic>{
'url': instance.url,
};

View File

@@ -0,0 +1,80 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import '../../common/color/appFontsize.dart';
import '../../controller/mh/apply_repair_controller.dart';
class ImgPreviewWidget extends GetView {
String imgUrl;
int index;
ApplyRepairController applyRepairController;
bool isDel;
ImgPreviewWidget(
{required this.imgUrl,
required this.index,
required this.applyRepairController,
required this.isDel}) {}
@override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.sizeOf(context).width * 0.25,
height: MediaQuery.sizeOf(context).height * 0.15,
constraints: BoxConstraints(
minHeight: 140,
),
decoration: BoxDecoration(
color: Colors.white,
),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Expanded(
child: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 0.116,
decoration: BoxDecoration(
color: Color(0xFFF3F5F6),
borderRadius: BorderRadius.circular(8),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Image.network(
'https://picsum.photos/seed/73/600',
// applyRepairController.getPublicUrl(imgUrl),
width: 300,
height: 200,
fit: BoxFit.cover,
),
),
),
),
Visibility(
visible: isDel,
child: Align(
alignment: AlignmentDirectional(0, 0),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(0, 8, 0, 13),
child: InkWell(
onTap: () {
applyRepairController.model.issue_img!.removeAt(index);
applyRepairController.updateAll();
},
child: Text(
'删除',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Readex Pro',
color: Color(0xFF9EA4B7),
fontSize: AppFontsize.small_text_size,
letterSpacing: 0,
),
),
)),
)),
],
),
);
}
}

View File

@@ -1,6 +1,102 @@
// import 'package:flutter/material.dart';
// import 'package:vbvs_app/common/util/FitTool.dart';
// class CustomCard extends StatefulWidget {
// final double borderRadius; // 圆角
// final VoidCallback onTap; // 点击回调
// final List<Color> colors; // 背景颜色列表
// final Widget child; // 子组件
// final bool enableAnimation; // 是否启用动画效果
// final bool enableGradient; // 是否启用渐变
// const CustomCard({
// Key? key,
// required this.borderRadius,
// required this.onTap,
// required this.colors,
// required this.child,
// this.enableAnimation = true, // 默认启用动画效果
// this.enableGradient = true, // 默认启用渐变效果
// }) : super(key: key);
// @override
// State<CustomCard> createState() => _CustomCardState();
// }
// class _CustomCardState extends State<CustomCard>
// with SingleTickerProviderStateMixin {
// double _scale = 1.0;
// final Duration _animationDuration = const Duration(milliseconds: 50);
// Future<void> _handleTap() async {
// if (widget.enableAnimation) {
// setState(() {
// _scale = 0.95;
// });
// await Future.delayed(_animationDuration);
// setState(() {
// _scale = 1.0;
// });
// }
// widget.onTap();
// }
// @override
// Widget build(BuildContext context) {
// final bool isGradient = widget.enableGradient && widget.colors.length > 1;
// final Color baseColor = widget.colors.first;
// return Material(
// color: Colors.transparent,
// borderRadius: BorderRadius.circular(widget.borderRadius),
// child: InkWell(
// onTap: _handleTap,
// borderRadius: BorderRadius.circular(widget.borderRadius),
// splashColor: widget.colors.first.withOpacity(0.2),
// child: widget.enableAnimation
// ? AnimatedScale(
// scale: _scale,
// duration: _animationDuration,
// curve: Curves.easeInOut,
// child: _buildContent(isGradient, baseColor),
// )
// : _buildContent(isGradient, baseColor),
// ),
// );
// }
// Widget _buildContent(bool isGradient, Color baseColor) {
// return Container(
// decoration: BoxDecoration(
// color: isGradient ? null : baseColor,
// gradient: isGradient
// ? LinearGradient(
// colors: widget.colors,
// begin: Alignment.topLeft,
// end: Alignment.bottomRight,
// )
// : null,
// borderRadius: BorderRadius.circular(widget.borderRadius),
// ),
// child: Padding(
// padding: EdgeInsets.fromLTRB(0.rpx, 0.rpx, 0.rpx, 5.rpx),
// child: widget.child,
// ),
// );
// }
// }
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:vbvs_app/common/util/FitTool.dart'; import 'package:vbvs_app/common/util/FitTool.dart';
/// 枚举控制渐变方向
enum GradientDirection {
horizontal,
vertical,
}
class CustomCard extends StatefulWidget { class CustomCard extends StatefulWidget {
final double borderRadius; // 圆角 final double borderRadius; // 圆角
final VoidCallback onTap; // 点击回调 final VoidCallback onTap; // 点击回调
@@ -8,6 +104,8 @@ class CustomCard extends StatefulWidget {
final Widget child; // 子组件 final Widget child; // 子组件
final bool enableAnimation; // 是否启用动画效果 final bool enableAnimation; // 是否启用动画效果
final bool enableGradient; // 是否启用渐变 final bool enableGradient; // 是否启用渐变
final GradientDirection gradientDirection; // 渐变方向
final EdgeInsetsGeometry? margin; // 外部间距
const CustomCard({ const CustomCard({
Key? key, Key? key,
@@ -15,8 +113,10 @@ class CustomCard extends StatefulWidget {
required this.onTap, required this.onTap,
required this.colors, required this.colors,
required this.child, required this.child,
this.enableAnimation = true, // 默认启用动画效果 this.enableAnimation = true,
this.enableGradient = true, // 默认启用渐变效果 this.enableGradient = true,
this.gradientDirection = GradientDirection.horizontal,
this.margin,
}) : super(key: key); }) : super(key: key);
@override @override
@@ -49,21 +149,24 @@ class _CustomCardState extends State<CustomCard>
final bool isGradient = widget.enableGradient && widget.colors.length > 1; final bool isGradient = widget.enableGradient && widget.colors.length > 1;
final Color baseColor = widget.colors.first; final Color baseColor = widget.colors.first;
return Material( return Container(
color: Colors.transparent, margin: widget.margin, // 应用外部间距
borderRadius: BorderRadius.circular(widget.borderRadius), child: Material(
child: InkWell( color: Colors.transparent,
onTap: _handleTap,
borderRadius: BorderRadius.circular(widget.borderRadius), borderRadius: BorderRadius.circular(widget.borderRadius),
splashColor: widget.colors.first.withOpacity(0.2), child: InkWell(
child: widget.enableAnimation onTap: _handleTap,
? AnimatedScale( borderRadius: BorderRadius.circular(widget.borderRadius),
scale: _scale, splashColor: widget.colors.first.withOpacity(0.2),
duration: _animationDuration, child: widget.enableAnimation
curve: Curves.easeInOut, ? AnimatedScale(
child: _buildContent(isGradient, baseColor), scale: _scale,
) duration: _animationDuration,
: _buildContent(isGradient, baseColor), curve: Curves.easeInOut,
child: _buildContent(isGradient, baseColor),
)
: _buildContent(isGradient, baseColor),
),
), ),
); );
} }
@@ -75,14 +178,18 @@ class _CustomCardState extends State<CustomCard>
gradient: isGradient gradient: isGradient
? LinearGradient( ? LinearGradient(
colors: widget.colors, colors: widget.colors,
begin: Alignment.topLeft, begin: widget.gradientDirection == GradientDirection.vertical
end: Alignment.bottomRight, ? Alignment.topCenter
: Alignment.centerLeft,
end: widget.gradientDirection == GradientDirection.vertical
? Alignment.bottomCenter
: Alignment.centerRight,
) )
: null, : null,
borderRadius: BorderRadius.circular(widget.borderRadius), borderRadius: BorderRadius.circular(widget.borderRadius),
), ),
child: Padding( child: Padding(
padding: EdgeInsets.fromLTRB(0.rpx, 0.rpx, 0.rpx, 5.rpx), padding: EdgeInsets.fromLTRB(0.rpx, 0.rpx, 0.rpx, 0.rpx),
child: widget.child, child: widget.child,
), ),
); );

View File

@@ -0,0 +1,31 @@
import 'package:ef/ef.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:vbvs_app/controller/main_bottom/main_page_controller.dart';
part 'main_page_b_controller.g.dart';
@JsonSerializable()
class MainPageBModel {
int currentIndex = 0;
MainPageBModel();
factory MainPageBModel.fromJson(Map<String, dynamic> json) {
try {
return _$MainPageBModelFromJson(json);
} catch (e) {
// 在实际应用中,应该有更细致的异常处理策略和错误日志
return MainPageBModel(); // 或者返回一个带有错误信息的特定DeviceInfoModel实例
}
}
// 序列化为JSON时的异常处理
Map<String, dynamic> toJson() => _$MainPageBModelToJson(this);
}
class MainPageBController extends GetControllerEx<MainPageBModel> {
MainPageBController() {
attr = GetModel(MainPageBModel()).obs;
}
resetParm() {
model.currentIndex = 0;
}
}

View File

@@ -0,0 +1,15 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'main_page_b_controller.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
MainPageBModel _$MainPageBModelFromJson(Map<String, dynamic> json) =>
MainPageBModel()..currentIndex = (json['currentIndex'] as num).toInt();
Map<String, dynamic> _$MainPageBModelToJson(MainPageBModel instance) =>
<String, dynamic>{
'currentIndex': instance.currentIndex,
};

View File

@@ -0,0 +1,155 @@
import 'package:ef/ef.dart';
import 'package:flutter_city_picker/model/address.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:vbvs_app/controller/mh/user_data.dart';
import 'package:vbvs_app/controller/mh/muser_info_controller.dart';
part 'address_controller.g.dart';
@JsonSerializable()
class AddressModel {
//版本id
String? province; //省份
String? city; //市
String? county; //区
String? street; //街道
String? detail; //详细信息
String? name; //名字
String? phone; //手机号
bool? ischecked = false; //是否默认
int currentType = 0;
String? all_address;
@JsonKey(ignore: true)
List<AddressNode>? addressList = [];
AddressModel();
static AddressModel fromJson(Map<String, dynamic> json) =>
_$AddressModelFromJson(json);
Map<String, dynamic> toJson() => _$AddressModelToJson(this);
}
class AddressController extends GetControllerEx<AddressModel> {
AddressController() {
attr = GetModel(AddressModel()).obs;
}
Future<String> updateAddress(
Map<String, dynamic> address, AddressModel model) async {
if (model.addressList != null && model.addressList!.isNotEmpty) {
if (model.addressList!.length > 0) {
address["province"] = model.addressList![0].name; // 第一个元素为省
}
if (model.addressList!.length > 1) {
address["city"] = model.addressList![1].name; // 第二个元素为市
}
if (model.addressList!.length > 2) {
address["county"] = model.addressList![2].name; // 第三个元素为区
}
if (model.addressList!.length > 3) {
address["street"] = model.addressList![3].name; // 第四个元素为街道
}
}
address['detail'] = model.detail;
address['name'] = model.name;
address['phone'] = model.phone;
address['isChecked'] = model.ischecked;
try {
final data = await ef.client.rpc("get_now_datetime");
final response = await ef.client.from("app_user_address").update({
'province': address["province"],
'city': address["city"],
'county': address["county"],
'street': address["street"],
'detail': address["detail"],
'name': address["name"],
'phone': address["phone"],
'ischecked': address['isChecked'] ? 1 : 0,
'update_time':
DateFormat("yyyy-MM-dd HH:mm:ss").parse("$data").toString(),
}).eq("id", address['id']);
} catch (e) {
print('Error fetching repairs: $e');
return e.toString();
}
return '';
}
addAddress(AddressModel model) async {
try {
final MUserInfoController userInfoController =
Get.find<MUserInfoController>();
UserModel user = userInfoController.model.user!;
// 设置省市区街道名称
if (model.addressList != null && model.addressList!.isNotEmpty) {
if (model.addressList!.length > 0)
model.province = model.addressList![0].name; // 第一个元素为省
if (model.addressList!.length > 1)
model.city = model.addressList![1].name; // 第二个元素为市
if (model.addressList!.length > 2)
model.county = model.addressList![2].name; // 第三个元素为区
if (model.addressList!.length > 3)
model.street = model.addressList![3].name; // 第四个元素为街道
}
// 查询数据库是否已有该用户的地址
final existingAddresses = await ef.client
.from('app_user_address')
.select()
.eq('user_id', user.uid!);
// 如果没有地址,将新增地址默认选中
if (existingAddresses.isEmpty) {
model.ischecked = true;
} else if (model.ischecked == true) {
// 如果新地址被选中,将其他地址的 `ischecked` 字段设为 `0`
await ef.client
.from('app_user_address')
.update({'ischecked': 0}).eq('user_id', user.uid!);
}
// 添加新地址
final response = await ef.client.from('app_user_address').insert({
'province': model.province,
'city': model.city,
'county': model.county,
'street': model.street,
'detail': model.detail,
'name': model.name,
'phone': model.phone,
'ischecked': model.ischecked! ? 1 : 0,
'user_id': user.uid,
});
} catch (e) {
print(e);
}
}
Future<List<AddressNode>> getData({int? level, int? pid}) async {
// 构建查询
var query = ef.from("app_area_city").select();
// 如果 pid 不为 null添加 pid 的条件
if (pid != null) {
query = query.eq("pid", pid);
}
if (level != null) {
query = query.eq("deep", level);
}
List arr = await query;
List<AddressNode> addressNodes = arr.map((item) {
return AddressNode.fromJson({
"name": item["ext_name"], // ext_name 对应 name
"code": item["id"], // id 对应 code
"letter": item["pinyin_prefix_upper"], // pinyin_prefix_upper 对应 letter
});
}).toList();
return addressNodes;
}
}

View File

@@ -0,0 +1,33 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'address_controller.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
AddressModel _$AddressModelFromJson(Map<String, dynamic> json) => AddressModel()
..province = json['province'] as String?
..city = json['city'] as String?
..county = json['county'] as String?
..street = json['street'] as String?
..detail = json['detail'] as String?
..name = json['name'] as String?
..phone = json['phone'] as String?
..ischecked = json['ischecked'] as bool?
..currentType = (json['currentType'] as num).toInt()
..all_address = json['all_address'] as String?;
Map<String, dynamic> _$AddressModelToJson(AddressModel instance) =>
<String, dynamic>{
'province': instance.province,
'city': instance.city,
'county': instance.county,
'street': instance.street,
'detail': instance.detail,
'name': instance.name,
'phone': instance.phone,
'ischecked': instance.ischecked,
'currentType': instance.currentType,
'all_address': instance.all_address,
};

View File

@@ -0,0 +1,64 @@
import 'package:ef/ef.dart';
import 'package:json_annotation/json_annotation.dart';
part 'address_list_controller.g.dart';
@JsonSerializable()
class AddressListModel {
List addressList = [];
Map address = {}; //之前控制的设备
int? type = 1; //1添加2编辑
AddressListModel();
static AddressListModel fromJson(Map<String, dynamic> json) =>
_$AddressListModelFromJson(json);
Map<String, dynamic> toJson() => _$AddressListModelToJson(this);
}
class AddressListController extends GetControllerEx<AddressListModel> {
AddressListController() {
attr = GetModel(AddressListModel()).obs;
}
// getAddressList() async {
// await ApiService.request.get("/api/address/info/list").then((d) {
// model.addressList = d.data["data"] ?? [];
// updateAll();
// }).catchError((e) {
// print("$e");
// });
// }
// //更新默认
// Future<void> updateDefault(address) async {
// var id = address['id'];
// var uid = address['userId'];
// try {
// await ef.client
// .from("app_user_address")
// .update({
// 'ischecked': 0,
// })
// .eq("user_id", address['userId'])
// .eq("ischecked", 1);
// await ef.client.from("app_user_address").update({
// 'ischecked': 1,
// }).eq("id", address['id']);
// } catch (e) {
// print('Error fetching repairs: $e');
// }
// }
// // 删除地址
// Future<void> deleteAddress(String id) async {
// try {
// await ef.client.from("app_user_address").delete().eq("id", id);
// print("Address with ID $id has been successfully deleted.");
// } catch (e) {
// print("Error deleting address with ID $id: $e");
// }
// }
}

View File

@@ -0,0 +1,20 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'address_list_controller.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
AddressListModel _$AddressListModelFromJson(Map<String, dynamic> json) =>
AddressListModel()
..addressList = json['addressList'] as List<dynamic>
..address = json['address'] as Map<String, dynamic>
..type = (json['type'] as num?)?.toInt();
Map<String, dynamic> _$AddressListModelToJson(AddressListModel instance) =>
<String, dynamic>{
'addressList': instance.addressList,
'address': instance.address,
'type': instance.type,
};

View File

@@ -0,0 +1,198 @@
import 'dart:io';
import 'package:ef/ef.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:img_picker/img_picker.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:path/path.dart' as p;
import 'package:uuid/uuid.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'muser_info_controller.dart';
part 'apply_repair_controller.g.dart';
@JsonSerializable()
class ApplyRepairModel {
int? id; //报修id
String? apply_name; //申请人名称
String? tel; //手机号
String? address; //地址
String? desc; //问题描述
DateTime? create_time; //创建时间
String? device_type; //类型 床,床垫 不能为空
String? device_category; //型号 不能为空
String? device_id; //序列号 设备id 不能为空
String? device_name; //名称 可为空
List<String>? issue_img = []; //图片
int? imagesLImit = 3; //图片限制上传数量
String? img_bucket = 'mianhuatang_repair';
String? status; //维修状态
String? select_device;
// String? select_type;
// List<String>? device_list = ['床垫/BY-H/智能床垫', '床垫/BY-A/智能床垫', '床垫/BY-C/智能床垫'];
List<dynamic>? device_list = [];
int? score;
DateTime? score_time; //创建时间
int? messageType = 1; //消息类型
int? repairId; //消息类型
ApplyRepairModel();
static ApplyRepairModel fromJson(Map<String, dynamic> json) =>
_$ApplyRepairModelFromJson(json);
Map<String, dynamic> toJson() => _$ApplyRepairModelToJson(this);
}
class ApplyRepairController extends GetControllerEx<ApplyRepairModel> {
// RepairRepository repairRepository = RepairRepository();
ApplyRepairController() {
attr = GetModel(ApplyRepairModel()).obs;
}
// //上传图片
// Future<void> uploadImg() async {
// final ImagePicker picker = ImagePicker();
// final XFile? image = await picker.pickImage(source: ImageSource.gallery);
// final user = Supabase.instance.client.auth.currentUser;
// try {
// if (image != null) {
// int fileSize = await image.length(); // 获取图片大小,单位为字节
// if (fileSize > 1024 * 1024 * 5) {
// // 1 MB = 1024 * 1024 bytes
// showToast("上传图片不能超过5MB");
// return;
// }
// final filePath = image.path; // 获取文件路径
// final fileExtension = p.extension(filePath); // 获取文件扩展名,包括点(.
// // 获取当前日期并格式化为 yyyy-MM-dd
// final String folderName =
// DateFormat('yyyy-MM-dd').format(DateTime.now());
// final file = File(image.path);
// // 构造文件路径,文件会被上传到 record_img 文件夹下的当天日期文件夹
// var response = await ef.client.storage
// .from(model.img_bucket!)
// .upload('$folderName/${Uuid().v4()}$fileExtension', file);
// if (response != null) {
// String publicUrl =
// ef.client.storage.from(model.img_bucket!).getPublicUrl(response);
// print('文件上传成功: $response');
// print('文件上传成功: $publicUrl');
// String prefixToRemove = 'mianhuatang_repair/';
// model.issue_img!.add(response.startsWith(prefixToRemove)
// ? response.substring(prefixToRemove.length)
// : response);
// updateAll();
// }
// print('/$model.img_bucket');
// } else {
// print('未选择图片');
// return;
// }
// } catch (e) {
// print('上传失败: $e');
// }
// }
// //提交
// Future<String> submitRepair(BuildContext context) async {
// //tmp
// // return '';
// String message = '';
// final MyDialogController myDialogController =
// Get.find<MyDialogController>();
// if (model.device_type == null || model.device_type!.isEmpty) {
// message = '请选择设备类型!';
// showToast(message);
// return message;
// }
// if (model.device_category == null || model.device_category!.isEmpty) {
// message = '请输入设备型号!';
// showToast(message);
// return message;
// }
// if (model.device_id == null || model.device_id!.isEmpty) {
// message = '请输入设备序列号id';
// showToast(message);
// return message;
// }
// if (model.apply_name == null || model.apply_name!.isEmpty) {
// message = '请输入姓名!';
// showToast(message);
// return message;
// }
// RegExp nameRegExp = RegExp(r'^[\u4e00-\u9fa5]{2,4}$');
// if (!nameRegExp.hasMatch(model.apply_name!)) {
// message = '姓名必须为2到4个汉字';
// showToast(message);
// return message;
// }
// if (model.tel == null || model.tel!.isEmpty) {
// message = '请输入手机号!';
// showToast(message);
// return message;
// }
// if (!MyUtils.isValidPhoneNumber(model.tel!)) {
// message = '无效的手机号!';
// showToast(message);
// return message;
// }
// if (model.address == null || model.address!.isEmpty) {
// message = '请输入地址!';
// showToast(message);
// return message;
// }
// if (model.desc == null || model.desc!.isEmpty) {
// message = '请输入问题描述!';
// showToast(message);
// return message;
// }
// if (model.issue_img == null || model.issue_img!.isEmpty) {
// message = '请至少上传一张问题图片!';
// showToast(message);
// return message;
// }
// model.status = RepairStatus.pending;
// await repairRepository.saveRepair(model);
// return message;
// }
// Future<void> getDeviceList() async {
// final UserInfoController userInfoController =
// Get.find<UserInfoController>();
// // UserModel loginUser = userInfoController.model.user!;
// DeviceListController deviceListController = Get.find();
// await deviceListController.getDeviceList();
// var aa = deviceListController.model.deviceListWyf;
// ApplyRepairController applyRepairController = Get.find();
// applyRepairController.model.device_list = aa;
// }
// String getPublicUrl(String path) {
// try {
// String bucketPath = '${model.img_bucket}/';
// if (path.contains(bucketPath)) {
// int firstIndex = path.indexOf(bucketPath);
// // int secondIndex =
// // response.indexOf(bucketPath, firstIndex + bucketPath.length);
// if (firstIndex != -1) {
// // 去掉第一个存储桶路径
// path = path.replaceFirst(bucketPath, '', firstIndex);
// }
// }
// String publicUrl =
// ef.client.storage.from(model.img_bucket!).getPublicUrl(path);
// return publicUrl;
// } catch (e) {}
// return '';
// }
}

View File

@@ -0,0 +1,60 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'apply_repair_controller.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
ApplyRepairModel _$ApplyRepairModelFromJson(Map<String, dynamic> json) =>
ApplyRepairModel()
..id = (json['id'] as num?)?.toInt()
..apply_name = json['apply_name'] as String?
..tel = json['tel'] as String?
..address = json['address'] as String?
..desc = json['desc'] as String?
..create_time = json['create_time'] == null
? null
: DateTime.parse(json['create_time'] as String)
..device_type = json['device_type'] as String?
..device_category = json['device_category'] as String?
..device_id = json['device_id'] as String?
..device_name = json['device_name'] as String?
..issue_img = (json['issue_img'] as List<dynamic>?)
?.map((e) => e as String)
.toList()
..imagesLImit = (json['imagesLImit'] as num?)?.toInt()
..img_bucket = json['img_bucket'] as String?
..status = json['status'] as String?
..select_device = json['select_device'] as String?
..device_list = json['device_list'] as List<dynamic>?
..score = (json['score'] as num?)?.toInt()
..score_time = json['score_time'] == null
? null
: DateTime.parse(json['score_time'] as String)
..messageType = (json['messageType'] as num?)?.toInt()
..repairId = (json['repairId'] as num?)?.toInt();
Map<String, dynamic> _$ApplyRepairModelToJson(ApplyRepairModel instance) =>
<String, dynamic>{
'id': instance.id,
'apply_name': instance.apply_name,
'tel': instance.tel,
'address': instance.address,
'desc': instance.desc,
'create_time': instance.create_time?.toIso8601String(),
'device_type': instance.device_type,
'device_category': instance.device_category,
'device_id': instance.device_id,
'device_name': instance.device_name,
'issue_img': instance.issue_img,
'imagesLImit': instance.imagesLImit,
'img_bucket': instance.img_bucket,
'status': instance.status,
'select_device': instance.select_device,
'device_list': instance.device_list,
'score': instance.score,
'score_time': instance.score_time?.toIso8601String(),
'messageType': instance.messageType,
'repairId': instance.repairId,
};

View File

@@ -0,0 +1,74 @@
import 'dart:convert';
import 'package:ef/ef.dart';
class BookInfoModel {
// DateTime? dateTime; //预约时间
String? userName; //预约人
String? userPhone; //预约电话
List time_period = []; //预约时段
// String? select_time; //选择时间
int? select_time_index; //选择时间
List datetimes = [];
int? datetimes_index;
Map dataT = {};
BookInfoModel();
}
class BookInfoController extends GetControllerEx<BookInfoModel> {
BookInfoController() {
attr = GetModel(BookInfoModel()).obs;
}
// get userInfoController => Get.find<UserInfoController>();
// getData(id) {
// model.datetimes = [];
// model.datetimes_index = null;
// model.dataT = {};
// updateAll();
// ApiService.reservation.get("/agent/userBook/config/detailConfigByStore?storeId=$id")
// .then((d) {
// model.datetimes = d.data["dateList"];
// model.datetimes_index = 0;
// model.dataT = d.data;
// time_periodChange();
// });
// }
// time_periodChange() {
// if(model.datetimes_index == null) {
// return;
// }
// model.select_time_index = null;
// model.time_period = model.dataT[model.datetimes?[model.datetimes_index!]["day"]];
// updateAll();
// }
// submitData(id) {
// String tel = userInfoController.model?.user?.tel ?? "";
// if(tel.isEmpty) {
// showToast("用户未存在手机号");
// return;
// }
// return ApiService.reservation.post("/agent/userBook/submitBook", data: {
// "extUserId": tel,
// "storeId": id,
// "realName": model.userName,
// "userPhone": model.userPhone,
// "bookDateId": model.time_period[model.select_time_index!]["id"]
// });
// }
// messageAdd(Map data) {
// return ApiService.request.post("/api/message/info", data: {
// "type": 0,
// "status": 1,
// "read": 1,
// "data": jsonEncode(data)
// });
// }
}

View File

@@ -0,0 +1,125 @@
import 'dart:ui';
import 'package:ef/ef.dart';
import 'package:json_annotation/json_annotation.dart';
part 'experience_store_list_page.g.dart';
@JsonSerializable()
class ExperienceStoreListModel {
List experienceStoreModelList = []; //体验店列
@JsonKey(ignore: true)
String? keyword = '';
@JsonKey(ignore: true)
Color? color = Color(0xFFFFFFFF);
ExperienceStoreListModel();
// static ExperienceStoreListModel fromJson(Map<String, dynamic> json) =>
// _$ExperienceStoreListModelFromJson(json);
// Map<String, dynamic> toJson() => _$ExperienceStoreListModelToJson(this);
}
class ExperienceStoreListController
extends GetControllerEx<ExperienceStoreListModel> {
ExperienceStoreListController() {
attr = GetModel(ExperienceStoreListModel()).obs;
}
// Position? position;
// double latitude = 31.8512;
// double longitude = 117.26061;
// int total = 0;
// int page = 0;
// bool lock = false;
// resetParm() {
// position = null;
// total = 0;
// page = 0;
// lock = false;
// model.experienceStoreModelList = [];
// updateAll();
// }
// getData({int count = 10}) async {
// if (page != 0 && page * count > total) {
// return;
// }
// if (lock) {
// return;
// }
// if (page == 0) {
// position = await locationCheck();
// }
// lock = true;
// int page_ = page;
// ApiService.reservation
// .get(
// "/agent/userBook/config/getBookStoreList?storeName=${"${model.keyword}".isNotEmpty ? model.keyword : ''}&latitude=${position == null ? latitude : position?.latitude}&longitude=${position == null ? longitude : position?.longitude}&page=$page&size=$count&sort=distance")
// .then((d) {
// lock = false;
// if (page == 0) {
// model.experienceStoreModelList = d.data["records"];
// } else {
// int index = 0;
// d.data["records"]?.forEach((item) {
// if (model.experienceStoreModelList
// .indexWhere((item2) => item2["id"] == item["id"]) ==
// -1) {
// model.experienceStoreModelList.add(item);
// } else {
// model.experienceStoreModelList[index] = item;
// }
// index++;
// });
// }
// page = page_ + 1;
// total = d.data["total"];
// updateAll();
// }).catchError((d) {
// lock = false;
// });
// }
determinePosition() async {
// bool serviceEnabled;
// LocationPermission permission;
// // Test if location services are enabled.
// serviceEnabled = await Geolocator.isLocationServiceEnabled();
// if (!serviceEnabled) {
// // Location services are not enabled don't continue
// // accessing the position and request users of the
// // App to enable the location services.
// return Future.error('Location services are disabled.');
// }
// permission = await Geolocator.checkPermission();
// if (permission == LocationPermission.denied) {
// permission = await Geolocator.requestPermission();
// if (permission == LocationPermission.denied) {
// // Permissions are denied, next time you could try
// // requesting permissions again (this is also where
// // Android's shouldShowRequestPermissionRationale
// // returned true. According to Android guidelines
// // your App should show an explanatory UI now.
// return Future.error('Location permissions are denied');
// }
// }
// if (permission == LocationPermission.deniedForever) {
// // Permissions are denied forever, handle appropriately.
// return Future.error(
// 'Location permissions are permanently denied, we cannot request permissions.');
// }
// // When we reach here, permissions are granted and we can
// // continue accessing the position of the device.
// position = await Geolocator.getCurrentPosition();
}
}

View File

@@ -0,0 +1,19 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'experience_store_list_page.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
ExperienceStoreListModel _$ExperienceStoreListModelFromJson(
Map<String, dynamic> json) =>
ExperienceStoreListModel()
..experienceStoreModelList =
json['experienceStoreModelList'] as List<dynamic>;
Map<String, dynamic> _$ExperienceStoreListModelToJson(
ExperienceStoreListModel instance) =>
<String, dynamic>{
'experienceStoreModelList': instance.experienceStoreModelList,
};

View File

@@ -0,0 +1,55 @@
import 'package:ef/ef.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
part 'issue_controller.g.dart';
@JsonSerializable()
class IssueListModel {
List issueList = [];
int limit = AppConstants.limit;
int offset = 0;
bool isLoading = false;
bool hasMore = true;
int? selectedIndex;
IssueListModel();
static IssueListModel fromJson(Map<String, dynamic> json) =>
_$IssueListModelFromJson(json);
Map<String, dynamic> toJson() => _$IssueListModelToJson(this);
}
class IssueListController extends GetControllerEx<IssueListModel> {
// HelpRepository helpRepository = HelpRepository();
IssueListController() {
attr = GetModel(IssueListModel()).obs;
}
// //初始化列表数据
// Future<void> initData() async {
// if (model.isLoading) {
// return;
// }
// model.isLoading = true;
// final List<dynamic> fetchedRepairs = await helpRepository.findHelpInfos(
// limit: model.limit, offset: model.offset);
// if (fetchedRepairs != null) {
// List<IssueModel> infos = [];
// List<dynamic> tmp = fetchedRepairs as List<dynamic>;
// try {
// // infos = tmp.map((repair) => IssueModel.fromJson(repair)).toList();
// // model.issueList!.addAll(infos);
// model.issueList.addAll(tmp);
// } catch (e) {
// print('Error parsing JSON: $e');
// }
// }
// model.offset += model.limit; // 更新 offset下一次查询跳过当前已经加载的记录
// model.hasMore = fetchedRepairs.length == model.limit; // 判断是否还有更多数据
// model.isLoading = false;
// updateAll();
// }
}

View File

@@ -0,0 +1,26 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'issue_controller.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
IssueListModel _$IssueListModelFromJson(Map<String, dynamic> json) =>
IssueListModel()
..issueList = json['issueList'] as List<dynamic>
..limit = (json['limit'] as num).toInt()
..offset = (json['offset'] as num).toInt()
..isLoading = json['isLoading'] as bool
..hasMore = json['hasMore'] as bool
..selectedIndex = (json['selectedIndex'] as num?)?.toInt();
Map<String, dynamic> _$IssueListModelToJson(IssueListModel instance) =>
<String, dynamic>{
'issueList': instance.issueList,
'limit': instance.limit,
'offset': instance.offset,
'isLoading': instance.isLoading,
'hasMore': instance.hasMore,
'selectedIndex': instance.selectedIndex,
};

View File

@@ -0,0 +1,20 @@
import 'package:ef/ef.dart';
import 'package:json_annotation/json_annotation.dart';
part 'issue_preview_controller.g.dart';
@JsonSerializable()
class IssuePreviewInfoModel {
IssuePreviewInfoModel();
static IssuePreviewInfoModel fromJson(Map<String, dynamic> json) =>
_$IssuePreviewInfoModelFromJson(json);
Map<String, dynamic> toJson() => _$IssuePreviewInfoModelToJson(this);
}
class IssuePreviewInfoController extends GetControllerEx<IssuePreviewInfoModel> {
IssuePreviewInfoController() {
attr = GetModel(IssuePreviewInfoModel()).obs;
}
}

View File

@@ -0,0 +1,15 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'issue_preview_controller.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
IssuePreviewInfoModel _$IssuePreviewInfoModelFromJson(
Map<String, dynamic> json) =>
IssuePreviewInfoModel();
Map<String, dynamic> _$IssuePreviewInfoModelToJson(
IssuePreviewInfoModel instance) =>
<String, dynamic>{};

View File

@@ -0,0 +1,198 @@
import 'dart:convert';
import 'package:EasyDartModule/EasyDartModule.dart';
import 'package:ef/ef.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:vbvs_app/common/color/ServiceConstant.dart';
import 'package:vbvs_app/common/color/app_uri_status.dart';
import 'package:vbvs_app/common/util/DailyLogUtils.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/model/api_response.dart';
part 'message_controller.g.dart'; // 由json_serializable自动生成的部分
@JsonSerializable()
class MhMessageModel {
int? type = 1; //设备类型 1:体征消息 2.系统消息
int? body_message_read = 0; //体征消息 0已读 1未读
int? system_message_read = 0; //系统消息 0已读 1未读
MhMessageModel();
// 从JSON反序列化时的异常处理
factory MhMessageModel.fromJson(Map<String, dynamic> json) {
try {
return _$MhMessageModelFromJson(json);
} catch (e) {
// 在实际应用中,应该有更细致的异常处理策略和错误日志
return MhMessageModel(); // 或者返回一个带有错误信息的特定DeviceInfoModel实例
}
}
// 序列化为JSON时的异常处理
Map<String, dynamic> toJson() => _$MhMessageModelToJson(this);
}
class MhMessageController extends GetControllerEx<MhMessageModel> {
MhMessageController() {
attr = GetModel(MhMessageModel()).obs;
}
RxList messageList = [].obs;
Future<ApiResponse> getMessageList({String? key}) async {
try {
ApiResponse apiResponse = ApiResponse(code: -1, msg: "请求失败".tr);
String serviceAddress = ServiceConstant.service_address;
String serviceName = ServiceConstant.server_service;
String serviceApi = ServiceConstant.message_list;
String messageType = "app_system";
if (model.type == 1) {
messageType = "app_body";
} else {
messageType = "app_system";
}
String queryUrl =
"${serviceAddress}${serviceName}${serviceApi}?type=${messageType}";
String? language = "";
if (languageController.selectLanguage != null) {
language = languageController.selectLanguage.value!.language_code;
}
if (language != null && language.isNotEmpty) {
if (queryUrl.contains("?")) {
queryUrl += "&lang=$language";
} else {
queryUrl += "?lang=$language";
}
}
var response = await EasyDartModule.dio.get(queryUrl);
if (response != null) {
var responseData =
response.data is String ? jsonDecode(response.data) : response.data;
ApiResponse res =
ApiResponse.fromJson(responseData, (object) => object);
MyUtils.formatResponse(res, "请求成功".tr, "请求失败".tr);
if (res.code == HttpStatusCodes.ok) {
updateAll();
messageList.value = res.data;
return res;
}
} else {
return ApiResponse(code: -1, msg: "服务器.失败".tr);
}
return apiResponse;
} catch (e) {
EasyDartModule.logger.info("设备请求列表: $e");
DailyLogUtils.writeLog("设备请求列表: $e");
}
return ApiResponse(code: -1, msg: "未知错误".tr); // Default return statement
}
//获取消息已读未读
Future<ApiResponse> getMessageStatus() async {
try {
ApiResponse apiResponse = ApiResponse(code: -1, msg: "请求失败".tr);
// return apiResponse;
String serviceAddress = ServiceConstant.service_address;
String serviceName = ServiceConstant.server_service;
String serviceApi = ServiceConstant.message_read;
String queryUrl = "${serviceAddress}${serviceName}${serviceApi}";
String? language = "";
if (languageController.selectLanguage != null) {
language = languageController.selectLanguage.value!.language_code;
}
if (language != null && language.isNotEmpty) {
if (queryUrl.contains("?")) {
queryUrl += "&lang=$language";
} else {
queryUrl += "?lang=$language";
}
}
var response = await EasyDartModule.dio.get(queryUrl);
if (response != null) {
var responseData =
response.data is String ? jsonDecode(response.data) : response.data;
ApiResponse res =
ApiResponse.fromJson(responseData, (object) => object);
MyUtils.formatResponse(res, "请求成功".tr, "请求失败".tr);
if (res.code == HttpStatusCodes.ok) {
updateAll();
List dataList = res.data;
// 查找 type 为 app_vsm 的项
var vsmItem = dataList.firstWhere(
(e) => e['type'] == 'app_vsm',
orElse: () => null,
);
model.body_message_read = vsmItem?['count'] ?? 0;
// 查找 type 为 app_system 的项
var systemItem = dataList.firstWhere(
(e) => e['type'] == 'app_system',
orElse: () => null,
);
model.system_message_read = systemItem?['count'] ?? 0;
updateAll();
return res;
}
} else {
return ApiResponse(code: -1, msg: "服务器.失败".tr);
}
return apiResponse;
} catch (e) {
EasyDartModule.logger.info("获取消息已读未读: $e");
DailyLogUtils.writeLog("获取消息已读未读: $e");
}
return ApiResponse(code: -1, msg: "未知错误".tr); // Default return statement
}
//更新消息已读
Future<ApiResponse> updateMessageStatus({String? type}) async {
EasyDartModule.logger.info("更新消息已读状态");
DailyLogUtils.writeLog("更新消息已读状态");
try {
ApiResponse apiResponse = ApiResponse(code: -1, msg: "操作失败".tr);
String serviceAddress = ServiceConstant.service_address;
String serviceName = ServiceConstant.server_service;
String serviceApi = ServiceConstant.message_read;
// 拼接 URL添加 type 参数
String queryUrl = "$serviceAddress$serviceName$serviceApi";
if (type != null && type.isNotEmpty) {
queryUrl += "?type=$type";
}
String? language = "";
if (languageController.selectLanguage != null) {
language = languageController.selectLanguage.value!.language_code;
}
if (language != null && language.isNotEmpty) {
if (queryUrl.contains("?")) {
queryUrl += "&lang=$language";
} else {
queryUrl += "?lang=$language";
}
}
var response = await EasyDartModule.dio.post(queryUrl);
if (response != null) {
var responseData =
response.data is String ? jsonDecode(response.data) : response.data;
ApiResponse res =
ApiResponse.fromJson(responseData, (object) => object);
MyUtils.formatResponse(res, "操作成功".tr, "操作成功".tr);
return res;
} else {
return ApiResponse(code: -1, msg: "服务器.失败".tr);
}
} catch (e) {
EasyDartModule.logger.info("更新消息已读状态->$e");
DailyLogUtils.writeLog("更新消息已读状态->$e");
return ApiResponse(code: -1, msg: "服务器.失败".tr);
}
}
}

View File

@@ -0,0 +1,20 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'message_controller.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
MhMessageModel _$MhMessageModelFromJson(Map<String, dynamic> json) =>
MhMessageModel()
..type = (json['type'] as num?)?.toInt()
..body_message_read = (json['body_message_read'] as num?)?.toInt()
..system_message_read = (json['system_message_read'] as num?)?.toInt();
Map<String, dynamic> _$MhMessageModelToJson(MhMessageModel instance) =>
<String, dynamic>{
'type': instance.type,
'body_message_read': instance.body_message_read,
'system_message_read': instance.system_message_read,
};

View File

@@ -0,0 +1,177 @@
import 'dart:io';
import 'package:ef/ef.dart';
import 'package:fluwx/fluwx.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:path/path.dart' as p;
import 'package:vbvs_app/controller/mh/user_data.dart';
part 'muser_info_controller.g.dart';
@JsonSerializable()
class MUserInfoModel {
int? message = 0; //消息数量
UserModel? user; //用户信息
String? token; //token值
String? runSystem; //运行系统
String? phoneVersion; //手机版本
String? deviceId; //手机唯一
String? deviceModel; //设备可见型号(如 "iPhone""iPad"
String? appVersion; //app版本信息
@JsonKey(ignore: true)
Session? superbase_session;
@JsonKey(ignore: true)
User? superbase_user;
String? img_bucket = 'user';
int? login = 0; //是否登录0未登录 1已登录
MUserInfoModel();
static MUserInfoModel fromJson(Map<String, dynamic> json) =>
_$MUserInfoModelFromJson(json);
Map<String, dynamic> toJson() => _$MUserInfoModelToJson(this);
}
class MUserInfoController extends GetControllerEx<MUserInfoModel> {
// 初始化实例
final Fluwx fluwx = Fluwx();
MUserInfoController() {
attr = GetModel(MUserInfoModel()).obs;
}
// Future<void> uploadImg() async {
// final ImagePicker picker = ImagePicker();
// final XFile? image = await picker.pickImage(source: ImageSource.gallery);
// final user = Supabase.instance.client.auth.currentUser;
// try {
// if (image != null) {
// int fileSize = await image.length(); // 获取图片大小,单位为字节
// if (fileSize > 1048576) {
// // 1 MB = 1024 * 1024 bytes
// showToast("头像图片不能超过1MB");
// return;
// }
// final filePath = image.path; // 获取文件路径
// final fileExtension = p.extension(filePath); // 获取文件扩展名,包括点(.
// // 获取当前日期并格式化为 yyyy-MM-dd
// final String folderName =
// DateFormat('yyyy-MM-dd').format(DateTime.now());
// final file = File(image.path);
// // 构造文件路径,文件会被上传到 record_img 文件夹下的当天日期文件夹
// var response = await ef.client.storage
// .from(model.img_bucket!)
// .upload('$folderName/${Uuid().v4()}$fileExtension', file);
// if (response != null) {
// String publicUrl =
// ef.client.storage.from(model.img_bucket!).getPublicUrl(response);
// print('文件上传成功: $response');
// print('文件上传成功: $publicUrl');
// String prefixToRemove = 'user/';
// // model.user!.tmpHead = model.user!.head;
// model.user!.tmpHead = publicUrl.startsWith(prefixToRemove)
// ? response.substring(prefixToRemove.length)
// : response;
// updateAll();
// }
// print('/$model.img_bucket');
// } else {
// print('未选择图片');
// return;
// }
// } catch (e) {
// print('上传失败: $e');
// }
// }
// updateData() {
// UserInfoController controller = Get.find();
// UserRepository userRepository = UserRepository();
// return userRepository.updateInfo(controller.model.user!);
// }
// autoLogin(String token) async {
// final UserInfoController userInfoController = Get.find();
// try {
// final Map<String, dynamic> requestBody = {
// 'token': token,
// };
// var response = await ApiService.request
// .post("/api/auth/account/info/autoLogin", data: requestBody);
// if (response.statusCode == 200) {
// if (response.data != null) {
// ApiResponse<UserModel> apiResponse = ApiResponse.fromJson(
// response.data,
// (json) => UserModel.fromJson(json as Map<String, dynamic>));
// if (apiResponse.code == HttpStatusCodes.ok) {
// userInfoController.model.user = apiResponse.data;
// userInfoController.model.token = response.headers['token']!.first;
// userInfoController.model.login = 1;
// final box = GetStorage();
// box.write(
// 'user', userInfoController.model.user!.toJson()); // 存储用户信息
// box.write('token', userInfoController.model.token); // 存储 token
// String efPd = await getValueBySysConfigKey(CommonVariables.efKey);
// if (efPd != null && efPd.isNotEmpty) {
// await initDataEf(key: efPd);
// } else {
// print("efPD为空无法初始化");
// // 清除本地缓存
// final box = GetStorage();
// box.remove('user');
// box.remove('token');
// userInfoController.model.token = null;
// userInfoController.model.user = null;
// // 设置成未登录
// userInfoController.model.login = 0;
// return;
// }
// final AuthResponse res = await ef.client.auth.signInWithPassword(
// phone: userInfoController.model.user!.tel,
// password: userInfoController.model.user!.exp1!,
// );
// userInfoController.model.superbase_session = res.session;
// userInfoController.model.superbase_user = res.user;
// userInfoController.updateAll();
// // 登录成功移出网络检查监听
// Checknetwork.subscription?.cancel();
// }
// }
// } else {
// // 处理非 200 响应
// print('Failed to sign in. Status code: ${response.statusCode}');
// print('Response data: ${response.data}');
// }
// } catch (e) {
// e.printError();
// // 清除本地缓存
// final box = GetStorage();
// box.remove('user');
// box.remove('token');
// userInfoController.model.token = null;
// userInfoController.model.user = null;
// // 设置成未登录
// userInfoController.model.login = 0;
// }
// }
// // 拉起微信企业客服
// Future<void> openWeChatCustomerService() async {
// bool isWeChatInstalled = await fluwx.isWeChatInstalled;
// if (!isWeChatInstalled) {
// showToast("请先安装微信APP再联系客服", color: color_error);
// return;
// }
// showToast('正在打开微信客服...', color: color_success);
// await fluwx.open(
// target: CustomerServiceChat(
// corpId: CommonVariables.wxCorpId, url: CommonVariables.wxKfUrl));
// }
}

View File

@@ -0,0 +1,36 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'muser_info_controller.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
MUserInfoModel _$MUserInfoModelFromJson(Map<String, dynamic> json) =>
MUserInfoModel()
..message = (json['message'] as num?)?.toInt()
..user = json['user'] == null
? null
: UserModel.fromJson(json['user'] as Map<String, dynamic>)
..token = json['token'] as String?
..runSystem = json['runSystem'] as String?
..phoneVersion = json['phoneVersion'] as String?
..deviceId = json['deviceId'] as String?
..deviceModel = json['deviceModel'] as String?
..appVersion = json['appVersion'] as String?
..img_bucket = json['img_bucket'] as String?
..login = (json['login'] as num?)?.toInt();
Map<String, dynamic> _$MUserInfoModelToJson(MUserInfoModel instance) =>
<String, dynamic>{
'message': instance.message,
'user': instance.user,
'token': instance.token,
'runSystem': instance.runSystem,
'phoneVersion': instance.phoneVersion,
'deviceId': instance.deviceId,
'deviceModel': instance.deviceModel,
'appVersion': instance.appVersion,
'img_bucket': instance.img_bucket,
'login': instance.login,
};

View File

@@ -0,0 +1,115 @@
import 'dart:convert';
import 'package:ef/ef.dart';
class BookExperienceListModel {
List bookInfoList = []; //预约列表
List experienceStoreModelList = [];
}
class BookExperienceListController
extends GetControllerEx<BookExperienceListModel> {
BookExperienceListController() {
attr = GetModel(BookExperienceListModel()).obs;
}
// resetParm() {
// model.bookInfoList = [];
// model.experienceStoreModelList = [];
// total = 0;
// page = 0;
// lock = false;
// updateAll();
// }
// getAllBook() {
// ApiService.reservation
// .get(
// "/agent/userBook/config/getBookStoreList?storeName=&latitude=31.8512&longitude=117.26061&page=0&size=20000&sort=distance")
// .then((d) {
// model.experienceStoreModelList = d.data["records"];
// updateAll();
// });
// }
// int total = 0;
// int page = 0;
// bool lock = false;
// getData({int count = 10, Function? finished}) {
// if (page != 0 && page * count > total) {
// finished?.call();
// return;
// }
// if (lock) {
// finished?.call();
// return;
// }
// lock = true;
// int page_ = page;
// String tel = Get.find<UserInfoController>().model.user?.tel ?? "";
// if (tel.isEmpty) {
// showToast("用户未存在手机号");
// finished?.call();
// return;
// }
// ApiService.reservation
// .get(
// "/agent/userBook/list?extUserId=$tel&page=$page_&size=$count&sort=create_time,desc")
// .then((d) {
// lock = false;
// finished?.call();
// if (page == 0) {
// model.bookInfoList = d.data["records"];
// } else {
// int index = 0;
// d.data["records"]?.forEach((item) {
// if (model.bookInfoList
// .indexWhere((item2) => item2["id"] == item["id"]) ==
// -1) {
// model.bookInfoList.add(item);
// } else {
// model.bookInfoList[index] = item;
// }
// index++;
// });
// }
// page = page_ + 1;
// total = d.data["total"];
// updateAll();
// }).catchError((d) {
// lock = false;
// finished?.call();
// });
// }
// cancelBook(id, {Function? success}) {
// String tel = Get.find<UserInfoController>().model.user?.tel ?? "";
// if (tel.isEmpty) {
// showToast("用户未存在手机号");
// return;
// }
// LoadingDialog.show("提交中...");
// ApiService.reservation
// .post("/agent/userBook/cancel?extUserId=$tel&id=$id")
// .then((d) {
// page = 0;
// getData(finished: () {
// LoadingDialog.hide();
// });
// success?.call();
// }).catchError((d) {
// LoadingDialog.hide();
// });
// }
// messageAdd(Map data) {
// return ApiService.request.post("/api/message/info", data: {
// "type": 0,
// "status": 1,
// "read": 1,
// "data": jsonEncode(data)
// });
// }
}

View File

@@ -0,0 +1,111 @@
import 'package:ef/ef.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
part 'people_info_controller.g.dart'; // 由json_serializable自动生成的部分
class PeopleInfoModel {
List<PeopleInfoPojo> peopleList = [PeopleInfoPojo(), PeopleInfoPojo()];
}
@JsonSerializable()
class PeopleInfoPojo {
String? name;
String sex = "";
String? height;
String? weight;
DateTime? birthday;
String? tel;
String? emergencyContact;
PeopleInfoPojo();
// // 从JSON反序列化时的异常处理
factory PeopleInfoPojo.fromJson(Map<String, dynamic> json) {
try {
return _$PeopleInfoPojoFromJson(json);
} catch (e) {
// 在实际应用中,应该有更细致的异常处理策略和错误日志
return PeopleInfoPojo(); // 或者返回一个带有错误信息的特定PeopleInfoModel实例
}
}
// 序列化为JSON时的异常处理
Map<String, dynamic> toJson() => _$PeopleInfoPojoToJson(this);
}
class PeopleInfoController extends GetControllerEx<PeopleInfoModel> {
PeopleInfoController() {
attr = GetModel(PeopleInfoModel()).obs;
}
GlobalController get glcontroller => Get.find<GlobalController>();
// getPeoples() async {
// var arr = [];
// String bindMacA =
// glcontroller.getUpperCaseMac(glcontroller.model.deviceMain["bindMacA"]);
// String bindMacB =
// glcontroller.getUpperCaseMac(glcontroller.model.deviceMain["bindMacB"]);
// arr.add(bindMacA);
// if (bindMacB.length > 6) {
// arr.add(bindMacB);
// } else {
// model.peopleList[1] = PeopleInfoPojo();
// }
// model.peopleList[0] = PeopleInfoPojo();
// print("getuser $arr");
// var data = await ef.from("app_personnel").select().inFilter("mac", arr);
// print("getuser $data");
// data?.forEach((d) {
// PeopleInfoPojo peopleInfoPojo = PeopleInfoPojo();
// peopleInfoPojo.name = d["name"];
// peopleInfoPojo.sex = d["gender"] == 1 ? "男" : "女";
// peopleInfoPojo.height = d["height"] == null ? null : "${d["height"]}";
// peopleInfoPojo.weight = d["weight"] == null ? null : "${d["weight"]}";
// if (d["birthday"] != null) {
// peopleInfoPojo.birthday = DateTime.parse(d["birthday"]).toLocal();
// }
// peopleInfoPojo.tel = d["tel"];
// peopleInfoPojo.emergencyContact = d["contact"];
// if (glcontroller.getUpperCaseMac(d['mac']) == bindMacA) {
// model.peopleList[0] = peopleInfoPojo;
// }
// if (glcontroller.getUpperCaseMac(d['mac']) == bindMacB) {
// model.peopleList[1] = peopleInfoPojo;
// }
// });
// updateAll();
// attr.value.updateAll();
// }
// savePeoples() async {
// String bindMacA =
// glcontroller.getUpperCaseMac(glcontroller.model.deviceMain["bindMacA"]);
// String bindMacB =
// glcontroller.getUpperCaseMac(glcontroller.model.deviceMain["bindMacB"]);
// List<Future> arr = [];
// for (var i = 0; i < 2; i++) {
// if (i == 1 && bindMacB.length < 6) {
// break;
// }
// arr.add(ef.from("app_personnel").update({
// "name": model.peopleList[i].name,
// "gender": model.peopleList[i].sex == "男" ? 1 : 0,
// "height": int.tryParse("${model.peopleList[i].height}"),
// "weight": int.tryParse("${model.peopleList[i].weight}"),
// "birthday": model.peopleList[i].birthday == null
// ? null
// : model.peopleList[i].birthday.toString(),
// "tel": model.peopleList[i].tel,
// "contact": model.peopleList[i].emergencyContact
// }).eq("mac", i == 0 ? bindMacA : bindMacB));
// }
// return Future.wait(arr);
// }
// Future saveOnePeople(mac, data) async {
// return ef.from("app_personnel").update(data).eq("mac", mac);
// }
}

View File

@@ -0,0 +1,30 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'people_info_controller.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
PeopleInfoPojo _$PeopleInfoPojoFromJson(Map<String, dynamic> json) =>
PeopleInfoPojo()
..name = json['name'] as String?
..sex = json['sex'] as String
..height = json['height'] as String?
..weight = json['weight'] as String?
..birthday = json['birthday'] == null
? null
: DateTime.parse(json['birthday'] as String)
..tel = json['tel'] as String?
..emergencyContact = json['emergencyContact'] as String?;
Map<String, dynamic> _$PeopleInfoPojoToJson(PeopleInfoPojo instance) =>
<String, dynamic>{
'name': instance.name,
'sex': instance.sex,
'height': instance.height,
'weight': instance.weight,
'birthday': instance.birthday?.toIso8601String(),
'tel': instance.tel,
'emergencyContact': instance.emergencyContact,
};

View File

@@ -0,0 +1,68 @@
import 'package:ef/ef.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:vbvs_app/controller/mh/apply_repair_controller.dart';
import 'package:vbvs_app/controller/mh/repair_process.dart';
part 'repair_info_controller.g.dart';
@JsonSerializable()
class RepairInfoModel {
String? id; //记录id
DateTime? create_time; //提交时间
String? status; //状态
String? desc; //描述
int? record_id; //归属记录id
List<RepairProcessModel> repairProcessList = []; //审核流程
String? device_name;
ApplyRepairModel? applyRepairModel;
RepairInfoModel();
static RepairInfoModel fromJson(Map<String, dynamic> json) =>
_$RepairInfoModelFromJson(json);
Map<String, dynamic> toJson() => _$RepairInfoModelToJson(this);
}
class RepairInfoController extends GetControllerEx<RepairInfoModel> {
// RepairRepository repairRepository = RepairRepository();
RepairInfoController() {
attr = GetModel(RepairInfoModel()).obs;
}
// Future<void> initData(ApplyRepairModel applyRepairModel) async {
// if (applyRepairModel != null) {
// final List<dynamic> fetchedRepairs =
// await repairRepository.findData(applyRepairModel.id!);
// RepairListController repairListController = Get.find();
// final List<dynamic> info = await repairListController.repairRepository
// .findRecordData(applyRepairModel.id!);
// if (info.isNotEmpty) {
// List<ApplyRepairModel> infos = [];
// List<dynamic> tmp = info as List<dynamic>;
// try {
// infos =
// tmp.map((repair) => ApplyRepairModel.fromJson(repair)).toList();
// model.applyRepairModel = infos.first;
// updateAll();
// } catch (e) {
// print('Error parsing JSON: $e');
// }
// // model.applyRepairModel = applyRepairModel;
// }
// if (fetchedRepairs != null) {
// List<RepairProcessModel> infos = [];
// List<dynamic> tmp = fetchedRepairs as List<dynamic>;
// try {
// infos =
// tmp.map((repair) => RepairProcessModel.fromJson(repair)).toList();
// model.repairProcessList = infos;
// updateAll();
// } catch (e) {
// print('Error parsing JSON: $e');
// }
// }
// }
// }
}

View File

@@ -0,0 +1,37 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'repair_info_controller.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
RepairInfoModel _$RepairInfoModelFromJson(Map<String, dynamic> json) =>
RepairInfoModel()
..id = json['id'] as String?
..create_time = json['create_time'] == null
? null
: DateTime.parse(json['create_time'] as String)
..status = json['status'] as String?
..desc = json['desc'] as String?
..record_id = (json['record_id'] as num?)?.toInt()
..repairProcessList = (json['repairProcessList'] as List<dynamic>)
.map((e) => RepairProcessModel.fromJson(e as Map<String, dynamic>))
.toList()
..device_name = json['device_name'] as String?
..applyRepairModel = json['applyRepairModel'] == null
? null
: ApplyRepairModel.fromJson(
json['applyRepairModel'] as Map<String, dynamic>);
Map<String, dynamic> _$RepairInfoModelToJson(RepairInfoModel instance) =>
<String, dynamic>{
'id': instance.id,
'create_time': instance.create_time?.toIso8601String(),
'status': instance.status,
'desc': instance.desc,
'record_id': instance.record_id,
'repairProcessList': instance.repairProcessList,
'device_name': instance.device_name,
'applyRepairModel': instance.applyRepairModel,
};

View File

@@ -0,0 +1,83 @@
import 'package:ef/ef.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'apply_repair_controller.dart';
part 'repair_list_controller.g.dart';
@JsonSerializable()
class RepairListModel {
int limit = AppConstants.limit;
int offset = 0;
bool isLoading = false;
bool hasMore = true;
List<ApplyRepairModel> repairList = [];
RepairListModel();
static RepairListModel fromJson(Map<String, dynamic> json) =>
_$RepairListModelFromJson(json);
Map<String, dynamic> toJson() => _$RepairListModelToJson(this);
}
class RepairListController extends GetControllerEx<RepairListModel> {
// RepairRepository repairRepository = RepairRepository();
// RepairListController() {
// attr = GetModel(RepairListModel()).obs;
// }
// //初始化列表数据
// Future<void> initData() async {
// if (model.isLoading) {
// return;
// }
// model.isLoading = true;
// final List<dynamic> fetchedRepairs = await repairRepository.fetchRepairs(
// limit: model.limit, offset: model.offset);
// if (fetchedRepairs != null) {
// List<ApplyRepairModel> infos = [];
// List<dynamic> tmp = fetchedRepairs as List<dynamic>;
// try {
// infos = tmp.map((repair) => ApplyRepairModel.fromJson(repair)).toList();
// model.repairList.addAll(infos);
// } catch (e) {
// print('Error parsing JSON: $e');
// }
// }
// model.offset += model.limit; // 更新 offset下一次查询跳过当前已经加载的记录
// model.hasMore = fetchedRepairs.length == model.limit; // 判断是否还有更多数据
// model.isLoading = false;
// updateAll();
// }
// Future<String> addScore(int id, int score) async {
// return await repairRepository.addScore(id, score);
// }
@override
void onInit() {
super.onInit();
loadMockRepairList();
}
void loadMockRepairList() {
model.repairList = [
ApplyRepairModel()
..id = 1001
..device_category = '智能床垫 BY-H'
..status = '待维修'
..create_time = DateTime.now().subtract(Duration(days: 1))
..device_id = 'BYH-001',
ApplyRepairModel()
..id = 1002
..device_category = '智能床垫 BY-A'
..status = '维修中'
..create_time = DateTime.now().subtract(Duration(days: 2))
..device_id = 'BYA-002',
ApplyRepairModel()
..id = 1003
..device_category = '智能床垫 BY-C'
..status = '已完成'
..create_time = DateTime.now().subtract(Duration(days: 3))
..device_id = 'BYC-003',
];
}
}

View File

@@ -0,0 +1,26 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'repair_list_controller.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
RepairListModel _$RepairListModelFromJson(Map<String, dynamic> json) =>
RepairListModel()
..limit = (json['limit'] as num).toInt()
..offset = (json['offset'] as num).toInt()
..isLoading = json['isLoading'] as bool
..hasMore = json['hasMore'] as bool
..repairList = (json['repairList'] as List<dynamic>)
.map((e) => ApplyRepairModel.fromJson(e as Map<String, dynamic>))
.toList();
Map<String, dynamic> _$RepairListModelToJson(RepairListModel instance) =>
<String, dynamic>{
'limit': instance.limit,
'offset': instance.offset,
'isLoading': instance.isLoading,
'hasMore': instance.hasMore,
'repairList': instance.repairList,
};

View File

@@ -0,0 +1,18 @@
import 'package:json_annotation/json_annotation.dart';
part 'repair_process.g.dart';
@JsonSerializable()
class RepairProcessModel {
String? status; //审核状态
DateTime? create_time; //审核时间
String? desc; //审核意见
int? record_id; //归属记录
int? deal_user; //处理人
RepairProcessModel();
static RepairProcessModel fromJson(Map<String, dynamic> json) =>
_$RepairProcessModelFromJson(json);
Map<String, dynamic> toJson() => _$RepairProcessModelToJson(this);
}

View File

@@ -0,0 +1,26 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'repair_process.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
RepairProcessModel _$RepairProcessModelFromJson(Map<String, dynamic> json) =>
RepairProcessModel()
..status = json['status'] as String?
..create_time = json['create_time'] == null
? null
: DateTime.parse(json['create_time'] as String)
..desc = json['desc'] as String?
..record_id = (json['record_id'] as num?)?.toInt()
..deal_user = (json['deal_user'] as num?)?.toInt();
Map<String, dynamic> _$RepairProcessModelToJson(RepairProcessModel instance) =>
<String, dynamic>{
'status': instance.status,
'create_time': instance.create_time?.toIso8601String(),
'desc': instance.desc,
'record_id': instance.record_id,
'deal_user': instance.deal_user,
};

View File

@@ -0,0 +1,20 @@
import 'package:ef/ef.dart';
import 'package:json_annotation/json_annotation.dart';
part 'score_controller.g.dart';
@JsonSerializable()
class ScoreModel {
int? score = 5;
ScoreModel();
static ScoreModel fromJson(Map<String, dynamic> json) =>
_$ScoreModelFromJson(json);
Map<String, dynamic> toJson() => _$ScoreModelToJson(this);
}
class ScoreController extends GetControllerEx<ScoreModel> {
ScoreController() {
attr = GetModel(ScoreModel()).obs;
}
}

View File

@@ -0,0 +1,15 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'score_controller.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
ScoreModel _$ScoreModelFromJson(Map<String, dynamic> json) =>
ScoreModel()..score = (json['score'] as num?)?.toInt();
Map<String, dynamic> _$ScoreModelToJson(ScoreModel instance) =>
<String, dynamic>{
'score': instance.score,
};

View File

@@ -0,0 +1,94 @@
import 'dart:convert';
import 'package:dio/src/form_data.dart' as formdata;
import 'package:ef/ef.dart';
import 'package:json_annotation/json_annotation.dart';
part 'sleeping_habit_controller.g.dart'; // 由json_serializable自动生成的部分
@JsonSerializable()
class SleepingHabitModel {
bool rxhxIsStart = false;
List<int> rxhxWakeTime = [0, 0];
bool rxhxIsBell = false;
bool rxhxIsAnMo = false;
int rxhxLocation = 0;
List rxhxWeeks = [0, 0, 0, 0, 0, 0, 0];
bool dhgyIsStart = false;
bool smysIsStart = false;
List<int> smysStartTime = [20, 0];
List<int> smysEndTime = [9, 0];
String get rxhxWakeTimeToString {
return '${rxhxWakeTime[0]}'.padLeft(2, "0") +
":" +
'${rxhxWakeTime[1]}'.padLeft(2, "0");
}
String get smysStartTimeToString {
return '${smysStartTime[0]}'.padLeft(2, "0") +
":" +
'${smysStartTime[1]}'.padLeft(2, "0");
}
String get smysEndTimeToString {
return '${smysEndTime[0]}'.padLeft(2, "0") +
":" +
'${smysEndTime[1]}'.padLeft(2, "0");
}
SleepingHabitModel();
factory SleepingHabitModel.fromJson(Map<String, dynamic> json) {
try {
return _$SleepingHabitModelFromJson(json);
} catch (e) {
print("$e");
// 在实际应用中,应该有更细致的异常处理策略和错误日志
return SleepingHabitModel(); // 或者返回一个带有错误信息的特定AboutModel实例
}
}
Map<String, dynamic> toJson() => _$SleepingHabitModelToJson(this);
}
class SleepingHabitController extends GetControllerEx<SleepingHabitModel> {
SleepingHabitController() {
attr = GetModel(SleepingHabitModel()).obs;
}
// saveDataApi() {
// String mac = Get.find<GlobalController>().model.deviceMain["mac"];
// ApiService.request.post("/api/device/info/config",
// data: formdata.FormData.fromMap({
// "mac": mac,
// "type": "sleepHabit",
// "data": jsonEncode(model.toJson())
// }));
// }
// loadDataApi({int time = 3}) {
// String mac = Get.find<GlobalController>().model.deviceMain["mac"];
// ApiService.request
// .get("/api/device/info/config?type=sleepHabit&mac=${mac}")
// .then((d) async {
// if (d.data["data"] != null && d.data["data"]["data"] != null) {
// attr.value.model =
// SleepingHabitModel.fromJson(jsonDecode(d.data["data"]["data"]));
// print("load ${model.toJson()}");
// } else {
// attr.value.model = SleepingHabitModel();
// print("load error");
// }
// updateAll();
// }).catchError((d) {
// if (time > 0) {
// loadDataApi(time: time - 1);
// } else {
// attr.value.model = SleepingHabitModel();
// }
// });
// }
}

View File

@@ -0,0 +1,40 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'sleeping_habit_controller.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
SleepingHabitModel _$SleepingHabitModelFromJson(Map<String, dynamic> json) =>
SleepingHabitModel()
..rxhxIsStart = json['rxhxIsStart'] as bool
..rxhxWakeTime = (json['rxhxWakeTime'] as List<dynamic>)
.map((e) => (e as num).toInt())
.toList()
..rxhxIsBell = json['rxhxIsBell'] as bool
..rxhxIsAnMo = json['rxhxIsAnMo'] as bool
..rxhxLocation = (json['rxhxLocation'] as num).toInt()
..rxhxWeeks = json['rxhxWeeks'] as List<dynamic>
..dhgyIsStart = json['dhgyIsStart'] as bool
..smysIsStart = json['smysIsStart'] as bool
..smysStartTime = (json['smysStartTime'] as List<dynamic>)
.map((e) => (e as num).toInt())
.toList()
..smysEndTime = (json['smysEndTime'] as List<dynamic>)
.map((e) => (e as num).toInt())
.toList();
Map<String, dynamic> _$SleepingHabitModelToJson(SleepingHabitModel instance) =>
<String, dynamic>{
'rxhxIsStart': instance.rxhxIsStart,
'rxhxWakeTime': instance.rxhxWakeTime,
'rxhxIsBell': instance.rxhxIsBell,
'rxhxIsAnMo': instance.rxhxIsAnMo,
'rxhxLocation': instance.rxhxLocation,
'rxhxWeeks': instance.rxhxWeeks,
'dhgyIsStart': instance.dhgyIsStart,
'smysIsStart': instance.smysIsStart,
'smysStartTime': instance.smysStartTime,
'smysEndTime': instance.smysEndTime,
};

View File

@@ -0,0 +1,22 @@
import 'package:json_annotation/json_annotation.dart';
part 'user_data.g.dart';
@JsonSerializable()
class UserModel {
String? uid;
String? userName;
String? nickName;
String? tel;
String? avatar;
String? exp1;
String? exp2;
String? head;
String? tmpHead;
String? tmpNickName;
UserModel();
static UserModel fromJson(Map<String, dynamic> json) =>
_$UserModelFromJson(json);
Map<String, dynamic> toJson() => _$UserModelToJson(this);
}

View File

@@ -0,0 +1,32 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'user_data.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
UserModel _$UserModelFromJson(Map<String, dynamic> json) => UserModel()
..uid = json['uid'] as String?
..userName = json['userName'] as String?
..nickName = json['nickName'] as String?
..tel = json['tel'] as String?
..avatar = json['avatar'] as String?
..exp1 = json['exp1'] as String?
..exp2 = json['exp2'] as String?
..head = json['head'] as String?
..tmpHead = json['tmpHead'] as String?
..tmpNickName = json['tmpNickName'] as String?;
Map<String, dynamic> _$UserModelToJson(UserModel instance) => <String, dynamic>{
'uid': instance.uid,
'userName': instance.userName,
'nickName': instance.nickName,
'tel': instance.tel,
'avatar': instance.avatar,
'exp1': instance.exp1,
'exp2': instance.exp2,
'head': instance.head,
'tmpHead': instance.tmpHead,
'tmpNickName': instance.tmpNickName,
};

View File

@@ -31,6 +31,20 @@ import 'package:vbvs_app/controller/message/common_message_setting_controller.da
import 'package:vbvs_app/controller/message/message_controller.dart'; import 'package:vbvs_app/controller/message/message_controller.dart';
import 'package:vbvs_app/controller/message/message_review_controller.dart'; import 'package:vbvs_app/controller/message/message_review_controller.dart';
import 'package:vbvs_app/controller/message/message_setting_controller.dart'; import 'package:vbvs_app/controller/message/message_setting_controller.dart';
import 'package:vbvs_app/controller/mh/address_controller.dart';
import 'package:vbvs_app/controller/mh/address_list_controller.dart';
import 'package:vbvs_app/controller/mh/book_info_controller.dart';
import 'package:vbvs_app/controller/mh/experience_store_list_page.dart';
import 'package:vbvs_app/controller/mh/issue_controller.dart';
import 'package:vbvs_app/controller/mh/issue_preview_controller.dart';
import 'package:vbvs_app/controller/mh/message_controller.dart';
import 'package:vbvs_app/controller/mh/muser_info_controller.dart';
import 'package:vbvs_app/controller/mh/my_experience_list_controller.dart';
import 'package:vbvs_app/controller/mh/people_info_controller.dart';
import 'package:vbvs_app/controller/mh/repair_info_controller.dart';
import 'package:vbvs_app/controller/mh/repair_list_controller.dart';
import 'package:vbvs_app/controller/mh/score_controller.dart';
import 'package:vbvs_app/controller/mh/sleeping_habit_controller.dart';
import 'package:vbvs_app/controller/person/person_controller.dart'; import 'package:vbvs_app/controller/person/person_controller.dart';
import 'package:vbvs_app/controller/repair/repair_controller.dart'; import 'package:vbvs_app/controller/repair/repair_controller.dart';
import 'package:vbvs_app/controller/setting/language/language_controller.dart'; import 'package:vbvs_app/controller/setting/language/language_controller.dart';
@@ -43,7 +57,13 @@ import 'package:vbvs_app/controller/weather/weather_controller.dart';
import 'package:vbvs_app/language/AppLanguage.dart'; import 'package:vbvs_app/language/AppLanguage.dart';
import 'package:vbvs_app/model/CustomThemeColor.dart'; import 'package:vbvs_app/model/CustomThemeColor.dart';
import 'package:vbvs_app/model/user_data.dart'; import 'package:vbvs_app/model/user_data.dart';
import 'package:vbvs_app/pages/device_control/BackMovement.dart';
import 'package:vbvs_app/pages/device_control/MattressControl.dart';
import 'package:vbvs_app/pages/device_control/people_info.dart';
import 'package:vbvs_app/pages/main_bottom/component/main_page_b_bottom_change.dart';
import 'package:vbvs_app/routers/mh_routers.dart';
import 'controller/mh/apply_repair_controller.dart';
import 'controller/user_info_controller.dart'; import 'controller/user_info_controller.dart';
import 'routers/routers.dart'; import 'routers/routers.dart';
@@ -198,55 +218,87 @@ class MyApp extends StatelessWidget {
MyApp({super.key}); MyApp({super.key});
final ThemeController themeController = Get.put(ThemeController()); final ThemeController themeController = Get.put(ThemeController());
// This widget is the root of your application. Widget buildmht(BuildContext context, BoxConstraints cons) {
@override return GetMaterialApp(
Widget build(BuildContext context) { translations: AppLanguage(),
themeController.changeTheme(CustomThemeColor.dark); debugShowCheckedModeBanner: false,
UserInfoController userInfoController = Get.find(); title: '',
return LayoutBuilder(builder: (contxt, cons) { theme: themeController.currentTheme,
double width = cons.maxWidth; home: MainPageBBottomChange(),
double height = cons.maxHeight; onGenerateRoute: mhonGenerateRoute,
if (width < 1) { initialBinding: BindingsBuilder(() => [
return Container(); // Get.lazyPut(() => UserInfoController()),
} Get.put(GlobalController()),
FitTool.init(width < height ? width : height); Get.lazyPut(() => ControlCardController()),
return GetMaterialApp( Get.lazyPut(() => RepairListController()),
translations: AppLanguage(), Get.lazyPut(() => RepairInfoController()),
// locale: const Locale("zh", "CN"), Get.lazyPut(() => MUserInfoController()),
locale: AppLanguage().currentLocale, // ✅ 动态读取当前语言 Get.lazyPut(() => MhMessageController()),
fallbackLocale: const Locale("zh", "CN"), Get.lazyPut(() => ScoreController()),
localizationsDelegates: [ Get.lazyPut(() => ExperienceStoreListController()),
GlobalMaterialLocalizations.delegate, Get.lazyPut(() => BookExperienceListController()),
GlobalWidgetsLocalizations.delegate, Get.lazyPut(() => IssuePreviewInfoController()),
GlobalCupertinoLocalizations.delegate, Get.lazyPut(() => IssueListController()),
SfGlobalLocalizations.delegate, Get.lazyPut(() => ApplyRepairController()),
], Get.lazyPut(() => SleepingHabitController()),
supportedLocales: [ Get.lazyPut(() => PeopleInfoController()),
const Locale('zh', 'CN'), // 中文 Get.lazyPut(() => MainPageController()),
const Locale('en', 'US'), // ⚠️ 添加你支持的语言 Get.lazyPut(() => AddressListController()),
], Get.lazyPut(() => AddressController()),
debugShowCheckedModeBanner: false, Get.lazyPut(() => BlueteethBindController()),
title: '', Get.lazyPut(() => BookInfoController()),
theme: themeController.currentTheme, Get.lazyPut(() => PersonController()),
// home: const MyHomePage(title: '智慧眠花糖 Home Page'), Get.lazyPut(() => CountdownController()),
initialRoute: "/mianPageBottomChange", Get.lazyPut(() => LoginController()),
onGenerateRoute: onGenerateRoute, Get.lazyPut(() => DeviceTypeController()),
initialBinding: BindingsBuilder(() => [ Get.lazyPut(() => BodyDeviceController()),
// Get.lazyPut(() => UserInfoController()), Get.lazyPut(() => HomeController()),
Get.put(GlobalController()), Get.lazyPut(() => DeviceShareController()),
Get.lazyPut(() => DeviceShareListController()),
Get.lazyPut(() => DeviceCalibrationController()),
Get.lazyPut(() => RepairController()),
Get.lazyPut(() => PdfController()),
]));
}
Widget buildth(BuildContext context, BoxConstraints cons) {
return GetMaterialApp(
translations: AppLanguage(),
// locale: const Locale("zh", "CN"),
locale: AppLanguage().currentLocale, // ✅ 动态读取当前语言
fallbackLocale: const Locale("zh", "CN"),
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
SfGlobalLocalizations.delegate,
],
supportedLocales: [
const Locale('zh', 'CN'), // 中文
const Locale('en', 'US'), // ⚠️ 添加你支持的语言
],
debugShowCheckedModeBanner: false,
title: '',
theme: themeController.currentTheme,
// home: const MyHomePage(title: '智慧眠花糖 Home Page'),
initialRoute: "/mianPageBottomChange",
onGenerateRoute: onGenerateRoute,
initialBinding: BindingsBuilder(() => [
// Get.lazyPut(() => UserInfoController()),
Get.put(GlobalController()),
Get.put(WeatherModelController()), Get.put(WeatherModelController()),
Get.lazyPut(() => MainPageController()), Get.lazyPut(() => MainPageController()),
Get.lazyPut(() => BlueteethBindController()), Get.lazyPut(() => BlueteethBindController()),
Get.lazyPut(() => PersonController()), Get.lazyPut(() => PersonController()),
Get.lazyPut(() => CountdownController()), Get.lazyPut(() => CountdownController()),
Get.lazyPut(() => LoginController()), Get.lazyPut(() => LoginController()),
Get.lazyPut(() => DeviceTypeController()), Get.lazyPut(() => DeviceTypeController()),
Get.lazyPut(() => BodyDeviceController()), Get.lazyPut(() => BodyDeviceController()),
Get.lazyPut(() => HomeController()), Get.lazyPut(() => HomeController()),
Get.lazyPut(() => DeviceShareController()), Get.lazyPut(() => DeviceShareController()),
Get.lazyPut(() => DeviceShareListController()), Get.lazyPut(() => DeviceShareListController()),
Get.lazyPut(() => DeviceCalibrationController()), Get.lazyPut(() => DeviceCalibrationController()),
Get.lazyPut(() => RepairController()), Get.lazyPut(() => RepairController()),
Get.lazyPut(() => UserPdfController()), Get.lazyPut(() => UserPdfController()),
Get.lazyPut(() => PrivacyPdfController()), Get.lazyPut(() => PrivacyPdfController()),
Get.lazyPut(() => CalendarController()), Get.lazyPut(() => CalendarController()),
@@ -254,7 +306,25 @@ class MyApp extends StatelessWidget {
Get.lazyPut(() => MessageReviewController()), Get.lazyPut(() => MessageReviewController()),
Get.lazyPut(() => MessageSettingController()), Get.lazyPut(() => MessageSettingController()),
Get.lazyPut(() => CommonMessageSettingController()), Get.lazyPut(() => CommonMessageSettingController()),
])); ]));
}
final selectapp = "mht";
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
var co = MediaQuery.sizeOf(context);
FitTool.init(co.height);
themeController.changeTheme(CustomThemeColor.dark);
return LayoutBuilder(builder: (contxt, cons) {
switch (selectapp) {
case "th":
return buildth(context, cons);
case "mht":
return buildmht(contxt, cons);
default:
return buildth(context, cons);
}
}); });
} }
} }

View File

@@ -0,0 +1,151 @@
// bezier_bottom_navigation_bar.dart
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
class BezierBottomNavigationBar extends StatelessWidget {
final int selectedIndex;
final double animatedPosition;
final ValueChanged<int> onTap;
final List<String> path;
final List<String> titles;
const BezierBottomNavigationBar({
Key? key,
required this.selectedIndex,
required this.animatedPosition,
required this.onTap,
required this.path,
required this.titles,
}) : super(key: key);
@override
Widget build(BuildContext context) {
final itemCount = path.length;
return SizedBox(
height: 130.rpx,
child: Stack(
children: [
Positioned.fill(
child: CustomPaint(
size: Size(MediaQuery.of(context).size.width, 130.rpx),
painter: BezierPainter(
position: animatedPosition,
itemCount: itemCount,
),
),
),
Row(
children: path.asMap().entries.map((entry) {
final i = entry.key;
final icon = entry.value;
return Expanded(
child: GestureDetector(
// 用 InkWell 替换 GestureDetector支持点击反馈
onTap: () => onTap(i),
// splashColor: Colors.transparent, // 可选:关闭 splash 效果
// highlightColor: Colors.transparent, // 可选:关闭高亮效果
child: SizedBox.expand(
child: Padding(
padding: EdgeInsets.only(top: 14.rpx),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(top: 11.rpx),
child: SvgPicture.asset(icon,
width: 42.rpx,
height: 42.rpx,
color: selectedIndex == i
? Colors.white
: Color(0XFF929699)),
),
SizedBox(height: 3),
Text(
titles[i],
style: TextStyle(
fontSize: 22.rpx,
color: selectedIndex == i
? Colors.white
: Colors.grey.shade400,
),
),
],
),
)
// 关键点:撑满 Expanded 区域
),
),
);
}).toList(),
),
],
),
);
}
}
class BezierPainter extends CustomPainter {
final double position;
final int itemCount;
BezierPainter({required this.position, required this.itemCount});
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.white
..style = PaintingStyle.stroke
..strokeWidth = 1.0;
final path = Path();
final itemWidth = size.width / itemCount;
final curveWidth = itemWidth * 0.8;
double curveHeight = 8.5;
final centerX = itemWidth * position + itemWidth / 2;
final left = centerX - curveWidth / 2;
final right = centerX + curveWidth / 2;
// 控制点偏移比例(越小越平滑)
final controlOffsetX = curveWidth * 0.2;
final controlOffsetY = curveHeight * 0.9;
// 起点
path.moveTo(0, 0);
// 到左侧前的一段直线
path.lineTo(left, 0);
// 凸起贝塞尔曲线
path.cubicTo(
left + controlOffsetX,
0,
centerX - controlOffsetX,
-controlOffsetY,
centerX,
-controlOffsetY,
);
path.cubicTo(
centerX + controlOffsetX,
-controlOffsetY,
right - controlOffsetX,
0,
right,
0,
);
// 右边剩余直线
path.lineTo(size.width, 0);
// 向下平移,保证凸起在容器内部
canvas.translate(0, controlOffsetY);
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(covariant BezierPainter oldDelegate) {
return oldDelegate.position != position;
}
}

View File

@@ -0,0 +1,228 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'dart:math' as math;
import 'package:vbvs_app/common/util/MyUtils.dart';
class BackMovementPage extends StatefulWidget {
const BackMovementPage({super.key});
@override
State<BackMovementPage> createState() => _BackMovementPageState();
}
class _BackMovementPageState extends State<BackMovementPage> {
double intensity = 4;
int selectedTime = 10;
final List<int> timeOptions = [10, 20, 30];
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, bodysize) {
final double totalWidth = bodysize.maxWidth - 40.rpx * 2; // 减去左右 padding
final double spacing = 34.rpx;
final double buttonHeight = 101.rpx;
return GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
child: Scaffold(
appBar: AppBar(
iconTheme: IconThemeData(color: themeController.currentColor.sc3),
backgroundColor: const Color(0xFF011C33), // 统一背景色
automaticallyImplyLeading: false,
titleSpacing: 0,
title: SizedBox(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
// 中间居中的标题
Text(
'背部律动',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 30.rpx,
),
),
// 左侧图标
Positioned(
left: 20.rpx,
child: returnIconButtomNew,
),
],
),
),
centerTitle: false,
),
backgroundColor: const Color(0xFF011C33),
body: Padding(
padding: EdgeInsets.fromLTRB(0.rpx, 0, 0.rpx, 0),
child: Column(
// crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SingleChildScrollView(
child: Column(
children: [
SizedBox(height: 30.rpx),
Text(
'力度调节',
style: TextStyle(color: Colors.grey, fontSize: 30.rpx),
),
SizedBox(height: 148.rpx),
Text(
intensity.toInt().toString(),
style:
TextStyle(color: Colors.white, fontSize: 160.rpx),
),
SizedBox(height: 41.rpx),
SizedBox(
height: 451.rpx, // 外部容器高度固定
child: Stack(
children: [
// 左边的 强/弱 文本
Positioned(
left: 0,
top: 0,
bottom: 0,
child: SizedBox(
width: 60.rpx,
child: Column(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text('',
style: TextStyle(
color: Colors.grey,
fontSize: 30.rpx)),
Text('',
style: TextStyle(
color: Colors.grey,
fontSize: 30.rpx)),
],
),
),
),
// 右侧 slider27.rpx 后居中
Positioned(
left: 60.rpx - 27.rpx, // 60 是文字宽度27 是间隔
right: 0,
top: 0,
bottom: 0,
child: Center(
child: Transform.rotate(
angle: -math.pi / 2,
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: 451.rpx,
maxHeight: 451.rpx,
),
child: SliderTheme(
data: SliderTheme.of(context).copyWith(
trackHeight: 60.rpx,
thumbShape: RoundSliderThumbShape(
enabledThumbRadius: 45.rpx),
overlayShape:
const RoundSliderOverlayShape(
overlayRadius: 20),
),
child: Slider(
value: intensity,
min: 1,
max: 6,
divisions: 7,
activeColor: Colors.cyanAccent,
inactiveColor: Colors.blue.shade900,
onChanged: (value) {
setState(() {
intensity = value;
});
},
),
),
),
),
),
),
],
),
),
SizedBox(height: 118.rpx),
Padding(
padding: EdgeInsets.only(
left: 47.rpx), // 👈 控制间隔大小(也可以是 all / symmetric
child: Align(
alignment: Alignment.centerLeft,
child: Text(
'按摩定时',
style: TextStyle(
color: Colors.white70, fontSize: 30.rpx),
),
),
),
SizedBox(height: 74.rpx),
Padding(
padding: EdgeInsets.fromLTRB(40.rpx, 0, 40.rpx, 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children:
List.generate(timeOptions.length, (index) {
final min = timeOptions[index];
final isSelected = selectedTime == min;
return SizedBox(
height: buttonHeight,
child: ElevatedButton(
onPressed: () {
setState(() {
selectedTime = min;
});
},
style: ElevatedButton.styleFrom(
backgroundColor: isSelected
? Colors.cyanAccent
: Colors.blue.shade900,
foregroundColor: isSelected
? Colors.black
: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
),
child: Text('$min分钟'),
));
}),
)),
],
)),
Padding(
padding: EdgeInsets.fromLTRB(30.rpx, 0, 30.rpx,
81.rpx), // 👈 控制上方间隔(也可以用 all / symmetric
child: OutlinedButton(
onPressed: () {
setState(() {
intensity = 4;
selectedTime = 10;
});
},
style: OutlinedButton.styleFrom(
side: const BorderSide(color: Color(0XFF74DAE5)),
foregroundColor: Colors.cyanAccent,
minimumSize: Size(bodysize.maxWidth, 92.rpx),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
),
child: const Text('恢复到默认设置'),
),
),
],
),
),
)));
});
}
}

View File

@@ -0,0 +1,94 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
class ColorChangeOnPress extends StatefulWidget {
final Color? initialColor; // 初始颜色
final Color pressColor; // 按下时的颜色
final bool shouldNavigate; // 是否需要跳转
final String? routeName; // 路由名称
final Widget child; // 子组件
final String? toastMessage; // Toast 消息
final ToastColor? toastColor; // Toast 颜色
final double topLeft; // 左上圆角
final double topRight; // 右上圆角
final double bottomRight; // 右下圆角
final double bottomLeft; // 左下圆角
final VoidCallback? onTap; // 点击回调
const ColorChangeOnPress({
Key? key,
this.initialColor = Colors.white, // 默认初始颜色为白色
this.pressColor = Colors.grey, // 默认按下颜色为灰色
this.shouldNavigate = false, // 默认不跳转
this.routeName,
required this.child,
this.toastMessage, // Toast 消息
this.toastColor, // Toast 颜色
this.topLeft = 0.0, // 左上圆角
this.topRight = 0.0, // 右上圆角
this.bottomRight = 0.0, // 右下圆角
this.bottomLeft = 0.0, // 左下圆角
this.onTap, // 点击回调
}) : super(key: key);
@override
_ColorChangeOnPressState createState() => _ColorChangeOnPressState();
}
class _ColorChangeOnPressState extends State<ColorChangeOnPress> {
Color? _currentColor;
@override
void initState() {
super.initState();
_currentColor = widget.initialColor; // 初始化为初始颜色
}
void _handleTap() {
// 如果提供了 onTap 回调,调用它
if (widget.onTap != null) {
widget.onTap!(); // 执行自定义逻辑
}
setState(() {
_currentColor = widget.pressColor; // 改变为按下的颜色
});
// 显示 Toast 消息
if (widget.toastMessage != null) {
showToast(widget.toastMessage!, color: widget.toastColor!);
}
// 在0.5秒后恢复颜色
Future.delayed(const Duration(milliseconds: 100), () {
setState(() {
_currentColor = widget.initialColor; // 恢复为初始颜色
});
// 如果需要跳转,则执行路由跳转
if (widget.shouldNavigate && widget.routeName != null) {
Get.toNamed(widget.routeName!); // 在颜色恢复后执行跳转
}
});
}
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: _currentColor,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(widget.topLeft), // 左上圆角
topRight: Radius.circular(widget.topRight), // 右上圆角
bottomRight: Radius.circular(widget.bottomRight), // 右下圆角
bottomLeft: Radius.circular(widget.bottomLeft), // 左下圆角
),
),
child: InkWell(
onTap: _handleTap,
child: widget.child,
),
);
}
}

View File

@@ -0,0 +1,54 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
class Empty extends StatefulWidget {
Empty({super.key});
@override
State<Empty> createState() => _EmptyState();
}
class _EmptyState extends State<Empty> {
String empty = "";
bool closepage = false;
@override
void initState() {
// TODO: implement initState
super.initState();
Timer(const Duration(milliseconds: 1200), () {
if (empty.isEmpty && closepage == false) {
setState(() {
empty = "assets/images/new_empty.png";
});
}
});
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
closepage = true;
}
@override
Widget build(BuildContext context) {
if (empty.isEmpty) {
return Container();
} else {
return Container(
width: double.infinity,
margin: EdgeInsets.only(top: MediaQuery.of(context).size.height * 0.3),
alignment: Alignment.center,
child: Container(
width: 164.rpx,
height: 230.rpx,
child: Image.asset(empty),
),
);
}
}
}

View File

@@ -0,0 +1,37 @@
import 'dart:async';
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
class EmptyMessageWidget extends StatelessWidget {
final String imagePath;
final double width;
final double height;
var empty = "".obs;
EmptyMessageWidget({
Key? key,
this.imagePath = 'assets/images/new_empty.png', // 默认图片路径
double? width, // 默认宽度
double? height, // 默认高度
}) : width = 164.rpx, // 初始化宽度
height = 230.rpx, // 初始化高度变为原来的三分之二
super(key: key);
@override
Widget build(BuildContext context) {
Timer(Duration(milliseconds: 5000), () {
empty.value = "assets/images/new_empty.png";
});
return Center(
child: Image.asset(
imagePath,
width: width,
height: height,
color: Colors.white,
),
);
}
}

View File

@@ -0,0 +1,245 @@
import 'dart:async';
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
class HomeDeviceType extends StatefulWidget {
HomeDeviceType({super.key});
@override
State<HomeDeviceType> createState() => _HomeDeviceTypeState();
}
class _HomeDeviceTypeState extends State<HomeDeviceType> {
bool isExec = false;
@override
Widget build(BuildContext context) {
// if (isExec == false) {
// Timer(const Duration(milliseconds: 10), () {
// controller.getDeviceType();
// });
// isExec = true;
// }
return LayoutBuilder(
builder: (context, boxConstraints) => GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/new_background.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
iconTheme: const IconThemeData(color: Colors.white),
titleSpacing: 0,
// leading: returnIconButtom,
title: SizedBox(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
// 中间居中的标题
Text(
'添加设备',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 30.rpx,
),
),
// 左侧图标
Positioned(
left: 20.rpx,
child: returnIconButtom,
),
],
),
),
centerTitle: false,
),
body: SafeArea(
top: true,
child: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 1.123,
// decoration: const BoxDecoration(
// image: DecorationImage(
// image: AssetImage("assets/images/new_background.png"),
// fit: BoxFit.cover,
// ),
// ),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
48.rpx, 24.rpx, 0, 0),
child: Text(
'选择类型',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Colors.white,
fontSize: 30.rpx,
letterSpacing: 0,
),
),
),
_buildControlCard(context),
],
),
),
),
),
),
)),
);
}
}
Widget _buildControlCard(BuildContext context) {
final List<Map<String, dynamic>> deviceTypeList = [
{
"id": 1,
"name": "智能床垫",
"desc": "SWES01 MHT01 SWES01 MHT01 SWES01 MHT01 ",
"img": "assets/images/device_bed.png",
"page": 1,
},
{
"id": 2,
"name": "智能电动床",
"desc": "M300",
"img": "assets/images/electric_bed.png",
"page": 2,
},
];
return SizedBox(
// height: 221.rpx,
child: Padding(
padding: EdgeInsets.only(left: 30.rpx, right: 30.rpx, top: 7.rpx),
child: Column(
children: List.generate(
deviceTypeList.length,
(index) => _buildDeviceItem(context, deviceTypeList[index]),
),
)));
}
Widget _buildDeviceItem(BuildContext context, Map<String, dynamic> dtype) {
return Padding(
padding: EdgeInsetsDirectional.fromSTEB(0, 25.rpx, 0, 0),
child: InkWell(
onTap: () {
// Get.offAndToNamed("/bindDevice", arguments: dtype["id"]);
},
child: Container(
height: 221.rpx,
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context).secondaryBackground,
borderRadius: BorderRadius.circular(6),
),
constraints: BoxConstraints(minHeight: 221.rpx),
child: Row(
children: [
Padding(
padding: EdgeInsetsDirectional.only(start: 59.rpx),
child: Container(
child: ClipRRect(
borderRadius: BorderRadius.circular(6.rpx),
child: Image.asset(
dtype["img"],
width: 180.rpx,
height: 109.rpx,
fit: BoxFit.cover,
),
),
),
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: EdgeInsets.fromLTRB(0, 59.rpx, 0, 0),
child: Text(
dtype["name"],
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Readex Pro',
fontSize: 30.rpx,
fontWeight: FontWeight.bold,
),
),
),
SizedBox(height: 35.rpx),
Expanded(
child: Padding(
padding: EdgeInsets.only(left: 80.rpx, right: 80.rpx),
child: SizedBox(
height: 40.rpx, // 固定高度(两行高度 + 行间距)
child: LayoutBuilder(
builder: (context, constraints) {
final items = (dtype["desc"] as String)
.split(RegExp(r'\s+'))
.where((e) => e.trim().isNotEmpty)
.toList();
final limitedItems = items.take(6).toList();
final isSingleLine = limitedItems.length <= 3;
return Align(
alignment: isSingleLine
? Alignment.topCenter
: Alignment.topLeft,
child: Wrap(
spacing: 20.rpx,
runSpacing: 10.rpx,
alignment: isSingleLine
? WrapAlignment.center
: WrapAlignment.start,
children: limitedItems.map((item) {
return Container(
width: 75.rpx,
// height: 40.rpx,
alignment: Alignment.center,
child: Text(
item,
style: TextStyle(
fontSize: 20.rpx,
color: const Color(0xFF9AA0B3),
height: 1,
),
// overflow: TextOverflow.ellipsis,
maxLines: 1,
),
);
}).toList(),
),
);
},
),
),
))
],
),
),
],
),
),
),
);
}

View File

@@ -0,0 +1,158 @@
import 'package:ef/base/widget/flutterflow/FlutterFlowTheme.dart';
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
class LanguagePage extends StatefulWidget {
@override
_LanguagePageState createState() => _LanguagePageState();
}
BoxConstraints? bodysize;
List<String> languageList = [
'简体中文',
'繁體中文',
'English',
];
final Map<String, String> languageMap = {
'简体中文': 'zh_CN',
'繁體中文': 'zh_TW',
'English': 'en_US',
};
class _LanguagePageState extends State<LanguagePage> {
RxBool checkboxValue = false.obs;
RxString? selectLanguage = ''.obs;
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, cc) {
bodysize = cc;
return GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/new_background.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
backgroundColor: Colors.transparent,
iconTheme: const IconThemeData(color: Colors.white),
automaticallyImplyLeading: false,
titleSpacing: 0,
title: SizedBox(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
// 中间居中的标题
Text(
'切换语言',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 30.rpx,
),
),
// 左侧图标
Positioned(
left: 20.rpx,
child: returnIconButtomNew,
),
],
),
),
centerTitle: false,
),
body: SafeArea(
top: true,
child: Padding(
padding: EdgeInsets.only(
top: 30.rpx, left: 30.rpx, right: 30.rpx),
child: Container(
decoration: BoxDecoration(
color: Color(0XFF003058),
borderRadius: BorderRadius.circular(16.rpx)),
child: Padding(
padding: EdgeInsets.only(
left: 40.rpx,
top: 20.rpx,
bottom: 20.rpx,
right: 30.rpx),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemCount: languageList.length,
itemBuilder:
(BuildContext context, int index) {
return _buildItem(
context, index, languageList[index]);
},
),
Container(height: bodysize!.maxHeight * 0.12)
],
),
))))),
));
});
}
Widget _buildItem(BuildContext context, int index, String text) {
return Container(
// width: bodysize!.maxWidth * 1,
height: bodysize!.maxHeight * 0.055,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
text,
style: TextStyle(color: Colors.white, fontSize: 30.rpx),
),
Theme(
data: ThemeData(
checkboxTheme: CheckboxThemeData(
visualDensity: VisualDensity.compact,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4),
),
),
unselectedWidgetColor: FlutterFlowTheme.of(context).alternate,
),
child: Obx(() {
return Checkbox(
value: selectLanguage!.value == languageMap[text],
onChanged: (newValue) async {
if (newValue!) {
selectLanguage!.value = languageMap[
text]!; // Set selectLanguage to the current text value
} else {
selectLanguage!.value =
''; // Clear selection if unchecked
}
},
shape: CircleBorder(),
side: BorderSide(
width: 2,
color: FlutterFlowTheme.of(context).alternate,
),
activeColor: Color(0XFF6BFDAC),
checkColor: FlutterFlowTheme.of(context).info,
);
})),
],
),
);
}
}

View File

@@ -0,0 +1,352 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:flutter_switch/flutter_switch.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
class MattressControlPage extends StatefulWidget {
const MattressControlPage({super.key});
@override
State<MattressControlPage> createState() => _MattressControlPageState();
}
class _MattressControlPageState extends State<MattressControlPage> {
final controller = Get.put(ControlCardController());
int selectedIndex = 1; // 当前选中的tab索引
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, bodySize) => GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image:
AssetImage('assets/images/new_background.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
backgroundColor: Colors.transparent,
// 顶部返回 + 设备选择 + 蓝牙图标 + 设置按钮
appBar: AppBar(
backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
titleSpacing: 0,
elevation: 0,
title: SizedBox(
width: double.infinity,
height: 180.rpx,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(width: 20.rpx),
returnIconButtomNew,
SizedBox(width: 26.rpx),
Container(
decoration: BoxDecoration(
color: Color(0xFF003058),
borderRadius: BorderRadius.circular(30.rpx),
),
constraints: BoxConstraints(
minHeight: 60.rpx,
maxHeight: 60.rpx,
maxWidth: 260.rpx,
minWidth: 260.rpx),
padding: EdgeInsets.symmetric(
horizontal: 20.rpx), // 加左右边距
child: DropdownButton<String>(
value: 'Eason Chan',
underline: const SizedBox(),
dropdownColor: Colors.blueGrey,
iconEnabledColor: Colors.white,
style: const TextStyle(color: Colors.white),
isExpanded: true,
items: const [
DropdownMenuItem(
value: 'Eason Chan',
child: Text('Eason Chan'),
),
DropdownMenuItem(
value: 'Anna',
child: Text('Anna'),
),
],
onChanged: (_) {},
),
),
],
)),
actions: [
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.transparent,
padding: EdgeInsets.only(right: 69.rpx),
onTap: () {},
child: Icon(
Icons.bluetooth,
color: Colors.white,
size: 42.rpx,
),
),
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.transparent,
padding: EdgeInsets.only(right: 38.rpx),
onTap: () {
Get.toNamed('/bluetoothPage');
},
child: Icon(Icons.tune,
color: Colors.white, size: 42.rpx))
],
centerTitle: false,
),
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_buildBedImageSection(context),
_buildModeSelector(context),
Expanded(child: _buildControlCards(context)),
],
),
),
))));
}
// 床体图示
Widget _buildBedImageSection(BuildContext context) {
return Padding(
padding: EdgeInsets.fromLTRB(0, 38.rpx, 0, 63.rpx),
child: Image.asset(
'assets/images/bed_control.png',
width: MediaQuery.of(context).size.width * 0.7, // 你需要准备这个图像资源
height: 193.rpx,
),
);
}
Widget _buildModeSelector(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width - 60.rpx; // 左右各30
final spacing = 20.0.rpx;
final thirdWidth = 215.rpx; // 三个卡片两个间距
final tabCount = 3;
final tabWidth = screenWidth / tabCount;
final sideMargin = (tabWidth - thirdWidth) / 2;
final labels = ['', '全局', ''];
return Padding(
padding: EdgeInsets.symmetric(horizontal: 30.rpx),
child: Stack(
children: [
Row(
children: List.generate(tabCount, (index) {
return Expanded(
child: GestureDetector(
onTap: () {
selectedIndex = index;
},
child: _selectorTab(
labels[index],
isSelected: selectedIndex == index,
sideMargin: sideMargin,
),
),
);
}),
),
// 白线指示器
Positioned(
bottom: 0,
left: selectedIndex * tabWidth + sideMargin,
child: AnimatedContainer(
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
width: thirdWidth,
height: 3.rpx,
color: Colors.white,
),
),
],
),
);
}
Widget _selectorTab(String label,
{bool isSelected = false, double sideMargin = 0}) {
return Container(
margin: EdgeInsets.symmetric(horizontal: sideMargin),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Text(
label,
style: TextStyle(
color: isSelected ? Colors.white : Colors.grey,
fontSize: 30.rpx,
fontWeight: isSelected ? FontWeight.bold : FontWeight.normal,
),
),
),
if (isSelected) SizedBox(height: 15.rpx), // 保留间距,避免文字和线重叠
],
),
);
}
Widget _buildControlCards(BuildContext context) {
final spacing = 20.0.rpx;
final List<Map<String, dynamic>> allCards = [
{'title': '一键助眠', 'time': '30:00'},
{'title': '疲劳缓解', 'time': '20:00'},
{'title': '全身放松', 'time': '20:00'},
{'title': '背部律动', 'time': '10:00'},
{'title': '腿部律动', 'time': '30:00'},
{'title': '垂直律动', 'time': ''},
{'title': '加热', 'time': '30:00'},
{'title': '柔性唤醒', 'time': 'PM 08:00'},
{'title': '记忆', 'time': ''},
];
final firstRow = allCards.sublist(0, 3);
final restCards = allCards.sublist(3);
// 后续每行两个
List<List<Map<String, dynamic>>> chunkedRows = [];
for (int i = 0; i < restCards.length; i += 2) {
int end = (i + 2 < restCards.length) ? i + 2 : restCards.length;
chunkedRows.add(restCards.sublist(i, end));
}
return SingleChildScrollView(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 30.rpx, vertical: 30.rpx),
child: Column(
children: [
// 第一行:三个卡片
Row(
children: List.generate(firstRow.length * 2 - 1, (index) {
if (index.isOdd) {
return SizedBox(width: spacing); // 卡片间距
} else {
final item = firstRow[index ~/ 2];
return Expanded(
flex: 1,
child: _buildControlCard(
index ~/ 2,
item['title'],
item['time'],
// null, // 不再使用固定宽度
),
);
}
}),
),
SizedBox(height: spacing),
// 其余每行两个卡片
...chunkedRows.map((row) {
return Padding(
padding: EdgeInsets.only(bottom: spacing),
child: Row(
children: List.generate(row.length * 2 - 1, (index) {
if (index.isOdd) {
return SizedBox(width: spacing);
} else {
final item = row[index ~/ 2];
return Expanded(
flex: 1,
child: _buildControlCard(
index ~/ 2,
item['title'],
item['time'],
// null,
),
);
}
}),
),
);
}).toList(),
],
),
),
);
}
Widget _buildControlCard(
int index,
String title,
String time,
// double width,
) {
final controller = Get.find<ControlCardController>();
return Container(
// width: width,
height: 241.rpx,
decoration: BoxDecoration(
color: const Color(0xFF003058),
borderRadius: BorderRadius.circular(8),
),
padding: EdgeInsets.all(15.rpx),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
children: [
SvgPicture.asset(
'assets/img/icon/group.svg',
width: 60.rpx,
height: 60.rpx,
color: Colors.white,
),
SizedBox(height: 22.rpx),
Text(
title,
style: TextStyle(color: Colors.white, fontSize: 30.rpx),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
time,
style: TextStyle(
color: const Color(0XFF929699),
fontSize: 26.rpx,
fontFamily: 'PingFang SC',
),
),
Obx(() => FlutterSwitch(
width: 71.rpx,
height: 36.rpx,
toggleSize: 30.rpx,
activeColor: const Color(0XFF6BFDAC),
inactiveColor: const Color(0XFF011D33),
value: controller.switchStates[index].value,
onToggle: (val) {
controller.switchStates[index].value = val;
},
)),
],
),
],
),
);
}
}
class ControlCardController extends GetxController {
// 共9个卡片每个卡片有自己的开关状态
final List<RxBool> switchStates = List.generate(9, (index) => false.obs);
}

View File

@@ -0,0 +1,206 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/color/appFontsize.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/controller/mh/address_list_controller.dart';
import 'package:vbvs_app/pages/device_control/EmptyMessageWidget.dart';
import 'package:vbvs_app/pages/device_control/address_module_widget.dart';
class AddressListPage extends GetView<AddressListController> {
final scaffoldKey = GlobalKey<ScaffoldState>();
BoxConstraints? bodysize;
// AddressListPage() {
// controller.getAddressList();
// }
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, cc) {
bodysize = cc;
return GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/new_background.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: Colors.white),
titleSpacing: 0,
title: SizedBox(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
// 中间居中的标题
Text(
'地址管理',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 30.rpx,
),
),
// 左侧图标
Positioned(
left: 20.rpx,
child: returnIconButtomNew,
),
],
),
),
centerTitle: false,
),
body: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 1,
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Obx(() {
if (controller.model.addressList!.isEmpty) {
// 如果地址列表为空,显示 EmptyMessageWidget
return Expanded(
child: EmptyMessageWidget(),
);
} else {
// 如果地址列表不为空,显示地址列表
return Expanded(
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 1,
decoration: BoxDecoration(
color: Color(0xFFF6F6F6),
),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Align(
alignment: AlignmentDirectional(-1, 0),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
31, 27, 0, 26),
child: Text(
'我的地址',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
fontSize: AppFontsize.title_size,
letterSpacing: 0,
fontWeight: FontWeight.w600,
),
),
),
),
Expanded(
child: Obx(() => ListView(
shrinkWrap: true,
scrollDirection: Axis.vertical,
children: (controller.model.addressList!
.asMap()
.entries
.map((e) => AddressModuleWidget(
index: e.key,
addressListController:
controller,
))
.toList() as List<Widget>)
.divide(const SizedBox(height: 10))
.addToEnd(const SizedBox(
height: AppConstants
.list_end_height)),
)),
),
],
),
),
);
}
}),
Align(
alignment: AlignmentDirectional(0, 1),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(15, 15, 15,
AppConstants.page_button_bottom_padding),
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 0.056,
decoration: BoxDecoration(
// color: Color(0xFFF6F6F6),
border:
Border.all(width: 0, color: Color(0XFF85F5FF)),
borderRadius: BorderRadius.circular(12),
),
child: TextButton(
onPressed: () {
controller.model.address = {'isChecked': false};
controller.model.type = 1;
Get.toNamed("/editAddressPage");
},
style: TextButton.styleFrom(
backgroundColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
padding:
EdgeInsets.symmetric(horizontal: 24), // 按钮内边距
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Baseline(
baselineType: TextBaseline.alphabetic,
baseline: AppFontsize.normal_text_size *
1.6, // 调整基线位置
child: Text(
'+',
style: FlutterFlowTheme.of(context)
.titleSmall
.override(
fontFamily: 'Readex Pro',
color: Color(0xFF85F5FF),
fontSize:
AppFontsize.normal_text_size +
12, // 让加号比文字稍大
letterSpacing: 0,
),
),
),
SizedBox(width: 10), // 加号和文字间距
Text(
'添加新地址',
style: FlutterFlowTheme.of(context)
.titleSmall
.override(
fontFamily: 'Readex Pro',
color: Color(0xFF85F5FF),
fontSize: AppFontsize.normal_text_size,
letterSpacing: 0,
),
),
],
),
),
),
),
),
],
),
),
),
));
});
}
}

View File

@@ -0,0 +1,264 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:vbvs_app/controller/mh/address_list_controller.dart';
import '../../common/color/appFontsize.dart';
class AddressModuleWidget extends GetView {
final int index;
final AddressListController addressListController;
AddressModuleWidget({
required this.index,
required this.addressListController,
}) {}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: SlidableAutoCloseBehavior(
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(15, 0, 15, 0),
child: Container(
width: MediaQuery.sizeOf(context).width,
constraints: BoxConstraints(
minHeight: 100,
),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
),
child: Slidable(
endActionPane: ActionPane(
extentRatio: 0.26,
motion: ScrollMotion(),
children: [
Expanded(
child: InkWell(
onTap: () async {
// await addressListController.deleteAddress(
// addressListController.model.addressList[index]
// ['id']);
// addressListController.model.addressList.removeAt(index);
// addressListController.updateAll();
},
child: Container(
margin: EdgeInsets.only(left: 30),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.red,
),
alignment: Alignment.center,
child: Icon(
Icons.delete,
color: Colors.white,
),
),
),
)
],
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(15, 13, 15, 10),
child: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 0.123,
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 0.08,
constraints: BoxConstraints(
minHeight: 112,
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: MediaQuery.sizeOf(context).width * 0.7,
height:
MediaQuery.sizeOf(context).height * 0.08,
constraints: BoxConstraints(
minHeight: 112,
),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Flexible(
child: Align(
alignment: AlignmentDirectional(-1, 0),
child: Text(
[
addressListController.model
.addressList[index]['province'],
addressListController.model
.addressList[index]['city'],
addressListController.model
.addressList[index]['county'],
addressListController.model
.addressList[index]['street']
]
.where((element) =>
element != null &&
element.isNotEmpty)
.join(' '),
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Color(0xFF333333),
fontSize: AppFontsize
.normal_text_size,
letterSpacing: 0,
),
),
),
),
Flexible(
child: Align(
alignment: AlignmentDirectional(-1, 0),
child: Text(
addressListController
.model
.addressList[index]
['detail']
?.isEmpty ??
true
? '无详细地址'
: addressListController.model
.addressList[index]['detail'],
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Color(0xFF333333),
fontSize: AppFontsize
.normal_text_size,
letterSpacing: 0,
),
),
),
),
Flexible(
child: Align(
alignment: AlignmentDirectional(-1, 0),
child: Text(
'${addressListController.model.addressList[index]['name']} ' +
'${addressListController.model.addressList[index]['phone']} ',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Color(0xFF333333),
fontSize: AppFontsize
.normal_text_size,
letterSpacing: 0,
),
),
),
),
].divide(SizedBox(height: 5)),
),
),
Align(
alignment: AlignmentDirectional(1, -1),
child: Theme(
data: ThemeData(
checkboxTheme: CheckboxThemeData(
visualDensity: VisualDensity.compact,
materialTapTargetSize:
MaterialTapTargetSize.shrinkWrap,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(64),
),
),
unselectedWidgetColor: Color(0xFFD3D3D3),
),
child: Obx(() {
return Checkbox(
value: addressListController
.model.addressList[index]
['isChecked'] ??
false,
onChanged: (newValue) async {
// if (newValue == true) {
// for (var i = 0;
// i <
// addressListController
// .model.addressList.length;
// i++) {
// addressListController
// .model.addressList[i]
// ['isChecked'] = false;
// }
// addressListController
// .model.addressList[index]
// ['isChecked'] = newValue;
// addressListController.updateDefault(
// addressListController
// .model.addressList[index]);
// }
// addressListController.updateAll();
},
side: BorderSide(
width: 1.5,
color: FlutterFlowTheme.of(context)
.secondaryText,
),
activeColor: const Color(0xFFd3b684),
checkColor:
FlutterFlowTheme.of(context).info,
);
}),
),
)
],
),
),
),
Align(
alignment: AlignmentDirectional(1, 0),
child: InkWell(
onTap: () {
addressListController.model.address =
addressListController.model.addressList[index];
addressListController.model.type = 2;
Get.toNamed("/editAddressPage");
},
child: Container(
width: 100,
height: MediaQuery.sizeOf(context).height * 0.03,
child: Align(
alignment: AlignmentDirectional(1, 0),
child: Text(
'编辑',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Color(0xFF9EA4B7),
fontSize: AppFontsize.small_text_size,
letterSpacing: 0,
),
),
),
),
),
),
],
),
),
),
),
),
),
),
);
}
}

View File

@@ -0,0 +1,46 @@
// import 'package:map_launcher/map_launcher.dart';
// class AppMapLocation {
// static List<AvailableMap> availableMaps = [];
// static List availableMapsToNames = [];
// static Future<void> checkInstalledApps() async {
// availableMaps = await MapLauncher.installedMaps;
// availableMapsToNames = availableMaps.map((AvailableMap m) {
// String v = "";
// switch (m.mapType) {
// case MapType.baidu:
// v = '百度地图';
// break;
// case MapType.tencent:
// v = '腾讯地图';
// break;
// case MapType.amap:
// v = '高德地图';
// break;
// case MapType.apple:
// v = 'Apple地图';
// break;
// case MapType.google:
// v = 'Google地图';
// break;
// case MapType.googleGo:
// v = 'Google地图Go';
// break;
// case MapType.petal:
// v = 'Petal地图';
// break;
// default:
// v = m.mapName;
// }
// return v;
// }).toList();
// }
// static void launchMap(index, title, double latitude, double longitude) async {
// await availableMaps[index].showMarker(
// coords: Coords(latitude, longitude),
// title: title,
// );
// }
// }

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,188 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_svg/svg.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
class BluetoothPage extends StatefulWidget {
BluetoothPage({super.key});
@override
State<BluetoothPage> createState() => _BluetoothState();
}
BoxConstraints? bodysize;
class _BluetoothState extends State<BluetoothPage> {
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, cc) {
bodysize = cc;
return GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/new_background.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
backgroundColor: Colors.transparent,
iconTheme: const IconThemeData(color: Colors.white),
automaticallyImplyLeading: false,
titleSpacing: 0,
title: SizedBox(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
// 中间居中的标题
Text(
'设置',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 30.rpx,
),
),
// 左侧图标
Positioned(
left: 20.rpx,
child: returnIconButtomNew,
),
],
),
),
centerTitle: false,
),
body: SafeArea(
top: true,
child: Padding(
padding: EdgeInsets.fromLTRB(0.rpx, 115.rpx, 0.rpx, 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('TomFayer',
style: TextStyle(
color: Colors.white,
fontSize: 40.rpx,
)),
SizedBox(width: 27.rpx),
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: const Color(0xFF055466),
padding: EdgeInsets.only(left: 0),
onTap: () {
Get.toNamed("/editBedPage");
},
child: Container(
width: 42.rpx,
height: 42.rpx,
child: SvgPicture.asset(
"assets/img/icon/bluetooth_edit.svg",
color: Colors.white,
)))
],
),
const SizedBox(height: 4),
Text('MAC:4645146546',
style: TextStyle(
color: Colors.white70, fontSize: 26.rpx)),
const SizedBox(height: 16),
// 蓝牙连接状态
Column(
children: [
Image.asset(
'assets/images/active_bluetooth.png',
width: 42.rpx,
height: 42.rpx,
),
SizedBox(height: 4),
Text('已连接',
style: TextStyle(
color: Colors.green,
fontSize: 26.rpx)),
],
),
],
),
const SizedBox(height: 24),
// 按钮列表
Expanded(
child: ListView(
padding: EdgeInsets.symmetric(horizontal: 30.rpx),
children: [
_buildMenuButton(
context, '详情', "/devicePeopleInfo"),
_buildMenuButton(
context, '人员资料', "/devicePeopleInfo"),
_buildMenuButton(
context, '房间选择', "/roomPickerPage"),
_buildMenuButton(
context, '设备校准', "/devicePeopleInfo"),
_buildMenuButton(
context, '体征传感器', "/devicePeopleInfo"),
_buildMenuButton(
context, 'WIFI配置', "/devicePeopleInfo"),
_buildMenuButton(
context, '睡眠习惯', "/sleepHabitPage"),
_buildMenuButton(
context, '分享设备', "/devicePeopleInfo"),
_buildMenuButton(
context, '解绑', "/devicePeopleInfo"),
],
),
),
],
),
)),
)));
});
}
Widget _buildMenuButton(BuildContext context, String title, String? path) {
return Padding(
padding: EdgeInsets.only(bottom: 19.rpx), // 将 margin 外移
child: ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Color(0XFF055466),
padding: EdgeInsets.only(left: 0),
onTap: () {
if (path?.isNotEmpty == true) {
Get.toNamed(path!);
}
},
child: Container(
height: MediaQuery.sizeOf(context).height * 0.0566,
decoration: BoxDecoration(
color: const Color(0xFF003058),
borderRadius: BorderRadius.circular(16.rpx),
),
child: Center(
child: Text(
title,
style: const TextStyle(color: Colors.white, fontSize: 16),
),
),
),
),
);
}
}

View File

@@ -0,0 +1,87 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/controller/mh/book_info_controller.dart';
class BookDateWidget extends GetView<BookInfoController> {
// final String week;
// final String date;
// const BookDateWidget({
// super.key,
// String? week,
// String? date,
// }) : this.week = week ?? '周一',
// this.date = date ?? '07/10';
int index;
BookInfoController bookInfoController;
BookDateWidget({required this.index, required this.bookInfoController}) {}
@override
Widget build(BuildContext context) {
return InkWell(onTap: () {
// if(index == controller.model.datetimes_index) {
// return;
// }
// controller.model.datetimes_index = index;
// controller.time_periodChange();
// controller.updateAll();
}, child: Obx(() {
return Container(
width: 71.5,
height: 71.5,
constraints: BoxConstraints(
minHeight: 70,
),
decoration: BoxDecoration(
// color: FlutterFlowTheme.of(context).secondaryBackground,
color: controller.model.datetimes_index == index
? stringToColor('#D3B684')
: FlutterFlowTheme.of(context).secondaryBackground,
borderRadius: BorderRadius.circular(8),
),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Flexible(
child: Text(
"${bookInfoController.model.datetimes![index]?['dayName']}",
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Readex Pro',
letterSpacing: 0,
color: controller.model.datetimes_index == index
? stringToColor('#FFFFFF')
: stringToColor('#333333'),
),
),
),
Flexible(
child: Text(
"${bookInfoController.model.datetimes![index]?['day']}",
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Readex Pro',
letterSpacing: 0,
color: controller.model.datetimes_index == index
? stringToColor('#FFFFFF')
: stringToColor('#333333'),
),
),
),
Flexible(
child: Icon(
Icons.keyboard_arrow_down_rounded,
color: controller.model.datetimes_index == index
? stringToColor('#FFFFFF')
: stringToColor('#333333'),
size: 12,
),
),
],
),
);
}));
}
}

View File

@@ -0,0 +1,796 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/appColors.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/color/appFontsize.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/controller/mh/book_info_controller.dart';
import 'package:vbvs_app/pages/common/selectDialog.dart';
import 'package:vbvs_app/pages/device_control/book_date_widget.dart';
class BookInfoPage extends GetView<BookInfoController> {
final scaffoldKey = GlobalKey<ScaffoldState>();
Map data;
BookInfoPage({required this.data}) {
// controller.getData(data["id"]);
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/new_background.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
// key: scaffoldKey,
backgroundColor: Colors.transparent,
appBar: AppBar(
backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
iconTheme: const IconThemeData(color: Colors.white),
titleSpacing: 0,
title: Container(
width: double.infinity,
height: 70.rpx,
child: Stack(
alignment: Alignment.center,
children: [
// 中间居中的标题
Text(
'我要预约',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 30.rpx,
),
),
// 左侧图标
Positioned(
left: 20.rpx,
child: returnIconButtomNew,
),
],
),
),
actions: [],
centerTitle: false,
),
body: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 1,
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
// TitleComponentWidget(
// titleName: '我要预约',
// ),
Expanded(
child: Padding(
padding:
const EdgeInsetsDirectional.fromSTEB(28, 27, 28, 0),
child: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 1,
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
0, 0, 0, 10),
child: Container(
width: MediaQuery.sizeOf(context).width,
constraints: const BoxConstraints(
minHeight: 50,
),
child: Container(
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
'${data["name"]}',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
fontSize:
AppFontsize.title_size,
letterSpacing: 0,
fontWeight: FontWeight.w600,
color: Colors.white),
),
Text(
'地址:${data["addressDetail"]}',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
fontSize: AppFontsize
.normal_text_size,
letterSpacing: 0,
color: Colors.white),
),
],
),
),
),
),
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
0, 0, 0, 20),
child: Container(
width: MediaQuery.sizeOf(context).width,
height:
MediaQuery.sizeOf(context).height * 0.01,
constraints: const BoxConstraints(
maxHeight: 1,
),
decoration: const BoxDecoration(
color: Color(0xFF929699),
),
),
),
Align(
alignment: const AlignmentDirectional(-1, 0),
child: Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
0, 0, 0, 16),
child: Text(
'体验日期',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
fontSize: AppFontsize.title_size,
letterSpacing: 0,
fontWeight: FontWeight.w600,
color: Color(0xFF929699)),
),
),
),
Obx(() {
return Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: getBuildItems(context),
);
}),
// Obx(() => ListView(
// shrinkWrap: true,
// scrollDirection: Axis.horizontal,
// children: getBuildItems(context))),
// Padding(
// padding:
// EdgeInsetsDirectional.fromSTEB(0, 59, 0, 0),
// child: Row(
// mainAxisSize: MainAxisSize.max,
// mainAxisAlignment:
// MainAxisAlignment.spaceBetween,
// children: [
// Text(
// '体验时段',
// style: FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Readex Pro',
// fontSize: AppFontsize.title_size,
// letterSpacing: 0,
// ),
// ),
// Row(
// mainAxisSize: MainAxisSize.max,
// children: [
// Padding(
// padding: EdgeInsetsDirectional.fromSTEB(
// 0, 0, 17, 0),
// child: Text(
// '09:30',
// style: FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Readex Pro',
// fontSize:
// AppFontsize.title_size,
// letterSpacing: 0,
// ),
// ),
// ),
// Icon(
// Icons.keyboard_arrow_down_sharp,
// color: FlutterFlowTheme.of(context)
// .secondaryText,
// size: 12,
// ),
// ],
// ),
// ],
// ),
// ),
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
0, 59, 0, 0),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'体验时段',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
fontSize: AppFontsize.title_size,
letterSpacing: 0,
color: Color(0xFF929699),
// 设置加粗
),
),
Flexible(child: Obx(() {
return InkWell(
onTap: () {
showOneSelectionDialog(context,
arr: controller.model.time_period
.map((d) =>
"${d['timeStr']} (${d['unBookAmount']}/${d['amount']})")
.toList()!,
checkIndex: controller.model
.select_time_index ??
0, checkChange: (index) {
controller.model.select_time_index =
index;
controller.updateAll();
}, title: '请选择时间');
},
child: Container(
width: 140,
height: 30,
child: Row(
mainAxisAlignment:
MainAxisAlignment.end,
crossAxisAlignment:
CrossAxisAlignment
.center, // 确保图标和文本垂直居中
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding:
const EdgeInsetsDirectional
.fromSTEB(0, 3, 17, 0),
child: Text(
controller.model
.select_time_index !=
null
? "${controller.model.time_period?[controller.model.select_time_index!]?["timeStr"]}"
: '请选择时间',
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily:
'Readex Pro',
fontSize: AppFontsize
.normal_text_size,
letterSpacing: 0,
color: (controller
.model
.select_time_index ==
null)
? stringToColor(
'#D0D0D0')
: stringToColor(
'#333333')),
),
),
Icon(
Icons.keyboard_arrow_down_sharp,
color:
FlutterFlowTheme.of(context)
.secondaryText,
size: 16,
),
],
),
),
);
})),
],
),
),
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
0, 25, 0, 0),
child: Container(
width: MediaQuery.sizeOf(context).width,
height:
MediaQuery.sizeOf(context).height * 0.03,
constraints: BoxConstraints(
minHeight: 76.rpx,
),
decoration: const BoxDecoration(),
child: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height *
0.02,
decoration: const BoxDecoration(),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'体验人员',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
fontSize:
AppFontsize.title_size,
letterSpacing: 0,
color: Color(0xFF929699),
// 设置加粗
),
),
Flexible(
child: Align(
alignment:
const AlignmentDirectional(
1, 0),
child: Container(
width: MediaQuery.sizeOf(context)
.width *
0.3,
height: MediaQuery.sizeOf(context)
.height *
1,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(0),
),
child: Align(
alignment:
const AlignmentDirectional(
1, 0),
child: TextFormField(
// autofocus: true,
controller:
TextEditingController(
text: controller.model
.userName ??
""),
onChanged: (d) {
controller.model.userName =
d;
},
obscureText: false,
decoration: InputDecoration(
labelStyle:
FlutterFlowTheme.of(
context)
.labelMedium
.override(
fontFamily:
'Readex Pro',
fontSize: AppFontsize
.normal_text_size,
letterSpacing: 0,
),
hintText: '输入姓名',
hintStyle: FlutterFlowTheme
.of(context)
.labelMedium
.override(
fontFamily:
'Readex Pro',
fontSize: AppFontsize
.normal_text_size,
letterSpacing: 0,
color: Color(
0xFF929699)),
enabledBorder:
UnderlineInputBorder(
borderSide:
const BorderSide(
color:
Color(0x00000000),
width: 2,
),
borderRadius:
BorderRadius.circular(
8),
),
focusedBorder:
UnderlineInputBorder(
borderSide:
const BorderSide(
color:
Color(0x00000000),
width: 2,
),
borderRadius:
BorderRadius.circular(
8),
),
errorBorder:
UnderlineInputBorder(
borderSide:
const BorderSide(
color:
Color(0x00000000),
width: 2,
),
borderRadius:
BorderRadius.circular(
8),
),
focusedErrorBorder:
UnderlineInputBorder(
borderSide:
const BorderSide(
color:
Color(0x00000000),
width: 2,
),
borderRadius:
BorderRadius.circular(
8),
),
contentPadding:
const EdgeInsetsDirectional
.fromSTEB(
0, 0, 0, 12),
),
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily:
'Readex Pro',
fontSize: AppFontsize
.normal_text_size,
letterSpacing: 0,
),
textAlign: TextAlign.end,
),
),
),
),
),
],
),
),
),
),
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
0, 25, 0, 0),
child: Container(
width: MediaQuery.sizeOf(context).width,
height:
MediaQuery.sizeOf(context).height * 0.03,
constraints: BoxConstraints(
minHeight: 76.rpx,
),
decoration: const BoxDecoration(),
child: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height *
0.02,
decoration: const BoxDecoration(),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'手机号',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
fontSize:
AppFontsize.title_size,
letterSpacing: 0,
color: Color(0xFF929699),
// 设置加粗
),
),
Flexible(
child: Align(
alignment:
const AlignmentDirectional(
1, 0),
child: Container(
width: MediaQuery.sizeOf(context)
.width *
0.3,
height: MediaQuery.sizeOf(context)
.height *
1,
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(0),
),
child: Align(
alignment:
const AlignmentDirectional(
1, 0),
child: TextFormField(
// autofocus: true,
controller:
TextEditingController(
text: controller.model
.userPhone ??
""),
onChanged: (d) {
controller.model.userPhone =
d;
},
obscureText: false,
keyboardType:
TextInputType.phone,
decoration: InputDecoration(
labelStyle:
FlutterFlowTheme.of(
context)
.labelMedium
.override(
fontFamily:
'Readex Pro',
fontSize: AppFontsize
.normal_text_size,
letterSpacing: 0,
),
hintText: '输入手机号',
hintStyle: FlutterFlowTheme
.of(context)
.labelMedium
.override(
fontFamily:
'Readex Pro',
fontSize: AppFontsize
.normal_text_size,
letterSpacing: 0,
color: Color(
0xFF929699)),
enabledBorder:
UnderlineInputBorder(
borderSide:
const BorderSide(
color:
Color(0x00000000),
width: 2,
),
borderRadius:
BorderRadius.circular(
8),
),
focusedBorder:
UnderlineInputBorder(
borderSide:
const BorderSide(
color:
Color(0x00000000),
width: 2,
),
borderRadius:
BorderRadius.circular(
8),
),
errorBorder:
UnderlineInputBorder(
borderSide:
const BorderSide(
color:
Color(0x00000000),
width: 2,
),
borderRadius:
BorderRadius.circular(
8),
),
focusedErrorBorder:
UnderlineInputBorder(
borderSide:
const BorderSide(
color:
Color(0x00000000),
width: 2,
),
borderRadius:
BorderRadius.circular(
8),
),
contentPadding:
const EdgeInsetsDirectional
.fromSTEB(
0, 0, 0, 12),
),
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily:
'Readex Pro',
fontSize: AppFontsize
.normal_text_size,
letterSpacing: 0,
),
textAlign: TextAlign.end,
),
),
),
),
),
],
),
),
),
),
],
),
)),
),
),
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
15, 0, 15, AppConstants.page_button_bottom_padding),
child: CustomCard(
borderRadius: 10,
gradientDirection: GradientDirection.vertical,
onTap: () {
// if (controller.model.select_time_index == null) {
// showToast("请选择体验时间");
// return;
// }
// if (controller.model.userName == null ||
// controller.model.userName == "") {
// showToast("请输入姓名");
// return;
// }
// if (controller.model.userPhone == null ||
// controller.model.userPhone == "") {
// showToast("请输入手机号");
// return;
// }
// if (MyUtils.isValidPhoneNumber(
// controller.model.userPhone!) ==
// false) {
// showToast("请输入正确的手机号");
// return;
// }
// controller.submitData(data["id"]).then((d) {
// if (d.data["status"] == 2) {
// d.data["addressDetail"] = data['addressDetail'];
// d.data["name"] = data["name"];
// controller.messageAdd(d.data);
// Get.offAndToNamed("/bookSuccessPage",
// arguments: {"data": d.data});
// } else {
// showToast("预约失败");
// }
// }).catchError((d) {
// showToast("预约失败");
// });
Get.toNamed("/bookSuccessPage", arguments: {
"data": {
"id": "7fbfbd614ef5befa3d8a84730f666853",
"code": "10000114",
"orderSn": "2025051411302980610000114",
"userId": "09db8134288e8fb716c7acfdcca9f763",
"extUserId": null,
"deptId": 35,
"storeId": "962df2043ba06c99e6490616b37a60d4",
"customerId": "531ba6efe42d5e2cc3c8f219ebed4cee",
"idCard": null,
"realName": "江有龙",
"userPhone": "18956025450",
"province": "",
"city": "",
"district": "",
"addressDetail": "",
"bookType": 2,
"bookDateId": 104167,
"bookRoomNo": null,
"bookTimeStart": 1747281600000,
"bookTimeEnd": 1747303200000,
"payAmount": 0,
"transactionId": null,
"paid": 0,
"payTime": null,
"payType": null,
"status": 2,
"isVerify": false,
"verifyAdminId": null,
"verifyTime": null,
"giftAdminId": null,
"giftTime": null,
"createTime": 1747193430000,
"refundTime": null,
"isDel": false,
"audienceId": null,
"store": {
"id": "962df2043ba06c99e6490616b37a60d4",
"code": "55102",
"name": "合肥眠花糖共享会议华润大厦B座",
"deptId": 35,
"kingdeeId": ""
},
"dateStr": "2025年05月15日周四",
"timeStr": "12:00~18:00",
"qrCode": "",
"payName": "未付款",
"statusName": "待体验",
"user": {
"id": "09db8134288e8fb716c7acfdcca9f763",
"nickName": "生陌",
"avatar": null,
"mobile": "18956025450"
},
"verifyAdmin": null,
"giftAdmin": null,
"storeName": "合肥眠花糖共享会议华润大厦B座",
"storeAddress": null
},
});
},
colors: const [
Color(0xFFFCFCFC),
Color(0xFFF8FAF9),
Color(0XFFECF6F3),
Color(0XFFD9F0E9),
Color(0xFFCEECE3)
],
child: Container(
width: double.infinity,
height: 90.rpx,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
),
child: Text(
"提交预约",
style:
FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Readex Pro',
color: stringToColor("#011D33"),
letterSpacing: 0,
fontSize: 30.rpx,
),
),
),
)),
],
),
),
),
),
);
}
List<Widget> getBuildItems(BuildContext context) {
List<Widget> images = [];
controller.model.datetimes!.forEach((element) async {
images.add(BookDateWidget(
index: controller.model.datetimes!.indexOf(element),
bookInfoController: controller,
));
});
return images;
}
}

View File

@@ -0,0 +1,210 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/appColors.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
class BookSuccessPage extends GetView {
final scaffoldKey = GlobalKey<ScaffoldState>();
BoxConstraints? bodysize;
Map data;
BookSuccessPage({required this.data});
final infoList = [
{"label": "预约编号:", "value": "54648614654646"},
{"label": "预约人员:", "value": "张大大"},
{"label": "手机号码:", "value": "139****5699"},
{"label": "体验时间:", "value": "2024-02-15 07:30"},
{"label": "预约门店:", "value": "SWES眠花糖杭州南星桥旗舰店"},
{"label": "门店地址:", "value": "浙江省杭州市上城区飞云江路45号一层"},
];
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, cc) {
bodysize = cc;
return GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/new_background.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
// key: scaffoldKey,
backgroundColor: Colors.transparent,
appBar: AppBar(
backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: Colors.white),
titleSpacing: 0,
// leading: returnIconButtomAddCallback(() {
// controller.saveDataApi();
// updateParm(isShowToast: false);
// }),
// leading: returnIconButtomNew,
title: Container(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
// 中间居中的标题
Text(
'我要预约',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 30.rpx,
),
),
// 左侧图标
Positioned(
left: 20.rpx,
child: returnIconButtomNew,
),
],
),
),
actions: [],
centerTitle: false,
),
body: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 1,
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: bodysize!.maxWidth,
margin: EdgeInsets.only(top: 90.rpx),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: 148.rpx,
height: 148.rpx,
clipBehavior: Clip.antiAlias,
decoration: const BoxDecoration(
shape: BoxShape.circle,
),
child: Image.asset(
'assets/images/success.png',
fit: BoxFit.contain,
color: Color(0xFF84F5FF),
),
),
Align(
alignment: const AlignmentDirectional(0, 0),
child: Text(
'预约成功!',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
fontSize: 30.rpx,
color: Colors.white,
letterSpacing: 0,
fontWeight: FontWeight.w600,
),
),
),
].divide(SizedBox(height: 30.rpx)),
),
),
Container(
margin: EdgeInsets.only(
left: 30.rpx, right: 30.rpx, top: 55.rpx),
width: bodysize!.maxWidth,
decoration: BoxDecoration(
color: Color(0xFF003058),
borderRadius: BorderRadius.circular(16.rpx),
),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 20), // 上间距
for (var item in infoList)
Container(
height: 60.rpx,
padding: EdgeInsets.symmetric(horizontal: 35),
alignment: Alignment.centerLeft,
child: Row(
children: [
Text(
item['label']!,
style: TextStyle(
color: Color(0XFF929699),
fontSize: 26.rpx,
),
),
SizedBox(width: 35.rpx),
Text(
item['value']!,
style: TextStyle(
color: Colors.white,
fontSize: 26.rpx,
),
),
],
),
),
SizedBox(height: 60.rpx), // 空间隔断
Padding(
padding: EdgeInsets.symmetric(horizontal: 35),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 200.rpx,
height: 60.rpx,
child: ElevatedButton(
onPressed: () {},
child: Text("关闭",
style: TextStyle(
color: Color(0XFF011D33),
fontSize: 26.rpx)),
style: ElevatedButton.styleFrom(
backgroundColor: Color(0xFF84F5FF),
// minimumSize: Size(0, 60),
),
),
),
SizedBox(width: 60.rpx),
SizedBox(
width: 200.rpx,
height: 60.rpx,
child: ElevatedButton(
onPressed: () {},
child: Text("我的预约",
style: TextStyle(
color: Color(0XFF011D33),
fontSize: 26.rpx)),
style: ElevatedButton.styleFrom(
backgroundColor: Color(0xFF84F5FF),
// minimumSize: Size(0, 60),
),
),
)
],
),
),
SizedBox(height: 80), // 下间距
],
)),
),
],
),
),
),
));
});
}
}

View File

@@ -0,0 +1,328 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/color/appFontsize.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
class DeletedAccountPage extends GetView {
BoxConstraints? bodysize;
final scaffoldKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, cc) {
bodysize = cc;
return GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/new_background.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
iconTheme: const IconThemeData(color: Colors.white),
titleSpacing: 0,
title: SizedBox(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
// 中间居中的标题
Text(
'注销账号',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 30.rpx,
),
),
// 左侧图标
Positioned(
left: 20.rpx,
child: returnIconButtomNew,
),
],
),
),
centerTitle: false,
),
key: scaffoldKey,
backgroundColor: Colors.transparent,
body: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 1,
decoration: const BoxDecoration(),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: Container(
width: MediaQuery.sizeOf(context).width,
height: 100,
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(
15, 33, 15, 0),
child: Container(
width: MediaQuery.sizeOf(context).width,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
),
child: Padding(
padding:
const EdgeInsetsDirectional.fromSTEB(
21, 0, 22, 0),
child: Container(
width: MediaQuery.sizeOf(context).width,
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
crossAxisAlignment:
CrossAxisAlignment.center,
children: [
Container(
width: 50,
height: 50,
child: Image.asset(
'assets/images/delete_account.png',
fit: BoxFit.cover,
color: Color(0XFF84F5FF),
),
),
const Text(
"注销智慧眠花糖账号",
style: TextStyle(
fontSize: 20, // 设置字体大小
color: Color(0xFFFFFFFF),
// decoration: TextDecoration.underline, // 添加下划线
),
),
Container(
child: Column(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
RichText(
text: TextSpan(
text: "账号注销后,你将无法使用以下功能,",
style: TextStyle(
fontSize: AppFontsize
.normal_text_size, // 设置字体大小
color: Color(
0xFF9AA0B3), // 默认颜色
),
children: [
TextSpan(
text:
"并且当前有绑定以及被分享的智能床、智能床垫等设备的账号不能注销",
style: TextStyle(
fontSize: AppFontsize
.normal_text_size,
color: const Color(
0xFFFF7159), // 设置为#E45E91的颜色
),
),
TextSpan(
text:
",可先进行解绑后再进行注销操作。",
style: TextStyle(
fontSize: AppFontsize
.normal_text_size,
color:
Color(0xFF9AA0B3),
),
),
],
),
),
const SizedBox(
height: 24,
),
Text(
"无法控制智能床、智能床垫等设备",
style: TextStyle(
fontSize: AppFontsize
.title_size, // 设置字体大小
color:
const Color(0xFFFFFFFF),
),
),
const SizedBox(
height: 6,
),
Text(
"你将无法控制你的智能床、智能床垫等设备,以及与其相关的各种操作。",
style: TextStyle(
fontSize: AppFontsize
.normal_text_size, // 设置字体大小
color: Color(0xFF9AA0B3),
),
),
const SizedBox(
height: 24,
),
Text(
"无法查询睡眠报告和体征数据",
style: TextStyle(
fontSize: AppFontsize
.title_size, // 设置字体大小
color:
const Color(0xFFFFFFFF),
),
),
const SizedBox(
height: 6,
),
Text(
"注销账号后你将查询不到你以前的睡眠报告和实时数据。",
style: TextStyle(
fontSize: AppFontsize
.normal_text_size, // 设置字体大小
color: Color(0xFF9AA0B3),
),
),
const SizedBox(
height: 24,
),
Text(
"无法使用的其他功能",
style: TextStyle(
fontSize: AppFontsize
.title_size, // 设置字体大小
color:
const Color(0xFFFFFFFF),
),
),
const SizedBox(
height: 6,
),
Text(
"包含设备报修、门店体验预约等。",
style: TextStyle(
fontSize: AppFontsize
.normal_text_size, // 设置字体大小
color: Color(0xFF9AA0B3),
),
),
],
)),
]
.divide(
const SizedBox(height: 24))
.addToStart(
const SizedBox(height: 14))
.addToEnd(
const SizedBox(height: 17)),
),
),
),
),
),
),
],
),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
15, 0, 15, AppConstants.page_button_bottom_padding),
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 0.056,
// decoration: BoxDecoration(
// color:
// FlutterFlowTheme.of(context).secondaryBackground,
// ),
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 0.056,
decoration: BoxDecoration(
// color: FlutterFlowTheme.of(context)
// .secondaryBackground,
borderRadius: BorderRadius.circular(12),
),
child: FFButtonWidget(
onPressed: () async {
// showCustomConfirmDialog(context, "是否确认注销?")
// .then((v) async {
// if (v != "confirm") {
// return;
// }
// LoginController loginController = Get.find();
// UserInfoController userInfoController =
// Get.find<UserInfoController>();
// var code = await loginController.deletedAccount();
// if (code != null && code == 1) {
// final box = GetStorage();
// box.remove('user');
// box.remove('token');
// userInfoController.model.token = null;
// userInfoController.model.user = null;
// userInfoController.model.login = 0;
// userInfoController.model.message = 0;
// GlobalController globalController =
// Get.find<GlobalController>();
// globalController.resetParmAll();
// Get.offAllNamed("/loginPage");
// }
// });
},
text: '注销账号',
options: FFButtonOptions(
height: 40,
padding: const EdgeInsetsDirectional.fromSTEB(
24, 0, 24, 0),
iconPadding: const EdgeInsetsDirectional.fromSTEB(
0, 0, 0, 0),
color: const Color(0xFFFF7159),
textStyle: FlutterFlowTheme.of(context)
.titleSmall
.override(
fontFamily: 'Readex Pro',
color: Colors.white,
fontSize: AppFontsize.normal_text_size,
letterSpacing: 0,
),
elevation: 0,
borderSide: const BorderSide(
color: Colors.transparent,
width: 1,
),
borderRadius: BorderRadius.circular(8),
),
),
),
),
),
],
),
),
),
));
});
}
Future<void> _copyToClipboard(String text) async {
await Clipboard.setData(ClipboardData(text: text));
}
}

View File

@@ -0,0 +1,266 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/base/THFlutterFlowDropDown.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
class DevicePeopleInfo extends StatelessWidget {
DevicePeopleInfo({super.key});
get glController => Get.find<GlobalController>();
get bodyData => glController.model.mainDevicePeople;
getInfoRow(context, String str) {
return Container(
width: double.infinity,
height: 60.rpx,
decoration: BoxDecoration(),
alignment: Alignment.centerLeft,
child: Text(
'$str',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Readex Pro',
color: Colors.white,
fontSize: 26.rpx,
letterSpacing: 0,
),
),
);
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, boxConstraints) => GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/new_background.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: Colors.white),
titleSpacing: 0,
title: AppBar(
backgroundColor: Colors.transparent,
iconTheme: const IconThemeData(color: Colors.white),
automaticallyImplyLeading: false,
titleSpacing: 0,
title: SizedBox(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
// 中间居中的标题
Text(
'详情',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 30.rpx,
),
),
// 左侧图标
Positioned(
left: 20.rpx,
child: returnIconButtomNew,
),
],
),
),
centerTitle: false,
),
actions: [],
centerTitle: false,
),
body: SafeArea(
top: true,
child: Obx(
() => Container(
padding: EdgeInsets.only(
left: 30.rpx, right: 30.rpx, top: 30.rpx),
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 1.123,
// decoration: BoxDecoration(
// // color: AppColors.bg_color,
// image: DecorationImage(
// image: AssetImage("assets/images/background.png"),
// fit: BoxFit.cover,
// ),
// ),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
ClickableContainer(
backgroundColor: Color(0xFF003058),
highlightColor: Color(0xFF036060),
borderRadius: 16.rpx,
padding: EdgeInsets.fromLTRB(
30.rpx, 20.rpx, 0, 20.rpx),
onTap: () {},
child: Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(16.rpx)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
alignment: Alignment.centerLeft,
child: Text(
'设备信息',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Colors.white,
fontSize: 30.rpx,
),
),
),
getInfoRow(context,
"名称:${glController.getDeviceGroupName2(glController.model.deviceMain)}"),
getInfoRow(context,
"房间:${glController.model.deviceMain["roomName"] ?? "-"}"),
getInfoRow(context,
"网络:${glController.model.deviceMain["status"] ?? "-"}"),
getInfoRow(context,
"MAC${glController.model.deviceMain["mac"] ?? "-"}"),
],
),
)),
...List.generate(
"${glController.model.deviceMain["bindMacB"]}"
.length >
6
? 2
: 1, (index) {
String location_ = "";
if ("${glController.model.deviceMain["bindMacB"]}"
.length >
6 &&
(glController.model.mainDevicePeople[0]
?["direction"] ==
1 ||
glController.model.mainDevicePeople[1]
?["direction"] ==
1)) {
location_ =
"${glController.model.mainDevicePeople[index]?["direction"] == 1 ? '左侧' : '右侧'}";
}
// return Container(
// decoration: BoxDecoration(
// color: Color(0xFF003058),
// borderRadius: BorderRadius.circular(16.rpx),
// ),
// child: Padding(
// padding: EdgeInsets.symmetric(
// horizontal: 30.rpx),
// child: Column(
// children: [
// Container(
// width: double.infinity,
// margin: EdgeInsets.only(
// bottom: 30.rpx, top: 50.rpx),
// decoration: BoxDecoration(),
// child: Text(
// '人员资料${index == 0 ? "A" : "B"}',
// style: FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Readex Pro',
// color: Colors.white,
// fontSize: 32.rpx,
// letterSpacing: 0,
// ),
// ),
// ),
// if (location_.isNotEmpty)
// getInfoRow(
// context, "校准位置:$location_"),
// getInfoRow(context,
// "姓名:${bodyData[index]["name"] ?? "-"}"),
// getInfoRow(context,
// "性别:${bodyData[index]["gender"] == null ? "-" : (bodyData[index]["gender"] == 1 ? "男" : "女")}"),
// getInfoRow(context,
// "身高:${bodyData[index]["height"] == null ? "-" : "${bodyData[index]["height"]}cm"}"),
// getInfoRow(context,
// "体重:${bodyData[index]["weight"] == null ? "-" : "${bodyData[index]["weight"]}kg"}"),
// getInfoRow(context,
// "生日:${bodyData[index]["birthday"] == null ? "-" : (time_08_Formatter_pattern(bodyData[index]["birthday"], "yyyy年MM月dd日"))}"),
// getInfoRow(context,
// "电话:${bodyData[index]["tel"] ?? "-"}"),
// getInfoRow(context,
// "紧急联系人:${bodyData[index]["contact"] ?? "-"}"),
// ],
// )));
return ClickableContainer(
backgroundColor: Color(0xFF003058),
highlightColor: Color(0xFF036060),
borderRadius: 16.rpx,
padding: EdgeInsets.fromLTRB(
30.rpx, 20.rpx, 30.rpx, 20.rpx),
onTap: () {},
child: Column(
children: [
Container(
width: double.infinity,
alignment: Alignment.centerLeft,
child: Text(
'人员资料${index == 0 ? "A" : "B"}',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Colors.white,
fontSize: 32.rpx,
letterSpacing: 0,
),
),
),
if (location_.isNotEmpty)
getInfoRow(context, "校准位置:$location_"),
getInfoRow(context,
"姓名:${bodyData[index]["name"] ?? "-"}"),
getInfoRow(context,
"性别:${bodyData[index]["gender"] == null ? "-" : (bodyData[index]["gender"] == 1 ? "" : "")}"),
getInfoRow(context,
"身高:${bodyData[index]["height"] == null ? "-" : "${bodyData[index]["height"]}cm"}"),
getInfoRow(context,
"体重:${bodyData[index]["weight"] == null ? "-" : "${bodyData[index]["weight"]}kg"}"),
getInfoRow(context,
"生日:${bodyData[index]["birthday"] == null ? "-" : (time_08_Formatter_pattern(bodyData[index]["birthday"], "yyyy年MM月dd日"))}"),
getInfoRow(context,
"电话:${bodyData[index]["tel"] ?? "-"}"),
getInfoRow(context,
"紧急联系人:${bodyData[index]["contact"] ?? "-"}"),
],
),
);
})
].divide(SizedBox(
height: 25.rpx,
)),
),
),
),
),
),
),
)),
);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,203 @@
import 'package:ef/base/widget/flutterflow/FlutterFlowTheme.dart';
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart';
class EditBedPage extends StatefulWidget {
const EditBedPage({Key? key}) : super(key: key);
@override
_EditBedPageState createState() => _EditBedPageState();
}
BoxConstraints? bodysize;
RxString _bedName = "".obs;
class _EditBedPageState extends State<EditBedPage> {
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, cc) {
bodysize = cc;
return GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/new_background.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
backgroundColor: Colors.transparent,
iconTheme: const IconThemeData(color: Colors.white),
automaticallyImplyLeading: false,
titleSpacing: 0,
title: SizedBox(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
// 中间居中的标题
Text(
'智能床名称',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 30.rpx,
),
),
// 左侧图标
Positioned(
left: 20.rpx,
child: returnIconButtomNew,
),
],
),
),
centerTitle: false,
),
body: SafeArea(
top: true,
child: Padding(
padding: EdgeInsets.only(top: 40.rpx),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: bodysize!.maxHeight * 1,
height: bodysize!.maxHeight * 0.335,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
child:
Image.asset('assets/images/bed_name.png'),
width: bodysize!.maxWidth * 0.69,
height: 193.rpx,
),
Padding(
padding:
EdgeInsets.symmetric(horizontal: 60.rpx),
child: Container(
alignment: Alignment.center,
height: bodysize!.maxHeight * 0.076,
decoration: const BoxDecoration(
border: Border(
bottom: BorderSide(
color: Color(0xFF929699),
width: 0))),
child: TextFormField(
// autofocus: true,
obscureText: false,
onChanged: (val) {
// controller.model.name = val;
},
textAlign: TextAlign.center,
initialValue: _bedName.value,
decoration: InputDecoration(
hintText: "请输入床的名称",
contentPadding:
const EdgeInsetsDirectional
.fromSTEB(10, 0, 10, 0),
labelStyle: FlutterFlowTheme.of(context)
.labelMedium
.override(
fontFamily: 'Readex Pro',
letterSpacing: 0,
fontSize: 36.rpx, // 设置输入文字大小
color: Colors.white, // 设置输入文字颜色
),
hintStyle: FlutterFlowTheme.of(context)
.labelMedium
.override(
fontFamily: 'Readex Pro',
letterSpacing: 0,
color: Color(0xFF929699),
fontSize: 36.rpx,
),
enabledBorder: UnderlineInputBorder(
borderSide: const BorderSide(
color: Color(0x00000000),
width: 2,
),
borderRadius:
BorderRadius.circular(8),
),
focusedBorder: UnderlineInputBorder(
borderSide: const BorderSide(
color: Color(0x00000000),
width: 2,
),
borderRadius:
BorderRadius.circular(8),
),
errorBorder: UnderlineInputBorder(
borderSide: const BorderSide(
color: Color(0x00000000),
width: 2,
),
borderRadius:
BorderRadius.circular(8),
),
focusedErrorBorder:
UnderlineInputBorder(
borderSide: const BorderSide(
color: Color(0x00000000),
width: 2,
),
borderRadius:
BorderRadius.circular(8),
),
),
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
letterSpacing: 0,
),
),
))
],
),
),
Padding(
padding: EdgeInsets.only(
left: 30.rpx, right: 30.rpx, bottom: 85.rpx),
child: CustomCard(
borderRadius: 10,
gradientDirection: GradientDirection.vertical,
onTap: () {},
colors: const [
Color(0xFFFCFCFC),
Color(0xFFF8FAF9),
Color(0XFFECF6F3),
Color(0XFFD9F0E9),
Color(0xFFCEECE3)
],
child: Container(
width: double.infinity,
height: 90.rpx,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
),
child: Text("完成",
style: TextStyle(
color: const Color(0xFF003058),
fontSize: 26.rpx)),
),
))
],
))),
),
),
);
});
}
}

View File

@@ -0,0 +1,205 @@
import 'package:ef/base/widget/flutterflow/FlutterFlowTheme.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart';
import '../../controller/mh/muser_info_controller.dart';
class EditUserInfoPage extends GetView<MUserInfoController> {
final scaffoldKey = GlobalKey<ScaffoldState>();
// EditUserInfoPage() {
// UserInfoController controller = Get.find();
// controller.model.user!.tmpHead = controller.model.user!.head;
// }
@override
Widget build(BuildContext context) {
// UserInfoController controller = Get.find();
return GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/new_background.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
backgroundColor: Colors.transparent,
key: scaffoldKey,
appBar: AppBar(
backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: Colors.white),
titleSpacing: 0,
title: Container(
width: double.infinity,
height: 70.rpx,
child: Stack(
alignment: Alignment.center,
children: [
// 中间居中的标题
Text(
'编辑资料',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 30.rpx,
),
),
// 左侧图标
Positioned(
left: 20.rpx,
child: returnIconButtomNew,
),
Positioned(
right: 30.rpx,
child: CustomCard(
borderRadius: 10,
gradientDirection: GradientDirection.vertical,
onTap: () {},
colors: const [
Color(0xFFFCFCFC),
Color(0xFFF8FAF9),
Color(0XFFECF6F3),
Color(0XFFD9F0E9),
Color(0xFFCEECE3)
],
child: Container(
width: 120.rpx,
height: 60.rpx,
alignment: Alignment.center,
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(5),
// color: stringToColor("#182B7C"),
// ),
child: Text(
"保存",
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: stringToColor("#9EA4B7"),
letterSpacing: 0,
fontSize: 30.rpx,
),
),
),
))
],
),
),
centerTitle: false,
),
body: Container(
width: double.infinity,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(top: 108.rpx),
child: Container(
width: 160.rpx,
height: 160.rpx,
clipBehavior: Clip.antiAlias,
decoration: const BoxDecoration(
shape: BoxShape.circle,
),
child: Image.asset(
"assets/images/people_avatar.png",
fit: BoxFit.cover,
),
),
),
Padding(
padding: EdgeInsets.only(top: 44.rpx),
child: Text(
'点击更换头像',
style:
TextStyle(color: Color(0XFF85F5FF), fontSize: 26.rpx),
),
),
Padding(
padding:
EdgeInsets.fromLTRB(60.rpx, 122.rpx, 60.rpx, 0.rpx),
child: Container(
width: double.infinity,
height: 88.rpx,
decoration: BoxDecoration(
border: Border(
top: BorderSide(
color: Color(0xFFD3D3D3), width: 2.rpx), // 上边线
bottom: BorderSide(
color: Color(0xFFD3D3D3), width: 2.rpx), // 下边线
),
),
alignment: Alignment(0, 0),
child: Text(
'玛利亚',
style: TextStyle(
color: Color(0XFFFFFFFF), fontSize: 26.rpx),
),
),
),
],
),
),
),
));
}
// Widget getImageWidget(BuildContext context) {
// try {
// UserInfoController controller = Get.find();
// var head = controller.model.user!.tmpHead;
// return InkWell(
// onTap: () {
// controller.uploadImg();
// },
// child: Row(
// children: [
// Container(
// width: 50,
// height: 50,
// decoration: BoxDecoration(
// color: FlutterFlowTheme.of(context).secondaryBackground,
// ),
// child: Container(
// width: 120,
// height: 120,
// clipBehavior: Clip.antiAlias,
// decoration: BoxDecoration(
// shape: BoxShape.circle,
// ),
// child: head == null || head.isEmpty
// ? Image.asset(
// 'assets/images/avatar.png',
// fit: BoxFit.cover,
// )
// : Image.network(
// "${getStorageResourceUrl(head)}",
// fit: BoxFit.cover,
// ),
// ),
// ),
// SizedBox(width: 10),
// Icon(
// Icons.arrow_forward_ios,
// color: Color(0xFF373737),
// size: 12,
// ),
// ],
// ),
// );
// } catch (e) {
// print(e);
// }
// return Container();
// }
}

View File

@@ -0,0 +1,454 @@
import 'dart:async';
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/appColors.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/color/appFontsize.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/controller/mh/experience_store_list_page.dart';
import 'package:vbvs_app/pages/device_control/Empty.dart';
import 'package:vbvs_app/pages/device_control/experience_store_widget.dart';
import 'package:vbvs_app/pages/device_control/searchWidget.dart';
class ExperienceStorePage extends GetView<ExperienceStoreListController> {
ExperienceStorePage({super.key});
// class _ExperienceStorePageState extends State<ExperienceStorePage> {
// get controller => Get.find<ExperienceStoreListController>();
// final scaffoldKey = GlobalKey<ScaffoldState>();
BoxConstraints? bodysize;
ScrollController scrollController = ScrollController();
ExperienceStoreListController controller = Get.find();
int runTime = 0;
// @override
// void initState() {
// // TODO: implement initState
// super.initState();
// Timer(Duration(milliseconds: 100), () async {
// controller.resetParm();
// await controller.determinePosition();
// controller.page = 0;
// controller.getData();
// scrollController.addListener(() {
// int ctime = DateTime.now().millisecondsSinceEpoch;
// if (ctime - runTime > 100 &&
// scrollController.position.pixels + 80 >
// scrollController.position.maxScrollExtent) {
// runTime = ctime;
// print(
// "bottom get more data ${scrollController.position.pixels} ${scrollController.position.maxScrollExtent}");
// controller.getData();
// }
// });
// });
// }
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, cc) {
controller.model.experienceStoreModelList = [
{
"id": "5b82d1d9c33c74647e7624ec1db7918f",
"enabled": true,
"code": "3401002",
"name": "SWES眠花糖合肥省委大院体验店",
"customerId": null,
"setNetCustomerKid": null,
"customer": null,
"kingdeeId": "",
"channel": null,
"salePersonId": "ed648f977422a9f32a05b4892a3cb529",
"salePerson": null,
"deptId": 3,
"deptName": null,
"dept": null,
"introduction": "",
"mobile": "18156022846",
"hotline": "0551-64464894",
"city": "合肥市",
"district": "庐阳区",
"addressDetail": "合肥市庐阳区逍遥津街道南含山路与红星路交汇处",
"image": "",
"latitude": "31.858934",
"longitude": "117.282166",
"isDel": false,
"isAppShow": true,
"business": true,
"authEndTime": null,
"createTime": 1701133326000,
"createAdminId": "f6da6faa2d50e7eff7b54bcdd55b0283",
"updateTime": 1709193588000,
"updateAdminId": null,
"distance": 2.2
},
{
"id": "97603deebb83f610f73acf5d0def2bce",
"enabled": true,
"code": "3401003",
"name": "SWES眠花糖合肥安粮国贸体验店",
"customerId": null,
"setNetCustomerKid": null,
"customer": null,
"kingdeeId": "",
"channel": null,
"salePersonId": "69297c65588adde4ee5de3c43a2c4033",
"salePerson": null,
"deptId": 3,
"deptName": null,
"dept": null,
"introduction": "",
"mobile": "18655643429",
"hotline": "0551-65156985",
"city": "合肥市",
"district": "政务新区",
"addressDetail": "安徽省合肥市蜀山区合作化南路16号",
"image": "",
"latitude": "31.82018",
"longitude": "117.25367",
"isDel": false,
"isAppShow": true,
"business": true,
"authEndTime": null,
"createTime": 1701133473000,
"createAdminId": "f6da6faa2d50e7eff7b54bcdd55b0283",
"updateTime": 1709193752000,
"updateAdminId": null,
"distance": 3.5
},
{
"id": "b6b588d7ff6b248115ee3e5951cf39a1",
"enabled": true,
"code": "3301001",
"name": "SWES眠花糖杭州南星桥旗舰店",
"customerId": null,
"setNetCustomerKid": null,
"customer": null,
"kingdeeId": "",
"channel": null,
"salePersonId": "f3a5e7935f65e94bc5aa6b2d63211e61",
"salePerson": null,
"deptId": 33,
"deptName": null,
"dept": null,
"introduction": "",
"mobile": "15222919097",
"hotline": "0571-86718606",
"city": "杭州市",
"district": "上城区",
"addressDetail": "浙江省杭州市上城区飞云江路45号一层102室",
"image": "",
"latitude": "30.21667",
"longitude": "120.17757",
"isDel": false,
"isAppShow": true,
"business": true,
"authEndTime": null,
"createTime": 1701135379000,
"createAdminId": "f6da6faa2d50e7eff7b54bcdd55b0283",
"updateTime": 1709194185000,
"updateAdminId": null,
"distance": 332.1
},
{
"id": "38fdbb715dc7bfddae3e32685c288e49",
"enabled": true,
"code": "3102001",
"name": "SWES眠花糖上海复兴荟旗舰店",
"customerId": null,
"setNetCustomerKid": null,
"customer": null,
"kingdeeId": "",
"channel": null,
"salePersonId": "4ae944badb423197bc54c0a6ec252944",
"salePerson": null,
"deptId": 32,
"deptName": null,
"dept": null,
"introduction": "",
"mobile": "13053037959",
"hotline": "021-63391962",
"city": "上海市",
"district": "黄浦区",
"addressDetail": "上海市黄浦区复兴东路1108号1层-1室",
"image": "",
"latitude": "31.22209",
"longitude": "121.494667",
"isDel": false,
"isAppShow": true,
"business": true,
"authEndTime": null,
"createTime": 1701135192000,
"createAdminId": "f6da6faa2d50e7eff7b54bcdd55b0283",
"updateTime": 1709194151000,
"updateAdminId": null,
"distance": 407.3
},
{
"id": "af908e6c5d1a2c8113b1c73117e15064",
"enabled": true,
"code": "3101001",
"name": "SWES眠花糖上海外滩九里体验店",
"customerId": null,
"setNetCustomerKid": null,
"customer": null,
"kingdeeId": "",
"channel": null,
"salePersonId": "1794f729f27ad4a44afad10061446dd5",
"salePerson": null,
"deptId": 31,
"deptName": null,
"dept": null,
"introduction": "",
"mobile": "13856414205",
"hotline": "021-63391208",
"city": "上海市",
"district": "黄浦区",
"addressDetail": "上海市黄浦区紫霞路103-107号1层103-12室",
"image": "",
"latitude": "31.218434",
"longitude": "121.502098",
"isDel": false,
"isAppShow": true,
"business": true,
"authEndTime": null,
"createTime": 1701134886000,
"createAdminId": "f6da6faa2d50e7eff7b54bcdd55b0283",
"updateTime": 1709194053000,
"updateAdminId": null,
"distance": 408.1
},
{
"id": "a5f1fc9a03ba827841c473e28a3fcdb2",
"enabled": true,
"code": "3101002",
"name": "SWES眠花糖上海尚悦湾旗舰店",
"customerId": null,
"setNetCustomerKid": null,
"customer": null,
"kingdeeId": "",
"channel": null,
"salePersonId": "d97ec48ee3b1060eb7ff5c81f0ffa37f",
"salePerson": null,
"deptId": 31,
"deptName": null,
"dept": null,
"introduction": "",
"mobile": "19523660595",
"hotline": "021-63336707",
"city": "上海市",
"district": "浦东新区",
"addressDetail": "上海市浦东新区银城路66号",
"image": "",
"latitude": "31.24103",
"longitude": "121.51045",
"isDel": false,
"isAppShow": true,
"business": true,
"authEndTime": null,
"createTime": 1701135694000,
"createAdminId": "f6da6faa2d50e7eff7b54bcdd55b0283",
"updateTime": 1709194087000,
"updateAdminId": null,
"distance": 408.4
},
{
"id": "21ddfb547060e930f841605dc4469bec",
"enabled": true,
"code": "1101001",
"name": "SWES眠花糖北京富力城旗舰店",
"customerId": null,
"setNetCustomerKid": null,
"customer": null,
"kingdeeId": "",
"channel": null,
"salePersonId": "b66028a628ce0fcb871ab7db5c17128e",
"salePerson": null,
"deptId": 11,
"deptName": null,
"dept": null,
"introduction": "",
"mobile": "15556119960",
"hotline": "010-58766288",
"city": "北京市",
"district": "朝阳区",
"addressDetail": "北京市朝阳区天力街3号楼1至2层商业12号",
"image": "",
"latitude": "39.89862",
"longitude": "116.45851",
"isDel": false,
"isAppShow": false,
"business": true,
"authEndTime": null,
"createTime": 1701134049000,
"createAdminId": "f6da6faa2d50e7eff7b54bcdd55b0283",
"updateTime": 1733193484000,
"updateAdminId": null,
"distance": 897.7
},
{
"id": "432bfdf508115827c5dca474b72dea68",
"enabled": true,
"code": "1102001",
"name": "SWES眠花糖北京英皇中心旗舰店",
"customerId": null,
"setNetCustomerKid": null,
"customer": null,
"kingdeeId": "",
"channel": null,
"salePersonId": "155848302d5b6f2768111574f0161816",
"salePerson": null,
"deptId": 12,
"deptName": null,
"dept": null,
"introduction": "",
"mobile": "18225602774",
"hotline": "010-53269059",
"city": "北京市",
"district": "朝阳区",
"addressDetail": "北京市朝阳区建国门外大街丁12号",
"image": "",
"latitude": "39.907911",
"longitude": "116.444584",
"isDel": false,
"isAppShow": true,
"business": true,
"authEndTime": null,
"createTime": 1701134158000,
"createAdminId": "f6da6faa2d50e7eff7b54bcdd55b0283",
"updateTime": 1710490644000,
"updateAdminId": null,
"distance": 898.9
}
];
bodysize = cc;
return GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/new_background.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
// key: scaffoldKey,
backgroundColor: Colors.transparent,
appBar: AppBar(
backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: Colors.white),
titleSpacing: 0,
title: SizedBox(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
// 中间居中的标题
Text(
'预约体验',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 30.rpx,
),
),
// 左侧图标
Positioned(
left: 20.rpx,
child: returnIconButtomNew,
),
Positioned(
right: 30.rpx,
child: ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Color(0xFF055466),
padding: EdgeInsets.only(left: 0),
onTap: () {
Get.toNamed("/myExperiencePage");
},
child: SvgPicture.asset(
'assets/img/icon/history_store.svg',
width: 35.rpx,
height: 35.rpx,
color: Colors.white,
)))
],
),
),
centerTitle: false,
),
body: SingleChildScrollView(
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 1,
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
//todo
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 40.rpx, 0, 38.rpx),
child: SearchWidget(
keyword: controller.model.keyword,
color: controller.model.color,
hint: "请输入门店名称",
onChange: (d) {
controller.model.keyword = d;
},
findCallback: () {
// controller.page = 0;
// controller.getData();
},
),
),
Obx(() {
if (controller
.model.experienceStoreModelList.length ==
0) {
return Empty();
} else {
return Container();
}
}),
Expanded(
child: Obx(() => ListView(
controller: scrollController,
shrinkWrap: true,
scrollDirection: Axis.vertical,
children: List.generate(
controller
.model
.experienceStoreModelList
.length, (index) {
return ExperienceStoreWidget(
index: index,
data: controller.model
.experienceStoreModelList[index]);
})
.divide(const SizedBox(
height: 25,
))
.addToStart(SizedBox(
height: AppConstants.list_start_height,
))
.addToEnd(SizedBox(
height: AppConstants.list_ano_end_height,
))))),
],
),
),
)),
));
});
}
}

View File

@@ -0,0 +1,306 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/controller/mh/book_info_controller.dart';
import 'package:vbvs_app/pages/common/selectDialog.dart';
import 'package:vbvs_app/pages/device_control/app_map_location.dart';
import '../../common/color/appFontsize.dart';
import '../../common/util/MyUtils.dart';
class ExperienceStoreWidget extends GetView {
int index;
Map data;
ExperienceStoreWidget({required this.index, required this.data}) {}
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsetsDirectional.fromSTEB(30.rpx, 0, 30.rpx, 0),
child: Container(
width: MediaQuery.sizeOf(context).width,
// height: MediaQuery.sizeOf(context).height * 0.187,
decoration: BoxDecoration(
color: Color(0XFF003058),
borderRadius: BorderRadius.circular(16),
),
child: Container(
width: MediaQuery.sizeOf(context).width,
margin: EdgeInsetsDirectional.fromSTEB(26.rpx, 14, 14, 15),
height: 120,
decoration: BoxDecoration(
color: Color(0XFF003058),
),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding: const EdgeInsetsDirectional.fromSTEB(0, 0, 0, 4),
child: Container(
width: MediaQuery.sizeOf(context).width,
// height: MediaQuery.sizeOf(context).height * 0.018,
constraints: const BoxConstraints(
minHeight: 30,
),
child: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 0.018,
child: Align(
alignment: const AlignmentDirectional(0, 0),
child: Text(
// experienceStoreModel.name ?? '未命名',
data["name"] ?? '',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Readex Pro',
color: Colors.white,
fontSize: 30.rpx,
fontWeight: FontWeight.bold,
letterSpacing: 0,
),
),
),
),
),
),
Container(
width: MediaQuery.sizeOf(context).width,
height: 1.rpx,
decoration: const BoxDecoration(
color: Color(0xFF929699),
),
),
Flexible(
child: Padding(
padding: const EdgeInsetsDirectional.fromSTEB(0, 10, 0, 0),
child: Container(
width: MediaQuery.sizeOf(context).width,
// height: MediaQuery.sizeOf(context).height * 0.034,
constraints: const BoxConstraints(
minHeight: 55,
),
child: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 0.034,
constraints: const BoxConstraints(
minHeight: 55,
),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Flexible(
child: Align(
alignment: const AlignmentDirectional(-1, 0),
child: Text(
'地址:${data["addressDetail"]}',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: const Color(0xFF929699),
fontSize: 20.rpx,
letterSpacing: 0,
lineHeight: 1),
),
),
),
Flexible(
child: Align(
alignment: const AlignmentDirectional(-1, 0),
child: Text(
'电话:${data["hotline"]}',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: const Color(0xFF929699),
fontSize: 20.rpx,
letterSpacing: 0,
lineHeight: 1),
),
),
),
],
),
),
),
),
),
Flexible(
child: Container(
width: MediaQuery.sizeOf(context).width,
// height: MediaQuery.sizeOf(context).height * 0.038,
child: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 0.038,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Flexible(
child: InkWell(
onTap: () {
MyUtils.makePhoneCall("${data["hotline"]}");
},
child: Container(
width: MediaQuery.sizeOf(context).width * 0.105,
height: MediaQuery.sizeOf(context).height * 0.038,
constraints: const BoxConstraints(
minWidth: 50,
),
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Flexible(
// child: Icon(
// Icons.phone_in_talk,
// color: Color(0xFFD3B684),
// size: 12,
// ),
child: SvgPicture.asset(
'assets/images/phone.svg',
width: 27.rpx,
height: 27.rpx,
color: const Color(0xFF84F5FF),
),
),
Text(
'咨询',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Colors.white,
fontSize: AppFontsize.small_text_size,
letterSpacing: 0,
),
),
].divide(const SizedBox(width: 13)),
),
),
)),
Flexible(
child: InkWell(
onTap: () async {
// //"latitude" -> "31.858934" "longitude" -> "117.282166"
// AppMapLocation.checkInstalledApps()
// .then((d) {
// if (AppMapLocation
// .availableMapsToNames.isEmpty) {
// showToast("未检测到导航软件");
// } else {
// showOneSelectionDialog(context,
// title: "选择地图",
// arr: AppMapLocation
// .availableMapsToNames,
// checkChange: (index) {
// AppMapLocation.launchMap(
// index,
// data["name"],
// double.parse(
// "${data["latitude"]}"),
// double.parse(
// "${data["longitude"]}"));
// });
// }
// });
},
child: Container(
width: MediaQuery.sizeOf(context).width * 0.105,
height: MediaQuery.sizeOf(context).height * 0.038,
constraints: const BoxConstraints(
minWidth: 50,
),
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Flexible(
// child: Icon(
// Icons.location_on,
// color: Color(0xFFD3B684),
// size: 12,
// ),
child: SvgPicture.asset(
'assets/images/locationColor.svg',
width: 22.rpx,
height: 29.rpx,
color: Color(0xFF84F5FF),
),
),
Text(
'导航',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Colors.white,
fontSize: AppFontsize.small_text_size,
letterSpacing: 0,
),
),
].divide(const SizedBox(width: 13)),
),
),
),
),
Container(
width: MediaQuery.sizeOf(context).width * 0.208,
height: MediaQuery.sizeOf(context).height * 0.038,
constraints: BoxConstraints(
maxWidth: 156.rpx,
maxHeight: 60.rpx,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30.rpx),
),
child: FFButtonWidget(
onPressed: () {
BookInfoController bookInfoController =
Get.find<BookInfoController>();
bookInfoController.model.userName = "";
bookInfoController.model.userPhone = "";
Get.toNamed("/bookInfoPage",
arguments: {"data": data});
},
text: '预约',
options: FFButtonOptions(
padding: const EdgeInsetsDirectional.fromSTEB(
0, 0, 0, 0),
color: Color(0xFF84F5FF),
textStyle: FlutterFlowTheme.of(context)
.titleSmall
.override(
fontFamily: 'Readex Pro',
color: Color(0xFF011D33),
fontSize: 26.rpx,
letterSpacing: 0,
),
elevation: 0,
borderSide: const BorderSide(
color: Colors.transparent,
width: 1,
),
borderRadius: BorderRadius.circular(30.rpx),
),
),
),
].divide(const SizedBox(width: 26)),
),
),
),
),
],
),
),
// ),
),
);
}
}

View File

@@ -0,0 +1,187 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:vbvs_app/common/color/appFontsize.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/pages/device_control/issue_preview_widget.dart';
import '../../controller/mh/issue_controller.dart';
class IssueListPage extends GetView<IssueListController> {
final scaffoldKey = GlobalKey<ScaffoldState>();
BoxConstraints? bodysize;
final ScrollController scrollController = ScrollController();
// IssueListPage() {
// controller.model.limit = AppConstants.limit;
// controller.model.offset = 0;
// controller.model.isLoading = false;
// controller.model.hasMore = true;
// controller.model.issueList!.clear();
// controller.initData();
// scrollController.addListener(() {
// if (scrollController.position.pixels ==
// scrollController.position.maxScrollExtent &&
// controller.model.hasMore) {
// controller.initData();
// controller.updateAll();
// }
// });
// }
// void initData() async {}
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, cc) {
bodysize = cc;
controller.model.issueList = [
{'title': 'APP如何连接我的智能床'},
{'title': '智能床如何连接网络?'},
{'title': '跟换WIFI名称或密码或者刚换了路由器后我的智能床无法使用怎么办'},
{'title': '在APP中如何查看我的睡眠报告'},
{'title': '在APP中如何查看我的睡眠报告'},
{'title': '在APP中如何查看我的睡眠报告'}
];
return GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/new_background.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: Colors.white),
titleSpacing: 0,
title: SizedBox(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
// 中间居中的标题
Text(
'问题与帮助',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 30.rpx,
),
),
// 左侧图标
Positioned(
left: 20.rpx,
child: returnIconButtomNew,
),
],
),
),
actions: [],
centerTitle: false,
),
// backgroundColor: FlutterFlowTheme.of(context).primaryBackground,
body: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 1,
decoration: BoxDecoration(
// color: AppColors.bg_color,
// color: Color(0xFFF6F6F6),
),
child: Obx(() {
return Visibility(
visible: controller.model.issueList != null &&
controller.model.issueList!.isNotEmpty,
replacement: Container(
width: MediaQuery.sizeOf(context).width,
height: 100,
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context).secondaryBackground,
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(31, 27, 0, 0),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Align(
alignment: AlignmentDirectional(-1, 0),
child: Text(
'暂无内容!',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Color(0xFF9EA4B7),
fontSize: AppFontsize.title_size,
letterSpacing: 0,
fontWeight: FontWeight.w600,
),
),
),
],
),
),
),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
// TitleComponentWidget(
// titleName: '问题与帮助',
// ),
Flexible(
child: Padding(
padding:
EdgeInsetsDirectional.fromSTEB(15, 13, 15, 15),
child: Container(
width: bodysize!.maxWidth,
decoration: BoxDecoration(
// color: Colors.white,
// borderRadius: BorderRadius.circular(16),
),
child: Obx(() => ListView(
controller: scrollController,
padding: const EdgeInsets.fromLTRB(
0,
5,
0,
0,
),
shrinkWrap: true,
scrollDirection: Axis.vertical,
children: (controller.model.issueList!
.asMap()
.entries
.map((e) => IssuePreviewWidget(
index: e.key,
issueListController: controller))
.toList() as List<Widget>)
// .divide(const SizedBox(
// height: 30,
// ))
// .addToEnd(const SizedBox(
// height: 26,
// ))
// .addToStart(SizedBox(
// height: 16,
// ))
)),
),
),
),
],
),
);
}),
),
),
));
});
}
}

View File

@@ -0,0 +1,104 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/controller/mh/issue_controller.dart';
import 'package:vbvs_app/controller/mh/issue_preview_controller.dart';
import '../../common/color/appFontsize.dart';
class IssuePreviewWidget extends GetView<IssuePreviewInfoController> {
final int index;
final IssueListController issueListController;
IssuePreviewWidget({
required this.index,
required this.issueListController,
});
@override
Widget build(BuildContext context) {
return InkWell(
onTap: () async {
// issueListController.model.selectedIndex = index;
// issueListController.updateAll();
// await Future.delayed(Duration(milliseconds: 100));
// issueListController.model.selectedIndex = -1;
// issueListController.updateAll();
// var article = issueListController.model.issueList![index];
// Get.toNamed("/helpArticle", arguments: article);
},
child: Obx(() {
return Container(
alignment: Alignment.center,
width: double.infinity,
constraints: BoxConstraints(
// minWidth: 100,
minHeight: 119.rpx,
),
decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(0),
// 整行的背景颜色
color: index == issueListController.model.selectedIndex
? Colors.grey[300]
: Colors.transparent,
border: Border(
bottom: BorderSide(color: const Color(0xFF929699), width: 0.rpx),
),
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(16.rpx, 0, 41.rpx, 0),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Flexible(
flex: 9,
child: Align(
alignment: AlignmentDirectional(-1, -1),
child: Text(
issueListController.model.issueList![index]['title'] ??
'',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Readex Pro',
color: Color(0xFFFFFFFF),
fontSize: AppFontsize.title_size,
letterSpacing: 0,
lineHeight: 1),
),
),
),
Expanded(
flex: 1,
child: Align(
alignment: Alignment.centerRight,
child: ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.transparent,
padding: EdgeInsets.only(right: 0),
onTap: () {},
child: Container(
height: 30.rpx,
width: 30.rpx,
child: SvgPicture.asset(
'assets/img/icon/expand.svg',
color: Colors.white,
)
// Icon(
// Icons.arrow_forward_ios,
// color: Colors.white,
// // size: 14.rpx,
// ),
)),
),
),
],
),
),
);
}),
);
}
}

View File

@@ -0,0 +1,418 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/svg.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/color/appFontsize.dart';
import 'package:vbvs_app/common/color/app_uri_status.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/NullDataComponentWidget.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/mh/message_controller.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
import 'package:vbvs_app/pages/main_bottom/component/MessageWidgetWidget.dart';
class MessagePage extends StatefulWidget {
const MessagePage({super.key});
@override
State<MessagePage> createState() => _MessagePageState();
}
class _MessagePageState extends State<MessagePage> {
ThemeController themeController = Get.find();
MhMessageController messageController = Get.find();
late PageController _pageController;
@override
void initState() {
super.initState();
messageController.model.type = 1;
_pageController =
PageController(initialPage: messageController.model.type == 1 ? 0 : 1);
messageController.getMessageStatus();
_fetchMessageData();
}
void _fetchMessageData() {
String type = messageController.model.type == 1 ? "app_vsm" : "app_system";
messageController.updateMessageStatus(type: type);
messageController.getMessageList().then((response) {
if (response.code != HttpStatusCodes.ok) {
TopSlideNotification.show(
// Get.context!,
context,
text: response.msg ?? "服务器.失败".tr,
textColor: themeController.currentColor.sc9,
);
}
});
}
void _onTabChanged(int index) {
messageController.model.type = index == 0 ? 1 : 2;
messageController.updateAll();
_fetchMessageData();
_pageController.animateToPage(index,
duration: const Duration(milliseconds: 300), curve: Curves.easeInOut);
}
void _onPageChanged(int index) {
int newType = index == 0 ? 1 : 2;
if (messageController.model.type != newType) {
messageController.model.type = newType;
messageController.updateAll();
_fetchMessageData();
}
}
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
messageController.messageList.value = [
{
"_id": "6836c3ee4e626030c8000000",
"type": "app_vsm",
"data": {
"title": "实时监测通知",
"val": [
{"k": "设备ID", "v": "48ca43b1b454"},
{"k": "使用人员", "v": "bb"},
{"k": "消息类型", "v": "呼吸异常"},
{"k": "检测值", "v": '26'},
{"k": "检测时间", "v": "2025-05-28 16:06:07"}
]
},
"level": 3,
"tid": "67f5d96e26ef310463000000",
"uid": "68319fe9702cc59bd1000000",
"status": 0,
"createTime": "1748419566651"
},
{
"_id": "6836c3e84e625f30c8000000",
"type": "app_vsm",
"data": {
"title": "实时监测通知",
"val": [
{"k": "设备ID", "v": "48ca43b1b454"},
{"k": "使用人员", "v": "bb"},
{"k": "消息类型", "v": "心率异常"},
{"k": "检测值", "v": '115'},
{"k": "检测时间", "v": "2025-05-28 16:06:00"}
]
},
"level": 3,
"tid": "67f5d96e26ef310463000000",
"uid": "68319fe9702cc59bd1000000",
"status": 0,
"createTime": "1748419560486"
},
{
"_id": "6836bd0c4e625e30c8000000",
"type": "app_vsm",
"data": {
"title": "实时监测通知",
"val": [
{"k": "设备ID", "v": "48ca43b1b454"},
{"k": "使用人员", "v": "bb"},
{"k": "消息类型", "v": "心率异常"},
{"k": "检测值", "v": '107'},
{"k": "检测时间", "v": "1748417761000"}
]
},
"level": 3,
"tid": "67f5d96e26ef310463000000",
"uid": "68319fe9702cc59bd1000000",
"status": 0,
"createTime": "1748417804381"
}
];
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.light,
));
return LayoutBuilder(
builder: (context, boxConstraints) => GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/new_background.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: themeController.currentColor.sc3),
titleSpacing: 0,
title: SizedBox(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
// 中间居中的标题
Text(
'消息中心',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 30.rpx,
),
),
// 左侧图标
Positioned(
left: 20.rpx,
child: returnIconButtomNew,
),
],
),
),
actions: const [],
centerTitle: false,
),
backgroundColor: Colors.transparent,
body: SafeArea(
top: true,
child: Padding(
padding: EdgeInsets.only(top: 30.rpx),
child: Column(
children: [
SizedBox(
height: 100.rpx,
child: Stack(
alignment: Alignment.bottomCenter,
children: [
Row(
children: [
// 第一个 Tab 占据屏幕一半
bodyMessage(),
// 第二个 Tab 占据屏幕另一半
systemMessage(),
],
),
Obx(() {
double screenWidth =
MediaQuery.of(context).size.width;
double tabWidth = screenWidth / 2;
double margin = 30.rpx;
double lineWidth = tabWidth - 2 * margin;
// 计算滑块左边距保证滑块水平居中于对应tab的文字
double left = (messageController.model.type == 1
? 0
: tabWidth) +
margin;
return AnimatedPositioned(
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
bottom: 0,
left: left,
child: Container(
width: lineWidth,
height: 4.rpx,
decoration: BoxDecoration(
color: Color(0xFF84F5FF),
borderRadius: BorderRadius.circular(2.rpx),
),
),
);
}),
],
),
),
Expanded(
child: PageView(
controller: _pageController,
onPageChanged: _onPageChanged,
children: [
Obx(() {
final list = messageController.messageList.value;
return list.isEmpty
? const NullDataWidget()
: _buildMessageListView(list);
}),
Obx(() {
final list = messageController.messageList.value;
return list.isEmpty
? const NullDataWidget()
: _buildMessageListView(list);
}),
],
),
),
bottomIcon(context)
],
),
)),
),
),
),
);
}
Container bottomIcon(BuildContext context) {
return Container(
height: 120.rpx,
decoration: BoxDecoration(
color: Color(0xFF003058),
),
width: double.infinity,
child: TextButton(
onPressed: () {},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Baseline(
baselineType: TextBaseline.alphabetic,
baseline: AppFontsize.normal_text_size * 1.6, // 调整基线位置
child: SvgPicture.asset(
'assets/images/read_message.svg',
width: 40.rpx,
height: 40.rpx,
)),
SizedBox(width: 14.rpx), // 加号和文字间距
Text(
'全部已读',
style: FlutterFlowTheme.of(context).titleSmall.override(
fontFamily: 'Readex Pro',
color: Colors.white,
fontSize: 26.rpx,
letterSpacing: 0,
),
),
],
),
),
);
}
Expanded systemMessage() {
return Expanded(
child: Align(
alignment: Alignment.center,
child: Obx(() {
return ClickableContainer(
padding: EdgeInsets.zero,
backgroundColor: Colors.transparent,
highlightColor: themeController.currentColor.sc21,
borderRadius: 8.rpx,
onTap: () => _onTabChanged(1),
child: Stack(
alignment: Alignment.center,
clipBehavior: Clip.none,
children: [
Text(
'系统消息'.tr,
style: TextStyle(
fontSize: AppConstants().title_text_fontSize,
color: messageController.model.type == 1
? Colors.white
: Color(0xFF84F5FF),
height: 1.0,
),
),
Obx(() {
return messageController.model.system_message_read == 1
? Positioned(
top: -4,
right: -14,
child: Container(
width: 8,
height: 8,
decoration: const BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
),
)
: const SizedBox.shrink();
}),
],
),
);
}),
),
);
}
Expanded bodyMessage() {
return Expanded(
child: Align(
alignment: Alignment.center,
child: Obx(() {
return ClickableContainer(
padding: EdgeInsets.zero,
backgroundColor: Colors.transparent,
highlightColor: themeController.currentColor.sc21,
borderRadius: 8.rpx,
onTap: () => _onTabChanged(0),
child: Stack(
alignment: Alignment.center,
clipBehavior: Clip.none,
children: [
Text(
'体征消息'.tr,
style: TextStyle(
fontSize: AppConstants().title_text_fontSize,
color: messageController.model.type == 2
? Colors.white
: Color(0xFF84F5FF),
height: 1.0,
),
),
Obx(() {
return messageController.model.body_message_read == 1
? Positioned(
top: -4,
right: -14,
child: Container(
width: 8,
height: 8,
decoration: const BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
),
)
: const SizedBox.shrink();
}),
],
),
);
}),
),
);
}
Widget _buildMessageListView(List dataList) {
return Container(
width: double.infinity,
padding: EdgeInsets.symmetric(horizontal: 30.rpx),
child: SingleChildScrollView(
child: Column(
children: [
SizedBox(height: 30.rpx),
...dataList
.map((item) => MessageWidgetWidget(data: item))
.toList()
.divide(SizedBox(height: 30.rpx)),
SizedBox(height: 30.rpx),
],
),
),
);
}
}

View File

@@ -0,0 +1,152 @@
import 'dart:async';
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:vbvs_app/common/color/appColors.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/controller/mh/my_experience_list_controller.dart';
import 'package:vbvs_app/pages/device_control/Empty.dart';
import 'package:vbvs_app/pages/device_control/my_experience_widget.dart';
class MyExperiencePage extends StatefulWidget {
const MyExperiencePage({super.key});
@override
State<MyExperiencePage> createState() => _MyExperiencePageState();
}
class _MyExperiencePageState extends State<MyExperiencePage> {
ScrollController scrollController = ScrollController();
int runTime = 0;
@override
void initState() {
super.initState();
Timer(Duration.zero, () {
controller.resetParm();
controller.getAllBook();
controller.page = 0;
controller.getData();
scrollController.addListener(() {
print(
"${scrollController.position.pixels} ${scrollController.position.maxScrollExtent}");
int ctime = DateTime.now().millisecondsSinceEpoch;
if (ctime - runTime > 100 &&
scrollController.position.pixels + 80 >
scrollController.position.maxScrollExtent) {
runTime = ctime;
print(
"bottom get more data ${scrollController.position.pixels} ${scrollController.position.maxScrollExtent}");
controller.getData();
}
});
});
}
get controller => Get.find<BookExperienceListController>();
final scaffoldKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/new_background.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
// key: scaffoldKey,
backgroundColor: Colors.transparent,
appBar: AppBar(
backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: Colors.white),
titleSpacing: 0,
// leading: returnIconButtomAddCallback(() {
// controller.saveDataApi();
// updateParm(isShowToast: false);
// }),
// leading: returnIconButtomNew,
title: Container(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
// 中间居中的标题
Text(
'我的预约',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 30.rpx,
),
),
// 左侧图标
Positioned(
left: 20.rpx,
child: returnIconButtomNew,
),
],
),
),
actions: [],
centerTitle: false,
),
body: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 1,
decoration: BoxDecoration(
color: Color(0xFFF6F6F6),
),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
// TitleComponentWidget(
// titleName: '我的预约',
// ),
Obx(() {
if (controller.model.bookInfoList.length == 0) {
return Empty();
} else {
return Container();
}
}),
Expanded(
child: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 1,
decoration: BoxDecoration(),
child: Obx(() => ListView(
controller: scrollController,
shrinkWrap: true,
scrollDirection: Axis.vertical,
children: [
const SizedBox(
height: AppConstants.list_start_height),
...List.generate(
controller.model.bookInfoList.length,
(index) {
return MyExperienceWidget(
index: index,
bookExperienceListController: controller);
}),
SizedBox(
height: AppConstants.list_end_height,
)
],
))),
)
],
),
),
),
));
}
}

View File

@@ -0,0 +1,424 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/controller/mh/my_experience_list_controller.dart';
import '../../common/color/appFontsize.dart';
class MyExperienceWidget extends GetView {
int index;
BookExperienceListController bookExperienceListController;
MyExperienceWidget(
{required this.index, required this.bookExperienceListController}) {}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsetsDirectional.fromSTEB(15, 0, 15, 0),
child: Obx(() {
Map data = {};
bookExperienceListController.model.experienceStoreModelList
.forEach((item) {
if (item["id"] ==
bookExperienceListController.model.bookInfoList[index]
["storeId"]) {
data = item;
}
});
return Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 0.187,
margin: const EdgeInsets.only(bottom: 25),
constraints: const BoxConstraints(
minHeight: 170,
),
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context).secondaryBackground,
borderRadius: BorderRadius.circular(16),
),
child: Padding(
padding: const EdgeInsetsDirectional.fromSTEB(14, 14, 14, 0),
child: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 0.187,
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context).secondaryBackground,
),
child: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 0.187,
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context).secondaryBackground,
),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding:
const EdgeInsetsDirectional.fromSTEB(0, 0, 0, 17),
child: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 0.018,
constraints: const BoxConstraints(
minHeight: 20,
),
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context)
.secondaryBackground,
),
child: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 0.018,
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context)
.secondaryBackground,
),
child: Align(
alignment: const AlignmentDirectional(0, 0),
child: Text(
// widget!.name,
"体验时间:${DateFormat("yyyy-MM-dd HH:mm").format(DateTime.fromMillisecondsSinceEpoch(int.parse("${bookExperienceListController.model.bookInfoList[index]["bookTimeStart"]}")))}",
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: const Color(0xFF182B7C),
fontSize: AppFontsize.title_size,
letterSpacing: 0,
),
),
),
),
),
),
Container(
width: MediaQuery.sizeOf(context).width,
height: 1.rpx,
decoration: const BoxDecoration(
color: Color(0xFFAAAFC0),
),
),
Padding(
padding:
const EdgeInsetsDirectional.fromSTEB(0, 10, 0, 0),
child: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 0.034,
constraints: const BoxConstraints(
minHeight: 55,
),
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context)
.secondaryBackground,
),
child: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 0.034,
constraints: const BoxConstraints(
minHeight: 55,
),
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context)
.secondaryBackground,
),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Flexible(
child: Align(
alignment:
const AlignmentDirectional(-1, 0),
child: Text(
'门店:${data["name"] ?? ""}',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: const Color(0xFF9EA4B7),
fontSize:
AppFontsize.small_text_size,
letterSpacing: 0,
),
),
),
),
Flexible(
child: Align(
alignment:
const AlignmentDirectional(-1, 0),
child: Text(
'地址:${data['addressDetail'] ?? ""}',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: const Color(0xFF9EA4B7),
fontSize:
AppFontsize.small_text_size,
letterSpacing: 0,
),
),
),
),
Flexible(
child: Align(
alignment:
const AlignmentDirectional(-1, 0),
child: Text(
'电话:${data["hotline"]} ',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: const Color(0xFF9EA4B7),
fontSize:
AppFontsize.small_text_size,
letterSpacing: 0,
),
),
),
),
],
),
),
),
),
Padding(
padding:
const EdgeInsetsDirectional.fromSTEB(0, 4, 0, 0),
child: Container(
constraints: const BoxConstraints(
minHeight: 40,
),
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 0.038,
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context)
.secondaryBackground,
),
child: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 0.038,
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context)
.secondaryBackground,
),
child: // Generated code for this Row Widget...
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Flexible(
child: InkWell(
onTap: () {
if (data["hotline"] != null) {
MyUtils.makePhoneCall(data["hotline"]);
}
},
child: Container(
width: MediaQuery.sizeOf(context).width *
0.105,
height:
MediaQuery.sizeOf(context).height *
0.038,
constraints: const BoxConstraints(
maxWidth: 50,
),
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context)
.secondaryBackground,
),
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
const Flexible(
child: Icon(
Icons.phone_in_talk,
color: Color(0xFFD3B684),
size: 12,
),
),
Text(
'咨询',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
// color: Color(0xFF9EA4B7),
color:
const Color(0xFF333333),
fontSize: AppFontsize
.small_text_size,
letterSpacing: 0,
),
),
].divide(const SizedBox(width: 13)),
),
),
)),
Flexible(
child: InkWell(
onTap: () {
// AppMapLocation.checkInstalledApps()
// .then((d) {
// if (AppMapLocation
// .availableMapsToNames.isEmpty) {
// showToast("未检测到导航软件");
// } else {
// showOneSelectionDialog(context,
// title: "选择地图",
// arr: AppMapLocation
// .availableMapsToNames,
// checkChange: (index) {
// AppMapLocation.launchMap(
// index,
// data["name"],
// double.parse(
// "${data["latitude"]}"),
// double.parse(
// "${data["longitude"]}"));
// });
// }
// });
},
child: Container(
width: MediaQuery.sizeOf(context).width *
0.105,
height:
MediaQuery.sizeOf(context).height *
0.038,
constraints: const BoxConstraints(
maxWidth: 50,
),
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context)
.secondaryBackground,
),
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
const Flexible(
child: Icon(
Icons.location_on,
color: Color(0xFFD3B684),
size: 12,
),
),
Text(
'导航',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
// color: Color(0xFF9EA4B7),
color:
const Color(0xFF333333),
fontSize: AppFontsize
.small_text_size,
letterSpacing: 0,
),
),
].divide(const SizedBox(width: 13)),
),
),
)),
Container(
width:
MediaQuery.sizeOf(context).width * 0.22,
height: MediaQuery.sizeOf(context).height *
0.038,
constraints: const BoxConstraints(
maxWidth: 78,
maxHeight: 100,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
),
child: FFButtonWidget(
onPressed: () {
// if (bookExperienceListController
// .model.bookInfoList[index]
// ["status"] ==
// 2) {
// showCustomConfirmAndCancelDialog(
// context, "取消预约")
// .then((d) {
// if (d == "confirm") {
// bookExperienceListController
// .cancelBook(
// bookExperienceListController
// .model
// .bookInfoList[
// index]["id"],
// success: () {
// var rd = jsonDecode(jsonEncode(
// bookExperienceListController
// .model
// .bookInfoList[index]));
// rd["status"] = -1;
// rd["addressDetail"] =
// data['addressDetail'];
// rd["name"] = data["name"];
// bookExperienceListController
// .messageAdd(rd);
// });
// }
// });
// }
},
text: bookExperienceListController
.model.bookInfoList[index]
["status"] ==
2
? '取消预约'
: bookExperienceListController
.model.bookInfoList[index]
["statusName"],
options: FFButtonOptions(
height: 40,
padding: const EdgeInsetsDirectional
.fromSTEB(13, 0, 13, 0),
iconPadding: const EdgeInsetsDirectional
.fromSTEB(0, 0, 0, 0),
color: bookExperienceListController
.model
.bookInfoList[index]
["status"] ==
2
? const Color(0xFFD3B684)
: stringToColor("#D3D3D3"),
textStyle: FlutterFlowTheme.of(context)
.titleSmall
.override(
fontFamily: 'Readex Pro',
color: Colors.white,
fontSize:
AppFontsize.small_text_size,
letterSpacing: 0,
),
elevation: 0,
borderSide: const BorderSide(
color: Colors.transparent,
width: 1,
),
borderRadius: BorderRadius.circular(32),
),
),
),
].divide(const SizedBox(width: 26)),
)),
),
),
],
),
),
),
),
);
}));
}
}

View File

@@ -0,0 +1,854 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/controller/device/body_device_controller.dart';
import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
import 'package:vbvs_app/controller/mh/muser_info_controller.dart';
class NewHomePage extends StatefulWidget {
const NewHomePage({super.key});
@override
State<NewHomePage> createState() => _NewHomePageState();
}
class _NewHomePageState extends State<NewHomePage> {
MUserInfoController userInfoController = Get.find();
BodyDeviceController deviceController = Get.find();
double borderRadius = 16.rpx;
var formFieldController = FormFieldController<String>(null);
get gloablController => Get.find<GlobalController>();
// get userInfoController => Get.find<UserInfoController>();
var sleepDays = [].obs;
var sleep_mac = "".obs;
Map scoreColor = {
"-1": "#d3d3d3",
"1": "#4e8408",
"2": "#7bbb33",
"3": "#e15b8d",
"4": "#ff0000",
};
Map scoreName = {
"-1": "暂无",
"1": "优秀",
"2": "良好",
"3": "合格",
"4": "注意",
};
@override
void initState() {
super.initState();
}
getWeekName(int i) {
String v = "";
switch (i) {
case 1:
v = "周一";
break;
case 2:
v = "周二";
break;
case 3:
v = "周三";
break;
case 4:
v = "周四";
break;
case 5:
v = "周五";
break;
case 6:
v = "周六";
break;
case 7:
v = "周日";
break;
}
return v;
}
@override
Widget build(BuildContext context) {
int login = userInfoController.model.login!;
return GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/new_background.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
iconTheme: IconThemeData(color: themeController.currentColor.sc3),
backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
titleSpacing: 0,
title: Row(
children: [
// 左侧头像
SizedBox(width: 40.rpx),
CircleAvatar(
radius: 27.rpx, // 可根据需求调整
backgroundImage: login == 1
? (userInfoController.model.user!.avatar == null ||
userInfoController.model.user!.avatar!.isEmpty
? const AssetImage(
"assets/images/people_avatar.png",
)
: NetworkImage(
userInfoController.model.user!.avatar!,
))
: const AssetImage(
"assets/images/people_avatar.png",
),
),
SizedBox(width: 23.rpx), // 左侧头像和文本之间的间距
Text(
'Eason Chan',
style: TextStyle(fontSize: 30.rpx, color: Colors.white),
),
const Spacer(), // 左右分隔
// Container(
// width: 61.rpx,
// height: 78.rpx,
// alignment: const Alignment(0, 0),
// child: Image.asset(
// "assets/images/xiaoe.png",
// fit: BoxFit.cover,
// ),
// ),
// SizedBox(width: 46.rpx), // icon 之间的间距
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.transparent,
padding: EdgeInsets.only(right: 0),
onTap: () {},
child: Container(
height: 60.rpx,
width: 75.rpx,
child: SvgPicture.asset(
'assets/img/icon/xiaoe.svg',
// color: Colors.white,
))),
// SizedBox(width: 40.rpx),
],
),
centerTitle: false,
),
body: SafeArea(
child: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 1.123,
// decoration: BoxDecoration(
// color: AppColors.bg_color,
// image: DecorationImage(
// image: AssetImage("assets/images/background.png"),
// fit: BoxFit.cover,
// ),
// ),
decoration: BoxDecoration(
),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Container(
padding:
EdgeInsets.fromLTRB(26.rpx, 10.rpx, 26.rpx, 40.rpx),
width: double.infinity,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 30.rpx),
child: Column(
children: [
Padding(
padding:
EdgeInsets.fromLTRB(17.rpx, 30.rpx, 0, 0),
child: Row(
children: [
Text('上海 22° 多云',
style: TextStyle(
fontSize: 26.rpx,
color: Colors.white)),
Icon(Icons.cloud,
size: 30.rpx, color: Colors.white),
],
),
),
],
))),
Container(
padding: EdgeInsets.only(left: 30.rpx, right: 30.rpx),
child: Column(
children: [
if (gloablController.model.deviceList.length > 0)
Container(
child: Column(
children: [
Container(
width: MediaQuery.sizeOf(context).width,
decoration: BoxDecoration(
color: Colors.white,
borderRadius:
BorderRadius.circular(borderRadius),
),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding:
EdgeInsetsDirectional.fromSTEB(
30.rpx,
16.rpx,
16.rpx,
8.rpx),
child: Container(
width: MediaQuery.sizeOf(context)
.width,
height: MediaQuery.sizeOf(context)
.height *
0.065,
decoration: BoxDecoration(
color:
FlutterFlowTheme.of(context)
.secondaryBackground,
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
ValueListenableBuilder(
valueListenable:
formFieldController,
builder: (c, a, s) =>
FlutterFlowDropDown<
String>(
controller:
formFieldController,
options: gloablController
.model.JunheDevices
.map<String>((d) =>
"${d["mac"]}")
.toList(),
optionLabels:
gloablController
.model.JunheDevices
.map<String>((d) {
var s =
d["name"] ?? d["mac"];
if (s == null) {
return "";
} else {
return "$s";
}
}).toList(),
onChanged: (val) {
// print("$val");
// if (val == null) {
// sleepDays.value = [];
// } else {
// getSleeps(
// formFieldController
// .value);
// }
// // sleep_mac.value = val!;
},
width: 360.rpx,
height: 72.rpx,
maxHeight: 200.rpx,
textStyle: TextStyle(
fontSize: 28.rpx,
overflow: TextOverflow
.ellipsis),
hintText: '',
icon: Icon(
Icons
.keyboard_arrow_down_rounded,
color:
FlutterFlowTheme.of(
context)
.secondaryText,
size: 48.rpx,
),
fillColor: stringToColor(
"#F3F5F6"),
elevation: 2,
borderColor: stringToColor(
"#F3F5F6"),
borderWidth: 2,
borderRadius: 18,
margin:
EdgeInsetsDirectional
.fromSTEB(
32.rpx,
8.rpx,
32.rpx,
8.rpx),
hidesUnderline: true,
isOverButton: false,
isSearchable: false,
isMultiSelect: false,
),
),
InkWell(
onTap: () {
// if (formFieldController
// .value !=
// null) {
// Get.toNamed(
// "/sleepWebview",
// arguments: [
// formFieldController
// .value
// ]);
// }
},
child: Row(
mainAxisSize:
MainAxisSize.max,
children: [
Text(
'睡眠报告',
style: FlutterFlowTheme
.of(context)
.bodyMedium
.override(
fontFamily:
'Readex Pro',
letterSpacing:
0,
fontSize:
30.rpx),
),
SizedBox(
width: 12.rpx,
),
SvgPicture.asset(
"assets/images/table.svg",
width: 28.rpx,
height: 28.rpx),
SizedBox(
width: 20.rpx,
),
],
),
),
],
),
),
),
Container(
padding: EdgeInsets.only(
top: 0.rpx,
bottom: 20.rpx,
left: 16.rpx,
right: 16.rpx),
width: double.infinity,
decoration: BoxDecoration(),
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
...List.generate(
sleepDays.value.length,
(index) {
var day = sleepDays[index];
return Expanded(
child: Container(
padding: EdgeInsets.only(
top: 10.rpx,
bottom: 20.rpx),
width: 100,
// decoration: BoxDecoration(
// color: index == 2
// ? stringToColor("#F3F5F6")
// : Colors.white,
// borderRadius:
// BorderRadius.circular(
// borderRadius),
// ),
child: Column(
mainAxisSize:
MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment
.start,
crossAxisAlignment:
CrossAxisAlignment
.center,
children: [
Text(
day['week'],
style: FlutterFlowTheme
.of(context)
.bodyMedium
.override(
fontFamily:
'Readex Pro',
fontSize:
30.rpx,
letterSpacing:
0,
),
),
Text(
day['date'],
style: FlutterFlowTheme
.of(context)
.bodyMedium
.override(
fontFamily:
'Readex Pro',
letterSpacing:
0,
fontSize:
24.rpx,
),
),
SizedBox(
height: 6.rpx,
),
Column(
children: [
Row(
mainAxisSize:
MainAxisSize
.max,
mainAxisAlignment:
MainAxisAlignment
.center,
children: [
Text(
'${day['score'] ?? "-"}',
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily:
'Readex Pro',
fontSize:
48.rpx,
letterSpacing:
0,
),
),
if (day['score'] !=
null)
SizedBox(
width:
2.rpx,
),
if (day['score'] !=
null)
Text(
'',
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily:
'Readex Pro',
letterSpacing:
0,
fontSize:
26.rpx,
),
),
],
),
Container(
width: 120.rpx,
height: 52.rpx,
decoration:
BoxDecoration(
color: stringToColor(
day['scoreColor'] ??
"#f3f5f6"),
borderRadius:
BorderRadius
.circular(
26.rpx),
shape: BoxShape
.rectangle,
),
alignment:
Alignment
.center,
child: Text(
'${day['scoreType'] ?? "暂无"}',
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily:
'Readex Pro',
color: day['scoreType'] !=
null
? Colors
.white
: stringToColor(
"#ced1d7"),
letterSpacing:
0,
fontSize:
28.rpx,
),
),
)
],
)
],
),
),
);
})
],
),
),
],
),
),
...List.generate(
gloablController.model.deviceList.length,
(index) {
var device = gloablController
.model.deviceList[index];
String rname = device['roomName'];
if (index != 0) {
String lrname = gloablController.model
.deviceList[index - 1]["roomName"];
if (lrname == rname) {
rname = "";
}
}
return Column(children: [
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
20.rpx, 20.rpx, 0, 0),
child: Container(
decoration: BoxDecoration(),
alignment:
AlignmentDirectional(-1, 0),
child: rname.isNotEmpty
? Text(
"$rname",
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily:
'Readex Pro',
color: Colors.white,
fontSize: 32.rpx,
letterSpacing: 0,
),
)
: SizedBox(
height: 10.rpx,
),
),
),
// getDeviceList(context, device)
]);
}),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 40.rpx, 0, 100.rpx),
child: Container(
width: MediaQuery.sizeOf(context).width,
height: 84.rpx,
decoration: BoxDecoration(),
child: FFButtonWidget(
onPressed: () {
// print('Button pressed ...');
// Get.toNamed("/homeDeviceType");
},
text: '添加新设备',
icon: Icon(
Icons.add,
size: 60.rpx,
),
options: FFButtonOptions(
height: 80.rpx,
padding:
EdgeInsetsDirectional.fromSTEB(
48.rpx, 0, 48.rpx, 0),
iconPadding:
EdgeInsetsDirectional.fromSTEB(
0, 0, 0, 0),
color: stringToColor("#182B7C"),
textStyle:
FlutterFlowTheme.of(context)
.titleSmall
.override(
fontFamily: 'Readex Pro',
color: Colors.white,
letterSpacing: 0,
fontSize: 30.rpx),
elevation: 3,
borderSide: BorderSide(
color: Colors.transparent,
width: 1,
),
borderRadius: BorderRadius.circular(
borderRadius),
),
),
),
),
],
),
),
if (gloablController.model.deviceList.length == 0)
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 0, 0, 80.rpx),
child: Container(
width: MediaQuery.sizeOf(context).width,
padding: EdgeInsets.only(
top: 90.rpx, bottom: 80.rpx),
decoration: BoxDecoration(
color: Colors.white,
borderRadius:
BorderRadius.circular(borderRadius),
),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'检测到您当前暂无设备!',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Color(0xFF9EA4B7),
fontSize: 32.rpx,
letterSpacing: 0,
),
),
SizedBox(
height:
MediaQuery.sizeOf(context).height *
0.037,
),
Container(
width: MediaQuery.sizeOf(context).width *
0.54,
height: 90.rpx,
decoration: BoxDecoration(
color: FlutterFlowTheme.of(context)
.secondaryBackground,
borderRadius: BorderRadius.circular(0),
),
child: FFButtonWidget(
onPressed: () {
// print('Button pressed ...');
Get.toNamed("/homeDeviceType");
},
text: '立即添加一台',
icon: Icon(
Icons.add,
color: FlutterFlowTheme.of(context)
.primaryText,
size: 60.rpx,
),
options: FFButtonOptions(
iconPadding:
EdgeInsetsDirectional.fromSTEB(
0, 0, 0, 0),
color: Colors.white,
textStyle:
FlutterFlowTheme.of(context)
.titleSmall
.override(
fontFamily: 'Readex Pro',
color:
FlutterFlowTheme.of(
context)
.primaryText,
letterSpacing: 0,
fontSize: 30.rpx),
elevation: 3,
borderSide: BorderSide(
color: Color(0xFFABB0C0),
width: 1,
),
borderRadius:
BorderRadius.circular(45.rpx),
),
),
),
],
),
),
),
],
),
)
],
),
),
)
// Padding(
// padding: EdgeInsets.symmetric(horizontal: 30.rpx),
// child: Column(
// children: [
// Padding(
// padding: EdgeInsets.fromLTRB(17.rpx, 30.rpx, 0, 0),
// child: Row(
// children: [
// Text('上海 22° 多云',
// style: TextStyle(
// fontSize: 26.rpx, color: Colors.white)),
// Icon(Icons.cloud,
// size: 30.rpx, color: Colors.white),
// ],
// ),
// ),
// ],
// ))
),
),
));
}
}
class ScoreItem {
final String weekday; // 如“周四”
final String dateStr; // 如“07/03”
final int score;
final bool isToday;
ScoreItem({
required this.weekday,
required this.dateStr,
required this.score,
this.isToday = false,
});
}
class ScoreCard extends StatelessWidget {
final String selectedUser;
final List<ScoreItem> scoreList;
final ValueChanged<String?>? onUserChanged;
final VoidCallback? onChartPressed;
const ScoreCard({
super.key,
required this.selectedUser,
required this.scoreList,
this.onUserChanged,
this.onChartPressed,
});
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: const Color(0xff0F2B44),
borderRadius: BorderRadius.circular(16),
),
padding: const EdgeInsets.all(12),
child: Column(
children: [
// 顶部用户选择 + 图标按钮
Row(
children: [
DropdownButtonHideUnderline(
child: DropdownButton<String>(
value: selectedUser,
borderRadius: BorderRadius.circular(12),
dropdownColor: const Color(0xff0F2B44),
iconEnabledColor: Colors.white,
style: const TextStyle(color: Colors.white),
items: ['Eason Chan', 'Jay Chou', 'G.E.M.']
.map((user) => DropdownMenuItem(
value: user,
child: Text(user),
))
.toList(),
onChanged: onUserChanged,
),
),
const Spacer(),
IconButton(
onPressed: onChartPressed,
icon: const Icon(Icons.bar_chart, color: Colors.white),
),
],
),
const SizedBox(height: 12),
// 日期+分数 横向滚动展示
SizedBox(
height: 70,
child: ListView.separated(
scrollDirection: Axis.horizontal,
itemCount: scoreList.length,
separatorBuilder: (_, __) => const SizedBox(width: 12),
itemBuilder: (context, index) {
final item = scoreList[index];
final isToday = item.isToday;
return Container(
padding:
const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
decoration: BoxDecoration(
color: isToday
? Colors.white.withOpacity(0.1)
: Colors.transparent,
borderRadius: BorderRadius.circular(12),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(item.weekday,
style: const TextStyle(
color: Colors.white70, fontSize: 12)),
Text(item.dateStr,
style: const TextStyle(
color: Colors.white54, fontSize: 10)),
const SizedBox(height: 4),
Text(
item.score.toString(),
style: TextStyle(
color: Colors.white,
fontWeight:
isToday ? FontWeight.bold : FontWeight.normal,
fontSize: 16,
),
),
],
),
);
},
),
)
],
),
);
}
}

View File

@@ -0,0 +1,304 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/color/app_uri_status.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/component/NullDataComponentWidget.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
import 'package:vbvs_app/controller/message/message_controller.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
import 'package:vbvs_app/pages/main_bottom/component/MessageWidgetWidget.dart';
class MessagePage extends StatefulWidget {
const MessagePage({super.key});
@override
State<MessagePage> createState() => _MessagePageState();
}
class _MessagePageState extends State<MessagePage> {
ThemeController themeController = Get.find();
MessageController messageController = Get.find();
late PageController _pageController;
@override
void initState() {
super.initState();
_pageController =
PageController(initialPage: messageController.model.type == 1 ? 0 : 1);
messageController.getMessageStatus();
_fetchMessageData();
}
void _fetchMessageData() {
String type = messageController.model.type == 1 ? "app_vsm" : "app_system";
messageController.updateMessageStatus(type: type);
messageController.getMessageList().then((response) {
if (response.code != HttpStatusCodes.ok) {
TopSlideNotification.show(
Get.context!,
text: response.msg ?? "服务器.失败".tr,
textColor: themeController.currentColor.sc9,
);
}
});
}
void _onTabChanged(int index) {
messageController.model.type = index == 0 ? 1 : 2;
messageController.updateAll();
_fetchMessageData();
_pageController.animateToPage(index,
duration: const Duration(milliseconds: 300), curve: Curves.easeInOut);
}
void _onPageChanged(int index) {
int newType = index == 0 ? 1 : 2;
if (messageController.model.type != newType) {
messageController.model.type = newType;
messageController.updateAll();
_fetchMessageData();
}
}
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.light,
));
return LayoutBuilder(
builder: (context, boxConstraints) => GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/img/bgNoImg.png'),
fit: BoxFit.fill,
),
),
child: Scaffold(
appBar: AppBar(
backgroundColor: themeController.currentColor.sc17,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: themeController.currentColor.sc3),
toolbarHeight: 140.rpx,
titleSpacing: 0,
title: Padding(
padding: EdgeInsetsDirectional.fromSTEB(40.rpx, 0, 0, 0),
child: Container(
width: double.infinity,
height: 140.rpx,
child: Column(
children: [
SizedBox(height: 40.rpx),
Expanded(
child: Stack(
alignment: Alignment.bottomLeft,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Obx(() {
return ClickableContainer(
padding: EdgeInsets.all(0),
backgroundColor: Colors.transparent,
highlightColor:
themeController.currentColor.sc21,
borderRadius: 8.rpx,
onTap: () => _onTabChanged(0),
child: Container(
width: 160.rpx,
alignment: Alignment.center,
child: Stack(
alignment: Alignment.center,
clipBehavior: Clip.none,
children: [
Text(
'体征消息'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: AppConstants()
.title_text_fontSize,
color:
messageController
.model.type ==
2
? themeController
.currentColor.sc3
: themeController
.currentColor.sc2,
),
),
Obx(() {
return messageController.model
.body_message_read ==
1
? Positioned(
top: -4,
right: -14,
child: Container(
width: 8,
height: 8,
decoration:
const BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
),
)
: const SizedBox.shrink();
}),
],
),
),
);
}),
Obx(() {
return ClickableContainer(
padding: EdgeInsets.all(0),
backgroundColor: Colors.transparent,
highlightColor:
themeController.currentColor.sc21,
borderRadius: 8.rpx,
onTap: () => _onTabChanged(1),
child: Container(
width: 160.rpx,
alignment: Alignment.center,
child: Stack(
alignment: Alignment.center,
clipBehavior: Clip.none,
children: [
Text(
'系统消息'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Inter',
fontSize: AppConstants()
.title_text_fontSize,
color:
messageController
.model.type ==
1
? themeController
.currentColor.sc3
: themeController
.currentColor.sc2,
),
),
Obx(() {
return messageController.model
.system_message_read ==
1
? Positioned(
top: -4,
right: -14,
child: Container(
width: 8,
height: 8,
decoration:
const BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
),
)
: const SizedBox.shrink();
}),
],
),
),
);
}),
].divide(SizedBox(width: 10.rpx)),
),
Obx(() {
double lineWidth = 170.rpx;
return AnimatedPositioned(
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
bottom: 0,
left: messageController.model.type == 1
? 0
: 170.rpx,
child: Container(
width: lineWidth,
height: 4.rpx,
decoration: BoxDecoration(
color: themeController.currentColor.sc2,
borderRadius: BorderRadius.circular(2.rpx),
),
),
);
}),
],
),
),
SizedBox(height: 17.rpx),
],
),
),
),
actions: const [],
centerTitle: false,
),
backgroundColor: Colors.transparent,
body: SafeArea(
top: true,
child: PageView(
controller: _pageController,
onPageChanged: _onPageChanged,
children: [
Obx(() {
final list = messageController.messageList.value;
return list.isEmpty
? const NullDataWidget()
: _buildMessageListView(list);
}),
Obx(() {
final list = messageController.messageList.value;
return list.isEmpty
? const NullDataWidget()
: _buildMessageListView(list);
}),
],
),
),
),
),
),
);
}
Widget _buildMessageListView(List dataList) {
return Container(
width: double.infinity,
padding: EdgeInsets.symmetric(horizontal: 30.rpx),
child: SingleChildScrollView(
child: Column(
children: [
SizedBox(height: 30.rpx),
...dataList
.map((item) => MessageWidgetWidget(data: item))
.toList()
.divide(SizedBox(height: 30.rpx)),
SizedBox(height: 30.rpx),
],
),
),
);
}
}

View File

@@ -0,0 +1,416 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/svg.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
import 'package:vbvs_app/controller/mh/muser_info_controller.dart';
import 'package:vbvs_app/controller/theme_controller/ThemeController.dart';
import 'package:vbvs_app/enum/LoginStatus.dart';
class NewMinePage extends StatefulWidget {
const NewMinePage({super.key});
@override
State<NewMinePage> createState() => _MinePageState();
}
class _MinePageState extends State<NewMinePage> {
GlobalController globalController = Get.find();
MUserInfoController userInfoController = Get.find();
ThemeController themeController = Get.find();
final GlobalKey _textKey = GlobalKey();
double _textHalfWidth = 0;
@override
void initState() {
super.initState();
_calculateTextHalfWidth('Eason Chan');
}
void _calculateTextHalfWidth(String text) {
final textSpan = TextSpan(
text: text,
style: TextStyle(
fontSize: 30.rpx,
height: 1,
),
);
final textPainter = TextPainter(
text: textSpan,
textDirection: TextDirection.ltr,
);
textPainter.layout(); // 计算文本宽度
setState(() {
_textHalfWidth = textPainter.width / 2;
});
}
@override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
statusBarColor: Colors.transparent, // 这里设置你希望的颜色
statusBarIconBrightness: Brightness.light, // 状态栏图标的亮度
));
int login = userInfoController.model.login!;
return LayoutBuilder(
builder: (context, bodySize) => GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/new_background.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
backgroundColor: Colors.transparent,
iconTheme: const IconThemeData(color: Colors.white),
automaticallyImplyLeading: false,
titleSpacing: 0,
actions: [
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.transparent,
padding: EdgeInsets.only(right: 38.rpx),
onTap: () {
// if (userInfoController.model.login ==
// LoginStatus.LOGIN.code) {
// TopSlideNotification.show(
// context,
// text: "待开发功能".tr,
// );
// } else {
// TopSlideNotification.show(
// context,
// text: "必须登录提示".tr,
// textColor: themeController.currentColor.sc9,
// );
// Get.toNamed("/loginPage");
// }
Get.toNamed('/messagePage');
},
child: Container(
height: 42.rpx,
width: 42.rpx,
child: SvgPicture.asset(
'assets/img/icon/message.svg',
color: Colors.white,
// color: Colors.white,
))),
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.transparent,
padding: EdgeInsets.only(right: 11.rpx),
onTap: () {
Get.toNamed("/peopleInfoPage");
},
child: Container(
height: 42.rpx,
width: 42.rpx,
child: SvgPicture.asset(
'assets/img/icon/people_info.svg',
color: Colors.white,
))),
],
),
body: SafeArea(
top: true,
child: Container(
height: bodySize.maxHeight,
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding: EdgeInsetsDirectional.only(top: 30.rpx),
child: Container(
width: 120.rpx,
height: 120.rpx,
clipBehavior: Clip.antiAlias,
decoration: const BoxDecoration(
shape: BoxShape.circle,
),
child: login == 1
? (userInfoController.model.user!.avatar == null ||
userInfoController
.model.user!.avatar!.isEmpty
? Image.asset(
"assets/images/people_avatar.png",
fit: BoxFit.cover,
)
: Image.network(
userInfoController.model.user!.avatar!,
fit: BoxFit.cover,
))
: Image.asset(
"assets/images/people_avatar.png",
fit: BoxFit.cover,
),
),
),
Padding(
padding: EdgeInsetsDirectional.only(top: 19.rpx),
child: Container(
width: double.infinity,
decoration: const BoxDecoration(),
child: Stack(
alignment: Alignment.center, // 使子组件在Stack中居中
children: [
Container(
// width: 194.rpx,
height: 63.rpx,
child: Column(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
crossAxisAlignment:
CrossAxisAlignment.center, // 文字水平居中
children: [
Text(
'Eason Chan',
style: TextStyle(
fontSize: 30.rpx,
color: Colors.white,
height: 1),
),
Text(
'135****2598',
style: TextStyle(
fontSize: 26.rpx,
color: const Color(0XFF929699),
height: 1),
),
],
),
),
Positioned(
left: MediaQuery.of(context).size.width / 2 +
_textHalfWidth +
30.rpx,
top: -10.rpx,
child: ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: const Color(0xFF055466),
padding: EdgeInsets.zero,
onTap: () {
Get.toNamed("/editUserInfoPage");
},
child: Container(
width: 42.rpx,
height: 42.rpx,
alignment: Alignment.center,
child: SvgPicture.asset(
'assets/images/edit.svg',
color: Colors.white,
width: 18.rpx,
height: 18.rpx,
),
)),
),
],
),
),
),
Container(
margin: EdgeInsets.only(
left: 60.rpx, right: 60.rpx, top: 94.rpx),
child: Text(
'对已绑定的智能设备进行个性化配置,以获得更好的体验,',
style: TextStyle(
fontSize: 26.rpx,
color: const Color(0XFF929699),
height: 1),
)),
Padding(
padding: EdgeInsets.only(top: 46.rpx, bottom: 109.rpx),
child: ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
backgroundColor: const Color(0XFF85F5FF),
side: const BorderSide(color: Color(0XFF74DAE5)),
// foregroundColor: Colors.cyanAccent,
minimumSize: Size(260.rpx, 60.rpx),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
),
child: Text(
'我的智能床',
style: TextStyle(
fontSize: 26.rpx, color: const Color(0xFF003058)),
),
),
),
// 使用 Expanded 让滚动区域占据可用空间
// SizedBox(height: 109.rpx),
Expanded(
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
color: Colors.transparent,
),
child: SingleChildScrollView(
// 直接使用 SingleChildScrollView
child: Column(
children: [
_buildListTile(
Icons.receipt_long, '我的订单', '快捷查看我在网上的订单记录',
showTopLine: true),
_buildListTile(Icons.store_mall_directory, '门店体验',
'如果想免费体验智能设备,可在此进行提前预约',
path: "/experienceStorePage"),
_buildListTile(
Icons.build,
'设备报修',
'当您的智能设备需要报修时,可以通过该功能联系解决',
path: '/deviceRepairPage',
),
_buildListTile(
Icons.shopping_cart, '网上商城', '最新的智能产品线上购买服务'),
_buildListTile(
Icons.location_on, '地址管理', '用于收货和报修时联系您',
path: "/addressListPage"),
_buildListTile(Icons.help_outline, '问题与帮助',
'常见的问题汇总,如:智能床连接流程、如何查看睡眠报告',
path: "/issueListpage"),
_buildListTile(
Icons.headset_mic,
'在线客服',
'购买和使用智能床过程中,如果遇到疑问可与客服进行联系',
),
],
),
),
),
), // 使用 Expanded 让滚动区域占据可用空间
Padding(
padding:
EdgeInsets.fromLTRB(30.rpx, 24.rpx, 30.rpx, 50.rpx),
child: _buildSettingButton(),
),
],
),
// Column(
// mainAxisSize: MainAxisSize.max,
// children: [
// ],
// ),
),
),
),
),
),
);
}
/// 构建列表项(带分隔线)
Widget _buildListTile(
IconData icon,
String title,
String subtitle, {
// VoidCallback? onTap,
String? path,
bool showTopLine = false,
}) {
return ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.white,
padding: EdgeInsets.all(0.rpx),
onTap: () {
Get.toNamed(path!);
},
child: Container(
decoration: BoxDecoration(
border: Border(
top: showTopLine
? BorderSide(color: Color(0xFF929699), width: 2.rpx)
: BorderSide.none,
bottom: BorderSide(color: Color(0xFF929699), width: 2.rpx),
),
),
height: 116.rpx,
child: Padding(
padding: EdgeInsets.fromLTRB(40.rpx, 0.rpx, 40.rpx, 0.rpx),
child: Row(
children: [
Icon(icon, color: const Color(0xFF85F5FF), size: 28.rpx),
SizedBox(width: 30.rpx),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center, // 垂直方向居中对齐
children: [
Text(
title,
style: TextStyle(
color: Colors.white,
fontSize: 30.rpx,
),
),
// SizedBox(height: 6.rpx), // 加点间距
Text(
subtitle,
style: TextStyle(
color: Color(0xFF929699),
fontSize: 20.rpx,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
softWrap: true, // 允许换行
),
],
),
),
ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Colors.transparent,
padding: EdgeInsets.only(right: 0),
onTap: () {},
child: Container(
height: 30.rpx,
width: 30.rpx,
child: SvgPicture.asset(
'assets/img/icon/expand.svg',
color: Colors.white,
)
// Icon(
// Icons.arrow_forward_ios,
// color: Colors.white,
// // size: 14.rpx,
// ),
)),
],
),
),
));
}
Widget _buildSettingButton() {
return Container(
width: double.infinity,
height: MediaQuery.sizeOf(context).height * 0.055,
constraints: BoxConstraints(
minHeight: 90.rpx,
),
child: ElevatedButton(
onPressed: () {
Get.toNamed("/settingPage");
},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF04345E),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.rpx)),
),
child:
Text('设置', style: TextStyle(fontSize: 26.rpx, color: Colors.white)),
),
);
}
}

View File

@@ -0,0 +1,618 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/appConstants.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/component/tool/TopSlideNotification.dart';
class SettingPage extends StatefulWidget {
@override
_SettingPageState createState() => _SettingPageState();
}
class _SettingPageState extends State<SettingPage> {
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, bodySize) {
return GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/new_background.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
backgroundColor: Colors.transparent,
iconTheme: const IconThemeData(color: Colors.white),
titleSpacing: 0,
automaticallyImplyLeading: false,
title: SizedBox(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
// 中间居中的标题
Text(
'设置',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 30.rpx,
),
),
// 左侧图标
Positioned(
left: 20.rpx,
child: returnIconButtomNew,
),
],
),
),
centerTitle: false,
),
body: SafeArea(
top: true,
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(30.rpx, 0, 30.rpx, 0),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 25.rpx, 0.rpx, 0),
child: Container(
width: double.infinity,
decoration: BoxDecoration(
color: Color(0xFF003058),
borderRadius: BorderRadius.circular(
AppConstants().normal_container_radius),
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 0, 0.rpx, 0),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
ClickableContainer(
backgroundColor:
Colors.transparent, // 容器背景色
highlightColor: themeController
.currentColor.sc21, // 点击时的背景色
padding: EdgeInsetsDirectional.fromSTEB(
40.rpx, 0.rpx, 40.rpx, 0.rpx),
onTap: () {
TopSlideNotification.show(context,
text: "待开发功能".tr);
},
child: Container(
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 30.rpx, 0.rpx, 30.rpx),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisSize: MainAxisSize.max,
children: [
Text('修改密码',
style: TextStyle(
fontSize: 30.rpx,
color: Colors.white,
height: 1)),
].divide(SizedBox(width: 22.rpx)),
),
SvgPicture.asset(
'assets/img/icon/arrow_right.svg',
width: 8.rpx,
height: 15
.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
color: themeController
.currentColor.sc3,
),
// Row(
// mainAxisSize: MainAxisSize.max,
// children: [
// Text(
// '深色',
// style: FlutterFlowTheme.of(
// context)
// .bodyMedium
// .override(
// fontFamily: 'Inter',
// color:
// Color(0xFFD9E3EB),
// fontSize: 26.rpx,
// letterSpacing: 0.0,
// ),
// ),
// ].divide(SizedBox(width: 28.rpx)),
// ),
],
),
),
),
),
ClickableContainer(
backgroundColor:
Colors.transparent, // 容器背景色
highlightColor: themeController
.currentColor.sc21, // 点击时的背景色
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 0.rpx, 0.rpx, 0.rpx),
onTap: () {
print('点击了容器');
Get.toNamed("/aboutUsPage");
},
child: Container(
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
40.rpx, 30.rpx, 40.rpx, 30.rpx),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisSize: MainAxisSize.max,
children: [
Text(
'当前版本',
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily: 'Inter',
color: Colors.white,
fontSize: AppConstants()
.title_text_fontSize,
letterSpacing: 0.0,
lineHeight: 1.0,
),
),
].divide(SizedBox(width: 22.rpx)),
),
Text('SWES3.513.4',
style: TextStyle(
color: Colors.white,
fontSize: 26.rpx,
height: 1)),
// SvgPicture.asset(
// 'assets/img/icon/arrow_right.svg',
// width: 8.rpx,
// height: 14
// .rpx, // 如果 SVG 中没有固定颜色,可以这样设置
// color: themeController
// .currentColor.sc3,
// ),
],
),
),
),
),
ClickableContainer(
backgroundColor:
Colors.transparent, // 容器背景色
highlightColor: themeController
.currentColor.sc21, // 点击时的背景色
padding: EdgeInsetsDirectional.fromSTEB(
40.rpx, 0.rpx, 40.rpx, 0.rpx),
onTap: () {
// TopSlideNotification.show(context,
// text: "待开发功能".tr);
Get.toNamed("/languagePage");
},
child: Container(
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 30.rpx, 0.rpx, 30.rpx),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisSize: MainAxisSize.max,
children: [
Text(
'切换语言',
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily: 'Inter',
color: Colors.white,
fontSize: AppConstants()
.title_text_fontSize,
letterSpacing: 0.0,
lineHeight: 1.0),
),
].divide(SizedBox(width: 22.rpx)),
),
Row(
mainAxisSize: MainAxisSize.max,
children: [
Obx(() {
return Text(
languageController
.selectLanguage
.value!
.language_name!,
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily: 'Inter',
color:
Color(0xFFD9E3EB),
fontSize: 26.rpx,
letterSpacing: 0.0,
lineHeight: 1.0,
),
);
}),
// SvgPicture.asset(
// 'assets/img/icon/arrow_right.svg',
// width: 8.rpx,
// height: 15
// .rpx, // 如果 SVG 中没有固定颜色,可以这样设置
// color: themeController
// .currentColor.sc3,
// ),
].divide(SizedBox(width: 28.rpx)),
),
],
),
),
),
),
ClickableContainer(
backgroundColor:
Colors.transparent, // 容器背景色
highlightColor: themeController
.currentColor.sc21, // 点击时的背景色
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 0.rpx, 0.rpx, 0.rpx),
onTap: () {
print('点击了容器');
Get.toNamed("/aboutUsPage");
},
child: Container(
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
40.rpx, 30.rpx, 40.rpx, 30.rpx),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisSize: MainAxisSize.max,
children: [
Text(
'设置页.关于我们'.tr,
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily: 'Inter',
color: Colors.white,
fontSize: AppConstants()
.title_text_fontSize,
letterSpacing: 0.0,
lineHeight: 1.0,
),
),
].divide(SizedBox(width: 22.rpx)),
),
SvgPicture.asset(
'assets/img/icon/arrow_right.svg',
width: 8.rpx,
height: 14
.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
color: themeController
.currentColor.sc3,
),
],
),
),
),
),
ClickableContainer(
backgroundColor:
Colors.transparent, // 容器背景色
highlightColor: themeController
.currentColor.sc21, // 点击时的背景色
padding: EdgeInsetsDirectional.fromSTEB(
40.rpx, 0.rpx, 40.rpx, 0.rpx),
onTap: () {
TopSlideNotification.show(context,
text: "待开发功能".tr);
},
child: Container(
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 30.rpx, 0.rpx, 30.rpx),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisSize: MainAxisSize.max,
children: [
Text(
'设置页.用户协议'.tr,
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily: 'Inter',
color: Colors.white,
fontSize: AppConstants()
.title_text_fontSize,
letterSpacing: 0.0,
lineHeight: 1.0,
),
),
].divide(SizedBox(width: 22.rpx)),
),
SvgPicture.asset(
'assets/img/icon/arrow_right.svg',
width: 8.rpx,
height: 15
.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
color: themeController
.currentColor.sc3,
),
],
),
),
),
),
ClickableContainer(
backgroundColor:
Colors.transparent, // 容器背景色
highlightColor: themeController
.currentColor.sc21, // 点击时的背景色
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 0.rpx, 0.rpx, 0.rpx),
onTap: () {
TopSlideNotification.show(context,
text: "待开发功能".tr);
},
child: Container(
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
40.rpx, 30.rpx, 40.rpx, 30.rpx),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisSize: MainAxisSize.max,
children: [
Text(
'设置页.隐私协议'.tr,
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily: 'Inter',
color: Colors.white,
fontSize: AppConstants()
.title_text_fontSize,
letterSpacing: 0.0,
lineHeight: 1.0,
),
),
].divide(SizedBox(width: 22.rpx)),
),
SvgPicture.asset(
'assets/img/icon/arrow_right.svg',
width: 8.rpx,
height: 14
.rpx, // 如果 SVG 中没有固定颜色,可以这样设置
color: themeController
.currentColor.sc3,
),
],
),
),
),
),
]
.divide(SizedBox(height: 0.rpx))
.addToStart(SizedBox(height: 30.rpx))
.addToEnd(SizedBox(height: 30.rpx)),
),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 174.rpx, 0.rpx, 0),
child: CustomCard(
borderRadius: 16.rpx,
// 圆角半径
onTap: () {
// ApiResponse apiResponse =
// userInfoController.logOut();
// TopSlideNotification.show(
// context,
// text: apiResponse.msg!,
// textColor:
// apiResponse.code == HttpStatusCodes.ok
// ? themeController.currentColor.sc2
// : themeController.currentColor.sc9,
// );
// if (apiResponse.code == HttpStatusCodes.ok) {
// Get.offAllNamed("/mianPageBottomChange");
// }
},
colors: [
Color(0XFF84F5FF),
], // 渐变色是同一个色,也可以根据需要调整
child: Container(
width:
// MediaQuery.sizeOf(context).width * 0.66,
bodySize.maxWidth,
height: MediaQuery.sizeOf(context).height * 0.055,
constraints: BoxConstraints(
minWidth: 500.rpx,
minHeight: 90.rpx,
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'设置页.退出登录'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
color: Color(0xFF003058),
fontFamily: 'Inter',
fontSize: AppConstants()
.normal_text_fontSize,
letterSpacing: 0.0,
),
),
].divide(SizedBox(
width: 17.rpx,
)),
),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
100.rpx, 20.rpx, 100.rpx, 0),
child: CustomCard(
borderRadius:
AppConstants().button_container_radius, // 圆角半径
onTap: () {
TopSlideNotification.show(
context,
text: "待开发功能".tr,
);
},
colors: [
Colors.transparent,
], // 渐变色是同一个色,也可以根据需要调整
child: Container(
width:
// MediaQuery.sizeOf(context).width * 0.66,
bodySize.maxWidth,
height: MediaQuery.sizeOf(context).height * 0.055,
constraints: BoxConstraints(
minWidth: 500.rpx,
minHeight: 90.rpx,
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'设置页.注销账号'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
color:
themeController.currentColor.sc9,
fontFamily: 'Inter',
fontSize: AppConstants()
.normal_text_fontSize,
letterSpacing: 0.0,
),
),
].divide(SizedBox(
width: 17.rpx,
)),
),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 135.rpx, 0.rpx, 0),
child: ClickableContainer(
borderRadius:
AppConstants().button_container_radius, // 圆角半径
onTap: () {},
backgroundColor:
Colors.transparent, // 渐变色是同一个色,也可以根据需要调整
highlightColor: themeController.currentColor.sc5,
padding: EdgeInsetsDirectional.fromSTEB(
0.rpx, 0.rpx, 0.rpx, 0),
child: Container(
width:
// MediaQuery.sizeOf(context).width * 0.66,
bodySize.maxWidth,
height: MediaQuery.sizeOf(context).height * 0.055,
constraints: BoxConstraints(
minWidth: 500.rpx,
minHeight: 90.rpx,
),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'ICP备案号:浙ICP备2023000785号-1'.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
color: themeController
.currentColor.sc4,
fontFamily: 'Inter',
fontSize: AppConstants()
.smaller_text_fontSize,
letterSpacing: 0.0,
),
),
Text(
'Copyright © 202-2025 嘉兴太和信息技术有限责任公司 版权所有'
.tr,
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
color: themeController
.currentColor.sc4,
fontFamily: 'Inter',
fontSize: AppConstants()
.smaller_text_fontSize,
letterSpacing: 0.0,
),
),
].divide(SizedBox(
height: 17.rpx,
))),
),
),
),
],
),
),
),
),
)),
);
});
}
}

View File

@@ -0,0 +1,815 @@
import 'dart:async';
import 'package:ef/base/widget/flutterflow/FlutterFlowTheme.dart';
import 'package:ef/ef.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/controller/main_bottom/global_controller.dart';
import 'package:vbvs_app/controller/mh/people_info_controller.dart';
import 'package:vbvs_app/pages/common/selectDialog.dart';
class PeopleInfoPage extends StatefulWidget {
const PeopleInfoPage({super.key});
@override
State<PeopleInfoPage> createState() => _PeopleInfoState();
}
class _PeopleInfoState extends State<PeopleInfoPage> {
get controller => Get.find<PeopleInfoController>();
get glcontroller => Get.find<GlobalController>();
// @override
// void initState() {
// super.initState();
// Timer(const Duration(milliseconds: 100), () {
// controller.getPeoples();
// });
// }
getLine() {
return Container(
height: 1,
color: stringToColor("#152676"),
);
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, boxConstraints) => GestureDetector(
// onTap: () => FocusScope.of(context).unfocus(),
onTap: () {
// 触摸收起键盘
FocusScope.of(context).requestFocus(FocusNode());
},
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/new_background.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
backgroundColor: Colors.transparent,
automaticallyImplyLeading: false,
iconTheme: IconThemeData(color: Colors.white),
titleSpacing: 0,
title: AppBar(
backgroundColor: Colors.transparent,
iconTheme: const IconThemeData(color: Colors.white),
automaticallyImplyLeading: false,
titleSpacing: 0,
title: SizedBox(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
// 中间居中的标题
Text(
'人员资料',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 30.rpx,
),
),
// 左侧图标
Positioned(
left: 20.rpx,
child: returnIconButtomNew,
),
Positioned(
right: 30.rpx,
child: CustomCard(
borderRadius: 10,
gradientDirection: GradientDirection.vertical,
onTap: () {
// bool isOk = true;
// for (var i = 0; i < 2; i++) {
// var d = controller.model.peopleList[i];
// print("${d.toJson()}");
// String before = "人员信息${i == 0 ? "A" : "B"}";
// if (isOk &&
// d.height != null &&
// d.height != "" &&
// int.tryParse("${d.height}") == null) {
// showToast("$before身高请输入数字");
// isOk = false;
// }
// if (isOk &&
// d.weight != null &&
// d.weight != "" &&
// int.tryParse("${d.weight}") == null) {
// showToast("$before体重请输入数字");
// isOk = false;
// }
// if (isOk &&
// d.tel != null &&
// d.tel != "" &&
// MyUtils.isValidPhoneNumber("${d.tel}") ==
// false) {
// showToast("$before请输入正确的电话");
// isOk = false;
// }
// if (isOk &&
// d.emergencyContact != null &&
// d.emergencyContact != "" &&
// MyUtils.isValidPhoneNumber(
// "${d.emergencyContact}") ==
// false) {
// showToast("$before请输入正确的紧急联系人电话");
// isOk = false;
// }
// if (isOk) {
// controller.savePeoples().then((d) {
// showToast("保存成功", color: color_success);
// }).catchError((d) {
// print("$d");
// showToast("保存失败");
// });
// }
// }
// controller.model.peopleList.forEach((d) {});
},
colors: const [
Color(0xFFFCFCFC),
Color(0xFFF8FAF9),
Color(0XFFECF6F3),
Color(0XFFD9F0E9),
Color(0xFFCEECE3)
],
child: Container(
width: 120.rpx,
height: 60.rpx,
alignment: Alignment.center,
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(5),
// color: stringToColor("#182B7C"),
// ),
child: Text(
"保存",
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: stringToColor("#9EA4B7"),
letterSpacing: 0,
fontSize: 30.rpx,
),
),
),
))
],
),
),
actions: [],
centerTitle: false,
),
centerTitle: false,
),
body: SafeArea(
top: true,
child: Container(
padding: EdgeInsets.only(left: 30.rpx, right: 30.rpx),
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height * 1.123,
// decoration: BoxDecoration(
// color: Colors.transparent,
// image: DecorationImage(
// image: AssetImage("assets/images/background.png"),
// fit: BoxFit.cover,
// ),
// ),
child: SingleChildScrollView(
child: Column(
children: [
...List.generate(
"${glcontroller.model.deviceMain["bindMacB"]}"
.length >
6
? 2
: 1, (index) {
String location_ = "";
if ("${glcontroller.model.deviceMain["bindMacB"]}"
.length >
6 &&
(glcontroller.model.mainDevicePeople[0]
?["direction"] ==
1 ||
glcontroller.model.mainDevicePeople[1]
?["direction"] ==
1)) {
location_ =
"${glcontroller.model.mainDevicePeople[index]?["direction"] == 1 ? '左侧' : '右侧'}";
}
return Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: EdgeInsets.only(
top: index == 0 ? 30.rpx : 90.rpx,
bottom: 20.rpx),
child: Text(
"人员信息${index == 0 ? "A" : "B"}",
style: TextStyle(
color: Colors.white, fontSize: 30.rpx),
),
),
Container(
padding:
EdgeInsets.only(left: 30.rpx, right: 30.rpx),
child: Column(
children: [
if (location_.isNotEmpty)
Container(
width: double.infinity,
height:
MediaQuery.sizeOf(context).height *
0.064,
decoration: BoxDecoration(),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'校准位置',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Color(0xFF9EA4B7),
fontSize: 30.rpx,
letterSpacing: 0,
),
),
Text(
'$location_',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Color(0xFF9EA4B7),
fontSize: 30.rpx,
letterSpacing: 0,
),
),
],
),
),
getLine(),
Container(
width: double.infinity,
height: MediaQuery.sizeOf(context).height *
0.064,
decoration: BoxDecoration(),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'性名',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Color(0xFF9EA4B7),
fontSize: 30.rpx,
letterSpacing: 0,
),
),
Container(
width: 300.rpx,
child: TextField(
obscureText: false,
textAlign: TextAlign.right,
style: TextStyle(
fontSize: 30.rpx,
color: Colors.white),
decoration: const InputDecoration(
fillColor: Colors.transparent,
filled: true,
hintText: "请输入姓名",
hintStyle: TextStyle(
color: Colors.white),
border: InputBorder.none,
contentPadding:
EdgeInsets.all(0)),
onChanged: (value) {
controller.model.peopleList[index]
.name = value;
controller.updateAll();
},
controller: controller.onReDraw(
TextEditingController(
text: controller
.model
.peopleList[index]
.name ??
""),
(textEditingController) {
textEditingController.text =
controller
.model
.peopleList[index]
.name ??
"";
}, "people_name_$index"),
),
),
],
),
),
getLine(),
Obx(
() => Container(
width: double.infinity,
height:
MediaQuery.sizeOf(context).height *
0.064,
decoration: BoxDecoration(),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'性别',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Color(0xFF9EA4B7),
fontSize: 30.rpx,
letterSpacing: 0,
),
),
InkWell(
onTap: () {
// 触摸收起键盘
FocusScope.of(context)
.requestFocus(FocusNode());
Future.delayed(
const Duration(
milliseconds: 250), () {
// 延迟执行的代码
showOneSelectionDialog(context,
arr: ["", ""],
checkIndex: controller
.model
.peopleList[
index]
.sex ==
""
? 0
: 1,
checkChange: (sindex) {
controller
.model
.peopleList[index]
.sex =
(sindex == 0 ? '' : '');
controller.updateAll();
print("sex $sindex");
}).then((d) {
// Timer(Duration.zero, () {
// FocusScope.of(context).unfocus();
// });
});
});
},
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Container(
width: 200.rpx,
child: Text(
'${controller.model.peopleList[index].sex}',
textAlign: TextAlign.right,
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily:
'Readex Pro',
color: Colors.white,
fontSize: 30.rpx,
letterSpacing: 0,
),
),
),
SizedBox(
width: 16.rpx,
),
Icon(
Icons.expand_more,
color: Colors.white,
size: 48.rpx,
),
],
),
),
],
),
),
),
getLine(),
Container(
width: double.infinity,
height: MediaQuery.sizeOf(context).height *
0.064,
decoration: BoxDecoration(),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'身高(cm)',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Color(0xFF9EA4B7),
fontSize: 30.rpx,
letterSpacing: 0,
),
),
Container(
width: 300.rpx,
child: TextField(
obscureText: false,
keyboardType: TextInputType.number,
textInputAction:
TextInputAction.done,
textAlign: TextAlign.right,
style: TextStyle(
fontSize: 30.rpx,
color: Colors.white),
decoration: InputDecoration(
fillColor: Colors.transparent,
filled: true,
hintText: "请输入身高(厘米)",
hintStyle: TextStyle(
color: Colors.white),
border: InputBorder.none,
contentPadding:
EdgeInsets.all(0)),
onChanged: (value) {
controller.model.peopleList[index]
.height = value;
controller.updateAll();
},
controller: controller.onReDraw(
TextEditingController(
text: controller
.model
.peopleList[index]
.height ??
""),
(textEditingController) {
textEditingController.text =
controller
.model
.peopleList[index]
.height ??
"";
}, "people_height_$index"),
),
)
],
),
),
getLine(),
Container(
width: double.infinity,
height: MediaQuery.sizeOf(context).height *
0.064,
decoration: BoxDecoration(),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'体重(kg)',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Color(0xFF9EA4B7),
fontSize: 30.rpx,
letterSpacing: 0,
),
),
Container(
width: 300.rpx,
child: TextField(
obscureText: false,
keyboardType: TextInputType.number,
textInputAction:
TextInputAction.done,
textAlign: TextAlign.right,
style: TextStyle(
fontSize: 30.rpx,
color: Colors.white),
decoration: InputDecoration(
fillColor: Colors.transparent,
filled: true,
hintText: "请输入体重(公斤)",
hintStyle: TextStyle(
color: Colors.white),
border: InputBorder.none,
contentPadding:
EdgeInsets.all(0)),
onChanged: (value) {
controller.model.peopleList[index]
.weight = value;
controller.updateAll();
},
controller: controller.onReDraw(
TextEditingController(
text: controller
.model
.peopleList[index]
.weight ??
""),
(textEditingController) {
textEditingController.text =
controller
.model
.peopleList[index]
.weight ??
"";
}, "people_weight_$index"),
),
),
],
),
),
getLine(),
Obx(
() => Container(
width: double.infinity,
height:
MediaQuery.sizeOf(context).height *
0.064,
decoration: BoxDecoration(),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'生日',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Color(0xFF9EA4B7),
fontSize: 30.rpx,
letterSpacing: 0,
),
),
InkWell(
onTap: () {
// 触摸收起键盘
FocusScope.of(context)
.requestFocus(FocusNode());
Future.delayed(
const Duration(
milliseconds: 250), () {
// 延迟执行的代码
showDateSelectionDialog(context,
checkDate: controller
.model
.peopleList[index]
.birthday ??
DateTime.now(),
checkChange: (DateTime d) {
controller
.model
.peopleList[index]
.birthday = d;
controller.updateAll();
print("$d");
}).then((d) {
// Timer(Duration.zero, () {
// FocusScope.of(context).unfocus();
// });
});
});
},
child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Container(
constraints: BoxConstraints(
minWidth: 200.rpx),
child: Text(
controller
.model
.peopleList[
index]
.birthday !=
null
? DateFormat(
"yyyy年MM月dd日")
.format(controller
.model
.peopleList[
index]
.birthday!)
: '',
textAlign: TextAlign.right,
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily:
'Readex Pro',
color: Colors.white,
fontSize: 30.rpx,
letterSpacing: 0,
),
),
),
SizedBox(
width: 16.rpx,
),
Icon(
Icons.expand_more,
color: Colors.white,
size: 48.rpx,
),
],
),
),
],
),
),
),
// getLine(),
// Container(
// width: double.infinity,
// height: MediaQuery.sizeOf(context).height *
// 0.064,
// decoration: BoxDecoration(),
// child: Row(
// mainAxisSize: MainAxisSize.max,
// mainAxisAlignment:
// MainAxisAlignment.spaceBetween,
// children: [
// Text(
// '电话',
// style: FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Readex Pro',
// color: Color(0xFF9EA4B7),
// fontSize: 30.rpx,
// letterSpacing: 0,
// ),
// ),
// Container(
// width: 300.rpx,
// child: TextField(
// obscureText: false,
// keyboardType: TextInputType.number,
// textInputAction:
// TextInputAction.done,
// textAlign: TextAlign.right,
// style: TextStyle(
// fontSize: 30.rpx,
// color: Colors.white),
// decoration: InputDecoration(
// fillColor: Colors.transparent,
// filled: true,
// hintText: "请输入电话",
// hintStyle: TextStyle(
// color: Colors.white),
// border: InputBorder.none,
// contentPadding:
// EdgeInsets.all(0)),
// onChanged: (value) {
// controller.model.peopleList[index]
// .tel = value;
// controller.updateAll();
// },
// controller: controller.onReDraw(
// TextEditingController(
// text: controller
// .model
// .peopleList[index]
// .tel ??
// ""),
// (textEditingController) {
// textEditingController.text =
// controller
// .model
// .peopleList[index]
// .tel ??
// "";
// }, "people_tel_$index"),
// ),
// ),
// ],
// ),
// ),
getLine(),
Container(
width: double.infinity,
height: MediaQuery.sizeOf(context).height *
0.064,
decoration: BoxDecoration(),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
'联系人',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Color(0xFF9EA4B7),
fontSize: 30.rpx,
letterSpacing: 0,
),
),
Container(
width: 300.rpx,
child: TextField(
obscureText: false,
keyboardType: TextInputType.number,
textInputAction:
TextInputAction.done,
textAlign: TextAlign.right,
style: TextStyle(
fontSize: 30.rpx,
color: Colors.white),
decoration: InputDecoration(
fillColor: Colors.transparent,
filled: true,
hintText: "请输入联系人",
hintStyle: TextStyle(
color: Colors.white),
border: InputBorder.none,
contentPadding:
EdgeInsets.all(0)),
onChanged: (value) {
controller.model.peopleList[index]
.emergencyContact = value;
controller.updateAll();
},
controller: controller.onReDraw(
TextEditingController(
text: controller
.model
.peopleList[index]
.emergencyContact ??
""),
(textEditingController) {
textEditingController.text =
controller
.model
.peopleList[index]
.emergencyContact ??
"";
}, "people_emergencyContact_$index"),
),
),
],
),
),
],
),
)
],
);
}),
SizedBox(
height: 100.rpx,
),
],
)),
),
),
),
)),
);
}
}

View File

@@ -0,0 +1,797 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:timeline_tile/timeline_tile.dart';
import 'package:vbvs_app/common/color/appColors.dart';
import 'package:vbvs_app/common/color/appFontsize.dart';
import 'package:vbvs_app/common/color/repair_status.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/controller/mh/repair_process.dart';
import 'package:vbvs_app/pages/device_control/repair_process_widget.dart';
import '../../component/img/img_preview_widget.dart';
import '../../controller/mh/apply_repair_controller.dart';
import '../../controller/mh/repair_info_controller.dart';
class RepairHistoryListPage extends GetView<RepairInfoController> {
final scaffoldKey = GlobalKey<ScaffoldState>();
BoxConstraints? bodysize;
@override
Widget build(BuildContext context) {
controller.model.applyRepairModel = ApplyRepairModel()
..id = 1001
..apply_name = '张三'
..tel = '13812345678'
..address = '北京市海淀区清华东路66号'
..desc = '床垫传感器失灵,无法监测心率和呼吸'
..create_time = DateTime.parse('2025-05-01 10:00:00')
..device_type = '床垫'
..device_category = 'BY-H'
..device_id = 'BD202505011001'
..device_name = '智能床垫 BY-H 型号'
..issue_img = [
'https://example.com/img1.jpg',
'https://example.com/img2.jpg'
]
..imagesLImit = 3
..img_bucket = 'mianhuatang_repair'
..status = '待处理'
..select_device = '床垫/BY-H/智能床垫'
..device_list = ['床垫/BY-H/智能床垫', '床垫/BY-A/智能床垫', '床垫/BY-C/智能床垫']
..score = null
..score_time = null
..messageType = 1
..repairId = 1001;
controller.model.repairProcessList = [
RepairProcessModel()
..status = '申请提交'
..create_time = DateTime.parse('2025-05-01 10:05:00')
..desc = '用户提交了维修申请'
..record_id = 1001
..deal_user = null,
RepairProcessModel()
..status = '客服受理'
..create_time = DateTime.parse('2025-05-01 10:20:00')
..desc = '客服已联系用户确认问题'
..record_id = 1001
..deal_user = 2001,
RepairProcessModel()
..status = '维修完成'
..create_time = DateTime.parse('2025-05-02 15:30:00')
..desc = '维修人员完成修复,等待用户确认'
..record_id = 1001
..deal_user = 3001,
];
final List events = controller.model.repairProcessList;
return LayoutBuilder(builder: (context, cc) {
bodysize = cc;
return WillPopScope(
child: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/new_background.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
// key: scaffoldKey,
backgroundColor: Colors.transparent,
appBar: AppBar(
backgroundColor: Colors.transparent,
iconTheme: const IconThemeData(color: Colors.white),
automaticallyImplyLeading: false,
titleSpacing: 0,
title: SizedBox(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
// 中间居中的标题
Text(
'详情',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 30.rpx,
),
),
// 左侧图标
Positioned(
left: 20.rpx,
child: returnIconButtomNew,
),
],
),
),
centerTitle: false,
),
body: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 1,
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(
30.rpx, 30.rpx, 30.rpx, 0),
child: Container(
width: bodysize!.maxWidth,
height: bodysize!.maxHeight * 1,
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding:
const EdgeInsetsDirectional.fromSTEB(
0, 0, 0, 10),
child: Container(
width: MediaQuery.sizeOf(context).width,
decoration: BoxDecoration(
color: Color(0xFF003058), //true
borderRadius: BorderRadius.circular(8),
),
child: Padding(
padding: const EdgeInsetsDirectional
.fromSTEB(17, 10, 0, 0),
child: Container(
decoration: const BoxDecoration(),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Align(
alignment:
const AlignmentDirectional(
-1, 0),
child: Text(
// 'SWES01号智能一键入眠床',
controller
.model
.applyRepairModel!
.device_name ??
'未命名',
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily:
'Readex Pro',
fontSize: 30.rpx,
letterSpacing: 0,
color: Colors.white,
),
),
),
Align(
alignment:
const AlignmentDirectional(
-1, 0),
child: Text(
'系列:' +
(controller
.model
.applyRepairModel!
.device_category ??
'未命名'),
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily:
'Readex Pro',
color: const Color(
0xFF929699),
fontSize: 26.rpx,
letterSpacing: 0,
),
),
),
Align(
alignment:
const AlignmentDirectional(
-1, 0),
child: Text(
'类型:' +
(controller
.model
.applyRepairModel!
.device_type ??
'未命名'),
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily:
'Readex Pro',
color: const Color(
0xFF929699),
fontSize: 26.rpx,
letterSpacing: 0,
),
),
),
Align(
alignment:
const AlignmentDirectional(
-1, 0),
child: Text(
'序列号:' +
(controller
.model
.applyRepairModel!
.device_id ??
'未命名'),
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily:
'Readex Pro',
color: const Color(
0xFF929699),
fontSize: 26.rpx,
letterSpacing: 0,
),
),
),
Align(
alignment:
const AlignmentDirectional(
-1, 0),
child: Text(
'报修单号:' +
(controller
.model
.applyRepairModel!
.id
.toString() ??
'未命名'),
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily:
'Readex Pro',
color: const Color(
0xFF929699),
fontSize: 26.rpx,
letterSpacing: 0,
),
),
),
Align(
alignment:
const AlignmentDirectional(
-1, 0),
child: Text(
'提交时间:' +
(MyUtils.formatDateTime(
controller
.model
.applyRepairModel!
.create_time!)),
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily:
'Readex Pro',
color: const Color(
0xFF929699),
fontSize: 26.rpx,
letterSpacing: 0,
),
),
),
Align(
alignment:
const AlignmentDirectional(
-1, 0),
child: Text(
'问题描述:' +
(controller
.model
.applyRepairModel!
.desc ??
'未命名'),
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily:
'Readex Pro',
color: const Color(
0xFF929699),
fontSize: 26.rpx,
letterSpacing: 0,
),
),
),
Padding(
padding:
const EdgeInsetsDirectional
.fromSTEB(
0, 10, 0, 24),
child: Container(
width: MediaQuery.sizeOf(
context)
.width,
height: MediaQuery.sizeOf(
context)
.height *
0.15,
constraints:
const BoxConstraints(
// minHeight: 140,
),
child: Container(
width: 100,
height: 100,
child: Obx(() =>
ListView(
shrinkWrap:
true,
scrollDirection:
Axis
.horizontal,
children: getImage(controller
.model
.applyRepairModel!)
.divide(
const SizedBox(
width:
12,
))
.addToStart(
const SizedBox(
width:
0,
))))),
)),
]
.divide(
const SizedBox(height: 5))
.addToStart(const SizedBox(
height: 5,
)),
),
)),
),
),
Padding(
padding:
const EdgeInsetsDirectional.fromSTEB(
0, 25, 0, 25), // 设置上下间距为 34
child: Align(
alignment: AlignmentDirectional
.centerStart, // 文字左对齐
child: Text(
'报修状态',
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: Colors.white,
fontSize: 30.rpx,
letterSpacing: 0.0,
),
),
),
),
Container(
width: bodysize!.maxWidth, // 设置宽度自适应
child: ListView.builder(
shrinkWrap: true, // 让ListView根据内容自适应高度
physics:
const NeverScrollableScrollPhysics(), // 禁用内部滚动,交由外部滚动视图处理
itemCount: events.length,
itemBuilder: (context, index) {
bool isLast =
index == events.length - 1;
return TimelineTile(
isFirst: index == 0,
isLast: isLast,
axis:
TimelineAxis.vertical, // 垂直方向时间轴
alignment:
TimelineAlign.start, // 线条左对齐
lineXY: 0.5, // 线条和圆圈相对位置
indicatorStyle: IndicatorStyle(
width: 15, // 圆圈的宽度
padding: const EdgeInsets.all(
1), // 避免线条进入圆圈内部
indicatorXY: 0.2, // 圆圈居中
indicator: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: const Color(
0xFFC8CBD2), // 最后一个元素为蓝色
width: 1,
),
color: stringToColor("#C8CBD2"),
),
),
),
beforeLineStyle: LineStyle(
color: stringToColor(
"#C8CBD2"), // 上方线条颜色
thickness: 1, // 线条厚度
),
afterLineStyle: LineStyle(
color: stringToColor(
"#C8CBD2"), // 最后一个节点的线条颜色
thickness: 1, // 线条厚度
),
endChild: Padding(
padding: const EdgeInsets.all(8.0),
child: RepairStatusWidget(
index: index,
repairInfoController: controller,
),
),
);
},
),
),
Obx(() {
if (RepairStatus.completed ==
controller.model.applyRepairModel!
.status &&
controller.model.applyRepairModel!
.score ==
null)
return Align(
alignment:
const AlignmentDirectional(1, 0),
child: Padding(
padding: const EdgeInsetsDirectional
.fromSTEB(17, 33, 0, 24),
child: Container(
width: 61,
height: MediaQuery.sizeOf(context)
.height *
0.03,
constraints: const BoxConstraints(
minHeight: 24,
),
decoration: const BoxDecoration(),
child: FFButtonWidget(
onPressed: () {
Get.toNamed("/scorePage");
},
text: '待评价',
options: FFButtonOptions(
height: 40,
padding:
const EdgeInsetsDirectional
.fromSTEB(0, 0, 0, 0),
iconPadding:
const EdgeInsetsDirectional
.fromSTEB(0, 0, 0, 0),
// color: FlutterFlowTheme.of(context)
// .secondaryBackground,
color: Colors.white,
textStyle:
FlutterFlowTheme.of(context)
.titleSmall
.override(
fontFamily:
'Readex Pro',
// color: Color(0xFF333333),
// color: stringToColor("#D3B684"),
color: stringToColor(
"#117EFD"),
fontSize: 11,
letterSpacing: 0,
),
elevation: 0,
borderSide: BorderSide(
// color: Color(0xFFC8CBD2),
// color: stringToColor("#D3B684"),
color:
stringToColor("#117EFD"),
width: 1,
),
borderRadius:
BorderRadius.circular(50),
),
),
),
),
);
return Container();
}),
Obx(() {
if (RepairStatus.completed ==
controller.model.applyRepairModel!
.status &&
controller.model.applyRepairModel!
.score !=
null)
return Padding(
padding: const EdgeInsetsDirectional
.fromSTEB(0, 0, 0, 5),
child: Container(
width:
MediaQuery.sizeOf(context).width,
decoration: BoxDecoration(
color: Colors.white, //true
borderRadius:
BorderRadius.circular(8),
),
child: Padding(
padding: const EdgeInsetsDirectional
.fromSTEB(0, 0, 0, 0),
child: Container(
decoration: const BoxDecoration(),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Padding(
padding:
const EdgeInsetsDirectional
.fromSTEB(
17, 0, 30, 10),
child: Container(
width: MediaQuery.sizeOf(
context)
.width,
height: 30,
decoration:
const BoxDecoration(),
child: Align(
alignment:
const AlignmentDirectional(
-1, 0),
child: Text(
'评价状态',
style: FlutterFlowTheme
.of(context)
.bodyMedium
.override(
fontFamily:
'Readex Pro',
color: const Color(
0xFF333333),
fontSize: 15,
letterSpacing:
0.0,
),
),
),
),
),
Align(
alignment:
const AlignmentDirectional(
-1, 0),
child: Padding(
padding:
const EdgeInsetsDirectional
.fromSTEB(
17, 0, 0, 0),
child: Container(
width:
MediaQuery.sizeOf(
context)
.width,
constraints:
const BoxConstraints(
minHeight: 24,
),
decoration:
const BoxDecoration(),
child: // Generated code for this Column Widget...
Column(
mainAxisSize:
MainAxisSize.max,
children: [
Align(
alignment:
const AlignmentDirectional(
-1, 0),
child: Padding(
padding:
const EdgeInsetsDirectional
.fromSTEB(
0,
0,
0,
10),
child: Text(
// '2023-08-22 12:12:44',
MyUtils.formatDateTime(
controller
.model
.applyRepairModel!
.score_time!),
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily:
'Readex Pro',
fontSize:
AppFontsize.normal_text_size,
letterSpacing:
0.0,
),
),
),
),
Row(
mainAxisSize:
MainAxisSize
.max,
children: [
Align(
alignment:
const AlignmentDirectional(
-1,
0),
child:
Padding(
padding:
const EdgeInsetsDirectional
.fromSTEB(
0,
0,
5,
0),
child: Text(
'已评价',
style: FlutterFlowTheme.of(
context)
.bodyMedium
.override(
fontFamily:
'Readex Pro',
fontSize:
AppFontsize.normal_text_size,
letterSpacing:
0.0,
),
),
),
),
Icon(
Icons.star,
color: controller
.model
.applyRepairModel!
.score! >=
1
? stringToColor(
"#F8AE00")
: stringToColor(
"#D0D0D0"),
size: 14,
),
Icon(
Icons.star,
color: controller
.model
.applyRepairModel!
.score! >=
2
? stringToColor(
"#F8AE00")
: stringToColor(
"#D0D0D0"),
size: 14,
),
Icon(
Icons.star,
color: controller
.model
.applyRepairModel!
.score! >=
3
? stringToColor(
"#F8AE00")
: stringToColor(
"#D0D0D0"),
size: 14,
),
Icon(
Icons.star,
color: controller
.model
.applyRepairModel!
.score! >=
4
? stringToColor(
"#F8AE00")
: stringToColor(
"#D0D0D0"),
size: 14,
),
Icon(
Icons.star,
color: controller
.model
.applyRepairModel!
.score! >=
5
? stringToColor(
"#F8AE00")
: stringToColor(
"#D0D0D0"),
size: 14,
),
],
),
],
),
),
),
),
]
.divide(const SizedBox(
height: 0))
.addToStart(const SizedBox(
height: 5,
))
.addToEnd(const SizedBox(
height: 15,
)),
),
),
),
),
);
return Container();
}),
],
),
),
),
),
),
],
),
),
),
)),
onWillPop: () async {
// 处理返回事件,比如弹出提示框等
print("页面返回事件");
return true; // 返回 true 允许页面返回,返回 false 阻止页面返回
},
);
});
}
List<Widget> getImage(ApplyRepairModel applyRepairModel) {
List<Widget> images = [];
ApplyRepairController controller = Get.find();
applyRepairModel.issue_img!.forEach((element) async {
images.add(
Container(
// height: 10,
// width: 10,
child: ImgPreviewWidget(
imgUrl: element,
index: applyRepairModel.issue_img!.indexOf(element),
applyRepairController: controller,
isDel: false,
),
),
);
});
return images;
}
}

View File

@@ -0,0 +1,144 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:flutterflow_ui/flutterflow_ui.dart';
import 'package:vbvs_app/common/color/appColors.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/controller/mh/repair_info_controller.dart';
import 'package:vbvs_app/controller/mh/repair_list_controller.dart';
import 'package:vbvs_app/pages/device_control/ColorChangeOnTap.dart';
import '../../common/color/appFontsize.dart';
class RepairHistoryWidget extends GetView<RepairInfoController> {
int index;
RepairListController repairListController;
RepairHistoryWidget(
{required this.index, required this.repairListController}) {}
@override
Widget build(BuildContext context) {
int tmp = index;
index = tmp;
return ColorChangeOnPress(
pressColor: AppColors().press_color, // 按下时的颜色
shouldNavigate: true, // 是否需要跳转
routeName: "/repairHistoryListPage", // 路由名称
topLeft: 16,
topRight: 16,
bottomLeft: 16,
bottomRight: 16,
onTap: () async {
// print("object");
// final RepairInfoController repairInfoController =
// Get.find<RepairInfoController>();
// await repairInfoController
// .initData(repairListController.model.repairList[index])
// .then((_) {
// repairInfoController.updateAll();
// // Get.toNamed("/repairHistoryListPage"); // 这个在 ColorChangeOnPress 中已经处理
// });
},
child: Container(
width: MediaQuery.sizeOf(context).width,
constraints: BoxConstraints(
minHeight: 70,
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(15, 14, 15, 13),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: MediaQuery.sizeOf(context).width * 0.5,
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Align(
alignment: AlignmentDirectional(-1, 0),
child: Text(
repairListController
.model.repairList[index].device_category ??
'',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Readex Pro',
color: Color(0xFF333333),
fontSize: AppFontsize.title_size,
letterSpacing: 0,
),
),
),
Align(
alignment: AlignmentDirectional(-1, 0),
child: Text(
"报修单号:${repairListController.model.repairList[index].id}",
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Readex Pro',
color: Color(0xFFC8CBD2),
fontSize: AppFontsize.small_text_size,
letterSpacing: 0,
),
),
),
Align(
alignment: AlignmentDirectional(-1, 0),
child: Text(
"提交时间:" +
(MyUtils.formatDateTime(repairListController
.model.repairList[index].create_time!) ??
''),
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Readex Pro',
color: Color(0xFFC8CBD2),
fontSize: AppFontsize.small_text_size,
letterSpacing: 0,
),
),
),
],
),
),
Container(
width: MediaQuery.sizeOf(context).width * 0.2,
height: MediaQuery.sizeOf(context).height * 0.075,
constraints: BoxConstraints(
maxWidth: 130,
),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Align(
alignment: AlignmentDirectional(0, 0),
child: Text(
repairListController.model.repairList[index].status ??
'',
style: FlutterFlowTheme.of(context).bodyMedium.override(
fontFamily: 'Readex Pro',
color: Color(0xFF333333),
fontSize: AppFontsize.normal_text_size,
letterSpacing: 0,
),
),
),
Flexible(
child: Align(
alignment: AlignmentDirectional(0, 0.05),
child: Icon(
Icons.arrow_forward_ios,
color: FlutterFlowTheme.of(context).secondaryText,
size: 10,
),
),
),
].divide(SizedBox(width: 27)),
),
),
],
),
),
),
);
}
}

View File

@@ -0,0 +1,575 @@
import 'package:ef/ef.dart';
import 'package:flutter/material.dart';
import 'package:vbvs_app/common/util/FitTool.dart';
import 'package:vbvs_app/common/util/MyUtils.dart';
import 'package:vbvs_app/component/tool/ClickableContainer.dart';
import 'package:vbvs_app/component/tool/CustomCard.dart';
import 'package:vbvs_app/controller/mh/apply_repair_controller.dart';
import 'package:vbvs_app/controller/mh/repair_list_controller.dart';
class DeviceRepairPage extends GetView<RepairListController> {
final scaffoldKey = GlobalKey<ScaffoldState>();
BoxConstraints? bodysize;
// final ScrollController scrollController = ScrollController();
// final RepairListController controller = Get.find();
// DeviceRepairPage() {
// controller.model.limit = AppConstants.limit;
// controller.model.offset = 0;
// controller.model.isLoading = false;
// controller.model.hasMore = true;
// controller.model.repairList.clear();
// controller.initData();
// Get.put(RepairListController());
// scrollController.addListener(() {
// if (scrollController.position.pixels ==
// scrollController.position.maxScrollExtent &&
// controller.model.hasMore) {
// controller.initData();
// controller.updateAll();
// }
// });
// }
final List<ApplyRepairModel> mockData = List.generate(4, (index) {
return ApplyRepairModel()
..device_name = "SWESO1号智能一键入眠床"
..status = index == 0 ? "已提交" : "已完成"
..create_time = DateTime(2024, 5, 12, 12, 5, 12);
});
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, cc) {
bodysize = cc;
return GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/new_background.png'), // 本地图片
fit: BoxFit.fill, // 填满整个 Container
),
),
child: Scaffold(
// key: scaffoldKey,
backgroundColor: Colors.transparent,
appBar: AppBar(
backgroundColor: Colors.transparent,
iconTheme: const IconThemeData(color: Colors.white),
automaticallyImplyLeading: false,
titleSpacing: 0,
title: SizedBox(
width: double.infinity,
height: 180.rpx,
child: Stack(
alignment: Alignment.center,
children: [
// 中间居中的标题
Text(
'设备报修',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 30.rpx,
),
),
// 左侧图标
Positioned(
left: 20.rpx,
child: returnIconButtomNew,
),
],
),
),
centerTitle: false,
),
body: SafeArea(
top: true,
child: Padding(
padding: EdgeInsets.fromLTRB(30.rpx, 6.rpx, 30.rpx, 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// 报修须知
Container(
height: 412.rpx,
decoration: BoxDecoration(
border: Border.all(
color: Color(0XFFC8CBD2), width: 0.rpx),
borderRadius: BorderRadius.circular(10),
),
child: Padding(
padding: EdgeInsets.fromLTRB(
27.rpx, 49.rpx, 43.rpx, 39.rpx),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.center,
children: [
// 固定的标题部分
Text(
"报修须知",
style: TextStyle(
fontSize: 30.rpx,
fontWeight: FontWeight.bold,
color: Colors.white,
),
textAlign: TextAlign.center,
),
SizedBox(height: 33.rpx),
// 可滚动的正文部分,限定高度
Expanded(
child: SingleChildScrollView(
child: RichText(
text: TextSpan(
style: TextStyle(
color: Color(0XFF929699),
fontSize: 26.rpx,
),
children: [
TextSpan(
text:
"尊敬的用户感谢您选择我司产品。在使用过程中如果设备出现故障需要维修请首先确认设备是否正确连接控制器或网络检查设置是否正常排除误操作问题。若问题依然存在请记录下设备名称、设备编号、和具体故障内容方便我们快速地为您提供帮助。您可以通过智慧棉花糖APP保修页面直接报修或拨打 ",
style: TextStyle(
color:
Color(0XFF929699),
fontSize: 26.rpx,
height: 1.3)),
TextSpan(
text: "400-8756-966",
style: TextStyle(
color: Colors.white,
// height: 1.3,
decoration: TextDecoration
.underline, // 添加下划线
decorationColor:
Colors.white,
decorationThickness: 4.rpx,
),
),
TextSpan(
text: " 反馈。",
style: TextStyle(
color:
Color(0XFF929699),
fontSize: 26.rpx,
height: 1.3)),
],
),
),
),
),
],
))),
SizedBox(height: 24.rpx),
InkWell(
onTap: () {
// bool isOk = true;
// for (var i = 0; i < 2; i++) {
// var d = controller.model.peopleList[i];
// print("${d.toJson()}");
// String before = "人员信息${i == 0 ? "A" : "B"}";
// if (isOk &&
// d.height != null &&
// d.height != "" &&
// int.tryParse("${d.height}") == null) {
// showToast("$before身高请输入数字");
// isOk = false;
// }
// if (isOk &&
// d.weight != null &&
// d.weight != "" &&
// int.tryParse("${d.weight}") == null) {
// showToast("$before体重请输入数字");
// isOk = false;
// }
// if (isOk &&
// d.tel != null &&
// d.tel != "" &&
// MyUtils.isValidPhoneNumber("${d.tel}") ==
// false) {
// showToast("$before请输入正确的电话");
// isOk = false;
// }
// if (isOk &&
// d.emergencyContact != null &&
// d.emergencyContact != "" &&
// MyUtils.isValidPhoneNumber(
// "${d.emergencyContact}") ==
// false) {
// showToast("$before请输入正确的紧急联系人电话");
// isOk = false;
// }
// if (isOk) {
// controller.savePeoples().then((d) {
// showToast("保存成功", color: color_success);
// }).catchError((d) {
// print("$d");
// showToast("保存失败");
// });
// }
// }
// controller.model.peopleList.forEach((d) {});
},
child: CustomCard(
borderRadius: 10,
gradientDirection: GradientDirection.vertical,
onTap: () {
Get.toNamed("/applyRepairPage");
},
colors: const [
Color(0xFFFCFCFC),
Color(0xFFF8FAF9),
Color(0XFFECF6F3),
Color(0XFFD9F0E9),
Color(0xFFCEECE3)
],
child: Container(
width: double.infinity,
height: 90.rpx,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
),
child: Text(
"我要报修",
style: FlutterFlowTheme.of(context)
.bodyMedium
.override(
fontFamily: 'Readex Pro',
color: stringToColor("#011D33"),
letterSpacing: 0,
fontSize: 30.rpx,
),
),
),
)),
SizedBox(height: 235.rpx),
// 报修历史标题
Container(
width: double.infinity,
child: Text("报修历史",
style: TextStyle(
color: Colors.white,
fontSize: 30.rpx,
height: 1)),
),
SizedBox(height: 32.rpx),
// 报修历史列表
Expanded(
child: ListView.builder(
itemCount: mockData.length,
itemBuilder: (context, index) {
final item = mockData[index];
return ClickableContainer(
backgroundColor: Colors.transparent,
highlightColor: Color(0XFF055466),
padding: EdgeInsets.only(top: 0),
onTap: () {
Get.toNamed("/repairHistoryListPage");
},
child: Container(
height: 119.rpx,
// margin: const EdgeInsets.only(bottom: 10),
// padding: const EdgeInsets.symmetric(
// vertical: 12, horizontal: 16),
decoration: BoxDecoration(
// color: const Color(0xFF06486F),
border: Border(
top: index == 0
? BorderSide(
color:
const Color(0xFF929699),
width: 1.rpx)
: BorderSide.none,
bottom: BorderSide(
color: const Color(0xFF929699),
width: 1.rpx),
),
),
child: Padding(
padding: EdgeInsets.fromLTRB(
17.rpx, 0, 30.rpx, 0),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
crossAxisAlignment:
CrossAxisAlignment.center,
children: [
// 左侧设备信息
Column(
mainAxisAlignment:
MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
item.device_name ?? '',
style: TextStyle(
color: Colors.white,
fontSize: 30.rpx),
),
const SizedBox(height: 4),
Text(
"提交时间:${item.create_time?.toString().substring(0, 19) ?? ''}",
style: TextStyle(
color: Colors.white60,
fontSize: 20.rpx),
),
],
),
// 右侧状态
Row(
children: [
Text(
item.status ?? '',
style: TextStyle(
color: Colors.white,
fontSize: 26.rpx),
),
Icon(Icons.arrow_forward_ios,
color: Colors.white,
size: 30.rpx),
],
)
],
),
)));
},
),
),
],
),
))
// Container(
// width: bodysize!.maxWidth,
// height: bodysize!.maxHeight * 1,
// decoration: BoxDecoration(
// color: Color(0xFFF6F6F6),
// ),
// child: Column(
// mainAxisSize: MainAxisSize.max,
// children: [
// // TitleComponentWidget(
// // titleName: '设备报修',
// // ),
// Expanded(
// child: Padding(
// padding: EdgeInsetsDirectional.fromSTEB(15, 0, 15, 0),
// child: Container(
// width: bodysize!.maxWidth,
// height: bodysize!.maxHeight * 0.9,
// decoration: BoxDecoration(
// color: Color(0xFFF6F6F6),
// ),
// child: Column(
// mainAxisSize: MainAxisSize.max,
// children: [
// Padding(
// padding:
// EdgeInsetsDirectional.fromSTEB(0, 14, 0, 13),
// child: Container(
// width: bodysize!.maxWidth,
// height: bodysize!.maxHeight * 0.186,
// constraints: BoxConstraints(
// minHeight: 170,
// ),
// decoration: BoxDecoration(
// color: FlutterFlowTheme.of(context)
// .secondaryBackground,
// borderRadius: BorderRadius.circular(16),
// border: Border.all(
// color: Colors.white,
// ),
// ),
// child: Column(
// mainAxisSize: MainAxisSize.max,
// children: [
// Padding(
// padding: EdgeInsetsDirectional.fromSTEB(
// 0, 14, 0, 18),
// child: Text(
// '报修须知',
// style: FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Readex Pro',
// fontSize: AppFontsize.title_size,
// letterSpacing: 0,
// fontWeight: FontWeight.w600,
// ),
// ),
// ),
// Flexible(
// child: Padding(
// padding: EdgeInsetsDirectional.fromSTEB(
// 14, 0, 14, 14), // 应用 padding
// child: SingleChildScrollView(
// child: Column(
// mainAxisSize: MainAxisSize.max,
// children: [
// Text(
// '尊敬的用户感谢您选择我司产品。在使用过程中如果设备出现故障或需要维修请首先确认设备是否正确连接电源和网络检查设置是否正常排除基本操作问题。若问题依然存在请记录下设备名称、设备型号、和具体故障情况等方便我们更快速地为您提供帮助。您可以通过智慧眠花糖APP保修或者直接拨打400-8756-966反馈。',
// style: FlutterFlowTheme.of(
// context)
// .bodyMedium
// .override(
// fontFamily: 'Readex Pro',
// color: Color(0xFF333333),
// fontSize: AppFontsize
// .small_text_size,
// letterSpacing: 0,
// lineHeight: 1.5,
// ),
// ),
// // 如果需要,可以在 Text 下面添加其他小部件
// ],
// ),
// ),
// ),
// )
// ],
// ),
// ),
// ),
// Padding(
// padding:
// EdgeInsetsDirectional.fromSTEB(0, 0, 0, 42),
// child: Container(
// width: bodysize!.maxWidth,
// height: 46,
// decoration: BoxDecoration(
// color: FlutterFlowTheme.of(context)
// .secondaryBackground,
// borderRadius: BorderRadius.circular(16),
// ),
// child: Container(
// width: bodysize!.maxWidth,
// height: bodysize!.maxHeight * 0.056,
// decoration: BoxDecoration(
// color: FlutterFlowTheme.of(context)
// .secondaryBackground,
// borderRadius: BorderRadius.circular(16),
// ),
// child: FFButtonWidget(
// onPressed: () {
// Get.toNamed("/applyRepairPage");
// },
// text: '我要报修',
// options: FFButtonOptions(
// height: 46,
// padding: EdgeInsetsDirectional.fromSTEB(
// 24, 0, 24, 0),
// iconPadding: EdgeInsetsDirectional.fromSTEB(
// 0, 0, 0, 0),
// color: Color(0xFFE55E92),
// textStyle: FlutterFlowTheme.of(context)
// .titleSmall
// .override(
// fontFamily: 'Readex Pro',
// color: Colors.white,
// fontSize: AppFontsize.title_size,
// letterSpacing: 0,
// ),
// elevation: 0,
// borderSide: BorderSide(
// color: Colors.transparent,
// width: 1,
// ),
// borderRadius: BorderRadius.circular(8),
// ),
// ),
// ),
// ),
// ),
// Expanded(
// child: Container(
// width: bodysize!.maxWidth,
// height: bodysize!.maxHeight * 1,
// decoration: BoxDecoration(
// color: Color(0xFFF6F6F6),
// ),
// child: Column(
// mainAxisSize: MainAxisSize.max,
// children: [
// Align(
// alignment: AlignmentDirectional(-1, 0),
// child: Padding(
// padding: EdgeInsetsDirectional.fromSTEB(
// 14, 0, 0, 17),
// child: Text(
// '报修历史',
// style: FlutterFlowTheme.of(context)
// .bodyMedium
// .override(
// fontFamily: 'Readex Pro',
// color: Color(0xFF333333),
// fontSize: AppFontsize.title_size,
// letterSpacing: 0,
// fontWeight: FontWeight.w600,
// ),
// ),
// ),
// ),
// Obx(() {
// return Visibility(
// visible:
// controller.model.repairList != null &&
// controller
// .model.repairList!.isNotEmpty,
// replacement:
// EmptyMessageWidget(),
// child: Expanded(
// // child: Obx(() =>
// child: ListView(
// controller:
// scrollController, // 绑定 ScrollController
// shrinkWrap: true,
// scrollDirection: Axis.vertical,
// children: (controller
// .model.repairList
// .asMap()
// .entries
// .map((e) =>
// RepairHistoryWidget(
// index: e.key,
// repairListController:
// controller))
// .toList() as List<Widget>)
// .divide(const SizedBox(
// height: 13,
// ))
// .addToEnd(SizedBox(
// height: AppConstants
// .list_end_height,
// )))
// // ),
// ),
// );
// }),
// ],
// ),
// ),
// ),
// ],
// ),
// ),
// ),
// ),
// ],
// ),
// ),
),
));
});
}
}

Some files were not shown because too many files have changed in this diff Show More