Jelajahi Sumber

修改额度申请控制

Co-authored-by: Copilot <copilot@github.com>
hurx 15 jam lalu
induk
melakukan
42ef6ec239

+ 10 - 0
src/api/pc/cost/creditApply.ts

@@ -21,3 +21,13 @@ export function addCreditApply(data: any) {
     data: data
   });
 }
+
+/**
+ * 撤回消息通知--删除
+ */
+export function deleteCreditApply(ids: number[]) {
+  return request({
+    url: `/customer/pcCreditApply/${ids.join(',')}`,
+    method: 'delete'
+  });
+}

+ 87 - 31
src/views/cost/quotaControl/apply.vue

@@ -1,9 +1,9 @@
 <template>
   <div class="quota-apply-container">
     <div class="page-header">
-      <el-button type="primary" link @click="handleBack"
-        ><el-icon><ArrowLeft /></el-icon>返回</el-button
-      >
+      <el-button type="primary" link @click="handleBack">
+        <el-icon><ArrowLeft /></el-icon>返回
+      </el-button>
       <span class="page-title">额度申请</span>
     </div>
 
@@ -36,15 +36,11 @@
         </el-form-item>
       </div>
 
-      <el-form-item label="主要办公采购类目" prop="mainPurchase">
+      <!-- 核心修改区域:绑定逻辑保持不变 -->
+      <el-form-item label="主要办公采购类目" prop="mainPurchaseArr">
         <div class="mainPurchase-tags">
-          <div
-            v-for="item in categoryList"
-            :key="item.value"
-            :class="['tag-item', { active: formData.mainPurchase === item.value }]"
-            @click="formData.mainPurchase = item.value"
-          >
-            {{ item.label }}
+          <div v-for="item in categoryList" :key="item.id" :class="['tag-item', { active: isSelected(item.id) }]" @click="toggleSelect(item.id)">
+            {{ item.categoryName }}
           </div>
         </div>
       </el-form-item>
@@ -71,27 +67,39 @@
 </template>
 
 <script setup lang="ts">
-import { ref, reactive } from 'vue';
+import { ref, reactive, onMounted, getCurrentInstance } from 'vue';
 import { useRouter } from 'vue-router';
 import { ArrowLeft, Plus } from '@element-plus/icons-vue';
 import { ElMessage } from 'element-plus';
 import { addCreditApply } from '@/api/pc/cost/creditApply';
+import { getProductCategoryList } from '@/api/home/index';
+import type { ComponentInternalInstance } from 'vue';
+
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-const { purchase_item } = toRefs<any>(proxy?.useDict('purchase_item'));
 const router = useRouter();
 const formRef = ref();
 
+// 表单数据
 const formData = reactive({
   monthPurchase: '',
   yearPurchase: '',
   applyAmount: '',
   amountPeriod: '',
-  mainPurchase: '0',
+  mainPurchaseArr: [] as (string | number)[], // 明确类型
+  mainPurchase: '', // 最终提交的字符串
   otherPurchase: '',
   cooperationImage: ''
 });
 
-const categoryList = computed(() => purchase_item.value || []);
+// 商品类别列表
+interface CategoryItem {
+  id?: number | string;
+  categoryName?: string;
+  [key: string]: any;
+}
+
+const categoryList = ref<CategoryItem[]>([]);
+
 const rules = {
   monthPurchase: [{ required: true, message: '请输入月度采购金额', trigger: 'blur' }],
   applyAmount: [{ required: true, message: '请输入申请信用金额', trigger: 'blur' }]
@@ -101,9 +109,35 @@ const handleBack = () => {
   router.back();
 };
 
+// --- 核心逻辑:多选切换 ---
+const toggleSelect = (id: string | number) => {
+  // 统一转换为字符串进行比较,防止数字1和字符串"1"不匹配
+  const currentId = String(id);
+  const index = formData.mainPurchaseArr.findIndex((item) => String(item) === currentId);
+
+  if (index > -1) {
+    formData.mainPurchaseArr.splice(index, 1); // 取消选中
+  } else {
+    formData.mainPurchaseArr.push(currentId); // 选中
+  }
+};
+
+const isSelected = (id: string | number) => {
+  return formData.mainPurchaseArr.includes(String(id));
+};
+// -------------------------
+
 const handleSave = async () => {
   const valid = await formRef.value?.validate();
   if (!valid) return;
+  if (formData.mainPurchaseArr.length === 0) {
+    ElMessage.error('请选择主要办公采购类目');
+    return;
+  }
+
+  // 将数组转换为逗号分隔的字符串
+  formData.mainPurchase = formData.mainPurchaseArr.join(',');
+
   try {
     await addCreditApply(formData);
     ElMessage.success('保存成功');
@@ -112,6 +146,21 @@ const handleSave = async () => {
     ElMessage.error('保存失败');
   }
 };
+
+const loadCategoryList = async () => {
+  try {
+    const res = await getProductCategoryList({ datasource: 'A10', classLevel: 1 });
+    if (res.data) {
+      categoryList.value = res.data;
+    }
+  } catch (error) {
+    console.error('获取商品类别失败:', error);
+  }
+};
+
+onMounted(() => {
+  loadCategoryList();
+});
 </script>
 
 <style scoped lang="scss">
@@ -157,27 +206,34 @@ const handleSave = async () => {
   }
 }
 
+/* 标签选择器样式 - 核心修改 */
 .mainPurchase-tags {
   display: flex;
   flex-wrap: wrap;
-  gap: 10px;
+  gap: 12px; // 标签间距
+}
 
-  .tag-item {
-    padding: 6px 16px;
-    border-radius: 4px;
-    cursor: pointer;
-    font-size: 13px;
-    color: #666;
-    background: #f5f5f5;
-    transition: all 0.2s;
+.tag-item {
+  padding: 8px 20px;
+  border: 1px solid #dcdfe6;
+  border-radius: 4px;
+  cursor: pointer;
+  font-size: 14px;
+  color: #606266;
+  background-color: #f5f7fa;
+  transition: all 0.2s ease;
+  user-select: none; // 防止快速点击时文字被选中
 
-    &:hover {
-      color: #e60012;
-    }
-    &.active {
-      background: #e60012;
-      color: #fff;
-    }
+  &:hover {
+    color: #e60012; // 鼠标悬停变绿
+  }
+
+  /* 选中状态下的高亮样式 - 红色主题 */
+  &.active {
+    background-color: #e60012;
+    color: #ffffff;
+    border-color: #e60012;
+    box-shadow: 0 2px 0 rgba(230, 0, 18, 0.2);
   }
 }
 

+ 61 - 4
src/views/cost/quotaControl/index.vue

@@ -39,7 +39,8 @@
       <el-table-column prop="applyAmount" label="申请信用金额" min-width="120" align="center" />
       <el-table-column prop="category" label="主要采购类目" min-width="120" align="center">
         <template #default="{ row }">
-          {{ getDictLabel(purchase_item, row.mainPurchase) }}
+          <!-- 调用新函数处理 ID 字符串 -->
+          {{ getCategoryNames(row.mainPurchase) }}
         </template>
       </el-table-column>
       <el-table-column prop="approvalStatus" label="申请状态" min-width="100" align="center">
@@ -49,6 +50,13 @@
           }}</span>
         </template>
       </el-table-column>
