bzkf3 3 年之前
父节点
当前提交
2e56e2d665

+ 68 - 0
src/components/ItemTable/index.vue

@@ -0,0 +1,68 @@
+<script setup lang="ts">
+import { ref, watch } from 'vue';
+
+
+const props = defineProps<{
+  cols: {
+    k: string
+    v: string
+  }[]
+  modelValue?: string
+}>()
+
+const emits = defineEmits(["update:modelValue"])
+
+type RowData = {
+  [key: string]: string
+}
+
+const data = ref<RowData[]>(props.modelValue ? JSON.parse(props.modelValue) : [])
+
+function newRow() {
+  const obj: RowData = {}
+  props.cols.forEach(({ k }) => {
+    obj[k] = ''
+  })
+  return obj
+}
+
+const addData = (i: number) => {
+  data.value.splice(i, 0, newRow())
+}
+
+const removeData = (i: number) => {
+  data.value.splice(i, 1)
+}
+
+
+watch(
+  () => data.value,
+  (val) => {
+    emits("update:modelValue", JSON.stringify(val))
+  },
+  {
+    deep: true
+  }
+)
+</script>
+
+<template>
+  <el-table :data="data" cell-class-name="py-0">
+    <el-table-column v-for="({ k, v }) in cols" :prop="k" :label="v">
+      <template #default="{ row }">
+        <el-input size="small" v-model="row[k]"></el-input>
+      </template>
+    </el-table-column>
+
+    <el-table-column>
+      <template #header>
+        <el-button size="small" @click="addData(0)">新增</el-button>
+      </template>
+
+      <template #default="{ row, $index }">
+        <el-button size="small" @click="addData($index + 1)">新增</el-button>
+        <el-button size="small" @click="removeData($index)">移除</el-button>
+      </template>
+    </el-table-column>
+  </el-table>
+</template>

+ 88 - 0
src/components/RemoteMultiSelect/index.vue

@@ -0,0 +1,88 @@
+<script setup lang="ts">
+import { ref, watch } from 'vue';
+import request from '~/utils/request';
+
+
+const props = defineProps<{
+  url?: string,
+  to?: 'team' | 'grade' | 'class',
+  modelValue?: string,
+  modelName?: string,
+  change?: (item: object | undefined) => void
+}>()
+const emits = defineEmits(["update:modelValue", "update:modelName"])
+
+const loading = ref(false)
+
+const value = ref(props.modelValue ? props.modelValue.split(',') : [])
+const names = props.modelName ? props.modelName.split(',') : []
+
+const options = ref<{ name: string, value: string, origin?: {} }[]>((value.value.length > 0) ? value.value.map((val, idx) => ({
+  value: val,
+  name: names[idx]
+})) : [])
+
+remoteMethod().then(() => {
+  // 
+
+  // console.log('true :>> ', props.modelValue, props.modelName, options.value.find(({ value: val }) => val === props.modelValue));
+  if (props.modelValue && props.modelName) {
+    value.value.forEach((val, idx) => {
+      if (!options.value.find((option) => val === option.value)) {
+        options.value.unshift({
+          value: val,
+          name: names[idx],
+        })
+      }
+    })
+  }
+})
+
+function remoteMethod(keyword?: string) {
+  loading.value = true
+  return request({
+    url: props.to ? `/jcxx/${props.to}/index` : props.url,
+    data: {
+      keyword,
+      limit: 15
+    }
+  }).then(({ data }) => {
+    options.value = data.page_data.map((item: { [index: string]: string }) => ({
+      name: item[props.to + '_name'],
+      value: item[props.to + '_id'],
+      origin: item
+    }))
+
+    loading.value = false
+  })
+}
+
+
+
+watch(
+  () => value.value,
+  (val) => {
+    const list = val.map(v => options.value.find(({ value }) => value === v)).sort();
+    // console.log('list :>> ', list, list.map(({ value }) => value).join(',')), list.map(({ name }) => name).join(',')));
+    emits("update:modelValue", list.map((i) => i?.value).join(','));
+    emits("update:modelName", list.map((i) => i?.name).join(','));
+    props.change?.(list.map((i) => i?.origin));
+  }
+)
+
+watch(() => props.modelValue, (val) => {
+  if (val === undefined) {
+    value.value = []
+  }
+})
+</script>
+
+
+
+<template>
+  <el-select class="w-full" v-model="value" filterable remote reserve-keyword clearable :remote-method="remoteMethod"
+    :loading="loading" multiple>
+    <el-option v-for="item in options" :key="item.value" :label="item.name" :value="item.value" />
+  </el-select>
+</template>
+

+ 83 - 0
src/components/RemoteSelect/index.vue

