超管后台 - 添加项目数据对齐

This commit is contained in:
柳清爽
2025-04-18 14:37:31 +08:00
parent c5774ffa29
commit f8a89a8cbd
7 changed files with 404 additions and 99 deletions

View File

@@ -516,15 +516,6 @@ if (!function_exists('exit_data')) {
}
}
/**
* 调试打印变量并终止程序
* @return void
*/
function dd()
{
call_user_func_array(['app\\common\\helper\\Debug', 'dd'], func_get_args());
}
/**
* 调试打印变量但不终止程序
* @return void

View File

@@ -2,12 +2,15 @@
namespace app\common\model;
use think\Model;
use think\model\concern\SoftDelete;
/**
* 项目模型
*/
class Company extends Model
{
use SoftDelete;
// 设置数据表名
protected $name = 'company';
@@ -15,4 +18,5 @@ class Company extends Model
protected $autoWriteTimestamp = true;
protected $createTime = 'createTime';
protected $updateTime = 'updateTime';
}
protected $deleteTime = 'deleteTime';
}

View File

@@ -1,9 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | 应用配置
// +----------------------------------------------------------------------
return [
// API基础URL
'api_base_url' => env('API_BASE_URL', 'http://yishi.com'),
];

View File

@@ -6,7 +6,9 @@ use app\common\model\Company as CompanyModel;
use app\common\model\User as UsersModel;
use app\library\s2\CurlHandle;
use app\superadmin\controller\BaseController;
use Eison\Utils\Helper\ArrHelper;
use think\Db;
use think\facade\Env;
use think\Validate;
/**
@@ -14,61 +16,29 @@ use think\Validate;
*/
class CreateCompanyController extends BaseController
{
/**
* 获取 CURL
*
* @return CurlHandle|null
*/
protected function getCurl()
{
return CurlHandle::getInstant()->setMethod('post')->setBaseUrl('http://yishi.com/');
}
/**
* S2 创建部门并返回id
*
* @param array $params
* @return array
*/
protected function s2CreateDepartment(array $params): array
protected function s2CreateDepartment(array $params): ?array
{
$response = $this->getCurl()->setMethod('post')->send('v1/api/account/department/create', [
'name' => $params['name'],
'memo' => $params['description'],
]);
$params = ArrHelper::getValue('name=departmentName,memo=departmentMemo,account=accountName,password=accountPassword,realName=accountRealName,nickname=accountNickname,accountMemo', $params);
// 创建公司部门
$response = CurlHandle::getInstant()
->setBaseUrl(Env::get('rpc.API_BASE_URL'))
->setMethod('post')
->send('/v1/api/account/createNewAccount', $params);
$result = json_decode($response, true);
if ($result['code'] != 200) {
throw new \Exception($result['msg'], '20011');
throw new \Exception($result['msg'], 210 . $result['code']);
}
return $result['data'];
}
/**
* S2 创建部门账号
*
* @param array $params
* @param int $departmentId
* @return array
* @throws \Exception
*/
protected function s2CreateUserAccountWithinDepartment(array $params, int $departmentId): array
{
$response = $this->getCurl()->send('v1/api/account/create', [
'userName' => $params['account'],
'password' => $params['password'],
'realName' => $params['realName'],
'nickname' => $params['nickname'],
'departmentId' => $departmentId
]);
$result = json_decode($response, true);
if ($result['code'] != 200) {
throw new \Exception($result['msg'], '20011');
}
return $result['data'] ?: null;
}
/**
@@ -84,9 +54,19 @@ class CreateCompanyController extends BaseController
'name' => 'require|max:50|/\S+/',
'nickname' => 'require|max:20|/\S+/',
'account' => 'require|regex:/^1[3-9]\d{9}$/',
'status' => 'require|in:0,1',
'password' => 'require|/\S+/',
'realName' => 'require|/\S+/',
'description' => 'require|/\S+/',
'memo' => '/\S+/',
], [
'name.require' => '请输入项目名称',
'nickname.require' => '请输入用户昵称',
'account.require' => '请输入账号',
'account.regex' => '账号为手机号',
'status.require' => '缺少重要参数',
'status.in' => '非法参数',
'password.require' => '请输入密码',
'realName.require' => '请输入真实姓名',
]);
if (!$validate->check($params)) {
@@ -105,31 +85,29 @@ class CreateCompanyController extends BaseController
*/
protected function creatS2About(array $params): array
{
// 1. 调用创建部门接口
$department = $this->s2CreateDepartment($params);
// 2. 调用创建账号接口
$this->s2CreateUserAccountWithinDepartment($params, $department['id']);
if (!$department || !isset($department['id']) || !isset($department['departmentId'])) {
throw new \Exception('S2返参异常', 210402);
}
return $department;
return array_merge($params, [
'companyId' => $department['departmentId'],
's2_accountId' => $department['id'],
]);
}
/**
* 存客宝创建项目
*
* @param array $params
* @return array
* @return void
* @throws \Exception
*/
protected function ckbCreateCompany(array $params): array
protected function ckbCreateCompany(array $params): void
{
$result = CompanyModel::create(
[
'companyId' => $departmentData['id'],
'name' => $departmentData['name'],
'mome' => $departmentData['memo']
]
);
$params = ArrHelper::getValue('companyId,name,memo,status', $params);
$result = CompanyModel::create($params);
if (!$result) {
throw new \Exception('创建公司记录失败', 402);
@@ -140,19 +118,18 @@ class CreateCompanyController extends BaseController
* 存客宝创建账号
*
* @param array $params
* @return array
* @return void
* @throws \Exception
*/
protected function ckbCreateUser(array $params): array
protected function ckbCreateUser(array $params): void
{
$result = UsersModel::create(
[
'account' => $params['account'],
'passwordMd5' => md5($params['password']),
'passwordLocal' => $params['password'],
'companyId' => $departmentData['data']['id']
]
);
$params = ArrHelper::getValue('nickname=username,account,password=passwordLocal,companyId,s2_accountId,status', $params);
$result = UsersModel::create(array_merge($params, [
'passwordMd5' => md5($params['passwordLocal']),
'isAdmin' => 1, // 主要账号默认1
'typeId' => 1, // 类型:运营后台/操盘手传1、 门店传2
]));
if (!$result) {
throw new \Exception('创建用户记录失败', 402);
@@ -161,38 +138,37 @@ class CreateCompanyController extends BaseController
/**
* @param array $params
* @return array
* @return void
* @throws \Exception
*/
protected function createCkbAbout(array $params): array
protected function createCkbAbout(array $params)
{
// 1. 存客宝创建项目
$this->ckbCreateCompany($params);
// 2. 存客宝创建操盘手总账号
$this->ckbCreateUser();
$this->ckbCreateUser($params);
}
/**
* 创建新项目
*
* @return \think\response\Json
*/
public function index()
{
try {
$params = $this->request->only(['name', 'nickname', 'account', 'password', 'realName', 'description']);
$department = $this->dataValidate($params)->creatS2About($params);
$params = $this->request->only(['name', 'status', 'nickname', 'account', 'password', 'realName', 'memo']);
$params = $this->dataValidate($params)->creatS2About($params);
Db::startTrans();
$this->createCkbAbout($department);
$this->createCkbAbout($params);
Db::commit();
return json([
'code' => 200,
'msg' => '创建成功'
]);
} catch (\Exception $e) {
Db::rollback();

View File

@@ -26,7 +26,8 @@
"topthink/think-worker": "2.0.*",
"topthink/think-queue": "2.0.*",
"textalk/websocket": "^1.5",
"guzzlehttp/guzzle": "^7.9"
"guzzlehttp/guzzle": "^7.9",
"eison/utils": "^1.2"
},
"autoload": {
"psr-4": {
@@ -41,5 +42,8 @@
"allow-plugins": {
"topthink/think-installer": true
}
},
"require-dev": {
"symfony/var-dumper": "^5.4"
}
}

320
Server/composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "9ad1ad6eaacd62087a3871dd6bef4424",
"content-hash": "a22534993315c048e8d06f566d1d675d",
"packages": [
{
"name": "adbario/php-dot-notation",
@@ -671,6 +671,54 @@
},
"time": "2017-10-17T09:59:25+00:00"
},
{
"name": "eison/utils",
"version": "v1.2",
"source": {
"type": "git",
"url": "git@gitlab.com:eison/helperclass.git",
"reference": "6d4676e73a608ec7062b954969211b8cc8d00fb4"
},
"dist": {
"type": "zip",
"url": "https://gitlab.com/api/v4/projects/eison%2Fhelperclass/repository/archive.zip?sha=6d4676e73a608ec7062b954969211b8cc8d00fb4",
"reference": "6d4676e73a608ec7062b954969211b8cc8d00fb4",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=7.2"
},
"type": "library",
"autoload": {
"psr-4": {
"Eison\\Utils\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "eison",
"email": "eison.icu@gmail.com"
}
],
"description": "helperClass",
"homepage": "https://gitlab.com/eison/helperclass",
"keywords": [
"PSR-4",
"array",
"helper"
],
"time": "2021-10-12T06:20:05+00:00"
},
{
"name": "endroid/qr-code",
"version": "2.5.1",
@@ -2465,7 +2513,275 @@
"time": "2023-09-13T14:30:13+00:00"
}
],
"packages-dev": [],
"packages-dev": [
{
"name": "symfony/polyfill-mbstring",
"version": "v1.31.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341",
"reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=7.2"
},
"provide": {
"ext-mbstring": "*"
},
"suggest": {
"ext-mbstring": "For best performance"
},
"type": "library",
"extra": {
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Mbstring\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for the Mbstring extension",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"mbstring",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-09-09T11:45:10+00:00"
},
{
"name": "symfony/polyfill-php80",
"version": "v1.31.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
"reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8",
"reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=7.2"
},
"type": "library",
"extra": {
"thanks": {
"url": "https://github.com/symfony/polyfill",
"name": "symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Php80\\": ""
},
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ion Bazan",
"email": "ion.bazan@gmail.com"
},
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-09-09T11:45:10+00:00"
},
{
"name": "symfony/var-dumper",
"version": "v5.4.48",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
"reference": "42f18f170aa86d612c3559cfb3bd11a375df32c8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/42f18f170aa86d612c3559cfb3bd11a375df32c8",
"reference": "42f18f170aa86d612c3559cfb3bd11a375df32c8",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=7.2.5",
"symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php80": "^1.16"
},
"conflict": {
"symfony/console": "<4.4"
},
"require-dev": {
"ext-iconv": "*",
"symfony/console": "^4.4|^5.0|^6.0",
"symfony/http-kernel": "^4.4|^5.0|^6.0",
"symfony/process": "^4.4|^5.0|^6.0",
"symfony/uid": "^5.1|^6.0",
"twig/twig": "^2.13|^3.0.4"
},
"suggest": {
"ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).",
"ext-intl": "To show region name in time zone dump",
"symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script"
},
"bin": [
"Resources/bin/var-dump-server"
],
"type": "library",
"autoload": {
"files": [
"Resources/functions/dump.php"
],
"psr-4": {
"Symfony\\Component\\VarDumper\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Provides mechanisms for walking through any arbitrary PHP variable",
"homepage": "https://symfony.com",
"keywords": [
"debug",
"dump"
],
"support": {
"source": "https://github.com/symfony/var-dumper/tree/v5.4.48"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-11-08T15:21:10+00:00"
}
],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],

View File

@@ -23,7 +23,8 @@ export default function NewProjectPage() {
confirmPassword: "",
realName: "",
nickname: "",
description: ""
description: "",
status: "1" // 默认启用
})
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
@@ -34,6 +35,13 @@ export default function NewProjectPage() {
}))
}
const handleStatusChange = (value: string) => {
setFormData(prev => ({
...prev,
status: value
}))
}
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
@@ -57,7 +65,8 @@ export default function NewProjectPage() {
password: formData.password,
realName: formData.realName,
nickname: formData.nickname,
description: formData.description
description: formData.description,
status: formData.status // 添加状态参数
}),
})
@@ -111,13 +120,27 @@ export default function NewProjectPage() {
<Label htmlFor="account"></Label>
<Input
id="account"
placeholder="请输入账号"
type="number"
placeholder="请输入手机号"
required
value={formData.account}
onChange={handleChange}
/>
</div>
<div className="space-y-2">
<Label htmlFor="status"></Label>
<Select value={formData.status} onValueChange={handleStatusChange}>
<SelectTrigger>
<SelectValue placeholder="请选择状态" />
</SelectTrigger>
<SelectContent>
<SelectItem value="1"></SelectItem>
<SelectItem value="0"></SelectItem>
</SelectContent>
</Select>
</div>
<div className="space-y-2">
<Label htmlFor="password"></Label>
<Input