edit.vue 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. <template>
  2. <s-layout :title="state.model.id ? '编辑地址' : '新增地址'">
  3. <uni-forms
  4. ref="addressFormRef"
  5. v-model="state.model"
  6. :rules="state.rules"
  7. validateTrigger="bind"
  8. labelWidth="160"
  9. labelAlign="left"
  10. border
  11. :labelStyle="{ fontWeight: 'bold' }"
  12. >
  13. <view class="bg-white form-box ss-p-x-30">
  14. <uni-forms-item name="consignee" label="收货人" class="form-item">
  15. <uni-easyinput
  16. v-model="state.model.consignee"
  17. placeholder="请填写收货人姓名"
  18. :inputBorder="false"
  19. placeholderStyle="color:#BBBBBB;font-size:30rpx;font-weight:400;line-height:normal"
  20. />
  21. </uni-forms-item>
  22. <uni-forms-item name="mobile" label="手机号" class="form-item">
  23. <uni-easyinput
  24. v-model="state.model.mobile"
  25. type="number"
  26. placeholder="请输入手机号"
  27. :inputBorder="false"
  28. placeholderStyle="color:#BBBBBB;font-size:30rpx;font-weight:400;line-height:normal"
  29. >
  30. </uni-easyinput>
  31. </uni-forms-item>
  32. <uni-forms-item
  33. name="region"
  34. label="省市区"
  35. @tap="state.showRegion = true"
  36. class="form-item"
  37. >
  38. <uni-easyinput
  39. v-model="state.model.region"
  40. disabled
  41. :inputBorder="false"
  42. :styles="{ disableColor: '#fff', color: '#333' }"
  43. placeholderStyle="color:#BBBBBB;font-size:30rpx;font-weight:400;line-height:normal"
  44. placeholder="请选择省市区"
  45. >
  46. <template v-slot:right>
  47. <uni-icons type="right"></uni-icons>
  48. </template>
  49. </uni-easyinput>
  50. </uni-forms-item>
  51. <uni-forms-item
  52. name="address"
  53. label="详细地址"
  54. :formItemStyle="{ alignItems: 'flex-start' }"
  55. :labelStyle="{ lineHeight: '5em' }"
  56. class="textarea-item"
  57. >
  58. <uni-easyinput
  59. :inputBorder="false"
  60. type="textarea"
  61. v-model="state.model.address"
  62. placeholderStyle="color:#BBBBBB;font-size:30rpx;font-weight:400;line-height:normal"
  63. placeholder="请输入详细地址"
  64. clearable
  65. ></uni-easyinput>
  66. </uni-forms-item>
  67. </view>
  68. <view class="ss-m-y-20 bg-white ss-p-x-30 ss-flex ss-row-between ss-col-center default-box">
  69. <view class="default-box-title"> 设为默认地址 </view>
  70. <su-switch style="transform: scale(0.8)" v-model="state.model.is_default"></su-switch>
  71. </view>
  72. </uni-forms>
  73. <su-fixed bottom :opacity="false" bg="" placeholder :noFixed="false" :index="10">
  74. <view class="footer-box ss-flex-col ss-row-between ss-p-20">
  75. <view class="ss-m-b-20"
  76. ><button class="ss-reset-button save-btn ui-Shadow-Main" @tap="onSave">保存</button></view
  77. >
  78. <button v-if="state.model.id" class="ss-reset-button cancel-btn" @tap="onDelete">
  79. 删除
  80. </button>
  81. </view>
  82. </su-fixed>
  83. <!-- 省市区弹窗 -->
  84. <su-region-picker
  85. :show="state.showRegion"
  86. @cancel="state.showRegion = false"
  87. @confirm="onRegionConfirm"
  88. >
  89. </su-region-picker>
  90. </s-layout>
  91. </template>
  92. <script setup>
  93. import { computed, watch, ref, reactive, unref } from 'vue';
  94. import sheep from '@/sheep';
  95. import { onLoad, onPageScroll } from '@dcloudio/uni-app';
  96. import _ from 'lodash';
  97. import { consignee, mobile, address, region } from '@/sheep/validate/form';
  98. const addressFormRef = ref(null);
  99. const state = reactive({
  100. showRegion: false,
  101. model: {
  102. consignee: '',
  103. mobile: '',
  104. address: '',
  105. is_default: false,
  106. region: '',
  107. },
  108. rules: {
  109. consignee,
  110. mobile,
  111. address,
  112. region,
  113. },
  114. });
  115. watch(
  116. () => state.model.province_name,
  117. (newValue) => {
  118. if (newValue) {
  119. state.model.region = `${state.model.province_name}-${state.model.city_name}-${state.model.district_name}`;
  120. }
  121. },
  122. {
  123. deep: true,
  124. },
  125. );
  126. const onRegionConfirm = (e) => {
  127. state.model = {
  128. ...state.model,
  129. ...e,
  130. };
  131. state.showRegion = false;
  132. };
  133. const getAreaData = () => {
  134. if (_.isEmpty(uni.getStorageSync('areaData'))) {
  135. sheep.$api.data.area().then((res) => {
  136. if (res.error === 0) {
  137. uni.setStorageSync('areaData', res.data);
  138. }
  139. });
  140. }
  141. };
  142. const onSave = async () => {
  143. const validate = await unref(addressFormRef)
  144. .validate()
  145. .catch((error) => {
  146. console.log('error: ', error);
  147. });
  148. if (!validate) return;
  149. let res = null;
  150. if (state.model.id) {
  151. res = await sheep.$api.user.address.update(state.model.id, state.model);
  152. } else {
  153. res = await sheep.$api.user.address.create(state.model);
  154. }
  155. if (res.error === 0) {
  156. sheep.$router.back();
  157. }
  158. };
  159. const onDelete = () => {
  160. uni.showModal({
  161. title: '提示',
  162. content: '确认删除此收货地址吗?',
  163. success: async function (res) {
  164. if (res.confirm) {
  165. const { error } = await sheep.$api.user.address.delete(state.model.id);
  166. if (res.error === 0) {
  167. sheep.$router.back();
  168. }
  169. }
  170. },
  171. });
  172. };
  173. onLoad(async (options) => {
  174. getAreaData();
  175. if (options.id) {
  176. let res = await sheep.$api.user.address.detail(options.id);
  177. if (res.error === 0) {
  178. state.model = {
  179. ...state.model,
  180. ...res.data,
  181. };
  182. }
  183. }
  184. if (options.data) {
  185. let data = JSON.parse(options.data);
  186. state.model = {
  187. ...state.model,
  188. ...data,
  189. };
  190. }
  191. });
  192. </script>
  193. <style lang="scss" scoped>
  194. :deep() {
  195. .uni-forms-item__label .label-text {
  196. font-size: 28rpx !important;
  197. color: #333333 !important;
  198. line-height: normal !important;
  199. }
  200. .uni-easyinput__content-input {
  201. font-size: 28rpx !important;
  202. color: #333333 !important;
  203. line-height: normal !important;
  204. padding-left: 0 !important;
  205. }
  206. .uni-easyinput__content-textarea {
  207. font-size: 28rpx !important;
  208. color: #333333 !important;
  209. line-height: normal !important;
  210. margin-top: 8rpx !important;
  211. }
  212. .uni-icons {
  213. font-size: 40rpx !important;
  214. }
  215. .is-textarea-icon {
  216. margin-top: 22rpx;
  217. }
  218. .is-disabled {
  219. color: #333333;
  220. }
  221. }
  222. .default-box {
  223. width: 100%;
  224. box-sizing: border-box;
  225. height: 100rpx;
  226. .default-box-title {
  227. font-size: 28rpx;
  228. color: #333333;
  229. line-height: normal;
  230. }
  231. }
  232. .footer-box {
  233. .save-btn {
  234. width: 710rpx;
  235. height: 80rpx;
  236. border-radius: 40rpx;
  237. background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
  238. color: $white;
  239. }
  240. .cancel-btn {
  241. width: 710rpx;
  242. height: 80rpx;
  243. border-radius: 40rpx;
  244. background: var(--ui-BG);
  245. }
  246. }
  247. </style>