|
|
@@ -21,6 +21,388 @@ class CommonController extends Controller
|
|
|
Helper::dealCommonResult(SMS::getInstance()->send($phone, '2094847', [$code]));
|
|
|
}
|
|
|
|
|
|
+ public function actionJson()
|
|
|
+ {
|
|
|
+ $newData = [];
|
|
|
+ $data = file_get_contents(PROJECT_PATH . '/runtime/city.json');
|
|
|
+ foreach (json_decode($data, true) as $province) {
|
|
|
+ $newData[] = ['label' => $province['province'], 'value' => $province['province'], 'children' => array_map(function($city) {
|
|
|
+ return ['label' => $city['city'], 'value' => $city['city'], 'children' => array_map(function($area) {
|
|
|
+ return ['label' => $area['area'], 'value' => $area['area']];
|
|
|
+ }, $city['areas'])];
|
|
|
+ }, $province['citys'])];
|
|
|
+ }
|
|
|
+ echo json_encode($newData, JSON_UNESCAPED_UNICODE);
|
|
|
+ }
|
|
|
+
|
|
|
+ public function actionEdit()
|
|
|
+ {
|
|
|
+ $table = Helper::getGetString('t1');
|
|
|
+ if (!$table) {
|
|
|
+ Helper::error('参数错误');
|
|
|
+ }
|
|
|
+ $table = DB::formTableName($table);
|
|
|
+ $sql = "show full columns from {$table}";
|
|
|
+ $taleInfo = \Yii::app()->db->createCommand($sql)->queryAll();
|
|
|
+ if (!$taleInfo) {
|
|
|
+ Helper::error('该表不存在');
|
|
|
+ }
|
|
|
+ $excludeField = ['create_date', 'update_date', 'is_delete', 'id', 'city', 'area', 'province'];
|
|
|
+ $this->getEditHtml($taleInfo, $excludeField);
|
|
|
+ }
|
|
|
+
|
|
|
+ public function getEditHtml(array $tableFieldArr, array $excludeField = []): void
|
|
|
+ {
|
|
|
+ $data = [];
|
|
|
+ $notNullField = [];
|
|
|
+ $allowEmptyField = [];
|
|
|
+ echo '$data = [<br/>';
|
|
|
+ foreach ($tableFieldArr as $column) {
|
|
|
+ if (in_array($column['Field'], $excludeField)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $name = $column['Field'];
|
|
|
+ $tmpl = "'{$name}' => Helper::{{method}}('{$name}'),<br/>";
|
|
|
+ if (Helper::hasAnyString($column['Type'], ['decimal', 'double', 'float'])) {
|
|
|
+ $method = 'getPostFloat';
|
|
|
+ } elseif (Helper::hasAnyString($column['Type'], ['int'])) {
|
|
|
+ $method = 'getPostInt';
|
|
|
+ } elseif (Helper::hasAnyString($column['Type'], ['datetime'])) {
|
|
|
+ $method = 'getPostDatetime';
|
|
|
+ } elseif (Helper::hasAnyString($column['Type'], ['date'])) {
|
|
|
+ $method = 'getPostDate';
|
|
|
+ } else {
|
|
|
+ $method = 'getPostString';
|
|
|
+ }
|
|
|
+ echo str_replace('{{method}}', $method, $tmpl);
|
|
|
+ if ($column['Null'] == 'NO') {
|
|
|
+ $notNullField[] = $name;
|
|
|
+ }
|
|
|
+ if ($column['Default'] != null || $method == 'getPostInt') {
|
|
|
+ $allowEmptyField[] = $name;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ echo '];<br/><br/>';
|
|
|
+ echo '$notNullField = ' . json_encode($notNullField) . ';<br/>';
|
|
|
+ echo '$allowEmptyField = ' . json_encode($allowEmptyField) . ';<br/>';
|
|
|
+ }
|
|
|
+
|
|
|
+ public function actionsqlToTs()
|
|
|
+ {
|
|
|
+ $table = Helper::getGetString('t1');
|
|
|
+ if (!$table) {
|
|
|
+ Helper::error('参数错误');
|
|
|
+ }
|
|
|
+ $table = strtolower($table);
|
|
|
+ $table1 = DB::formTableName($table);
|
|
|
+ $sql = "show full columns from {$table1}";
|
|
|
+ $taleInfo = \Yii::app()->db->createCommand($sql)->queryAll();
|
|
|
+ if (!$taleInfo) {
|
|
|
+ Helper::error('该表不存在');
|
|
|
+ }
|
|
|
+ $excludeField = ['create_date', 'update_date', 'is_delete'];
|
|
|
+ echo $this->getTsInterFace($table, $taleInfo, $excludeField);
|
|
|
+ // echo $this->getTableHtml($taleInfo, $excludeField);
|
|
|
+ $editTmpl = file_get_contents(PROJECT_PATH . '/protected/runtime/edit.tmpl');
|
|
|
+ $fromExcludeField = ['create_date', 'update_date', 'is_delete', 'id', 'city', 'area', 'province'];
|
|
|
+ echo $this->getTsInterFace($table, $taleInfo, $fromExcludeField);
|
|
|
+ $formDefault = $this->getFormDefault($taleInfo, $fromExcludeField);
|
|
|
+ list($template, $rule) = $this->getFormAndRule($table, $taleInfo, $fromExcludeField);
|
|
|
+ $editTmpl = str_replace(
|
|
|
+ ['{{template}}', '{{table}}', '{{formDefault}}', '{{formRule}}', '{{ucTable}}'],
|
|
|
+ [$template, $table, $formDefault, $rule, ucfirst($table)],
|
|
|
+ $editTmpl
|
|
|
+ );
|
|
|
+ $filePath = PROJECT_PATH . "/web/src/views/{$table}/edit.vue";
|
|
|
+ file_put_contents($filePath, $editTmpl);
|
|
|
+ // 格式化代码
|
|
|
+ echo "<h4>命令后执行下面代码</h4>";
|
|
|
+ echo "<p style='color: red;'>npx prettier --write $filePath</p>";
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成ts接口
|
|
|
+ * @param string $table
|
|
|
+ * @param array $tableFieldArr
|
|
|
+ * @param array $excludeField 排除的字段
|
|
|
+ * @return string
|
|
|
+ */
|
|
|
+ private function getTsInterFace(string $table, array $tableFieldArr, array $excludeField = []): string
|
|
|
+ {
|
|
|
+ $content = '';
|
|
|
+ foreach ($tableFieldArr as $column) {
|
|
|
+ if (in_array($column['Field'], $excludeField)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $type = $this->getTypeByColumn($column);
|
|
|
+ $temp = $column['Field'] . ": {$type}";
|
|
|
+ $comment = $column['Comment'] ? " // {$column['Comment']}" : '';
|
|
|
+ $content.= $temp . " {$comment}, <br/>";
|
|
|
+ }
|
|
|
+ $template = <<<typescript
|
|
|
+interface {$table} {<br/>
|
|
|
+$content}<br/><br/>
|
|
|
+typescript;
|
|
|
+
|
|
|
+ return $template;
|
|
|
+ }
|
|
|
+
|
|
|
+ private function getTypeByColumn(array $column) :string
|
|
|
+ {
|
|
|
+ $type = 'string';
|
|
|
+ if (str_contains($column['Field'], 'ids')) {
|
|
|
+ $type = 'number[]';
|
|
|
+ } elseif (Helper::hasAnyString($column['Type'], ['int', 'decimal', 'double', 'float'])) {
|
|
|
+ if (Helper::hasAnyString($column['Field'], ['is_', 'can_', 'has_', 'status', '_status', 'type'])) {
|
|
|
+ $type = '0|1';
|
|
|
+ } else {
|
|
|
+ $type = 'number';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return $type;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成form默认值
|
|
|
+ * @param array $tableFieldArr
|
|
|
+ * @param array $excludeField 排除的字段
|
|
|
+ * @return string
|
|
|
+ */
|
|
|
+ private function getFormDefault(array $tableFieldArr, array $excludeField = []): string
|
|
|
+ {
|
|
|
+ $content = '';
|
|
|
+ foreach ($tableFieldArr as $column) {
|
|
|
+ if (in_array($column['Field'], $excludeField)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $type = $this->getTypeByColumn($column);
|
|
|
+ if (in_array($type, ['number', '0|1'])) {
|
|
|
+ $default = $column['Default'] ? : 0;
|
|
|
+ $content.= $column['Field'] . ": {$default},";
|
|
|
+ } else {
|
|
|
+ $default = $column['Default'] ? : '';
|
|
|
+ $content.= $column['Field'] . ": '{$default}',";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return $content;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成form验证规则 前后端需要保持一致
|
|
|
+ * @param string $table
|
|
|
+ * @param array $tableFieldArr
|
|
|
+ * @param array $excludeField 排除的字段
|
|
|
+ * @return string
|
|
|
+ */
|
|
|
+ private function getFormAndRule(string $table, array $tableFieldArr, array $excludeField = []): array
|
|
|
+ {
|
|
|
+ $html = '';
|
|
|
+ $ruleHtml = '';
|
|
|
+ foreach ($tableFieldArr as $column) {
|
|
|
+ if (in_array($column['Field'], $excludeField)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $comment = explode(' ', $column['Comment'])[0];
|
|
|
+ $rule = [];
|
|
|
+ if ($column['Null'] == 'NO') {
|
|
|
+ $rule[] = "{ required: true, message: '请输入{$comment}', trigger: 'blur' }";
|
|
|
+ }
|
|
|
+ $type = $this->getTypeByColumn($column);
|
|
|
+ if ($type == 'string') {
|
|
|
+ // 图片处理
|
|
|
+ if (Helper::hasAnyString($column['Field'], ['img', 'image'])) {
|
|
|
+ // 单张图片
|
|
|
+ } elseif (Helper::hasAnyString($column['Field'], ['images', 'imgs'])) {
|
|
|
+ // 多张图片
|
|
|
+ } elseif (Helper::hasAnyString($column['Field'], ['_id'])) {
|
|
|
+ // select
|
|
|
+ } elseif (Helper::hasAnyString($column['Field'], ['ids'])) {
|
|
|
+ // 多选框
|
|
|
+ } else {
|
|
|
+ // input框
|
|
|
+ $inputType = 'text';
|
|
|
+ $max = $this->getMaxLength($column);
|
|
|
+ if ($max) {
|
|
|
+ $min = Helper::hasAnyString($column['Field'], ['']) ? 0 : 0;
|
|
|
+ if ($min) {
|
|
|
+ $rule[] = "{ min: {$min}, max: {$max}, message: '长度在{$min}到{$max}个字符', trigger: 'blur' }";
|
|
|
+ } else {
|
|
|
+ $rule[] = "{ max: {$max}, message: '长度最多{$max}个字符', trigger: 'blur' }";
|
|
|
+ }
|
|
|
+ if ($max > 64) {
|
|
|
+ $inputType = 'textarea';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ $html.= $this->getInputHtml($comment, $column['Field'], $inputType, $max);
|
|
|
+ }
|
|
|
+ } elseif ($type == 'number') {
|
|
|
+ $html.= $this->getInputHtml($comment, $column['Field'], 'number');
|
|
|
+ } elseif ($type == '0|1') {
|
|
|
+ $rule = '';
|
|
|
+ $html.= $this->getSelectHtml($comment, $column['Field'], $this->getSelectData($column, $type));
|
|
|
+ }
|
|
|
+ if ($rule) {
|
|
|
+ $rule = implode(',', $rule);
|
|
|
+ $ruleHtml.= $column['Field'] . ": [{$rule}],";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ $content = <<<typescript
|
|
|
+<template>
|
|
|
+ <ElForm ref="formRef" :model="formData" :rules="rules" label-width="auto">
|
|
|
+ <el-row :gutter="20">
|
|
|
+ {$html}
|
|
|
+ <el-col :span="24">
|
|
|
+ <ElFormItem label=" " prop="">
|
|
|
+ <ElButton type="primary" @click="handleSubmit">提交</ElButton>
|
|
|
+ </ElFormItem>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </ElForm>
|
|
|
+</template>
|
|
|
+typescript;
|
|
|
+
|
|
|
+ return [$content, $ruleHtml];
|
|
|
+ }
|
|
|
+
|
|
|
+ public function getInputHtml(string $name, string $field, 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="{$name}" prop="{$field}">
|
|
|
+ <ElInput v-model="formData.{$field}" $maxLengthHtml type="{$type}"/>
|
|
|
+</ElFormItem>
|
|
|
+</el-col>
|
|
|
+
|
|
|
+input;
|
|
|
+ }
|
|
|
+
|
|
|
+ public function getSelectHtml(string $name, string $field, array $selectData, bool $multi = false): string
|
|
|
+ {
|
|
|
+ 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="{$name}" prop="{$field}">
|
|
|
+ <el-select v-model="formData.{$field}" placeholder="请选择">
|
|
|
+ <el-option v-for="item in [{$data}]" :key="item.value" :value="item.value" :label="item.label"/>
|
|
|
+ </el-select>
|
|
|
+</ElFormItem>
|
|
|
+</el-col>
|
|
|
+
|
|
|
+select;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成table字段配置
|
|
|
+ * @param array $tableFieldArr
|
|
|
+ * @param array $excludeField 排除的字段
|
|
|
+ * @return string
|
|
|
+ */
|
|
|
+ private function getTableHtml(array $tableFieldArr, $excludeField = []): string
|
|
|
+ {
|
|
|
+ $tableContent = '';
|
|
|
+ foreach ($tableFieldArr as $column) {
|
|
|
+ if (in_array($column['Field'], $excludeField)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ $commentArr = explode(' ', $column['Comment']);
|
|
|
+ $JsTableArr = ['prop' => $column['Field'], 'label' => $commentArr[0]];
|
|
|
+
|
|
|
+ // 长字段列表需要添加showOverflowTooltip
|
|
|
+ if ($this->getMaxLength($column) || $this->isTextField($column)) {
|
|
|
+ $JsTableArr['showOverflowTooltip'] = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (str_contains($column['Field'], 'ids')) {
|
|
|
+ $JsTableArr = []; // TODO:这种一般是tag集合
|
|
|
+ } elseif (Helper::hasAnyString($column['Field'], ['is', 'can', 'has', 'status'])) {
|
|
|
+ if (count($commentArr) == 3) {
|
|
|
+ $arr1 = explode('-', $commentArr[1]);
|
|
|
+ $arr2 = explode('-', $commentArr[2]);
|
|
|
+ $tempArr[intval($arr1[0])] = $arr1[1];
|
|
|
+ $tempArr[intval($arr2[0])] = $arr2[1];
|
|
|
+ } else {
|
|
|
+ $tempArr = [0 => '否', 1 => '是'];
|
|
|
+ }
|
|
|
+ $JsTableArr['formatter'] = <<<HTML
|
|
|
+ (row) => {<br/>
|
|
|
+ return h(ElTag, { type: row.{$column['Field']} ? 'success' : 'danger' }, () => row.{$column['Field']} ? '{$tempArr[1]}' : '{$tempArr[0]}')<br/>
|
|
|
+ }
|
|
|
+HTML;
|
|
|
+ }
|
|
|
+ $tableContent.= $this->getHtmlWithJsTableArr($JsTableArr);
|
|
|
+ }
|
|
|
+ $template = <<<typescript
|
|
|
+{<br/>
|
|
|
+$tableContent}<br/><br/>
|
|
|
+typescript;
|
|
|
+ return $template;
|
|
|
+ }
|
|
|
+
|
|
|
+ private function getMaxLength(array $column):int
|
|
|
+ {
|
|
|
+ preg_match('/(\d+)/', $column['Type'], $match);
|
|
|
+ return $match[0] ?? 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ private function isNumberFiled(?string $type = null)
|
|
|
+ {
|
|
|
+ return $type == 'number' || str_contains($type, '|');
|
|
|
+ }
|
|
|
+
|
|
|
+ private function isTextField(array $column):int
|
|
|
+ {
|
|
|
+ return Helper::hasAnyString($column['Type'], ['text']);
|
|
|
+ }
|
|
|
+
|
|
|
+ public function getSelectData(array $column, ?string $type = null):array
|
|
|
+ {
|
|
|
+ if (!$type) {
|
|
|
+ $type = $this->getTypeByColumn($column);
|
|
|
+ }
|
|
|
+ if (!$this->isNumberFiled($type)) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ $arr = [];
|
|
|
+ preg_match_all('/(\d+\-\S+)/', $column['Comment'], $match);
|
|
|
+ if ($match) {
|
|
|
+ foreach ($match[0] as $matchItem) {
|
|
|
+ list($key, $value) = explode('-', $matchItem);
|
|
|
+ $arr[$key] = $value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return $arr;
|
|
|
+ }
|
|
|
+
|
|
|
+ private function getHtmlWithJsTableArr(array $arr): string
|
|
|
+ {
|
|
|
+ if (!$arr) {
|
|
|
+ return '';
|
|
|
+ }
|
|
|
+ $str = '{';
|
|
|
+ foreach ($arr as $k => $v) {
|
|
|
+ $str.= " {$k}:{$v},";
|
|
|
+ }
|
|
|
+ return trim($str, ',') . ' },<br/>';
|
|
|
+ }
|
|
|
+
|
|
|
public function actionSetPassword()
|
|
|
{
|
|
|
$phone = Helper::getPostString('phone');
|