AddressOperation.vue 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. <!--新增/编辑收货地址 @zjf-2021-01-06-->
  2. <template>
  3. <div class="address_operate_modal">
  4. <el-dialog
  5. :title="type == 'edit' ? '编辑地址' : '添加收货地址'"
  6. v-model="modalVisible"
  7. @close="close_dialog"
  8. >
  9. <el-form :model="form.data" :rules="rules" ref="ruleForm">
  10. <el-form-item
  11. label="收货人"
  12. :label-width="formLabelWidth"
  13. prop="memberName"
  14. >
  15. <el-input
  16. v-model="form.data.memberName"
  17. autocomplete="off"
  18. maxlength="25"
  19. show-word-limit
  20. placeholder="请输入收货人姓名"
  21. clearable
  22. >
  23. </el-input>
  24. </el-form-item>
  25. <el-form-item
  26. label="电话号码"
  27. :label-width="formLabelWidth"
  28. prop="telMobile"
  29. >
  30. <el-input
  31. v-model="form.data.telMobile"
  32. autocomplete="off"
  33. placeholder="请输入手机号"
  34. clearable
  35. maxlength="11"
  36. show-word-limit
  37. ></el-input>
  38. </el-form-item>
  39. <el-form-item
  40. label="所在地区"
  41. :label-width="formLabelWidth"
  42. prop="area"
  43. >
  44. <el-cascader
  45. ref="cascaderAddr"
  46. v-model="form.data.area"
  47. :options="areaDataArray"
  48. placeholder="请选择所在地区"
  49. :props="cascaderProps"
  50. clearable
  51. ></el-cascader>
  52. </el-form-item>
  53. <el-form-item
  54. label="详细地址"
  55. :label-width="formLabelWidth"
  56. prop="detailAddress"
  57. >
  58. <el-input
  59. type="textarea"
  60. :rows="2"
  61. v-model="form.data.detailAddress"
  62. autocomplete="off"
  63. placeholder="请输入详细地址"
  64. clearable
  65. maxlength="40"
  66. ></el-input>
  67. </el-form-item>
  68. <el-form-item label=" " :label-width="formLabelWidth">
  69. <el-checkbox v-model="form.data.isDefault">设为默认地址</el-checkbox>
  70. </el-form-item>
  71. </el-form>
  72. <template #footer>
  73. <span class="dialog-footer">
  74. <el-button @click="close_dialog">取 消</el-button>
  75. <el-button
  76. type="primary"
  77. @click="addAddress('ruleForm')"
  78. :loading="btnLoading"
  79. >确 定</el-button
  80. >
  81. </span>
  82. </template>
  83. </el-dialog>
  84. </div>
  85. </template>
  86. <script setup>
  87. import { ref, reactive, getCurrentInstance, watchEffect } from "vue";
  88. import areaData from "@/assets/area.json";
  89. import { ElMessage, ElButton, ElInput,ElDialog,ElCheckbox } from "element-plus";
  90. // import { lang_zn } from "@/assets/language/zh";
  91. import { getCurLanguage } from '@/composables/common.js';
  92. import { useFiltersStore } from "@/store/filter.js";
  93. const filtersStore = useFiltersStore();
  94. // const L = lang_zn;
  95. const L = getCurLanguage();
  96. definePageMeta({
  97. layout: "member",
  98. middleware: ["auth"],
  99. });
  100. const emit = defineEmits(["refreshAddress","close"])
  101. const props = defineProps(["visibleFlag", "type", "addressInfo"]);
  102. const { proxy } = getCurrentInstance();
  103. const formLabelWidth = "80px";
  104. const modalVisible = ref(true);
  105. const form = reactive({ data: {} });
  106. const areaDataArray = areaData;
  107. const cascaderProps = { label: "regionName", value: "regionCode" };
  108. const ruleForm = ref(null);
  109. const cascaderAddr = ref(null);
  110. const addressInfo = reactive(props.addressInfo);
  111. const btnLoading = ref(false);
  112. const type = ref(props.type);
  113. if (props.type == "edit") {
  114. var area = [addressInfo.data.provinceCode, addressInfo.data.cityCode];
  115. form.data.memberName = addressInfo.data.memberName;
  116. form.data.telMobile = addressInfo.data.telMobile;
  117. form.data.detailAddress = addressInfo.data.detailAddress; //详细地址
  118. form.data.isDefault = addressInfo.data.isDefault ? true : false; //是否默认地址:1-默认地址,0-非默认地址
  119. if (addressInfo.data.districtCode != "0") {
  120. area.push(addressInfo.data.districtCode);
  121. }
  122. form.data.area = area;
  123. } else {
  124. form.data.memberName = "";
  125. form.data.telMobile = "";
  126. form.data.detailAddress = ""; //详细地址
  127. form.data.isDefault = false; //是否默认地址:1-默认地址,0-非默认地址
  128. form.data.area = [];
  129. }
  130. const rules = {
  131. memberName: [
  132. { required: true, message: "请输入收货人", trigger: "change" },
  133. { min: 2, max: 25, message: "请输入2~25个字符", trigger: "change" },
  134. ],
  135. telMobile: [
  136. { required: true, message: "请输入手机号", trigger: "change" },
  137. {
  138. pattern: /^((\+?86)|(\(\+86\)))?(1[3-9]\d{9}$)|(\d{4}-)\d{6,8}$/,
  139. message: "请输入正确的电话号码",
  140. trigger: "change",
  141. },
  142. ],
  143. area: [{ required: true, message: "请选择所在地区", trigger: "change" }],
  144. detailAddress: [
  145. { required: true, message: "请输入详细地址", trigger: "change" },
  146. { min: 5, max: 40, message: "请输入5~40个字符", trigger: "change" },
  147. {
  148. pattern: /^[\u4e00-\u9fa5a-zA-Z0-9]+$/,
  149. message: "请输入正确的地址",
  150. trigger: "change",
  151. },
  152. ],
  153. }; //输入校验
  154. //增加地址
  155. const addAddress = () => {
  156. btnLoading.value = true;
  157. ruleForm.value.validate((valid) => {
  158. if (valid) {
  159. var param = {
  160. provinceCode: form.data.area[0],
  161. cityCode: form.data.area[1],
  162. districtCode: form.data.area[2],
  163. memberName: form.data.memberName.trim(),
  164. telMobile: form.data.telMobile.trim(),
  165. addressAll: cascaderAddr.value.getCheckedNodes()[0].pathLabels.join(""),
  166. isDefault: form.data.isDefault ? 1 : 0,
  167. detailAddress: form.data.detailAddress.trim(),
  168. };
  169. var url;
  170. if (props.type == "edit") {
  171. url = "v3/member/front/memberAddress/edit";
  172. param.addressId = addressInfo.data.addressId;
  173. } else if (props.type == "add") {
  174. url = "v3/member/front/memberAddress/add";
  175. }
  176. post(url, param).then((res) => {
  177. if (res.state == 200) {
  178. btnLoading.value = false;
  179. close_dialog();
  180. emit("refreshAddress", param, res.data);
  181. ElMessage.success(res.msg);
  182. } else {
  183. ElMessage(res.msg);
  184. }
  185. });
  186. } else {
  187. btnLoading.value = false;
  188. return false;
  189. }
  190. });
  191. };
  192. const close_dialog = () => {
  193. emit("close");
  194. document.body.style.overflow = "visible";
  195. };
  196. watchEffect(() => {
  197. // modalVisible.value = props.visibleFlag;
  198. // console.log(addressInfo)
  199. });
  200. </script>
  201. <style lang="scss">
  202. .el-cascader-menu__wrap {
  203. height: 204px !important;
  204. }
  205. textarea {
  206. resize: none;
  207. }
  208. .address_operate_modal {
  209. .el-dialog {
  210. width: 600px !important;
  211. }
  212. .el-cascader {
  213. width: 100% !important;
  214. }
  215. .el-checkbox {
  216. .el-checkbox__input {
  217. margin-top: -4px;
  218. }
  219. }
  220. .el-button--primary {
  221. color: #fff;
  222. background-color: $colorMain;
  223. border-color: $colorMain;
  224. }
  225. .el-checkbox__input.is-checked .el-checkbox__inner,
  226. .el-checkbox__input.is-indeterminate .el-checkbox__inner {
  227. background-color: $colorMain;
  228. border-color: $colorMain;
  229. }
  230. .el-checkbox__input.is-checked + .el-checkbox__label {
  231. color: $colorMain;
  232. }
  233. .el-button {
  234. padding: 9px 20px;
  235. }
  236. .el-dialog__body {
  237. padding: 20px;
  238. }
  239. .el-form-item {
  240. margin-bottom: 15px;
  241. }
  242. .el-form-item__content {
  243. position: relative;
  244. }
  245. .el-form-item__error {
  246. position: absolute;
  247. top: -2px;
  248. right: 0;
  249. display: inline-block;
  250. width: auto;
  251. z-index: 2;
  252. background: #fff;
  253. left: auto;
  254. padding: 0 3px;
  255. }
  256. input::-webkit-input-placeholder {
  257. /* Chrome/Opera/Safari */
  258. color: #ccc;
  259. font-size: 12px;
  260. }
  261. input::-moz-placeholder {
  262. /* Firefox 19+ */
  263. color: #ccc;
  264. font-size: 12px;
  265. }
  266. input:-ms-input-placeholder {
  267. /* IE 10+ */
  268. color: #ccc;
  269. font-size: 12px;
  270. }
  271. input:-moz-placeholder {
  272. /* Firefox 18- */
  273. color: #ccc;
  274. font-size: 12px;
  275. }
  276. textarea::-webkit-input-placeholder {
  277. /* Chrome/Opera/Safari */
  278. color: #ccc;
  279. font-size: 12px;
  280. }
  281. textarea::-moz-placeholder {
  282. /* Firefox 19+ */
  283. color: #ccc;
  284. font-size: 12px;
  285. }
  286. textarea:-ms-input-placeholder {
  287. /* IE 10+ */
  288. color: #ccc;
  289. font-size: 12px;
  290. }
  291. textarea:-moz-placeholder {
  292. /* Firefox 18- */
  293. color: #ccc;
  294. font-size: 12px;
  295. }
  296. .el-input {
  297. --el-input-focus-border: #e2231a;
  298. }
  299. .el-cascader-node.in-active-path {
  300. color: #e2231a !important;
  301. }
  302. }
  303. </style>