| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- <?php
- class DBColumn {
- public string $field;
- public string $type;
- public ?string $collation;
- public ?string $key;
- public ?string $default;
- public ?string $extra;
- public ?string $privileges;
- public string $comment;
- public ?string $wholeComment;
- public string $allowNull;
- public string $line = '<br/>';
- public function __construct(array $info) {
- $this->field = $info['Field'];
- $this->type = $info['Type'];
- $this->collation = $info['Collation'];
- $this->key = $info['Key'];
- $this->default = $info['Default'];
- $this->extra = $info['Extra'];
- $this->privileges = $info['Privileges'];
- $this->wholeComment = $info['Comment'];
- $this->comment = $info['Comment'] ? explode(' ', $info['Comment'])[0] : '';
- $this->allowNull = empty($info['Null']) || $info['Null'] == 'YES';
- }
- /**
- * 获取字段的ts类型
- * @return string
- */
- public function getTsType() :string
- {
- $type = 'string';
- if (str_contains($this->field, 'ids')) {
- $type = 'number[]';
- } elseif (Helper::hasAnyString($this->type, ['int', 'decimal', 'double', 'float'])) {
- if (Helper::hasAnyString($this->field, ['is_', 'can_', 'has_', 'status', '_status', 'type'])) {
- $type = '0|1';
- } else {
- $type = 'number';
- }
- }
- return $type;
- }
- /**
- * 获取字段的ts定义
- * @return string
- */
- public function getTsDefine() :string
- {
- $type = $this->getTsType();
- $temp = $this->field . ": {$type}";
- $comment = $this->comment ? " // {$this->comment}" : '';
- return $temp . " {$comment}";
- }
- /**
- * 获取字段的默认值
- * @return string
- */
- public function getDefaultValue() :string
- {
- $type = $this->getTsType();
- if (in_array($type, ['number', '0|1'])) {
- $default = $this->default ? : 0;
- return $this->field . ": {$default},";
- } else {
- $default = $this->default ? : '';
- return $this->field . ": '{$default}',";
- }
- }
- /**
- * 获取字段的表单html和验证规则
- * TODO: 这里可能要vue,react, layui, ... 代码
- * @return array
- */
- public function getFormHtmlAndRule() :array
- {
- $html = '';
- $rule = [];
- if (!$this->allowNull) {
- $rule[] = "{ required: true, message: '请输入{$this->comment}', trigger: 'blur' }";
- }
- $type = $this->getTsType();
- if ($type == 'string') {
- // 图片处理
- if (Helper::hasAnyString($this->field, ['img', 'image'])) {
- // 单张图片
- } elseif (Helper::hasAnyString($this->field, ['images', 'imgs'])) {
- // 多张图片
- } elseif (Helper::hasAnyString($this->field, ['_id'])) {
- // select
- } elseif (Helper::hasAnyString($this->field, ['ids'])) {
- // 多选框
- } else {
- // input
- $inputType = 'text';
- $max = $this->getMaxLength();
- $min = $this->getMinLength();
- if ($max > 64) {
- $inputType = 'textarea';
- }
- $html = $this->getInputHtml($inputType, $max);
- // rule
- if ($min > 0 && $max > 0) {
- $rule[] = "{ min: {$min}, max: {$max}, message: '长度在{$min}到{$max}个字符', trigger: 'blur' }";
- } elseif ($min > 0) {
- $rule[] = "{ min: {$min}, message: '长度最少{$min}个字符', trigger: 'blur' }";
- } elseif ($max > 0) {
- $rule[] = "{ max: {$max}, message: '长度最多{$max}个字符', trigger: 'blur' }";
- }
- }
- } elseif ($type == 'number') {
- $html = $this->getInputHtml('number');
- } elseif ($type == '0|1') {
- $rule = '';
- $html = $this->getSelectHtml();
- }
- $ruleHtml = '';
- if ($rule) {
- $rule = implode(',', $rule);
- $ruleHtml = $this->field . ": [{$rule}],";
- }
- return [$html, $ruleHtml];
- }
- /**
- * 获取字段的表单html和验证规则
- * TODO: 这里可能要vue,react, layui, ... 代码
- * @return array
- */
- public function getDetailHtml() :string
- {
- $html = "{{ info.{$this->field} }}";
- $type = $this->getTsType();
- $textType = 'string';
- if ($type == 'string') {
- // 图片处理
- if (Helper::hasAnyString($this->field, ['img', 'image'])) {
- // 单张图片
- } elseif (Helper::hasAnyString($this->field, ['images', 'imgs'])) {
- // 多张图片
- } elseif (Helper::hasAnyString($this->field, ['_id'])) {
- // select
- } elseif (Helper::hasAnyString($this->field, ['ids'])) {
- // 多选框
- } else {
- // input
- $max = $this->getMaxLength();
- if ($max > 64 || Helper::hasAnyString($this->field, ['text'])) {
- $textType = 'textarea';
- }
- }
- } elseif ($type == '0|1') {
- $data = $this->getCommentArr();
- $html = "{{ info.{$this->field} ? '{$data[1]}' : '$data[0]'}}";
- }
- $elHtml = $textType != 'textarea' ? ':xs="24" :lg="8" :sm="12"' : ':span=24';
- return <<<Detail
- <el-col {$elHtml}>
- <label>{$this->comment}:</label> <span>{$html}</span>
- </el-col>
- Detail;
- }
- /**
- * 生成input
- * @param string $type
- * @param int $maxLength
- * @return string
- */
- public function getInputHtml(string $type, int $maxLength = 0): string
- {
- $maxLengthHtml = '';
- if ($type != 'number' && $maxLength > 0) {
- $maxLengthHtml = "maxlength='{$maxLength}'";
- }
- $elHtml = $type != 'textarea' ? ':xs="24" :lg="8" :sm="12"' : ':span=24';
- return <<<input
- <el-col {$elHtml}>
- <ElFormItem label="{$this->comment}" prop="{$this->field}">
- <ElInput v-model="formData.{$this->field}" $maxLengthHtml type="{$type}"/>
- </ElFormItem> ≤,≤≥≤ rmItem>
- </el-col>
- input;
- }
- /**
- * 生成select
- * @return string
- */
- public function getSelectHtml(): string
- {
- $selectData = $this->getCommentArr();
- if (!$selectData) {
- return '';
- }
- $data = '';
- foreach ($selectData as $key => $item) {
- if (is_numeric($key)) {
- $data.= "{label: '{$item}', value: {$key}}, ";
- } else {
- $data.= "{label: '{$item}', value: '{$key}'},";
- }
- }
- return <<<select
- <el-col :xs="24" :lg="8" :sm="12">
- <ElFormItem label="{$this->comment}" prop="{$this->field}">
- <el-select v-model="formData.{$this->field}" placeholder="请选择">
- <el-option v-for="item in [{$data}]" :key="item.value" :value="item.value" :label="item.label"/>
- </el-select>
- </ElFormItem>
- </el-col>
- select;
- }
- /**
- * 获取字段的最大长度
- * @return int
- */
- public function getMaxLength():int
- {
- preg_match('/(\d+)/', $this->type, $match);
- return $match[0] ?? 0;
- }
- /**
- * 获取字段的最小长度
- * @return int
- */
- public function getMinLength():int
- {
- return 0;
- }
- /**
- * 判断字段是否是数字字段
- * @return bool
- */
- public function isNumberFiled(): bool
- {
- $type = $this->getTsType();
- return $type == 'number' || str_contains($type, '|');
- }
- /**
- * 获取字段的注释数组
- * @return array
- */
- public function getCommentArr():array
- {
- if (!$this->isNumberFiled()) {
- return [];
- }
- $arr = [];
- preg_match_all('/(\d+\-\S+)/', $this->wholeComment, $match);
- if ($match) {
- foreach ($match[0] as $matchItem) {
- list($key, $value) = explode('-', $matchItem);
- $arr[$key] = $value;
- }
- }
- return $arr;
- }
- public function getTableAttr(): array
- {
- $JsTableArr = ['prop' => $this->field, 'label' => $this->comment];
- // 长字段列表需要添加showOverflowTooltip
- if ($this->getMaxLength() > 64 || Helper::hasAnyString($this->field, ['text'])) {
- $JsTableArr['showOverflowTooltip'] = true;
- }
- if (str_contains($this->field, 'ids')) {
- $JsTableArr = [];
- } elseif (Helper::hasAnyString($this->field, ['is', 'can', 'has', 'status'])) {
- $commentArr = $this->getCommentArr();
- if (count($commentArr) == 2) {
- $JsTableArr['formatter'] = <<<HTML
- (row) => { {$this->line}
- return h(ElTag, { type: row.{$this->field} ? 'success' : 'danger' }, () => row.{$this->field} ? '{$commentArr[1]}' : '{$commentArr[0]}') {$this->line}
- }
- HTML;
- } else {
- $JsTableArr['formatter'] = <<<HTML
- (row) => {{$this->line}
- return h(ElTag, { type: row.{$this->field} ? 'success' : 'danger' }, () => row.{$this->field} ? '是' : '否'){$this->line}
- }
- HTML;
- }
-
- }
- return $JsTableArr;
- }
- }
|