Преглед изворни кода

完成三种基本类型内容表单

yuanmingze пре 2 месеци
родитељ
комит
d208c2263f

+ 75 - 0
src/pages-task/task-form/components/DateTimePicker.vue

@@ -0,0 +1,75 @@
+<template>
+  <view class="single-select">
+    <wd-cell
+      :placeholder="'请选择' + taskFieldConfig.taskFiledValue"
+      :title="taskFieldConfig.taskFiledValue"
+      :required="taskFieldConfig.isMustfill === '1'"
+      :value="cellValue"
+      :is-link="!isDisabled"
+      @click="pickerClick"
+    />
+
+    <wd-datetime-picker
+      v-model="datetimePickerValue"
+      v-model:visible="datetimePickerShow"
+      type="datetime"
+      @confirm="handleConfirm"
+    />
+  </view>
+</template>
+
+<script setup lang="ts">
+import { computed, ref, watch } from 'vue'
+
+import dayjs from 'dayjs'
+
+import type { TaskFieldConfigItem } from '@/services/modules/task/taskFrom/type'
+
+interface Props {
+  taskFieldConfig: TaskFieldConfigItem
+  disabled?: boolean
+  selectDisabled?: boolean
+}
+
+const props = withDefaults(defineProps<Props>(), {
+  disabled: false,
+  selectDisabled: false,
+})
+
+const DATE_TIME_FORMAT = 'YYYY-MM-DD HH:mm'
+
+const value = defineModel<FieldValue>('value')
+const label = defineModel<FieldValue>('label')
+
+const datetimePickerShow = ref(false)
+const datetimePickerValue = ref(Date.now())
+
+const isDisabled = computed(() => props.disabled || props.selectDisabled)
+
+const cellValue = computed(() => label.value || value.value || '')
+
+watch(
+  value,
+  (newValue) => {
+    if (!newValue) return
+
+    datetimePickerValue.value = new Date(String(newValue).replace(' ', 'T')).getTime()
+  },
+  {
+    immediate: true,
+  }
+)
+
+const pickerClick = () => {
+  if (isDisabled.value) return
+
+  datetimePickerShow.value = true
+}
+
+const handleConfirm = (timestamp: { value: number }) => {
+  const formattedValue = dayjs(timestamp.value).format(DATE_TIME_FORMAT)
+  value.value = formattedValue
+  label.value = formattedValue
+  datetimePickerValue.value = timestamp.value
+}
+</script>

+ 20 - 9
src/pages-task/task-form/components/SingleSelect.vue

@@ -4,9 +4,9 @@
       :placeholder="'请选择' + taskFieldConfig.taskFiledValue"
       :title="taskFieldConfig.taskFiledValue"
       :required="taskFieldConfig.isMustfill === '1'"
+      :value="cellValue"
+      :is-link="!isDisabled"
       @click="pickerClick"
-      is-link
-      :value="label"
     />
 
     <wd-picker
@@ -19,9 +19,17 @@
 </template>
 
 <script setup lang="ts">
+import { computed, ref } from 'vue'
+
 import type { DictItem } from '@/services/modules/common/type'
 import type { TaskFieldConfigItem, TaskFieldDictMap } from '@/services/modules/task/taskFrom/type'
 
