图书馆小程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

245 lines
4.9 KiB

2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
  1. <template>
  2. <view class="feedback-container">
  3. <view class="form-box">
  4. <view class="item">
  5. <text class="label">姓名</text>
  6. <input
  7. class="input"
  8. placeholder="请输入姓名"
  9. v-model="formData.name"
  10. :disabled="hasNickname"
  11. />
  12. </view>
  13. <view class="item">
  14. <text class="label">读者证</text>
  15. <input
  16. class="input"
  17. placeholder="请输入读者证号"
  18. v-model="formData.readerCard"
  19. disabled
  20. />
  21. </view>
  22. <view class="item">
  23. <text class="label">主题</text>
  24. <input
  25. class="input"
  26. placeholder="请输入主题(最少5个字)"
  27. v-model="formData.subject"
  28. maxlength="50"
  29. />
  30. </view>
  31. <view class="item">
  32. <text class="label">联系方式/手机号码</text>
  33. <input
  34. class="input"
  35. placeholder="请输入手机号码"
  36. v-model="formData.phone"
  37. type="number"
  38. maxlength="11"
  39. />
  40. </view>
  41. <view class="item textarea-item">
  42. <text class="label">您的建议或意见</text>
  43. <textarea
  44. class="textarea"
  45. placeholder="HI,请留下您的留言吧!(最少10个字)"
  46. v-model="formData.content"
  47. :maxlength="500"
  48. />
  49. </view>
  50. <button class="commit" type="primary" @click="onBtnClick">提交</button>
  51. </view>
  52. </view>
  53. </template>
  54. <script>
  55. import { getCurrentReaderCard } from '@/utils/storage';
  56. const USER_KEY = 'user-info';
  57. export default {
  58. data() {
  59. return {
  60. hasNickname: false,
  61. formData: {
  62. name: '',
  63. readerCard: '',
  64. subject: '',
  65. phone: '',
  66. content: ''
  67. }
  68. };
  69. },
  70. onLoad() {
  71. this.loadReaderCardInfo();
  72. this.loadUserInfo();
  73. },
  74. methods: {
  75. async loadReaderCardInfo() {
  76. try {
  77. const readerCard = await getCurrentReaderCard();
  78. if (readerCard) {
  79. this.formData.readerCard = readerCard.bindValue || '';
  80. }
  81. } catch (err) {
  82. console.error('获取读者证信息失败:', err);
  83. }
  84. },
  85. loadUserInfo() {
  86. const userInfo = uni.getStorageSync(USER_KEY) || {};
  87. if (userInfo.nickname) {
  88. this.formData.name = userInfo.nickname;
  89. this.hasNickname = true;
  90. }
  91. },
  92. validatePhone(phone) {
  93. const phoneReg = /^1[3-9]\d{9}$/;
  94. return phoneReg.test(phone);
  95. },
  96. onBtnClick() {
  97. const { name, readerCard, subject, phone, content } = this.formData;
  98. if (!name || name.trim().length === 0) {
  99. uni.showToast({
  100. title: '请输入姓名',
  101. icon: 'none'
  102. });
  103. return;
  104. }
  105. if (!readerCard || readerCard.trim().length === 0) {
  106. uni.showToast({
  107. title: '请先绑定读者证',
  108. icon: 'none'
  109. });
  110. return;
  111. }
  112. if (!subject || subject.trim().length < 5) {
  113. uni.showToast({
  114. title: '主题至少需要5个字',
  115. icon: 'none'
  116. });
  117. return;
  118. }
  119. if (!phone) {
  120. uni.showToast({
  121. title: '请输入手机号码',
  122. icon: 'none'
  123. });
  124. return;
  125. }
  126. if (!this.validatePhone(phone)) {
  127. uni.showToast({
  128. title: '手机号码格式不正确',
  129. icon: 'none'
  130. });
  131. return;
  132. }
  133. if (!content || content.trim().length < 10) {
  134. uni.showToast({
  135. title: '建议内容至少需要10个字',
  136. icon: 'none'
  137. });
  138. return;
  139. }
  140. uni.showLoading({
  141. title: '提交中'
  142. });
  143. setTimeout(() => {
  144. uni.hideLoading();
  145. uni.showToast({
  146. title: '提交成功',
  147. icon: 'success',
  148. mask: true
  149. });
  150. setTimeout(() => {
  151. uni.navigateBack();
  152. }, 1500);
  153. }, 1000);
  154. }
  155. }
  156. };
  157. </script>
  158. <style lang="scss" scoped>
  159. .feedback-container {
  160. padding: 15px;
  161. background-color: #f5f5f5;
  162. min-height: 100vh;
  163. }
  164. .form-box {
  165. background-color: #fff;
  166. border-radius: 10px;
  167. padding: 20px;
  168. }
  169. .item {
  170. margin-bottom: 20px;
  171. }
  172. .label {
  173. display: block;
  174. font-size: 15px;
  175. font-weight: bold;
  176. color: #333;
  177. margin-bottom: 10px;
  178. }
  179. .input {
  180. width: 100%;
  181. height: 44px;
  182. background-color: #f5f5f5;
  183. border-radius: 6px;
  184. padding: 0 15px;
  185. font-size: 14px;
  186. color: #333;
  187. box-sizing: border-box;
  188. }
  189. .input[disabled] {
  190. background-color: #e8e8e8;
  191. color: #999;
  192. }
  193. .textarea-item {
  194. margin-bottom: 30px;
  195. }
  196. .textarea {
  197. width: 100%;
  198. min-height: 120px;
  199. background-color: #f5f5f5;
  200. border-radius: 6px;
  201. padding: 12px 15px;
  202. font-size: 14px;
  203. color: #333;
  204. box-sizing: border-box;
  205. line-height: 1.6;
  206. }
  207. .commit {
  208. width: 100%;
  209. height: 44px;
  210. background-color: #01a4fe;
  211. color: #fff;
  212. border-radius: 22px;
  213. font-size: 16px;
  214. border: none;
  215. margin-top: 20px;
  216. }
  217. .commit::after {
  218. border: none;
  219. }
  220. </style>