From 5952d34811ee82e797ef0070f84ff041381072a5 Mon Sep 17 00:00:00 2001
From: huminmin <mac@MacBook-Pro.local>
Date: 星期二, 10 三月 2026 17:52:40 +0800
Subject: [PATCH] 新增采购退货单增加费用等数据
---
src/components/SearchPanel/index.vue | 257 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 257 insertions(+), 0 deletions(-)
diff --git a/src/components/SearchPanel/index.vue b/src/components/SearchPanel/index.vue
new file mode 100644
index 0000000..a1859d2
--- /dev/null
+++ b/src/components/SearchPanel/index.vue
@@ -0,0 +1,257 @@
+<template>
+ <div class="search-panel-container">
+ <el-form
+ ref="formRef"
+ :model="modelValue"
+ class="search-form"
+ label-width="0"
+ >
+ <el-row :gutter="10" class="form-row">
+ <!-- 娓叉煋琛ㄥ崟椤� -->
+ <el-col
+ v-for="(item, index) in visibleSchema"
+ :key="item.prop || index"
+ :xs="24"
+ :sm="12"
+ :md="8"
+ :lg="4"
+ :xl="4"
+ class="search-col"
+ >
+ <el-form-item :prop="item.prop" :rules="item.rules" class="search-form-item">
+ <!-- 鑷畾涔夋彃妲� -->
+ <slot v-if="item.slot" :name="item.slot" :item="item"></slot>
+ <!-- 榛樿娓叉煋绫诲瀷 -->
+ <template v-else>
+ <!-- 杈撳叆妗� -->
+ <el-input
+ v-if="item.type === 'input'"
+ v-model="modelValue[item.prop]"
+ :placeholder="item.placeholder || '璇疯緭鍏�'"
+ clearable
+ class="full-width"
+ v-bind="item.props"
+ @keyup.enter="handleSearch"
+ />
+
+ <!-- 涓嬫媺妗� -->
+ <el-select
+ v-else-if="item.type === 'select'"
+ v-model="modelValue[item.prop]"
+ :placeholder="item.placeholder || '璇烽�夋嫨'"
+ clearable
+ class="full-width"
+ v-bind="item.props"
+ >
+ {{ item || '璇烽�夋嫨' }}
+ <!-- <el-option
+ v-for="(opt,idx) in getOptions(item)"
+ :key="idx"
+ :label="opt.label"
+ :value="opt.value"
+ /> -->
+ </el-select>
+
+ <!-- 鏃ユ湡閫夋嫨鍣� -->
+ <el-date-picker
+ v-else-if="item.type === 'date'"
+ v-model="modelValue[item.prop]"
+ type="date"
+ :placeholder="item.placeholder || '閫夋嫨鏃ユ湡'"
+ style="width: 100%"
+ value-format="YYYY-MM-DD"
+ class="full-width"
+ v-bind="item.props"
+ />
+
+ <!-- 鏃ユ湡鑼冨洿閫夋嫨鍣� -->
+ <el-date-picker
+ v-else-if="item.type === 'daterange'"
+ v-model="modelValue[item.prop]"
+ type="daterange"
+ range-separator="鑷�"
+ start-placeholder="寮�濮嬫棩鏈�"
+ end-placeholder="缁撴潫鏃ユ湡"
+ value-format="YYYY-MM-DD"
+ class="full-width"
+ v-bind="item.props"
+ />
+ </template>
+ </el-form-item>
+ </el-col>
+
+ <!-- 鎸夐挳鍖哄煙 -->
+ <el-col :xs="24" :sm="12" :md="8" :lg="4" :xl="4" class="search-actions-col">
+ <el-form-item class="search-actions">
+ <el-button style="background: #002FA7; color: white;" icon="Search" @click="handleSearch">鎼滅储</el-button>
+ <el-button icon="Refresh" @click="handleReset">閲嶇疆</el-button>
+ </el-form-item>
+ </el-col>
+ </el-row>
+
+ <!-- 灞曞紑/鏀惰捣鎸夐挳 -->
+ <div v-if="schema.length > 5" class="expand-toggle" @click="toggleExpand">
+ <span>{{ isExpanded ? '鏀惰捣' : '灞曞紑' }}</span>
+ <el-icon :class="{ 'is-reverse': isExpanded }">
+ <ArrowDown />
+ </el-icon>
+ </div>
+ </el-form>
+ </div>
+</template>
+
+<script setup name="SearchPanel">
+import { ref, reactive, computed, getCurrentInstance, onMounted } from 'vue';
+import { ArrowDown, Search, Refresh } from '@element-plus/icons-vue';
+
+const { proxy } = getCurrentInstance();
+
+const props = defineProps({
+ // 琛ㄥ崟鏁版嵁瀵硅薄
+ modelValue: {
+ type: Object,
+ required: true
+ },
+ // 琛ㄥ崟閰嶇疆椤�
+ schema: {
+ type: Array,
+ default: () => []
+ }
+});
+
+const emit = defineEmits(['update:modelValue', 'search', 'reset']);
+
+// 鏄惁灞曞紑
+const isExpanded = ref(false);
+const formRef = ref(null);
+const dictMap = reactive({});
+
+// 璁$畻鍙鐨� schema 椤�
+const visibleSchema = computed(() => {
+ if (isExpanded.value || props.schema.length <= 5) {
+ return props.schema;
+ }
+ return props.schema.slice(0, 5);
+});
+
+// 鍒濆鍖栧瓧鍏告暟鎹�
+onMounted(() => {
+ const dicts = props.schema.filter(item => item.dict).map(item => item.dict);
+ if (dicts.length > 0 && proxy.useDict) {
+ const dictData = proxy.useDict(...dicts);
+ Object.keys(dictData).forEach(key => {
+ dictMap[key] = dictData[key];
+ });
+ }
+});
+
+// 鑾峰彇涓嬫媺閫夐」 (鏀寔闈欐�� options 鍜� 瀛楀吀 dict)
+function getOptions(item) {
+ if (item.options) return item.options;
+ if (item.dict && dictMap[item.dict]) {
+ return dictMap[item.dict].value || [];
+ }
+ return [];
+}
+
+// 鎼滅储
+function handleSearch() {
+ emit('search', props.modelValue);
+}
+
+// 閲嶇疆
+function handleReset() {
+ if (formRef.value) {
+ formRef.value.resetFields();
+ }
+ const keys = props.schema.map(item => item.prop).filter(Boolean);
+ keys.forEach(key => {
+ props.modelValue[key] = undefined;
+ });
+ emit('update:modelValue', props.modelValue);
+ emit('reset');
+}
+
+// 鍒囨崲灞曞紑/鏀惰捣
+function toggleExpand() {
+ isExpanded.value = !isExpanded.value;
+}
+</script>
+
+<style scoped lang="scss">
+.search-panel-container {
+ background: #fff;
+ padding: 15px 15px 5px;
+ border-radius: 8px;
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
+ margin-bottom: 15px;
+
+ .search-form {
+ .form-row {
+ width: 100%;
+ }
+
+ .search-col {
+ margin-bottom: 10px;
+ }
+
+ .search-form-item {
+ margin-right: 0;
+ margin-bottom: 0;
+ width: 100%;
+
+ :deep(.el-form-item__content) {
+ width: 100%;
+ }
+ }
+
+ .full-width {
+ width: 100% !important;
+ }
+
+ .search-actions-col {
+ margin-left: auto;
+ display: flex;
+ justify-content: flex-end;
+ margin-bottom: 10px;
+ }
+
+ .search-actions {
+ margin-bottom: 0;
+ margin-right: 0;
+
+ :deep(.el-button--primary) {
+ background-color: #409eff;
+ border-color: #409eff;
+ }
+ }
+
+ .expand-toggle {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 4px;
+ font-size: 13px;
+ color: #909399;
+ cursor: pointer;
+ padding: 5px 0;
+ user-select: none;
+ width: 100%;
+ border-top: 1px solid #f0f2f5;
+ margin-top: 5px;
+
+ &:hover {
+ color: #409eff;
+ }
+
+ .el-icon {
+ transition: transform 0.3s;
+ &.is-reverse {
+ transform: rotate(180deg);
+ }
+ }
+ }
+ }
+}
+</style>
+
--
Gitblit v1.9.3