From ad106d35ebd06e5e122fd1af31c8e2aac94ab0c7 Mon Sep 17 00:00:00 2001 From: p-honggang.li <p-honggang.li@pcitc.com> Date: 星期五, 29 八月 2025 14:01:08 +0800 Subject: [PATCH] 修改配置 --- src/views/productManage/productPriceViewer/index.vue | 566 +++++++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 419 insertions(+), 147 deletions(-) diff --git a/src/views/productManage/productPriceViewer/index.vue b/src/views/productManage/productPriceViewer/index.vue index fb0bd06..71022ee 100644 --- a/src/views/productManage/productPriceViewer/index.vue +++ b/src/views/productManage/productPriceViewer/index.vue @@ -1,12 +1,5 @@ <template> - <el-dialog - v-model="visible" - :title="dialogTitle" - :before-close="handleClose" - destroy-on-close - class="product-price-dialog" - :width="dialogWidth" - > + <div> <div class="price-viewer-container" v-loading="loading"> <!-- 浠锋牸瀵规瘮琛ㄦ牸 --> <div class="pricing-table-container" v-if="showPricePanel && priceList.length > 0"> @@ -19,7 +12,7 @@ > <div class="pricing-table-wrapper"> <table class="pricing-table"> - <thead> + <thead> <tr> <th class="feature-column">鍔熻兘瀵规瘮</th> <th @@ -174,19 +167,19 @@ <span class="label">浜у搧鍚嶇О锛�</span><span class="value strong">{{ productHeader.name }}</span> </div> <div class="grid-item"> - <span class="label">琛屼笟鏉垮潡锛�</span><span class="value">{{ productHeader.industry }}</span> + <span class="label">琛屼笟鏉垮潡锛�</span><span class="value">{{ productHeader.industrialChainName }}</span> </div> <div class="grid-item"> - <span class="label">鎻愪緵鑰咃細</span><span class="value">{{ productHeader.provider }}</span> + <span class="label">鎻愪緵鑰咃細</span><span class="value">{{ productHeader.submissionUnit }}</span> </div> <div class="grid-item"> <span class="label">鐢ㄦ埛濮撳悕锛�</span><span class="value">{{ userInfo.name }}</span> </div> <div class="grid-item"> - <span class="label">鍗曚綅锛�</span><span class="value">{{ userInfo.unit }}</span> + <span class="label">鍗曚綅锛�</span><span class="value">{{ userInfo.unitName }}</span> </div> <div class="grid-item"> - <span class="label">閮ㄩ棬锛�</span><span class="value">{{ userInfo.department }}</span> + <span class="label">閮ㄩ棬锛�</span><span class="value">{{ userInfo.departmentName }}</span> </div> </div> </el-card> @@ -249,10 +242,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> @@ -323,30 +331,29 @@ <el-empty description="鏆傛棤浠锋牸淇℃伅" /> </div> </div> - - <template #footer v-if="!showOrderStatus"> - <span class="dialog-footer"> - <template v-if="showPricePanel"> - <el-button @click="handleClose">鍏抽棴</el-button> - <el-button type="primary" @click="handleOrder">绔嬪嵆璁㈣喘</el-button> - </template> - <template v-else> - <el-button @click="showOrderPanel = false">杩斿洖浠锋牸瀵规瘮</el-button> - <el-button type="primary" @click="submitOrder">鎻愪氦鐢宠</el-button> - </template> - </span> - </template> - </el-dialog> + <div class="footer" v-if="showPricePanel"> + <el-button type="primary" @click="handleOrder">绔嬪嵆璁㈣喘</el-button> + </div> + <div class="footer" v-else> + <el-button @click="returnPricePanel">杩斿洖浠锋牸瀵规瘮</el-button> + <el-button type="primary" @click="submitOrder">鎻愪氦鐢宠</el-button> + </div> + </div> <!-- 浜у搧璁㈣喘瀵硅瘽妗嗙Щ闄わ紝鏀逛负鍐呭祵灞曠ず --> </template> <script setup lang="ts"> -import { ref, watch, computed } from 'vue' +import { ref, watch, computed, onMounted } from 'vue' 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' +import { useUserInfo } from '@/stores/modules/userInfo' +import { queryUserDetail } from '@/api/userInfo' +import productApi from '@/api/productApi' const route = useRoute() @@ -367,36 +374,11 @@ enableStatus: 'ENABLED' | 'DISABLED' } -interface Props { - modelValue: boolean - productId?: string - width?: string -} - -interface Emits { - (e: 'update:modelValue', value: boolean): void - (e: 'order', selectedItems: PriceItem[]): void -} - // 鍏煎 path 鍙傛暟 productId 涓� query 鍙傛暟 id/productId const currentProductId = computed<string | undefined>(() => { return (route.params.productId as string) || (route.query.productId as string) || (route.query.id as string) }) - -const props = withDefaults(defineProps<Props>(), { - modelValue: false, - productId: '', - width: '90%' -}) - - -const emit = defineEmits<Emits>() - -const visible = computed({ - get: () => props.modelValue, - set: (value) => emit('update:modelValue', value) -}) const loading = ref(false) const activeTab = ref('enterprise') @@ -406,6 +388,33 @@ const showOrderPanel = ref(false) const showPricePanel = ref(true) const showOrderStatus = ref(false) +// 妯℃嫙鐢ㄦ埛淇℃伅锛堝疄闄呭簲浠庣敤鎴风姸鎬佽幏鍙栵級 +const userStore = useUserInfo() +let currentUserId = computed(() => userStore.getUserId || userStore.getUserInfo?.userId) +const currentUnitId = computed(() => userStore.getUnitId || userStore.getUserInfo?.unitId || '') + +onMounted(async () => { + if (!currentUserId.value) { + try { + const res: any = await queryUserDetail() + if (res?.code === 200 && res.data) { + userStore.updateUserDetail(res.data) + currentUserId = res.data.userId || res.data.id + userInfo.value = res.data + } else { + ElMessage.error(res?.msg || '鏃犳硶鑾峰彇鐢ㄦ埛淇℃伅锛岃鍏堢櫥褰�') + return + } + } catch (e) { + console.error('鑾峰彇鐢ㄦ埛璇︽儏澶辫触:', e) + ElMessage.error('鑾峰彇鐢ㄦ埛淇℃伅澶辫触锛岃绋嶅悗閲嶈瘯') + return + } + }else{ + userInfo.value = userStore.getUserInfos + } + +}) type PriceTypeKey = 'POINTS' | 'CURRENCY' | 'AGREEMENT' | 'FREE' interface OrderSuite extends PriceItem { selected: boolean @@ -414,6 +423,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' @@ -488,14 +502,15 @@ // 浜у搧淇℃伅/鐢ㄦ埛淇℃伅锛堥潤鎬侊級 const productHeader = ref({ - name: '涓氦鏂硅繙鏅鸿兘瀹炴祴瀹為噺绠$悊绯荤粺', - industry: '鍏矾,甯傛斂,寤虹瓚', - provider: '涓氦寤虹瓚闆嗗洟绗竴宸ョ▼鏈夐檺鍏徃' + name: '', + industrialChainName: '', + submissionUnit: '', + createUserId: '' }) const userInfo = ref({ - name: '寮犻潤', - unit: '淇$闆嗗洟', - department: '闂ㄦ埛绯荤粺涓存椂缁�' + name: '', + departmentName: '', + unitName: '' }) // 鍏ㄩ�� @@ -522,17 +537,29 @@ 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(String(suite.id)) + orderSuites.value.splice(index, 1) + } catch (e) { + } +} + +// 璁㈣喘鎴愬姛鍥炶皟 +const handleOrderSuccess = (orderData: any) => { + console.log('璁㈣喘鎴愬姛:', orderData) + ElMessage.success('璁㈣喘鐢宠鎻愪氦鎴愬姛锛�') + // 娓呯┖閫夋嫨鐘舵�� + selectedSuiteIds.value.clear() +} // 寮圭獥鏍囬 const dialogTitle = computed(() => { return `銆�${productName.value}銆戜骇鍝佸畾浠穈 }) -// 寮圭獥瀹藉害 -const dialogWidth = computed(() => { - return props.width -}) // 鎸夊鎴峰璞″垎缁勭殑浠锋牸鏁版嵁 const groupedPriceData = computed(() => { @@ -658,57 +685,61 @@ } finally { loading.value = false } + //鑾峰彇浜у搧璇︽儏淇℃伅 + try { + // productDetail.value = mockProductMap[productId] || null + const data = { + id: productId + } + const detailRes: any = await productApi.getProductById(data) + if (detailRes?.code === 200) { + productHeader.value = detailRes.data || { name: '', industrialChainName: '', submissionUnit: '', createUserId: '' } + } else { + productHeader.value = { name: '', industrialChainName: '', submissionUnit: '', createUserId: '' } + ElMessage.error(detailRes?.msg || '鑾峰彇浜у搧璇︽儏澶辫触') + } + } catch (e) { + productHeader.value = { name: '', industrialChainName: '', submissionUnit: '', createUserId: '' } + ElMessage.error('鑾峰彇浜у搧璇︽儏澶辫触') + } finally { + loading.value = false + } } // 鐩戝惉浜у搧ID鍙樺寲 -watch(() => props.productId, (newProductId) => { - if (newProductId && visible.value) { +watch(currentProductId, (newProductId) => { + if (newProductId) { fetchProductData(newProductId) } -}) - -// 鐩戝惉寮圭獥鏄剧ず鐘舵�� -watch(() => visible.value, (newVisible) => { - if (newVisible && props.productId) { - fetchProductData(props.productId) - } -}) - -// 鍏抽棴寮圭獥 -const handleClose = () => { - visible.value = false - showOrderPanel.value = false - showOrderStatus.value = false - showPricePanel.value = true - orderSuites.value = [] - selectedSuiteIds.value.clear() -} +},{ immediate: true }) // 濂椾欢閫夋嫨澶勭悊 const handleSuiteSelect = (suiteId: number, checked: any) => { 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(String(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 +750,12 @@ // 鍚敤/鍋滅敤鎸夐挳 function handleToggleEnableStatus(row: any) { // ... existing code ... +} + +function returnPricePanel() { + showOrderPanel.value = false + showOrderStatus.value = false + showPricePanel.value = true } async function submitOrder() { @@ -734,33 +771,218 @@ return } - // 杩欓噷鍙鎺ュ疄闄呬笅鍗曟帴鍙o紱鍏堝仛鍓嶇鎻愮ず - // 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 + const hasPoints = items.some(item => item.priceType === 'POINTS') + const hasAGREEMENT = items.some(item => item.priceType === 'AGREEMENT') + let paymentType = '' + if(hasPoints){ + paymentType = '绉垎' + }else{ + paymentType = '鍗忚' + } + // 缁勮鍒涘缓璁㈠崟鍙傛暟锛圕reateOrderDTO锛� + const payload = { + userId: currentUserId.value, + unitId: currentUnitId.value, + productName: productHeader.value.name, + providerName: productHeader.value.submissionUnit, + providerId: productHeader.value.createUserId, + paymentType: paymentType, + buyerRemarks: '', + items: items.map(it => ({ + pricingId: it.id, + productId: 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: productHeader.value.createUserId, + providerName: productHeader.value.submissionUnit, + 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.submissionUnit, + status: 'SUBMITTED', + submitTime: data.applyTime ? String(data.applyTime) : new Date().toLocaleString(), + applyTime: data.applyTime ? String(data.applyTime) : new Date().toLocaleString() + } + // 璋冪敤宸ヤ綔娴佹帴鍙e彂璧峰鎵规祦绋嬶紝鎷垮埌娴佺▼瀹炰緥ID鍚庡洖鍐欒鍗晈orkflow_id + try { + // 鏍规嵁鏄惁鍖呭惈鍗忚鏄庣粏锛岄厤缃笉鍚屾祦绋嬪畾涔変笌涓氬姟Key锛堝厛鐢ㄩ潤鎬佸�煎崰浣嶏級 + const processdefId = hasAGREEMENT ? 'Process_Agreement_Static' : 'Process_Points_Static' + const businessKey = hasAGREEMENT ? 'agreement_biz_key' : 'points_biz_key' + const wfRes: any = await orderApi.startWorkflowAndComplete({ + processdefId, + userid: String(currentUserId.value || ''), + businessKey + }) + if (wfRes?.code === 200 && wfRes.data?.processinstId) { + await orderApi.updateWorkflowId(data.orderId, wfRes.data.processinstId) + } + } catch (e) { + console.warn('鍚姩宸ヤ綔娴佸け璐ユ垨鏇存柊workflow_id澶辫触', e) + } + + // 娓呯┖璐墿杞︼紙鍚庣 + 鏈湴鐘舵�侊級 + 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: 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: string) => { + 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 { + // 杩欓噷闇�瑕佹牴鎹疄闄呮帴鍙h皟鏁达紝鍙兘闇�瑕佷紶閫掓洿澶氬弬鏁� + 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) // 鏆傛椂浼犻�掗粯璁uration涓�1 + } catch (error) { + console.error('鏇存柊鏁伴噺澶辫触:', error) + } +} + +// 澶勭悊骞撮檺鍙樺寲 +const handleDurationChange = async (pricingId: number, duration: number) => { + try { + // 杩欓噷鍙兘闇�瑕佹牴鎹疄闄呮帴鍙h皟鏁达紝浼犻�抎uration鍙傛暟 + await updateCartItem(pricingId, 1, duration) // 鏆傛椂浼犻�掗粯璁uantity涓�1 + } catch (error) { + console.error('鏇存柊骞撮檺澶辫触:', error) + } } // 鑾峰彇閿�鍞舰寮忔枃鏈� @@ -872,29 +1094,65 @@ .pricing-table-container { .pricing-tabs { :deep(.el-tabs__header) { - margin-bottom: 5px; + margin-bottom: 12px; } - + /* 灞呬腑 tabs 瀵艰埅 */ + :deep(.el-tabs__nav-wrap) { + display: flex; + justify-content: center; + } + :deep(.el-tabs__nav) { + margin: 0 auto; + border: none !important; + } + /* 鍗$墖鍨� tabs 缇庡寲涓哄渾瑙掕兌鍥婃晥鏋� */ + :deep(.el-tabs--card > .el-tabs__header .el-tabs__nav) { + border: none; + } + :deep(.el-tabs--card > .el-tabs__header .el-tabs__item) { + border: none; + } + :deep(.el-tabs__item) { + border-radius: 999px; + padding: 8px 18px; + margin: 0 6px; + color: #606266; + background: #f6f8fb; + transition: all .2s ease; + } + :deep(.el-tabs__item:hover) { + color: #3a7afe; + background: #eff4ff; + } :deep(.el-tabs__item.is-active) { - font-weight: bold; + font-weight: 600; + color: #fff; + background: #3a7afe; + box-shadow: 0 6px 16px rgba(58, 122, 254, 0.25); } } .pricing-table-wrapper { overflow-x: auto; + background: #fff; + border-radius: 12px; + box-shadow: 0 6px 24px rgba(0, 0, 0, 0.06); + padding: 8px; .pricing-table { width: 100%; - border-collapse: collapse; - border: 1px solid #e4e7ed; + border-collapse: separate; + border-spacing: 0; background: #fff; + border-radius: 10px; th, td { - border: 1px solid #e4e7ed; - padding: 6px 8px; + border-bottom: 1px solid #eef2f7; + border-right: 1px solid #f3f5f7; + padding: 12px 14px; text-align: center; vertical-align: middle; - font-size: 16px; + font-size: 14px; } tr th:first-child, td:first-child{ font-weight: 700; @@ -902,7 +1160,7 @@ } th { - background-color: #f5f7fa; + background: linear-gradient(180deg, #f7f9fc 0%, #eef2f7 100%); font-weight: 600; color: #303133; } @@ -914,9 +1172,9 @@ .sub-header { th { - background-color: #fafafa; + background-color: #f8fafc; font-weight: 500; - font-size: 16px; + font-size: 13px; color: #606266; } } @@ -929,26 +1187,34 @@ } .feature-value { - color: #606266; - background: #fafafa; /* 琛屼负鐏拌壊 */ + color: #303133; + background: #fff; + } + + tbody tr:hover td { + background: #fafcff; } .order-methods { display: flex; flex-direction: column; - gap: 4px; + gap: 6px; align-items: center; .method-item { - font-size: 16px; - color: #409eff; + font-size: 12px; + color: #3a7afe; + background: #f4f7ff; + border: 1px solid #e3ebff; + border-radius: 999px; + padding: 2px 10px; } } .price-info { display: flex; flex-direction: column; /* 绔栨帓 */ - gap: 8px; + gap: 10px; align-items: center; .price-item { @@ -956,24 +1222,29 @@ align-items: flex-start; flex-direction: column; gap: 6px; + padding: 10px 12px; + border: 1px solid #f0f2f5; + border-radius: 10px; + background: #fff; + box-shadow: inset 0 -1px 0 rgba(0,0,0,0.02); .price-lable-icon{ display: flex; gap: 6px; } .price-label { - font-size: 16px; - color: #606266; + font-size: 12px; + color: #909399; } .price-value { - font-weight: 500; - font-size: 20px; + font-weight: 600; + font-size: 18px; &.points { color: #e7900d; } &.currency { - color: #f56c6c; + color: #10b981; } &.free { @@ -981,7 +1252,7 @@ } } .price-icon.points { color: #e6a23c; } - .price-icon.currency { color: #f56c6c; } + .price-icon.currency { color: #16a34a; } } .add-checkbox { @@ -994,7 +1265,7 @@ justify-content: center; align-items: center; padding: 8px 0; - .add-cart-icon { color: #409eff; font-size:22px} + .add-cart-icon { color: #3a7afe; font-size:22px} } } } @@ -1136,4 +1407,5 @@ .order-summary .summary-value.highlight{ color:#409eff; } .order-summary .summary-value.total{ color:#e6a23c; } .order-summary .summary-value.currency{ color:#f56c6c; } +.footer { display: flex; flex-direction: row-reverse; margin-right: 50px; gap: 50px; margin-top: 20px;} </style> -- Gitblit v1.8.0