فهرست منبع

Merge branch 'ecp' of http://git.echepei.com/gubersail/gubersail-platform-ui into ecp

Qukatie 1 ماه پیش
والد
کامیت
e86780523a

+ 15 - 0
src/api/order/lead-detail.js

@@ -6,9 +6,12 @@ import request from '@/router/axios'
  * @typedef {import('@/api/types/lead-detail').LeadDetailQueryParams} LeadDetailQueryParams
  * @typedef {import('@/api/types/lead-detail').LeadDetailAddParams} LeadDetailAddParams
  * @typedef {import('@/api/types/lead-detail').LeadDetailUpdateParams} LeadDetailUpdateParams
+ * @typedef {import('@/api/types/lead-detail').LeadDetailDeleteParams} LeadDetailDeleteParams
  * @typedef {import('@/api/types/lead-detail').LeadDetailListResponse} LeadDetailListResponse
  * @typedef {import('@/api/types/lead-detail').LeadDetailResponse} LeadDetailResponse
  * @typedef {import('@/api/types/lead-detail').LeadDetailOperationResponse} LeadDetailOperationResponse
+ * @typedef {import('@/api/types/lead-detail').LeadDetailDeleteResponse} LeadDetailDeleteResponse
+ * @typedef {import('@/api/types/lead-detail').DeleteResponse} DeleteResponse
  */
 
 
@@ -83,4 +86,16 @@ export const remove = (ids) => {
       ids
     }
   })
+}
+
+/**
+ * 根据ID删除线索详细信息 (DELETE方法)
+ * @param {string|number} id - 要删除的详细信息ID
+ * @returns {LeadDetailDeleteResponse} 操作结果
+ */
+export const deleteById = (id) => {
+  return request({
+    url: `/api/blade-factory/api/factory/lead-detail/${id}`,
+    method: 'delete'
+  })
 }

+ 6 - 0
src/api/types/claim.d.ts

@@ -102,6 +102,12 @@ export interface ClaimItem {
   updateTime: string;
   /** 备注 */
   remark?: string;
+  /** 车牌号 */
+  vehicleNumber?: string;
+  /** 轮胎数量 */
+  tireQuantity?: number;
+  /** 是否已提交 0-未提交 1-已提交 */
+  isSubmitTime?: number;
 }
 
 /**

+ 28 - 1
src/api/types/lead-detail.d.ts

@@ -41,6 +41,14 @@ export interface LeadDetailUpdateParams extends LeadDetailAddParams {
 }
 
 /**
+ * 根据ID删除参数
+ */
+export interface LeadDetailDeleteParams {
+  /** 详细信息ID */
+  id: string | number;
+}
+
+/**
  * 线索详细信息列表响应
  */
 export type LeadDetailListResponse = Promise<AxiosResponse<ApiResponse<PageResult<LeadDetailRecord>>>>;
@@ -53,4 +61,23 @@ export type LeadDetailResponse = Promise<AxiosResponse<ApiResponse<LeadDetailRec
 /**
  * 线索详细信息操作响应
  */
-export type LeadDetailOperationResponse = Promise<AxiosResponse<ApiResponse<boolean>>>;
+export type LeadDetailOperationResponse = Promise<AxiosResponse<ApiResponse<boolean>>>;
+
+/**
+ * 删除操作的响应类型
+ */
+export interface DeleteResponse {
+  /** 状态码 */
+  code: number;
+  /** 操作是否成功 */
+  success: boolean;
+  /** 返回数据 */
+  data: boolean;
+  /** 响应消息 */
+  msg: string;
+}
+
+/**
+ * 根据ID删除线索详细信息响应
+ */
+export type LeadDetailDeleteResponse = Promise<AxiosResponse<ApiResponse<DeleteResponse>>>;

+ 2 - 2
src/components/announcement/announcement-form-mixin.js

