Эх сурвалжийг харах

refactor(leave-source): 重构离店来源组件和对话框逻辑

- 调整了多个组件的样式和布局
- 优化了电话输入和验证逻辑
- 重构了对话框的显示和隐藏控制
- 改进了内容卡片的交互方式
- 优化了钩子函数的使用,提高了代码复用性

Signed-off-by: tangshizhe <48740614+tangshizhe@users.noreply.github.com>
tangshizhe 2 долоо хоног өмнө
parent
commit
ce195f91a3

+ 1 - 1
plugins/leave-source/src/lib/pc/components/BaseDialog.vue

@@ -43,7 +43,7 @@ defineExpose({
       flex-direction: column;
       justify-content: center;
       align-items: center;
-      margin: 300px auto;
+      margin: 400px auto;
       padding: 32px;
       border-radius: 8px;
       background: #fff;

+ 1 - 1
plugins/leave-source/src/lib/pc/components/ContractMine.vue

@@ -5,7 +5,7 @@
     </div>
     <div class="contract-mine-content">
       <label for="phone" class="contract-mine-label">联系电话:</label>
-      <input id="phone" v-model="phone" type="text" class="contract-mine-input" placeholder="请输入联系电话">
+      <input id="phone" v-model="phone" oninput="if(value.length > 11) value = value.slice(0, 11)" type="text" class="contract-mine-input" placeholder="请输入联系电话">
     </div>
     <button class="contract-mine-btn" @click="handle">
       与我联系

+ 34 - 5
plugins/leave-source/src/lib/pc/components/PhoneEditDialog.vue

@@ -5,7 +5,7 @@
         <header>修改联系电话</header>
         <main>
           <span>联系电话:</span>
-          <input v-model="phone" name="phone" class="phone-edit-ipt" type="text" placeholder="请输入联系电话">
+          <input v-model="phoneNumber" name="phone" class="phone-edit-ipt" type="text" placeholder="请输入联系电话">
         </main>
         <footer>
           <button @click="handleConfirm">
@@ -21,22 +21,51 @@
 </template>
 
 <script setup>
-import { ref } from 'vue'
+import { ref, watch } from 'vue'
 import BaseDialog from './BaseDialog.vue'
 
-const phone = ref('')
+const props = defineProps({
+  visible: {
+    type: Boolean,
+    default: false,
+  },
+  title: {
+    type: String,
+    default: '修改联系电话',
+  },
+  phone: {
+    type: String,
+    default: '',
+  },
+  confirmButtonText: {
+    type: String,
+    default: '确定',
+  },
+  cancelButtonText: {
+    type: String,
+    default: '取消',
+  },
+})
 
+const emit = defineEmits(['confirm', 'cancel'])
+const phoneNumber = ref(props.phone)
 const baseDialogRef = ref(null)
+// 监听visible变化,更新BaseDialog的显示状态
+watch(() => props.visible, (f) => {
+  console.log('visible change', props)
+  baseDialogRef.value.updateVisible(f)
+})
 
 function updateVisible(f = false) {
   baseDialogRef.value.updateVisible(f)
 }
 
 function handleConfirm() {
-  console.log('handleConfirm')
+  console.log(phoneNumber.value, 'handleConfirm')
+  emit('confirm', phoneNumber.value)
 }
 function handleCancel() {
-  console.log('handleCancel')
+  emit('cancel')
 }
 
 defineExpose({

+ 26 - 5
plugins/leave-source/src/lib/pc/components/SubMitSuccess.vue

@@ -2,13 +2,13 @@
   <div class="phone-edit-dialog">
     <BaseDialog ref="baseDialogRef">
       <template #content>
-        <header>提交成功</header>
+        <header>{{ title }}</header>
         <main>
-          我们的专属客服会在24小时内尽快与您联系,请注意电话接听。
+          {{ contentText }}
         </main>
         <footer>
           <button @click="handleConfirm">
-            我知道啦
+            {{ confirmButtonText }}
           </button>
         </footer>
       </template>
@@ -17,11 +17,32 @@
 </template>
 
 <script setup>
-import { ref } from 'vue'
+import { ref, watch } from 'vue'
 import BaseDialog from './BaseDialog.vue'
 
-const baseDialogRef = ref(null)
+const props = defineProps({
+  visible: {
+    type: Boolean,
+    default: false,
+  },
+  title: {
+    type: String,
+    default: '提交成功',
+  },
+  contentText: {
+    type: String,
+    default: '',
+  },
+  confirmButtonText: {
+    type: String,
+    default: '我知道啦',
+  }
+})
 
+const baseDialogRef = ref(null)
+watch(() => props.visible, (val) => {
+  baseDialogRef.value.updateVisible(val)
+})
 function updateVisible(f = false) {
   baseDialogRef.value.updateVisible(f)
 }

+ 7 - 9
plugins/leave-source/src/lib/pc/components/content-card.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="content-card">
-    <span class="j-icon icon-pc-close" />
+    <span class="j-icon icon-pc-close" @click="closeIconClick" />
     <ContractCard v-if="config.props.type === '1'" @contactMeEvent="contactMeEvent" />
     <ContractCardQrcode v-else class="qrcode-module" />
     <LeaveCommon :class="{ 'samll-footer': config.props.type === '2' }" />
@@ -48,16 +48,12 @@ export default {
       confirmPhoneDialog: {}
     }
   },
-  mounted() {
-    this.confirmPhoneDialog = usePhoneCheck(this.config)
-  },
   methods: {
     contactMeEvent(phone) {
-      console.log(this.config, 'config')
-      const newConfig = this.config
-      newConfig.configInfo.phone = phone
-      const { contactMe } = usePhoneCheck(newConfig)
-      contactMe()
+      this.$emit('contactMeEvent', phone)
+    },
+    closeIconClick() {
+      this.$emit('close')
     }
   }
 }
@@ -66,6 +62,8 @@ export default {
 <style scoped lang="scss">
 .content-card {
   position: relative;
+  background: #fff;
+  border-radius: 8px;
   .icon-pc-close {
     position: absolute;
     top: 16px;

+ 94 - 17
plugins/leave-source/src/lib/pc/components/phoneConfirmDialog.vue

@@ -1,34 +1,111 @@
 <template>
   <div class="phone-confirm-dialog">
-    <AnimatedOverlay
-      :visible="visible"
-      @update:visible="updateVisible"
-      @close="close"
-    >
-      <div class="phone-confirm">
-        <h1>Phone Confirm</h1>
-        <p>Please enter the code sent to your phone</p>
-      </div>
-    </AnimatedOverlay>
+    <BaseDialog ref="baseDialogRef">
+      <template #content>
+        <header>{{ title }}</header>
+        <main>
+          <span v-html="contentText" />
+        </main>
+        <footer>
+          <button @click="handleConfirm">
+            {{ confirmButtonText }}
+          </button>
+          <button @click="handleCancel">
+            {{ cancelButtonText }}
+          </button>
+        </footer>
+      </template>
+    </BaseDialog>
   </div>
 </template>
 
 <script setup>
-import { ref } from 'vue'
-import AnimatedOverlay from '../../../components/dialog/AnimatedOverlay.vue'
+import { ref, watch } from 'vue'
+import BaseDialog from './BaseDialog.vue'
+
+const props = defineProps({
+  visible: {
+    type: Boolean,
+    default: false,
+  },
+  title: {
+    type: String,
+    default: '提交成功',
+  },
+  contentText: {
+    type: String,
+    default: '',
+  },
+  confirmButtonText: {
+    type: String,
+    default: '确定',
+  },
+  cancelButtonText: {
+    type: String,
+    default: '取消',
+  },
+})
+
+const emit = defineEmits(['confirm', 'cancel'])
+const baseDialogRef = ref(null)
+// 监听visible变化,更新BaseDialog的显示状态
+watch(() => props.visible, (f) => {
+  console.log('visible change', props)
+  baseDialogRef.value.updateVisible(f)
+})
 
-const visible = ref(false)
 function updateVisible(f = false) {
-  visible.value = f
+  baseDialogRef.value.updateVisible(f)
 }
-function close() {
-  visible.value = false
+
+function handleConfirm() {
+  console.log('Confirm')
+  emit('confirm')
+}
+function handleCancel() {
+  console.log('handleCancel')
+  emit('cancel')
 }
+
 defineExpose({
   updateVisible
 })
 </script>
 
 <style lang="scss" scoped>
-
+  .phone-confirm-dialog {
+    header {
+      font-size: 18px;
+      line-height: 28px;
+      color: #1D1D1D;
+    }
+    main {
+      margin: 20px 0 32px;
+      font-size: 14px;
+      line-height: 22px;
+      color: #686868;
+      text-align: center;
+    }
+    footer {
+      display: flex;
+      justify-content: space-between;
+      width: 100%;
+      button {
+        width: 132px;
+        height: 36px;
+        border-radius: 6px;
+        background: #2ABED1;
+        color: #fff;
+        font-size: 16px;
+        line-height: 24px;
+        border: none;
+        cursor: pointer;
+        &:last-child {
+          background: #fff;
+          border: 1px solid #E0E0E0;
+          color: #1D1D1D;
+        }
+      }
+    }
+  }
 </style>

+ 41 - 13
plugins/leave-source/src/lib/pc/content-dialog.vue

@@ -1,10 +1,11 @@
 <script setup>
+import { watch, watchEffect } from 'vue'
 import AnimatedOverlay from '../../components/dialog/AnimatedOverlay.vue'
 import ContentCard from './components/content-card.vue'
 import PhoneConfirmDialog from './components/PhoneConfirmDialog.vue'
 import PhoneEditDialog from './components/PhoneEditDialog.vue'
 import SubMitSuccess from './components/SubMitSuccess.vue'
-import { usePreLeaveInfo } from '@/utils/hooks'
+import { usePhoneCheck, usePreLeaveInfo } from '@/utils/hooks'
 
 const props = defineProps({
   source: {
@@ -33,22 +34,32 @@ const {
   configInfo,
 } = usePreLeaveInfo({ props })
 
+const config = {
+  configInfo,
+  props,
+}
+
 const {
   confirmPhoneDialog,
-  confirmContentText,
   changePhoneDialog,
   successCheckDialog,
   dialogEvents,
   checkPhonePass,
+  contactMe
 } = usePhoneCheck({
   configInfo,
   props,
-  popupVisible: visible,
+  // popupVisible: visible,
 })
 
-const config = {
-  configInfo,
-  props,
+function contactMeEvent(phone) {
+  configInfo.phone = phone
+  contactMe()
+}
+
+function phoneEditConfirm(phone) {
+  changePhoneDialog.phoneNumber = phone
+  dialogEvents.phoneChangeConfirm()
 }
 
 defineExpose({
@@ -68,19 +79,36 @@ export default {
     :class="`pc-leave-dialog-${props.type}`"
     :visible="visible"
     @update:visible="updateVisible"
-    @close="close"
   >
-    <ContentCard :config="config" />
+    <ContentCard
+      :config="config"
+      @contactMeEvent="contactMeEvent"
+      @close="updateVisible(false)"
+    />
     <!-- 确认手机弹窗 -->
     <PhoneConfirmDialog
-      :confirm-phone-dialog="confirmPhoneDialog"
-      :confirm-content-text="confirmContentText"
+      :visible="confirmPhoneDialog.show"
+      :title="confirmPhoneDialog.title"
+      :content-text="confirmPhoneDialog.contentText"
+      :confirm-button-text="confirmPhoneDialog.confirmButtonText"
+      :cancel-button-text="confirmPhoneDialog.cancelButtonText"
+      @confirm="dialogEvents.confirmPhoneConfirm"
+      @cancel="dialogEvents.confirmPhoneCancel"
     />
     <!-- 修改手机号弹窗 -->
-    <PhoneEditDialog />
+    <PhoneEditDialog
+      :visible="changePhoneDialog.show"
+      :phone="changePhoneDialog.phoneNumber"
+      @confirm="phoneEditConfirm"
+      @cancel="dialogEvents.phoneChangeCancel"
+    />
     <!-- 提交成功弹窗 -->
     <SubMitSuccess
-      :success-check-dialog="successCheckDialog"
+      :visible="successCheckDialog.show"
+      :title="successCheckDialog.title"
+      :content-text="successCheckDialog.contentText"
+      :confirm-button-text="successCheckDialog.confirmButtonText"
+      @confirm="dialogEvents.successConfirm"
     />
   </AnimatedOverlay>
 </template>
@@ -91,7 +119,7 @@ export default {
     .overlay-content {
       margin: 300px auto;
       width: 732px;
-      background: #fff;
+      // background: #fff;
       border-radius: 8px;
     }
   }

+ 8 - 3
plugins/leave-source/src/utils/hooks.js

@@ -1,4 +1,4 @@
-import { computed, reactive, ref, watch } from 'vue'
+import { computed, nextTick, reactive, ref, watch } from 'vue'
 import { doLeave } from './leave'
 import {
   requestBehaviorClues,
@@ -192,9 +192,14 @@ export function usePhoneCheck(options = {}) {
     }
     finally {
       changePhoneDialog.show = false
-      successCheckDialog.show = false
       confirmPhoneDialog.show = false
-      popupVisible.value = false
+      if (popupVisible) {
+        popupVisible.value = false
+      }
+      successCheckDialog.show = false
+      // 使用 nextTick 确保状态更新
+      await nextTick()
+      successCheckDialog.show = true
     }
   }