Browse Source

冲突合并

Xiao_123 3 weeks ago
parent
commit
0a0b4d42d7

+ 482 - 0
components/selector/multipleSelector.vue

@@ -0,0 +1,482 @@
+<template>
+  <view>
+    <!-- 表单输入框 -->
+    <view v-if="formInput">
+      <uni-easyinput
+        v-model="inputVal"
+        type="text"
+        :placeholder="placeholder"
+        :clearable="clearable"
+        :readonly="readonly"
+        @focus.stop="handleOpen('focus')"
+      ></uni-easyinput>
+    </view>
+    <!-- 插槽 -->
+    <view v-else @tap="handleOpen('slot')">
+      <slot></slot>
+    </view>
+    <!-- 弹窗 -->
+    <uni-popup ref="popup">
+      <view class="popup-content" :style="popupStyle">
+        <view class="popup-header">
+          <view class="popup-title">{{ label }}</view>
+          <uni-icons 
+            type="closeempty" 
+            size="24" 
+            color="#999" 
+            @tap="closePopup"
+          />
+        </view>
+        
+        <view class="popup-search" v-if="filter">
+          <uni-easyinput
+            v-model="keyword"
+            type="text"
+            :placeholder="searchPlaceholder"
+            @input="inputChange"
+            suffixIcon="search"
+          ></uni-easyinput>
+        </view>
+        
+        <scroll-view 
+          class="popup-body" 
+          scroll-y 
+          :style="{ height: bodyHeight + 'px' }"
+        >
+          <view
+            v-for="(level, levelIndex) in showList" 
+            :key="levelIndex" 
+            class="level-container"
+          >
+            <view v-if="!level.data?.length">
+              {{ keyword ? '没有匹配的数据' : '暂无数据' }}
+            </view>
+            <template v-else>
+              <view
+                v-for="item in level.data" 
+                :key="item[itemValue]" 
+                class="item-container"
+                :class="calcClass(item, levelIndex)"
+                @tap="handleItemClick(item, levelIndex)"
+              >
+                <text class="item-label">{{ item[itemLabel] }}</text>
+                <view class="item-icons">
+                  <uni-icons 
+                    v-if="isItemActive(item, levelIndex) && !hasChildren(item)"
+                    type="checkmarkempty" 
+                    color="#00B760" 
+                    size="16"
+                  />
+                  <uni-icons 
+                    v-if="hasChildren(item)"
+                    type="arrowright" 
+                    color="#999" 
+                    size="16"
+                  />
+                </view>
+              </view>
+            </template>
+          </view>
+        </scroll-view>
+        
+        <view class="popup-footer" v-if="showFooter || multiple || isTreeData">
+          <button 
+            v-if="clearable" 
+            class="btn cancel" 
+            @tap="handleClear"
+          >
+            {{ clearText }}
+          </button>
+          <button 
+            class="btn confirm" 
+            @tap="handleConfirm"
+            :disabled="!hasSelection"
+          >
+            {{ submitText }}
+          </button>
+        </view>
+      </view>
+    </uni-popup>
+  </view>
+</template>
+
+<script setup>
+import { ref, computed, watch, nextTick } from 'vue'
+import { debounce } from 'lodash-es'
+
+const emit = defineEmits(['update:value', 'update:text', 'change', 'search'])
+
+const props = defineProps({
+  // 基础属性
+  value: [String, Number, Array, Object],
+  text: String,
+  items: {
+    type: Array,
+    default: () => []
+  },
+  label: {
+    type: String,
+    default: '请选择'
+  },
+  placeholder: {
+    type: String,
+    default: '请选择'
+  },
+  
+  // 字段映射
+  itemLabel: {
+    type: String,
+    default: 'label'
+  },
+  itemValue: {
+    type: String,
+    default: 'value'
+  },
+  children: {
+    type: String,
+    default: 'children'
+  },
+  
+  // 功能开关
+  multiple: Boolean,
+  formInput: Boolean, // 表单右侧输入框
+  filter: Boolean, // 可检索
+  clearable: Boolean,
+  readonly: Boolean,
+  oneLevel: Boolean, // 不展示子级
+  showFooter: { 
+    type: Boolean,
+    default: false
+  },
+  
+  // 搜索相关
+  searchPlaceholder: {
+    type: String,
+    default: '请输入'
+  },
+  searchDebounceTime: {
+    type: Number,
+    default: 500
+  },
+  
+  // 样式
+  popupStyle: [String, Object],
+  
+  // 文本自定义
+  clearText: {
+    type: String,
+    default: '清除'
+  },
+  submitText: {
+    type: String,
+    default: '确定'
+  }
+})
+
+  // 使用 lodash 的防抖
+  const debouncedSearch = debounce((value) => {
+  if (value = '') {
+    showList.value = [{
+      choose: props.multiple ? [] : -1,
+      data: props.items
+    }]
+  } else {
+    showList.value = [{
+      choose: showList.value?.choose || -1,
+      data: props.items?.length && props.items.map(j => j[props.itemLabel] && j[props.itemLabel].includes(value))
+    }]
+    debugger
+  }
+  emit('search', value)
+  }, props.searchDebounceTime)
+
+const isTreeData = ref(false)
+
+// 组件引用
+const popup = ref()
+const popupContent = ref()
+
+// 数据状态
+const inputVal = ref('')
+const keyword = ref('')
+const showList = ref([])
+const bodyHeight = ref(400)
+
+// 计算属性
+const hasSelection = computed(() => {
+  if (props.multiple) {
+    return showList.value.some(level => Array.isArray(level.choose) && level.choose.length > 0)
+  }
+  return showList.value.some(level => level.choose !== -1)
+})
+
+// 初始化
+const initShowList = () => {
+  showList.value = [{
+    choose: props.multiple ? [] : -1,
+    data: props.items
+  }]
+}
+
+
+const isItemActive = (item, levelIndex) => {
+  const level = showList.value[levelIndex]
+  if (!level) return false
+  
+  if (Array.isArray(level.choose)) {
+    return level.choose.includes(item[props.itemValue])
+  }
+  return level.choose === item[props.itemValue]
+}
+
+const hasChildren = (item) => {
+  return props.oneLevel ? false : Boolean(item[props.children] && item[props.children].length > 0)
+}
+
+// 方法
+const calcClass = (item, levelIndex) => {
+  return `${isItemActive(item, levelIndex) ? 'active' : ''}${hasChildren(item) ? 'has-children' : ''}`
+}
+
+const handleOpen = async () => {
+  popup.value.open('bottom')
+  await nextTick()
+  calculateBodyHeight()
+}
+
+const closePopup = () => {
+  popup.value.close()
+}
+
+const calculateBodyHeight = () => {
+  if (!popupContent.value) return
+  const query = uni.createSelectorQuery().in(popupContent.value)
+  query.select('.popup-content').boundingClientRect(data => {
+    if (data) {
+      bodyHeight.value = data.height - 120 // 减去头部和底部高度
+    }
+  }).exec()
+}
+
+const handleItemClick = (item, levelIndex) => {
+  // if ((!props.multiple && !item?.children?.length) || props.oneLevel) {
+  //   inputVal.value = item[props.itemLabel]
+  //   emit('update:value', item[props.itemValue])
+  //   emit('change', item[props.itemValue], item)
+  //   closePopup()
+  //   return
+  // }
+
+  // 处理多选
+  if (props.multiple) {
+    handleMultiSelect(item, levelIndex)
+    return
+  }
+  
+  // 处理单选
+  handleSingleSelect(item, levelIndex)
+}
+
+const handleSingleSelect = (item, levelIndex) => {
+  const newShowList = [...showList.value]
+  
+  // 更新当前级别的选择
+  newShowList[levelIndex].choose = item[props.itemValue]
+  
+  // 如果有子级,添加下一级
+  if (!props.oneLevel && hasChildren(item)) {
+    newShowList.splice(levelIndex + 1)
+    newShowList.push({
+      choose: -1,
+      data: item[props.children]
+    })
+  } else {
+    // 没有子级,截断后面的级别
+    newShowList.splice(levelIndex + 1)
+    // 最后一级,更新输出文本
+    inputVal.value = item[props.itemLabel]
+    emit('update:value', item[props.itemValue])
+    emit('change', item[props.itemValue], item)
+    closePopup()
+  }
+  
+  showList.value = newShowList
+}
+
+const handleMultiSelect = (item, levelIndex) => {
+  const newShowList = [...showList.value]
+  const currentLevel = newShowList[levelIndex]
+  
+  // 初始化选择数组
+  if (!Array.isArray(currentLevel.choose)) {
+    currentLevel.choose = []
+  }
+  
+  // 切换选择状态
+  const index = currentLevel.choose.indexOf(item[props.itemValue])
+  if (index === -1) {
+    currentLevel.choose.push(item[props.itemValue])
+  } else {
+    currentLevel.choose.splice(index, 1)
+  }
+  
+  showList.value = newShowList
+}
+
+const inputChange = () => {
+  debouncedSearch(keyword.value)
+}
+
+const handleClear = () => {
+  initShowList()
+  inputVal.value = ''
+  emit('update:value', props.multiple ? [] : null)
+  emit('update:text', '')
+  emit('change', props.multiple ? [] : null)
+  closePopup()
+}
+
+const handleConfirm = () => {
+  if (props.multiple) {
+    const selectedValues = []
+    const selectedLabels = []
+    
+    showList.value.forEach(level => {
+      if (Array.isArray(level.choose)) {
+        level.data.forEach(item => {
+          if (level.choose.includes(item[props.itemValue])) {
+            selectedValues.push(item[props.itemValue])
+            selectedLabels.push(item[props.itemLabel])
+          }
+        })
+      }
+    })
+    
+    emit('update:value', selectedValues)
+    emit('update:text', selectedLabels.join(','))
+    emit('change', selectedValues)
+  } else {
+    const lastLevel = showList.value[showList.value.length - 1]
+    const selectedItem = lastLevel.data.find(item => item[props.itemValue] === lastLevel.choose)
+    
+    if (selectedItem) {
+      emit('update:value', selectedItem[props.itemValue])
+      emit('update:text', selectedItem[props.itemLabel])
+      emit('change', selectedItem[props.itemValue])
+    }
+  }
+  
+  closePopup()
+}
+
+// 监听props变化
+watch(() => props.items, initShowList, { immediate: true })
+
+watch(() => props.value, (newVal) => {
+  // if (!newVal) {
+  //   initShowList()
+  //   inputVal.value = ''
+  //   return
+  // }
+  // TODO: 实现回显逻辑
+}, { immediate: true })
+
+watch(() => props.text, (newVal) => {
+  inputVal.value = newVal || ''
+}, { immediate: true })
+</script>
+
+<style lang="scss" scoped>
+.popup-content {
+  background: #fff;
+  border-radius: 16rpx 16rpx 0 0;
+  padding: 24rpx;
+  box-sizing: border-box;
+  display: flex;
+  flex-direction: column;
+}
+
+.popup-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding-bottom: 16rpx;
+  border-bottom: 1rpx solid #eee;
+}
+
+.popup-title {
+  font-size: 32rpx;
+  font-weight: bold;
+  color: #333;
+}
+
+.popup-search {
+  padding: 24rpx 0;
+}
+
+.popup-body {
+  flex: 1;
+  overflow: hidden;
+}
+
+.level-container {
+  margin-bottom: 16rpx;
+}
+
+.item-container {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 20rpx 16rpx;
+  border-radius: 8rpx;
+  margin-bottom: 8rpx;
+  
+  &.active {
+    background-color: #f5fff9;
+    color: #00B760;
+  }
+  
+  &.has-children {
+    background-color: #f9f9f9;
+  }
+}
+
+.item-label {
+  flex: 1;
+  font-size: 28rpx;
+}
+
+.item-icons {
+  margin-left: 16rpx;
+}
+
+.popup-footer {
+  display: flex;
+  justify-content: space-between;
+  padding-top: 24rpx;
+  border-top: 1rpx solid #eee;
+  
+  .btn {
+    flex: 1;
+    height: 80rpx;
+    line-height: 80rpx;
+    font-size: 28rpx;
+    border-radius: 8rpx;
+    
+    &.cancel {
+      background: #f5f5f5;
+      color: #666;
+      margin-right: 16rpx;
+    }
+    
+    &.confirm {
+      background: #00B760;
+      color: #fff;
+      
+      &[disabled] {
+        opacity: 0.6;
+      }
+    }
+  }
+}
+</style>

