507 lines
17 KiB
PHP
507 lines
17 KiB
PHP
<?php
|
||
|
||
namespace app\controller\backend;
|
||
|
||
use app\model\DiyForm;
|
||
use Overtrue\Pinyin\Pinyin;
|
||
use think\facade\Db;
|
||
|
||
class FormController extends BaseController
|
||
{
|
||
public function index(DiyForm $diyFormModel)
|
||
{
|
||
$limit = input('param.limit');
|
||
$name = input('param.name');
|
||
|
||
$where[] = ['is_del', '=', 1];
|
||
$where[] = ['seller_id', '=', $this->admin['seller_id']];
|
||
if (!empty($name)) {
|
||
$where[] = ['name', 'like', '%' . $name . '%'];
|
||
}
|
||
|
||
try {
|
||
|
||
$list = $diyFormModel->where($where)->order('id desc')->paginate($limit);
|
||
} catch (\Exception $e) {
|
||
return jsonReturn(-1, $e->getMessage());
|
||
}
|
||
|
||
return json(pageReturn(dataReturn(0, lang('成功'), $list)));
|
||
}
|
||
|
||
public function info(DiyForm $diyFormModel)
|
||
{
|
||
$id = $this->request->param('id');
|
||
|
||
$info = $diyFormModel->where('id', $id)->find();
|
||
if (empty($info)) {
|
||
return jsonReturn(-3, lang('该表单不存在'));
|
||
}
|
||
|
||
return jsonReturn(0, lang('获取成功'), $info);
|
||
}
|
||
|
||
public function add(DiyForm $diyFormModel)
|
||
{
|
||
$param = input('post.');
|
||
|
||
if (empty($param['name'])) {
|
||
return jsonReturn(-1, lang('请输入表单名称'));
|
||
}
|
||
|
||
try {
|
||
|
||
$has = $diyFormModel->where('name', $param['name'])->find();
|
||
if (!empty($has)) {
|
||
return jsonReturn(-3, lang('该表单已经存在'));
|
||
}
|
||
|
||
$pinyinModel = new Pinyin();
|
||
$tableName = $pinyinModel->abbr($param['name']);
|
||
$has = $diyFormModel->where('table', $tableName)->find();
|
||
if (!empty($has)) {
|
||
$tableName = $tableName . '_' . uniqid();
|
||
}
|
||
|
||
$param['seller_id'] = $this->admin['seller_id'];
|
||
$param['table'] = $tableName;
|
||
$param['code'] = uniqid(); // 表单唯一标识
|
||
$param['create_time'] = date('Y-m-d H:i:s');
|
||
|
||
$diyFormModel->insert($param);
|
||
} catch (\Exception $e) {
|
||
return jsonReturn(-4, $e->getMessage());
|
||
}
|
||
|
||
return jsonReturn(0, lang('添加成功'));
|
||
}
|
||
|
||
public function edit(DiyForm $diyFormModel)
|
||
{
|
||
$param = input('post.');
|
||
|
||
if (empty($param['name'])) {
|
||
return jsonReturn(-1, lang('请输入表单名称'));
|
||
}
|
||
|
||
try {
|
||
|
||
$has = $diyFormModel->where('name', $param['name'])->where('id', '<>', $param['id'])->find();
|
||
if (!empty($has)) {
|
||
return jsonReturn(-3, lang('该表单已经存在'));
|
||
}
|
||
|
||
$pinyinModel = new Pinyin();
|
||
$tableName = $pinyinModel->abbr($param['name']);
|
||
$has = $diyFormModel->where('table', $tableName)->where('id', '<>', $param['id'])->find();
|
||
if (!empty($has)) {
|
||
$tableName = $tableName . '_' . uniqid();
|
||
}
|
||
|
||
$param['table'] = $tableName;
|
||
$param['update_time'] = date('Y-m-d H:i:s');
|
||
$diyFormModel->where('id', $param['id'])->update($param);
|
||
} catch (\Exception $e) {
|
||
return jsonReturn(-4, $e->getMessage());
|
||
}
|
||
|
||
return jsonReturn(0, lang('编辑成功'));
|
||
}
|
||
|
||
public function del(DiyForm $diyFormModel)
|
||
{
|
||
$id = input('param.id');
|
||
try {
|
||
$info = $diyFormModel->where('id', $id)->find();
|
||
if ($info['status'] == 2) {
|
||
return jsonReturn(-1, lang('该表单已经发布,请先卸载'));
|
||
}
|
||
|
||
$diyFormModel->where('id', $id)->delete();
|
||
} catch (\Exception $e) {
|
||
return jsonReturn(-2, $e->getMessage());
|
||
}
|
||
|
||
return jsonReturn(0, lang('删除成功'));
|
||
}
|
||
|
||
public function detail(DiyForm $diyFormModel)
|
||
{
|
||
$param = input('param.');
|
||
try {
|
||
|
||
$info = $diyFormModel->where('id', $param['id'])->find();
|
||
$formJson = json_decode($info['design_content'], true);
|
||
|
||
$field2Dict = [];
|
||
$header = [];
|
||
|
||
foreach ($formJson as $vo) {
|
||
if (!isset($vo['field'])) {
|
||
continue;
|
||
}
|
||
|
||
$header[] = [
|
||
'label' => $vo['title'],
|
||
'property' => $vo['field'],
|
||
'type' => $vo['type'],
|
||
'options' => $vo['options'] ?? ''
|
||
];
|
||
|
||
// 为了方便字典翻译,优化前端显示
|
||
if (isset($vo['options'])) {
|
||
|
||
$dictDataMap = [];
|
||
foreach ($vo['options'] as $k => $v) {
|
||
$dictDataMap[$v['value']] = $v['label'];
|
||
}
|
||
|
||
$field2Dict[$vo['field']] = $dictDataMap;
|
||
}
|
||
|
||
if ($vo['type'] == 'switch') {
|
||
$dictDataMap = [];
|
||
$dictDataMap[$vo['props']['activeValue']] = $vo['props']['activeText'];
|
||
$dictDataMap[$vo['props']['inactiveValue']] = $vo['props']['inactiveText'];
|
||
$field2Dict[$vo['field']] = $dictDataMap;
|
||
}
|
||
|
||
}
|
||
|
||
$param['queryParams'] = json_decode($param['queryParams'], true);
|
||
|
||
if (!empty($param['queryParams']) &&
|
||
!empty($param['queryParams']['condition']) &&
|
||
!empty($param['queryParams']['childTips'])) {
|
||
|
||
$where = $this->buildWhere($param['queryParams']['childTips']);
|
||
if ($param['queryParams']['condition'] == 'and') {
|
||
|
||
|
||
$data = Db::table(makeFormTable($info['table']))->where($where)
|
||
->order('id', 'desc')->paginate($param['limit']);
|
||
} else if ($param['queryParams']['condition'] == 'or') {
|
||
|
||
$data = Db::table(makeFormTable($info['table']))->whereOr($where)
|
||
->order('id', 'desc')->paginate($param['limit']);
|
||
}
|
||
|
||
} else {
|
||
|
||
$data = Db::table(makeFormTable($info['table']))
|
||
->order('id', 'desc')->paginate($param['limit']);
|
||
}
|
||
|
||
$data = $data->each(function ($item) use ($field2Dict) {
|
||
|
||
foreach ($item as $key => $vo) {
|
||
|
||
if (isset($field2Dict[$key])) {
|
||
|
||
$showValueMap = [];
|
||
$valueMap = explode(',', $vo);
|
||
|
||
foreach ($valueMap as $valueKey) {
|
||
$showValueMap[] = isset($field2Dict[$key][$valueKey]) ? $field2Dict[$key][$valueKey] : $valueKey;
|
||
}
|
||
|
||
$item[$key] = implode(',', $showValueMap);
|
||
}
|
||
}
|
||
|
||
return $item;
|
||
});
|
||
|
||
} catch (\Exception $e) {
|
||
return jsonReturn(-3, $e->getMessage() . $e->getLine());
|
||
}
|
||
|
||
return jsonReturn(0, 'success', [
|
||
'header' => $header,
|
||
'data' => $data->getCollection(),
|
||
'total' => $data->total()
|
||
]);
|
||
}
|
||
|
||
public function deploy(DiyForm $diyFormModel)
|
||
{
|
||
$id = input('param.id');
|
||
$info = $diyFormModel->where('id', $id)->find();
|
||
|
||
if ($info['status'] == 2) {
|
||
return jsonReturn(-1, lang('该表单已经发布,无需再次发布'));
|
||
}
|
||
|
||
if (empty($info['design_content'])) {
|
||
return jsonReturn(-2, lang('请先完成表单设计'));
|
||
}
|
||
|
||
$tableName = makeFormTable($info['table']);
|
||
$title = $info['name'];
|
||
|
||
$column = '';
|
||
$columnMap = json_decode($info['design_content'], true);
|
||
foreach ($columnMap as $key => $vo) {
|
||
|
||
if (empty($vo['field'])) {
|
||
continue;
|
||
}
|
||
|
||
// 强迫症为了dd打印的时候格式对其,其实没啥意义
|
||
$tab = '';
|
||
if ($key > 0) {
|
||
$tab = ' ';
|
||
}
|
||
|
||
$column .= $tab . '`' . $vo['field'] . '` varchar(255) NULL DEFAULT NULL COMMENT "' . $vo['title'] . '",' . PHP_EOL;
|
||
}
|
||
|
||
try {
|
||
|
||
$sql = <<<EOL
|
||
CREATE TABLE `{$tableName}` (
|
||
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT "id",
|
||
{$column} `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT "创建时间",
|
||
`update_time` datetime NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT "更新时间",
|
||
`visitor_id` varchar(255) DEFAULT '' COMMENT '前端标识',
|
||
`sub_id` int(11) DEFAULT 0 COMMENT '关联内容id',
|
||
`ip` varchar(20) DEFAULT '',
|
||
`user_agent` varchar(255) DEFAULT '' COMMENT '浏览器标识',
|
||
PRIMARY KEY (`id`)
|
||
)ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 COMMENT='{$title}';
|
||
EOL;
|
||
Db::execute($sql);
|
||
|
||
$diyFormModel->where('id', $id)->update([
|
||
'status' => 2,
|
||
'update_time' => date('Y-m-d H:i:s')
|
||
]);
|
||
} catch (\Exception $e) {
|
||
return jsonReturn(-4, $e->getMessage());
|
||
}
|
||
|
||
return jsonReturn(0, lang('部署成功'));
|
||
}
|
||
|
||
public function undeploy(DiyForm $diyFormModel)
|
||
{
|
||
$id = input('param.id');
|
||
|
||
$info = $diyFormModel->where('id', $id)->find();
|
||
if ($info['status'] != 2) {
|
||
return jsonReturn(-1, lang('该表单尚未发布,无法卸载'));
|
||
}
|
||
|
||
try {
|
||
|
||
Db::query('DROP TABLE IF EXISTS `' . makeFormTable($info['table']) . '`');
|
||
$diyFormModel->where('id', $id)->update([
|
||
'status' => 1,
|
||
'update_time' => date('Y-m-d H:i:s')
|
||
]);
|
||
} catch (\Exception $e) {
|
||
return jsonReturn(-1, $e->getMessage());
|
||
}
|
||
|
||
return jsonReturn(0, lang('卸载成功'));
|
||
}
|
||
|
||
// 获取问题和答案详情
|
||
public function quesDetail(DiyForm $diyFormModel)
|
||
{
|
||
$param = input('param.');
|
||
try {
|
||
|
||
$info = $diyFormModel->where('id', $param['id'])->find();
|
||
$formJson = json_decode($info['design_content'], true);
|
||
|
||
$field2Dict = [];
|
||
$header = [];
|
||
|
||
foreach ($formJson as $vo) {
|
||
if (!isset($vo['field'])) {
|
||
continue;
|
||
}
|
||
|
||
$header[$vo['field']] = [
|
||
'label' => $vo['title'],
|
||
'property' => $vo['field'],
|
||
'type' => $vo['type'],
|
||
'options' => []
|
||
];
|
||
|
||
if ($vo['type'] == 'switch') {
|
||
$header[$vo['field']]['options'][$vo['props']['activeValue']] = ['label' => $vo['props']['activeText']];
|
||
$header[$vo['field']]['options'][$vo['props']['inactiveValue']] = ['label' => $vo['props']['inactiveText']];
|
||
}
|
||
|
||
if (!empty($vo['options'])) {
|
||
foreach ($vo['options'] as $v) {
|
||
$header[$vo['field']]['options'][$v['value']] = $v;
|
||
}
|
||
}
|
||
}
|
||
|
||
$param['queryParams'] = json_decode($param['queryParams'], true);
|
||
|
||
if (!empty($param['queryParams']) &&
|
||
!empty($param['queryParams']['condition']) &&
|
||
!empty($param['queryParams']['childTips'])) {
|
||
|
||
$where = $this->buildWhere($param['queryParams']['childTips']);
|
||
|
||
if ($param['queryParams']['condition'] == 'and') {
|
||
|
||
$data = Db::table(makeFormTable($info['table']))->where($where)->select();
|
||
|
||
} else if ($param['queryParams']['condition'] == 'or') {
|
||
|
||
$data = Db::table(makeFormTable($info['table']))->whereOr($where)->select();
|
||
} else {
|
||
$data = [];
|
||
}
|
||
} else {
|
||
$data = Db::table(makeFormTable($info['table']))->select();
|
||
}
|
||
|
||
|
||
$newData = [];
|
||
$quesNum = 1;
|
||
foreach ($header as $key => $value) {
|
||
foreach ($data as $item) {
|
||
if (!isset($item[$key])) {
|
||
continue;
|
||
}
|
||
|
||
$newData[$key]['quesNum'] = $quesNum;
|
||
$newData[$key]['type'] = $value['type'];
|
||
$newData[$key]['ques'] = $value['label'];
|
||
|
||
if (!isset($newData[$key]['total'])) {
|
||
$newData[$key]['total'] = 0;
|
||
}
|
||
if ($value['type'] == 'input' || $value['type'] == 'timePicker' || $value['type'] == 'datePicker') {
|
||
$newData[$key]['type_name'] = '填空';
|
||
$newData[$key]['type'] = 'list';
|
||
// 填空题 ,填的才是答案,使用列表展示
|
||
$newData[$key]['total']++;
|
||
|
||
$newData[$key]['detail'][] = [
|
||
'id' => $item['id'],
|
||
'answer' => $item[$key],
|
||
];
|
||
} else if ($value['type'] == 'radio' || $value['type'] == 'select' || $value['type'] == 'switch') {
|
||
$newData[$key]['type_name'] = '单选';
|
||
$newData[$key]['type'] = 'radio';
|
||
// 单选题 使用饼图展示,需要计算百分比
|
||
$newData[$key]['total']++;
|
||
|
||
if (isset($newData[$key]['detail'][$item[$key]]['count'])) {
|
||
$newData[$key]['detail'][$item[$key]]['count']++;
|
||
} else {
|
||
$newData[$key]['detail'][$item[$key]]['answer'] = $value['options'][$item[$key]]['label'];
|
||
$newData[$key]['detail'][$item[$key]]['count'] = 1;
|
||
}
|
||
} else if ($value['type'] == 'slider' || $value['type'] == 'rate'){
|
||
$newData[$key]['type_name'] = '滑块/打分';
|
||
$newData[$key]['type'] = 'rate';
|
||
$newData[$key]['total']++;
|
||
if (isset($newData[$key]['detail'][$item[$key]]['count'])) {
|
||
$newData[$key]['detail'][$item[$key]]['count']++;
|
||
} else {
|
||
$newData[$key]['detail'][$item[$key]]['answer'] = $item[$key];
|
||
$newData[$key]['detail'][$item[$key]]['count'] = 1;
|
||
}
|
||
}
|
||
else if ($value['type'] == 'checkbox') {
|
||
$newData[$key]['type_name'] = '多选';
|
||
// 多选题 默认使用柱状图,需要计算百分比
|
||
$answer = explode(',', $item[$key]);
|
||
foreach ($answer as $v) {
|
||
$newData[$key]['total']++;
|
||
|
||
if (isset($newData[$key]['detail'][$v]['count'])) {
|
||
$newData[$key]['detail'][$v]['count']++;
|
||
} else {
|
||
$newData[$key]['detail'][$v]['answer'] = $value['options'][$v]['label'];
|
||
$newData[$key]['detail'][$v]['count'] = 1;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
$quesNum++;
|
||
}
|
||
|
||
// 整理成前端echart需要的数据
|
||
foreach ($newData as &$value) {
|
||
if ($value['type'] == 'list') {
|
||
continue;
|
||
}
|
||
$newDetail = [];
|
||
foreach ($value['detail'] as $v) {
|
||
$newDetail['data'][] = [
|
||
'name' => $v['answer'],
|
||
'value' => $v['count'],
|
||
];
|
||
$newDetail['nameArr'][] = $v['answer'];
|
||
$newDetail['valueArr'][] = $v['count'];
|
||
}
|
||
$value['detail'] = $newDetail;
|
||
}
|
||
|
||
// dd($newData);
|
||
|
||
} catch (\Exception $e) {
|
||
return jsonReturn(-3, $e->getMessage() . $e->getLine());
|
||
}
|
||
|
||
return jsonReturn(0, lang('成功'), [
|
||
'header' => array_values($header),
|
||
'data' => $newData,
|
||
'total' => count($newData),
|
||
]);
|
||
}
|
||
|
||
private function buildWhere($childTips)
|
||
{
|
||
$where = [];
|
||
|
||
foreach ($childTips as $vo) {
|
||
|
||
switch ($vo['rule']) {
|
||
|
||
case 'eq':
|
||
$where[] = [$vo['field'], '=', $vo['val']];
|
||
break;
|
||
case 'like':
|
||
$where[] = [$vo['field'], 'like', '%' . $vo['val'] . '%'];
|
||
break;
|
||
case 'left_like':
|
||
$where[] = [$vo['field'], 'like', '%' . $vo['val']];
|
||
break;
|
||
case 'right_like':
|
||
$where[] = [$vo['field'], 'like', $vo['val'] . '%'];
|
||
break;
|
||
case 'neq':
|
||
$where[] = [$vo['field'], '<>', $vo['val']];
|
||
break;
|
||
case 'gt':
|
||
$where[] = [$vo['field'], '>', $vo['val']];
|
||
break;
|
||
case 'gte':
|
||
$where[] = [$vo['field'], '>=', $vo['val']];
|
||
break;
|
||
break;
|
||
case 'lt':
|
||
$where[] = [$vo['field'], '<', $vo['val']];
|
||
break;
|
||
case 'lte':
|
||
$where[] = [$vo['field'], '<=', $vo['val']];
|
||
break;
|
||
}
|
||
}
|
||
|
||
return $where;
|
||
}
|
||
}
|