feat: update appraisal ordering and payment flows
This commit is contained in:
@@ -179,6 +179,9 @@ export interface AdminOrderListItem {
|
||||
brand_name: string;
|
||||
service_provider: string;
|
||||
service_provider_text: string;
|
||||
price_package_name: string;
|
||||
price_package_code: string;
|
||||
price_package_price: number;
|
||||
source_channel: string;
|
||||
source_channel_text: string;
|
||||
source_customer_id: string;
|
||||
@@ -196,6 +199,9 @@ export interface AdminOrderDetail {
|
||||
appraisal_no: string;
|
||||
service_provider: string;
|
||||
service_provider_text: string;
|
||||
price_package_name: string;
|
||||
price_package_code: string;
|
||||
price_package_price: number;
|
||||
source_channel: string;
|
||||
source_channel_text: string;
|
||||
source_customer_id: string;
|
||||
@@ -320,6 +326,8 @@ export interface AdminManualOrderMaterialItem {
|
||||
|
||||
export interface AdminManualOrderCreatePayload {
|
||||
service_provider: string;
|
||||
price_package_id?: number;
|
||||
price_package_code?: string;
|
||||
product_info: {
|
||||
category_id: number;
|
||||
brand_id: number;
|
||||
@@ -370,6 +378,7 @@ export interface AdminManualOrderMeta {
|
||||
category_ids: number[];
|
||||
supported_service_types: string[];
|
||||
}>;
|
||||
service_price_packages: AdminServicePriceProviderOption[];
|
||||
}
|
||||
|
||||
export interface CatalogOverviewCard {
|
||||
@@ -1404,6 +1413,44 @@ export interface AdminSystemConfigUploadResult {
|
||||
original_name: string;
|
||||
}
|
||||
|
||||
export interface AdminServicePricePackage {
|
||||
id: number;
|
||||
service_provider: string;
|
||||
service_provider_text: string;
|
||||
package_name: string;
|
||||
package_code: string;
|
||||
price: number;
|
||||
description: string;
|
||||
is_enabled: boolean;
|
||||
is_default: boolean;
|
||||
sort_order: number;
|
||||
sla_hours: number;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface AdminServicePriceProviderOption {
|
||||
service_provider: string;
|
||||
service_provider_text: string;
|
||||
price: number;
|
||||
sla_hours: number;
|
||||
default_package_id: number;
|
||||
default_package: AdminServicePricePackage | null;
|
||||
packages: AdminServicePricePackage[];
|
||||
}
|
||||
|
||||
export interface AdminServicePricePayload {
|
||||
id?: number;
|
||||
service_provider: string;
|
||||
package_name: string;
|
||||
package_code: string;
|
||||
price: number;
|
||||
description: string;
|
||||
is_enabled: boolean;
|
||||
is_default: boolean;
|
||||
sort_order: number;
|
||||
}
|
||||
|
||||
export interface AdminPageVisualsConfig {
|
||||
order_background_image_url: string;
|
||||
report_background_image_url: string;
|
||||
@@ -2317,6 +2364,46 @@ export const adminApi = {
|
||||
data: { id: number };
|
||||
}>;
|
||||
},
|
||||
getServicePricePackages() {
|
||||
return request.get("/api/admin/service-price-packages") as Promise<{
|
||||
code: number;
|
||||
message: string;
|
||||
data: {
|
||||
providers: Array<{
|
||||
service_provider: string;
|
||||
service_provider_text: string;
|
||||
sla_hours: number;
|
||||
}>;
|
||||
list: AdminServicePricePackage[];
|
||||
};
|
||||
}>;
|
||||
},
|
||||
saveServicePricePackage(data: AdminServicePricePayload) {
|
||||
return request.post("/api/admin/service-price-package/save", data) as Promise<{
|
||||
code: number;
|
||||
message: string;
|
||||
data: { id: number };
|
||||
}>;
|
||||
},
|
||||
updateServicePricePackageStatus(id: number, isEnabled: boolean) {
|
||||
return request.post("/api/admin/service-price-package/status", {
|
||||
id,
|
||||
is_enabled: isEnabled,
|
||||
}) as Promise<{
|
||||
code: number;
|
||||
message: string;
|
||||
data: { id: number };
|
||||
}>;
|
||||
},
|
||||
setDefaultServicePricePackage(id: number) {
|
||||
return request.post("/api/admin/service-price-package/default", {
|
||||
id,
|
||||
}) as Promise<{
|
||||
code: number;
|
||||
message: string;
|
||||
data: { id: number };
|
||||
}>;
|
||||
},
|
||||
getExpressCompanies(params?: { enabled_only?: 0 | 1 }) {
|
||||
return request.get("/api/admin/express-companies", { params }) as Promise<{
|
||||
code: number;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { House, Tickets, CollectionTag, DocumentChecked, DataAnalysis, Bell, ChatLineRound, User, Lock, Setting, OfficeBuilding, Connection, Box, Van } from "@element-plus/icons-vue";
|
||||
import { House, Tickets, CollectionTag, DocumentChecked, DataAnalysis, Bell, ChatLineRound, User, Lock, Setting, OfficeBuilding, Connection, Box, Van, Money } from "@element-plus/icons-vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { adminApi } from "../api/admin";
|
||||
import { clearAdminSession, getAdminInfo, hasPermission } from "../utils/auth";
|
||||
@@ -28,6 +28,7 @@ const menus = [
|
||||
{ index: "users", label: "用户管理", icon: User, permission: "users.manage" },
|
||||
{ index: "customers", label: "客户管理", icon: Connection, permission: "customers.manage" },
|
||||
{ index: "warehouses", label: "仓库中心", icon: OfficeBuilding, permission: "warehouses.manage" },
|
||||
{ index: "service-prices", label: "服务价格", icon: Money, permission: "service_prices.manage" },
|
||||
{ index: "express-companies", label: "快递公司", icon: Van, permission: "warehouses.manage" },
|
||||
{ index: "materials", label: "物料管理", icon: Box, permission: "materials.manage" },
|
||||
{ index: "access", label: "权限中心", icon: Lock, permission: "access.manage" },
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
type AdminOrderDetail,
|
||||
type AdminOrderListItem,
|
||||
type AdminOrderWarehouseOption,
|
||||
type AdminServicePricePackage,
|
||||
} from "../../api/admin";
|
||||
import OrderStatusTag from "../../components/OrderStatusTag.vue";
|
||||
import { recognizeReturnAddress } from "../../utils/address-recognition";
|
||||
@@ -36,7 +37,7 @@ const defaultExpressCompany = ref("");
|
||||
const manualDialogVisible = ref(false);
|
||||
const manualSubmitting = ref(false);
|
||||
const manualMetaLoading = ref(false);
|
||||
const manualMeta = ref<AdminManualOrderMeta>({ categories: [], brands: [] });
|
||||
const manualMeta = ref<AdminManualOrderMeta>({ categories: [], brands: [], service_price_packages: [] });
|
||||
const manualForm = ref<AdminManualOrderCreatePayload>(createManualOrderForm());
|
||||
const manualAddressRecognitionText = ref("");
|
||||
|
||||
@@ -150,11 +151,16 @@ const expressCompanySelectOptions = computed(() => {
|
||||
...expressCompanyOptions.value,
|
||||
];
|
||||
});
|
||||
const manualServicePackages = computed<AdminServicePricePackage[]>(() =>
|
||||
manualMeta.value.service_price_packages.find((item) => item.service_provider === manualForm.value.service_provider)?.packages.filter((item) => item.is_enabled) || [],
|
||||
);
|
||||
let returnRecognitionTimer: ReturnType<typeof setTimeout> | undefined;
|
||||
|
||||
function createManualOrderForm(): AdminManualOrderCreatePayload {
|
||||
return {
|
||||
service_provider: "anxinyan",
|
||||
price_package_id: 0,
|
||||
price_package_code: "",
|
||||
product_info: {
|
||||
category_id: 0,
|
||||
brand_id: 0,
|
||||
@@ -214,6 +220,7 @@ async function ensureManualMeta() {
|
||||
try {
|
||||
const response = await adminApi.getManualOrderMeta();
|
||||
manualMeta.value = response.data;
|
||||
applyManualDefaultPackage(true);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
ElMessage.error("补录订单选项加载失败");
|
||||
@@ -222,11 +229,24 @@ async function ensureManualMeta() {
|
||||
}
|
||||
}
|
||||
|
||||
function applyManualDefaultPackage(force = false) {
|
||||
const current = manualServicePackages.value.find((item) => item.id === manualForm.value.price_package_id);
|
||||
if (current && !force) {
|
||||
manualForm.value.price_package_code = current.package_code;
|
||||
return;
|
||||
}
|
||||
|
||||
const target = manualServicePackages.value.find((item) => item.is_default) || manualServicePackages.value[0];
|
||||
manualForm.value.price_package_id = target?.id || 0;
|
||||
manualForm.value.price_package_code = target?.package_code || "";
|
||||
}
|
||||
|
||||
async function openManualDialog() {
|
||||
manualForm.value = createManualOrderForm();
|
||||
manualAddressRecognitionText.value = "";
|
||||
manualDialogVisible.value = true;
|
||||
await ensureManualMeta();
|
||||
applyManualDefaultPackage(true);
|
||||
}
|
||||
|
||||
async function ensureExpressCompanyOptions() {
|
||||
@@ -260,6 +280,10 @@ function applyRecognizedManualAddress() {
|
||||
|
||||
function validateManualForm() {
|
||||
const form = manualForm.value;
|
||||
if (!form.price_package_id) {
|
||||
ElMessage.warning("请选择价格套餐");
|
||||
return false;
|
||||
}
|
||||
if (!form.product_info.category_id) {
|
||||
ElMessage.warning("请选择品类");
|
||||
return false;
|
||||
@@ -474,6 +498,10 @@ watch(returnTrackingNo, () => {
|
||||
}
|
||||
});
|
||||
|
||||
watch(() => manualForm.value.service_provider, () => {
|
||||
applyManualDefaultPackage(true);
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (returnRecognitionTimer) {
|
||||
clearTimeout(returnRecognitionTimer);
|
||||
@@ -523,6 +551,9 @@ onMounted(fetchOrders);
|
||||
<el-table-column prop="appraisal_no" label="鉴定单号" min-width="180" />
|
||||
<el-table-column prop="product_name" label="商品名称" min-width="220" />
|
||||
<el-table-column prop="service_provider_text" label="服务类型" min-width="120" />
|
||||
<el-table-column prop="price_package_name" label="价格套餐" min-width="150">
|
||||
<template #default="{ row }">{{ row.price_package_name || "-" }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="下单渠道" min-width="150">
|
||||
<template #default="{ row }">
|
||||
<span>{{ row.source_channel_text }}</span>
|
||||
@@ -615,6 +646,10 @@ onMounted(fetchOrders);
|
||||
<div class="order-detail-item__label">服务类型</div>
|
||||
<div class="order-detail-item__value">{{ detail.order_info.service_provider_text }}</div>
|
||||
</div>
|
||||
<div class="order-detail-item">
|
||||
<div class="order-detail-item__label">价格套餐</div>
|
||||
<div class="order-detail-item__value">{{ detail.order_info.price_package_name || "-" }}</div>
|
||||
</div>
|
||||
<div class="order-detail-item">
|
||||
<div class="order-detail-item__label">下单渠道</div>
|
||||
<div class="order-detail-item__value">{{ detail.order_info.source_channel_text || "-" }}</div>
|
||||
@@ -966,6 +1001,21 @@ onMounted(fetchOrders);
|
||||
<el-option label="中检鉴定" value="zhongjian" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="价格套餐">
|
||||
<el-select
|
||||
v-model="manualForm.price_package_id"
|
||||
style="width: 100%"
|
||||
:disabled="manualServicePackages.length === 0"
|
||||
@change="applyManualDefaultPackage(false)"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in manualServicePackages"
|
||||
:key="item.id"
|
||||
:label="`${item.package_name} / ¥${item.price}`"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="品类">
|
||||
<el-select v-model="manualForm.product_info.category_id" filterable style="width: 100%">
|
||||
<el-option v-for="item in manualMeta.categories" :key="item.id" :label="item.name" :value="item.id" />
|
||||
|
||||
256
admin-web/src/pages/service-prices/index.vue
Normal file
256
admin-web/src/pages/service-prices/index.vue
Normal file
@@ -0,0 +1,256 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, reactive, ref } from "vue";
|
||||
import { Edit, Plus, Star } from "@element-plus/icons-vue";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { adminApi, type AdminServicePricePackage, type AdminServicePricePayload } from "../../api/admin";
|
||||
|
||||
const loading = ref(false);
|
||||
const submitting = ref(false);
|
||||
const dialogVisible = ref(false);
|
||||
const activeProvider = ref("anxinyan");
|
||||
const providers = ref<Array<{ service_provider: string; service_provider_text: string; sla_hours: number }>>([]);
|
||||
const packages = ref<AdminServicePricePackage[]>([]);
|
||||
|
||||
const form = reactive<AdminServicePricePayload>({
|
||||
service_provider: "anxinyan",
|
||||
package_name: "",
|
||||
package_code: "",
|
||||
price: 0,
|
||||
description: "",
|
||||
is_enabled: true,
|
||||
is_default: false,
|
||||
sort_order: 0,
|
||||
});
|
||||
|
||||
const filteredPackages = computed(() => packages.value.filter((item) => item.service_provider === activeProvider.value));
|
||||
const activeProviderText = computed(() => providerText(activeProvider.value));
|
||||
|
||||
function providerText(serviceProvider: string) {
|
||||
return providers.value.find((item) => item.service_provider === serviceProvider)?.service_provider_text || serviceProvider;
|
||||
}
|
||||
|
||||
function formatMoney(value: number) {
|
||||
const amount = Number(value || 0);
|
||||
return Number.isInteger(amount) ? amount.toFixed(0) : amount.toFixed(2);
|
||||
}
|
||||
|
||||
function defaultPackageCode(serviceProvider: string) {
|
||||
return serviceProvider === "zhongjian" ? "zhongjian_" : "anxinyan_";
|
||||
}
|
||||
|
||||
async function fetchPackages() {
|
||||
loading.value = true;
|
||||
try {
|
||||
const response = await adminApi.getServicePricePackages();
|
||||
providers.value = response.data.providers;
|
||||
packages.value = response.data.list;
|
||||
if (!providers.value.some((item) => item.service_provider === activeProvider.value)) {
|
||||
activeProvider.value = providers.value[0]?.service_provider || "anxinyan";
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
ElMessage.error("服务价格加载失败");
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function resetForm(serviceProvider = activeProvider.value) {
|
||||
form.id = undefined;
|
||||
form.service_provider = serviceProvider;
|
||||
form.package_name = "";
|
||||
form.package_code = defaultPackageCode(serviceProvider);
|
||||
form.price = 0;
|
||||
form.description = "";
|
||||
form.is_enabled = true;
|
||||
form.is_default = filteredPackages.value.length === 0;
|
||||
form.sort_order = filteredPackages.value.length + 1;
|
||||
}
|
||||
|
||||
function openDialog(row?: AdminServicePricePackage) {
|
||||
if (row) {
|
||||
form.id = row.id;
|
||||
form.service_provider = row.service_provider;
|
||||
form.package_name = row.package_name;
|
||||
form.package_code = row.package_code;
|
||||
form.price = row.price;
|
||||
form.description = row.description;
|
||||
form.is_enabled = row.is_enabled;
|
||||
form.is_default = row.is_default;
|
||||
form.sort_order = row.sort_order;
|
||||
} else {
|
||||
resetForm(activeProvider.value);
|
||||
}
|
||||
dialogVisible.value = true;
|
||||
}
|
||||
|
||||
async function submit() {
|
||||
submitting.value = true;
|
||||
try {
|
||||
await adminApi.saveServicePricePackage({ ...form });
|
||||
ElMessage.success(form.id ? "套餐已更新" : "套餐已创建");
|
||||
dialogVisible.value = false;
|
||||
await fetchPackages();
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
ElMessage.error("套餐保存失败");
|
||||
} finally {
|
||||
submitting.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function updateStatus(row: AdminServicePricePackage, isEnabled: boolean) {
|
||||
try {
|
||||
await adminApi.updateServicePricePackageStatus(row.id, isEnabled);
|
||||
ElMessage.success(isEnabled ? "套餐已启用" : "套餐已停用");
|
||||
await fetchPackages();
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
ElMessage.error("套餐状态更新失败");
|
||||
await fetchPackages();
|
||||
}
|
||||
}
|
||||
|
||||
async function setDefault(row: AdminServicePricePackage) {
|
||||
try {
|
||||
await ElMessageBox.confirm(`确认将「${row.package_name}」设为${row.service_provider_text}默认套餐?`, "设置默认套餐", {
|
||||
type: "warning",
|
||||
confirmButtonText: "确认",
|
||||
cancelButtonText: "取消",
|
||||
});
|
||||
await adminApi.setDefaultServicePricePackage(row.id);
|
||||
ElMessage.success("默认套餐已更新");
|
||||
await fetchPackages();
|
||||
} catch (error) {
|
||||
if (error !== "cancel") {
|
||||
console.error(error);
|
||||
ElMessage.error("默认套餐设置失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(fetchPackages);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-loading="loading" class="service-prices-page">
|
||||
<el-card class="panel-card" shadow="never">
|
||||
<div class="service-prices-toolbar">
|
||||
<el-tabs v-model="activeProvider" class="service-prices-tabs">
|
||||
<el-tab-pane v-for="provider in providers" :key="provider.service_provider" :label="provider.service_provider_text" :name="provider.service_provider" />
|
||||
</el-tabs>
|
||||
<el-button type="primary" :icon="Plus" @click="openDialog()">新增套餐</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-card class="panel-card orders-table" shadow="never">
|
||||
<el-table :data="filteredPackages" stripe>
|
||||
<el-table-column prop="package_name" label="套餐名称" min-width="180" />
|
||||
<el-table-column prop="package_code" label="套餐编码" min-width="160" />
|
||||
<el-table-column label="服务方" min-width="120">
|
||||
<template #default="{ row }">{{ row.service_provider_text }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="价格" min-width="120">
|
||||
<template #default="{ row }">¥{{ formatMoney(row.price) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" min-width="160">
|
||||
<template #default="{ row }">
|
||||
<el-space>
|
||||
<el-tag :type="row.is_enabled ? 'success' : 'info'">{{ row.is_enabled ? "启用" : "停用" }}</el-tag>
|
||||
<el-tag v-if="row.is_default" type="warning">默认</el-tag>
|
||||
</el-space>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="sort_order" label="排序" min-width="90" />
|
||||
<el-table-column prop="description" label="说明" min-width="220" show-overflow-tooltip />
|
||||
<el-table-column label="操作" fixed="right" width="250">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" :icon="Edit" @click="openDialog(row)">编辑</el-button>
|
||||
<el-button link :type="row.is_enabled ? 'warning' : 'success'" @click="updateStatus(row, !row.is_enabled)">
|
||||
{{ row.is_enabled ? "停用" : "启用" }}
|
||||
</el-button>
|
||||
<el-button link type="primary" :icon="Star" :disabled="row.is_default || !row.is_enabled" @click="setDefault(row)">设默认</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<template #empty>
|
||||
<el-empty :description="`${activeProviderText}暂无价格套餐`" />
|
||||
</template>
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-model="dialogVisible" :title="form.id ? '编辑服务价格套餐' : '新增服务价格套餐'" width="640px" destroy-on-close>
|
||||
<el-form label-position="top">
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="服务方">
|
||||
<el-select v-model="form.service_provider" :disabled="Boolean(form.id)" style="width: 100%">
|
||||
<el-option v-for="provider in providers" :key="provider.service_provider" :label="provider.service_provider_text" :value="provider.service_provider" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="排序">
|
||||
<el-input v-model.number="form.sort_order" type="number" placeholder="越小越靠前" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="套餐名称">
|
||||
<el-input v-model="form.package_name" maxlength="128" placeholder="例如 安心验基础套餐" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="套餐编码">
|
||||
<el-input v-model="form.package_code" maxlength="64" placeholder="例如 anxinyan_basic" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="价格">
|
||||
<el-input-number v-model="form.price" :min="0" :precision="2" :step="1" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="状态">
|
||||
<el-switch v-model="form.is_enabled" inline-prompt active-text="启用" inactive-text="停用" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="说明">
|
||||
<el-input v-model="form.description" type="textarea" :rows="4" maxlength="500" show-word-limit placeholder="可填写适用范围或套餐说明" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="默认套餐">
|
||||
<el-switch v-model="form.is_default" :disabled="!form.is_enabled" inline-prompt active-text="默认" inactive-text="普通" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitting" @click="submit">保存</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.service-prices-page {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.service-prices-toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.service-prices-tabs {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.service-prices-tabs :deep(.el-tabs__header) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -86,13 +86,14 @@ function buildH5OAuthRedirectUrl(pageBaseUrl: string) {
|
||||
}
|
||||
|
||||
function applyDerivedConfigValues(group: AdminSystemConfigGroupItem) {
|
||||
if (group.group_code !== "h5") return;
|
||||
if (group.group_code === "h5") {
|
||||
const pageBaseUrl = group.items.find((item) => item.config_key === "page_base_url");
|
||||
const oauthRedirectUrl = group.items.find((item) => item.config_key === "oauth_redirect_url");
|
||||
if (!oauthRedirectUrl) return;
|
||||
|
||||
const pageBaseUrl = group.items.find((item) => item.config_key === "page_base_url");
|
||||
const oauthRedirectUrl = group.items.find((item) => item.config_key === "oauth_redirect_url");
|
||||
if (!oauthRedirectUrl) return;
|
||||
|
||||
oauthRedirectUrl.value = buildH5OAuthRedirectUrl(pageBaseUrl?.value || "");
|
||||
oauthRedirectUrl.value = buildH5OAuthRedirectUrl(pageBaseUrl?.value || "");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
function handleFieldValueChange(
|
||||
@@ -120,7 +121,7 @@ async function saveGroup(group: AdminSystemConfigGroupItem) {
|
||||
ElMessage.success(`${group.group_name}已保存`);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
ElMessage.error(`${group.group_name}保存失败`);
|
||||
ElMessage.error(error instanceof Error ? error.message : `${group.group_name}保存失败`);
|
||||
} finally {
|
||||
savingGroupCode.value = "";
|
||||
}
|
||||
@@ -262,7 +263,7 @@ onMounted(fetchConfigs);
|
||||
v-else-if="item.field_type !== 'textarea'"
|
||||
:model-value="item.value"
|
||||
:type="item.field_type === 'password' ? 'password' : 'text'"
|
||||
show-password
|
||||
:show-password="item.field_type === 'password'"
|
||||
:disabled="item.read_only"
|
||||
:placeholder="item.placeholder"
|
||||
@update:model-value="handleFieldValueChange(group, item, $event)"
|
||||
|
||||
@@ -113,6 +113,16 @@ const adminChildren = [
|
||||
permission: "warehouses.manage",
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "service-prices",
|
||||
name: "service-prices",
|
||||
component: () => import("../pages/service-prices/index.vue"),
|
||||
meta: {
|
||||
title: "服务价格",
|
||||
desc: "维护安心验与中检服务的可选价格套餐。",
|
||||
permission: "service_prices.manage",
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "express-companies",
|
||||
name: "express-companies",
|
||||
|
||||
Reference in New Issue
Block a user