spring
23 小时以前 9cfe25c453366d1203fc34fae59cabe396ec4abc
Merge branch 'dev_new' of http://114.132.189.42:9002/r/product-inventory-APP-before into dev_new
已添加17个文件
已修改14个文件
2362 ■■■■■ 文件已修改
src/api/basicData/customerFile.js 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/equipmentManagement/repair.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/salesManagement/salesQuotation.js 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages.json 72 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/basicData/customerFile/detail.vue 205 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/basicData/customerFile/edit.vue 342 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/basicData/customerFile/index.vue 183 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/cooperativeOffice/customerManage/detail.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/equipmentManagement/repair/maintain.vue 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/equipmentManagement/upkeep/maintain.vue 94 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/login.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/qualityManagement/finalInspection/add.vue 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/qualityManagement/finalInspection/detail.vue 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/qualityManagement/materialInspection/add.vue 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/qualityManagement/materialInspection/detail.vue 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/qualityManagement/processInspection/add.vue 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/qualityManagement/processInspection/detail.vue 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/sales/salesQuotation/detail.vue 235 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/sales/salesQuotation/edit.vue 613 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/sales/salesQuotation/index.vue 226 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/works.vue 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/static/images/icon/fahuotaizhang.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/static/images/icon/fankuidengji.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/static/images/icon/gongyingshangdangan.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/static/images/icon/jiekuanguanli.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/static/images/icon/kehudangan.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/static/images/icon/shouhouchuli.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/static/images/icon/shouruguanli.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/static/images/icon/xiaoshoubaojia.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/static/images/icon/xiaoshoutuihuo.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/static/images/icon/zhichuguanli.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/basicData/customerFile.js
@@ -50,3 +50,44 @@
    })
}
// æ–°å¢žå®¢æˆ·è·Ÿè¿›
export function addCustomerFollow(data) {
    return request({
        url: '/basic/customer-follow/add',
        method: 'post',
        data: data
    })
}
// ä¿®æ”¹å®¢æˆ·è·Ÿè¿›
export function updateCustomerFollow(data) {
    return request({
        url: '/basic/customer-follow/edit',
        method: 'put',
        data: data,
    })
}
// åˆ é™¤å®¢æˆ·è·Ÿè¿›
export function delCustomerFollow(id) {
    return request({
        url: '/basic/customer-follow/'+id,
        method: 'delete',
    })
}
// å›žè®¿æé†’-新增/更新
export function addReturnVisit(data) {
    return request({
        url: '/basic/customer-follow/return-visit',
        method: 'post',
        data: data
    })
}
// èŽ·å–å›žè®¿æé†’è¯¦æƒ…
export function getReturnVisit(id) {
    return request({
        url: '/basic/customer-follow/return-visit/' + id,
        method: 'get'
    })
}
src/api/equipmentManagement/repair.js
@@ -70,3 +70,10 @@
    data,
  });
};
export const getSparePartsList = (params) => {
  return request({
    url: "/spareParts/listPage",
    method: "get",
    params,
  });
};
src/api/salesManagement/salesQuotation.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,112 @@
// é”€å”®æŠ¥ä»·é¡µé¢æŽ¥å£
import request from "@/utils/request";
// åˆ†é¡µæŸ¥è¯¢æŠ¥ä»·å•列表
export function getQuotationList(query) {
  return request({
    url: "/sales/quotation/list",
    method: "get",
    params: query,
  });
}
// æŸ¥è¯¢æŠ¥ä»·å•详情
export function getQuotationDetail(query) {
  return request({
    url: "/sales/quotation/detail",
    method: "get",
    params: query,
  });
}
// æ–°å¢žæŠ¥ä»·å•
export function addQuotation(data) {
  return request({
    url: "/sales/quotation/add",
    method: "post",
    data: data,
  });
}
// ä¿®æ”¹æŠ¥ä»·å•
export function updateQuotation(data) {
  return request({
    url: "/sales/quotation/update",
    method: "post",
    data: data,
  });
}
// åˆ é™¤æŠ¥ä»·å•
export function deleteQuotation(query) {
  return request({
    url: "/sales/quotation/delete",
    method: "delete",
    data: query,
  });
}
// å‘送报价单
export function sendQuotation(data) {
  return request({
    url: "/sales/quotation/send",
    method: "post",
    data: data,
  });
}
// æŠ¥ä»·å•转订单
export function convertToOrder(data) {
  return request({
    url: "/sales/quotation/convertToOrder",
    method: "post",
    data: data,
  });
}
// æŸ¥è¯¢å®¢æˆ·åˆ—表
export function getCustomerList(query) {
  return request({
    url: "/basic/customer/list",
    method: "get",
    params: query,
  });
}
// æŸ¥è¯¢äº§å“åˆ—表
export function getProductList(query) {
  return request({
    url: "/basic/product/list",
    method: "get",
    params: query,
  });
}
// æŸ¥è¯¢ä¸šåŠ¡å‘˜åˆ—è¡¨
export function getSalespersonList(query) {
  return request({
    url: "/system/user/salespersonList",
    method: "get",
    params: query,
  });
}
// å¯¼å‡ºæŠ¥ä»·å•
export function exportQuotation(query) {
  return request({
    url: "/sales/quotation/export",
    method: "get",
    params: query,
    responseType: "blob",
  });
}
// æ‰“印报价单
export function printQuotation(query) {
  return request({
    url: "/sales/quotation/print",
    method: "get",
    params: query,
    responseType: "blob",
  });
}
src/pages.json
@@ -40,19 +40,19 @@
      }
    },
    {
      "path": "pages/works",
      "path": "pages/index",
      "style": {
        "navigationBarTitleText": "首页",
        "navigationStyle": "custom"
      }
    },
//    {
//      "path": "pages/works",
//      "style": {
//        "navigationBarTitleText": "工作台",
//        "navigationStyle": "custom"
//      }
//    },
    {
      "path": "pages/works",
      "style": {
        "navigationBarTitleText": "工作台",
        "navigationStyle": "custom"
      }
    },
    {
      "path": "pages/login",
      "style": {
@@ -73,9 +73,51 @@
      }
    },
    {
      "path": "pages/basicData/customerFile/index",
      "style": {
        "navigationBarTitleText": "客户档案",
        "navigationStyle": "custom"
      }
    },
    {
      "path": "pages/basicData/customerFile/edit",
      "style": {
        "navigationBarTitleText": "客户信息",
        "navigationStyle": "custom"
      }
    },
    {
      "path": "pages/basicData/customerFile/detail",
      "style": {
        "navigationBarTitleText": "客户详情",
        "navigationStyle": "custom"
      }
    },
    {
      "path": "pages/sales/salesAccount/index",
      "style": {
        "navigationBarTitleText": "销售台账",
        "navigationStyle": "custom"
      }
    },
    {
      "path": "pages/sales/salesQuotation/index",
      "style": {
        "navigationBarTitleText": "销售报价",
        "navigationStyle": "custom"
      }
    },
    {
      "path": "pages/sales/salesQuotation/edit",
      "style": {
        "navigationBarTitleText": "销售报价",
        "navigationStyle": "custom"
      }
    },
    {
      "path": "pages/sales/salesQuotation/detail",
      "style": {
        "navigationBarTitleText": "报价详情",
        "navigationStyle": "custom"
      }
    },
