tab2.page.html 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. <ion-header sticky>
  2. <ion-toolbar>
  3. <ion-segment [(ngModel)]="selectedTab" color="primary" class="custom-segment">
  4. <ion-segment-button value="checkin">
  5. <ion-icon aria-hidden="true" name="calendar"></ion-icon>
  6. 打卡
  7. </ion-segment-button>
  8. <ion-segment-button value="plan">
  9. <ion-icon name="checkmark-circle" aria-hidden="true"></ion-icon>
  10. 计划
  11. </ion-segment-button>
  12. <ion-segment-button value="consultation">
  13. <ion-icon name="help-circle" aria-hidden="true"></ion-icon>
  14. 问诊
  15. </ion-segment-button>
  16. </ion-segment>
  17. </ion-toolbar>
  18. </ion-header>
  19. <ion-content [fullscreen]="true">
  20. <div style="height: 56px;"></div>
  21. <!-- 打卡 -->
  22. <div *ngIf="selectedTab === 'checkin'" class="checkin">
  23. <ion-card-content *ngFor="let user of planUser">
  24. <ion-card>
  25. <ion-card-header>
  26. <ion-card-title>欢迎回来!{{ user.get('name') }}</ion-card-title>
  27. </ion-card-header>
  28. <ion-card-content>
  29. <div class="greeting-container">
  30. <!-- 头像和信息容器 -->
  31. <div class="avatar-info-container">
  32. <!-- 头像部分 -->
  33. <div class="avatar-container">
  34. <img [src]="user.get('avater')" alt="用户头像" class="avatar">
  35. </div>
  36. <!-- 用户信息部分 -->
  37. <div class="user-info">
  38. <ion-card>
  39. <ion-card-content>
  40. <p><strong>身高:</strong>{{ user.get('height') }} cm</p>
  41. <p><strong>体重:</strong>{{ user.get('weight') }} kg</p>
  42. <p><strong>BMI:</strong>{{ calculateBMI(user.get('height'), user.get('weight')) }}</p>
  43. <p><strong>运动目标:</strong>{{ user.get('fitnessGoals') }}</p>
  44. </ion-card-content>
  45. </ion-card>
  46. <ion-label>{{ getEncouragement(calculateBMI(user.get('height'), user.get('weight'))) }}</ion-label>
  47. </div>
  48. </div>
  49. </div>
  50. </ion-card-content>
  51. </ion-card>
  52. <ion-card>
  53. <ion-card-header>
  54. <ion-card-title>打卡区域</ion-card-title>
  55. <div class="power-label">
  56. <strong>我的动能</strong>
  57. <p class="stat-value">{{ user.get('power') }}</p>
  58. </div>
  59. </ion-card-header>
  60. <ion-card-content>
  61. <ion-datetime [value]="realDate.toISOString()" (ionChange)="onDateChange($event)">
  62. </ion-datetime>
  63. <div class="card-info">
  64. <ion-button [disabled]="getButtonState(realDate).isDisabled"
  65. (click)="getButtonState(realDate).buttonText === '补签' ? handleMakeupClick() : markAttendance()"
  66. class="check">
  67. {{ getButtonState(realDate).buttonText }}
  68. </ion-button>
  69. </div>
  70. <div class="card-stats">
  71. <div class="stat-item">
  72. <p><strong>已打卡天数</strong></p>
  73. <p class="stat-value">{{ user.get('days') }}</p>
  74. </div>
  75. <div class="stat-item">
  76. <p><strong>连续打卡天数</strong></p>
  77. <p class="stat-value">{{ user.get('sucdays') }}</p>
  78. </div>
  79. </div>
  80. </ion-card-content>
  81. </ion-card>
  82. <ion-card>
  83. <!-- 未登录 -->
  84. @if(!currentUser?.id){
  85. <ion-card-header>
  86. <ion-card-title>请登录</ion-card-title>
  87. <ion-card-subtitle>暂无信息</ion-card-subtitle>
  88. </ion-card-header>
  89. }
  90. <!-- 未登录 -->
  91. @if(currentUser?.id){
  92. <ion-card-header>
  93. <ion-card-title>{{currentUser?.get("username")}} {{currentUser?.get("realname")}}</ion-card-title>
  94. <ion-card-subtitle>性别:{{currentUser?.get("gender")||"-"}} 年龄:{{currentUser?.get("age")||"-"}}
  95. </ion-card-subtitle>
  96. </ion-card-header>
  97. }
  98. <ion-card-content>
  99. @if(!currentUser?.id){
  100. <ion-button expand="block" (click)="signup()">注册</ion-button>
  101. <ion-button expand="block" (click)="login()">登录</ion-button>
  102. }
  103. @if(currentUser?.id){
  104. <ion-button expand="block" (click)="editUser()">编辑资料</ion-button>
  105. <ion-button expand="block" (click)="logout()" color="light">登出</ion-button>
  106. }
  107. </ion-card-content>
  108. </ion-card>
  109. </ion-card-content>
  110. </div>
  111. <!-- 计划 -->
  112. <div *ngIf="selectedTab === 'plan'" class="plan">
  113. <ion-card-content>
  114. <ion-card>
  115. <ion-card-header>
  116. <ion-card-title>我的本周计划</ion-card-title>
  117. </ion-card-header>
  118. <div class="plan-table">
  119. <ion-grid class="table">
  120. <ion-row>
  121. <ion-col size="1.5" class="grid-header">日期</ion-col>
  122. <ion-col size="1.5" class="grid-header">部位</ion-col>
  123. <ion-col size="1.5" class="grid-header">项目1</ion-col>
  124. <ion-col size="2.5" class="grid-header">项目2</ion-col>
  125. <ion-col size="2.5" class="grid-header">项目3</ion-col>
  126. <ion-col size="2.5" class="grid-header">项目4</ion-col>
  127. </ion-row>
  128. <!-- 绑定计划数据 -->
  129. <ion-row *ngFor="let day of planList">
  130. <ion-item-sliding>
  131. <ion-item>
  132. <!-- 显示计划内容 -->
  133. <ion-col size="1" class="plan-column">{{ day.get('date') }}</ion-col>
  134. <ion-col size="1" class="plan-column">{{ day.get('trainingPart') }}</ion-col>
  135. <!-- 显示每个训练项目,确保即使为空也占位 -->
  136. <ion-col size="2.5" *ngFor="let task of day.get('trainingItems'); let i = index" class="plan-column">
  137. <div class="task-container">
  138. <span class="task-item">{{ task.item || '' }}</span>
  139. <span class="sets-reps">{{ task.sets }} x {{ task.reps }}</span>
  140. </div>
  141. </ion-col>
  142. </ion-item>
  143. <!-- 滑动时显示的按钮,设置 side="end" 来将按钮显示在右边 -->
  144. <ion-item-options side="end">
  145. <ion-item-option class="edit-btn" color="primary" shape="round" (click)="editPlan(day)">编辑
  146. </ion-item-option>
  147. <ion-item-option class="delete-btn" color="danger" (click)="deletePlan(day)">删除</ion-item-option>
  148. </ion-item-options>
  149. </ion-item-sliding>
  150. </ion-row>
  151. </ion-grid>
  152. </div>
  153. </ion-card>
  154. <ion-card-subtitle>
  155. <ion-icon name="alert-circle-outline" style="margin-right: 5px;"></ion-icon>左滑行内数据可对计划进行修改哦!
  156. </ion-card-subtitle>
  157. <ion-button expand="full" shape="round" class="reverse" (click)="regeneratePlan()">
  158. <ion-icon name="infinite-outline" style="margin-right:5px ;"></ion-icon>重新生成计划
  159. </ion-button>
  160. </ion-card-content>
  161. </div>
  162. <!-- 问诊 -->
  163. <div *ngIf="selectedTab === 'consultation'" class="consult">
  164. <ion-card-content>
  165. <div
  166. style="width: 95%; margin: auto; height: 110px; display: flex; justify-content: space-between; background-color: #ffffff; border: 1px solid #e7e7db; border-radius: 20px; overflow: hidden;"
  167. (click)="doPoemTask()">
  168. <!-- 左侧内容部分 -->
  169. <div
  170. style="display: flex; flex-direction: column; justify-content: flex-start; margin-top: 23px; margin-left: 40px; position: relative;">
  171. <!-- 品牌动态提示标签 -->
  172. <div
  173. style="position: absolute; padding: 5px; color: #fff; background-color: #009b7d; top: -25px; left: -20px; border-radius: 7px; font-size: 12px;">
  174. 健身动作
  175. </div>
  176. <!-- 标题 -->
  177. <h3>
  178. 一键<span style="color: #6dbdac; font-size: 30px; font-weight: bolder; font-family: SimSun;">生成</span>
  179. </h3>
  180. <!-- 按钮 -->
  181. <div style="color: #fff;">
  182. <ion-button size="small" class="lan">点击了解-></ion-button>
  183. </div>
  184. </div>
  185. <!-- 右侧图片部分 -->
  186. <div>
  187. <img src="../../assets/images/action5.png" style="height: 100px; display: flex; justify-content: flex-end;"
  188. alt="">
  189. </div>
  190. </div>
  191. <!-- 任务区域 -->
  192. <ion-card *ngIf="actionTaskVisible">
  193. <ion-card-header>
  194. <ion-card-title>动作生成</ion-card-title>
  195. </ion-card-header>
  196. <ion-card-content>
  197. <div *ngFor="let step of actionTaskList">
  198. <ion-item>
  199. <ion-icon *ngIf="step.progress === 0 && !step.error" name="radio-button-off-outline"></ion-icon>
  200. <ion-icon *ngIf="step.progress !== 0 && step.progress !== 1" name="reload-outline"></ion-icon>
  201. <ion-icon *ngIf="step.progress === 1" name="checkmark-circle-outline"></ion-icon>
  202. <ion-icon *ngIf="step.error" name="close-circle-outline"></ion-icon>
  203. {{ step.title }}
  204. <span *ngIf="step.progress">{{ step.progress * 100 | number:'2.0-0' }}%</span>
  205. <span *ngIf="step.error" style="color:red;">{{ step.error }}</span>
  206. </ion-item>
  207. </div>
  208. </ion-card-content>
  209. </ion-card>
  210. <!-- 图片展示 -->
  211. <ion-card *ngIf="shareData.images">
  212. <ion-card-header>
  213. <ion-card-title>动作展示</ion-card-title>
  214. </ion-card-header>
  215. <ion-card-content>
  216. <div *ngFor="let imageUrl of shareData.images">
  217. <img [src]="imageUrl" alt="诊断图片" style="width: 100%; height: 400px; object-fit: cover;" />
  218. </div>
  219. </ion-card-content>
  220. </ion-card>
  221. <!-- 诊断结果 -->
  222. <!-- AI教练互动 -->
  223. <ion-card id="coaches">
  224. <ion-card-header>
  225. <ion-card-title>教练简介</ion-card-title>
  226. <ion-card-subtitle>顶级教练</ion-card-subtitle>
  227. </ion-card-header>
  228. <ion-card-content style="padding: 5px;">
  229. <ion-list>
  230. <ion-item *ngFor="let coach of coachList" lines="none">
  231. <ion-thumbnail slot="start">
  232. <img [src]="coach.get('avater') || '../../assets/images/coach1.jpg'" [alt]="coach.get('name')" />
  233. </ion-thumbnail>
  234. <div class="coach-info" style="width: 120px;">
  235. <h3>{{ coach.get('name') }}({{ coach.get('age') }}岁)</h3>
  236. <p>擅长领域:{{ coach.get('specialize')}}</p>
  237. <p>WiseFitness俱乐部</p>
  238. </div>
  239. <div style="margin-left: 10px;">
  240. <ion-button shape="round" size="small" (click)="openInquiry(coach)">
  241. <ion-icon name="logo-gitlab" style="margin-right: 5px;"></ion-icon>
  242. 立即咨询
  243. </ion-button>
  244. </div>
  245. </ion-item>
  246. </ion-list>
  247. </ion-card-content>
  248. </ion-card>
  249. <div
  250. style="width: 95%; margin: auto; height: 110px; display: flex; justify-content: space-between; background-color: #ffffff; border: 1px solid #e7e7db; border-radius: 20px; overflow: hidden;"
  251. (click)="doInqueryTask()">
  252. <!-- 左侧内容部分 -->
  253. <div
  254. style="display: flex; flex-direction: column; justify-content: flex-start; margin-top: 23px; margin-left: 40px; position: relative;">
  255. <!-- 品牌动态提示标签 -->
  256. <div
  257. style="position: absolute; padding: 5px; color: #fff; background-color: #009b7d; top: -25px; left: -20px; border-radius: 7px; font-size: 12px;">
  258. 身体疼痛
  259. </div>
  260. <!-- 标题 -->
  261. <h3>
  262. 一键<span style="color: #6dbdac; font-size: 30px; font-weight: bolder; font-family: SimSun;">诊断</span>
  263. </h3>
  264. <!-- 按钮 -->
  265. <div style="color: #fff;">
  266. <ion-button size="small" class="lan">点击诊断-></ion-button>
  267. </div>
  268. </div>
  269. <!-- 右侧图片部分 -->
  270. <div>
  271. <img src="../../assets/images/battle1.png" style="height: 100px; display: flex; justify-content: flex-end;"
  272. alt="">
  273. </div>
  274. </div>
  275. <ion-card *ngIf="healthTaskVisible">
  276. <ion-card-header>
  277. <ion-card-title>医疗诊断</ion-card-title>
  278. </ion-card-header>
  279. <ion-card-content>
  280. <div *ngFor="let step of healthTaskList">
  281. <ion-item>
  282. <ion-icon *ngIf="step.progress === 0 && !step.error" name="radio-button-off-outline"></ion-icon>
  283. <ion-icon *ngIf="step.progress !== 0 && step.progress !== 1" name="reload-outline"></ion-icon>
  284. <ion-icon *ngIf="step.progress === 1" name="checkmark-circle-outline"></ion-icon>
  285. <ion-icon *ngIf="step.error" name="close-circle-outline"></ion-icon>
  286. {{ step.title }}
  287. <span *ngIf="step.progress">{{ step.progress * 100 | number:'2.0-0' }}%</span>
  288. <span *ngIf="step.error" style="color:red;">{{ step.error }}</span>
  289. </ion-item>
  290. </div>
  291. </ion-card-content>
  292. </ion-card>
  293. <ion-card *ngIf="shareData.diagResult">
  294. <ion-card-header>
  295. <ion-card-title>{{ shareData.diagResult.title }}</ion-card-title>
  296. </ion-card-header>
  297. <ion-card-content>
  298. <h2>{{ shareData.diagResult.desc }}</h2>
  299. <fm-markdown-preview class="content-style" [content]=shareData.diagResult.content>
  300. </fm-markdown-preview>
  301. </ion-card-content>
  302. </ion-card>
  303. </ion-card-content>
  304. </div>
  305. </ion-content>