Files
xk-admin/apps/web-antd/src/views/system/system-config/index.vue
李琦 073f7f882b
Some checks failed
CI / Test (ubuntu-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Lint (ubuntu-latest) (push) Has been cancelled
CI / Lint (windows-latest) (push) Has been cancelled
CI / Check (ubuntu-latest) (push) Has been cancelled
CI / Check (windows-latest) (push) Has been cancelled
CI / CI OK (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Website on push / Deploy Push Playground Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Docs Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Antd Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Element Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Naive Ftp (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
1. 推广员功能增强
2026-06-18 15:05:02 +08:00

156 lines
5.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import { Page } from '@vben/common-ui';
import { Button, Card, Input, InputNumber, message, Radio, Space, Switch, Tag } from 'ant-design-vue';
import type { QuickDiscountOption } from '#/utils/pricePercentAdjust';
import { getSystemConfigList, saveSystemConfig } from './api';
defineOptions({ name: 'SystemConfig' });
const loading = ref(false);
const saving = ref(false);
const scope = ref<'both' | 'sale_only'>('sale_only');
const quickOptions = ref<QuickDiscountOption[]>([
{ name: '九五折', value: 95 },
{ name: '九折', value: 90 },
{ name: '八五折', value: 85 },
{ name: '八折', value: 80 },
{ name: '涨10%', value: 110 },
{ name: '涨20%', value: 120 },
]);
const newQuickName = ref('');
const newQuickValue = ref<number | null>(null);
const inputAutoAuditPass = ref(true);
function parseQuickOptions(raw: unknown): QuickDiscountOption[] {
if (typeof raw === 'string') {
try {
const parsed = JSON.parse(raw);
return parseQuickOptions(parsed);
} catch {
return quickOptions.value;
}
}
if (!Array.isArray(raw)) return quickOptions.value;
const list: QuickDiscountOption[] = [];
for (const item of raw) {
if (item && typeof item === 'object' && 'value' in item) {
const val = Number((item as QuickDiscountOption).value);
if (val > 0) list.push({ name: String((item as QuickDiscountOption).name || `${val}%`), value: val });
} else if (typeof item === 'number' && item > 0) {
list.push({ name: `${item}%`, value: item });
}
}
return list.length ? list : quickOptions.value;
}
async function load() {
loading.value = true;
try {
const list = await getSystemConfigList();
const rows = Array.isArray(list) ? list : list?.data || [];
for (const row of rows) {
if (row.config_key === 'order_price_adjust_scope') {
scope.value = row.config_value === 'both' ? 'both' : 'sale_only';
}
if (row.config_key === 'order_discount_quick_options') {
quickOptions.value = parseQuickOptions(row.config_value);
}
if (row.config_key === 'input_auto_audit_pass') {
inputAutoAuditPass.value = row.config_value === '1' || row.config_value === true || row.config_value === 'true';
}
}
} finally {
loading.value = false;
}
}
function addQuick() {
const v = Number(newQuickValue.value);
const name = String(newQuickName.value || '').trim();
if (!name || !v || v <= 0) {
message.warning('请填写名称和有效比例值');
return;
}
if (!quickOptions.value.some((o) => o.value === v && o.name === name)) {
quickOptions.value = [...quickOptions.value, { name, value: v }].sort((a, b) => b.value - a.value);
}
newQuickName.value = '';
newQuickValue.value = null;
}
function removeQuick(opt: QuickDiscountOption) {
quickOptions.value = quickOptions.value.filter((o) => !(o.name === opt.name && o.value === opt.value));
}
async function handleSave() {
saving.value = true;
try {
await saveSystemConfig([
{ config_key: 'order_price_adjust_scope', config_value: scope.value },
{
config_key: 'order_discount_quick_options',
config_value: JSON.stringify(quickOptions.value),
},
{
config_key: 'input_auto_audit_pass',
config_value: inputAutoAuditPass.value ? '1' : '0',
},
]);
message.success('保存成功');
} finally {
saving.value = false;
}
}
onMounted(load);
</script>
<template>
<Page auto-content-height title="系统配置">
<Card :loading="loading" title="订单调价配置">
<div class="mb-6">
<div class="mb-2 font-medium">订单打折时价格浮动范围</div>
<Radio.Group v-model:value="scope">
<Radio value="sale_only">仅售价浮动</Radio>
<Radio value="both">供货价与售价一起浮动</Radio>
</Radio.Group>
</div>
<div class="mb-6">
<div class="mb-2 font-medium">调价快捷选项name 展示名value 比例100=原价90=九折120=涨20%</div>
<Space wrap class="mb-3">
<Tag
v-for="item in quickOptions"
:key="item.name + item.value"
closable
:color="item.value < 100 ? 'processing' : 'warning'"
@close="removeQuick(item)"
>
{{ item.name }}{{ item.value }}%
</Tag>
</Space>
<Space wrap>
<Input v-model:value="newQuickName" placeholder="名称,如九折" style="width: 140px" />
<InputNumber v-model:value="newQuickValue" :min="1" :max="500" placeholder="比例值" />
<Button @click="addQuick">添加快捷项</Button>
</Space>
</div>
<Button type="primary" :loading="saving" @click="handleSave">保存配置</Button>
</Card>
<Card :loading="loading" class="mt-4" title="录入审核配置">
<div class="mb-2 font-medium">诊所/医生信息预填录入后是否自动通过审核</div>
<Switch v-model:checked="inputAutoAuditPass" checked-children="" un-checked-children="" />
<div class="mt-4">
<Button type="primary" :loading="saving" @click="handleSave">保存配置</Button>
</div>
</Card>
</Page>
</template>