浏览代码

feat: 适配暗黑模式

叶静 1 周之前
父节点
当前提交
8609477f02

+ 240 - 325
src/sheep/components/sa-table/sa-search/sa-search-inline.global.vue

@@ -7,77 +7,37 @@
           <template v-for="(ft, key, index) in searchFields" :key="key">
             <el-form-item v-if="isExpanded || index < 3" :prop="key" :label="ft.label">
               <!-- tinputprepend 类型 -->
-              <el-input
-                v-if="ft.type == 'tinputprepend' && filter.data[ft.field]"
-                v-model="filter.data[ft.field].value"
-                :placeholder="ft.placeholder || ''"
-                clearable
-              >
+              <el-input v-if="ft.type == 'tinputprepend' && filter.data[ft.field]" v-model="filter.data[ft.field].value"
+                :placeholder="ft.placeholder || ''" clearable>
                 <template #prepend>
-                  <el-select
-                    v-model="filter.data[ft.field].field"
-                    placeholder="选择"
-                    :style="{ width: ft.width ? ft.width + 'px' : '118px' }"
-                  >
-                    <el-option
-                      v-for="o in ft.options"
-                      :key="o.value"
-                      :label="o.label"
-                      :value="o.value"
-                    />
+                  <el-select v-model="filter.data[ft.field].field" placeholder="选择"
+                    :style="{ width: ft.width ? ft.width + 'px' : '118px' }">
+                    <el-option v-for="o in ft.options" :key="o.value" :label="o.label" :value="o.value" />
                   </el-select>
                 </template>
               </el-input>
 
               <!-- tinput 类型 -->
-              <el-input
-                v-else-if="ft.type == 'tinput'"
-                v-model="filter.data[ft.field]"
-                :placeholder="ft.placeholder || ''"
-                clearable
-              />
+              <el-input v-else-if="ft.type == 'tinput'" v-model="filter.data[ft.field]"
+                :placeholder="ft.placeholder || ''" clearable />
 
               <!-- tselect 类型 -->
-              <el-select
-                v-else-if="ft.type == 'tselect' && ft.options.props"
-                v-model="filter.data[ft.field]"
-                :placeholder="ft.label"
-                clearable
-                :style="{ width: ft.width ? ft.width + 'px' : '200px' }"
-              >
-                <el-option
-                  v-for="o in ft.options.data"
-                  :key="o"
-                  :label="o[ft.options.props.label]"
-                  :value="o[ft.options.props.value]"
-                />
+              <el-select v-else-if="ft.type == 'tselect' && ft.options.props" v-model="filter.data[ft.field]"
+                :placeholder="ft.label" clearable :style="{ width: ft.width ? ft.width + 'px' : '200px' }">
+                <el-option v-for="o in ft.options.data" :key="o" :label="o[ft.options.props.label]"
+                  :value="o[ft.options.props.value]" />
               </el-select>
 
               <!-- tcascader 类型 -->
-              <el-cascader
-                v-else-if="ft.type == 'tcascader'"
-                :ref="(el) => setCascaderRef(el, key)"
-                v-model="filter.data[ft.field]"
-                :options="ft.options.data"
-                :props="ft.options.props"
-                :placeholder="ft.label"
-                clearable
-                :style="{ width: ft.width ? ft.width + 'px' : '200px' }"
-              />
+              <el-cascader v-else-if="ft.type == 'tcascader'" :ref="(el) => setCascaderRef(el, key)"
+                v-model="filter.data[ft.field]" :options="ft.options.data" :props="ft.options.props"
+                :placeholder="ft.label" clearable :style="{ width: ft.width ? ft.width + 'px' : '200px' }" />
 
               <!-- tdatetimerange 类型 -->
-              <el-date-picker
-                v-else-if="ft.type == 'tdatetimerange'"
-                v-model="filter.data[ft.field]"
-                type="datetimerange"
-                value-format="YYYY-MM-DD HH:mm:ss"
-                format="YYYY-MM-DD HH:mm:ss"
-                :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]"
-                range-separator="至"
-                start-placeholder="开始日期"
-                end-placeholder="结束日期"
-                :editable="false"
-              />
+              <el-date-picker v-else-if="ft.type == 'tdatetimerange'" v-model="filter.data[ft.field]"
+                type="datetimerange" value-format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss"
+                :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]" range-separator="至"
+                start-placeholder="开始日期" end-placeholder="结束日期" :editable="false" />
             </el-form-item>
           </template>
 
@@ -88,12 +48,7 @@
           <el-form-item>
             <el-button type="primary" @click="confirm">搜索</el-button>
             <el-button @click="reset">重置</el-button>