+ 341 - 0
components/selector/singleSelector.vue

@@ -0,0 +1,341 @@
+<!-- 单选选择器 -->
+<template>
+  <view>
+    <!-- 表单输入框 -->
+    <view v-if="formInput">
+      <uni-easyinput
+        v-model="inputText"
+        type="text"
+        :placeholder="placeholder"
+        :clearable="clearable"
+        :readonly="readonly"
+        @clear="handleClear"
+        @focus.stop="handleOpen('focus')"
+      ></uni-easyinput>
+    </view>
+    <!-- 插槽 -->
+    <view v-else @tap="handleOpen('slot')">
+      <slot></slot>
+    </view>
+    <!-- 弹窗 -->
+    <uni-popup ref="popup">
+      <view class="popup-content" :style="popupStyle">
+        <view class="popup-header">
+          <view class="popup-title">{{ label }}</view>
+          <uni-icons 
+            type="closeempty" 
+            size="24" 
+            color="#999" 
+            @tap="closePopup"
+          />
+        </view>
+        
+        <view class="popup-search" v-if="filter">
+          <uni-easyinput
+            v-model="inputKeyword"
+            type="text"
+            :placeholder="searchPlaceholder"
+            @input="inputChange"
+            suffixIcon="search"
+            clearable
+          ></uni-easyinput>
+        </view>
+        
+        <scroll-view class="popup-body" scroll-y :style="{ height: bodyHeight }">
+          <view class="level-container">
+            <view v-if="!showList?.length" class="empty-state">
+              <uni-icons type="info" size="24" color="#999" />
+              <text class="empty-text">{{ inputKeyword ? '没有匹配的数据' : '暂无数据' }}</text>
+            </view>
+            <template v-else>
+              <view
+                v-for="item in showList" 
+                :key="item[itemValue]" 
+                class="item-container"
+                :class="calcClass(item)"
+                @tap="handleItemClick(item)"
+              >
+                <text class="item-label">{{ item[itemLabel] }}</text>
+                <view class="item-icons">
+                  <uni-icons 
+                    v-if="isItemActive(item)"
+                    type="checkmarkempty" 
+                    color="#00B760" 
+                    size="16"
+                  />
+                </view>
+              </view>
+            </template>
+          </view>
+        </scroll-view>
+      </view>
+    </uni-popup>
+  </view>
+</template>
+
+<script setup>
+import { ref, watch, computed } from 'vue'
+import { debounce } from 'lodash-es'
+
+const emit = defineEmits(['update:modelValue', 'change', 'search'])
+
+const props = defineProps({
+  // 基础属性
+  modelValue: [String, Number, Array, Object],
+  text: String,
+  items: {
+    type: Array,
+    default: () => []
+  },
+  label: {
+    type: String,
+    default: '请选择'
+  },
+  placeholder: {
+    type: String,
+    default: '请选择'
+  },
+  
+  // 字段映射
+  itemLabel: {
+    type: String,
+    default: 'label'
+  },
+  itemValue: {
+    type: String,
+    default: 'value'
+  },
+  children: {
+    type: String,
+    default: 'children'
+  },
+  bodyHeight: {
+    type: String,
+    default: '60vh'
+  },
+  
+  // 功能开关
+  multiple: Boolean,
+  filter: Boolean, // 可检索
+  clearable: Boolean,
+  readonly: Boolean,
+  hideChildren: Boolean, // 不展示子级
+  footer: Boolean, // 显示底部按钮
+  // 表单右侧输入框
+  formInput: {
+    type: Boolean,
+    default: true
+  },
+  // 搜索相关
+  searchPlaceholder: {
+    type: String,
+    default: '请输入'
+  },
+  searchDebounceTime: {
+    type: Number,
+    default: 500
+  },
+  
+  // 样式
+  popupStyle: [String, Object],
+  
+  // 文本自定义
+  clearText: {
+    type: String,
+    default: '清除'
+  },
+  submitText: {
+    type: String,
+    default: '确定'
+  }
+})
+
+// 组件引用
+const popup = ref()
+
+// 数据状态
+const inputText = ref('')
+const inputValue = ref(null)
+const inputKeyword = ref('')
+const showList = ref([])
+
+// 计算属性
+const filteredItems = computed(() => {
+  if (!inputKeyword.value) {
+    return props.items
+  }
+  return props.items?.filter(item => 
+    item[props.itemLabel]?.toLowerCase().includes(inputKeyword.value.toLowerCase())
+  )
+})
+
+// 使用 lodash 的防抖
+const debouncedSearch = debounce(() => {
+  showList.value = filteredItems.value
+  emit('search', inputKeyword.value)
+}, props.searchDebounceTime)
+
+const inputChange = () => {
+  debouncedSearch()
+}
+
+const isItemActive = (item) => {
+  return inputValue.value === item[props.itemValue]
+}
+
+// 方法
+const calcClass = (item) => {
+  return {
+    active: isItemActive(item),
+    // 'has-children': item[props.children]?.length > 0
+  }
+}
+
+const handleOpen = async () => {
+  popup.value.open('bottom')
+}
+
+const handleClear = () => {
+  inputValue.value = null
+  inputText.value = ''
+  emit('update:modelValue', null)
+  emit('change', null, null)
+}
+
+const closePopup = () => {
+  popup.value.close()
+}
+
+const handleItemClick = (item) => {
+  inputText.value = item[props.itemLabel]
+  inputValue.value = item[props.itemValue]
+  emit('update:modelValue', item[props.itemValue])
+  emit('change', item[props.itemValue], item)
+  closePopup()
+}
+
+// 回显
+const getInputText = () => {
+  if (inputValue.value && props.items?.length) {
+    const item = props.items.find(i => i[props.itemValue] === inputValue.value)
+    inputText.value = item?.[props.itemLabel] || ''
+  }
+}
+
+const initShowList = () => {
+  showList.value = filteredItems.value
+  getInputText()
+}
+
+// 监听props变化
+watch(() => props.items, initShowList, { immediate: true })
+
+// 实现回显逻辑
+watch(() => props.modelValue, (newVal) => {
+  inputValue.value = newVal || null
+  getInputText()
+}, { immediate: true })
+
+</script>
+
+<style lang="scss" scoped>
+.popup-content {
+  background: #fff;
+  border-radius: 16rpx 16rpx 0 0;
+  padding: 24rpx;
+  box-sizing: border-box;
+  display: flex;
+  flex-direction: column;
+}
+
+.popup-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding-bottom: 16rpx;
+  border-bottom: 1rpx solid #eee;
+}
+
+.popup-title {
+  font-size: 32rpx;
+  font-weight: bold;
+  color: #333;
+}
+
+.popup-search {
+  padding: 24rpx 0;
+}
+
+.level-container {
+  margin-bottom: 16rpx;
+}
+
+.empty-state {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  padding: 40rpx 0;
+  
+  .empty-text {
+    margin-top: 16rpx;
+    color: #999;
+    font-size: 28rpx;
+  }
+}
+
+.item-container {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 20rpx 16rpx;
+  border-radius: 8rpx;
+  margin-bottom: 8rpx;
+  transition: all 0.3s ease;
+  
+  &.active {
+    background-color: #f5fff9;
+    color: #00B760;
+  }
+}
+
+.item-label {
+  flex: 1;
+  font-size: 28rpx;
+}
+
+.item-icons {
+  margin-left: 16rpx;
+}
+
+.popup-footer {
+  display: flex;
+  justify-content: space-between;
+  padding-top: 24rpx;
+  border-top: 1rpx solid #eee;
+  
+  .btn {
+    flex: 1;
+    height: 80rpx;
+    line-height: 80rpx;
+    font-size: 28rpx;
+    border-radius: 8rpx;
+    text-align: center;
+    
+    &.cancel {
+      background: #f5f5f5;
+      color: #666;
+      margin-right: 16rpx;
+    }
+    
+    &.confirm {
+      background: #00B760;
+      color: #fff;
+      
+      &[disabled] {
+        opacity: 0.6;
+      }
+    }
+  }
+}
+</style>

