diff --git a/frontend/src/views/Prices.vue b/frontend/src/views/Prices.vue
index 24c50b5..6d18d1f 100644
--- a/frontend/src/views/Prices.vue
+++ b/frontend/src/views/Prices.vue
@@ -6,7 +6,10 @@
- 提交价格
+
@@ -38,27 +41,27 @@
-
-
{{ row.model }}
-
+
+ {{ row.model }}
+
待审核: {{ row.temp_model }}
-
+
-
-
{{ getBillingType(row.billing_type) }}
-
+
+ {{ getBillingType(row.billing_type) }}
+
待审核: {{ getBillingType(row.temp_billing_type) }}
-
+
-
+
{{ getProvider(row.channel_type)?.name || row.channel_type }}
-
+
待审核: {{ getProvider(row.temp_channel_type)?.name || row.temp_channel_type }}
-
+
-
-
{{ row.currency }}
-
+
+ {{ row.currency }}
+
待审核: {{ row.temp_currency }}
-
+
-
-
{{ row.input_price }}
-
+
+ {{ row.input_price }}
+
待审核: {{ row.temp_input_price }}
-
+
-
-
{{ row.output_price }}
-
+
+ {{ row.output_price }}
+
待审核: {{ row.temp_output_price }}
-
+
@@ -115,11 +118,11 @@
-
-
{{ row.price_source }}
-
+
+ {{ row.price_source }}
+
待审核: {{ row.temp_price_source }}
-
+
@@ -142,6 +145,90 @@
+
+
+
+
+ 添加行
+ 删除选中行
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ provider.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -401,6 +488,91 @@ const updateStatus = async (id, status) => {
}
}
+// 批量添加相关的状态
+const batchDialogVisible = ref(false)
+const batchForms = ref([])
+const selectedRows = ref([])
+const batchSubmitting = ref(false)
+
+// 创建新行的默认数据
+const createNewRow = () => ({
+ model: '',
+ billing_type: 'tokens',
+ channel_type: '',
+ currency: 'USD',
+ input_price: 0,
+ output_price: 0,
+ price_source: '',
+ created_by: props.user?.username || ''
+})
+
+// 添加新行
+const addRow = () => {
+ batchForms.value.push(createNewRow())
+}
+
+// 处理选择变化
+const handleSelectionChange = (rows) => {
+ selectedRows.value = rows
+}
+
+// 删除选中的行
+const removeSelectedRows = () => {
+ const selectedIds = new Set(selectedRows.value.map(row => batchForms.value.indexOf(row)))
+ batchForms.value = batchForms.value.filter((_, index) => !selectedIds.has(index))
+ selectedRows.value = []
+}
+
+// 打开批量添加对话框
+const handleBatchAdd = () => {
+ if (!props.user) {
+ router.push('/login')
+ ElMessage.warning('请先登录')
+ return
+ }
+ batchForms.value = [createNewRow()]
+ batchDialogVisible.value = true
+}
+
+// 提交批量表单
+const submitBatchForms = async () => {
+ if (!batchForms.value.length) {
+ ElMessage.warning('请至少添加一条数据')
+ return
+ }
+
+ // 验证数据
+ const invalidForms = batchForms.value.filter(form =>
+ !form.model || !form.channel_type || !form.price_source
+ )
+
+ if (invalidForms.length) {
+ ElMessage.error('请填写完整所有必填字段')
+ return
+ }
+
+ batchSubmitting.value = true
+ try {
+ // 逐个提交数据
+ for (const form of batchForms.value) {
+ await axios.post('/api/prices', form)
+ }
+
+ await loadPrices()
+ batchDialogVisible.value = false
+ ElMessage.success('批量添加成功')
+ } catch (error) {
+ console.error('Failed to submit batch prices:', error)
+ if (error.response?.data?.error) {
+ ElMessage.error(error.response.data.error)
+ } else {
+ ElMessage.error('批量添加失败')
+ }
+ } finally {
+ batchSubmitting.value = false
+ }
+}
+
onMounted(async () => {
await loadPrices()
try {
@@ -472,12 +644,43 @@ onMounted(async () => {
padding-right: 0;
}
-.pending-update {
- font-size: 12px;
- color: #E6A23C;
- margin-top: 4px;
- padding: 2px 4px;
- background-color: #FDF6EC;
- border-radius: 2px;
+.value-container {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+}
+
+.value-container :deep(.el-tag) {
+ margin: 0;
+ width: fit-content;
+}
+
+.value-container span {
+ word-break: break-all;
+}
+
+.header-buttons {
+ display: flex;
+ gap: 12px;
+}
+
+.batch-add-container {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+}
+
+.batch-toolbar {
+ display: flex;
+ gap: 12px;
+ padding: 8px 0;
+}
+
+:deep(.el-input-number) {
+ width: 100%;
+}
+
+:deep(.el-select) {
+ width: 100%;
}
\ No newline at end of file