-            <el-button
-              v-if="hasMoreThanThree"
-              type="text"
-              @click="toggleExpand"
-              class="advanced-toggle-btn"
-            >
+            <el-button v-if="hasMoreThanThree" type="text" @click="toggleExpand" class="advanced-toggle-btn">
               {{ isExpanded ? '收起' : '展开' }}
               <el-icon class="advanced-toggle-icon" :class="{ 'is-expanded': isExpanded }">
                 <ArrowDown />
@@ -108,77 +63,37 @@
             <template v-for="(ft, key, index) in filter.tools" :key="'advanced-' + ft">
               <el-form-item v-if="ft.type && index >= 3" :prop="ft.field" :label="ft.label">
                 <!-- tinputprepend 类型 -->
-                <el-input
-                  v-if="ft.type == 'tinputprepend' && filter.data[ft.field]"
-                  v-model="filter.data[ft.field].value"
-                  :placeholder="ft.placeholder || ''"
-                  clearable
-                >
+                <el-input v-if="ft.type == 'tinputprepend' && filter.data[ft.field]"
+                  v-model="filter.data[ft.field].value" :placeholder="ft.placeholder || ''" clearable>
                   <template #prepend>
-                    <el-select
-                      v-model="filter.data[ft.field].field"
-                      placeholder="选择"
-                      :style="{ width: ft.width ? ft.width + 'px' : '118px' }"
-                    >
-                      <el-option
-                        v-for="o in ft.options"
-                        :key="o.value"
-                        :label="o.label"
-                        :value="o.value"
-                      />
+                    <el-select v-model="filter.data[ft.field].field" placeholder="选择"
+                      :style="{ width: ft.width ? ft.width + 'px' : '118px' }">
+                      <el-option v-for="o in ft.options" :key="o.value" :label="o.label" :value="o.value" />
                     </el-select>
                   </template>
                 </el-input>
 
                 <!-- tinput 类型 -->
-                <el-input
-                  v-else-if="ft.type == 'tinput'"
-                  v-model="filter.data[ft.field]"
-                  :placeholder="ft.placeholder || ''"
-                  clearable
-                />
+                <el-input v-else-if="ft.type == 'tinput'" v-model="filter.data[ft.field]"
+                  :placeholder="ft.placeholder || ''" clearable />
 
                 <!-- tselect 类型 -->
-                <el-select
-                  v-else-if="ft.type == 'tselect' && ft.options.props"
-                  v-model="filter.data[ft.field]"
-                  :placeholder="ft.label"
-                  clearable
-                  :style="{ width: ft.width ? ft.width + 'px' : '200px' }"
-                >
-                  <el-option
-                    v-for="o in ft.options.data"
-                    :key="o"
-                    :label="o[ft.options.props.label]"
-                    :value="o[ft.options.props.value]"
-                  />
+                <el-select v-else-if="ft.type == 'tselect' && ft.options.props" v-model="filter.data[ft.field]"
+                  :placeholder="ft.label" clearable :style="{ width: ft.width ? ft.width + 'px' : '200px' }">
+                  <el-option v-for="o in ft.options.data" :key="o" :label="o[ft.options.props.label]"
+                    :value="o[ft.options.props.value]" />
                 </el-select>
 
                 <!-- tcascader 类型 -->
-                <el-cascader
-                  v-else-if="ft.type == 'tcascader'"
-                  :ref="(el) => setCascaderRef(el, key)"
-                  v-model="filter.data[ft.field]"
-                  :options="ft.options.data"
-                  :props="ft.options.props"
-                  :placeholder="ft.label"
-                  clearable
-                  :style="{ width: ft.width ? ft.width + 'px' : '200px' }"
-                />
+                <el-cascader v-else-if="ft.type == 'tcascader'" :ref="(el) => setCascaderRef(el, key)"
+                  v-model="filter.data[ft.field]" :options="ft.options.data" :props="ft.options.props"
+                  :placeholder="ft.label" clearable :style="{ width: ft.width ? ft.width + 'px' : '200px' }" />
 
                 <!-- tdatetimerange 类型 -->
-                <el-date-picker
-                  v-else-if="ft.type == 'tdatetimerange'"
-                  v-model="filter.data[ft.field]"
-                  type="datetimerange"
-                  value-format="YYYY-MM-DD HH:mm:ss"
-                  format="YYYY-MM-DD HH:mm:ss"
-                  :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]"
-                  range-separator="至"
-                  start-placeholder="开始日期"
-                  end-placeholder="结束日期"
-                  :editable="false"
-                />
+                <el-date-picker v-else-if="ft.type == 'tdatetimerange'" v-model="filter.data[ft.field]"
+                  type="datetimerange" value-format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss"
+                  :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)]" range-separator="至"
+                  start-placeholder="开始日期" end-placeholder="结束日期" :editable="false" />
               </el-form-item>
             </template>
           </div>
