普兆健康管家前端代码仓库
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.

305 lines
7.0 KiB

  1. <template>
  2. <view>
  3. <uv-popup ref="popup" mode="bottom" bgColor="none" >
  4. <view class="popup__view">
  5. <view class="flex header">
  6. <view class="title">{{ title }}</view>
  7. <button class="btn" @click="close">关闭</button>
  8. </view>
  9. <view class="form">
  10. <uv-form
  11. ref="form"
  12. :model="form"
  13. :rules="rules"
  14. errorType="toast"
  15. >
  16. <view class="form-item">
  17. <uv-form-item prop="name" :customStyle="formItemStyle">
  18. <view class="form-item-label">联系人</view>
  19. <view class="form-item-content">
  20. <formInput v-model="form.name"></formInput>
  21. </view>
  22. </uv-form-item>
  23. </view>
  24. <view class="form-item">
  25. <uv-form-item prop="phone" :customStyle="formItemStyle">
  26. <view class="form-item-label">手机号</view>
  27. <view class="form-item-content">
  28. <formInput v-model="form.phone"></formInput>
  29. </view>
  30. </uv-form-item>
  31. </view>
  32. <view class="form-item">
  33. <uv-form-item prop="phone" :customStyle="formItemStyle">
  34. <view class="form-item-label">所在地区</view>
  35. <view class="form-item-content">
  36. <picker mode="region" @change="onAreaChange" :value="form.area">
  37. <view class="flex region">
  38. <view v-if="form.area">{{ form.area.join('') }}</view>
  39. <view v-else class="placeholder">选择省市区街道</view>
  40. </view>
  41. </picker>
  42. </view>
  43. </uv-form-item>
  44. </view>
  45. <view class="form-item">
  46. <uv-form-item prop="detail" :customStyle="formItemStyle">
  47. <view class="form-item-label">详细地址</view>
  48. <view class="form-item-content">
  49. <formInput v-model="form.detail" placeholder="小区楼栋、门牌号、村等"></formInput>
  50. </view>
  51. </uv-form-item>
  52. </view>
  53. </uv-form>
  54. </view>
  55. <view class="footer">
  56. <button class="flex btn" @click="onSave">保存</button>
  57. </view>
  58. </view>
  59. </uv-popup>
  60. </view>
  61. </template>
  62. <script>
  63. import formInput from '@/pages_order/components/formInput.vue'
  64. export default {
  65. components: {
  66. formInput,
  67. },
  68. data() {
  69. return {
  70. id: null,
  71. title: null,
  72. form: {
  73. name: null,
  74. phone: null,
  75. area: null,
  76. detail: null,
  77. },
  78. rules: {
  79. 'name': {
  80. type: 'string',
  81. required: true,
  82. message: '请输入联系人',
  83. },
  84. 'phone': {
  85. type: 'string',
  86. required: true,
  87. message: '请输入手机号',
  88. },
  89. 'area': {
  90. type: 'array',
  91. required: true,
  92. message: '请选择省市区',
  93. },
  94. 'detail': {
  95. type: 'string',
  96. required: true,
  97. message: '请输入详细地址',
  98. },
  99. },
  100. formItemStyle: { padding: 0 },
  101. }
  102. },
  103. methods: {
  104. async fetchAddressDetail(id) {
  105. try {
  106. const result = await this.$fetch('getAddressById', { id })
  107. const {
  108. name,
  109. phone,
  110. province,
  111. city,
  112. district,
  113. detail,
  114. } = result
  115. this.form = {
  116. name,
  117. phone,
  118. area: [province, city, district].filter(val => val),
  119. detail,
  120. }
  121. } catch (err) {
  122. }
  123. },
  124. open(id) {
  125. if (id) {
  126. this.id = id
  127. this.title = '编辑地址'
  128. this.fetchAddressDetail(id)
  129. } else {
  130. this.id = null
  131. this.title = '新建地址'
  132. this.form = {
  133. name: null,
  134. phone: null,
  135. area: null,
  136. detail: null,
  137. }
  138. }
  139. this.$refs.popup.open()
  140. },
  141. close() {
  142. this.$refs.popup.close()
  143. },
  144. onAreaChange(e) {
  145. this.form.area = e.detail.value
  146. },
  147. async onSave() {
  148. try {
  149. await this.$refs.form.validate()
  150. const {
  151. name,
  152. phone,
  153. area,
  154. detail,
  155. } = this.form
  156. const [province, city, district] = area
  157. const params = {
  158. name,
  159. phone,
  160. province,
  161. city,
  162. district,
  163. detail,
  164. }
  165. if (this.id) {
  166. params.id = this.id
  167. await this.$fetch('updateAddress', params)
  168. uni.showToast({
  169. icon: 'success',
  170. title: '修改地址成功',
  171. });
  172. } else {
  173. await this.$fetch('addAddress', params)
  174. uni.showToast({
  175. icon: 'success',
  176. title: '新建地址成功',
  177. });
  178. }
  179. this.$emit('submitted')
  180. this.close()
  181. } catch (err) {
  182. console.log('onSave err', err)
  183. }
  184. },
  185. },
  186. }
  187. </script>
  188. <style lang="scss" scoped>
  189. .popup__view {
  190. width: 100vw;
  191. display: flex;
  192. flex-direction: column;
  193. box-sizing: border-box;
  194. background: #FFFFFF;
  195. border-top-left-radius: 32rpx;
  196. border-top-right-radius: 32rpx;
  197. }
  198. .header {
  199. position: relative;
  200. width: 100%;
  201. padding: 24rpx 0;
  202. box-sizing: border-box;
  203. border-bottom: 2rpx solid #EEEEEE;
  204. .title {
  205. font-family: PingFang SC;
  206. font-weight: 500;
  207. font-size: 34rpx;
  208. line-height: 1.4;
  209. color: #181818;
  210. }
  211. .btn {
  212. font-family: PingFang SC;
  213. font-weight: 500;
  214. font-size: 32rpx;
  215. line-height: 1.4;
  216. color: #8B8B8B;
  217. position: absolute;
  218. top: 26rpx;
  219. left: 40rpx;
  220. }
  221. }
  222. .form {
  223. padding: 32rpx 40rpx;
  224. &-item {
  225. padding: 8rpx 0 6rpx 0;
  226. & + & {
  227. padding-top: 24rpx;
  228. border-top: 2rpx solid #EEEEEE;
  229. }
  230. &-label {
  231. margin-bottom: 14rpx;
  232. font-family: PingFang SC;
  233. font-weight: 400;
  234. font-size: 26rpx;
  235. line-height: 1.4;
  236. color: #181818;
  237. }
  238. &-content {
  239. .placeholder {
  240. color: #C6C6C6;
  241. font-size: 32rpx;
  242. font-weight: 400;
  243. }
  244. .region {
  245. min-height: 44rpx;
  246. justify-content: flex-start;
  247. }
  248. }
  249. }
  250. }
  251. .footer {
  252. width: 100%;
  253. padding: 32rpx 40rpx;
  254. box-sizing: border-box;
  255. border-top: 2rpx solid #F1F1F1;
  256. .btn {
  257. width: 100%;
  258. padding: 16rpx 0;
  259. font-family: PingFang SC;
  260. font-weight: 500;
  261. font-size: 36rpx;
  262. line-height: 1.4;
  263. color: #FFFFFF;
  264. background-image: linear-gradient(to right, #4B348F, #845CFA);
  265. border-radius: 41rpx;
  266. }
  267. }
  268. </style>