+ 2 - 0
layout/components/authModal/selectUserType/index.vue

@@ -29,6 +29,8 @@ import { ref } from 'vue'
 import studentInfoForm from './studentInfoForm.vue'
 import { showAuthModal } from '@/hooks/useModal'
 
+// handleClickRole(1) // 测试
+
 const showSelect = ref(true)
 
 const handleClickRole = (type) => {

+ 24 - 1
layout/components/authModal/selectUserType/studentInfoForm.vue

@@ -45,7 +45,21 @@
           <uni-data-picker v-model="formData.majorId" :localdata="selects?.major" :clear-icon="false" popup-title="请选择所学专业" @change="getSelectData(2)" :map="{ text: 'nameCn', value: 'id' }"></uni-data-picker>
         </uni-forms-item>
         <uni-forms-item name="schoolClassId" label="所在班级">
-          <searchComBox ref="schoolClassIdRef" v-model="formData.schoolClassId" :candidates="classList" itemTextName='schoolClassName' itemValueName='schoolClassId' labelKey='name' valueKey='id' placeholder="请选择所在班级"></searchComBox>
+          <searchCombox ref="schoolClassIdRef" v-model="formData.schoolClassId" :candidates="classList" itemTextName='schoolClassName' itemValueName='schoolClassId' labelKey='name' valueKey='id' placeholder="请选择所在班级"></searchCombox>
+          <!-- <singleSelector 
+            v-model="formData.schoolClassId"
+            ref="schoolClassIdRef" 
+            filter
+            input
+            :clearable="true"
+            :items="classList" 
+            itemTextName='schoolClassName' 
+            itemValueName='schoolClassId' 
+            itemLabel='name' 
+            itemValue='id' 
+            label='所在班级' 
+            placeholder="请选择所在班级"
+          ></singleSelector> -->
         </uni-forms-item>
         <uni-forms-item name="studentNo" label="学号">
           <uni-easyinput placeholder="请填写学号" v-model="formData.studentNo" :inputBorder="false" type="text"></uni-easyinput>
@@ -84,6 +98,7 @@ import searchComBox from '@/components/searchCombox'
 import { weixinLoginAuthorize } from '@/api/qrcodeLogin.js'
 
 const wxLoginCode = uni.getStorageSync('wxLoginCode')
+// import singleSelector from '@/components/selector/singleSelector.vue'
 
 const baseInfoRef = ref()
 const formData = ref({ // 必填项目
@@ -116,6 +131,14 @@ onMounted(() => {
 // // 下拉列表 
 const selects = ref({})
 const classList = ref([])
+// classList.value = Array.from({ length: 20 }, (_, index) => ({
+//   name: `测试${index + 1}`,
+//   id: `${index + 1}`
+// }))
+// classList.value[1].children = [{name: '二级1', id: '123'}]
+// classList.value[3].children = [{name: '二级3', id: '1233'}]
+// console.log(classList.value)
+
 const getSelectData = async (type = 'default', init = false) => { // type: 0院系|1专业|2班级
   const params = { ...(type !== 'default' && { type }) }
   // 查院系用 schoolId 查班级用 parentId

+ 1 - 1
pages/index/my.vue

@@ -135,7 +135,7 @@ watch(
 watch(
   () => vip.value, 
   (newVal) => {
-		if (newVal) list.value.splice(3, 0, {	title: '我的vip权益', key: 'vip',	path: '/pagesA/vip/index', src: 'https://minio.menduner.com/dev/58cc8847965aaa4e80064732a2024b690ff2285aa57cc4d133846a1e06a23478.png'	})
+		if (newVal) list.value.splice(3, 0, {	title: '我的vip权益', key: 'vip',	path: '/pagesA/vip/index', src: 'https://minio.menduner.com/dev/4e9f86f6a48b78c1aca7a6a6b3c5971044275a7f890f73d7c3b981f125378a0f.png'	})
 		else list.value = list.value.filter(e => !e.key || e.key !== 'vip')
   },
   { immediate: true },

+ 1 - 1
store/modal.js

@@ -3,7 +3,7 @@ import { defineStore } from 'pinia';
 export const modalStore = defineStore({
   id: 'modal',
   state: () => ({
-    auth: '', // 授权弹框 login|resetPassword|changeMobile|changePassword|changeUsername
+    auth: '', // 授权弹框 login|resetPassword|changeMobile|changePassword|changeUsername|selectUserType
     lastTimer: {
       // 短信验证码计时器,为了防止刷新请求做了持久化
       smsRegister: 0,