@@ -194,264 +109,264 @@
 </template>
 
 <script>
-  import { nextTick, onMounted, reactive, ref, computed } from 'vue';
-  import { isEmpty } from 'lodash';
-  import { ArrowDown } from '@element-plus/icons-vue';
-
-  export default {
-    name: 'SaSearchInline',
-    components: {
-      ArrowDown,
-    },
-  };
+import { nextTick, onMounted, reactive, ref, computed } from 'vue';
+import { isEmpty } from 'lodash';
+import { ArrowDown } from '@element-plus/icons-vue';
+
+export default {
+  name: 'SaSearchInline',
+  components: {
+    ArrowDown,
+  },
+};
 </script>
 
 <script setup>
-  const props = defineProps(['filterParams']);
-  const emit = defineEmits(['filterBack', 'deleteFilter']);
-
-  const formRef = ref();
-  const isExpanded = ref(false);
-
-  const fp = JSON.parse(JSON.stringify(props.filterParams));
-
-  const filter = reactive({
-    tools: fp.tools,
-    data: fp.data,
-    conditionLabel: fp.conditionLabel,
-  });
-
-  // 计算是否有超过3个搜索条件
-  const hasMoreThanThree = computed(() => {
-    return Object.keys(filter.tools).filter((key) => filter.tools[key].type).length > 3;
+const props = defineProps(['filterParams']);
+const emit = defineEmits(['filterBack', 'deleteFilter']);
+
+const formRef = ref();
+const isExpanded = ref(false);
+
+const fp = JSON.parse(JSON.stringify(props.filterParams));
+
+const filter = reactive({
+  tools: fp.tools,
+  data: fp.data,
+  conditionLabel: fp.conditionLabel,
+});
+
+// 计算是否有超过3个搜索条件
+const hasMoreThanThree = computed(() => {
+  return Object.keys(filter.tools).filter((key) => filter.tools[key].type).length > 3;
+});
+
+// 计算是否有已选条件
+const hasConditions = computed(() => {
+  return Object.keys(filter.conditionLabel).length > 0;
+});
+
+// 展开收起切换
+const toggleExpand = () => {
+  isExpanded.value = !isExpanded.value;
+};
+
+// 重置搜索
+function reset() {
+  for (let key in filter.data) {
+    if (filter.tools[key].type == 'tinputprepend') {
+      filter.data[key] = filter.tools[key][filter.tools[key].field];
+    } else {
+      filter.data[key] = filter.tools[key].value;
+    }
+    delete filter.conditionLabel[key];
+  }
+  initLabel();
+  emit('filterBack', {
+    event: 'reset',
+    data: filter,
   });
-
-  // 计算是否有已选条件
-  const hasConditions = computed(() => {
-    return Object.keys(filter.conditionLabel).length > 0;
+}
+
+// 确认搜索
+function confirm() {
+  initLabel();
+  emit('filterBack', {
+    event: 'confirm',
+    data: filter,
   });
+}
 
-  // 展开收起切换
-  const toggleExpand = () => {
-    isExpanded.value = !isExpanded.value;
-  };
-
-  // 重置搜索
-  function reset() {
-    for (let key in filter.data) {
-      if (filter.tools[key].type == 'tinputprepend') {
-        filter.data[key] = filter.tools[key][filter.tools[key].field];
-      } else {
-        filter.data[key] = filter.tools[key].value;
-      }
-      delete filter.conditionLabel[key];
-    }
-    initLabel();
-    emit('filterBack', {
-      event: 'reset',
-      data: filter,
-    });
-  }
+// 删除单个条件
+const deleteFilter = (key) => {
+  emit('deleteFilter', key);
+};
 
-  // 确认搜索
-  function confirm() {
-    initLabel();
-    emit('filterBack', {
-      event: 'confirm',
-      data: filter,
-    });
+// 初始化标签
+function initLabel() {
+  for (let k in filter.conditionLabel) {
+    delete filter.conditionLabel[k];
   }
 
-  // 删除单个条件
-  const deleteFilter = (key) => {
-    emit('deleteFilter', key);
-  };
+  for (var filed in filter.data) {
+    if (filter.tools[filed] && filter.tools[filed].type) {
+      // tinputprepend
+      if (filter.tools[filed].type == 'tinputprepend' && !isEmpty(filter.data[filed].value)) {
+        filter.conditionLabel[filed] =
+          findTinputprependLabel(filter.data[filed].field, filter.tools[filed].options).label +
+          ':' +
+          filter.data[filed].value;
+      }
 
-  // 初始化标签
-  function initLabel() {
-    for (let k in filter.conditionLabel) {
-      delete filter.conditionLabel[k];
-    }
+      // tselect 数据保持一致
+      if (filter.tools[filed].type == 'tselect') {
+        if (!filter.tools[filed].options.props) {
+          filter.tools[filed].options.props = {
+            label: 'label',
+            value: 'value',
+          };
+        }
+      }
 
-    for (var filed in filter.data) {
-      if (filter.tools[filed] && filter.tools[filed].type) {
-        // tinputprepend
-        if (filter.tools[filed].type == 'tinputprepend' && !isEmpty(filter.data[filed].value)) {
-          filter.conditionLabel[filed] =
-            findTinputprependLabel(filter.data[filed].field, filter.tools[filed].options).label +
-            ':' +
-            filter.data[filed].value;
+      if (!isEmpty(filter.data[filed])) {
+        // tinput
+        if (filter.tools[filed].type == 'tinput') {
+          filter.conditionLabel[filed] = filter.tools[filed].label + ':' + filter.data[filed];
         }
 
-        // tselect 数据保持一致
+        // tselect
         if (filter.tools[filed].type == 'tselect') {
-          if (!filter.tools[filed].options.props) {
-            filter.tools[filed].options.props = {
-              label: 'label',
-              value: 'value',
-            };
-          }
+          filter.conditionLabel[filed] =
+            filter.tools[filed].label +
+            ':' +
+            findTselectLabel(filter.data[filed], filter.tools[filed].options)?.[
+            filter.tools[filed].options.props.label
+            ];
         }
 
-        if (!isEmpty(filter.data[filed])) {
-          // tinput
-          if (filter.tools[filed].type == 'tinput') {
-            filter.conditionLabel[filed] = filter.tools[filed].label + ':' + filter.data[filed];
-          }
-
-          // tselect
-          if (filter.tools[filed].type == 'tselect') {
-            filter.conditionLabel[filed] =
-              filter.tools[filed].label +
-              ':' +
-              findTselectLabel(filter.data[filed], filter.tools[filed].options)?.[
-                filter.tools[filed].options.props.label
-              ];
-          }
-
-          // tdatetimerange
-          if (filter.tools[filed].type == 'tdatetimerange') {
-            filter.conditionLabel[filed] =
-              filter.tools[filed].label +
-              ':' +
-              (filter.data[filed] ? filter.data[filed].join(' ~ ') : '');
-          }
+        // tdatetimerange
+        if (filter.tools[filed].type == 'tdatetimerange') {
+          filter.conditionLabel[filed] =
+            filter.tools[filed].label +
+            ':' +
+            (filter.data[filed] ? filter.data[filed].join(' ~ ') : '');
         }
       }
     }
+  }
 
-    // 处理自定义区间字段(价格区间)
-    if (filter.data.price && (filter.data.price.min || filter.data.price.max)) {
-      const min = filter.data.price.min || '0';
-      const max = filter.data.price.max || '∞';
-      filter.conditionLabel.price = `价格区间:${min} - ${max}`;
-    }
+  // 处理自定义区间字段(价格区间)
+  if (filter.data.price && (filter.data.price.min || filter.data.price.max)) {
+    const min = filter.data.price.min || '0';
+    const max = filter.data.price.max || '∞';
+    filter.conditionLabel.price = `价格区间:${min} - ${max}`;
+  }
 
-    // tcascader
-    nextTick(() => {
-      for (let c in cascaderRef) {
-        if (cascaderRef[c]) {
-          let text = [];
-          cascaderRef[c].getCheckedNodes().forEach((l) => {
-            if (l) {
-              text.push(l.text);
-            }
-          });
-          if (!isEmpty(text)) {
-            filter.conditionLabel[c] = filter.tools[c].label + ':' + text.join(',');
+  // tcascader
+  nextTick(() => {
+    for (let c in cascaderRef) {
+      if (cascaderRef[c]) {
+        let text = [];
+        cascaderRef[c].getCheckedNodes().forEach((l) => {
+          if (l) {
+            text.push(l.text);
           }
+        });
+        if (!isEmpty(text)) {
+          filter.conditionLabel[c] = filter.tools[c].label + ':' + text.join(',');
         }
       }
-    });
-  }
-
-  let cascaderRef = {};
-  const setCascaderRef = (el, key) => {
-    if (el) {
-      cascaderRef[key] = el;
     }
-  };
+  });
+}
 
-  function findTselectLabel(value, options) {
-    return options.data.find((a) => {
-      return a[options.props.value] == value;
-    });
+let cascaderRef = {};
+const setCascaderRef = (el, key) => {
+  if (el) {
+    cascaderRef[key] = el;
   }
+};
 
-  function findTinputprependLabel(value, data) {
-    return data.find((a) => {
-      return a.value == value;
-    });
-  }
+function findTselectLabel(value, options) {
+  return options.data.find((a) => {
+    return a[options.props.value] == value;
+  });
+}
 
-  onMounted(() => {
-    initLabel();
+function findTinputprependLabel(value, data) {
+  return data.find((a) => {
+    return a.value == value;
   });
+}
+
+onMounted(() => {
+  initLabel();
+});
 </script>
 
 <style lang="scss" scoped>
-  .sa-search-inline {
-    width: 100%;
+.sa-search-inline {
+  width: 100%;
 
-    .search-form {
-      padding: 16px;
-      background-color: #fff;
-      border-radius: 4px;
+  .search-form {
+    padding: 16px;
+    background-color: var(--sa-card-background);
+    border-radius: 4px;
 
-      :deep(.el-form-item) {
-        margin-bottom: 16px;
-        margin-right: 16px;
-      }
+    :deep(.el-form-item) {
+      margin-bottom: 16px;
+      margin-right: 16px;
+    }
 
-      .search-form-main {
-        display: flex;
-        flex-wrap: wrap;
-        align-items: flex-end;
-        margin-bottom: 0;
-      }
+    .search-form-main {
+      display: flex;
+      flex-wrap: wrap;
+      align-items: flex-end;
+      margin-bottom: 0;
+    }
 
-      .search-form-advanced {
-        display: flex;
-        flex-wrap: wrap;
-        align-items: flex-end;
-        margin-top: 16px;
-        padding-top: 16px;
-      }
+    .search-form-advanced {
+      display: flex;
+      flex-wrap: wrap;
+      align-items: flex-end;
+      margin-top: 16px;
+      padding-top: 16px;
+    }
 
-      .advanced-toggle-btn {
-        margin-left: 8px;
-        color: #409eff;
+    .advanced-toggle-btn {
+      margin-left: 8px;
+      color: #409eff;
 
-        .advanced-toggle-icon {
-          margin-left: 4px;
-          transition: transform 0.3s ease;
+      .advanced-toggle-icon {
+        margin-left: 4px;
+        transition: transform 0.3s ease;
 
-          &.is-expanded {
-            transform: rotate(180deg);
-          }
+        &.is-expanded {
+          transform: rotate(180deg);
         }
+      }
 
-        &:hover {
-          color: #66b1ff;
-        }
+      &:hover {
+        color: #66b1ff;
       }
     }
+  }
 
-    .search-conditions {
-      margin-bottom: 16px;
-    }
+  .search-conditions {
+    margin-bottom: 16px;
   }
+}
 
-  // 响应式设计
-  @media (max-width: 768px) {
-    .sa-search-inline {
-      .search-form {
-        padding: 12px;
+// 响应式设计
+@media (max-width: 768px) {
+  .sa-search-inline {
+    .search-form {
+      padding: 12px;
 
-        :deep(.el-form-item) {
-          margin-bottom: 12px;
-          margin-right: 12px;
-        }
+      :deep(.el-form-item) {
+        margin-bottom: 12px;
+        margin-right: 12px;
+      }
 
-        .search-form-main,
-        .search-form-advanced {
-          flex-direction: column;
-          align-items: stretch;
-        }
+      .search-form-main,
+      .search-form-advanced {
+        flex-direction: column;
+        align-items: stretch;
       }
     }
   }
+}
 
-  @media (max-width: 480px) {
-    .sa-search-inline {
-      .search-form {
-        padding: 8px;
+@media (max-width: 480px) {
+  .sa-search-inline {
+    .search-form {
+      padding: 8px;
 
-        :deep(.el-form-item) {
-          margin-bottom: 8px;
-          margin-right: 8px;
-        }
+      :deep(.el-form-item) {
+        margin-bottom: 8px;
+        margin-right: 8px;
       }
     }
   }
+}
 </style>

+ 1 - 1
src/sheep/components/sa-table/sa-search/sa-search-simple.global.vue

@@ -269,7 +269,7 @@ watch(
 
   .search-form {
     margin-top: 30px;
-    background-color: #fff;
+    background-color: var(--sa-card-background);
     border-radius: 4px;
 
     :deep(.el-form-item) {