+      <el-table-column label="操作" width="120" align="center" fixed="right">
+        <template #default="{ row }">
+          <div style="display: flex; gap: 8px; justify-content: center">
+            <el-button type="danger" link v-if="row.approvalStatus == '0'" @click="handleDelete(row)">撤回</el-button>
+          </div>
+        </template>
+      </el-table-column>
     </el-table>
   </div>
 </template>
@@ -58,16 +66,22 @@ import { ref } from 'vue';
 import { useRouter } from 'vue-router';
 import { CreditCard } from '@element-plus/icons-vue';
 import { PageTitle } from '@/components';
-import { getCreditApplyList } from '@/api/pc/cost/creditApply';
+import { getCreditApplyList, deleteCreditApply } from '@/api/pc/cost/creditApply';
 import { getEnterpriseInfo } from '@/api/pc/enterprise';
-import { any } from 'vue-types';
+import { getProductCategoryList } from '@/api/home/index';
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-const { purchase_item } = toRefs<any>(proxy?.useDict('purchase_item'));
 const router = useRouter();
 
 const recordList = ref([]);
 const customerSalesInfoVo = ref({} as any);
+// 商品类别列表
+interface CategoryItem {
+  id?: number | string;
+  categoryName?: string;
+  [key: string]: any;
+}
 
+const categoryList = ref<CategoryItem[]>([]);
 const loadCreditApply = async () => {
   try {
     const res = await getCreditApplyList();
@@ -80,6 +94,24 @@ const loadCreditApply = async () => {
   }
 };
 
+// 新增:处理类目 ID 字符串回显名称的函数
+const getCategoryNames = (idStr: string) => {
+  // 1. 如果为空,直接返回空或提示
+  if (!idStr) return '-';
+
+  // 2. 将字符串按逗号分割成数组
+  const ids = idStr.split(',');
+
+  // 3. 遍历 ID 数组,在 categoryList 中查找对应的名称
+  const names = ids.map((id) => {
+    const category = categoryList.value.find((item) => String(item.id) === String(id));
+    return category ? category.categoryName : ''; // 找到则返回名称,否则返回空
+  });
+
+  // 4. 过滤掉未匹配到的空值,并用顿号或逗号拼接返回
+  return names.filter((name) => name).join('、');
+};
+
 const getDictLabel = (dictOptions: any[], value: string) => {
   if (!dictOptions || !value) return value;
   const dict = dictOptions.find((item) => item.value === value);
@@ -96,7 +128,32 @@ const handleApplyQuota = () => {
   router.push('/cost/quotaControl/apply');
 };
 
+const handleDelete = (item: any) => {
+  ElMessageBox.confirm('确定要撤回该额度申请吗?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(
+    async () => {
+      try {
+        await deleteCreditApply([item.id]);
+        ElMessage.success('操作成功');
+        loadCreditApply();
+      } catch (error) {
+        ElMessage.error('操作失败');
+      }
+    }
+  );
+};
+const loadCategoryList = async () => {
+  try {
+    const res = await getProductCategoryList({ datasource: 'A10', classLevel: 1 });
+    if (res.data) {
+      categoryList.value = res.data;
+    }
+  } catch (error) {
+    console.error('获取商品类别失败:', error);
+  }
+};
+
 onMounted(() => {
+  loadCategoryList();
   getEnterpriseInfo().then((res) => {
     if (res.code == 200) {
       if (res.data && res.data.customerSalesInfoVo) {