@@ -0,0 +1,83 @@
+<script setup lang="ts">
+import { ref, watch } from 'vue';
+import request from '~/utils/request';
+
+
+const props = defineProps<{
+  url?: string,
+  to?: 'team' | 'grade' | 'class',
+  modelValue?: string,
+  modelName?: string,
+  change?: (item: object | undefined) => void,
+  fields?: [string, string]
+}>()
+const emits = defineEmits(["update:modelValue", "update:modelName"])
+
+const loading = ref(false)
+
+const value = ref(props.modelValue)
+const options = ref<{ name: string, value: string, origin?: {} }[]>((props.modelValue && props.modelName) ? [{
+  name: props.modelName,
+  value: props.modelValue
+}] : [])
+
+remoteMethod().then(() => {
+  // 
+
+  // console.log('true :>> ', props.modelValue, props.modelName, options.value.find(({ value: val }) => val === props.modelValue));
+  if (props.modelValue && props.modelName && !options.value.find(({ value: val }) => val === props.modelValue)) {
+    // console.log('true :>> ', true);
+    options.value.unshift({
+      name: props.modelName,
+      value: props.modelValue
+    })
+  }
+})
+
+function remoteMethod(keyword?: string) {
+  loading.value = true
+  return request({
+    url: props.to ? `/jcxx/${props.to}/index` : props.url,
+    data: {
+      keyword,
+      limit: 15
+    }
+  }).then(({ data }) => {
+    options.value = data.page_data.map((item: { [index: string]: string }) => ({
+      value: item[props.fields ? props.fields[0] : props.to + '_id'],
+      name: item[props.fields ? props.fields[1] : props.to + '_name'],
+      origin: item
+    }))
+
+    loading.value = false
+  })
+}
+
+
+
+watch(
+  () => value.value,
+  (val) => {
+    const item = options.value.find(({ value }) => value === val)
+    emits("update:modelValue", val)
+    emits("update:modelName", item?.name)
+    props.change?.(item?.origin)
+  }
+)
+
+watch(() => props.modelValue, (val) => {
+  if (val === undefined) {
+    value.value = undefined
+  }
+})
+</script>
+
+
+
+<template>
+  <el-select class="w-full" v-model="value" filterable remote reserve-keyword clearable :remote-method="remoteMethod"
+    :loading="loading">
+    <el-option v-for="item in options" :key="item.value" :label="item.name" :value="item.value" />
+  </el-select>
+</template>
+

+ 126 - 0
src/components/RemoteSelectClass/index.vue

@@ -0,0 +1,126 @@
+<script setup lang="ts">
+import { ref, watch } from 'vue';
+import request from '~/utils/request';
+
+
+const props = defineProps<{
+  modelValue?: string,
+  modelName?: string,
+  teamId?: string,
+  teamName?: string,
+  gradeId?: string,
+  gradeName?: string,
+  change?: (item: object | undefined) => void,
+  focusing?: boolean
+}>()
+const emits = defineEmits(["update:modelValue", "update:modelName", "update:teamId", "update:teamName", "update:gradeId", "update:gradeName"])
+
+const loading = ref(false)
+
+const value = ref(props.modelValue)
+const options = ref<{
+  class_name: string,
+  class_id: string,
+  team_id?: string,
+  team_name?: string,
+  grade_id?: string,
+  grade_name?: string,
+}[]>((props.modelValue && props.modelName) ? [{
+  class_name: props.modelName,
+  class_id: props.modelValue,
+  team_id: props.teamId,
+  team_name: props.teamName,
+  grade_id: props.gradeId,
+  grade_name: props.gradeName,
+}] : [])
+
+if (!props.focusing) {
+  remoteMethod().then(() => {
+    if (props.modelValue && props.modelName && !options.value.find(({ class_id: val }) => val === props.modelValue)) {
+      options.value.unshift({
+        class_name: props.modelName,
+        class_id: props.modelValue
+      })
+    }
+  })
+}
+
+let Initing = true
+const handleFocus = () => {
+  if (props.focusing && Initing) {
+    remoteMethod().then(() => {
+      if (props.modelValue && props.modelName && !options.value.find(({ class_id: val }) => val === props.modelValue)) {
+        options.value.unshift({
+          class_name: props.modelName,
+          class_id: props.modelValue
+        })
+      }
+      Initing = false
+    })
+  }
+}
+
+function remoteMethod(keyword?: string) {
+  loading.value = true
+  // console.log('object :>> ', props.teamId, props.gradeId);
+  const assignData = props.focusing ? {
+    team_id: props.teamId,
+    grade_id: props.gradeId,
+  } : {}
+  return request({
+    url: `/jcxx/class/index`,
+    data: {
+      keyword,
+      limit: 15,
+      ...assignData
+    }
+  }).then(({ data }) => {
+    options.value = data.page_data
+    loading.value = false
+  })
+}
+
+
+
+watch(
+  () => value.value,
+  (val) => {
+    const item = options.value.find(({ class_id }) => class_id === val)
+    emits("update:modelValue", val)
+    emits("update:modelName", item?.class_name)
+    if (!props.focusing) {
+      emits("update:teamId", item?.team_id)
+      emits("update:teamName", item?.team_name)
+      emits("update:gradeId", item?.grade_id)
+      emits("update:gradeName", item?.grade_name)
+    }
+    props?.change?.(item)
+  }
+)
+
+watch(() => props.modelValue, (val) => {
+  if (val === undefined) {
+    value.value = undefined
+  }
+})
+
+if (props.focusing) {
+  function init() {
+    if ((props.teamId || props.gradeId) && value.value !== undefined) {
+      Initing = true
+      value.value = ''
+    }
+  }
+  watch(() => props.teamId, () => init())
+  watch(() => props.gradeId, () => init())
+}
+</script>
+
+
+<template>
+  <el-select class="w-full" v-model="value" filterable remote reserve-keyword clearable :remote-method="remoteMethod"
+    :loading="loading" @focus="handleFocus">
+    <el-option v-for="item in options" :key="item.class_id" :label="item.class_name" :value="item.class_id" />
+  </el-select>
+</template>
+