seatonwan9
2025-08-19 95cb69b9f79893d7cd1319d754064c93e3fa4e2f
src/views/productManage/productPriceViewer/index.vue
@@ -249,10 +249,25 @@
                    </div>
                  </td>
                  <td class="th-center">
                    <el-input-number v-model="suite.quantity" :min="1" :max="999" :controls="false" size="small" />
                    <el-input-number
                      v-model="suite.quantity"
                      :min="1"
                      :max="999"
                      :controls="true"
                      size="large"
                      @change="(value) => handleQuantityChange(suite.id, value?value:1)"
                    />
                  </td>
                  <td class="th-center">
                    <el-input-number v-model="suite.duration" :min="1" :max="10" :controls="false" size="small" />
                      <el-input-number
                        v-model="suite.duration"
                        :min="1"
                        :max="100"
                        :controls="true"
                        size="large"
                        :disabled="suite.priceType === 'FREE'"
                        @change="(value) => handleDurationChange(suite.id, value?value:1)"
                      />
                  </td>
                  <td class="th-center">
                    <el-button type="danger" link @click="removeSuite(idx)">删除</el-button>
@@ -331,7 +346,7 @@
        <el-button type="primary" @click="handleOrder">立即订购</el-button>
        </template>
        <template v-else>
          <el-button @click="showOrderPanel = false">返回价格对比</el-button>
          <el-button @click="returnPricePanel">返回价格对比</el-button>
          <el-button type="primary" @click="submitOrder">提交申请</el-button>
        </template>
      </span>