@@ -79,7 +79,7 @@ const dataConverter = {
       content: formModel.content,
       categoryId: formModel.categoryId != null ? String(formModel.categoryId) : '',
       categoryName: formModel.categoryName,
-      orgId: Number(formModel.orgId),
+      orgId: formModel.orgId ? formModel.orgId.toString() : '0',
       orgCode: formModel.orgCode,
       orgName: formModel.orgName,
       /** @type {string} */
@@ -355,7 +355,7 @@ export default {
             content: newVal.content || '',
             categoryId: newVal.categoryId != null ? String(newVal.categoryId) : '',
             categoryName: newVal.categoryName,
-            orgId: Number(newVal.orgId || 0),
+            orgId: newVal.orgId ? newVal.orgId.toString() : '0',
             orgCode: newVal.orgCode || '',
             orgName: newVal.orgName || '',
             visibleRoles: dataConverter.parseVisibleRoles(newVal.visibleRoles || 0),

+ 1 - 1
src/components/announcement/index.js

@@ -39,7 +39,7 @@ const DataConverter = {
        title: formData.title,
        content: formData.content,
        categoryId: formData.categoryId,
-       orgId: Number(formData.orgId) || 0,
+       orgId: formData.orgId ? formData.orgId.toString() : '0',
        orgCode: formData.orgCode,
        orgName: formData.orgName,
        visibleRoles: '0', // 需要根据实际逻辑计算

+ 8 - 8
src/components/forecast-form/forecast-form-mixin.js

@@ -610,7 +610,7 @@ export default {
         customerId: data.customerId ? data.customerId.toString() : null,
         customerCode: String(data.customerCode || ''),
         customerName: String(data.customerName || ''),
-        brandId: Number(data.brandId) || null,
+        brandId: data.brandId ? data.brandId.toString() : null,
         brandCode: String(data.brandCode || ''),
         brandName: String(data.brandName || ''),
         itemId: data.itemId ? data.itemId.toString() : null,
@@ -765,7 +765,7 @@ export default {
         const data = ok ? response.data.data : null
         if (ok && data) {
           // 根据接口common.d.ts中的CustomerInfoData结构进行赋值
-          this.formData.customerId = data.Customer_ID ? Number(data.Customer_ID) : null
+          this.formData.customerId = data.Customer_ID ? data.Customer_ID.toString() : null
           this.formData.customerCode = data.Customer_CODE || ''
           this.formData.customerName = data.Customer_NAME || ''
         }
@@ -1201,7 +1201,7 @@ export default {
      */
     handleCustomerSelected(/** @type {import('./types').CustomerSelectData} */ customerData) {
       if (customerData && customerData.customerId) {
-        this.formData.customerId = Number(customerData.customerId)
+        this.formData.customerId = customerData.customerId ? customerData.customerId.toString() : null
         this.formData.customerCode = customerData.customerCode
         this.formData.customerName = customerData.customerName
         // 选中客户后加载该用户关联的品牌与库存物料(仅新增模式自动加载,编辑模式不覆盖回显数据)
@@ -1240,8 +1240,8 @@ export default {
         this.brandDescList = brandList
         // 存储库存列表供选择用,不直接展示到表格
         this.stockDescList = stockList
-        // 默认显示全部物料至下方表格,预测数量默认 0,用户可手动删除不需要的物料
-        this.stockTableData = stockList.map(item => ({ ...item, forecastQuantity: 0 }))
+        // 默认显示全部物料至下方表格,预测数量默认 1,用户可手动删除不需要的物料
+        this.stockTableData = stockList.map(item => ({ ...item, forecastQuantity: 1 }))
         // 根据表格中已有的物料,过滤下拉选项
         this.updateStockSelectOptions()
         // 规范化分页并回显选择(新增模式首次加载)
@@ -1296,8 +1296,8 @@ export default {
         return
       }
 
-      // 添加到表格,默认预测数量为 0
-      this.stockTableData.push({ ...stock, forecastQuantity: 0 })
+      // 添加到表格,默认预测数量为 1
+      this.stockTableData.push({ ...stock, forecastQuantity: 1 })
       // 清空已选
       this.selectedStockId = null
       // 导入后更新下拉选项(过滤掉已在表格中的物料)
@@ -1576,7 +1576,7 @@ export default {
      */
     handleMaterialSelected(/** @type {import('./types').MaterialSelectData} */ materialData) {
       if (materialData && materialData.itemId) {
-        this.formData.itemId = Number(materialData.itemId)
+        this.formData.itemId = materialData.itemId ? materialData.itemId.toString() : null
         this.formData.itemCode = materialData.itemCode
         this.formData.itemName = materialData.itemName
         this.formData.itemSpecs = materialData.specification || ''

+ 2 - 2
src/components/forecast-form/index.js

@@ -340,7 +340,7 @@ export default {
         itemName: '',
         specs: '',
         itemSpecs: '',
-        forecastQuantity: 0,
+        forecastQuantity: 1,
         currentInventory: null,
         approvalStatus: APPROVAL_STATUS.PENDING,
         approvedName: '',
@@ -384,7 +384,7 @@ export default {
         customerId: data.customerId ? data.customerId.toString() : null,
         customerCode: String(data.customerCode || ''),
         customerName: String(data.customerName || ''),
-        brandId: Number(data.brandId) || null,
+        brandId: data.brandId ? data.brandId.toString() : null,
         brandCode: String(data.brandCode || ''),
         brandName: String(data.brandName || ''),
         itemId: data.itemId ? data.itemId.toString() : null,

+ 145 - 0
src/components/order-item-table-optimized/index.vue

@@ -0,0 +1,145 @@
+<template>
+  <div class="order-item-table-optimized">
+    <el-table
+      :data="itemData"
+      :loading="loading"
+      border
+      size="small"
+      style="width: 100%"
+    >
+      <el-table-column prop="itemCode" label="物料编码" width="120" />
+      <el-table-column prop="itemName" label="物料名称" width="150" />
+      <el-table-column prop="specs" label="规格型号" width="120" />
+      <el-table-column prop="mainItemCategoryName" label="主物料分类" width="120" />
+      <el-table-column prop="warehouseName" label="仓库名称" width="120" />
+      <el-table-column prop="availableQuantity" label="库存数量" width="100" align="right">
+        <template slot-scope="scope">
+          {{ scope.row.availableQuantity | numberFormat(4) }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="orderQuantity" label="订单数量" width="100" align="right">
+        <template slot-scope="scope">
+          {{ scope.row.orderQuantity | numberFormat(4) }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="confirmQuantity" label="确认数量" width="100" align="right">
+        <template slot-scope="scope">
+          {{ scope.row.confirmQuantity | numberFormat(4) }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="unitPrice" label="单价" width="100" align="right">
+        <template slot-scope="scope">
+          ¥{{ scope.row.unitPrice | numberFormat(2) }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="taxRate" label="税率" width="80" align="right">
+        <template slot-scope="scope">
+          {{ scope.row.taxRate | numberFormat(2) }}%
+        </template>
+      </el-table-column>
+      <el-table-column prop="taxAmount" label="税额" width="100" align="right">
+        <template slot-scope="scope">
+          ¥{{ scope.row.taxAmount | numberFormat(2) }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="totalAmount" label="总金额" width="100" align="right">
+        <template slot-scope="scope">
+          ¥{{ scope.row.totalAmount | numberFormat(2) }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="itemStatus" label="明细状态" width="100" align="center">
+        <template slot-scope="scope">
+          <el-tag
+            :type="getStatusType(scope.row.itemStatus)"
+            size="mini"
+          >
+            {{ getStatusText(scope.row.itemStatus) }}
+          </el-tag>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script>
+import { getList } from '@/api/order/order-item'
+import { getOrderItemStatusLabel, getOrderItemStatusTagType } from '@/constants'
+import { formatFloatNumber } from '@/components/order-form/number-format-utils'
+
+export default {
+  name: 'OrderItemTableOptimized',
+  props: {
+    // 新增:支持直接传入明细数据
+    orderItemData: {
+      type: Array,
+      default: () => []
+    },
+    // 保持原有兼容性
+    orderId: {
+      type: [String, Number],
+      default: null
+    }
+  },
+  data() {
+    return {
+      itemData: [],
+      loading: false
+    }
+  },
+  watch: {
+    // 优先使用传入的明细数据
+    orderItemData: {
+      handler(newVal) {
+        if (Array.isArray(newVal) && newVal.length > 0) {
+          this.itemData = newVal
+          this.loading = false
+        }
+      },
+      immediate: true
+    },
+    // 降级:如果没有传入数据,则按原有方式查询
+    orderId: {
+      handler(newVal) {
+        if (newVal && (!this.orderItemData || this.orderItemData.length === 0)) {
+          this.loadItemData()
+        }
+      },
+      immediate: true
+    }
+  },
+  methods: {
+    async loadItemData() {
+      if (!this.orderId) return
+
+      this.loading = true
+      try {
+        const response = await getList(1, 1000, { orderId: this.orderId })
+        this.itemData = response.data.data.records || []
+      } catch (error) {
+        console.error('加载订单明细失败:', error)
+        this.$message.error('加载订单明细失败')
+        this.itemData = []
+      } finally {
+        this.loading = false
+      }
+    },
+    getStatusText(status) {
+      return getOrderItemStatusLabel(status)
+    },
+    getStatusType(status) {
+      return getOrderItemStatusTagType(status)
+    }
+  },
+  filters: {
+    numberFormat(value, precision = 2) {
+      return formatFloatNumber(value)
+    }
+  }
+}
+</script>
+
+<style scoped>
+.order-item-table-optimized {
+  padding: 10px 0;
+}
+</style>

+ 1 - 1
src/constants/forecast.js

@@ -586,7 +586,7 @@ export const DEFAULT_FORECAST_SUMMARY_FORM = {
   itemName: '',
   specs: '',
   itemSpecs: '',
-  forecastQuantity: 0,
+  forecastQuantity: 1,
   currentInventory: 0,
   approvalStatus: APPROVAL_STATUS.PENDING,
   approvedName: '',

+ 374 - 0
src/mixins/survey/surveyCrudMixin.js

@@ -0,0 +1,374 @@
+/**
+ * Survey模块avue-crud配置mixin
+ * @fileoverview 提供基于avue-crud的调查问卷管理功能
+ * @author 开发者
+ * @date 2024-XX-XX
+ */
+
+import {
+  getList,
+  add,
+  update,
+  getDetail
+} from '@/api/survey/survey'
+import {
+  SURVEY_STATUS_OPTIONS,
+  SURVEY_TEMPLATE_OPTIONS,
+  getSurveyStatusLabel,
+  getSurveyStatusType,
+  getSurveyTemplateLabel,
+  getSurveyTemplateType
+} from '@/constants/survey'
+
+export default {
+  data() {
+    return {
+      // avue-crud标准配置
+      option: {
+        height: 'auto',
+        calcHeight: 80,
+        tip: false,
+        searchShow: true,
+        searchMenuSpan: 12,
+        searchIndex: 3,
+        border: true,
+        index: true,
+        viewBtn: true,
+        editBtn: true,
+        delBtn: false, // 暂时禁用删除
+        addBtn: true,
+        selection: false,
+        dialogClickModal: false,
+        menu: true,
+        menuWidth: 200,
+        column: [
+          // 问卷编码列
+          {
+            label: '问卷编码',
+            prop: 'surveyCode',
+            width: 150,
+            search: true,
+            rules: [{
+              required: true,
+              message: '请输入问卷编码',
+              trigger: 'blur'
+            }, {
+              min: 3,
+              max: 50,
+              message: '长度在 3 到 50 个字符',
+              trigger: 'blur'
+            }, {
+              pattern: /^[A-Za-z0-9_-]+$/,
+              message: '只能包含字母、数字、下划线和横线',
+              trigger: 'blur'
+            }]
+          },
+          // 问卷标题列
+          {
+            label: '问卷标题',
+            prop: 'title',
+            minWidth: 200,
+            search: true,
+            overHidden: true,
+            rules: [{
+              required: true,
+              message: '请输入问卷标题',
+              trigger: 'blur'
+            }, {
+              min: 2,
+              max: 100,
+              message: '长度在 2 到 100 个字符',
+              trigger: 'blur'
+            }]
+          },
+          // 问卷描述列
+          {
+            label: '问卷描述',
+            prop: 'description',
+            minWidth: 250,
+            search: false,
+            overHidden: true,
+            type: 'textarea',
+            span: 24,
+            minRows: 3,
+            maxRows: 6,
+            rules: [{
+              required: true,
+              message: '请输入问卷描述',
+              trigger: 'blur'
+            }, {
+              min: 5,
+              max: 500,
+              message: '长度在 5 到 500 个字符',
+              trigger: 'blur'
+            }]
+          },
+          // 状态列
+          {
+            label: '状态',
+            prop: 'status',
+            width: 100,
+            search: true,
+            type: 'select',
+            dicData: SURVEY_STATUS_OPTIONS,
+            slot: true,
+            rules: [{
+              required: true,
+              message: '请选择状态',
+              trigger: 'change'
+            }]
+          },
+          // 是否模板列
+          {
+            label: '是否模板',
+            prop: 'isTemplate',
+            width: 100,
+            search: true,
+            type: 'select',
+            dicData: SURVEY_TEMPLATE_OPTIONS,
+            slot: true
+          },
+          // 开始时间列
+          {
+            label: '开始时间',
+            prop: 'startTime',
+            width: 160,
+            type: 'datetime',
+            format: 'yyyy-MM-dd HH:mm:ss',
+            valueFormat: 'yyyy-MM-dd HH:mm:ss',
+            searchRange: true,
+            search: true,
+            rules: [{
+              required: true,
+              message: '请选择开始时间',
+              trigger: 'change'
+            }]
+          },
+          // 结束时间列
+          {
+            label: '结束时间',
+            prop: 'endTime',
+            width: 160,
+            type: 'datetime',
+            format: 'yyyy-MM-dd HH:mm:ss',
+            valueFormat: 'yyyy-MM-dd HH:mm:ss',
+            searchRange: true,
+            search: true,
+            rules: [{
+              required: true,
+              message: '请选择结束时间',
+              trigger: 'change'
+            }]
+          },
+          // 创建时间列
+          {
+            label: '创建时间',
+            prop: 'createTime',
+            width: 160,
+            type: 'datetime',
+            format: 'yyyy-MM-dd HH:mm:ss',
+            valueFormat: 'yyyy-MM-dd HH:mm:ss',
+            addDisplay: false,
+            editDisplay: false,
+            search: false
+          }
+        ]
+      },
+
+      // 数据和分页
+      data: [],
+      page: {
+        currentPage: 1,
+        pageSize: 20,
+        total: 0
+      },
+
+      // 查询和表单
+      query: {},
+      form: {},
+      loading: true,
+
+      // 题目编辑相关
+      questionEditorVisible: false,
+      currentSurveyId: null,
+
+      // 权限配置
+      permissionList: {
+        addBtn: true,
+        viewBtn: true,
+        editBtn: true,
+        delBtn: false
+      }
+    }
+  },
+
+
+  mounted() {
+    this.onLoad(this.page)
+  },
+
+  methods: {
+    // 导入工具函数
+    getSurveyStatusLabel,
+    getSurveyStatusType,
+    getSurveyTemplateLabel,
+    getSurveyTemplateType,
+
+    // avue-crud标准方法
+    async onLoad(page, params = {}) {
+      this.loading = true
+      try {
+        // 处理时间范围查询
+        const queryParams = { ...params }
+        if (queryParams.startTime && Array.isArray(queryParams.startTime)) {
+          queryParams.startTimeStart = queryParams.startTime[0]
+          queryParams.startTimeEnd = queryParams.startTime[1]
+          delete queryParams.startTime
+        }
+        if (queryParams.endTime && Array.isArray(queryParams.endTime)) {
+          queryParams.endTimeStart = queryParams.endTime[0]
+          queryParams.endTimeEnd = queryParams.endTime[1]
+          delete queryParams.endTime
+        }
+
+        const response = await getList(
+          page.currentPage,
+          page.pageSize,
+          queryParams
+        )
+
+        if (response.data && response.data.success) {
+          const { records, total } = response.data.data
+          this.data = records || []
+          this.page.total = total || 0
+        } else {
+          this.$message.error(response.data?.msg || '获取数据失败')
+        }
+      } catch (error) {
+        console.error('加载数据失败:', error)
+        this.$message.error('加载数据失败,请稍后重试')
+      } finally {
+        this.loading = false
+      }
+    },
+
+    searchChange(params, done) {
+      this.query = params
+      this.onLoad(this.page, params)
+      done()
+    },
+
+    searchReset(done) {
+      this.query = {}
+      this.onLoad(this.page)
+      done()
+    },
+
+
+    currentChange(currentPage) {
+      this.page.currentPage = currentPage
+    },
+
+    sizeChange(pageSize) {
+      this.page.pageSize = pageSize
+    },
+
+    refreshChange() {
+      this.onLoad(this.page, this.query)
+    },
+
+    // CRUD操作
+    async beforeOpen(done, type) {
+      if (['edit', 'view'].includes(type)) {
+        try {
+          const response = await getDetail(this.form.id)
+          if (response.data && response.data.success) {
+            this.form = response.data.data
+          } else {
+            this.$message.error('获取详情失败')
+            return
+          }
+        } catch (error) {
+          console.error('获取详情失败:', error)
+          this.$message.error('获取详情失败')
+          return
+        }
+      }
+      done()
+    },
+
+    async rowSave(row, done, loading) {
+      try {
+        // 时间验证
+        if (new Date(row.startTime) >= new Date(row.endTime)) {
+          this.$message.error('开始时间必须小于结束时间')
+          loading()
+          return
+        }
+
+        const response = await add(row)
+        if (response.data && response.data.success) {
+          this.$message.success('新增问卷成功')
+          this.onLoad(this.page)
+          done()
+        } else {
+          this.$message.error(response.data?.msg || '新增失败')
+          loading()
+        }
+      } catch (error) {
+        console.error('新增失败:', error)
+        this.$message.error('新增失败,请稍后重试')
+        loading()
+      }
+    },
+
+    async rowUpdate(row, index, done, loading) {
+      try {
+        // 时间验证
+        if (new Date(row.startTime) >= new Date(row.endTime)) {
+          this.$message.error('开始时间必须小于结束时间')
+          loading()
+          return
+        }
+
+        const response = await update(row)
+        if (response.data && response.data.success) {
+          this.$message.success('更新问卷成功')
+          this.onLoad(this.page)
+          done()
+        } else {
+          this.$message.error(response.data?.msg || '更新失败')
+          loading()
+        }
+      } catch (error) {
+        console.error('更新失败:', error)
+        this.$message.error('更新失败,请稍后重试')
+        loading()
+      }
+    },
+
+    // 题目编辑功能
+    handleEditQuestions(row) {
+      this.currentSurveyId = row.id
+      this.questionEditorVisible = true
+
+      this.$nextTick(() => {
+        if (this.$refs.questionEditor) {
+          this.$refs.questionEditor.loadQuestionList()
+        }
+      })
+    },
+
+    handleCloseQuestionEditor() {
+      this.questionEditorVisible = false
+      this.currentSurveyId = null
+
+      this.$nextTick(() => {
+        if (this.$refs.questionEditor) {
+          this.$refs.questionEditor = null
+        }
+      })
+    }
+
+  }
+}

+ 1 - 1
src/router/page/index.js

@@ -74,7 +74,7 @@ export default [{
     }]
 
   },
-  {
+    {
     path: '*',
     redirect: '/404'
   }

+ 3 - 3
src/router/views/index.js

@@ -148,7 +148,7 @@ export default [
             {
                 path: "index",
                 name: "调查问卷管理",
-                component: () => import("@/views/survey/index"),
+                component: () => import("@/views/survey/index-avue"),
                 meta: {
                     keepAlive: true,
                     isAuth: true,
@@ -218,12 +218,12 @@ export default [
         children: [
             {
                 path: "index",
-                name: "理赔查询",
+                name: "理赔管理",
                 component: () => import("@/views/claim/index"),
                 meta: {
                     keepAlive: true,
                     isAuth: true,
-                    title: "理赔查询",
+                    title: "理赔管理",
                     icon: "el-icon-warning"
                 }
             }

+ 5 - 1
src/util/util.js

@@ -368,10 +368,14 @@ export const downloadFileBase64 = (path, name) => {
 
 /**
  * 格式化文件大小
- * @param {number} bytes - 文件大小(字节)
+ * @param {number|null|undefined} bytes - 文件大小(字节)
  * @returns {string} 格式化后的文件大小
  */
 export const formatFileSize = (bytes) => {
+  // 处理null、undefined、非数字值
+  if (bytes === null || bytes === undefined || isNaN(bytes) || bytes < 0) {
+    return '-/-'
+  }
   if (bytes === 0) return '0 B'
   const k = 1024
   const sizes = ['B', 'KB', 'MB', 'GB', 'TB']

+ 4 - 0
src/views/announcement/index.scss

@@ -122,6 +122,10 @@
 }
 
 // 响应式设计
+::v-deep .el-col-md-8 { 
+  width: 24.33333%;
+}
+
 @media (max-width: 768px) {
   .detail-content {
     .detail-info {

+ 6 - 3
src/views/announcement/mixins/announcementIndex.js

@@ -172,10 +172,14 @@ export default {
                 height: 'auto',
                 calcHeight: 30,
                 dialogWidth: 1000,
+                menuWidth: 120,
                 labelWidth: 120,
                 tip: false,
                 searchShow: true,
-                searchMenuSpan: 6,
+                searchMenuSpan: 8,
+                searchIndex: 3,
+                searchIcon: true,
+                align: 'center',
                 border: true,
                 index: true,
                 viewBtn: false,
@@ -188,7 +192,6 @@ export default {
                     {
                         label: "公告标题",
                         prop: "title",
-                        span: 12,
                         search: true,
                         overHidden: true,
                         rules: [{
@@ -208,7 +211,6 @@ export default {
                         },
                         slot: true,
                         search: true,
-                        span: 12,
                         searchProp: "categoryId",
                         rules: [{
                             required: true,
@@ -276,6 +278,7 @@ export default {
                         type: "select",
                         dicData: STATUS_OPTIONS,
                         slot: true,
+                        search: true,
                         addDisplay: true,
                         editDisplay: true,
                         // width: 80

+ 33 - 2
src/views/claim/claimMixin.js

@@ -180,7 +180,8 @@ export default {
         calcHeight: 30,
         tip: false,
         searchShow: true,
-        searchMenuSpan: 6,
+        searchMenuSpan: 12,
+        searchIndex: 3,
         border: true,
         index: true,
         indexLabel: '序号',
@@ -253,6 +254,16 @@ export default {
             prop: 'runMileage'
           },
           {
+            label: '车牌号',
+            prop: 'vehicleNumber',
+            search: true
+          },
+          {
+            label: '轮胎数量',
+            prop: 'tireQuantity',
+            type: 'number'
+          },
+          {
             label: '理赔原因',
             prop: 'claimReason'
           },
@@ -275,6 +286,17 @@ export default {
             type: 'datetime',
             format: 'yyyy-MM-dd HH:mm:ss',
             valueFormat: 'yyyy-MM-dd HH:mm:ss'
+          },
+          {
+            label: '提交状态',
+            prop: 'isSubmitTime',
+            type: 'select',
+            dicData: [
+              { label: '未提交', value: 0 },
+              { label: '已提交', value: 1 }
+            ],
+            search: true,
+            slot: true
           }
         ]
       },
@@ -283,7 +305,16 @@ export default {
     }
   },
   computed: {
-    ...mapGetters(['permission'])
+    ...mapGetters(['permission']),
+    
+    /**
+     * 是否可以新增审核记录
+     * 根据isSubmitTime字段判断:0-不可新增,1-可新增
+     * @returns {boolean} 是否可以新增审核记录
+     */
+    canAddAudit() {
+      return this.currentClaimRow?.isSubmitTime === 1
+    }
   },
   methods: {
     /**

+ 31 - 1
src/views/claim/index.vue

@@ -46,6 +46,11 @@
           {{ getAuditStatusLabel(row.auditStatus) }}
         </el-tag>
       </template>
+      <template slot-scope="{row}" slot="isSubmitTime">
+        <el-tag :type="row.isSubmitTime === 1 ? 'success' : 'warning'">
+          {{ row.isSubmitTime === 1 ? '已提交' : '未提交' }}
+        </el-tag>
+      </template>
     </avue-crud>
 
     <!-- 理赔详情对话框 -->
@@ -163,6 +168,18 @@
                 <span>{{ formatYmd(claimDetail.mountDate) }}</span>
               </div>
             </el-col>
+            <el-col :span="8">
+              <div class="detail-item">
+                <label>车牌号:</label>
+                <span>{{ claimDetail.vehicleNumber || '-' }}</span>
+              </div>
+            </el-col>
+            <el-col :span="8">
+              <div class="detail-item">
+                <label>轮胎数量:</label>
+                <span>{{ claimDetail.tireQuantity || '-' }}</span>
+              </div>
+            </el-col>
           </el-row>
         </el-card>
 
@@ -307,7 +324,17 @@
                width="1000px"
                append-to-body>
       <div style="margin-bottom: 16px;">
-        <el-button type="primary" size="small" @click="handleAddAudit">新增审核</el-button>
+        <el-button 
+          type="primary" 
+          size="small" 
+          @click="handleAddAudit"
+          :disabled="!canAddAudit"
+          :title="canAddAudit ? '新增审核记录' : '该理赔记录未提交,无法新增审核记录'">
+          新增审核
+        </el-button>
+        <span v-if="!canAddAudit" style="margin-left: 8px; color: #999; font-size: 12px;">
+          该理赔记录未提交,无法新增审核记录
+        </span>
       </div>
       <el-table :data="auditList" v-loading="auditLoading">
         <el-table-column prop="auditResult" label="审核结果" width="100">
@@ -662,4 +689,7 @@ export default {
   }
 }
 
+::v-deep .el-col-md-8 { 
+  width: 24.33333%;
+}
 </style>

+ 2 - 1
src/views/complaint/complaintMixin.js

@@ -177,7 +177,8 @@ export default {
         calcHeight: 30,
         tip: false,
         searchShow: true,
-        searchMenuSpan: 6,
+        searchMenuSpan: 18,
+        searchIndex: 3,
         border: true,
         index: true,
         viewBtn: true,

+ 3 - 0
src/views/complaint/index.vue

@@ -450,4 +450,7 @@ export default {
     }
   }
 }
+::v-deep .el-col-md-8 { 
+  width: 24.33333%;
+}
 </style>

+ 2 - 1
src/views/forecast-audit/auditIndex.js

@@ -63,7 +63,8 @@ export default {
         height: 'auto',
         calcHeight: 30,
         searchShow: true,
-        searchMenuSpan: 6,
+        searchMenuSpan: 18,
+        searchIndex: 3,
         border: true,
         index: false,
         viewBtn: false,

+ 2 - 1
src/views/forecast-summary/summaryIndex.js

@@ -80,7 +80,8 @@ import { safeBigInt } from '@/util/util'
          calcHeight: 30,
          tip: false,
          searchShow: true,
-         searchMenuSpan: 6,
+         searchMenuSpan: 12,
+         searchIndex: 3,
          border: true,
          index: true,
          viewBtn: false,

+ 1 - 0
src/views/image-store-apply/mixins/imageStoreApplyIndex.js

@@ -92,6 +92,7 @@ export default {
         tip: false,
         searchShow: true,
         searchMenuSpan: 6,
+        searchIndex: 3,
         border: true,
         index: true,
         viewBtn: false,

+ 58 - 17
src/views/lead/mixins/leadIndex.js

@@ -1,6 +1,6 @@
 // @ts-check
 import { getList, add, update, getDetail } from '@/api/order/lead'
-import { getList as getDetailList, add as addDetail, update as updateDetail, remove as removeDetail, getDetail as getDetailDetail } from '@/api/order/lead-detail'
+import { getList as getDetailList, add as addDetail, update as updateDetail, deleteById, getDetail as getDetailDetail } from '@/api/order/lead-detail'
 import { getCustomerList } from '@/api/common/index'
 import { mapGetters } from 'vuex'
 import {
@@ -304,6 +304,7 @@ export default {
                 tip: false,
                 searchShow: true,
                 searchMenuSpan: 6,
+                searchIndex: 3,
                 border: true,
                 index: true,
                 viewBtn: true,
@@ -1128,7 +1129,7 @@ export default {
         },
         
         /**
-         * 详细信息删除
+         * 详细信息删除 (单条删除)
          * @param {LeadDetailRecord} row - 行数据
          * @param {number} index - 行索引
          * @returns {Promise<void>}
@@ -1136,16 +1137,25 @@ export default {
          */
         async detailRowDel(row, index) {
             try {
-                const res = await removeDetail(row.id)
-                if (res.data && res.data.success) {
-                    this.$message.success('删除成功')
+                await this.$confirm(`确定删除这条详细信息吗?`, '提示', {
+                    confirmButtonText: '确定',
+                    cancelButtonText: '取消',
+                    type: 'warning'
+                })
+                
+                // 使用deleteById方法进行单条删除
+                const res = await deleteById(row.id)
+                if (res.data && res.data.code === 200 && res.data.success) {
+                    this.$message.success(res.data.msg || '删除成功')
                     this.detailOnLoad(this.detailPage)
                 } else {
                     this.$message.error(res.data ? res.data.msg : '删除失败')
                 }
             } catch (error) {
-                console.error('删除失败:', error)
-                this.$message.error('删除失败,请稍后重试')
+                if (error !== 'cancel') {
+                    console.error('删除失败:', error)
+                    this.$message.error('删除失败,请稍后重试')
+                }
             }
         },
         
@@ -1198,26 +1208,57 @@ export default {
                 this.$message.warning('请选择要删除的数据')
                 return
             }
-        
+
             try {
-                await this.$confirm('确定删除选中的详细信息吗?', '提示', {
+                await this.$confirm(`确定删除选中的 ${this.detailSelectionList.length} 条详细信息吗?`, '提示', {
                     confirmButtonText: '确定',
                     cancelButtonText: '取消',
                     type: 'warning'
                 })
-        
-                const res = await removeDetail(this.detailIds)
-                if (res.data && res.data.success) {
-                    this.$message.success('删除成功')
+
+                // 显示删除进度提示
+                const loadingMessage = this.$message({
+                    message: `正在删除 ${this.detailSelectionList.length} 条记录...`,
+                    type: 'info',
+                    duration: 0
+                })
+
+                try {
+                    // 并发调用deleteById进行批量删除
+                    const deletePromises = this.detailIds.map(id => deleteById(id))
+                    const results = await Promise.all(deletePromises)
+                    
+                    // 统计成功和失败的数量
+                    const successCount = results.filter(res => 
+                        res.data && res.data.code === 200 && res.data.success
+                    ).length
+                    const failedCount = this.detailIds.length - successCount
+
+                    // 关闭进度提示
+                    loadingMessage.close()
+
+                    // 根据结果显示不同的提示
+                    if (failedCount === 0) {
+                        this.$message.success(`成功删除 ${successCount} 条记录`)
+                    } else if (successCount === 0) {
+                        this.$message.error(`删除失败,共 ${failedCount} 条记录`)
+                    } else {
+                        this.$message.warning(`部分删除成功:成功 ${successCount} 条,失败 ${failedCount} 条`)
+                    }
+
+                    // 刷新数据并清空选择
                     this.detailOnLoad(this.detailPage)
                     this.$refs.detailCrud.toggleSelection()
-                } else {
-                    this.$message.error(res.data ? res.data.msg : '删除失败')
+
+                } catch (deleteError) {
+                    loadingMessage.close()
+                    throw deleteError
                 }
+
             } catch (error) {
                 if (error !== 'cancel') {
-                    console.error('删除失败:', error)
-                    this.$message.error('删除失败,请稍后重试')
+                    console.error('批量删除失败:', error)
+                    this.$message.error('批量删除失败,请稍后重试')
                 }
             }
         }

+ 2 - 1
src/views/marketing-activity/mixins/marketingActivityIndex.js

@@ -206,7 +206,8 @@ export default {
                 calcHeight: 30,
                 tip: false,
                 searchShow: true,
-                searchMenuSpan: 6,
+                searchMenuSpan: 18,
+                searchIndex: 3,
                 border: true,
                 index: true,
                 viewBtn: true,

+ 1 - 1
src/views/order/address/addressMixin.js

@@ -300,7 +300,7 @@ export default {
         const selectedCustomer = this.customerOptions.find(option => option.value === value)
         if (selectedCustomer) {
           // 自动填充客户信息
-          this.form.customerId = Number(selectedCustomer.customerId)
+          this.form.customerId = selectedCustomer.customerId
           this.form.customerCode = selectedCustomer.customerCode
           this.form.customerName = selectedCustomer.customerName
         } else {

+ 16 - 15
src/views/order/order/index-avue.vue

@@ -120,7 +120,10 @@
             <span class="order-code">订单编码:{{ row.orderCode }}</span>
           </div>
           <div class="expand-body">
-            <order-item-table :order-id="row.id" />
+            <order-item-table-optimized
+              :order-id="row.id"
+              :order-item-data="row.pcBladeOrderItemList"
+            />
           </div>
         </div>
       </template>
@@ -146,7 +149,7 @@ import {
   getOrderStatusLabel,
   getOrderStatusTagType
 } from '@/constants'
-import OrderItemTable from '@/components/order-item-table/index.vue'
+import OrderItemTableOptimized from '@/components/order-item-table-optimized/index.vue'
 import OrderForm from '@/components/order-form/order-form.vue'
 import { ORDER_FORM_EVENTS } from '@/components/order-form/events'
 import { mapGetters } from 'vuex'
@@ -154,7 +157,7 @@ import { mapGetters } from 'vuex'
 export default {
   name: 'OrderAvue',
   components: {
-    OrderItemTable,
+    OrderItemTableOptimized,
     OrderForm
   },
   data() {
@@ -218,21 +221,19 @@ export default {
       }
       Object.keys(query).forEach(k => query[k] === undefined && delete query[k])
 
-      getOrderList(page.currentPage, page.pageSize, query).then(async res => {
+      getOrderList(page.currentPage, page.pageSize, query).then(res => {
         const data = res.data.data
         const records = Array.isArray(data.records) ? data.records : []
-        // 与工厂列表一致:并行查询每条订单的明细总数,使用分页响应的 total
-        const counts = await Promise.all(records.map(async (row) => {
-          try {
-            const resp = await getOrderItemList(1, 1, { orderId: row.id })
-            const payload = resp && resp.data && resp.data.data ? resp.data.data : { total: 0 }
-            return Number(payload.total || 0)
-          } catch (e) {
-            return 0
-          }
+
+        // 优化:直接使用接口返回的明细数据,无需额外查询
+        this.data = records.map(row => ({
+          ...row,
+          // 如果接口返回了pcBladeOrderItemList,计算明细条数;否则使用原有逻辑作为降级
+          detailCount: Array.isArray(row.pcBladeOrderItemList)
+            ? row.pcBladeOrderItemList.length
+            : (row.detailCount || 0)
         }))
-        // 将计算得到的明细条数合并到每条记录的 detailCount 字段
-        this.data = records.map((row, idx) => ({ ...row, detailCount: counts[idx] }))
+
         this.page.total = data.total
         this.loading = false
       }).catch(() => {

+ 330 - 0
src/views/survey/index-avue.scss

@@ -0,0 +1,330 @@
+// Survey模块avue-crud样式定制
+.survey-management-avue {
+  // 搜索区域样式
+  .avue-crud__search {
+    background: #fff;
+    padding: 20px;
+    border-radius: 4px;
+    margin-bottom: 16px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+
+    .avue-form {
+      .el-form-item {
+        margin-bottom: 18px;
+
+        .el-form-item__label {
+          font-weight: 500;
+          color: #303133;
+        }
+
+        .el-input,
+        .el-select,
+        .el-date-editor {
+          width: 100%;
+        }
+      }
+    }
+  }
+
+  // 表格区域样式
+  .avue-crud__menu {
+    margin-bottom: 16px;
+    padding: 16px 20px;
+    background: #fff;
+    border-radius: 4px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+
+    .el-button {
+      margin-right: 8px;
+
+      &:last-child {
+        margin-right: 0;
+      }
+    }
+  }
+
+  // 表格样式
+  .avue-crud {
+    background: #fff;
+    border-radius: 4px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+
+    .el-table {
+      .el-table__header {
+        background-color: #f5f7fa;
+
+        th {
+          background-color: #f5f7fa;
+          color: #606266;
+          font-weight: 600;
+        }
+      }
+
+      .el-table__row {
+        &:hover {
+          background-color: #f5f7fa;
+        }
+      }
+    }
+
+    // 状态标签样式
+    .el-tag {
+      font-weight: 500;
+      border-radius: 4px;
+
+      &.el-tag--success {
+        background-color: #f0f9ff;
+        border-color: #67c23a;
+        color: #67c23a;
+      }
+
+      &.el-tag--warning {
+        background-color: #fdf6ec;
+        border-color: #e6a23c;
+        color: #e6a23c;
+      }
+
+      &.el-tag--info {
+        background-color: #f4f4f5;
+        border-color: #909399;
+        color: #909399;
+      }
+    }
+
+    // 操作按钮样式
+    .el-button--text {
+      padding: 2px 8px;
+      font-size: 12px;
+
+      &:hover {
+        background-color: #f0f9ff;
+        color: #409eff;
+      }
+    }
+  }
+
+  // 分页样式
+  .avue-crud__pagination {
+    padding: 20px 0;
+    text-align: right;
+    background: #fff;
+    border-radius: 4px;
+    margin-top: 16px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+
+    .el-pagination {
+      .el-pagination__total,
+      .el-pagination__sizes,
+      .el-pagination__jump {
+        color: #606266;
+      }
+    }
+  }
+}
+
+// 题目编辑弹窗样式
+.question-editor-dialog {
+  .el-dialog__header {
+    background-color: #f5f7fa;
+    padding: 16px 20px;
+    border-bottom: 1px solid #e4e7ed;
+
+    .el-dialog__title {
+      font-size: 16px;
+      font-weight: 600;
+      color: #303133;
+    }
+  }
+
+  .el-dialog__body {
+    padding: 10px 20px;
+    max-height: 70vh;
+    overflow-y: auto;
+
+    &::-webkit-scrollbar {
+      width: 6px;
+    }
+
+    &::-webkit-scrollbar-thumb {
+      background-color: #c0c4cc;
+      border-radius: 3px;
+    }
+
+    &::-webkit-scrollbar-track {
+      background-color: #f5f7fa;
+      border-radius: 3px;
+    }
+  }
+
+  .el-dialog__footer {
+    padding: 16px 20px;
+    background-color: #f5f7fa;
+    border-top: 1px solid #e4e7ed;
+    text-align: center;
+
+    .el-button {
+      margin: 0 8px;
+      min-width: 80px;
+    }
+  }
+}
+
+// 响应式设计
+@media (max-width: 1200px) {
+  .survey-management-avue {
+    .avue-crud__search {
+      padding: 15px;
+    }
+
+    .avue-crud__menu {
+      padding: 12px 15px;
+
+      .el-button {
+        margin-bottom: 8px;
+        font-size: 12px;
+      }
+    }
+  }
+}
+
+@media (max-width: 768px) {
+  .survey-management-avue {
+    .avue-crud__search {
+      padding: 10px;
+
+      .avue-form {
+        .el-form-item {
+          margin-bottom: 12px;
+        }
+      }
+    }
+
+    .avue-crud__menu {
+      padding: 10px;
+
+      .el-button {
+        width: 100%;
+        margin-bottom: 8px;
+        margin-right: 0;
+      }
+    }
+
+    .avue-crud {
+      .el-table {
+        font-size: 12px;
+
+        .el-table__header th {
+          padding: 8px 4px;
+        }
+
+        .el-table__row td {
+          padding: 8px 4px;
+        }
+      }
+
+      .el-button--text {
+        padding: 4px 6px;
+        font-size: 11px;
+      }
+    }
+
+    .avue-crud__pagination {
+      padding: 15px 0;
+      text-align: center;
+
+      .el-pagination {
+        justify-content: center;
+
+        .el-pagination__sizes,
+        .el-pagination__jump {
+          display: none;
+        }
+      }
+    }
+  }
+
+  .question-editor-dialog {
+    width: 95% !important;
+    margin-top: 5vh !important;
+
+    .el-dialog__body {
+      padding: 8px 15px;
+    }
+  }
+}
+
+@media (max-width: 480px) {
+  .survey-management-avue {
+    .avue-crud__search {
+      .avue-form {
+        .el-form-item {
+          .el-form-item__content {
+            .el-input,
+            .el-select,
+            .el-date-editor {
+              font-size: 14px;
+            }
+          }
+        }
+      }
+    }
+
+    .avue-crud {
+      .el-table {
+        .el-table__header th,
+        .el-table__row td {
+          padding: 6px 2px;
+          font-size: 11px;
+        }
+
+        .cell {
+          padding: 0 2px;
+        }
+      }
+    }
+  }
+}
+
+// 动画效果
+.fade-enter-active,
+.fade-leave-active {
+  transition: opacity 0.3s ease;
+}
+
+.fade-enter,
+.fade-leave-to {
+  opacity: 0;
+}
+
+.slide-fade-enter-active {
+  transition: all 0.3s ease;
+}
+
+.slide-fade-leave-active {
+  transition: all 0.2s cubic-bezier(1, 0.5, 0.8, 1);
+}
+
+.slide-fade-enter,
+.slide-fade-leave-to {
+  transform: translateX(10px);
+  opacity: 0;
+}
+
+// 加载状态样式
+.avue-crud {
+  .el-loading-mask {
+    background-color: rgba(255, 255, 255, 0.8);
+
+    .el-loading-spinner {
+      .path {
+        stroke: #409eff;
+      }
+    }
+  }
+}
+
+// 工具提示样式
+.el-tooltip__popper {
+  max-width: 300px;
+  line-height: 1.5;
+}

+ 158 - 0
src/views/survey/index-avue.vue

@@ -0,0 +1,158 @@
+<template>
+  <basic-container>
+    <!-- avue-crud表格组件 -->
+    <avue-crud
+      :option="option"
+      :data="data"
+      ref="crud"
+      v-model="form"
+      :page.sync="page"
+      :permission="permissionList"
+      :before-open="beforeOpen"
+      @row-save="rowSave"
+      @row-update="rowUpdate"
+      @row-del="rowDel"
+      @search-change="searchChange"
+      @search-reset="searchReset"
+      @selection-change="selectionChange"
+      @current-change="currentChange"
+      @size-change="sizeChange"
+      @refresh-change="refreshChange"
+    >
+      <!-- 状态插槽 -->
+      <template slot="status" slot-scope="{row}">
+        <el-tag :type="getSurveyStatusType(row.status)">
+          {{ getSurveyStatusLabel(row.status) }}
+        </el-tag>
+      </template>
+
+      <!-- 是否模板插槽 -->
+      <template slot="isTemplate" slot-scope="{row}">
+        <el-tag :type="getSurveyTemplateType(row.isTemplate)">
+          {{ getSurveyTemplateLabel(row.isTemplate) }}
+        </el-tag>
+      </template>
+
+      <!-- 菜单插槽 -->
+      <template slot="menu" slot-scope="{row}">
+        <el-button
+          type="text"
+          size="small"
+          icon="el-icon-setting"
+          @click="handleEditQuestions(row)"
+        >
+          题目编辑
+        </el-button>
+      </template>
+
+          </avue-crud>
+
+    <!-- 题目编辑弹窗 -->
+    <el-dialog
+      title="题目编辑"
+      :visible.sync="questionEditorVisible"
+      width="90%"
+      append-to-body
+      :close-on-click-modal="false"
+      custom-class="question-editor-dialog"
+      @close="handleCloseQuestionEditor"
+    >
+      <survey-question-editor
+        v-if="questionEditorVisible"
+        :survey-id="currentSurveyId"
+        ref="questionEditor"
+      />
+
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="handleCloseQuestionEditor">关闭</el-button>
+      </div>
+    </el-dialog>
+  </basic-container>
+</template>
+
+<script>
+import surveyCrudMixin from '@/mixins/survey/surveyCrudMixin'
+import SurveyQuestionEditor from '@/components/survey-question-editor'
+
+export default {
+  name: 'SurveyManagementAvue',
+
+  components: {
+    SurveyQuestionEditor
+  },
+
+  mixins: [surveyCrudMixin]
+}
+</script>
+
+<style lang="scss" scoped>
+.survey-management-avue {
+  // 题目编辑弹窗样式
+  ::v-deep .question-editor-dialog {
+    .el-dialog__body {
+      padding: 10px 20px;
+      max-height: 70vh;
+      overflow-y: auto;
+    }
+
+    .el-dialog__footer {
+      padding: 10px 20px 20px;
+      text-align: center;
+    }
+  }
+
+  // avue-crud样式优化
+  ::v-deep .avue-crud {
+    .avue-crud__search {
+      .avue-form {
+        .el-form-item {
+          margin-bottom: 18px;
+        }
+      }
+    }
+
+    .avue-crud__menu {
+      .el-button {
+        margin-right: 8px;
+      }
+    }
+
+    .el-tag {
+      &--success {
+        background-color: #f0f9ff;
+        border-color: #67c23a;
+        color: #67c23a;
+      }
+
+      &--warning {
+        background-color: #fdf6ec;
+        border-color: #e6a23c;
+        color: #e6a23c;
+      }
+
+      &--info {
+        background-color: #f4f4f5;
+        border-color: #909399;
+        color: #909399;
+      }
+    }
+  }
+}
+
+// 响应式设计
+@media (max-width: 768px) {
+  .survey-management-avue {
+    ::v-deep .avue-crud {
+      .avue-crud__search {
+        padding: 15px;
+      }
+
+      .avue-crud__menu {
+        .el-button {
+          margin-bottom: 8px;
+        }
+      }
+    }
+  }
+}
+</style>