Browse Source

feat: 更新数据表单组件,添加复选框类型支持,优化属性定义和数据绑定

EvilDragon 3 months ago
parent
commit
ab294c6157

+ 6 - 2
packages/app/src/components/data-form.ts

@@ -1,12 +1,16 @@
 export interface DataFormProps {
   labelWidth?: number
   defaultValue?: Date
+  placeholder?: string
+  columns?: { label: string; value: string }[]
+  disabled?: boolean
+  'onUpdate:modelValue'?: (value: string) => void
 }
 export interface DataFormSchema {
   [key: symbol | string]: {
-    type: 'TextField' | 'Select' | 'Radio' | 'Submit' | 'TimePick' | 'Textarea'
+    type: 'TextField' | 'Select' | 'Radio' | 'Submit' | 'TimePick' | 'Textarea' | 'Checkbox'
     label?: string
-    existing?: string
+    existing?: boolean
     props?: DataFormProps
   }
 }

+ 54 - 23
packages/app/src/components/data-form.vue

@@ -3,34 +3,17 @@ import WdButton from 'wot-design-uni/components/wd-button/wd-button.vue'
 import WdInput from 'wot-design-uni/components/wd-input/wd-input.vue'
 import WdPicker from 'wot-design-uni/components/wd-picker/wd-picker.vue'
 import { ConfigProviderThemeVars } from 'wot-design-uni'
+import { DataFormProps, DataFormSchema } from './data-form'
+import { addUnit } from 'wot-design-uni/components/common/util'
+import { omit } from 'radash'
 
 const modelValue = defineModel({
   type: Object,
   default: () => ({}),
 })
