plan-create.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. <template>
  2. <view class="page">
  3. <view class="card">
  4. <view class="form-group">
  5. <text class="label">方案标题 <text class="required">*</text></text>
  6. <input
  7. class="input"
  8. v-model="title"
  9. placeholder="请输入方案标题"
  10. />
  11. </view>
  12. <view class="form-group">
  13. <text class="label">方案描述</text>
  14. <textarea
  15. class="textarea"
  16. v-model="description"
  17. placeholder="请输入方案描述(可选)"
  18. :maxlength="-1"
  19. />
  20. </view>
  21. </view>
  22. <view class="actions">
  23. <button class="btn-primary" :disabled="submitting" @click="submitPlan">
  24. {{ submitting ? '提交中...' : '保存方案' }}
  25. </button>
  26. <button class="btn-cancel" @click="goBack">取消</button>
  27. </view>
  28. </view>
  29. </template>
  30. <script>
  31. import { createTrainingPlan } from '@/utils/api.js'
  32. export default {
  33. data() {
  34. return {
  35. title: '',
  36. description: '',
  37. submitting: false
  38. }
  39. },
  40. methods: {
  41. submitPlan() {
  42. if (!this.title || !this.title.trim()) {
  43. uni.showToast({ title: '请输入方案标题', icon: 'none' })
  44. return
  45. }
  46. this.submitting = true
  47. // 创建方案(memberId 留空,由后端关联当前用户)
  48. createTrainingPlan(null, this.title.trim(), this.description.trim() || '')
  49. .then(res => {
  50. this.submitting = false
  51. if (res && res.code === 200) {
  52. uni.showToast({ title: '创建成功', icon: 'success' })
  53. // 延迟跳转,让用户看到成功提示
  54. setTimeout(() => {
  55. uni.navigateBack()
  56. }, 1000)
  57. } else {
  58. uni.showToast({ title: (res && res.message) || '创建失败', icon: 'none' })
  59. }
  60. })
  61. .catch(err => {
  62. this.submitting = false
  63. console.error('创建方案失败', err)
  64. uni.showToast({ title: '创建失败', icon: 'none' })
  65. })
  66. },
  67. goBack() {
  68. uni.navigateBack()
  69. }
  70. }
  71. }
  72. </script>
  73. <style scoped lang="scss">
  74. .page {
  75. padding: 24rpx;
  76. background: $facade-fill-blue-ghost;
  77. min-height: 100vh;
  78. }
  79. .card {
  80. background: $app-surface;
  81. border-radius: 16rpx;
  82. padding: 30rpx;
  83. margin-bottom: 20rpx;
  84. }
  85. .form-group {
  86. margin-bottom: 30rpx;
  87. }
  88. .form-group:last-child {
  89. margin-bottom: 0;
  90. }
  91. .label {
  92. font-size: 28rpx;
  93. color: #1F2D3D;
  94. display: block;
  95. margin-bottom: 12rpx;
  96. font-weight: 500;
  97. }
  98. .required {
  99. color: #F44336;
  100. }
  101. .input {
  102. width: 100%;
  103. height: 80rpx;
  104. background: #F7F9FC;
  105. border-radius: 12rpx;
  106. padding: 0 20rpx;
  107. font-size: 28rpx;
  108. color: #1F2D3D;
  109. box-sizing: border-box;
  110. }
  111. .textarea {
  112. width: 100%;
  113. min-height: 200rpx;
  114. background: #F7F9FC;
  115. border-radius: 12rpx;
  116. padding: 20rpx;
  117. font-size: 28rpx;
  118. color: #1F2D3D;
  119. box-sizing: border-box;
  120. }
  121. .actions {
  122. display: flex;
  123. flex-direction: column;
  124. gap: 16rpx;
  125. }
  126. .btn-primary {
  127. width: 100%;
  128. background: $brand-primary;
  129. color: $app-surface;
  130. font-size: 30rpx;
  131. font-weight: 600;
  132. padding: 24rpx 0;
  133. border-radius: 12rpx;
  134. border: none;
  135. }
  136. .btn-primary:disabled {
  137. background: $facade-text-ghost;
  138. }
  139. .btn-cancel {
  140. width: 100%;
  141. background: #F2F4F7;
  142. color: #5A6478;
  143. font-size: 30rpx;
  144. padding: 24rpx 0;
  145. border-radius: 12rpx;
  146. border: none;
  147. }
  148. </style>