@@ -1307,17 +1349,17 @@
    "backgroundColor": "#ffffff",
    "list": [
      {
        "pagePath": "pages/works",
        "pagePath": "pages/index",
        "iconPath": "static/images/tabbar/home.png",
        "selectedIconPath": "static/images/tabbar/homeBlue.png",
        "text": "首页"
      },
//      {
//        "pagePath": "pages/works",
//        "iconPath": "static/images/tabbar/work.png",
//        "selectedIconPath": "static/images/tabbar/workBlue.png",
//        "text": "工作台"
//      },
      {
        "pagePath": "pages/works",
        "iconPath": "static/images/tabbar/work.png",
        "selectedIconPath": "static/images/tabbar/workBlue.png",
        "text": "工作台"
      },
      {
        "pagePath": "pages/message",
        "iconPath": "static/images/tabbar/new.png",
src/pages/basicData/customerFile/detail.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,205 @@
<template>
  <view class="customer-detail-page">
    <PageHeader title="客户详情" @back="goBack" />
    <view class="detail-content">
      <view class="section">
        <view class="section-title">客户信息</view>
        <view class="info-list">
          <view class="info-item">
            <text class="info-label">客户名称</text>
            <text class="info-value">{{ detailData.customerName || "-" }}</text>
          </view>
          <view class="info-item">
            <text class="info-label">客户分类</text>
            <text class="info-value">{{ detailData.customerType || "-" }}</text>
          </view>
          <view class="info-item">
            <text class="info-label">纳税人识别号</text>
            <text class="info-value">{{ detailData.taxpayerIdentificationNumber || "-" }}</text>
          </view>
          <view class="info-item">
            <text class="info-label">公司地址</text>
            <text class="info-value">{{ detailData.companyAddress || "-" }}</text>
          </view>
          <view class="info-item">
            <text class="info-label">公司电话</text>
            <text class="info-value">{{ detailData.companyPhone || "-" }}</text>
          </view>
          <view class="info-item">
            <text class="info-label">法人</text>
            <text class="info-value">{{ detailData.corporation || "-" }}</text>
          </view>
          <view class="info-item">
            <text class="info-label">代理人</text>
            <text class="info-value">{{ detailData.agent || "-" }}</text>
          </view>
          <view class="info-item">
            <text class="info-label">传真</text>
            <text class="info-value">{{ detailData.fax || "-" }}</text>
          </view>
        </view>
      </view>
      <view class="section">
        <view class="section-title">联系信息</view>
        <view class="info-list">
          <view class="info-item">
            <text class="info-label">联系人</text>
            <text class="info-value">{{ detailData.contactPerson || "-" }}</text>
          </view>
          <view class="info-item">
            <text class="info-label">联系电话</text>
            <text class="info-value">{{ detailData.contactPhone || "-" }}</text>
          </view>
        </view>
      </view>
      <view class="section">
        <view class="section-title">银行信息</view>
        <view class="info-list">
          <view class="info-item">
            <text class="info-label">银行基本户</text>
            <text class="info-value">{{ detailData.basicBankAccount || "-" }}</text>
          </view>
          <view class="info-item">
            <text class="info-label">银行账号</text>
            <text class="info-value">{{ detailData.bankAccount || "-" }}</text>
          </view>
          <view class="info-item">
            <text class="info-label">开户银行</text>
            <text class="info-value">{{ detailData.bankName || "-" }}</text>
          </view>
          <view class="info-item">
            <text class="info-label">开户行号</text>
            <text class="info-value">{{ detailData.bankCode || "-" }}</text>
          </view>
        </view>
      </view>
      <view class="section">
        <view class="section-title">维护信息</view>
        <view class="info-list">
          <view class="info-item">
            <text class="info-label">维护人</text>
            <text class="info-value">{{ detailData.maintainer || "-" }}</text>
          </view>
          <view class="info-item">
            <text class="info-label">维护时间</text>
            <text class="info-value">{{ detailData.maintenanceTime || "-" }}</text>
          </view>
        </view>
      </view>
    </view>
    <FooterButtons
      cancelText="返回"
      confirmText="编辑"
      @cancel="goBack"
      @confirm="goEdit"
    />
  </view>
</template>
<script setup>
  import { ref } from "vue";
  import { onLoad, onShow } from "@dcloudio/uni-app";
  import FooterButtons from "@/components/FooterButtons.vue";
  import { getCustomer } from "@/api/basicData/customerFile";
  const customerId = ref("");
  const detailData = ref({});
  const goBack = () => {
    uni.navigateBack();
  };
  const goEdit = () => {
    if (!customerId.value) return;
    uni.navigateTo({ url: `/pages/basicData/customerFile/edit?id=${customerId.value}` });
  };
  const getDetail = () => {
    if (!customerId.value) return;
    uni.showLoading({ title: "加载中...", mask: true });
    getCustomer(customerId.value)
      .then(res => {
        detailData.value = res.data || {};
      })
      .catch(() => {
        uni.showToast({ title: "获取详情失败", icon: "error" });
      })
      .finally(() => {
        uni.hideLoading();
      });
  };
  onLoad(options => {
    if (options?.id) {
      customerId.value = options.id;
      getDetail();
    }
  });
  onShow(() => {
    if (customerId.value) {
      getDetail();
    }
  });
</script>
<style scoped lang="scss">
  .customer-detail-page {
    min-height: 100vh;
    background-color: #f5f5f5;
    padding-bottom: 90px;
  }
  .detail-content {
    padding: 16px;
  }
  .section {
    background: #ffffff;
    border-radius: 12px;
    margin-bottom: 16px;
    overflow: hidden;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
  }
  .section-title {
    padding: 16px;
    font-size: 16px;
    font-weight: 600;
    color: #303133;
    border-bottom: 1px solid #f0f0f0;
  }
  .info-list {
    padding: 8px 0;
  }
  .info-item {
    display: flex;
    padding: 12px 16px;
    border-bottom: 1px solid #f8f8f8;
  }
  .info-item:last-child {
    border-bottom: none;
  }
  .info-label {
    width: 120px;
    font-size: 14px;
    color: #606266;
  }
  .info-value {
    flex: 1;
    font-size: 14px;
    color: #303133;
    text-align: right;
    word-break: break-all;
  }
</style>
src/pages/basicData/customerFile/edit.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,342 @@
<template>
  <view class="account-detail">
    <PageHeader :title="pageTitle" @back="goBack" />
    <view class="form-container">
      <up-form
        ref="formRef"
        :model="form"
        :rules="rules"
        label-width="110"
        input-align="right"
        error-message-align="right"
      >
        <u-cell-group title="客户信息" class="form-section">
          <up-form-item label="客户名称" prop="customerName" required>
            <up-input
              v-model="form.customerName"
              placeholder="请输入客户名称"
              clearable
            />
          </up-form-item>
          <up-form-item label="客户分类" prop="customerType" required>
            <up-input
              v-model="customerTypeText"
              placeholder="请选择客户分类"
              readonly
              @click="showCustomerTypeSheet = true"
            />
            <template #right>
              <up-icon name="arrow-right" @click="showCustomerTypeSheet = true"></up-icon>
            </template>
          </up-form-item>
          <up-form-item
            label="纳税人识别号"
            prop="taxpayerIdentificationNumber"
          >
            <up-input
              v-model="form.taxpayerIdentificationNumber"
              placeholder="请输入纳税人识别号"
              clearable
            />
          </up-form-item>
          <up-form-item label="公司地址" prop="companyAddress">
            <up-input
              v-model="form.companyAddress"
              placeholder="请输入公司地址"
              clearable
            />
          </up-form-item>
          <up-form-item label="公司电话" prop="companyPhone">
            <up-input
              v-model="form.companyPhone"
              placeholder="请输入公司电话"
              clearable
            />
          </up-form-item>
          <up-form-item label="法人" prop="corporation">
            <up-input
              v-model="form.corporation"
              placeholder="请输入法人"
              clearable
            />
          </up-form-item>
          <up-form-item label="代理人" prop="agent">
            <up-input
              v-model="form.agent"
              placeholder="请输入代理人"
              clearable
            />
          </up-form-item>
          <up-form-item label="传真" prop="fax">
            <up-input
              v-model="form.fax"
              placeholder="请输入传真"
              clearable
            />
          </up-form-item>
        </u-cell-group>
        <u-cell-group title="联系信息" class="form-section">
          <up-form-item label="联系人" prop="contactPerson">
            <up-input
              v-model="form.contactPerson"
              placeholder="请输入联系人"
              clearable
            />
          </up-form-item>
          <up-form-item label="联系电话" prop="contactPhone">
            <up-input
              v-model="form.contactPhone"
              placeholder="请输入联系电话"
              clearable
            />
          </up-form-item>
        </u-cell-group>
        <u-cell-group title="银行信息" class="form-section">
          <up-form-item label="银行基本户" prop="basicBankAccount">
            <up-input
              v-model="form.basicBankAccount"
              placeholder="请输入银行基本户"
              clearable
            />
          </up-form-item>
          <up-form-item label="银行账号" prop="bankAccount">
            <up-input
              v-model="form.bankAccount"
              placeholder="请输入银行账号"
              clearable
            />
          </up-form-item>
          <up-form-item label="开户银行" prop="bankName">
            <up-input
              v-model="form.bankName"
              placeholder="请输入开户银行"
              clearable
            />
          </up-form-item>
          <up-form-item label="开户行号" prop="bankCode">
            <up-input
              v-model="form.bankCode"
              placeholder="请输入开户行号"
              clearable
            />
          </up-form-item>
        </u-cell-group>
        <u-cell-group title="维护信息" class="form-section">
          <up-form-item label="维护人" prop="maintainer">
            <up-input
              v-model="form.maintainer"
              disabled
              placeholder="自动填充"
            />
          </up-form-item>
          <up-form-item label="维护时间" prop="maintenanceTime">
            <up-input
              v-model="form.maintenanceTime"
              disabled
              placeholder="自动填充"
            />
          </up-form-item>
        </u-cell-group>
      </up-form>
    </view>
    <FooterButtons
      :loading="loading"
      confirmText="保存"
      @cancel="goBack"
      @confirm="handleSubmit"
    />
    <up-action-sheet
      :show="showCustomerTypeSheet"
      title="选择客户分类"
      :actions="customerTypeActions"
      @select="onSelectCustomerType"
      @close="showCustomerTypeSheet = false"
    />
  </view>
</template>
<script setup>
  import { computed, onMounted, ref } from "vue";
  import { onLoad } from "@dcloudio/uni-app";
  import FooterButtons from "@/components/FooterButtons.vue";
  import useUserStore from "@/store/modules/user";
  import { formatDateToYMD } from "@/utils/ruoyi";
  import { addCustomer, getCustomer, updateCustomer } from "@/api/basicData/customerFile";
  const userStore = useUserStore();
  const formRef = ref();
  const loading = ref(false);
  const customerId = ref("");
  const showCustomerTypeSheet = ref(false);
  const form = ref({
    customerName: "",
    customerType: "",
    taxpayerIdentificationNumber: "",
    companyAddress: "",
    companyPhone: "",
    corporation: "",
    agent: "",
    fax: "",
    contactPerson: "",
    contactPhone: "",
    basicBankAccount: "",
    bankAccount: "",
    bankName: "",
    bankCode: "",
    maintainer: "",
    maintenanceTime: "",
  });
  const rules = {
    customerName: [{ required: true, message: "请输入客户名称", trigger: "blur" }],
    customerType: [{ required: true, message: "请选择客户分类", trigger: "change" }],
  };
  const customerTypeActions = [
    { name: "零售客户", value: "零售客户" },
    { name: "经销商客户", value: "经销商客户" },
  ];
  const pageTitle = computed(() =>
    customerId.value ? "编辑客户" : "新增客户"
  );
  const customerTypeText = computed(() => form.value.customerType || "");
  const goBack = () => {
    uni.navigateBack();
  };
  const initForAdd = () => {
    form.value.maintainer = userStore.nickName || "";
    form.value.maintenanceTime = formatDateToYMD(Date.now());
  };
  const loadDetail = () => {
    if (!customerId.value) return;
    uni.showLoading({ title: "加载中...", mask: true });
    getCustomer(customerId.value)
      .then(res => {
        form.value = { ...form.value, ...(res.data || {}) };
      })
      .catch(() => {
        uni.showToast({ title: "获取详情失败", icon: "error" });
      })
      .finally(() => {
        uni.hideLoading();
      });
  };
  const onSelectCustomerType = action => {
    form.value.customerType = action.value;
    showCustomerTypeSheet.value = false;
  };
  const handleSubmit = async () => {
    const valid = await formRef.value.validate().catch(() => false);
    if (!valid) return;
    loading.value = true;
    const action = customerId.value ? updateCustomer : addCustomer;
    action({ ...form.value, id: customerId.value || undefined })
      .then(() => {
        uni.showToast({ title: "保存成功", icon: "success" });
        setTimeout(() => {
          uni.navigateBack();
        }, 300);
      })
      .catch(() => {
        uni.showToast({ title: "保存失败", icon: "error" });
      })
      .finally(() => {
        loading.value = false;
      });
  };
  onMounted(async () => {
    if (!userStore.nickName) {
      await userStore.getInfo().catch(() => null);
    }
    if (!customerId.value) {
      initForAdd();
    }
  });
  onLoad(options => {
    if (options?.id) {
      customerId.value = options.id;
      loadDetail();
    }
  });
</script>
<style scoped lang="scss">
  @import "@/static/scss/form-common.scss";
  .account-detail {
    min-height: 100vh;
    background: #f8f9fa;
    padding-bottom: 100px;
  }
  .form-container {
    padding: 12px 12px 0;
  }
  .hero-card {
    margin-bottom: 12px;
    padding: 18px 18px 16px;
    border-radius: 16px;
    background: linear-gradient(135deg, #f4f8ff 0%, #ffffff 100%);
    box-shadow: 0 6px 18px rgba(41, 121, 255, 0.08);
  }
  .hero-title {
    display: block;
    font-size: 18px;
    font-weight: 600;
    color: #1f2d3d;
    margin-bottom: 6px;
  }
  .hero-desc {
    display: block;
    font-size: 13px;
    line-height: 1.6;
    color: #7a8599;
  }
  .form-section {
    margin-bottom: 12px;
    border-radius: 12px;
    overflow: hidden;
    box-shadow: 0 2px 10px rgba(15, 35, 95, 0.05);
  }
  :deep(.u-cell-group__title) {
    padding: 14px 18px 10px !important;
    font-size: 15px !important;
    font-weight: 600 !important;
    color: #22324d !important;
    background: #f8fbff !important;
  }
  :deep(.u-form-item__content__slot) {
    flex: 1;
  }
  :deep(.u-input__content) {
    justify-content: flex-end;
  }
  :deep(.u-input__content__field-wrapper__field),
  :deep(.u-input__input) {
    text-align: right !important;
  }
</style>
src/pages/basicData/customerFile/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,183 @@
<template>
  <view class="sales-account">
    <PageHeader title="客户档案" @back="goBack" />
    <view class="search-section">
      <view class="search-bar">
        <view class="search-input">
          <up-input
            class="search-text"
            v-model="customerName"
            placeholder="请输入客户名称"
            clearable
            @change="getList"
          />
        </view>
        <view class="filter-button" @click="getList">
          <up-icon name="search" size="24" color="#999999"></up-icon>
        </view>
      </view>
    </view>
    <view class="tabs-section">
      <up-tabs
        v-model="tabValue"
        :list="tabList"
        itemStyle="width: 33.33%;height: 80rpx;"
        @change="onTabChange"
      />
    </view>
    <view v-if="list.length > 0" class="ledger-list">
      <view v-for="item in list" :key="item.id" class="ledger-item">
        <view class="item-header">
          <view class="item-left">
            <view class="document-icon">
              <up-icon name="account-fill" size="16" color="#ffffff"></up-icon>
            </view>
            <text class="item-id">{{ item.customerName || "-" }}</text>
          </view>
          <text class="item-index">{{ item.customerType || "-" }}</text>
        </view>
        <up-divider></up-divider>
        <view class="item-details">
          <view class="detail-row">
            <text class="detail-label">纳税人识别号</text>
            <text class="detail-value">{{ item.taxpayerIdentificationNumber || "-" }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">公司电话</text>
            <text class="detail-value">{{ item.companyPhone || "-" }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">公司地址</text>
            <text class="detail-value">{{ item.companyAddress || "-" }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">法人</text>
            <text class="detail-value">{{ item.corporation || "-" }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">代理人</text>
            <text class="detail-value">{{ item.agent || "-" }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">维护人</text>
            <text class="detail-value">{{ item.maintainer || "-" }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">维护时间</text>
            <text class="detail-value">{{ item.maintenanceTime || "-" }}</text>
          </view>
        </view>
        <view class="action-buttons">
                    <up-button class="action-btn" size="small" type="primary" @click="goEdit(item)"
                    >编辑</up-button
                    >
          <up-button class="action-btn" size="small" @click="goDetail(item)"
            >详情</up-button
          >
        </view>
      </view>
    </view>
    <view v-else class="no-data">
      <text>暂无客户档案数据</text>
    </view>
    <view class="fab-button" @click="goAdd">
      <up-icon name="plus" size="28" color="#ffffff"></up-icon>
    </view>
  </view>
</template>
<script setup>
  import { reactive, ref } from "vue";
  import { onShow } from "@dcloudio/uni-app";
  import { listCustomer } from "@/api/basicData/customerFile";
  const customerName = ref("");
  const list = ref([]);
  const tabList = reactive([
    { name: "全部客户", value: "" },
    { name: "零售客户", value: "零售客户" },
    { name: "经销商客户", value: "经销商客户" },
  ]);
  const tabValue = ref(0);
  const page = {
    current: -1,
    size: -1,
  };
  const goBack = () => {
    uni.navigateBack();
  };
  const goAdd = () => {
    uni.navigateTo({ url: "/pages/basicData/customerFile/edit" });
  };
  const goEdit = item => {
    uni.navigateTo({ url: `/pages/basicData/customerFile/edit?id=${item.id}` });
  };
  const goDetail = item => {
    uni.navigateTo({ url: `/pages/basicData/customerFile/detail?id=${item.id}` });
  };
  const onTabChange = val => {
    tabValue.value = val.index;
    getList();
  };
  const getCurrentCustomerType = () => {
    const currentTab = tabList[tabValue.value];
    return currentTab?.value || "";
  };
  const getList = () => {
    uni.showLoading({ title: "加载中...", mask: true });
    listCustomer({
      ...page,
      customerName: customerName.value,
      customerType: getCurrentCustomerType(),
    })
      .then(res => {
        list.value = res?.records || res?.data?.records || [];
      })
      .catch(() => {
        uni.showToast({ title: "查询失败", icon: "error" });
      })
      .finally(() => {
        uni.hideLoading();
      });
  };
  onShow(() => {
    getList();
  });
</script>
<style scoped lang="scss">
  @import "@/styles/procurement-common.scss";
  .tabs-section {
    background: #ffffff;
    padding: 0 12px 8px 12px;
  }
  .item-index {
    max-width: 180rpx;
    text-align: center;
  }
  .detail-value {
    max-width: 70%;
    word-break: break-all;
  }
</style>
src/pages/cooperativeOffice/customerManage/detail.vue
@@ -170,14 +170,6 @@
  import { onLoad, onShow } from "@dcloudio/uni-app";
  import dayjs from "dayjs";
  // èŽ·å–é¡µé¢å‚æ•°
  const getPageId = () => {
    const pages = getCurrentPages();
    const currentPage = pages[pages.length - 1];
    const options = currentPage.options || {};
    return options.id || "";
  };
  // è¯¦æƒ…数据
  const detailData = ref({});
src/pages/equipmentManagement/repair/maintain.vue
@@ -82,7 +82,6 @@
                    @click.stop="showSparePart = true"></u-icon>
          </template>
        </u-form-item>
        <u-form-item v-if="selectedSpareParts.length"
                     label="领用数量"
                     border-bottom>
@@ -119,7 +118,6 @@
                        format="YYYY-MM-DD HH:mm:ss"
                        @confirm="onDateConfirm"
                        @cancel="showDatePicker = false" />
    <!-- è®¾å¤‡å¤‡ä»¶é€‰æ‹©å™¨ -->
    <up-popup :show="showSparePart"
              mode="bottom"
@@ -155,7 +153,7 @@
  import { onShow } from "@dcloudio/uni-app";
  import PageHeader from "@/components/PageHeader.vue";
  import { addMaintain } from "@/api/equipmentManagement/repair";
  import { getSparePartsList } from "@/api/equipmentManagement/spareParts";
  import { getSparePartsList } from "@/api/equipmentManagement/repair";
  import useUserStore from "@/store/modules/user";
  import dayjs from "dayjs";
@@ -232,7 +230,7 @@
    };
    selectedSpareParts.value = [];
    tempSelectedSpareParts.value = [];
    Object.keys(sparePartQtyMap).forEach((k) => delete sparePartQtyMap[k]);
    Object.keys(sparePartQtyMap).forEach(k => delete sparePartQtyMap[k]);
  };
  const resetFormAndValidate = () => {
@@ -265,7 +263,10 @@
      }
      form.value.status = Number(form.value.status);
      // é¢†ç”¨æ•°é‡æ ¡éªŒ
      if (Array.isArray(form.value.sparePartsIds) && form.value.sparePartsIds.length > 0) {
      if (
        Array.isArray(form.value.sparePartsIds) &&
        form.value.sparePartsIds.length > 0
      ) {
        for (const partId of form.value.sparePartsIds) {
          const qty = Number(sparePartQtyMap?.[partId]);
          if (!Number.isFinite(qty) || qty <= 0) {
@@ -273,11 +274,19 @@
            loading.value = false;
            return;
          }
          const part = sparePartOptions.value.find((p) => String(p.id) === String(partId));
          const part = sparePartOptions.value.find(
            p => String(p.id) === String(partId)
          );
          const stock = part?.quantity;
          if (stock !== null && stock !== undefined && Number.isFinite(Number(stock))) {
          if (
            stock !== null &&
            stock !== undefined &&
            Number.isFinite(Number(stock))
          ) {
            if (qty > Number(stock)) {
              showToast(`备件「${part?.name || ""}」领用数量不能超过库存(${stock})`);
              showToast(
                `备件「${part?.name || ""}」领用数量不能超过库存(${stock})`
              );
              loading.value = false;
              return;
            }
@@ -285,12 +294,21 @@
        }
      }
      const spareIds = Array.isArray(form.value.sparePartsIds) ? form.value.sparePartsIds : [];
      const spareIds = Array.isArray(form.value.sparePartsIds)
        ? form.value.sparePartsIds
        : [];
      const submitData = {
        ...form.value,
        sparePartsIds: spareIds.length ? spareIds.join(",") : "",
        sparePartsQty: spareIds.length ? spareIds.map((pid) => sparePartQtyMap?.[pid] ?? 1).join(",") : "",
        sparePartsUseList: spareIds.length ? spareIds.map((pid) => ({ id: pid, quantity: sparePartQtyMap?.[pid] ?? 1 })) : [],
        sparePartsQty: spareIds.length
          ? spareIds.map(pid => sparePartQtyMap?.[pid] ?? 1).join(",")
          : "",
        sparePartsUseList: spareIds.length
          ? spareIds.map(pid => ({
              id: pid,
              quantity: sparePartQtyMap?.[pid] ?? 1,
            }))
          : [],
      };
      const { code } = await addMaintain({ id: id, ...submitData });
@@ -344,12 +362,14 @@
    }
  };
  const isSparePartSelected = (id) => {
    return tempSelectedSpareParts.value.some((p) => String(p.id) === String(id));
  const isSparePartSelected = id => {
    return tempSelectedSpareParts.value.some(p => String(p.id) === String(id));
  };
  const toggleSparePartSelection = (item) => {
    const idx = tempSelectedSpareParts.value.findIndex((p) => String(p.id) === String(item.id));
  const toggleSparePartSelection = item => {
    const idx = tempSelectedSpareParts.value.findIndex(
      p => String(p.id) === String(item.id)
    );
    if (idx >= 0) {
      tempSelectedSpareParts.value.splice(idx, 1);
      delete sparePartQtyMap[item.id];
@@ -367,20 +387,23 @@
  const confirmSparePartSelection = () => {
    selectedSpareParts.value = [...tempSelectedSpareParts.value];
    form.value.sparePartsIds = selectedSpareParts.value.map((i) => i.id);
    form.value.sparePartsIds = selectedSpareParts.value.map(i => i.id);
    // ä¿åº•给未填的数量赋值
    selectedSpareParts.value.forEach((p) => {
      if (!Number.isFinite(Number(sparePartQtyMap[p.id])) || Number(sparePartQtyMap[p.id]) <= 0) {
    selectedSpareParts.value.forEach(p => {
      if (
        !Number.isFinite(Number(sparePartQtyMap[p.id])) ||
        Number(sparePartQtyMap[p.id]) <= 0
      ) {
        sparePartQtyMap[p.id] = 1;
      }
    });
    showSparePart.value = false;
  };
  const removeSparePart = (index) => {
  const removeSparePart = index => {
    const removed = selectedSpareParts.value.splice(index, 1)[0];
    tempSelectedSpareParts.value = [...selectedSpareParts.value];
    form.value.sparePartsIds = selectedSpareParts.value.map((i) => i.id);
    form.value.sparePartsIds = selectedSpareParts.value.map(i => i.id);
    if (removed?.id !== null && removed?.id !== undefined) {
      delete sparePartQtyMap[removed.id];
    }
@@ -408,17 +431,23 @@
    initForm();
  });
  watch(showSparePart, (val) => {
  watch(showSparePart, val => {
    if (val) {
      tempSelectedSpareParts.value = [...selectedSpareParts.value];
      tempSelectedSpareParts.value.forEach((p) => {
        if (!Number.isFinite(Number(sparePartQtyMap[p.id])) || Number(sparePartQtyMap[p.id]) <= 0) {
      tempSelectedSpareParts.value.forEach(p => {
        if (
          !Number.isFinite(Number(sparePartQtyMap[p.id])) ||
          Number(sparePartQtyMap[p.id]) <= 0
        ) {
          sparePartQtyMap[p.id] = 1;
        }
      });
      // å…œåº•:如果还没加载备件列表,打开弹窗时再拉一次
      if (!Array.isArray(sparePartOptions.value) || sparePartOptions.value.length === 0) {
      if (
        !Array.isArray(sparePartOptions.value) ||
        sparePartOptions.value.length === 0
      ) {
        fetchSparePartOptions().catch(() => {});
      }
    }
src/pages/equipmentManagement/upkeep/maintain.vue
@@ -79,7 +79,6 @@
                  @click="showSparePartPicker" />
        </template>
      </u-form-item>
      <u-form-item v-if="selectedSpareParts.length"
                   label="领用数量"
                   border-bottom>
@@ -236,10 +235,8 @@
  import { ref, onMounted, reactive } from "vue";
  import { onShow } from "@dcloudio/uni-app";
  import PageHeader from "@/components/PageHeader.vue";
  import {
    addMaintenance,
  } from "@/api/equipmentManagement/upkeep";
  import { getSparePartsList } from "@/api/equipmentManagement/spareParts";
  import { addMaintenance } from "@/api/equipmentManagement/upkeep";
  import { getSparePartsList } from "@/api/equipmentManagement/repair";
  import useUserStore from "@/store/modules/user";
  import dayjs from "dayjs";
  import { formatDateToYMD } from "@/utils/ruoyi";
@@ -337,7 +334,7 @@
    maintenancestatusText.value = "";
    selectedSpareParts.value = [];
    tempSelectedSpareParts.value = [];
    Object.keys(sparePartQtyMap).forEach((k) => delete sparePartQtyMap[k]);
    Object.keys(sparePartQtyMap).forEach(k => delete sparePartQtyMap[k]);
    sparePartsQtyRaw.value = "";
  };
@@ -406,7 +403,9 @@
        return;
      }
      // é¢†ç”¨æ•°é‡æ ¡éªŒ
      const spareIds = Array.isArray(form.value.sparePartsIds) ? form.value.sparePartsIds : [];
      const spareIds = Array.isArray(form.value.sparePartsIds)
        ? form.value.sparePartsIds
        : [];
      if (spareIds.length > 0) {
        for (const partId of spareIds) {
          const qty = Number(sparePartQtyMap?.[partId]);
@@ -415,11 +414,19 @@
            loading.value = false;
            return;
          }
          const part = sparePartOptions.value.find((p) => String(p.id || p.value) === String(partId));
          const part = sparePartOptions.value.find(
            p => String(p.id || p.value) === String(partId)
          );
          const stock = part?.quantity;
          if (stock !== null && stock !== undefined && Number.isFinite(Number(stock))) {
          if (
            stock !== null &&
            stock !== undefined &&
            Number.isFinite(Number(stock))
          ) {
            if (qty > Number(stock)) {
              showToast(`备件「${part?.name || ""}」领用数量不能超过库存(${stock})`);
              showToast(
                `备件「${part?.name || ""}」领用数量不能超过库存(${stock})`
              );
              loading.value = false;
              return;
            }
@@ -431,8 +438,15 @@
        ...form.value,
        imagesFile: form.value.status == "1" ? uploadFiles.value : [],
        sparePartsIds: spareIds.length ? spareIds.join(",") : "",
        sparePartsQty: spareIds.length ? spareIds.map((pid) => sparePartQtyMap?.[pid] ?? 1).join(",") : "",
        sparePartsUseList: spareIds.length ? spareIds.map((pid) => ({ id: pid, quantity: sparePartQtyMap?.[pid] ?? 1 })) : [],
        sparePartsQty: spareIds.length
          ? spareIds.map(pid => sparePartQtyMap?.[pid] ?? 1).join(",")
          : "",
        sparePartsUseList: spareIds.length
          ? spareIds.map(pid => ({
              id: pid,
              quantity: sparePartQtyMap?.[pid] ?? 1,
            }))
          : [],
      };
      const { code } = await addMaintenance({ id: id, ...submitData });
@@ -512,10 +526,13 @@
  // æ˜¾ç¤ºè®¾å¤‡å¤‡ä»¶é€‰æ‹©å™¨
  const showSparePartPicker = () => {
    tempSelectedSpareParts.value = [...selectedSpareParts.value];
    tempSelectedSpareParts.value.forEach((p) => {
    tempSelectedSpareParts.value.forEach(p => {
      const pid = p?.id ?? p?.value;
      if (pid !== null && pid !== undefined) {
        if (!Number.isFinite(Number(sparePartQtyMap[pid])) || Number(sparePartQtyMap[pid]) <= 0) {
        if (
          !Number.isFinite(Number(sparePartQtyMap[pid])) ||
          Number(sparePartQtyMap[pid]) <= 0
        ) {
          sparePartQtyMap[pid] = 1;
        }
      }
@@ -541,7 +558,10 @@
      delete sparePartQtyMap[itemId];
    } else {
      tempSelectedSpareParts.value.push(item);
      if (!Number.isFinite(Number(sparePartQtyMap[itemId])) || Number(sparePartQtyMap[itemId]) <= 0) {
      if (
        !Number.isFinite(Number(sparePartQtyMap[itemId])) ||
        Number(sparePartQtyMap[itemId]) <= 0
      ) {
        sparePartQtyMap[itemId] = 1;
      }
    }
@@ -550,11 +570,16 @@
  // ç¡®è®¤å¤‡ä»¶é€‰æ‹©
  const confirmSparePartSelection = () => {
    selectedSpareParts.value = [...tempSelectedSpareParts.value];
    form.value.sparePartsIds = selectedSpareParts.value.map(item => item.id || item.value);
    selectedSpareParts.value.forEach((p) => {
    form.value.sparePartsIds = selectedSpareParts.value.map(
      item => item.id || item.value
    );
    selectedSpareParts.value.forEach(p => {
      const pid = p?.id ?? p?.value;
      if (pid !== null && pid !== undefined) {
        if (!Number.isFinite(Number(sparePartQtyMap[pid])) || Number(sparePartQtyMap[pid]) <= 0) {
        if (
          !Number.isFinite(Number(sparePartQtyMap[pid])) ||
          Number(sparePartQtyMap[pid]) <= 0
        ) {
          sparePartQtyMap[pid] = 1;
        }
      }
@@ -565,7 +590,9 @@
  // ç§»é™¤å·²é€‰å¤‡ä»¶
  const removeSparePart = index => {
    const removed = selectedSpareParts.value.splice(index, 1)[0];
    form.value.sparePartsIds = selectedSpareParts.value.map(item => item.id || item.value);
    form.value.sparePartsIds = selectedSpareParts.value.map(
      item => item.id || item.value
    );
    const rid = removed?.id ?? removed?.value;
    if (rid !== null && rid !== undefined) delete sparePartQtyMap[rid];
  };
@@ -671,7 +698,9 @@
            const idArray =
              typeof sparePartsIds.value === "string"
                ? sparePartsIds.value.split(",")
                : (Array.isArray(sparePartsIds.value) ? sparePartsIds.value : []);
                : Array.isArray(sparePartsIds.value)
                ? sparePartsIds.value
                : [];
            if (idArray.length > 0) {
              selectedSpareParts.value = sparePartOptions.value
@@ -688,28 +717,41 @@
                  quantity: option.quantity,
                }));
              // è®¾ç½®å¤‡ä»¶IDs(保持数组,提交时再 join)
              form.value.sparePartsIds = idArray.map((v) => {
              form.value.sparePartsIds = idArray.map(v => {
                const n = Number(String(v).trim());
                return Number.isFinite(n) ? n : String(v).trim();
              });
              // å›žæ˜¾é¢†ç”¨æ•°é‡ï¼ˆè‹¥æœ‰ sparePartsQty)
              if (typeof sparePartsQtyRaw.value === "string" && sparePartsQtyRaw.value.trim()) {
                const qtyArr = sparePartsQtyRaw.value.split(",").map((s) => Number(String(s).trim()));
              if (
                typeof sparePartsQtyRaw.value === "string" &&
                sparePartsQtyRaw.value.trim()
              ) {
                const qtyArr = sparePartsQtyRaw.value
                  .split(",")
                  .map(s => Number(String(s).trim()));
                selectedSpareParts.value.forEach((p, idx) => {
                  const pid = p?.id ?? p?.value;
                  const q = qtyArr[idx];
                  if (pid !== null && pid !== undefined && Number.isFinite(q) && q > 0) {
                  if (
                    pid !== null &&
                    pid !== undefined &&
                    Number.isFinite(q) &&
                    q > 0
                  ) {
                    sparePartQtyMap[pid] = q;
                  }
                });
              }
              // é»˜è®¤æ•°é‡å…œåº•
              selectedSpareParts.value.forEach((p) => {
              selectedSpareParts.value.forEach(p => {
                const pid = p?.id ?? p?.value;
                if (pid !== null && pid !== undefined) {
                  if (!Number.isFinite(Number(sparePartQtyMap[pid])) || Number(sparePartQtyMap[pid]) <= 0) {
                  if (
                    !Number.isFinite(Number(sparePartQtyMap[pid])) ||
                    Number(sparePartQtyMap[pid]) <= 0
                  ) {
                    sparePartQtyMap[pid] = 1;
                  }
                }
src/pages/login.vue
@@ -183,7 +183,7 @@
      sendClientIdToServer();
      // å¯åŠ¨å®šæ—¶èŽ·å–æœªè¯»æ¶ˆæ¯æ•°é‡çš„å®šæ—¶å™¨
      startNoticeCountTimer(userId);
      uni.switchTab({ url: "/pages/works" });
      uni.switchTab({ url: "/pages/index" });
    });
  }
src/pages/qualityManagement/finalInspection/add.vue
@@ -302,7 +302,7 @@
<script setup>
  import { ref, computed, onMounted, nextTick } from "vue";
  import { onShow } from "@dcloudio/uni-app";
  import { onShow, onLoad } from "@dcloudio/uni-app";
  import PageHeader from "@/components/PageHeader.vue";
  import dayjs from "dayjs";
  import { getOptions } from "@/api/procurementManagement/procurementLedger.js";
@@ -454,7 +454,7 @@
  // æ˜¯å¦ä¸ºç¼–辑模式
  const isEdit = computed(() => {
    const id = getPageId();
    const id = optionsId.value;
    return !!id;
  });
@@ -463,13 +463,6 @@
    const v = form.value || {};
    return !!(v.productMainId != null || v.purchaseLedgerId != null);
  });
  // èŽ·å–é¡µé¢ID
  const getPageId = () => {
    const pages = getCurrentPages();
    const currentPage = pages[pages.length - 1];
    return currentPage.options.id;
  };
  // è¿”回上一页
  const goBack = () => {
@@ -737,7 +730,7 @@
  // åˆå§‹åŒ–表单
  const initForm = async () => {
    const id = getPageId();
    const id = optionsId.value;
    if (id) {
      // ç¼–辑模式,加载数据
      // å…ˆé‡ç½®è¡¨å•数据
@@ -890,6 +883,12 @@
  onShow(() => {
    initForm();
  });
  const optionsId = ref("");
  onLoad(options => {
    optionsId.value = options.id || "";
    getDetail();
  });
</script>
<style scoped lang="scss">
src/pages/qualityManagement/finalInspection/detail.vue
@@ -131,7 +131,7 @@
<script setup>
  import { ref, onMounted } from "vue";
  import { onShow } from "@dcloudio/uni-app";
  import { onShow, onLoad } from "@dcloudio/uni-app";
  import PageHeader from "@/components/PageHeader.vue";
  import dayjs from "dayjs";
  import { qualityInspectParamInfo } from "@/api/qualityManagement/materialInspection.js";
@@ -204,16 +204,9 @@
    }, 1500);
  };
  // èŽ·å–é¡µé¢ID
  const getPageId = () => {
    const pages = getCurrentPages();
    const currentPage = pages[pages.length - 1];
    return currentPage.options.id;
  };
  // èŽ·å–è¯¦æƒ…æ•°æ®
  const getDetail = () => {
    const id = getPageId();
    const id = optionsId.value;
    if (!id) {
      showToast("参数错误");
      return;
@@ -262,6 +255,11 @@
  onMounted(() => {
    getDetail();
  });
  const optionsId = ref("");
  onLoad(options => {
    optionsId.value = options.id || "";
    getDetail();
  });
</script>
<style scoped lang="scss">
src/pages/qualityManagement/materialInspection/add.vue
@@ -309,7 +309,7 @@
<script setup>
  import { ref, computed, onMounted, nextTick } from "vue";
  import { onShow } from "@dcloudio/uni-app";
  import { onShow, onLoad } from "@dcloudio/uni-app";
  import PageHeader from "@/components/PageHeader.vue";
  import dayjs from "dayjs";
  import { getOptions } from "@/api/procurementManagement/procurementLedger.js";
@@ -460,7 +460,7 @@
  // æ˜¯å¦ä¸ºç¼–辑模式
  const isEdit = computed(() => {
    const id = getPageId();
    const id = optionsId.value;
    return !!id;
  });
@@ -469,13 +469,6 @@
    const v = form.value || {};
    return !!(v.productMainId != null || v.purchaseLedgerId != null);
  });
  // èŽ·å–é¡µé¢ID
  const getPageId = () => {
    const pages = getCurrentPages();
    const currentPage = pages[pages.length - 1];
    return currentPage.options.id;
  };
  // è¿”回上一页
  const goBack = () => {
@@ -743,7 +736,7 @@
  // åˆå§‹åŒ–表单
  const initForm = async () => {
    const id = getPageId();
    const id = optionsId.value;
    if (id) {
      // ç¼–辑模式,加载数据
      // å…ˆé‡ç½®è¡¨å•数据
@@ -896,6 +889,12 @@
  onShow(() => {
    initForm();
  });
  const optionsId = ref("");
  onLoad(options => {
    optionsId.value = options.id || "";
    initForm();
  });
</script>
<style scoped lang="scss">
src/pages/qualityManagement/materialInspection/detail.vue
@@ -131,7 +131,7 @@
<script setup>
  import { ref, onMounted } from "vue";
  import { onShow } from "@dcloudio/uni-app";
  import { onShow, onLoad } from "@dcloudio/uni-app";
  import PageHeader from "@/components/PageHeader.vue";
  import dayjs from "dayjs";
  import { qualityInspectParamInfo } from "@/api/qualityManagement/materialInspection.js";
@@ -204,16 +204,9 @@
    }, 1500);
  };
  // èŽ·å–é¡µé¢ID
  const getPageId = () => {
    const pages = getCurrentPages();
    const currentPage = pages[pages.length - 1];
    return currentPage.options.id;
  };
  // èŽ·å–è¯¦æƒ…æ•°æ®
  const getDetail = () => {
    const id = getPageId();
    const id = optionsId.value;
    if (!id) {
      showToast("参数错误");
      return;
@@ -261,6 +254,11 @@
  onMounted(() => {
    getDetail();
  });
  const optionsId = ref("");
  onLoad(options => {
    optionsId.value = options.id || "";
    getDetail();
  });
</script>
<style scoped lang="scss">
src/pages/qualityManagement/processInspection/add.vue
@@ -302,7 +302,7 @@
<script setup>
  import { ref, computed, onMounted, nextTick } from "vue";
  import { onShow } from "@dcloudio/uni-app";
  import { onShow, onLoad } from "@dcloudio/uni-app";
  import PageHeader from "@/components/PageHeader.vue";
  import dayjs from "dayjs";
  import { getOptions } from "@/api/procurementManagement/procurementLedger.js";
@@ -454,7 +454,7 @@
  // æ˜¯å¦ä¸ºç¼–辑模式
  const isEdit = computed(() => {
    const id = getPageId();
    const id = optionsId.value;
    return !!id;
  });
@@ -463,13 +463,6 @@
    const v = form.value || {};
    return !!(v.productMainId != null || v.purchaseLedgerId != null);
  });
  // èŽ·å–é¡µé¢ID
  const getPageId = () => {
    const pages = getCurrentPages();
    const currentPage = pages[pages.length - 1];
    return currentPage.options.id;
  };
  // è¿”回上一页
  const goBack = () => {
@@ -737,7 +730,7 @@
  // åˆå§‹åŒ–表单
  const initForm = async () => {
    const id = getPageId();
    const id = optionsId.value;
    if (id) {
      // ç¼–辑模式,加载数据
      // å…ˆé‡ç½®è¡¨å•数据
@@ -890,6 +883,11 @@
  onShow(() => {
    initForm();
  });
  const optionsId = ref("");
  onLoad(options => {
    optionsId.value = options.id || "";
    initForm();
  });
</script>
<style scoped lang="scss">
src/pages/qualityManagement/processInspection/detail.vue
@@ -131,7 +131,7 @@
<script setup>
  import { ref, onMounted } from "vue";
  import { onShow } from "@dcloudio/uni-app";
  import { onShow, onLoad } from "@dcloudio/uni-app";
  import PageHeader from "@/components/PageHeader.vue";
  import dayjs from "dayjs";
  import { qualityInspectParamInfo } from "@/api/qualityManagement/materialInspection.js";
@@ -204,16 +204,9 @@
    }, 1500);
  };
  // èŽ·å–é¡µé¢ID
  const getPageId = () => {
    const pages = getCurrentPages();
    const currentPage = pages[pages.length - 1];
    return currentPage.options.id;
  };
  // èŽ·å–è¯¦æƒ…æ•°æ®
  const getDetail = () => {
    const id = getPageId();
    const id = optionsId.value;
    if (!id) {
      showToast("参数错误");
      return;
@@ -263,6 +256,12 @@
  onMounted(() => {
    getDetail();
  });
  const optionsId = ref("");
  onLoad(options => {
    optionsId.value = options.id || "";
    getDetail();
  });
</script>
<style scoped lang="scss">
src/pages/sales/salesQuotation/detail.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,235 @@
<template>
  <view class="customer-detail-page">
    <PageHeader title="报价详情" @back="goBack" />
    <view class="detail-content">
      <view class="section">
        <view class="section-title">基础信息</view>
        <view class="info-list">
          <view class="info-item">
            <text class="info-label">报价单号</text>
            <text class="info-value">{{ detailData.quotationNo || "-" }}</text>
          </view>
          <view class="info-item">
            <text class="info-label">客户名称</text>
            <text class="info-value">{{ detailData.customer || "-" }}</text>
          </view>
          <view class="info-item">
            <text class="info-label">业务员</text>
            <text class="info-value">{{ detailData.salesperson || "-" }}</text>
          </view>
          <view class="info-item">
            <text class="info-label">报价日期</text>
            <text class="info-value">{{ detailData.quotationDate || "-" }}</text>
          </view>
          <view class="info-item">
            <text class="info-label">有效期至</text>
            <text class="info-value">{{ detailData.validDate || "-" }}</text>
          </view>
          <view class="info-item">
            <text class="info-label">付款方式</text>
            <text class="info-value">{{ detailData.paymentMethod || "-" }}</text>
          </view>
          <view class="info-item">
            <text class="info-label">审批状态</text>
            <text class="info-value">{{ detailData.status || "-" }}</text>
          </view>
          <view class="info-item">
            <text class="info-label">报价总额</text>
            <text class="info-value highlight">{{ formatAmount(detailData.totalAmount) }}</text>
          </view>
          <view class="info-item">
            <text class="info-label">备注</text>
            <text class="info-value">{{ detailData.remark || "-" }}</text>
          </view>
        </view>
      </view>
      <view class="section">
        <view class="section-title">审批节点</view>
        <view v-if="approverNames.length" class="info-list">
          <view v-for="(name, index) in approverNames" :key="index" class="info-item">
            <text class="info-label">审批节点 {{ index + 1 }}</text>
            <text class="info-value">{{ name }}</text>
          </view>
        </view>
        <view v-else class="empty-box">
          <text>暂无审批节点</text>
        </view>
      </view>
      <view class="section">
        <view class="section-title">产品明细</view>
        <view v-if="detailData.products && detailData.products.length > 0" class="product-list">
          <view v-for="(item, index) in detailData.products" :key="index" class="product-card">
            <view class="product-head">产品 {{ index + 1 }}</view>
            <view class="info-item">
              <text class="info-label">产品名称</text>
              <text class="info-value">{{ item.product || item.productName || "-" }}</text>
            </view>
            <view class="info-item">
              <text class="info-label">规格型号</text>
              <text class="info-value">{{ item.specification || "-" }}</text>
            </view>
            <view class="info-item">
              <text class="info-label">单位</text>
              <text class="info-value">{{ item.unit || "-" }}</text>
            </view>
            <view class="info-item">
              <text class="info-label">数量</text>
              <text class="info-value">{{ item.quantity || "-" }}</text>
            </view>
            <view class="info-item">
              <text class="info-label">单价</text>
              <text class="info-value">{{ formatAmount(item.unitPrice) }}</text>
            </view>
            <view class="info-item">
              <text class="info-label">金额</text>
              <text class="info-value highlight">{{ formatAmount(item.amount) }}</text>
            </view>
          </view>
        </view>
        <view v-else class="empty-box">
          <text>暂无产品明细</text>
        </view>
      </view>
    </view>
    <FooterButtons cancelText="返回" confirmText="编辑" @cancel="goBack" @confirm="goEdit" />
  </view>
</template>
<script setup>
  import { computed, ref } from "vue";
  import { onLoad, onShow } from "@dcloudio/uni-app";
  import FooterButtons from "@/components/FooterButtons.vue";
  import PageHeader from "@/components/PageHeader.vue";
  const quotationId = ref("");
  const detailData = ref({});
  const approverNames = computed(() => {
    const approverText = detailData.value.approveUserNames || detailData.value.approverNames || detailData.value.approveUserIds || "";
    if (Array.isArray(approverText)) return approverText.filter(Boolean);
    return String(approverText)
      .split(",")
      .map(item => item.trim())
      .filter(Boolean);
  });
  const goBack = () => {
    uni.navigateBack();
  };
  const goEdit = () => {
    if (!quotationId.value) return;
    uni.navigateTo({ url: `/pages/sales/salesQuotation/edit?id=${quotationId.value}` });
  };
  const formatAmount = amount => `Â¥${Number(amount || 0).toFixed(2)}`;
  const loadDetailFromStorage = () => {
    const cachedData = uni.getStorageSync("salesQuotationDetail");
    detailData.value = cachedData || {};
  };
  onLoad(options => {
    if (options?.id) {
      quotationId.value = options.id;
    }
    loadDetailFromStorage();
  });
  onShow(() => {
    loadDetailFromStorage();
  });
</script>
<style scoped lang="scss">
  .customer-detail-page {
    min-height: 100vh;
    background-color: #f5f5f5;
    padding-bottom: 90px;
  }
  .detail-content {
    padding: 16px;
  }
  .section {
    background: #ffffff;
    border-radius: 12px;
    margin-bottom: 16px;
    overflow: hidden;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
  }
  .section-title {
    padding: 16px;
    font-size: 16px;
    font-weight: 600;
    color: #303133;
    border-bottom: 1px solid #f0f0f0;
  }
  .info-list {
    padding: 8px 0;
  }
  .info-item {
    display: flex;
    padding: 12px 16px;
    border-bottom: 1px solid #f8f8f8;
  }
  .info-item:last-child {
    border-bottom: none;
  }
  .info-label {
    width: 120px;
    font-size: 14px;
    color: #606266;
  }
  .info-value {
    flex: 1;
    font-size: 14px;
    color: #303133;
    text-align: right;
    word-break: break-all;
  }
  .highlight {
    color: #2979ff;
    font-weight: 600;
  }
  .empty-box {
    padding: 20px 16px;
    font-size: 14px;
    color: #999;
    text-align: center;
  }
  .product-list {
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 12px;
  }
  .product-card {
    background: #f9fafc;
    border-radius: 10px;
    overflow: hidden;
  }
  .product-head {
    padding: 12px 16px;
    font-size: 14px;
    font-weight: 600;
    color: #22324d;
    border-bottom: 1px solid #eef2f7;
  }
</style>
src/pages/sales/salesQuotation/edit.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,613 @@
<template>
  <view class="account-detail">
    <PageHeader :title="pageTitle" @back="goBack" />
    <view class="form-container">
      <up-form
        ref="formRef"
        :model="form"
        :rules="rules"
        label-width="110"
        input-align="right"
        error-message-align="right"
      >
        <u-cell-group title="基础信息" class="form-section">
          <up-form-item label="客户名称" prop="customer" required>
            <up-input v-model="form.customer" placeholder="请选择客户" readonly @click="showCustomerSheet = true" />
            <template #right>
              <up-icon name="arrow-right" @click="showCustomerSheet = true"></up-icon>
            </template>
          </up-form-item>
          <up-form-item label="业务员" prop="salesperson" required>
            <up-input
              v-model="form.salesperson"
              placeholder="请选择业务员"
              readonly
              @click="showSalespersonSheet = true"
            />
            <template #right>
              <up-icon name="arrow-right" @click="showSalespersonSheet = true"></up-icon>
            </template>
          </up-form-item>
          <up-form-item label="报价日期" prop="quotationDate" required>
            <up-input
              v-model="form.quotationDate"
              placeholder="请选择报价日期"
              readonly
              @click="showQuotationDatePicker = true"
            />
            <template #right>
              <up-icon name="arrow-right" @click="showQuotationDatePicker = true"></up-icon>
            </template>
          </up-form-item>
          <up-form-item label="有效期至" prop="validDate" required>
            <up-input
              v-model="form.validDate"
              placeholder="请选择有效期"
              readonly
              @click="showValidDatePicker = true"
            />
            <template #right>
              <up-icon name="arrow-right" @click="showValidDatePicker = true"></up-icon>
            </template>
          </up-form-item>
          <up-form-item label="付款方式" prop="paymentMethod" required>
            <up-input v-model="form.paymentMethod" placeholder="请输入付款方式" clearable />
          </up-form-item>
          <up-form-item label="备注" prop="remark">
            <up-textarea v-model="form.remark" placeholder="请输入备注" auto-height />
          </up-form-item>
        </u-cell-group>
        <u-cell-group title="审批节点" class="form-section">
          <view class="section-tools">
            <up-button type="primary" size="small" text="新增节点" @click="addApproverNode" />
          </view>
          <view v-if="salespersonList.length === 0" class="empty-text">
            <text>暂无可选审批人,请检查用户数据</text>
          </view>
          <view class="node-list">
            <view v-for="(node, index) in approverNodes" :key="node.id" class="node-card">
              <view class="node-top">
                <text class="node-title">审批节点 {{ index + 1 }}</text>
                <up-icon
                  v-if="approverNodes.length > 1"
                  name="trash"
                  color="#ee0a24"
                  size="18"
                  @click="removeApproverNode(index)"
                ></up-icon>
              </view>
              <view class="picker-field" @click="openApproverPicker(index)">
                <up-input :model-value="node.nickName || ''" placeholder="请选择审批人" readonly disabled />
                <up-icon name="arrow-right" color="#909399" size="16"></up-icon>
              </view>
            </view>
          </view>
        </u-cell-group>
        <u-cell-group title="产品信息" class="form-section">
          <view class="section-tools">
            <up-button type="primary" size="small" text="新增产品" @click="addProduct" />
          </view>
          <view v-if="form.products.length === 0" class="empty-text">
            <text>暂无产品,请先添加产品</text>
          </view>
          <view v-else class="product-list">
            <view v-for="(product, index) in form.products" :key="product.uid" class="product-card">
              <view class="product-header">
                <text class="product-title">产品 {{ index + 1 }}</text>
                <up-icon name="trash" color="#ee0a24" size="18" @click="removeProduct(index)"></up-icon>
              </view>
              <up-divider></up-divider>
              <view class="product-body">
                <up-form-item label="产品名称">
                  <up-input
                    v-model="product.product"
                    placeholder="请选择产品"
                    readonly
                    @click="openProductPicker(index)"
                  />
                  <template #right>
                    <up-icon name="arrow-right" @click="openProductPicker(index)"></up-icon>
                  </template>
                </up-form-item>
                <up-form-item label="规格型号">
                  <up-input
                    v-model="product.specification"
                    placeholder="请选择规格型号"
                    readonly
                    @click="openModelPicker(index)"
                  />
                  <template #right>
                    <up-icon name="arrow-right" @click="openModelPicker(index)"></up-icon>
                  </template>
                </up-form-item>
                <up-form-item label="单位">
                  <up-input v-model="product.unit" placeholder="请输入单位" clearable />
                </up-form-item>
                <up-form-item label="数量">
                  <up-input
                    v-model="product.quantity"
                    type="number"
                    placeholder="请输入数量"
                    clearable
                    @blur="calculateAmount(product)"
                  />
                </up-form-item>
                <up-form-item label="单价">
                  <up-input
                    v-model="product.unitPrice"
                    type="number"
                    placeholder="请输入单价"
                    clearable
                    @blur="calculateAmount(product)"
                  />
                </up-form-item>
                <up-form-item label="金额">
                  <up-input :model-value="formatAmount(product.amount)" disabled placeholder="自动计算" />
                </up-form-item>
              </view>
            </view>
          </view>
        </u-cell-group>
        <u-cell-group title="汇总信息" class="form-section">
          <up-form-item label="报价总额">
            <up-input :model-value="formatAmount(totalAmount)" disabled placeholder="自动汇总" />
          </up-form-item>
        </u-cell-group>
      </up-form>
    </view>
    <FooterButtons :loading="loading" confirmText="保存" @cancel="goBack" @confirm="handleSubmit" />
    <up-action-sheet :show="showCustomerSheet" title="选择客户" :actions="customerActions" @select="onSelectCustomer" @close="showCustomerSheet = false" />
    <up-action-sheet :show="showSalespersonSheet" title="选择业务员" :actions="salespersonActions" @select="onSelectSalesperson" @close="showSalespersonSheet = false" />
    <up-action-sheet :show="showProductSheet" title="选择产品" :actions="productActions" @select="onSelectProduct" @close="showProductSheet = false" />
    <up-action-sheet :show="showModelSheet" title="选择规格型号" :actions="modelActions" @select="onSelectModel" @close="showModelSheet = false" />
    <up-datetime-picker :show="showQuotationDatePicker" v-model="quotationDateValue" mode="date" @confirm="onQuotationDateConfirm" @cancel="showQuotationDatePicker = false" />
    <up-datetime-picker :show="showValidDatePicker" v-model="validDateValue" mode="date" @confirm="onValidDateConfirm" @cancel="showValidDatePicker = false" />
  </view>
</template>
<script setup>
  import { computed, onMounted, onUnmounted, ref } from "vue";
  import { onLoad } from "@dcloudio/uni-app";
  import FooterButtons from "@/components/FooterButtons.vue";
  import PageHeader from "@/components/PageHeader.vue";
  import { formatDateToYMD } from "@/utils/ruoyi";
  import { modelList, productTreeList } from "@/api/basicData/product";
  import { userListNoPageByTenantId } from "@/api/system/user";
  import { addQuotation, getCustomerList, getQuotationDetail, updateQuotation } from "@/api/salesManagement/salesQuotation";
  const formRef = ref();
  const loading = ref(false);
  const quotationId = ref("");
  const showCustomerSheet = ref(false);
  const showSalespersonSheet = ref(false);
  const showProductSheet = ref(false);
  const showModelSheet = ref(false);
  const showQuotationDatePicker = ref(false);
  const showValidDatePicker = ref(false);
  const quotationDateValue = ref(Date.now());
  const validDateValue = ref(Date.now());
  const currentProductIndex = ref(-1);
  const customerList = ref([]);
  const salespersonList = ref([]);
  const productList = ref([]);
  const modelActions = ref([]);
  let uidSeed = 1;
  let nextApproverId = 2;
  const form = ref({
    id: undefined,
    quotationNo: "",
    customer: "",
    salesperson: "",
    quotationDate: "",
    validDate: "",
    paymentMethod: "",
    status: "待审批",
    remark: "",
    approveUserIds: "",
    products: [],
    totalAmount: 0,
  });
  const approverNodes = ref([{ id: 1, userId: "", nickName: "" }]);
  const rules = {
    customer: [{ required: true, message: "请选择客户", trigger: "change" }],
    salesperson: [{ required: true, message: "请选择业务员", trigger: "change" }],
    quotationDate: [{ required: true, message: "请选择报价日期", trigger: "change" }],
    validDate: [{ required: true, message: "请选择有效期", trigger: "change" }],
    paymentMethod: [{ required: true, message: "请输入付款方式", trigger: "blur" }],
  };
  const pageTitle = computed(() => (quotationId.value ? "编辑报价" : "新增报价"));
  const totalAmount = computed(() =>
    Number((form.value.products || []).reduce((sum, item) => sum + Number(item.amount || 0), 0).toFixed(2))
  );
  const customerActions = computed(() => customerList.value.map(item => ({ name: item.customerName, value: item.customerName })));
  const salespersonActions = computed(() => salespersonList.value.map(item => ({ name: item.nickName, value: item.nickName })));
  const productActions = computed(() => productList.value.map(item => ({ name: item.label, value: item.value, label: item.label })));
  const createEmptyProduct = () => ({
    uid: `p_${uidSeed++}`,
    productId: "",
    product: "",
    specificationId: "",
    specification: "",
    unit: "",
    quantity: 1,
    unitPrice: 0,
    amount: 0,
    modelOptions: [],
  });
  const flattenProductTree = nodes => {
    const result = [];
    const walk = list => {
      (list || []).forEach(item => {
        if (item.children && item.children.length) {
          walk(item.children);
        } else {
          result.push({ label: item.label || item.productName || "", value: item.id || item.value });
        }
      });
    };
    walk(nodes);
    return result;
  };
  const formatAmount = amount => `Â¥${Number(amount || 0).toFixed(2)}`;
  const goBack = () => uni.navigateBack();
  const calculateAmount = product => {
    product.amount = Number((Number(product.quantity || 0) * Number(product.unitPrice || 0)).toFixed(2));
    form.value.totalAmount = totalAmount.value;
  };
  const addApproverNode = () => approverNodes.value.push({ id: nextApproverId++, userId: "", nickName: "" });
  const removeApproverNode = index => approverNodes.value.splice(index, 1);
  const openApproverPicker = index => {
    uni.setStorageSync("stepIndex", index);
    uni.navigateTo({
      url: "/pages/cooperativeOffice/collaborativeApproval/contactSelect",
    });
  };
  const addProduct = () => form.value.products.push(createEmptyProduct());
  const removeProduct = index => {
    form.value.products.splice(index, 1);
    form.value.totalAmount = totalAmount.value;
  };
  const fetchModelOptions = async (productId, product) => {
    const rows = await modelList({ id: productId }).catch(() => []);
    product.modelOptions = Array.isArray(rows) ? rows : [];
  };
  const openProductPicker = index => {
    currentProductIndex.value = index;
    showProductSheet.value = true;
  };
  const openModelPicker = index => {
    currentProductIndex.value = index;
    const current = form.value.products[index];
    if (!current?.productId) {
      uni.showToast({ title: "请先选择产品", icon: "none" });
      return;
    }
    modelActions.value = (current.modelOptions || []).map(item => ({ name: item.model, value: item.id, unit: item.unit }));
    if (!modelActions.value.length) {
      uni.showToast({ title: "暂无规格型号", icon: "none" });
      return;
    }
    showModelSheet.value = true;
  };
  const onSelectCustomer = action => {
    form.value.customer = action.value;
    showCustomerSheet.value = false;
  };
  const onSelectSalesperson = action => {
    form.value.salesperson = action.value;
    showSalespersonSheet.value = false;
  };
  const onSelectApprover = data => {
    const { stepIndex, contact } = data || {};
    if (stepIndex === undefined || !contact) return;
    if (!approverNodes.value[stepIndex]) return;
    approverNodes.value[stepIndex].userId = contact.userId;
    approverNodes.value[stepIndex].nickName = contact.nickName;
  };
  const onSelectProduct = action => {
    const current = form.value.products[currentProductIndex.value];
    if (!current) return;
    current.productId = action.value;
    current.product = action.label;
    current.specificationId = "";
    current.specification = "";
    current.unit = "";
    current.modelOptions = [];
    showProductSheet.value = false;
    fetchModelOptions(action.value, current);
  };
  const onSelectModel = action => {
    const current = form.value.products[currentProductIndex.value];
    if (!current) return;
    current.specificationId = action.value;
    current.specification = action.name;
    current.unit = action.unit || current.unit;
    showModelSheet.value = false;
  };
  const onQuotationDateConfirm = e => {
    form.value.quotationDate = formatDateToYMD(e.value);
    showQuotationDatePicker.value = false;
  };
  const onValidDateConfirm = e => {
    form.value.validDate = formatDateToYMD(e.value);
    showValidDatePicker.value = false;
  };
  const fetchBaseOptions = async () => {
      const [customers, users, productTree] = await Promise.all([
        getCustomerList({ current: -1, size: -1 }).catch(() => ({})),
        userListNoPageByTenantId().catch(() => ({})),
        productTreeList().catch(() => []),
      ]);
    customerList.value = customers?.data?.records || customers?.records || [];
    const userRows = users?.data || [];
    salespersonList.value = Array.isArray(userRows) ? userRows : [];
    productList.value = flattenProductTree(Array.isArray(productTree) ? productTree : productTree?.data || []);
  };
  const normalizeProductRows = async rows => {
    const normalized = await Promise.all((Array.isArray(rows) ? rows : []).map(async item => {
      const row = {
        uid: `p_${uidSeed++}`,
        productId: item.productId || "",
        product: item.product || item.productName || "",
        specificationId: item.specificationId || "",
        specification: item.specification || "",
        unit: item.unit || "",
        quantity: Number(item.quantity || 1),
        unitPrice: Number(item.unitPrice || 0),
        amount: Number(item.amount || 0),
        modelOptions: [],
      };
      if (row.productId) await fetchModelOptions(row.productId, row);
      return row;
    }));
    form.value.products = normalized;
  };
  const loadDetail = async () => {
    if (!quotationId.value) return;
    uni.showLoading({ title: "加载中...", mask: true });
    try {
      const res = await getQuotationDetail({ id: quotationId.value });
      const data = res?.data || {};
      form.value = {
        ...form.value,
        id: data.id,
        quotationNo: data.quotationNo || "",
        customer: data.customer || "",
        salesperson: data.salesperson || "",
        quotationDate: data.quotationDate || "",
        validDate: data.validDate || "",
        paymentMethod: data.paymentMethod || "",
        status: data.status || "待审批",
        remark: data.remark || "",
      };
      await normalizeProductRows(data.products || []);
      if (data.approveUserIds) {
        const ids = String(data.approveUserIds).split(",").map(item => item.trim()).filter(Boolean);
        approverNodes.value = ids.map((userId, index) => ({
          id: index + 1,
          userId,
          nickName: salespersonList.value.find(item => String(item.userId) === String(userId))?.nickName || "",
        }));
        nextApproverId = approverNodes.value.length + 1;
      }
      form.value.totalAmount = totalAmount.value;
    } catch {
      uni.showToast({ title: "获取详情失败", icon: "error" });
    } finally {
      uni.hideLoading();
    }
  };
  const validateProducts = () => {
    if (!form.value.products.length) {
      uni.showToast({ title: "请至少添加一个产品", icon: "none" });
      return false;
    }
    const invalid = form.value.products.some(item => !item.productId || !item.specificationId || !item.unit || !Number(item.quantity) || !Number(item.unitPrice));
    if (invalid) {
      uni.showToast({ title: "请完善产品信息", icon: "none" });
      return false;
    }
    return true;
  };
  const validateApprovers = () => {
    if (approverNodes.value.some(item => !item.userId)) {
      uni.showToast({ title: "请选择审批人", icon: "none" });
      return false;
    }
    return true;
  };
  const handleSubmit = async () => {
    const valid = await formRef.value.validate().catch(() => false);
    if (!valid || !validateApprovers() || !validateProducts()) return;
    loading.value = true;
    const payload = {
      ...form.value,
      approveUserIds: approverNodes.value.map(item => item.userId).join(","),
      totalAmount: totalAmount.value,
      products: form.value.products.map(item => ({
        productId: item.productId,
        product: item.product,
        specificationId: item.specificationId,
        specification: item.specification,
        quantity: Number(item.quantity || 0),
        unit: item.unit,
        unitPrice: Number(item.unitPrice || 0),
        amount: Number(item.amount || 0),
      })),
    };
    const action = quotationId.value ? updateQuotation : addQuotation;
    action(payload)
      .then(() => {
        uni.showToast({ title: "保存成功", icon: "success" });
        setTimeout(() => uni.navigateBack(), 300);
      })
      .catch(() => {
        uni.showToast({ title: "保存失败", icon: "error" });
      })
      .finally(() => {
        loading.value = false;
      });
  };
  onLoad(options => {
    if (options?.id) {
      quotationId.value = options.id;
      form.value.id = options.id;
    } else {
      const today = formatDateToYMD(Date.now());
      form.value.quotationDate = today;
      form.value.validDate = today;
    }
  });
  onMounted(async () => {
    await fetchBaseOptions();
    uni.$on("selectContact", onSelectApprover);
    if (quotationId.value) {
      await loadDetail();
    }
  });
  onUnmounted(() => {
    uni.$off("selectContact", onSelectApprover);
    uni.removeStorageSync("stepIndex");
  });
</script>
<style scoped lang="scss">
  @import "@/static/scss/form-common.scss";
  .account-detail {
    min-height: 100vh;
    background: #f8f9fa;
    padding-bottom: 100px;
  }
  .form-container {
    padding: 12px 12px 0;
  }
  .hero-card {
    margin-bottom: 12px;
    padding: 18px 18px 16px;
    border-radius: 16px;
    background: linear-gradient(135deg, #eef6ff 0%, #ffffff 100%);
    box-shadow: 0 6px 18px rgba(41, 121, 255, 0.08);
  }
  .hero-title {
    display: block;
    font-size: 18px;
    font-weight: 600;
    color: #1f2d3d;
    margin-bottom: 6px;
  }
  .hero-desc {
    display: block;
    font-size: 13px;
    line-height: 1.6;
    color: #7a8599;
  }
  .form-section {
    margin-bottom: 12px;
    border-radius: 12px;
    overflow: hidden;
    box-shadow: 0 2px 10px rgba(15, 35, 95, 0.05);
  }
  .section-tools {
    display: flex;
    justify-content: flex-end;
    padding: 12px 12px 0;
  }
  .node-list,
  .product-list {
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 12px;
  }
  .node-card {
    background: #f8fbff;
    border-radius: 12px;
    padding: 12px;
    border: 1px solid #e6eef8;
  }
  .picker-field {
    display: flex;
    align-items: center;
    gap: 8px;
  }
  .picker-field :deep(.u-input) {
    flex: 1;
  }
  .node-top,
  .product-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
  }
  .node-title,
  .product-title {
    font-size: 14px;
    font-weight: 600;
    color: #22324d;
  }
  .product-card {
    background: #fff;
    border-radius: 12px;
    padding: 0 12px 12px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
  }
  .product-header {
    padding: 12px 0;
  }
  .empty-text {
    padding: 16px 12px;
    color: #999;
    font-size: 14px;
  }
  :deep(.u-cell-group__title) {
    padding: 14px 18px 10px !important;
    font-size: 15px !important;
    font-weight: 600 !important;
    color: #22324d !important;
    background: #f8fbff !important;
  }
</style>
src/pages/sales/salesQuotation/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,226 @@
<template>
  <view class="sales-account">
    <PageHeader title="销售报价" @back="goBack" />
    <view class="search-section">
      <view class="search-bar">
        <view class="search-input">
          <up-input
            class="search-text"
            v-model="quotationNo"
            placeholder="请输入报价单号搜索"
            clearable
            @change="getList"
          />
        </view>
        <view class="filter-button" @click="getList">
          <up-icon name="search" size="24" color="#999"></up-icon>
        </view>
      </view>
    </view>
    <view class="tabs-section">
      <up-tabs
        v-model="tabValue"
        :list="tabList"
        itemStyle="width: 20%;height: 80rpx;"
        @change="onTabChange"
      />
    </view>
    <view v-if="quotationList.length > 0" class="ledger-list">
      <view v-for="item in quotationList" :key="item.id" class="ledger-item">
        <view class="item-header">
          <view class="item-left">
            <view class="document-icon">
              <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
            </view>
            <text class="item-id">{{ item.quotationNo || "-" }}</text>
          </view>
          <text class="item-index">{{ item.status || "-" }}</text>
        </view>
        <up-divider></up-divider>
        <view class="item-details">
          <view class="detail-row">
            <text class="detail-label">客户名称</text>
            <text class="detail-value">{{ item.customer || "-" }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">业务员</text>
            <text class="detail-value">{{ item.salesperson || "-" }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">报价日期</text>
            <text class="detail-value">{{ item.quotationDate || "-" }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">有效期至</text>
            <text class="detail-value">{{ item.validDate || "-" }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">付款方式</text>
            <text class="detail-value">{{ item.paymentMethod || "-" }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">报价金额</text>
            <text class="detail-value highlight">{{ formatAmount(item.totalAmount) }}</text>
          </view>
          <view class="detail-row">
            <text class="detail-label">备注</text>
            <text class="detail-value">{{ item.remark || "-" }}</text>
          </view>
        </view>
        <view class="action-buttons">
                    <up-button
                        class="action-btn"
                size="small"
                type="primary"
                :disabled="!canEdit(item)"
                @click="goEdit(item)"
                    >
                        ç¼–辑
                    </up-button>
          <up-button class="action-btn" size="small" @click="goDetail(item)">详情</up-button>
          <up-button class="action-btn" size="small" type="error" plain @click="handleDelete(item)">
            åˆ é™¤
          </up-button>
        </view>
      </view>
    </view>
    <view v-else class="no-data">
      <text>暂无销售报价数据</text>
    </view>
    <view class="fab-button" @click="goAdd">
      <up-icon name="plus" size="28" color="#ffffff"></up-icon>
    </view>
  </view>
</template>
<script setup>
  import { reactive, ref } from "vue";
  import { onShow } from "@dcloudio/uni-app";
  import PageHeader from "@/components/PageHeader.vue";
  import { deleteQuotation, getQuotationList } from "@/api/salesManagement/salesQuotation";
  const quotationNo = ref("");
  const quotationList = ref([]);
  const tabList = reactive([
    { name: "全部", value: "" },
    { name: "待审批", value: "待审批" },
    { name: "审核中", value: "审核中" },
    { name: "通过", value: "通过" },
    { name: "拒绝", value: "拒绝" },
  ]);
  const tabValue = ref(0);
  const page = {
    current: -1,
    size: -1,
  };
  const goBack = () => {
    uni.navigateBack();
  };
  const goAdd = () => {
    uni.navigateTo({ url: "/pages/sales/salesQuotation/edit" });
  };
  const goEdit = item => {
    if (!canEdit(item)) return;
    uni.navigateTo({ url: `/pages/sales/salesQuotation/edit?id=${item.id}` });
  };
  const goDetail = item => {
    uni.setStorageSync("salesQuotationDetail", item || {});
    uni.navigateTo({ url: `/pages/sales/salesQuotation/detail?id=${item.id}` });
  };
  const canEdit = item => ["待审批", "拒绝"].includes(item?.status);
  const onTabChange = val => {
    tabValue.value = val.index;
    getList();
  };
  const getCurrentStatus = () => {
    const currentTab = tabList[tabValue.value];
    return currentTab?.value || "";
  };
  const formatAmount = amount => {
    const num = Number(amount || 0);
    return `Â¥${num.toFixed(2)}`;
  };
  const getList = () => {
    uni.showLoading({ title: "加载中...", mask: true });
    getQuotationList({
      ...page,
      quotationNo: quotationNo.value,
      status: getCurrentStatus(),
    })
      .then(res => {
        const records = res?.data?.records || res?.records || [];
        quotationList.value = Array.isArray(records) ? records : [];
      })
      .catch(() => {
        uni.showToast({ title: "查询失败", icon: "error" });
      })
      .finally(() => {
        uni.hideLoading();
      });
  };
  const handleDelete = item => {
    if (!item?.id) return;
    uni.showModal({
      title: "删除确认",
      content: "确认删除该报价单吗?",
      success: res => {
        if (!res.confirm) return;
        uni.showLoading({ title: "处理中...", mask: true });
        deleteQuotation(item.id)
          .then(() => {
            uni.showToast({ title: "删除成功", icon: "success" });
            getList();
          })
          .catch(() => {
            uni.showToast({ title: "删除失败", icon: "error" });
          })
          .finally(() => {
            uni.hideLoading();
          });
      },
    });
  };
  onShow(() => {
    getList();
  });
</script>
<style scoped lang="scss">
  @import "@/styles/sales-common.scss";
  .tabs-section {
    background: #ffffff;
    padding: 0 12px 8px 12px;
  }
  .item-index {
    max-width: 180rpx;
    text-align: center;
  }
  .detail-value {
    max-width: 70%;
    word-break: break-all;
  }
</style>
src/pages/works.vue
@@ -303,6 +303,14 @@
  // è¥é”€ç®¡ç†åŠŸèƒ½æ•°æ®
  const marketingItems = reactive([
    {
      icon: "/static/images/icon/kehudangan.svg",
      label: "客户档案",
    },
    {
      icon: "/static/images/icon/xiaoshoubaojia.svg",
      label: "销售报价",
    },
    {
      icon: "/static/images/icon/xiaoshoutaizhang.svg",
      label: "销售台账",
    },
@@ -363,15 +371,15 @@
      label: "付款流水",
    },
    {
      icon: "/static/images/icon/huikuandengji.svg",
      icon: "/static/images/icon/shouruguanli.svg",
      label: "收入管理",
    },
    {
      icon: "/static/images/icon/fukuandengji.svg",
      icon: "/static/images/icon/zhichuguanli.svg",
      label: "支出管理",
    },
    {
      icon: "/static/images/icon/huikuanliushui.svg",
      icon: "/static/images/icon/jiekuanguanli.svg",
      label: "借款管理",
    },
  ]);
@@ -379,7 +387,7 @@
  // æ¡£æ¡ˆç®¡ç†åŠŸèƒ½æ•°æ®
  const archiveManagementItems = reactive([
    {
      icon: "/static/images/icon/gongchuguanli.svg",
      icon: "/static/images/icon/gongyingshangdangan.svg",
      label: "供应商档案",
    },
  ]);
@@ -387,11 +395,11 @@
  // å”®åŽæœåŠ¡åŠŸèƒ½æ•°æ®
  const afterSalesServiceItems = reactive([
    {
      icon: "/static/images/icon/xiaoshoutaizhang.svg",
      icon: "/static/images/icon/fankuidengji.svg",
      label: "反馈登记",
    },
    {
      icon: "/static/images/icon/caigouguanli.svg",
      icon: "/static/images/icon/shouhouchuli.svg",
      label: "售后处理",
    },
  ]);
@@ -554,11 +562,21 @@
  const handleCommonItemClick = item => {
    // æ ¹æ®ä¸åŒçš„功能项进行跳转
    switch (item.label) {
      case "客户档案":
        uni.navigateTo({
          url: "/pages/basicData/customerFile/index",
        });
        break;
      case "销售台账":
        uni.navigateTo({
          url: "/pages/sales/salesAccount/index",
        });
        break;
      case "销售报价":
        uni.navigateTo({
          url: "/pages/sales/salesQuotation/index",
        });
        break;
      case "开票登记":
        uni.navigateTo({
          url: "/pages/sales/invoicingRegistration/index",
src/static/images/icon/fahuotaizhang.svg
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="28" height="28" viewBox="0 0 28 28"><defs><clipPath id="master_svg0_134_35410"><rect x="0" y="0" width="28" height="28" rx="0"/></clipPath><clipPath id="master_svg1_134_35452"><rect x="8" y="7" width="16" height="16" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_134_35410)"><g transform="matrix(0,1.0000003576278687,-1.0000003576278687,0,29.00000089406967,-24.00000947713852)"><path d="M33.103223299999996,27.5C31.7891606,27.5,30.83216852,28.7456321,31.17075348,30.0153255L31.7081735,32.0306506C32.1751106,33.7816644,33.76091,35,35.5731134,35L41.426888,35C43.239091,35,44.824889,33.7816644,45.291826,32.0306506L45.829247,30.0153253C46.167831,28.7456321,45.210839,27.5,43.896776,27.5L33.103223299999996,27.5Z" fill="#69FFB4" fill-opacity="1" transform="matrix(1,0,0,-1,0,55)"/><path d="M26.5,17.999999000000003C26.5,21.313709,29.186291699999998,24,32.5000005,24L44.5,24C47.813709,24,50.5,21.313709,50.5,18L50.5,8.500001000000001C50.5,5.1862917,47.813709,2.5,44.5,2.5L32.500001,2.5C29.186291699999998,2.5,26.5,5.1862917,26.5,8.500001000000001L26.5,17.999999000000003Z" fill="#01BF34" fill-opacity="1" style="opacity:0.800000011920929;"/></g><g clip-path="url(#master_svg1_134_35452)"><path d="M10.92792578125,8.10400402545929Q11.37592578125,8.10400402545929,11.68792578125,8.40800404625Q11.99992588125,8.71200406625,11.99992588125,9.160003906250001L11.99992588125,9.97600390625Q11.99992588125,10.42400380625,11.68792578125,10.73600390625Q11.37592578125,11.048003906249999,10.92792578125,11.048003906249999L10.079925781250001,11.048003906249999Q9.64792573125,11.048003906249999,9.33592582125,10.73600390625Q9.02392590045929,10.42400380625,9.02392578125,9.97600390625L9.02392578125,9.160003906250001Q9.02392578125,8.71200394625,9.33592582125,8.40800392625Q9.64792585125,8.10400390625,10.079925781250001,8.10400390625L10.92792578125,8.10400402545929ZM21.903925781250003,8.10400402545929Q22.335925781249998,8.10400402545929,22.64792678125,8.40800404625Q22.959926781249997,8.71200406625,22.959926781249997,9.160003906250001L22.959926781249997,9.97600390625Q22.959926781249997,10.42400380625,22.64792678125,10.73600390625Q22.335925781249998,11.048003906249999,21.903925781250003,11.048003906249999L15.07192608125,11.048003906249999Q14.623926181249999,11.048003906249999,14.31192588125,10.73600390625Q13.99992558125,10.42400380625,13.99992658125,9.97600390625L13.99992658125,9.160003906250001Q13.99992658125,8.71200394625,14.31192588125,8.40800392625Q14.623926181249999,8.10400390625,15.07192608125,8.10400390625L21.903925781250003,8.10400402545929ZM10.92792578125,13.08000370625Q11.37592578125,13.08000370625,11.68792578125,13.39200400625Q11.99992588125,13.70400330625,11.99992588125,14.15200330625L11.99992588125,14.96800330625Q11.99992588125,15.40000340625,11.68792578125,15.71200370625Q11.37592578125,16.02400400625,10.92792578125,16.02400400625L10.079925781250001,16.02400400625Q9.64792573125,16.02400400625,9.33592582125,15.71200370625Q9.02392590045929,15.40000340625,9.02392578125,14.96800420625L9.02392578125,14.15200420625Q9.02392578125,13.704004306249999,9.33592582125,13.39200400625Q9.64792585125,13.08000470625,10.079925781250001,13.08000470625L10.92792578125,13.08000370625ZM21.903925781250003,13.08000370625Q22.335925781249998,13.08000370625,22.64792678125,13.39200400625Q22.959926781249997,13.70400330625,22.959926781249997,14.15200330625L22.959926781249997,14.96800330625Q22.959926781249997,15.40000340625,22.64792678125,15.71200370625Q22.335925781249998,16.02400400625,21.903925781250003,16.02400400625L15.07192608125,16.02400400625Q14.623926181249999,16.02400400625,14.31192588125,15.71200370625Q13.99992558125,15.40000340625,13.99992658125,14.96800420625L13.99992658125,14.15200420625Q13.99992658125,13.704004306249999,14.31192588125,13.39200400625Q14.623926181249999,13.08000470625,15.07192608125,13.08000470625L21.903925781250003,13.08000370625ZM10.92792578125,18.072003406249998Q11.37592578125,18.072003406249998,11.68792578125,18.38400390625Q11.99992588125,18.69600390625,11.99992588125,19.12800390625L11.99992588125,19.94400390625Q11.99992588125,20.39200390625,11.68792578125,20.70400390625Q11.37592578125,21.01600490625,10.92792578125,21.01600490625L10.079925781250001,21.01600490625Q9.64792573125,21.01600490625,9.33592582125,20.70400390625Q9.02392590045929,20.39200390625,9.02392578125,19.94400390625L9.02392578125,19.12800390625Q9.02392578125,18.69600390625,9.33592582125,18.38400390625Q9.64792585125,18.072003406249998,10.079925781250001,18.072003406249998L10.92792578125,18.072003406249998ZM21.903925781250003,18.072003406249998Q22.335925781249998,18.072003406249998,22.64792678125,18.38400390625Q22.959926781249997,18.69600390625,22.959926781249997,19.12800390625L22.959926781249997,19.94400390625Q22.959926781249997,20.39200390625,22.64792678125,20.70400390625Q22.335925781249998,21.01600490625,21.903925781250003,21.01600490625L15.07192608125,21.01600490625Q14.623926181249999,21.01600490625,14.31192588125,20.70400390625Q13.99992558125,20.39200390625,13.99992658125,19.94400390625L13.99992658125,19.12800390625Q13.99992658125,18.69600390625,14.31192588125,18.38400390625Q14.623926181249999,18.072003406249998,15.07192608125,18.072003406249998L21.903925781250003,18.072003406249998Z" fill="#FFFFFF" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>
src/static/images/icon/fankuidengji.svg
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="28" height="28" viewBox="0 0 28 28"><defs><clipPath id="master_svg0_134_34195"><rect x="0" y="0" width="28" height="28" rx="0"/></clipPath><clipPath id="master_svg1_134_35466"><rect x="8" y="7" width="12" height="12" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_134_34195)"><path d="M8.6032233,27C7.2891606,27,6.33216852,28.2456321,6.67075348,29.5153255L7.2081735,31.5306506C7.6751106,33.2816644,9.260909999999999,34.5,11.0731134,34.5L16.926887999999998,34.5C18.739091000000002,34.5,20.324889,33.2816644,20.791826,31.5306506L21.329247000000002,29.5153253C21.667831,28.2456321,20.710839,27,19.396776,27L8.6032233,27Z" fill="#FC99E5" fill-opacity="1" transform="matrix(1,0,0,-1,0,54)"/><path d="M2,17.499999000000003C2,20.813709,4.6862917,23.5,8.000000499999999,23.5L20,23.5C23.313709,23.5,26,20.813709,26,17.5L26,8.000001000000001C26,4.6862917,23.313709,2,20,2L8.000001000000001,2C4.6862917,2,2,4.6862917,2,8.000001000000001L2,17.499999000000003Z" fill="#6234F9" fill-opacity="1" style="opacity:0.800000011920929;"/><g clip-path="url(#master_svg1_134_35466)"><path d="M19.462062921875003,10.66726826875C18.863719921875,9.23552536875,17.732207321875002,8.09247156875,16.306608221875003,7.47963204875C14.831631221875,6.85509655875,13.166494821875,6.85509655875,11.691517321875,7.47963204875C10.986121921875,7.78120278875,10.346071021875,8.21701176875,9.806971821874999,8.76281396875C8.691300691875,9.89005426875,8.067200656975,11.41309356875,8.071062551813,12.99908686875C8.066570594475,15.39721776875,9.490492721875,17.56768846875,11.692063121875,18.51854246875C12.421584121875,18.829822468750002,13.206726521875,18.98968946875,13.999881221875,18.988450468750003C15.575773721874999,18.990966468750003,17.086290321874998,18.358783468749998,18.190608921875,17.234540468749998C18.734426921875,16.689084968750002,19.166427921874998,16.042722668750002,19.461789921875003,15.33144946875C20.084089921874998,13.83901166875,20.084188921875,12.15977766875,19.462062921875003,10.66726826875ZM16.341790221875,10.696450468750001C16.802152621875003,10.696450468750001,17.177152621875003,11.076086968750001,17.177152621875003,11.543813668750001C17.177152621875003,12.009359368750001,16.802152621875003,12.388995668749999,16.341790221875,12.388995668749999C15.880062621875,12.388995668749999,15.503426521875,12.009359368750001,15.503426521875,11.543813668750001C15.503426521875,11.075813768749999,15.880063021875,10.696450468750001,16.341790221875,10.696450468750001ZM11.659062421875,10.68063206875C12.121062321875,10.68063206875,12.497698821875,11.06026836875,12.497698821875,11.52663186875C12.497698821875,11.99299526875,12.121062321875,12.37263246875,11.659062421875,12.37263246875C11.193299521875,12.37160016875,10.817726121875,11.99100396875,10.822880721875,11.52526856875C10.823153521875,11.05945066875,11.197335721875,10.68063206875,11.659062421875,10.68063206875ZM17.113608321875,14.87217716875C16.760999721875002,15.34876826875,16.302616121874998,15.73703956875,15.774517021874999,16.00645066875C14.658683321875,16.57262996875,13.339714021875,16.57262996875,12.223880721875,16.00645066875C11.696393921875,15.73727986875,11.238638921875,15.34926506875,10.886698721875,14.87299636875C10.748108121875,14.68586586875,10.786201721874999,14.42201086875,10.972062621875,14.28172346875C11.159629321875,14.14738466875,11.420016721875001,14.186532068750001,11.559789421875,14.37008666875C12.120516821875,15.13072396875,13.033607521875,15.58372306875,14.000153521875,15.58372306875C14.966698621875,15.58372306875,15.880062621875,15.13072396875,16.441607521875,14.36872286875C16.581712721875,14.18624876875,16.841334321875,14.14786576875,17.028245021875,14.28199576875C17.212062821875,14.42272376875,17.249971421875,14.68481346875,17.113608321875,14.87217716875Z" fill="#FFFFFF" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>
src/static/images/icon/gongyingshangdangan.svg
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="28" height="28" viewBox="0 0 28 28"><defs><clipPath id="master_svg0_134_34630"><rect x="0" y="0" width="28" height="28" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_134_34630)"><path d="M6,13.9999995C6,16.2091389,7.7908611,18,10,18L18,18C20.209139,18,22,16.2091389,22,13.9999995L22,13.0000005C22,11.3431458,20.656855,10,19,10L9.0000005,10C7.3431458,10,6,11.3431458,6,13.0000005L6,13.9999995Z" fill="#9CEED2" fill-opacity="1" transform="matrix(1,0,0,-1,0,20)"/><path d="M1,19.681812L1,21.5Q1,21.647291,1.007227262,21.794406000000002Q1.014454524,21.941521,1.028891638,22.088102Q1.043328751,22.234684,1.064940929,22.380381Q1.086553112,22.526077,1.1152883,22.67054Q1.14402349,22.815001,1.17981246,22.957878Q1.21560144,23.100756,1.25835797,23.241707Q1.3011145,23.382656,1.3507355699999999,23.521336Q1.40035665,23.660017,1.45672277,23.796097Q1.51308888,23.932177,1.57606423,24.065327Q1.63903958,24.198479,1.70847243,24.328379Q1.77790529,24.458279,1.8536283999999998,24.584614Q1.92935145,24.710951,2.0111822999999998,24.83342Q2.0930133,24.955889,2.1807548,25.074196Q2.2684964,25.192501,2.3619373,25.30636Q2.4553782,25.420219,2.5542932,25.529354Q2.6532083,25.638489,2.7573593,25.74264Q2.8615103,25.84679,2.9706460999999997,25.945705Q3.079782,26.044621,3.1936402,26.138062Q3.307498,26.231503,3.4258039,26.319244Q3.5441098,26.406986,3.6665783,26.488815Q3.789047,26.570644,3.9153833,26.646368Q4.0417199,26.722092,4.1716199,26.791527Q4.3015194,26.86096,4.4346695,26.923935Q4.5678196,26.98691,4.7038991,27.043276Q4.8399789,27.099642,4.9786605999999995,27.149265Q5.117342,27.198887,5.2582917,27.241644Q5.399241,27.284401,5.5421185,27.320189Q5.6849961,27.355976,5.8294578,27.384712Q5.9739189,27.413448,6.1196165,27.435062Q6.2653141,27.456673,6.4118967,27.471111Q6.5584793,27.485546,6.7055931,27.492773Q6.8527079,27.5,7,27.5L21,27.5Q21.147291,27.5,21.294405,27.492775Q21.441521,27.485546,21.588104,27.471111Q21.734686,27.456673,21.880383,27.435061Q22.026079,27.413448,22.17054,27.384712Q22.315002,27.355976,22.457878,27.320187Q22.600758,27.284401,22.741707,27.241644Q22.882656,27.198887,23.021336,27.149263Q23.160017,27.099642,23.296097,27.043276Q23.432177,26.98691,23.565327,26.923935Q23.698479,26.86096,23.828379,26.791527Q23.958279,26.722092,24.084614,26.646368Q24.210949,26.570644,24.333418,26.488815Q24.455887,26.406986,24.574194,26.319244Q24.692501,26.231503,24.806358,26.138063Q24.920216,26.044621,25.029352,25.945705Q25.138489,25.84679,25.24264,25.74264Q25.34679,25.638489,25.445705,25.529354Q25.544621,25.420218,25.638063,25.306358Q25.731503,25.192501,25.819244,25.074194Q25.906986,24.955887,25.988815,24.833418Q26.070646,24.710949,26.14637,24.584614Q26.222094,24.458279,26.291527,24.328379Q26.360958,24.198479,26.423935,24.065327Q26.486908,23.932177,26.543274,23.796097Q26.59964,23.660017,26.649261,23.521336Q26.698883,23.382656,26.74164,23.241707Q26.784397,23.100756,26.820185,22.957878Q26.855972,22.815001,26.884708,22.67054Q26.913445,22.526077,26.935059,22.380383Q26.956671,22.234684,26.971109,22.088102Q26.985546,21.941521,26.992775,21.794404999999998Q27,21.647291,27,21.5L27,19.678486Q26.926178,19.681812,26.852272,19.681812Q26.699867,19.681812,26.548197,19.667695000000002Q26.396526,19.653578,26.247047,19.625477Q26.097572,19.59738,25.951731,19.555569Q25.805889,19.513759,25.665081,19.458638999999998Q25.524281,19.403522000000002,25.38987,19.335625999999998Q25.255463,19.267730999999998,25.128742,19.18771Q25.002022,19.107692,24.884212,19.016319Q24.766399,18.924948,24.658632,18.823102Q24.550867,18.721256,24.454182,18.609918999999998Q24.357498,18.498582,24.272823,18.378824Q24.188154,18.259068,24.11631,18.132044Q24.044468,18.005020000000002,23.986145,17.871952Q23.927822,17.738886,23.883583,17.601056Q23.839342,17.463227,23.809608,17.321963Q23.779877,17.1807,23.76494,17.037363Q23.75,16.894026,23.75,16.749994Q23.75,16.605964999999998,23.76494,16.462626Q23.779877,16.319288,23.809608,16.178024Q23.839342,16.036761,23.883583,15.8989325Q23.927822,15.7611027,23.986145,15.6280355Q24.044468,15.4949684,24.116312,15.3679447Q24.188154,15.240921,24.272823,15.1211624Q24.357498,15.0014057,24.454182,14.8900681Q24.550867,14.7787313,24.658632,14.6768856Q24.766399,14.5750408,24.884211,14.4836693Q25.002022,14.3922958,25.12874,14.3122768Q25.255463,14.2322578,25.38987,14.164362Q25.524281,14.0964661,25.665083,14.0413475Q25.805889,13.9862299,25.951733,13.9444199Q26.097572,13.9026098,26.247047,13.8745103Q26.396526,13.8464117,26.548197,13.832294000000001Q26.699867,13.8181767,26.852272,13.818176300000001Q26.926178,13.818176300000001,27,13.821502200000001L27,12Q27,11.8527079,26.992771,11.7055931Q26.985546,11.5584793,26.971109,11.4118967Q26.956671,11.265314100000001,26.935057,11.1196165Q26.913445,10.973918900000001,26.884708,10.8294573Q26.855972,10.6849957,26.820187,10.5421181Q26.784397,10.399241,26.741642,10.258291700000001Q26.698883,10.117342,26.649261,9.9786606Q26.59964,9.8399789,26.543274,9.703899100000001Q26.486908,9.5678196,26.423931,9.4346693Q26.360958,9.3015192,26.291525,9.1716194Q26.222092,9.0417197,26.14637,8.9153833Q26.070646,8.789047,25.988815,8.6665783Q25.906986,8.544109800000001,25.819244,8.4258039Q25.731503,8.307497999999999,25.638062,8.1936402Q25.544621,8.079782,25.445705,7.9706461Q25.34679,7.8615103,25.24264,7.7573593Q25.138489,7.6532083,25.029352,7.5542933Q24.920216,7.4553782,24.806358,7.3619373Q24.692501,7.2684963,24.574194,7.1807548Q24.455887,7.093013,24.333418,7.0111822Q24.210949,6.92935133,24.084614,6.85362822Q23.958279,6.77790523,23.828379,6.70847237Q23.698479,6.63903952,23.565327,6.57606423Q23.432177,6.51308888,23.296097,6.45672277Q23.160017,6.40035665,23.021336,6.3507356Q22.882656,6.3011145,22.741707,6.25835797Q22.600758,6.21560144,22.457878,6.17981246Q22.315002,6.14402349,22.17054,6.1152883Q22.026079,6.086553112,21.880383,6.064940937Q21.734686,6.043328751,21.588104,6.028891638Q21.441521,6.014454524,21.294407,6.007227262Q21.147291,6,21,6L7,6Q6.8527079,6,6.7055931,6.007227262Q6.5584793,6.014454524,6.4118967,6.028891638Q6.2653141,6.043328751,6.1196165,6.064940929Q5.9739189,6.086553112,5.8294573,6.1152883Q5.6849957,6.14402349,5.5421181,6.17981246Q5.399241,6.21560144,5.2582917,6.25835797Q5.117342,6.3011145,4.9786605999999995,6.35073557Q4.8399789,6.40035665,4.7038991,6.45672277Q4.5678196,6.51308888,4.4346692999999995,6.57606423Q4.3015191999999995,6.63903958,4.1716194,6.7084724300000005Q4.0417197,6.77790529,3.9153833,6.8536284Q3.789047,6.92935145,3.6665783,7.0111823Q3.5441098,7.0930133,3.4258039,7.1807548Q3.307498,7.2684964,3.1936402,7.3619373Q3.079782,7.4553782,2.9706460999999997,7.5542932Q2.8615103,7.6532083,2.7573593,7.7573593Q2.6532083,7.8615103,2.5542933000000003,7.9706461Q2.4553782,8.079782,2.3619373,8.1936402Q2.2684963,8.307497999999999,2.1807548,8.4258039Q2.093013,8.544109800000001,2.0111822,8.6665783Q1.92935133,8.789047,1.85362822,8.9153833Q1.77790523,9.0417199,1.70847237,9.1716199Q1.6390395199999999,9.3015194,1.57606423,9.4346695Q1.51308888,9.5678196,1.45672277,9.703899100000001Q1.40035665,9.8399789,1.3507356,9.9786606Q1.3011145,10.117342,1.25835797,10.258291700000001Q1.21560144,10.399241,1.17981246,10.5421185Q1.14402349,10.6849961,1.1152883,10.8294578Q1.086553112,10.973918900000001,1.064940937,11.1196165Q1.043328751,11.265314100000001,1.028891638,11.4118967Q1.014454524,11.5584793,1.007227262,11.7055931Q1,11.8527079,1,12L1,13.818176300000001L1.0000081062317,13.818176300000001Q1.15241298,13.8181767,1.30408397,13.8322945Q1.455755,13.8464117,1.6052314,13.8745103Q1.7547078699999998,13.9026098,1.90055025,13.944419400000001Q2.0463926,13.9862294,2.1871963,14.0413465Q2.3280000999999997,14.0964661,2.4624091,14.164361Q2.5968182,14.2322569,2.7235382,14.3122759Q2.8502584,14.3922958,2.968069,14.4836683Q3.0858796,14.5750408,3.193646,14.6768856Q3.3014126,14.7787313,3.3980973,14.890069Q3.494782,15.0014057,3.5794535,15.1211624Q3.6641252,15.2409201,3.7359684,15.3679438Q3.8078115,15.4949684,3.8661342,15.6280346Q3.9244571,15.7611027,3.968698,15.8989315Q4.012938699999999,16.036761,4.0426712,16.178024Q4.0724041,16.319288,4.0873425,16.462626Q4.1022806,16.605964999999998,4.1022806,16.749994Q4.1022806,16.894026,4.0873422999999995,17.037363Q4.0724041,17.1807,4.0426712,17.321963Q4.012938500000001,17.463227,3.9686975,17.601056Q3.9244566,17.738886,3.8661335,17.871952Q3.8078105,18.005020000000002,3.7359672,18.132044Q3.6641238,18.259068,3.5794518,18.378824Q3.4947801,18.498582,3.3980951,18.609918999999998Q3.3014104,18.721256,3.1936436,18.823102Q3.0858769,18.924948,2.9680660000000003,19.01632Q2.8502549999999998,19.107692,2.7235346,19.18771Q2.5968144,19.267730999999998,2.462405,19.335627000000002Q2.3279954,19.403522000000002,2.1871912,19.458640000000003Q2.0463872,19.513759999999998,1.90054452,19.55557Q1.7547017299999998,19.59738,1.60522485,19.625478Q1.45574808,19.653578,1.30407667,19.667695000000002Q1.15240528,19.681812,1,19.681812Z" fill-rule="evenodd" fill="#009B8B" fill-opacity="1" style="opacity:0.800000011920929;"/><path d="M7,20.7639999Q7,21.4919996,7.50400019,21.9960012Q8.0080004,22.5,8.7360005,22.5L19.235999,22.5Q19.964,22.5,20.467999,21.9960012Q20.972001,21.4919996,20.972001,20.7639999Q20.972001,20.0360012,20.467999,19.5180006Q19.964,19,19.235999,19L8.7360005,19Q8.0080004,19,7.50400019,19.5180006Q7,20.0360012,7,20.7639999Z" fill="#FFFFFF" fill-opacity="1"/><path d="M7,13.7639999Q7,14.4919996,7.50400019,14.9960012Q8.0080004,15.5,8.7360005,15.5L13.236084,15.5Q13.9640846,15.5,14.4680176,14.9960938Q14.9720192,14.4920921,14.971923799999999,13.7641602Q14.971923799999999,13.0361614,14.4680176,12.51806641Q13.9640179,12.000065803528,13.236084,12L8.7360005,12Q8.0080004,12,7.50400019,12.5180006Q7,13.0360012,7,13.7639999Z" fill="#FFFFFF" fill-opacity="1"/></g></svg>
src/static/images/icon/jiekuanguanli.svg
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="28" height="28" viewBox="0 0 28 28"><defs><clipPath id="master_svg0_134_34237"><rect x="0" y="0" width="28" height="28" rx="0"/></clipPath><clipPath id="master_svg1_134_35497"><rect x="7" y="5" width="15" height="15" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_134_34237)"><path d="M22,22.9999995C22,25.2091389,23.7908611,27,26,27L34,27C36.209139,27,38,25.2091389,38,22.9999995L38,22.0000005C38,20.3431458,36.656855,19,35,19L25.0000005,19C23.3431458,19,22,20.3431458,22,22.0000005L22,22.9999995Z" fill="#FDC3C1" fill-opacity="1" transform="matrix(-1,0,0,1,44,0)"/><rect x="2" y="2" width="24" height="22" rx="6" fill="#FF2B00" fill-opacity="1" style="opacity:0.800000011920929;"/><g clip-path="url(#master_svg1_134_35497)"><g><path d="M20.092001,17Q20.092001,17.4,19.956001,17.759999999999998Q19.82,18.119999999999997,19.58,18.384Q19.34,18.648,19.02,18.8Q18.700001,18.951999999999998,18.348,18.951999999999998L13.308000100000001,18.951999999999998L11.3400002,18.951999999999998L11.0840001,18.951999999999998L11.0840001,13.2559996L11.3400002,13.2559996L13.308000100000001,13.2559996L20.092001,13.2559996L20.092001,17ZM17.884000999999998,16.743999000000002L13.308000100000001,16.743999000000002L13.308000100000001,17.608L17.372,17.608Q17.596001,17.608,17.740000000000002,17.448Q17.884000999999998,17.288,17.884000999999998,17.048000000000002L17.884000999999998,16.743999000000002ZM17.884000999999998,14.6L13.308000100000001,14.6L13.308000100000001,15.4L17.884000999999998,15.4L17.884000999999998,14.6ZM10.8280001,7.575999299999999L9.6440001,10.2639999L10.2680001,10.2639999L10.2680001,18.951999999999998L8.059999900000001,18.951999999999998L8.059999900000001,11.911999699999999L6.58799988,11.911999699999999L8.5079999,7.575999299999999L10.8280001,7.575999299999999ZM12.6200004,11.367999600000001L12.6200004,10.0559998L11.2600002,10.0559998L11.2600002,8.6959991L12.6200004,8.6959991L12.6200004,7.5279999L14.828001,7.5279999L14.828001,8.6959991L16.396,8.6959991L16.396,7.5279999L18.604,7.5279999L18.604,8.6959991L19.980001,8.6959991L19.980001,10.0559998L18.604,10.0559998L18.604,11.367999600000001L20.396,11.367999600000001L20.396,12.6959991L10.8439999,12.6959991L10.8439999,11.367999600000001L12.6200004,11.367999600000001ZM14.828001,11.367999600000001L16.396,11.367999600000001L16.396,10.0559998L14.828001,10.0559998L14.828001,11.367999600000001Z" fill="#FFFFFF" fill-opacity="1"/></g></g></g></svg>
src/static/images/icon/kehudangan.svg
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="28.00002908707347" height="28.00002908707347" viewBox="0 0 28.00002908707347 28.00002908707347"><defs><clipPath id="master_svg0_134_34559"><rect x="0" y="28.00002908707347" width="28.000019073486328" height="28.000019073486328" rx="0"/></clipPath><clipPath id="master_svg1_134_35458"><rect x="24" y="35.00002908707347" width="14.999994277954102" height="14.999994277954102" rx="0"/></clipPath></defs><g transform="matrix(0,-1.0000003576278687,1.0000003576278687,0,-28.000039100664196,28.00002908707347)" clip-path="url(#master_svg0_134_34559)"><path d="M1,38.00002908707347L1,46.00002908707347C1,48.20916808707347,2.7908611,50.00002908707347,5.000001,50.00002908707347L6.9999995,50.00002908707347C8.6568542,50.00002908707347,10,48.65688408707347,10,47.00002908707347L10,37.00002958707347C10,35.343174887073474,8.6568542,34.00002908707347,6.9999995,34.00002908707347L5.0000005,34.00002908707347C2.7908611,34.00002908707347,1,35.79089018707347,1,38.00002908707347Z" fill="#7BF1FF" fill-opacity="1"/><rect x="5" y="30.00002908707347" width="22" height="24" rx="6" fill="#0066FF" fill-opacity="1" style="opacity:0.800000011920929;"/><g transform="matrix(0,0.9999996423721313,-0.9999996423721313,0,59.000016570087666,11.00003767014232)" clip-path="url(#master_svg1_134_35458)"><path d="M32.700103765625,44.23331736832347C32.700103765625,44.23331736832347,32.200108565625,44.09998746832347,32.066763865625,44.03332236832347C31.800104165625,43.86665246832347,31.633433365625,43.53331326832347,31.633433365625,43.19997266832347C31.633433365625,42.83332206832347,31.933433065625,42.53332236832347,32.133442865625,42.29997296832347C32.633437165625,41.69997306832347,32.900096865625,40.89997866832347,32.900096865625,39.99997876832347C32.900096865625,38.13332936832347,31.566768165625,36.63332986832347,29.933438265625,36.63332986832347C28.300108865625,36.63332986832347,26.966766365625,38.16664056832347,26.966766365625,40.033304668323474C26.966766365625,40.93330426832347,27.266766265625,41.73329926832347,27.733436065625,42.33329866832347C28.033436065625,42.499968568323474,28.233445665625,42.86664866832347,28.233445665625,43.23329826832347C28.233445665625,43.56663746832347,28.066775765625,43.86663816832347,27.800101065625,44.066647568323475L27.800101065625,44.09997316832347C27.766775865625,44.09997316832347,27.733450665625,44.13329886832347,27.733450665625,44.13329886832347C27.566766065625,44.23330406832347,27.400110965625,44.299968768323474,27.200101165625,44.299968768323474C25.933451165625,44.73329876832347,24.866767045625,45.39996386832347,24.233442095625,46.233297868323476L24.266767275625,46.233297868323476C24.100112281625,46.466660968323474,24.033447265625,46.733320868323474,24.033447265625,46.999981868323474C24.033447265625,47.79997586832347,24.700097385625,48.46664186832347,25.533446665625,48.46664186832347L34.333433265625004,48.46664186832347C35.200107265625,48.46664186832347,35.866773265625,47.83331686832347,35.866773265625,46.999981868323474C35.866773265625,46.66664286832347,35.733443265625,46.36664156832347,35.566773265625,46.099981768323474C34.933433265625,45.26664776832347,33.933444065625,44.63332226832347,32.700103765625,44.23331736832347ZM38.666762265624996,45.699977368323474C38.100102265625,44.99998716832347,37.233442265625,44.399988168323475,36.133433265625,44.066647568323475C36.133433265625,44.066647568323475,35.700103265625,43.96664236832347,35.566772265625,43.89997816832347C35.333423265625,43.733322668323474,35.200107265625,43.466647668323475,35.200107265625,43.16664786832347C35.200107265625,42.83332296832347,35.466767265625,42.56664796832347,35.633437265625,42.39997816832347C36.066767265625,41.866643468323474,36.333441265625,41.16665366832347,36.333441265625,40.36664366832347C36.333441265625,38.73331446832347,35.166767265625,37.36664503832347,33.700092365625,37.36664503832347C33.466773065625,37.36664503832347,33.233437565624996,37.399984898323474,33.033442465625,37.46664982832347C33.533437765624996,38.19997956832347,33.800097465625,39.06665396832347,33.800097465625,40.03331856832347C33.800097465625,41.06664846832347,33.433445965625,42.06665326832347,32.800106965625,42.89998766832347L32.733442265625,42.96663756832347L32.733442265625,42.99997756832347C32.666762365625004,43.06664276832347,32.566772465625,43.166647468323475,32.533431965625,43.26665256832347C32.533431965625,43.29997776832347,32.533431965625,43.29997776832347,32.566772465625,43.29997776832347C32.633421865624996,43.33331776832347,32.733442265625,43.366643468323474,32.833432165625,43.366643468323474L32.866771665625,43.366643468323474L33.000102065625,43.43332286832347C34.366770265625,43.86665246832347,35.533431265625,44.63332226832347,36.300100265625,45.59997226832347C36.633439265625,46.03331706832347,36.833435265625,46.533311368323474,36.833435265625,47.06664586832347C36.833435265625,47.36664486832347,36.766769265625,47.59998086832347,36.666765265625,47.86664086832347L37.633429265625,47.86664086832347C38.400099265625,47.86664086832347,39.000098265625,47.29998086832347,39.000098265625,46.56665086832347C38.966758265625,46.199985968323475,38.866768265625,45.93331096832347,38.666762265624996,45.699977368323474Z" fill="#FFFFFF" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>
src/static/images/icon/shouhouchuli.svg
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="28" height="28" viewBox="0 0 28 28"><defs><clipPath id="master_svg0_134_34204"><rect x="0" y="0" width="28" height="28" rx="0"/></clipPath><clipPath id="master_svg1_134_35472"><rect x="7" y="8" width="16" height="12.002930641174316" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_134_34204)"><path d="M1,10L1,18C1,20.209139,2.7908611,22,5.000001,22L6.9999995,22C8.6568542,22,10,20.656855,10,19L10,9.0000005C10,7.3431458,8.6568542,6,6.9999995,6L5.0000005,6C2.7908611,6,1,7.7908611,1,10Z" fill="#7BF1FF" fill-opacity="1"/><rect x="5" y="2" width="22" height="24" rx="6" fill="#0066FF" fill-opacity="1" style="opacity:0.800000011920929;"/><g clip-path="url(#master_svg1_134_35472)"><path d="M16.874501225,8.37548828125C13.814677725,8.42274617025,11.358972525,10.91667128125,11.358972525,13.976860081249999C11.358973025000001,17.03704928125,13.814676325,19.53097328125,16.874501225,19.57823228125C19.934316625,19.530962281249998,22.390008625,17.037040681249998,22.390008625,13.976860081249999C22.390006624999998,10.916679381249999,19.934316625,8.42275842325,16.874501225,8.37548828125ZM18.328204624999998,14.839745981250001C18.596277625,14.839745981250001,18.812997625,14.98444938125,18.812997625,15.16315748125C18.812997625,15.341865581250001,18.596265625,15.487236481250001,18.328204624999998,15.487236481250001L17.303969425,15.487236481250001L17.303969425,16.588833781250003C17.303969425,16.81156728125,17.158586525,16.99360368125,16.979879425,16.99360368125C16.801172225000002,16.99360368125,16.656467425000002,16.81356048125,16.656467425000002,16.588845281250002L16.656467425000002,15.48724798125L15.420822125,15.48724798125C15.152749025,15.48724798125,14.936040925,15.34187698125,14.936040925,15.16315748125C14.936040925,14.98443798125,15.152761925,14.83975748125,15.420823525,14.83975748125L16.656456025,14.83975748125L16.656456025,14.194928181249999L15.420822125,14.194928181249999C15.152749025,14.194928181249999,14.936040925,14.05022528125,14.936040925,13.87084868125C14.936040925,13.692141581249999,15.152761925,13.547437681249999,15.420823525,13.547437681249999L16.656456025,13.547437681249999L16.656456025,13.28937478125C16.585270925,13.25636288125,16.520657525,13.21072338125,16.465744925,13.154670281249999L15.115416025,11.79767108125C14.930706525,11.61296178125,14.882027125,11.36422948125,15.005384424999999,11.24087098125C15.128754625,11.118169281250001,15.378143825,11.16751718125,15.560860625,11.352226281250001L16.911846125,12.709237581250001L16.926521325,12.72388938125C16.942521125,12.70389218125,16.959857024999998,12.683895581249999,16.979867025,12.66522268125L18.173490625,11.47158788125C18.362208625,11.28220178125,18.618934625,11.23086138125,18.744966625,11.35689188125C18.870996625,11.48292298125,18.820980625,11.73898128125,18.630269625,11.92835568125L17.436645525,13.12199068125C17.395685225,13.16327958125,17.349769625,13.19934038125,17.299948725,13.22934868125C17.304403325,13.25444178125,17.306634924999997,13.27987818125,17.306617725000002,13.30536318125L17.306617725000002,13.54741478125L18.328860625,13.54741478125C18.596934625,13.54741478125,18.813654624999998,13.69213008125,18.813654624999998,13.87083718125C18.813654624999998,14.050212881250001,18.596922624999998,14.19491668125,18.328860625,14.19491668125L17.304615025,14.19491668125L17.304615025,14.83973408125L18.328860625,14.83973408125L18.328204624999998,14.839745981250001ZM10.554302025,10.45399978125L10.568297625,10.46066928125C10.873200624999999,10.59328128125,11.012909425,10.94792628125,10.880373725,11.25286268125C10.536207725,12.04848788125,10.360046125,12.906610981250001,10.362923125,13.77347798125C10.361976625,14.66525788125,10.548733025,15.54725268125,10.911049125,16.36211398125L10.957736525,16.40878968125C11.191961525,16.663968081249998,11.183594225,17.058368681250002,10.938757925,17.30338478125C10.693921325,17.54839988125,10.299526725,17.55705548125,10.044177525,17.32301708125L7.710943805,14.990439381249999C7.476962335,14.73508458125,7.485641178,14.340737781249999,7.730630535,14.09592488125C7.975619945,13.85111138125,8.369972525,13.84271578125,8.625159225,14.07688048125L9.191969525,14.64435908125C9.159153825,14.35544828125,9.142678125,14.06491518125,9.142621425,13.77414708125C9.142621425,12.72522738125,9.350680024999999,11.71297188125,9.760772225,10.76808118125C9.893157025,10.462205181249999,10.248632924999999,10.32180658125,10.554302025,10.45466878125L10.554302025,10.45399978125Z" fill="#FFFFFF" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>
src/static/images/icon/shouruguanli.svg
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="28" height="28" viewBox="0 0 28 28"><defs><clipPath id="master_svg0_134_34245"><rect x="0" y="0" width="28" height="28" rx="0"/></clipPath><clipPath id="master_svg1_134_35478"><rect x="7" y="5" width="14" height="14" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_134_34245)"><g transform="matrix(1,3.7247229744963306e-9,-3.7247229744963306e-9,1,7.449445948992661e-9,-7.449445948992661e-9)"><path d="M8.6032233,27C7.2891606,27,6.33216852,28.2456321,6.67075348,29.5153255L7.2081735,31.5306506C7.6751106,33.2816644,9.260909999999999,34.5,11.0731134,34.5L16.926887999999998,34.5C18.739091000000002,34.5,20.324889,33.2816644,20.791826,31.5306506L21.329247000000002,29.5153253C21.667831,28.2456321,20.710839,27,19.396776,27L8.6032233,27Z" fill="#69FFB4" fill-opacity="1" transform="matrix(1,0,0,-1,0,54)"/><path d="M2,17.499999000000003C2,20.813709,4.6862917,23.5,8.000000499999999,23.5L20,23.5C23.313709,23.5,26,20.813709,26,17.5L26,8.000001000000001C26,4.6862917,23.313709,2,20,2L8.000001000000001,2C4.6862917,2,2,4.6862917,2,8.000001000000001L2,17.499999000000003Z" fill="#01BF34" fill-opacity="1" style="opacity:0.800000011920929;"/></g><g clip-path="url(#master_svg1_134_35478)"><path d="M18.4955004375,10.05311485C18.1769224375,9.69913915,17.8229475375,9.41595935,17.468972237499997,9.16817685C17.3981771375,9.13277935,17.362779637499997,9.09738155,17.2919845375,9.06198405C17.7875499375,8.81420135,18.1415254375,8.35403345,18.1415254375,7.823070550000001C18.1415254375,6.97352985,17.327381137499998,6.33637428,16.336250337499997,6.33637428C16.1238651375,6.33637428,15.9114804375,6.3717719299999995,15.7344932375,6.44256687C15.6283006375,6.47796446,15.5929026375,6.51336193,15.5221076375,6.54875946C15.486710537499999,6.54875946,15.4159150375,6.54875946,15.380517037499999,6.51336193C15.3097219375,6.4071694,15.203529337500001,6.26557922,15.0265426375,6.12398911C14.7433624375,5.87620638,14.4247846375,5.734616235,14.0708088375,5.69921875C13.7168331375,5.734616287,13.398255837499999,5.87620638,13.1150756375,6.12398911C12.973485437499999,6.26557922,12.8318953375,6.37177181,12.7611003375,6.51336193C12.7611003375,6.47796446,12.6903047375,6.51336193,12.6549072375,6.47796446C12.6195097375,6.44256687,12.5487146375,6.4071694,12.4425220375,6.3717719299999995C12.265534837499999,6.30097681,12.0531497375,6.26557934,11.8407640375,6.26557934C10.8850307375,6.26557934,10.0354899375,6.90273485,10.0354899375,7.75227545C10.0354899375,8.28323865,10.3894648375,8.74340655,10.8850307375,8.99118925C10.8496332375,9.02658705,10.7788381375,9.06198455,10.7080433375,9.09738205C10.3540678375,9.34516505,10.0000927375,9.66374305,9.6815147375,9.98231985C8.7257814375,10.97345065,8.1240234375,12.10617205,8.1240234375,13.34508565C8.1240234375,16.81404275,10.8142361375,18.477726750000002,14.0354118375,18.477726750000002L14.1770019375,18.477726750000002C17.3981771375,18.477726750000002,20.0883894375,16.81404275,20.0883894375,13.34508465C20.052991437499998,12.141568150000001,19.4512334375,11.00884815,18.4955004375,10.05311485ZM15.8406863375,13.62826535C16.0530719375,13.62826535,16.1946611375,13.76985545,16.1946611375,13.98224065C16.1946611375,14.19462495,16.0530710375,14.33621595,15.8406863375,14.33621595L14.424785637500001,14.33621595L14.424785637500001,15.71671975C14.424785637500001,15.92910475,14.2831950375,16.07069375,14.0708103375,16.07069375C13.8584256375,16.07069375,13.716835037500001,15.92910375,13.716835037500001,15.71671975L13.716835037500001,14.33621595L12.3009333375,14.33621595C12.0885484375,14.33621595,11.9469580375,14.19462495,11.9469580375,13.98224065C11.9469580375,13.76985545,12.0885479375,13.62826535,12.3009333375,13.62826535L13.716834537499999,13.62826535L13.716834537499999,12.778724650000001L12.2655358375,12.778724650000001C12.0531509375,12.778724650000001,11.9115605375,12.637134549999999,11.9115605375,12.424749850000001C11.9115605375,12.21236515,12.0531504375,12.07077505,12.2655358375,12.07077505L13.3274622375,12.07077505L12.1593437375,10.90265655C12.0177536375,10.76106695,12.0177536375,10.54868125,12.1593437375,10.40709115C12.3009333375,10.26550145,12.5133190375,10.26550145,12.654909137499999,10.40709115L14.0708103375,11.82299235L15.486711037500001,10.40709115C15.6283016375,10.26550145,15.8406863375,10.26550145,15.982276437500001,10.40709115C16.1238670375,10.54868125,16.1238670375,10.76106695,15.982276437500001,10.90265655L14.8141584375,12.07077505L15.8760843375,12.07077505C16.0884695375,12.07077505,16.2300596375,12.21236515,16.2300596375,12.424749850000001C16.2300596375,12.637134549999999,16.0884690375,12.778724650000001,15.8760843375,12.778724650000001L14.424785637500001,12.778724650000001L14.424785637500001,13.62826535L15.8406863375,13.62826535Z" fill="#FFFFFF" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>
src/static/images/icon/xiaoshoubaojia.svg
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="28" height="28" viewBox="0 0 28 28"><defs><clipPath id="master_svg0_134_35423"><rect x="0" y="0" width="28" height="28" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_134_35423)"><path d="M4.9383273125,10.37722678125L16.819185875000002,10.37722678125C17.740669875000002,10.37722678125,17.855514875,10.24871108125,17.869186875,9.31355528125C17.885592875,8.214336181250001,17.863716875,7.10964868125,17.962155875,6.01589858125C18.074264875,4.79363301125,18.962936875,4.22488288125,20.056686875,4.55300790825C20.606296874999998,4.71707043125,20.890671875000002,5.11355483125,20.997312875,5.64128938125C21.060201875,5.95300798125,21.076610875,6.28113298125,21.076610875,6.60105468125C21.082076875,11.443633581250001,21.084811875,16.288944781250002,21.076610875,21.13152678125C21.073876875,22.29363678125,21.095748875,23.43660378125,21.962548875,24.44558878125C21.694577875,24.45652778125,21.516843875,24.47293278125,21.339109875,24.47293278125C17.007861875,24.47840278125,12.671142074999999,24.44558878125,8.334423075,24.50027678125C5.985595075,24.53035378125,4.9273916483,22.91160578125,4.935594856739,21.08230778125C4.94653219,18.04988478125,4.9383293986,15.02019778125,4.9383293986,11.98777528125L4.9383273125,10.37722678125ZM13.012936575,17.658867781250002C11.673092875,17.658867781250002,10.335983275,17.65613478125,8.996139575,17.658867781250002C8.301608575,17.66160178125,7.899655075,17.954180781250002,7.902389575,18.44363378125C7.905124175,18.938555781250002,8.312545775,19.24754178125,8.985202274999999,19.26394678125L9.138327575,19.26394678125C11.730514575,19.26394678125,14.322703375,19.266680781250002,16.914888875000003,19.26121378125C17.133638875000003,19.26121378125,17.363326875,19.253010781249998,17.565669874999998,19.18738478125C17.943012875,19.06707178125,18.150826875,18.78269778125,18.123482875,18.37800978125C18.096138875,17.98972878125,17.833639875,17.77644778125,17.480904875,17.68621378125C17.319575874999998,17.645197781249998,17.144576875,17.656136781249998,16.975044875000002,17.656136781249998C15.654342875,17.65886978125,14.333640075,17.65886978125,13.012936575,17.658867781250002ZM12.988327075,15.03660178125C14.393796875,15.03660178125,15.799263875,15.04480478125,17.207466875,15.03386778125C17.781685875,15.02839978125,18.139888875,14.70300978125,18.131685875000002,14.24089908125C18.126216875,13.80066398125,17.781685875,13.45886708125,17.243013875000003,13.45613288125C14.432076475,13.44519518125,11.618404375,13.44519518125,8.807466975,13.46160218125C8.588716975,13.46160218125,8.279733175,13.54636768125,8.175826275,13.69949338125C8.025435675,13.92097668125,7.935201675,14.26277348125,7.984420075,14.51980578125C8.060982275,14.91902378125,8.441060975,15.03386778125,8.818404475,15.03660378125C10.210201275,15.03933678125,11.599263175,15.03660378125,12.988327075,15.03660178125Z" fill="#FF9533" fill-opacity="1" style="mix-blend-mode:passthrough"/><path d="M19.578316234375,3.4912109375C18.008783234375002,3.9369141475,17.273235234375,4.8064451375,17.109174234375,6.3376951375C17.054486234375,6.8408198375,17.040814234375,7.3494138375,17.027142234375,7.8580079375C17.013470234375,8.3474607375,17.024409234375,8.834179837499999,17.024409234375,9.3701167375C16.830269234375002,9.381053937499999,16.668940234375,9.397460437500001,16.507611234375,9.397460437500001C12.310345634375,9.400195137499999,8.113080534375001,9.400195137499999,3.915814754375,9.397460437500001C3.172064840375,9.397460437500001,3.150189757375,9.3728513375,3.147455424075,8.6236329375C3.147455424075,7.7759766375,3.144721090775,6.9310548375,3.147455424075,6.0833985375C3.152924090575,4.4126952275,4.074408594375,3.4966798127,5.764252434375,3.4939454794C9.893158934375,3.49121114611626,14.024799234375,3.4939454794,18.153706234375,3.4939454794C18.588472234375,3.49121114611626,19.023235234375,3.49121114611626,19.578316234375,3.4912109375ZM21.938080234375,17.6826169375C22.848627234375,17.6826169375,23.709955234375,17.658006937499998,24.565813234375,17.704491937500002C24.724407234375,17.7126939375,24.992374234375,18.0162119375,24.995111234375,18.1884769375C25.022455234375,19.5912109375,25.038860234375,20.9966789375,24.975969234375,22.3966789375C24.929485234375,23.4521469375,24.286907234375,23.9498019375,23.264251234375,23.8759749375C22.761125234375,23.8404269375,22.383783234375,23.5998039375,22.206049234375,23.1376929375C22.074798234375,22.7958969375,21.957222234375,22.4240229375,21.951751234375,22.0630839375C21.921673234375,20.6302719375,21.938080234375,19.1919909375,21.938080234375,17.6826169375Z" fill="#FF9533" fill-opacity="1" style="mix-blend-mode:passthrough"/><path d="M21.938079833986915,17.68261718751621C22.848627091586913,17.68261718751621,23.709955251586916,17.65800666761621,24.565813051586915,17.70449161561621C24.724407151586913,17.71269416761621,24.992374451586915,18.016211506616212,24.995111451586915,18.18847656661621C25.022455251586912,19.59121130661621,25.038860351586912,20.996679306616212,24.975969351586915,22.39667890661621C24.929485351586912,23.45214650661621,24.286907151586913,23.94980240661621,23.264251751586915,23.87597460661621C22.761125561586915,23.84042740661621,22.383783341586913,23.59980390661621,22.206048961586912,23.13769340661621C22.074798581586915,22.79589650661621,21.957221984586916,22.42402270661621,21.951751708586915,22.06308360661621C21.921672820586913,20.630271906616212,21.938079833986915,19.19199080661621,21.938079833986915,17.68261718751621Z" fill="#FFDB42" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></svg>
src/static/images/icon/xiaoshoutuihuo.svg
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="28" height="28" viewBox="0 0 28 28"><defs><clipPath id="master_svg0_134_34539"><rect x="0" y="0" width="28" height="28" rx="0"/></clipPath><clipPath id="master_svg1_134_35443"><rect x="6" y="5" width="16" height="16" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_134_34539)"><path d="M22,22.9999995C22,25.2091389,23.7908611,27,26,27L34,27C36.209139,27,38,25.2091389,38,22.9999995L38,22.0000005C38,20.3431458,36.656855,19,35,19L25.0000005,19C23.3431458,19,22,20.3431458,22,22.0000005L22,22.9999995Z" fill="#FDC3C1" fill-opacity="1" transform="matrix(-1,0,0,1,44,0)"/><rect x="2" y="2" width="24" height="22" rx="6" fill="#FF2B00" fill-opacity="1" style="opacity:0.800000011920929;"/><g clip-path="url(#master_svg1_134_35443)"><path d="M16.1333332,10.933463575L14.066666603,10.933463575L14.066666603,10.600130085C14.066666603,10.533463478,14.13333321,10.466796875,14.19999981,10.466796875L15.9333334,10.466796875C16,10.466796875,16.0666666,10.533463478,16.0666666,10.600130085L16.0666666,10.933463575L16.1333332,10.933463575ZM15.9333334,12.133463375L14,12.133463375L14,11.666796675L16.0666666,11.666796675L16.0666666,12.000130175C16.1333332,12.066796775,16.0666666,12.133463375,15.9333334,12.133463375Z" fill="#FFFFFF" fill-opacity="1" style="mix-blend-mode:passthrough"/><path d="M14.000081546875,5.66650390625C9.933414746875,5.66650390625,6.666748046875,8.93317060625,6.666748046875,12.99983740625C6.666748046875,17.06650390625,9.933414746875,20.33317090625,14.000081546875,20.33317090625C18.066748046875,20.33317090625,21.333415046875,17.06650490625,21.333415046875,12.99983740625C21.333415046875,8.93316960625,18.066748046875,5.66650390625,14.000081546875,5.66650390625ZM13.000081546875,14.33317090625L13.000081546875,10.199837206249999C13.000081546875,9.79983710625,13.266748446874999,9.59983710625,13.733415146875,9.59983710625L16.600081446875002,9.59983710625C17.000081046875,9.59983710625,17.200082046875,9.79983710625,17.200082046875,10.199837206249999L17.200082046875,12.39983700625C17.200082046875,12.53317020625,17.200082046875,12.66650390625,17.133415046875,12.73317050625C17.266748046875,12.73317050625,17.333415046875,12.79983710625,17.400082046875,12.86650370625C17.533415046875,12.93317030625,17.600081046874998,13.06650400625,17.600081046874998,13.26650380625C17.600081046874998,13.33317040625,17.600081046874998,13.46650360625,17.533415046875,13.59983680625C17.333415046875,13.79983620625,17.133415046875,13.93316940625,16.866748046875,14.13317010625C17.066748046875,14.26650330625,17.200081046875,14.39983650625,17.333414046875,14.53316970625C17.400081046875002,14.59983630625,17.466747046875,14.73316950625,17.466747046875,14.86650280625C17.466747046875,14.99983600625,17.400081046875002,15.13316920625,17.333414046875,15.19983580625C17.266747046875,15.33316900625,17.133414046875,15.33316900625,17.000081046875,15.33316900625C16.866748046875,15.33316900625,16.733415046875002,15.26650240625,16.600081446875002,15.19983580625C15.866747846875,14.59983540625,15.200081846875,14.19983580625,14.600081946875001,13.79983620625C14.533415346875,13.79983620625,14.533415346875,13.73316950625,14.466748746875,13.73316950625C14.400082146875,13.666503406250001,14.400082146875,13.59983680625,14.400082146875,13.53317020625C14.400082146875,13.39983700625,14.466748746875,13.26650380625,14.533415346875,13.199837206249999C14.600081946875001,13.133170606250001,14.733414646875,13.06650400625,14.866747846875,13.06650400625C15.000081046875,13.06650400625,15.066747646875,13.06650400625,15.133414246875,13.133170606250001C15.400080646875,13.26650380625,15.733414646875,13.46650360625,16.000081046875,13.59983680625C16.200080846875,13.39983700625,16.400080646875,13.26650380625,16.600081446875002,13.066503006249999L14.000081546875,13.066503006249999L14.000081546875,14.39983560625C14.266747946875,14.33316900625,14.600081946875001,14.33316900625,14.866747846875,14.26650240625C14.933414446875,14.26650240625,15.066747646875,14.33316900625,15.133414246875,14.39983560625C15.200080846875,14.46650220625,15.200080846875,14.53316880625,15.200080846875,14.66650200625C15.200080846875,14.79983520625,15.133414246875,14.86650180625,15.066747646875,14.93316840625C15.000081046875,14.99983500625,14.933414446875,15.06650160625,14.800081246875,15.06650160625C14.133414746875001,15.19983480625,13.600081946875001,15.33316800625,13.266748446874999,15.33316800625C13.133415246875,15.33316800625,13.000081546875,15.26650140625,12.933414946875,15.19983480625C12.866748346875,15.13316820625,12.866748346875,14.99983500625,12.866748346875,14.86650180625C12.866748346875,14.73316860625,12.933414946875,14.59983540625,13.000081546875,14.53316880625L13.000081546875,14.33317090625ZM10.800081746875,9.66650370625C10.866748346875,9.59983710625,11.000081546875,9.53317050625,11.133415246875,9.53317050625C11.200081846875001,9.53317050625,11.333415046875,9.53317050625,11.400082146875,9.59983710625C11.733415646874999,9.79983710625,12.066748646875,9.99983740625,12.400082146875,10.26650380625C12.466748746875,10.33317040625,12.533415346875,10.46650360625,12.533415346875,10.59983730625C12.533415346875,10.73317100625,12.533415346875,10.86650420625,12.466748746875,10.93317080625C12.333415546874999,11.06650400625,12.266748946875001,11.133170606250001,12.066748646875,11.133170606250001C12.000082046875,11.133170606250001,11.933415446875,11.133170606250001,11.866748846875,11.06650400625C11.800082246875,11.06650400625,11.733415646874999,10.99983740625,11.733415646874999,10.99983740625L10.933415446875,10.39983750625L10.866748846875,10.33317090625C10.733415646874999,10.266504306249999,10.666749046875001,10.199837706250001,10.666749046875001,9.99983740625C10.666749046875001,9.86650420625,10.733415646874999,9.79983760625,10.800081746875,9.66650370625ZM17.600081046874998,16.399836906250002C17.533415046875,16.46650290625,17.400082046875,16.533169906250002,17.200082046875,16.533169906250002L14.266748946875001,16.533169906250002C13.200082346875,16.533169906250002,12.400082146875,16.46650290625,11.933415846875,16.26650290625C11.866749246874999,16.19983690625,11.800082646875001,16.19983690625,11.800082646875001,16.19983690625C11.800082646875001,16.19983690625,11.733416046875,16.19983690625,11.666749446875,16.26650290625C11.533416246875,16.399836906250002,11.333415946875,16.46650290625,11.200082746875001,16.533169906250002C11.133416146875,16.59983590625,11.000082946875,16.59983590625,10.933415846875,16.666502906250003C10.866749246874999,16.666502906250003,10.800082646875001,16.666502906250003,10.733416046875,16.59983590625C10.666749446875,16.533169906250002,10.533416046875,16.33316990625,10.466749446875,16.19983690625C10.400082846875,16.13316990625,10.400082846875,16.06650390625,10.400082846875,15.93316990625C10.400082846875,15.86650390625,10.466749446875,15.79983690625,10.533416046875,15.73317090625C10.800083146875,15.59983730625,11.066749546875,15.46650410625,11.200082746875001,15.33317090625C11.266749346874999,15.26650430625,11.266749346874999,15.26650430625,11.266749346874999,15.19983770625L11.266749346874999,12.99983740625C11.266749346874999,12.93317080625,11.266749346874999,12.93317080625,11.200082746875001,12.93317080625L10.866749246874999,12.93317080625C10.666749446875,12.93317080625,10.533415546875,12.86650420625,10.466748946875,12.79983760625C10.400082346875,12.73317100625,10.333415746875,12.599837806250001,10.333415746875,12.39983750625C10.333415746875,12.199837206249999,10.400082346875,12.133170606250001,10.466748946875,11.99983740625C10.533415546875,11.93317080625,10.666749046875001,11.86650420625,10.866749246874999,11.86650420625L11.600082846875,11.86650420625C12.066749546875,11.86650420625,12.266749346874999,12.06650400625,12.266749346874999,12.46650410625L12.266749346874999,15.26650330625C12.266749346874999,15.33316990625,12.400082546875,15.39983650625,12.600082846875,15.46650310625C12.933416346875,15.53316970625,13.400083046875,15.59983630625,14.066749046875,15.59983630625L17.333414046875,15.59983630625C17.466747046875,15.59983630625,17.600080046875,15.59983630625,17.666747046875003,15.66650290625C17.733414046874998,15.73316990625,17.800080046875,15.86650290625,17.800080046875,16.06650290625C17.733414046874998,16.19983590625,17.666747046875003,16.333168906250002,17.600081046874998,16.399836906250002Z" fill="#FFFFFF" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>
src/static/images/icon/zhichuguanli.svg
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="28" height="28" viewBox="0 0 28 28"><defs><clipPath id="master_svg0_134_34213"><rect x="0" y="0" width="28" height="28" rx="0"/></clipPath><clipPath id="master_svg1_134_35484"><rect x="7" y="5" width="16" height="16" rx="0"/></clipPath></defs><g clip-path="url(#master_svg0_134_34213)"><path d="M25,21.1513879C25,21.3787005,25.067284852,21.6009274,25.19337524,21.7900629L27.1094005,24.6641006C27.6657977,25.4986968,28.6024919,26,29.6055508,26L37,26C38.656855,26,40,24.656854199999998,40,23C40,21.343146,38.656855,20,37,20L26.1513879,20C25.51549393,20,25,20.51549393,25,21.1513879Z" fill="#FFDB42" fill-opacity="1" transform="matrix(-1,0,0,1,50,0)"/><rect x="2" y="2" width="25" height="21" rx="6" fill="#FF7B00" fill-opacity="1" style="opacity:0.800000011920929;"/><g clip-path="url(#master_svg1_134_35484)"><path d="M22.257600781249998,18.74337764375C22.31377408125,18.83753204375,22.34387108125,18.94494344375,22.34480098125,19.05457784375C22.34480098125,19.76737784375,20.99680038125,20.34577754375,19.33280088125,20.34577754375C17.66880128125,20.34577754375,16.32080078125,19.76737784375,16.32080078125,19.05457784375C16.32169055939,18.94493774375,16.35179042825,18.83751674375,16.40800094625,18.74337764375C18.23233798125,19.73173614375,20.43246368125,19.73173614375,22.25680068125,18.74337764375L22.257600781249998,18.74337764375ZM22.257600781249998,17.02257724375C22.31377408125,17.11673164375,22.34387108125,17.22414304375,22.34480098125,17.33377744375C22.34480098125,18.04657744375,20.99680038125,18.62417794375,19.33280088125,18.62417794375C17.66880128125,18.62417794375,16.32080078125,18.04577824375,16.32080078125,17.33377834375C16.32169055939,17.22413824375,16.35179042825,17.11671734375,16.40800094625,17.02257824375C18.23237518125,18.01078984375,20.43242648125,18.01078984375,22.25680068125,17.02257824375L22.257600781249998,17.02257724375ZM19.33280088125,14.32177734375C20.99680038125,14.32177734375,22.34480098125,14.90017700375,22.34480098125,15.61217694375C22.34480098125,16.32417674375,20.99680038125,16.90337654375,19.33280088125,16.90337654375C17.66880128125,16.90337654375,16.32080078125,16.32497694375,16.32080078125,15.61217694375C16.32080078125,14.89937687375,17.66960048125,14.32177734375,19.33360098125,14.32177734375L19.33280088125,14.32177734375Z" fill="#FFFFFF" fill-opacity="1" style="mix-blend-mode:passthrough"/><path d="M15.000000028125001,16.79931640625L8.600097658125,16.79931640625C8.158269998125,16.799317406249997,7.800048828125,16.44134040625,7.800048828125,15.99951170625L7.800048828125007,7.59912109625C7.800048768520362,7.15729331625,8.158269758125,6.79931640625,8.600097658125,6.79931640625L18.999999828125,6.79931640625C19.441827828125,6.79931640625,19.800048828125,7.15729331625,19.800048828125,7.59912109625L19.800048828125,13.009716006249999C19.666824828125,13.00288300625,19.533448828125,12.99941590625,19.400048828125,12.99931620625C16.973649028125,12.99931620625,15.000048628125,14.10811610625,15.000048628125,15.47051620625L15.000000028125001,16.79833980625L15.000000028125001,16.79931640625ZM12.709648628124999,9.64491630625L9.373648928125,12.98091650625L10.165648928125,13.772916806249999L12.709648628124999,11.22891710625L14.780048328125,13.299317406250001L17.930448828125,10.14811710625L17.138448728125,9.356117006249999L14.780048328125,11.715317206249999L12.709648628124999,9.64491630625Z" fill="#FFFFFF" fill-opacity="1" style="mix-blend-mode:passthrough"/></g></g></svg>