-// defineProps({
-//   schema: {
-//     type: Object as PropType<{
-//       [key: string | symbol]: { type: 'TextField' | 'Submit' | string; label?: string; props?: any }
-//     }>,
-//     required: true,
-//     default: () => ({}),
-//   },
-//   direction: {
-//     type: String as PropType<'horizontal' | 'vertical'>,
-//     default: 'vertical',
-//   },
-// })
 withDefaults(
   defineProps<{
-    schema: {
-      [key: symbol]: {
-        type: 'TextField' | 'Select' | 'Radio' | 'Submit'
-        label?: string
-        existing?: boolean
-        props?: any
-      }
-    }
+    schema: DataFormSchema
     direction?: 'horizontal' | 'vertical'
   }>(),
   { direction: 'vertical' },
@@ -78,12 +61,20 @@ const horizontalDefaultProps = {
   Radio: {
     customClass: 'my--4!',
   },
+  Checkbox: {
+    customClass: 'my--4!',
+  },
+  TimePick: {
+    customClass: 'm-0!',
+  },
 }
 const themeVars: ConfigProviderThemeVars = {
   cellPadding: '0',
   cellWrapperPadding: '10rpx',
   radioButtonRadius: '8rpx',
   radioButtonBg: 'transparent',
+  checkboxButtonRadius: '8rpx',
+  checkboxButtonBg: 'transparent',
 }
 const submit = () => {
   emits('submit', modelValue)
@@ -106,7 +97,7 @@ defineExpose({
           :class="[direction === 'horizontal' ? 'items-center' : '']"
           :style="
             direction === 'horizontal'
-              ? { 'grid-template-columns': `${props?.labelWidth} auto` }
+              ? { 'grid-template-columns': `${addUnit(props?.labelWidth)} auto` }
               : {}
           "
         >
@@ -124,10 +115,32 @@ defineExpose({
               ...(direction === 'vertical'
                 ? verticalDefaultProps[type]
                 : horizontalDefaultProps[type]),
-              ...props,
+              ...omit(props, ['labelWidth']),
             }"
             v-model="modelValue[prop]"
           ></wd-input>
+          <wd-datetime-picker
+            v-model="modelValue[prop]"
+            v-if="type === 'TimePick'"
+            v-bind="{
+              ...(direction === 'vertical'
+                ? verticalDefaultProps[type]
+                : horizontalDefaultProps[type]),
+              cell: false,
+              ...props,
+            }"
+          />
+          <wd-textarea
+            v-if="type === 'Textarea'"
+            v-model="modelValue[prop]"
+            v-bind="{
+              ...(direction === 'vertical'
+                ? verticalDefaultProps[type]
+                : horizontalDefaultProps[type]),
+              cell: false,
+              ...props,
+            }"
+          />
           <wd-picker
             v-if="type === 'Select'"
             v-bind="{
@@ -139,6 +152,7 @@ defineExpose({
             }"
             v-model="modelValue[prop]"
           ></wd-picker>
+
           <wd-radio-group
             v-if="type === 'Radio'"
             v-bind="{
@@ -155,6 +169,23 @@ defineExpose({
               <wd-radio :value="value">{{ label }}</wd-radio>
             </template>
           </wd-radio-group>
+
+          <wd-checkbox-group
+            v-if="type === 'Checkbox'"
+            v-bind="{
+              ...(direction === 'vertical'
+                ? verticalDefaultProps[type]
+                : horizontalDefaultProps[type]),
+              ...props,
+              cell: true,
+              shape: 'button',
+            }"
+            v-model="modelValue[prop]"
+          >
+            <template v-for="{ label, value } of props.columns" :key="value">
+              <wd-checkbox custom-class="mr-4!" :modelValue="value">{{ label }}</wd-checkbox>
+            </template>
+          </wd-checkbox-group>
           <wd-button
             v-if="type === 'Submit'"
             v-bind="{

+ 1 - 1
packages/app/src/core/libs/models.ts

@@ -513,7 +513,7 @@ export interface UserAuthInfo {
   channelSource: number
   referrer: string
   employer: string
-  spatialExpertiseType: number
+  spatialExpertiseType: string
   attachment: string
   auditStatus: number
   remark: string

+ 37 - 33
packages/app/src/pages/mine/authentication/index.vue

@@ -27,36 +27,27 @@ import { useRouter } from '../../../core/utils/router'
 import { requestToast } from '../../../core/utils/common'
 import { omit, pick } from 'radash'
 import UploadEvo from '@/components/upload-evo.vue'
+import { DataFormSchema } from '../../../components/data-form'
 
 const { alert } = useMessage()
 const router = useRouter()
 const userStore = useUserStore()
 const { userInfo, isDesigner } = storeToRefs(userStore)
 const { error } = useToast()
-const formData = ref<any>({})
+const formData = ref<any>({ mobile: userInfo.value?.mobile })
 const attachment = ref()
 const formInited = ref(false)
-const a = async () => ({ data: null, code: 0, msg: '' })
 const { data: userAuthInfo, run: setUserAuthInfo } = useRequest(() => getUserAuthInfo())
-// const { data: userAuthInfo, run: setUserAuthInfo } = useRequest(() => a())
-const schema = ref({
+const schema = ref<DataFormSchema>({
   channelSource: {
     type: 'Select',
     label: '来源',
     props: {
-      labelWidth: '126rpx',
+      labelWidth: 63,
       placeholder: '请选择通过哪个渠道入驻的筑巢荟',
       columns: [],
       disabled: userAuthInfo.value != null,
-      'onUpdate:modelValue': (value) => {
-        console.log(value)
-
-        if (value === '4') {
-          schema.value.referrer.existing = false
-        } else {
-          schema.value.referrer.existing = true
-        }
-      },
+      'onUpdate:modelValue': (value) => setReferrerExisting(value),
     },
   },
   referrer: {
@@ -64,8 +55,8 @@ const schema = ref({
     label: '推荐人',
     existing: true,
     props: {
-      labelWidth: '126rpx',
-      placeholder: '请如实填写推荐人编号,设计师会员编号或渠道编号',
+      labelWidth: 63,
+      placeholder: '请填写推荐人编号',
       disabled: userAuthInfo.value != null,
     },
   },
@@ -73,7 +64,7 @@ const schema = ref({
     type: 'TextField',
     label: '姓名',
     props: {
-      labelWidth: '126rpx',
+      labelWidth: 63,
       placeholder: '请输入真实姓名',
     },
   },
@@ -81,30 +72,39 @@ const schema = ref({
     type: 'TextField',
     label: '电话',
     props: {
-      labelWidth: '126rpx',
+      labelWidth: 63,
       placeholder: '请输入电话号码',
+      disabled: true,
     },
   },
   employer: {
     type: 'TextField',
     label: '公司',
     props: {
-      labelWidth: '126rpx',
+      labelWidth: 63,
       placeholder: '请输入所在公司或自己公司名称',
     },
   },
   spatialExpertiseType: {
-    type: 'Radio',
+    type: 'Checkbox',
     label: '擅长空间类型',
     props: {
-      labelWidth: '170rpx',
+      labelWidth: 84,
       placeholder: ' ',
       columns: [],
     },
   },
 })
+const setReferrerExisting = (value: string) => {
+  if (value === '4') {
+    schema.value.referrer.existing = false
+  } else {
+    schema.value.referrer.existing = true
+  }
+}
 const handleSubmit = async () => {
   console.log(formData.value)
+  // return
   if (!userAuthInfo.value) {
     if (formData.value.channelSource !== '4') {
       const { data, code: status } = await requestToast(() =>
@@ -117,9 +117,10 @@ const handleSubmit = async () => {
     }
     const { code, msg } = await createUserAuthInfo({
       gender: userInfo.value.sex,
-      attachment: 'https://via.placeholder.com/319x204',
+      attachment: attachment.value,
       userId: userInfo.value.userId,
       ...formData.value,
+      spatialExpertiseType: formData.value.spatialExpertiseType.join(','),
     })
     if (code === 0) {
       router.replace(`/pages/mine/authentication/submit/success/index`)
@@ -146,15 +147,18 @@ onMounted(async () => {
 
   if (userAuthInfo.value) {
     console.log(userAuthInfo.value)
-    formData.value = pick(userAuthInfo.value, [
-      'channelSource',
-      'referrer',
-      'designerName',
-      'designerName',
-      'mobile',
-      'employer',
-      'spatialExpertiseType',
-    ])
+    formData.value = {
+      ...pick(userAuthInfo.value, [
+        'channelSource',
+        'referrer',
+        'designerName',
+        'designerName',
+        'mobile',
+        'employer',
+      ]),
+      spatialExpertiseType: userAuthInfo.value.spatialExpertiseType?.split(','),
+    }
+    setReferrerExisting(userAuthInfo.value.channelSource.toString())
     attachment.value = userAuthInfo.value.attachment
   }
   const { data } = await getByDictType('member_channel_source')
@@ -173,7 +177,7 @@ onMounted(async () => {
   if (userInfo.value.userAuthStatus === 2) {
     alert({
       title: '审核不通过',
-      msg: '由于系统原因,您提交的认证暂时无法通过,请修改后重新提交',
+      msg: userAuthInfo.value?.remark || '由于系统原因,您提交的认证暂时无法通过,请修改后重新提交',
     })
   }
 })
@@ -186,7 +190,7 @@ defineExpose({})
         <wd-img
           width="100%"
           height="100%"
-          :src="'https://image.zhuchaohui.com/zhucaohui/21d6584cb711834f037a7126855d05572433f776b308596d94aca97dd37e6cfa.png'"
+          :src="'https://image.zhuchaohui.com/zhucaohui/21d6584cb711834f037a763855d05572433f776b308596d94aca97dd37e6cfa.png'"
         ></wd-img>
       </div>
       <div class="absolute top-0 left-0 right-0 bottom--18.5">

+ 1 - 0
packages/app/src/typings.ts

@@ -31,6 +31,7 @@ type IUserInfo = {
   point?: number
   level?: { cardCode: string; icon: string; level: number; name: string; point: number }
   userAuthStatus?: 0 | 1 | 2
+  mobile: string
 }
 
 enum TestEnum {