AllocationDrawer.vue 8.45 KB
<template>
    <BasicDrawer
      v-bind="$attrs"
      @register="registerDrawer"
      title="分配比例"
      width="600px"
      height="80vh"
      :showFooter="false"
    >
      <div class="allocation-container">
        <div class="allocation-form">
          <div class="allocation-header">
            <span class="font-bold">客户代码分配比例</span>
          </div>
          
          <div class="allocation-list">
            <div 
              v-for="item in allocationList" 
              :key="item.customerCode"
              class="allocation-item"
            >
              <a-row :gutter="16" align="middle">
                <a-col :span="8">
                  <span class="customer-code">{{ item.customerCode }}</span>
                </a-col>
                <a-col :span="10">
                  <div class="value-input-container">
                    <a-input-number
                      v-if="item.editing"
                      v-model:value="item.editValue"
                      :min="0"
                      :max="100"
                      :precision="2"
                      placeholder="输入比例"
                      style="width: 100%"
                      size="small"
                      @pressEnter="handleSaveEdit(item)"
                    />
                    <span v-else class="value-display">{{ item.value }}%</span>
                  </div>
                </a-col>
                <a-col :span="6">
                  <div class="action-buttons">
                    <template v-if="item.editing">
                      <a-button 
                        type="primary" 
                        size="small" 
                        @click="handleSaveEdit(item)"
                        :loading="item.saving"
                      >
                        确定
                      </a-button>
                      <a-button 
                        size="small" 
                        @click="handleCancelEdit(item)"
                        style="margin-left: 8px;"
                      >
                        取消
                      </a-button>
                    </template>
                    <template v-else>
                      <a-button 
                        v-if="!item.unlocked"
                        type="default" 
                        size="small" 
                        @click="handleUnlock(item)"
                        :icon="h(LockOutlined)"
                      >
                        解锁
                      </a-button>
                      <a-button 
                        v-else
                        type="link" 
                        size="small" 
                        @click="handleStartEdit(item)"
                      >
                        编辑
                      </a-button>
                    </template>
                  </div>
                </a-col>
              </a-row>
            </div>
          </div>
        </div>
      </div>
    </BasicDrawer>
  </template>
  
  <script lang="ts">
  import { defineComponent, ref, computed, h } from 'vue';
  import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
  import { defHttp } from '/@/utils/http/axios';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { LockOutlined } from '@ant-design/icons-vue';
  
  interface AllocationItem {
    customerCode: string;
    value: number;
    editing?: boolean;
    editValue?: number;
    saving?: boolean;
    unlocked?: boolean;
  }
  
  interface UserInfo {
    id: number;
    chineseName?: string;
    nickName?: string;
    phone?: string;
  }
  
  export default defineComponent({
    name: 'AllocationDrawer',
    components: { BasicDrawer },
    emits: ['success', 'register'],
    setup(_, { emit }) {
      const { createMessage } = useMessage();
      const formRef = ref();
      const confirmLoading = ref(false);
      const userInfo = ref<UserInfo>({} as UserInfo);
      const allocationList = ref<AllocationItem[]>([]);
      
      // 计算总比例
      const totalPercentage = computed(() => {
        return allocationList.value.reduce((sum, item) => sum + (item.value || 0), 0);
      });
  
      const [registerDrawer, { setDrawerProps }] = useDrawerInner(async (data) => {
        console.log('打开分配比例抽屉,接收数据:', data);
        
        if (data?.record) {
          userInfo.value = data.record;
          await loadAllocationData(data.record.id);
        }
      });
  
      // 加载分配比例数据
      async function loadAllocationData(userId: number) {
        try {
          setDrawerProps({ confirmLoading: true });
          
          const response = await defHttp.post({
            url: '/order/erp/userCustomerCode/list',
            data: { userId }
          });
          
          console.log('获取分配比例数据:', response);
          
          if (Array.isArray(response)) {
            allocationList.value = response.map(item => ({
              customerCode: item.customerCode,
              value: item.value || 0,
              editing: false,
              editValue: item.value || 0,
              saving: false,
              unlocked: false
            }));
          } else {
            allocationList.value = [];
            createMessage.warning('未获取到分配比例数据');
          }
        } catch (error) {
          console.error('获取分配比例数据失败:', error);
          createMessage.error('获取分配比例数据失败');
          allocationList.value = [];
        } finally {
          setDrawerProps({ confirmLoading: false });
        }
      }
  
      // 解锁
      function handleUnlock(item: AllocationItem) {
        item.unlocked = true;
        createMessage.success(`${item.customerCode} 已解锁,可以编辑`);
      }
  
      // 开始编辑
      function handleStartEdit(item: AllocationItem) {
        if (!item.unlocked) {
          createMessage.warning('请先解锁后再编辑');
          return;
        }
        item.editing = true;
        item.editValue = item.value;
      }
  
      // 取消编辑
      function handleCancelEdit(item: AllocationItem) {
        item.editing = false;
        item.editValue = item.value;
        // 取消编辑时自动锁定
        item.unlocked = false;
      }
  
      // 保存编辑
      async function handleSaveEdit(item: AllocationItem) {
        try {
          item.saving = true;
          
          const requestData = {
            userId: userInfo.value.id,
            customerCode: item.customerCode,
            value: item.editValue || 0
          };
          
          console.log('保存单个分配比例:', requestData);
          
          await defHttp.post({
            url: '/order/erp/userCustomerCode/edit',
            data: requestData
          });
          
          // 更新本地数据
          item.value = item.editValue || 0;
          item.editing = false;
          // 保存后自动锁定
          item.unlocked = false;
          
          createMessage.success(`${item.customerCode} 分配比例保存成功`);
          
        } catch (error) {
          console.error('保存分配比例失败:', error);
          createMessage.error('保存分配比例失败');
        } finally {
          item.saving = false;
        }
      }
  
      return {
        registerDrawer,
        formRef,
        confirmLoading,
        userInfo,
        allocationList,
        totalPercentage,
        handleUnlock,
        handleStartEdit,
        handleCancelEdit,
        handleSaveEdit,
        h,
        LockOutlined,
      };
    },
  });
  </script>
  
  <style lang="less" scoped>
  .allocation-container {
    padding: 0;
    height: 100%;
    display: flex;
    flex-direction: column;
  }
  
  .allocation-form {
    flex: 1;
    display: flex;
    flex-direction: column;
  }
  
  .allocation-header {
    padding: 12px 16px 8px 16px;
    border-bottom: 1px solid #f0f0f0;
    flex-shrink: 0;
  }
  
  .allocation-list {
    flex: 1;
    padding: 8px 16px 8px 16px;
    overflow-y: auto;
  }
  
  .allocation-item {
    padding: 8px 0;
    border-bottom: 1px solid #f5f5f5;
    
    &:last-child {
      border-bottom: none;
    }
  }
  
  .customer-code {
    font-weight: 500;
    color: #333;
    font-size: 14px;
  }
  
  .value-input-container {
    display: flex;
    align-items: center;
  }
  
  .value-display {
    font-size: 14px;
    color: #333;
    font-weight: 500;
  }
  
  .action-buttons {
    display: flex;
    justify-content: flex-end;
    align-items: center;
  }
  </style>