up. config name existence.

This commit is contained in:
u2nyakim 2025-08-26 10:05:45 +08:00
parent b9b3c7f186
commit 0133335794
4 changed files with 104 additions and 25 deletions

View File

@ -5,6 +5,8 @@ namespace app\controller\admin\system;
use app\BaseController; use app\BaseController;
use app\entity\SysConfig; use app\entity\SysConfig;
use app\service\CurdService; use app\service\CurdService;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\response\Json; use think\response\Json;
class ConfigController extends BaseController class ConfigController extends BaseController
@ -29,7 +31,22 @@ class ConfigController extends BaseController
return $this->writeSuccess('success', $config->toArray()); return $this->writeSuccess('success', $config->toArray());
} }
public function existence()
{
$id = $this->request->get('id/d',0);
$field = $this->request->get('field/s', '');
$value = $this->request->get('value/s', '');
try {
$model = SysConfig::field('id');
if($id > 0) {
$model = $model->where('id', '<>', $id);
}
$model->where([$field => $value])->findOrFail();
} catch (ModelNotFoundException|DataNotFoundException) {
return $this->writeError("配置不存在");
}
return $this->writeSuccess('配置已存在');
}
public function add() public function add()
{ {
$data = $this->request->post([ $data = $this->request->post([

View File

@ -70,6 +70,8 @@ Route::group("adminapi", function () {
*/ */
Route::get('config$', [ConfigController::class, "list"])->name("system.listConfig"); Route::get('config$', [ConfigController::class, "list"])->name("system.listConfig");
Route::get('config/data', [ConfigController::class, "data"])->name("system.getConfigData"); Route::get('config/data', [ConfigController::class, "data"])->name("system.getConfigData");
Route::get('config/existence', [ConfigController::class, "existence"])->name("system.configExistence");
Route::post("config", [ConfigController::class, "add"])->name("system.addConfig"); Route::post("config", [ConfigController::class, "add"])->name("system.addConfig");
Route::put("config$", [ConfigController::class, "update"])->name("system.updateConfig"); Route::put("config$", [ConfigController::class, "update"])->name("system.updateConfig");
Route::delete("config/batch", [ConfigController::class, "batchDelete"])->name("system.batchDeleteConfig"); Route::delete("config/batch", [ConfigController::class, "batchDelete"])->name("system.batchDeleteConfig");

View File

@ -77,3 +77,19 @@ export async function removeConfigs(ids: number[]) {
} }
return Promise.reject(new Error(res.data.message)); return Promise.reject(new Error(res.data.message));
} }
/**
*
*/
export async function checkExistence(
field: string,
value: string,
id?: number
) {
const res = await request.get<ApiResult<unknown>>('/system/config/existence', {
params: { field, value, id }
});
if (res.data.code === 0) {
return res.data.message;
}
return Promise.reject(new Error(res.data.message));
}

View File

@ -82,7 +82,7 @@
</template> </template>
</el-col> </el-col>
<el-col :span="11" :offset="1"> <el-col :span="11" :offset="1">
<el-form-item label="BIND"> <el-form-item label="BIND" prop="itemBind">
<el-input <el-input
:rows="4" :rows="4"
type="textarea" type="textarea"
@ -90,7 +90,7 @@
placeholder="" placeholder=""
/> />
</el-form-item> </el-form-item>
<el-form-item label="Class"> <el-form-item label="Class" prop="itemClass">
<el-input <el-input
type="text" type="text"
v-model="form.itemClass" v-model="form.itemClass"
@ -105,8 +105,7 @@
placeholder="请输入渲染框Style样式" placeholder="请输入渲染框Style样式"
/> />
</el-form-item> </el-form-item>
<el-divider/> <el-card header="样式预览:" style="margin-bottom: 30px;" v-if="HIDE_FORM_ITEM_WHERE.preview()">
<el-card header="样式预览:" style="margin-bottom: 30px;">
<config-form-item <config-form-item
:name="preview.name" :name="preview.name"
:title="preview.title" :title="preview.title"
@ -124,7 +123,7 @@
</el-card> </el-card>
</el-col> </el-col>
</el-row> </el-row>
<el-form-item label="配置说明"> <el-form-item label="配置说明" v-if="HIDE_FORM_ITEM_WHERE.tips()">
<el-input <el-input
type="textarea" type="textarea"
v-model="form.tips" v-model="form.tips"
@ -150,12 +149,12 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import {ref, reactive, watch, computed} from 'vue'; import {ref, watch, computed} from 'vue';
import type {FormInstance, FormRules} from 'element-plus'; import type {FormInstance, FormRules} from 'element-plus';
import {EleMessage} from 'ele-admin-plus'; import {EleMessage} from 'ele-admin-plus';
import {useFormData} from '@/utils/use-form-data'; import {useFormData} from '@/utils/use-form-data';
import type {Config} from '@/api/system/config/model'; import type {Config} from '@/api/system/config/model';
import {addConfig, updateConfig} from '@/api/system/config'; import {addConfig, updateConfig, checkExistence} from '@/api/system/config';
import ConfigSelect from './config-select.vue'; import ConfigSelect from './config-select.vue';
import {ItemType, getItemLabel} from '@/enum/config-item-type.ts'; import {ItemType, getItemLabel} from '@/enum/config-item-type.ts';
import ConfigFormItem from "@/views/system/config-set/components/config-form-item.vue"; import ConfigFormItem from "@/views/system/config-set/components/config-form-item.vue";
@ -170,6 +169,12 @@ const HIDE_FORM_ITEM_WHERE: any = {
}, },
option: () => { option: () => {
return ['tabs', 'tabs_item'].indexOf(<string>form.type) == -1 return ['tabs', 'tabs_item'].indexOf(<string>form.type) == -1
},
tips: () => {
return ['separator', 'alert', 'card', 'collapse','tabs'].indexOf(<string>form.type) == -1
},
preview: ()=>{
return ['tabs', 'tabs_item','card', 'collapse', 'alert', 'separator'].indexOf(<string>form.type) == -1
} }
}; };
const preview = computed(() => { const preview = computed(() => {
@ -248,23 +253,62 @@ const [form, resetFields, assignFields] = useFormData<ConfigEdit>({
}); });
/** 表单验证规则 */ /** 表单验证规则 */
const rules = reactive<FormRules>({ const rules = computed<FormRules>(() => {
const obj: FormRules = {
title: [
{
required: true,
type: 'string',
message: '请输入标题',
trigger: 'blur'
}
],
name: [ name: [
{ {
required: true, required: true,
message: '请输入配置名称', message: '请输入配置名称',
type: 'string', type: 'string',
trigger: 'blur' trigger: 'blur'
},
{
type: 'string',
trigger: 'blur',
validator: (_rule: any, value: string, callback: any) => {
checkExistence('name', value, isUpdate.value ? props.data.id : null)
.then(() => {
callback(new Error('配置名称已经存在'));
})
.catch(() => {
callback();
});
}
} }
], ],
title: [ itemBind: [
{ {
required: true,
message: '请输入配置标题',
type: 'string', type: 'string',
validator: (_rule: any, value: string, callback: any) => {
if (value) {
const msg = '请输入正确的JSON格式';
try {
const obj = JSON.parse(value);
if (obj == null || typeof obj !== 'object') {
callback(msg);
return;
}
} catch (_e) {
callback(msg);
return;
}
}
callback();
},
trigger: 'blur' trigger: 'blur'
} }
] ],
};
return obj;
}); });
/** 关闭弹窗 */ /** 关闭弹窗 */