+type FieldValue = string | number | undefined
+
+interface PickerConfirmEvent {
+  selectedItems: DictItem[]
+}
+
 interface Props {
   taskFieldConfig: TaskFieldConfigItem
   taskFieldDict: TaskFieldDictMap
@@ -34,17 +42,20 @@ const props = withDefaults(defineProps<Props>(), {
   selectDisabled: false,
 })
 
-const label = defineModel<string>('label')
-
-const value = defineModel<string | number>('value')
+const label = defineModel<FieldValue>('label')
+const value = defineModel<FieldValue>('value')
 
 const dict = ref<DictItem[]>([])
-
 const pickerShow = ref(false)
-
 const pickerValue = ref<(string | number)[]>([])
 
+const isDisabled = computed(() => props.disabled || props.selectDisabled)
+
+const cellValue = computed(() => label.value ?? '')
+
 const pickerClick = () => {
+  if (isDisabled.value) return
+
   const dictName = props.taskFieldConfig.dictGroupName
   dict.value = dictName ? (props.taskFieldDict[dictName] ?? []) : []
   pickerShow.value = true
@@ -52,10 +63,10 @@ const pickerClick = () => {
 
 const handleSelect = (option: PickerConfirmEvent) => {
   const selected = option.selectedItems[0]
+  if (!selected) return
+
   pickerValue.value = [selected.value]
   label.value = selected.label
   value.value = selected.value
 }
 </script>
-
-<style lang="scss" scoped></style>

+ 47 - 0
src/pages-task/task-form/components/SingleText.vue

@@ -0,0 +1,47 @@
+<template>
+  <view class="single-text">
+    <wd-cell :title="taskFieldConfig.taskFiledValue" :required="taskFieldConfig.isMustfill === '1'">
+      <wd-input
+        v-model="inputValue"
+        type="text"
+        :placeholder="'请输入' + taskFieldConfig.taskFiledValue"
+        clearable
+        clear-trigger="focus"
+        align-right
+        :disabled="props.disabled"
+        :readonly="props.readonly"
+        custom-style="--wot-input-padding: 0; padding: 0;"
+      />
+    </wd-cell>
+  </view>
+</template>
+
+<script setup lang="ts">
+import { computed } from 'vue'
+
+import type { TaskFieldConfigItem } from '@/services/modules/task/taskFrom/type'
+
+interface Props {
+  taskFieldConfig: TaskFieldConfigItem
+  disabled?: boolean
+  readonly?: boolean
+}
+
+const props = withDefaults(defineProps<Props>(), {
+  disabled: false,
+  readonly: false,
+})
+
+const label = defineModel<FieldValue>('label')
+const value = defineModel<FieldValue>('value')
+
+const inputValue = computed<string>({
+  get() {
+    return String(value.value ?? label.value ?? '')
+  },
+  set(newValue) {
+    value.value = newValue
+    label.value = newValue
+  },
+})
+</script>

+ 4 - 4
src/pages-task/task-form/composables/useTaskForm.ts

@@ -7,8 +7,8 @@ interface DynamicFormState {
   value: Record<
     string,
     {
-      label: string | number | boolean | null
-      value: string | number | boolean | null
+      label: FieldValue
+      value: FieldValue
     }
   >
 }
@@ -27,8 +27,8 @@ export const useTaskForm = () => {
 
     config.forEach((item) => {
       value[item.id] = {
-        label: null,
-        value: null,
+        label: '',
+        value: '',
       }
     })
 

+ 26 - 1
src/pages-task/task-form/index.vue

@@ -4,7 +4,7 @@
       <wd-notice-bar
         :text="noticeText"
         prefix="warn-bold"
-        type="info "
+        type="info"
         color="#f90"
         background-color="#fdf6ec "
       />
@@ -20,6 +20,23 @@
             v-model:value="form.value[item.id].value"
           />
         </template>
+        <template v-if="isTextInput(item.taskFiledType)">
+          <SingleText
+            :key="item.id"
+            :taskFieldConfig="item"
+            :readonly="item.taskFiledType === 'readonlytext'"
+            v-model:label="form.value[item.id].label"
+            v-model:value="form.value[item.id].value"
+          />
+        </template>
+        <template v-if="isDateTimePicker(item.taskFiledType)">
+          <DateTimePicker
+            :key="item.id"
+            :taskFieldConfig="item"
+            v-model:label="form.value[item.id].label"
+            v-model:value="form.value[item.id].value"
+          />
+        </template>
       </view>
     </view>
 
@@ -30,7 +47,9 @@
 <script setup lang="ts">
 import { onLoad } from '@dcloudio/uni-app'
 
+import DateTimePicker from './components/DateTimePicker.vue'
 import SingleSelect from './components/SingleSelect.vue'
+import SingleText from './components/SingleText.vue'
 import { useNavigation } from './composables/useNavigation'
 import { useTaskForm } from './composables/useTaskForm'
 import { useTaskNotice } from './composables/useTaskNotice'
@@ -44,6 +63,12 @@ const { form, taskFieldConfigList, taskFieldDict, loadTaskForm } = useTaskForm()
 const isSingleSelect = (taskFiledType: string) => {
   return ['domain', 'select'].includes(taskFiledType)
 }
+const isTextInput = (taskFiledType: string) => {
+  return ['text', 'readonlytext'].includes(taskFiledType)
+}
+const isDateTimePicker = (taskFiledType: string) => {
+  return ['datetime'].includes(taskFiledType)
+}
 
 type PageLoadOptions = {
   taskTitle?: string

+ 1 - 1
src/pages/index/index.vue

@@ -19,7 +19,7 @@
       <wd-notice-bar
         text="任务包即将完成时,请不要做积分较高的任务,避免浪费积分哦~"
         prefix="warn-bold"
-        type="info "
+        type="info"
         color="#f90"
         background-color="#fdf6ec "
       />

+ 2 - 0
src/types/wotui-global.d.ts

@@ -2,3 +2,5 @@ declare interface PickerConfirmEvent {
   selectedItems: PickerItem[]
   value: string[]
 }
+
+type FieldValue = string | number | undefined