@@ -346,6 +361,8 @@
import { ElMessage } from 'element-plus'
import { useRoute } from 'vue-router'
import productPricingApi from '@/api/productPricingApi'
import cartApi from '@/api/cartApi'
import orderApi from '@/api/orderApi'
import { ShoppingCart, Coin, Money } from '@element-plus/icons-vue'
const route = useRoute()
@@ -406,6 +423,9 @@
const showOrderPanel = ref(false)
const showPricePanel = ref(true)
const showOrderStatus = ref(false)
// 模拟用户信息(实际应从用户状态获取)
const currentUserId = ref(1)
const currentUnitId = ref(1)
type PriceTypeKey = 'POINTS' | 'CURRENCY' | 'AGREEMENT' | 'FREE'
interface OrderSuite extends PriceItem {
  selected: boolean
@@ -414,6 +434,11 @@
  priceType?: PriceTypeKey
}
const orderSuites = ref<OrderSuite[]>([])
// 购物车相关状态
const cartItems = ref<any[]>([])
const cartLoading = ref(false)
const idempotencyToken = ref<string>('')
// 订单状态相关
type OrderStatus = 'SUBMITTED' | 'AUTHORIZED' | 'CONFIRMED' | 'EVALUATED'
@@ -522,7 +547,25 @@
  const map: Record<string, string> = { SET: '/套', SET_PER_YEAR: '/套/年', YEAR: '/年' }
  return map[unit || ''] || ''
}
const removeSuite = (index: number) => { orderSuites.value.splice(index, 1) }
const removeSuite = async (index: number) => {
  const suite = orderSuites.value[index]
  if (!suite) return
  try {
    await removeFromCart(suite.id)
    orderSuites.value.splice(index, 1)
  } catch (e) {
  }
}
// 订购成功回调
const handleOrderSuccess = (orderData: any) => {
  console.log('订购成功:', orderData)
  ElMessage.success('订购申请提交成功!')
  // 清空选择状态
  selectedSuiteIds.value.clear()
  // 关闭价格查看器
  visible.value = false
}
// 弹窗标题
const dialogTitle = computed(() => {
@@ -689,26 +732,28 @@
  const isChecked = Boolean(checked)
  if (isChecked) {
    selectedSuiteIds.value.add(suiteId)
    // 添加到购物车
    const priceItem = priceList.value.find(item => item.id === suiteId)
    if (priceItem) {
      addToCart(priceItem)
    }
  } else {
    selectedSuiteIds.value.delete(suiteId)
    // 从购物车移除
    removeFromCart(suiteId)
  }
}
// 立即订购
const handleOrder = () => {
  if (selectedSuiteIds.value.size === 0) {
    ElMessage.warning('请选择要订购的软件套件')
    return
  }
  const selectedItems = priceList.value.filter(item => selectedSuiteIds.value.has(item.id))
  // 构建内嵌订购列表
  orderSuites.value = selectedItems.map(it => ({
    ...it,
    selected: true,
    quantity: 1,
    duration: 1,
    priceType: getDefaultPriceType(it as any)
  })) as any
  // 查询购物车信息进行展示
  fetchCartItems()
  // 获取一次性防重复提交token
  orderApi.getIdempotencyToken(currentUserId.value).then((res: any) => {
    if (res?.code === 200) {
      idempotencyToken.value = res.data as string
    }
  }).catch(() => {})
  showOrderPanel.value = true
  showPricePanel.value = false
}
@@ -719,6 +764,12 @@
// 启用/停用按钮
function handleToggleEnableStatus(row: any) {
  // ... existing code ...
}
function returnPricePanel() {
  showOrderPanel.value = false
  showOrderStatus.value = false
  showPricePanel.value = true
}
async function submitOrder() {
@@ -733,34 +784,195 @@
    ElMessage.error('暂不支持货币交易,请选择积分或协议支付方式')
    return
  }
  // 这里可对接实际下单接口;先做前端提示
  // emit('order', items as any)
  // 模拟订单状态数据
  orderStatus.value = {
    id: '4348442557619205545',
    productName: productHeader.value.name,
    provider: productHeader.value.provider,
    status: 'SUBMITTED',
    submitTime: new Date().toLocaleString(),
    applyTime: new Date().toLocaleString()
  if (!idempotencyToken.value) {
    ElMessage.error('下单Token获取失败,请返回重试')
    return
  }
  // 显示订单状态面板
  showOrderPanel.value = false
  showPricePanel.value = false
  showOrderStatus.value = true
  // 组装创建订单参数(CreateOrderDTO)
  const payload = {
    userId: currentUserId.value,
    unitId: currentUnitId.value,
    productName: productHeader.value.name,
    providerName: productHeader.value.provider,
    providerId: 3,
    paymentType: '积分',
    buyerRemarks: '',
    items: items.map(it => ({
      pricingId: it.id,
      productId: Number(it.productId),
      suiteName: getProductSuiteText(it.productSuite),
      salesForm: getSalesFormText(it.salesForm),
      customerType: getCustomerObjectText(it.customerObject),
      accountLimit: it.accountQuantityUnlimited ? '不限' : String(it.accountQuantity),
      concurrentNodes: it.concurrentNodeQuantityUnlimited ? '不限' : String(it.concurrentNodeQuantity),
      priceType: (it.priceType === 'POINTS' ? '积分' : it.priceType === 'CURRENCY' ? '货币' : it.priceType === 'AGREEMENT' ? '协议' : '免费'),
      priceUnit: getPriceUnitText(it.priceUnit),
      unitPrice: (it.priceType === 'POINTS' ? it.pointsAmount : it.currencyAmount) || 0,
      quantity: it.quantity,
      duration: it.duration,
      totalPrice: undefined,
      providerId: 3,
      providerName: productHeader.value.provider,
      remarks: ''
    }))
  }
  try {
    const res: any = await orderApi.createOrder(payload, idempotencyToken.value)
    if (res?.code === 200) {
      ElMessage.success('订单创建成功')
      const data = res.data || {}
      orderStatus.value = {
        id: data.orderId || '—',
        productName: data.productName || productHeader.value.name,
        provider: data.providerName || productHeader.value.provider,
        status: 'SUBMITTED',
        submitTime: data.applyTime ? String(data.applyTime) : new Date().toLocaleString(),
        applyTime: data.applyTime ? String(data.applyTime) : new Date().toLocaleString()
      }
      // 清空购物车(后端 + 本地状态)
      try {
        const clearRes: any = await cartApi.clearCart(currentUserId.value, currentUnitId.value)
        if (clearRes?.code === 200) {
          cartItems.value = []
          orderSuites.value = []
          selectedSuiteIds.value.clear()
          selectAllChecked.value = false
        }
      } catch (e) { /* ignore */ }
      // 显示订单状态面板
      showOrderPanel.value = false
      showPricePanel.value = false
      showOrderStatus.value = true
    } else {
      ElMessage.error(res?.msg || '创建订单失败')
    }
  } catch (e) {
    ElMessage.error('创建订单失败')
  }
}
// 订购成功回调
const handleOrderSuccess = (orderData: any) => {
  console.log('订购成功:', orderData)
  ElMessage.success('订购申请提交成功!')
  // 清空选择状态
  selectedSuiteIds.value.clear()
  // 关闭价格查看器
  visible.value = false
// 购物车相关方法
const addToCart = async (priceItem: PriceItem) => {
  try {
    const cartData = {
      pricingId: priceItem.id,
      productId: Number(priceItem.productId),
      productName: productName.value,
      suiteName: getProductSuiteText(priceItem.productSuite),
      salesForm: getSalesFormText(priceItem.salesForm),
      customerType: getCustomerObjectText(priceItem.customerObject),
      accountLimit: priceItem.accountQuantityUnlimited ? '不限' : String(priceItem.accountQuantity),
      concurrentNodes: priceItem.concurrentNodeQuantityUnlimited ? '不限' : String(priceItem.concurrentNodeQuantity),
      priceType: priceItem.priceSettings.map(item => getPriceSettingText(item)).join(','),
      priceUnit: getPriceUnitText(priceItem.priceUnit),
      unitPrice: priceItem.pointsAmount || priceItem.currencyAmount || 0,
      quantity: 1,
      duration: 1
    }
    const res: any = await cartApi.addToCart(cartData, currentUserId.value, currentUnitId.value)
    if (res?.code === 200) {
      ElMessage.success('已添加到购物车')
    } else {
      ElMessage.error(res?.msg || '添加到购物车失败')
    }
  } catch (error) {
    console.error('添加到购物车失败:', error)
    ElMessage.error('添加到购物车失败')
  }
}
const removeFromCart = async (pricingId: number) => {
  try {
    const res: any = await cartApi.removeFromCart(currentUserId.value, currentUnitId.value, pricingId)
    if (res?.code === 200) {
      ElMessage.success('已从购物车移除')
    } else {
      ElMessage.error(res?.msg || '从购物车移除失败')
    }
  } catch (error) {
    console.error('从购物车移除失败:', error)
    ElMessage.error('从购物车移除失败')
  }
}
const updateCartItem = async (pricingId: number, quantity: number, duration: number) => {
  try {
    // 这里需要根据实际接口调整,可能需要传递更多参数
    const res: any = await cartApi.updateCartItem(currentUserId.value, currentUnitId.value, pricingId, quantity)
    if (res?.code === 200) {
      ElMessage.success('购物车已更新')
    } else {
      ElMessage.error(res?.msg || '更新购物车失败')
    }
  } catch (error) {
    console.error('更新购物车失败:', error)
    ElMessage.error('更新购物车失败')
  }
}
const fetchCartItems = async () => {
  cartLoading.value = true
  try {
    const res: any = await cartApi.getCartItems(currentUserId.value, currentUnitId.value)
    if (res?.code === 200) {
      cartItems.value = res.data || []
      // 将购物车数据转换为订单套件格式
      orderSuites.value = cartItems.value.map((item: any) => ({
        id: item.pricingId,
        productId: String(item.productId),
        productSuite: item.suiteName,
        salesForm: mapSalesFormFromCN(item.salesForm),
        customerObject: mapCustomerFromCN(item.customerType),
        accountQuantity: item.accountLimit === '不限' ? 0 : Number(item.accountLimit),
        accountQuantityUnlimited: item.accountLimit === '不限',
        concurrentNodeQuantity: item.concurrentNodes === '不限' ? 0 : Number(item.concurrentNodes),
        concurrentNodeQuantityUnlimited: item.concurrentNodes === '不限',
        priceSettings: item.priceType.split(',').map((t: string) => mapPriceTypeFromCN(t)).filter(Boolean),
        pointsAmount: item.priceType.includes('积分') ? item.unitPrice : 0,
        currencyAmount: item.priceType.includes('货币') ? item.unitPrice : 0,
        priceUnit: mapUnitFromCN(item.priceUnit),
        enableStatus: 'ENABLED',
        selected: true,
        quantity: item.quantity || 1,
        duration: item.duration || 1,
        priceType: getDefaultPriceType({
          priceSettings: item.priceType.split(',').map((t: string) => mapPriceTypeFromCN(t)).filter(Boolean)
        } as any)
      })) as any
    } else {
      orderSuites.value = []
      ElMessage.error(res?.msg || '获取购物车信息失败')
    }
  } catch (error) {
    console.error('获取购物车信息失败:', error)
    orderSuites.value = []
    ElMessage.error('获取购物车信息失败')
  } finally {
    cartLoading.value = false
  }
}
// 处理数量变化
const handleQuantityChange = async (pricingId: number, quantity: number) => {
  try {
    await updateCartItem(pricingId, quantity, 1) // 暂时传递默认duration为1
  } catch (error) {
    console.error('更新数量失败:', error)
  }
}
// 处理年限变化
const handleDurationChange = async (pricingId: number, duration: number) => {
  try {
    // 这里可能需要根据实际接口调整,传递duration参数
    await updateCartItem(pricingId, 1, duration) // 暂时传递默认quantity为1
  } catch (error) {
    console.error('更新年限失败:', error)
  }
}
// 获取销售形式文本
@@ -973,7 +1185,7 @@
              }
              
              &.currency {
                color: #f56c6c;
                color: #e7900d;
              }
              
              &.free {
@@ -981,7 +1193,7 @@
              }
            }
            .price-icon.points { color: #e6a23c; }
            .price-icon.currency { color: #f56c6c; }
            .price-icon.currency { color: #e7900d; }
          }
          
                     .add-checkbox {