address.uvue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. <template>
  2. <cl-page>
  3. <view class="p-3">
  4. <view
  5. class="flex flex-col bg-white rounded-2xl p-4 mb-3 dark:!bg-surface-800"
  6. :class="{
  7. '!mb-0': index == addressList.length - 1
  8. }"
  9. v-for="(item, index) in addressList"
  10. :key="item.id"
  11. >
  12. <view class="flex flex-col">
  13. <cl-text
  14. :size="16"
  15. :pt="{
  16. className: 'mb-2'
  17. }"
  18. >{{ item.province }} {{ item.city }} {{ item.district }}
  19. {{ item.address }}</cl-text
  20. >
  21. <view class="flex flex-row">
  22. <cl-text :size="12">{{ item.contact }}</cl-text>
  23. <cl-text
  24. type="phone"
  25. mask
  26. :size="12"
  27. color="info"
  28. :value="item.phone"
  29. :pt="{ className: 'ml-3' }"
  30. ></cl-text>
  31. </view>
  32. </view>
  33. <view class="flex flex-row pt-4 mt-4 dark:!border-surface-700">
  34. <cl-radio
  35. v-model="defaultId"
  36. active-icon="checkbox-circle-fill"
  37. inactive-icon="checkbox-blank-circle-line"
  38. :pt="{
  39. className: 'max-w-[150px]',
  40. icon: {
  41. size: 16
  42. },
  43. label: {
  44. size: 12
  45. }
  46. }"
  47. :value="item.id"
  48. @change="onDefaultChange(item)"
  49. >{{ item.isDefault ? t("已设为默认") : t("设为默认") }}</cl-radio
  50. >
  51. <view
  52. class="flex flex-row items-center justify-center ml-auto"
  53. @tap="onDelete(item.id!)"
  54. >
  55. <cl-icon name="delete-bin-line"></cl-icon>
  56. <cl-text :size="12" :pt="{ className: 'ml-2' }">{{ t("删除") }}</cl-text>
  57. </view>
  58. <view
  59. class="flex flex-row items-center justify-center ml-6"
  60. @tap="toEdit(item.id!)"
  61. >
  62. <cl-icon name="edit-line"></cl-icon>
  63. <cl-text :size="12" :pt="{ className: 'ml-2' }">{{ t("修改") }}</cl-text>
  64. </view>
  65. </view>
  66. </view>
  67. <cl-empty v-if="list.length == 0"></cl-empty>
  68. </view>
  69. <cl-footer>
  70. <cl-button size="large" @tap="toAdd()">{{ t("添加地址") }}</cl-button>
  71. </cl-footer>
  72. </cl-page>
  73. </template>
  74. <script lang="ts" setup>
  75. import { useUi } from "@/uni_modules/cool-ui";
  76. import { parse, request, router, usePager, type Response, t } from "@/.cool";
  77. import { computed, ref } from "vue";
  78. import type { UserAddress } from "../types";
  79. const ui = useUi();
  80. const { refresh, list, loadMore } = usePager(async (data, { render }) => {
  81. await request({
  82. url: "/app/user/address/page",
  83. method: "POST",
  84. data
  85. })
  86. .then((res) => {
  87. if (res != null) {
  88. render(res);
  89. }
  90. })
  91. .catch((err) => {
  92. ui.showToast({
  93. message: (err as Response).message!
  94. });
  95. })
  96. .finally(() => {
  97. ui.hideLoading();
  98. });
  99. });
  100. // 默认地址id
  101. const defaultId = ref<number>(0);
  102. // 地址列表数据
  103. const addressList = computed(() =>
  104. list.value.map((e) => {
  105. e["isDefault"] = e["isDefault"] == 1 ? true : false;
  106. const d = parse<UserAddress>(e)!;
  107. if (d.isDefault) {
  108. defaultId.value = d.id!;
  109. }
  110. return d;
  111. })
  112. );
  113. // 添加地址
  114. function toAdd() {
  115. router.to("/pages/template/shop/address-edit");
  116. }
  117. // 编辑地址
  118. function toEdit(id: number) {
  119. router.push({
  120. path: "/pages/template/shop/address-edit",
  121. query: { id }
  122. });
  123. }
  124. // 删除地址
  125. function onDelete(id: number) {
  126. ui.showConfirm({
  127. title: t("提示"),
  128. message: t("删除地址后无法恢复,确认要删除该地址吗?"),
  129. callback: (action) => {
  130. if (action == "confirm") {
  131. request({
  132. url: "/app/user/address/delete",
  133. method: "POST",
  134. data: { ids: [id] }
  135. })
  136. .then(() => {
  137. ui.showToast({
  138. message: t("删除成功")
  139. });
  140. refresh({});
  141. })
  142. .catch((err) => {
  143. ui.showToast({
  144. message: (err as Response).message!
  145. });
  146. });
  147. }
  148. }
  149. });
  150. }
  151. // 设为默认地址
  152. function onDefaultChange(item: UserAddress) {
  153. // 遍历地址列表,设置选中的地址为默认地址,其他地址取消默认
  154. addressList.value.forEach((e) => {
  155. if (e.id == item.id) {
  156. // 切换当前地址的默认状态
  157. e.isDefault = !e.isDefault;
  158. // 如果取消了默认,则重置默认地址ID
  159. if (!e.isDefault) {
  160. defaultId.value = 0;
  161. }
  162. } else {
  163. // 其他地址全部取消默认
  164. e.isDefault = false;
  165. }
  166. });
  167. request({
  168. url: "/app/user/address/update",
  169. method: "POST",
  170. data: {
  171. id: item.id,
  172. isDefault: item.isDefault
  173. }
  174. });
  175. }
  176. onPullDownRefresh(() => {
  177. refresh({ page: 1 }).finally(() => {
  178. uni.stopPullDownRefresh();
  179. });
  180. });
  181. onReachBottom(() => {
  182. loadMore();
  183. });
  184. onReady(() => {
  185. ui.showLoading(t("加载中"));
  186. // 默认请求
  187. refresh({
  188. page: 1,
  189. size: 20
  190. });
  191. onPageShow(() => {
  192. refresh({});
  193. });
  194. });
  195. </script>