优化webman-buildadmin框架
This commit is contained in:
@@ -143,6 +143,10 @@ class Crud extends Backend
|
|||||||
$this->langTsData['zh-cn']['quick Search Fields'] = implode('、', $quickSearchFieldZhCnTitle);
|
$this->langTsData['zh-cn']['quick Search Fields'] = implode('、', $quickSearchFieldZhCnTitle);
|
||||||
$this->controllerData['attr']['quickSearchField'] = $quickSearchField;
|
$this->controllerData['attr']['quickSearchField'] = $quickSearchField;
|
||||||
|
|
||||||
|
if (array_key_exists('admin_id', $fieldsMap)) {
|
||||||
|
$this->controllerData['attr']['autoFillAdminId'] = true;
|
||||||
|
}
|
||||||
|
|
||||||
$weighKey = array_search('weigh', $fieldsMap);
|
$weighKey = array_search('weigh', $fieldsMap);
|
||||||
if ($weighKey !== false) {
|
if ($weighKey !== false) {
|
||||||
$this->indexVueData['enableDragSort'] = true;
|
$this->indexVueData['enableDragSort'] = true;
|
||||||
|
|||||||
@@ -96,11 +96,12 @@ class Helper
|
|||||||
|
|
||||||
protected static array $attrType = [
|
protected static array $attrType = [
|
||||||
'controller' => [
|
'controller' => [
|
||||||
'preExcludeFields' => 'array|string',
|
'preExcludeFields' => 'array|string',
|
||||||
'quickSearchField' => 'string|array',
|
'quickSearchField' => 'string|array',
|
||||||
'withJoinTable' => 'array',
|
'withJoinTable' => 'array',
|
||||||
'defaultSortField' => 'string|array',
|
'defaultSortField' => 'string|array',
|
||||||
'weighField' => 'string',
|
'weighField' => 'string',
|
||||||
|
'autoFillAdminId' => 'bool',
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -692,7 +693,14 @@ class Helper
|
|||||||
$modelMethodList = isset($modelData['relationMethodList']) ? array_merge($modelData['methods'], $modelData['relationMethodList']) : $modelData['methods'];
|
$modelMethodList = isset($modelData['relationMethodList']) ? array_merge($modelData['methods'], $modelData['relationMethodList']) : $modelData['methods'];
|
||||||
$modelData['methods'] = $modelMethodList ? "\n" . implode("\n", $modelMethodList) : '';
|
$modelData['methods'] = $modelMethodList ? "\n" . implode("\n", $modelMethodList) : '';
|
||||||
$modelData['append'] = self::buildModelAppend($modelData['append'] ?? []);
|
$modelData['append'] = self::buildModelAppend($modelData['append'] ?? []);
|
||||||
$modelData['fieldType'] = self::buildModelFieldType($modelData['fieldType'] ?? []);
|
$fieldType = $modelData['fieldType'] ?? [];
|
||||||
|
if ($modelData['autoWriteTimestamp'] == 'true') {
|
||||||
|
$fieldType = array_merge(
|
||||||
|
['create_time' => 'integer', 'update_time' => 'integer'],
|
||||||
|
$fieldType
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$modelData['fieldType'] = self::buildModelFieldType($fieldType);
|
||||||
|
|
||||||
if (isset($modelData['beforeInsertMixins']['snowflake'])) {
|
if (isset($modelData['beforeInsertMixins']['snowflake'])) {
|
||||||
$modelData['beforeInsert'] = self::assembleStub('mixins/model/beforeInsert', [
|
$modelData['beforeInsert'] = self::assembleStub('mixins/model/beforeInsert', [
|
||||||
@@ -726,6 +734,9 @@ class Helper
|
|||||||
$attrType = self::$attrType['controller'][$key] ?? '';
|
$attrType = self::$attrType['controller'][$key] ?? '';
|
||||||
if (is_array($item)) {
|
if (is_array($item)) {
|
||||||
$controllerAttr .= "\n" . self::tab() . "protected $attrType \$$key = ['" . implode("', '", $item) . "'];\n";
|
$controllerAttr .= "\n" . self::tab() . "protected $attrType \$$key = ['" . implode("', '", $item) . "'];\n";
|
||||||
|
} elseif ($attrType === 'bool') {
|
||||||
|
$val = ($item === true || $item === 'true') ? 'true' : 'false';
|
||||||
|
$controllerAttr .= "\n" . self::tab() . "protected $attrType \$$key = $val;\n";
|
||||||
} elseif ($item) {
|
} elseif ($item) {
|
||||||
$controllerAttr .= "\n" . self::tab() . "protected $attrType \$$key = '$item';\n";
|
$controllerAttr .= "\n" . self::tab() . "protected $attrType \$$key = '$item';\n";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ class {%className%} extends Backend
|
|||||||
{%methods%}
|
{%methods%}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 若需重写查看、编辑、删除等方法,请复制 @see \app\admin\library\traits\Backend 中对应的方法至此进行重写
|
* add、edit、del、sortable 已由父类 Backend 实现,无需重写即可直接使用
|
||||||
|
* 若需重写,请确保调用 initializeBackend($request) 并传入 Request 参数
|
||||||
|
* 若模型有 admin_id 字段需自动填充,可设置 protected bool $autoFillAdminId = true
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
@@ -97,6 +97,9 @@ trait Backend
|
|||||||
if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
|
if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
|
||||||
$data[$this->dataLimitField] = $this->auth->id;
|
$data[$this->dataLimitField] = $this->auth->id;
|
||||||
}
|
}
|
||||||
|
if ($this->autoFillAdminId && $this->dataLimitField === 'admin_id') {
|
||||||
|
$data['admin_id'] = $this->auth->id;
|
||||||
|
}
|
||||||
|
|
||||||
$result = false;
|
$result = false;
|
||||||
$this->model->startTrans();
|
$this->model->startTrans();
|
||||||
|
|||||||
@@ -80,6 +80,11 @@ class Backend extends Api
|
|||||||
*/
|
*/
|
||||||
protected bool $dataLimitFieldAutoFill = true;
|
protected bool $dataLimitFieldAutoFill = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加时自动填充 admin_id(当模型有 admin_id 字段但无数据权限限制时使用)
|
||||||
|
*/
|
||||||
|
protected bool $autoFillAdminId = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查看请求返回的主表字段
|
* 查看请求返回的主表字段
|
||||||
*/
|
*/
|
||||||
@@ -357,8 +362,10 @@ class Backend extends Api
|
|||||||
$order = $order ?: $this->defaultSortField;
|
$order = $order ?: $this->defaultSortField;
|
||||||
|
|
||||||
if ($order && is_string($order)) {
|
if ($order && is_string($order)) {
|
||||||
$order = explode(',', $order);
|
$orderParts = explode(',', $order);
|
||||||
$order = [$order[0] => $order[1] ?? 'asc'];
|
$orderField = trim($orderParts[0] ?? '');
|
||||||
|
$orderDir = trim($orderParts[1] ?? 'asc');
|
||||||
|
$order = $orderField !== '' ? [$orderField => $orderDir ?: 'asc'] : [];
|
||||||
}
|
}
|
||||||
if (!$this->orderGuarantee) {
|
if (!$this->orderGuarantee) {
|
||||||
$this->orderGuarantee = [$pk => 'desc'];
|
$this->orderGuarantee = [$pk => 'desc'];
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class User extends Model
|
|||||||
|
|
||||||
public function getAvatarAttr($value): string
|
public function getAvatarAttr($value): string
|
||||||
{
|
{
|
||||||
return full_url($value, false, config('buildadmin.default_avatar'));
|
return full_url($value ?? '', false, config('buildadmin.default_avatar'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setAvatarAttr($value): string
|
public function setAvatarAttr($value): string
|
||||||
|
|||||||
@@ -3,18 +3,18 @@
|
|||||||
<el-switch
|
<el-switch
|
||||||
v-if="field.prop"
|
v-if="field.prop"
|
||||||
@change="onChange"
|
@change="onChange"
|
||||||
:model-value="cellValue"
|
:model-value="displayValue"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
active-value="1"
|
active-value="1"
|
||||||
inactive-value="0"
|
inactive-value="0"
|
||||||
v-bind="invokeTableContextDataFun(field.customRenderAttr?.switch, { row, field, cellValue, column, index })"
|
v-bind="invokeTableContextDataFun(field.customRenderAttr?.switch, { row, field, cellValue: displayValue, column, index })"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { TableColumnCtx } from 'element-plus'
|
import { TableColumnCtx } from 'element-plus'
|
||||||
import { inject, ref } from 'vue'
|
import { inject, ref, onMounted } from 'vue'
|
||||||
import { getCellValue, invokeTableContextDataFun } from '/@/components/table/index'
|
import { getCellValue, invokeTableContextDataFun } from '/@/components/table/index'
|
||||||
import type baTableClass from '/@/utils/baTable'
|
import type baTableClass from '/@/utils/baTable'
|
||||||
|
|
||||||
@@ -28,13 +28,27 @@ interface Props {
|
|||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const props = defineProps<Props>()
|
const props = defineProps<Props>()
|
||||||
const baTable = inject('baTable') as baTableClass
|
const baTable = inject('baTable') as baTableClass
|
||||||
const cellValue = ref(getCellValue(props.row, props.field, props.column, props.index))
|
|
||||||
|
|
||||||
if (typeof cellValue.value === 'number') {
|
const rawValue = getCellValue(props.row, props.field, props.column, props.index)
|
||||||
cellValue.value = cellValue.value.toString()
|
const normalized = (v: unknown) => {
|
||||||
|
if (typeof v === 'number') return v.toString()
|
||||||
|
if (v === null || v === undefined || v === '') return '0'
|
||||||
|
return String(v)
|
||||||
}
|
}
|
||||||
|
const displayValue = ref(normalized(rawValue))
|
||||||
|
|
||||||
|
const mountedAt = ref(0)
|
||||||
|
onMounted(() => {
|
||||||
|
mountedAt.value = Date.now()
|
||||||
|
})
|
||||||
|
|
||||||
const onChange = (value: string | number | boolean) => {
|
const onChange = (value: string | number | boolean) => {
|
||||||
|
const newVal = String(value)
|
||||||
|
const prevVal = normalized(rawValue)
|
||||||
|
if (prevVal === newVal) return
|
||||||
|
if ([null, undefined, ''].includes(rawValue) && newVal === '0') return
|
||||||
|
if (Date.now() - mountedAt.value < 150) return
|
||||||
|
|
||||||
loading.value = true
|
loading.value = true
|
||||||
baTable.api
|
baTable.api
|
||||||
.postData('edit', {
|
.postData('edit', {
|
||||||
@@ -42,7 +56,7 @@ const onChange = (value: string | number | boolean) => {
|
|||||||
[props.field.prop!]: value,
|
[props.field.prop!]: value,
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
cellValue.value = value
|
displayValue.value = newVal
|
||||||
baTable.onTableAction('field-change', { value: value, ...props })
|
baTable.onTableAction('field-change', { value: value, ...props })
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user