no message

This commit is contained in:
kuaifan 2021-06-03 15:33:41 +08:00
parent 0b12ab55c0
commit 14a5ef5610
18 changed files with 984 additions and 74 deletions

View File

@ -0,0 +1,347 @@
<?php
namespace App\Http\Controllers\Api;
use App\Models\User;
use App\Module\Base;
use Request;
/**
* @apiDefine system
*
* 系统
*/
class SystemController extends AbstractController
{
/**
* @api {get} api/system/setting 01. 获取设置、保存设置
*
* @apiVersion 1.0.0
* @apiGroup system
* @apiName setting
*
* @apiParam {String} type
* - get: 获取(默认)
* - save: 保存设置参数reg、login_code
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
* @apiSuccess {Object} data 返回数据
*/
public function setting()
{
$type = trim(Request::input('type'));
if ($type == 'save') {
if (env("SYSTEM_SETTING") == 'disabled') {
return Base::retError('当前环境禁止修改!');
}
$user = User::authE();
if (Base::isError($user)) {
return $user;
} else {
$user = User::IDE($user['data']);
}
if (!$user->isAdmin()) {
return Base::retError('权限不足!');
}
$all = Request::input();
foreach ($all AS $key => $value) {
if (!in_array($key, ['reg', 'login_code'])) {
unset($all[$key]);
}
}
$setting = Base::setting('system', Base::newTrim($all));
} else {
$setting = Base::setting('system');
}
//
$setting['reg'] = $setting['reg'] ?: 'open';
$setting['login_code'] = $setting['login_code'] ?: 'auto';
//
return Base::retSuccess('success', $setting ?: json_decode('{}'));
}
/**
* @api {get} api/system/get/info 02. 获取终端详细信息
*
* @apiVersion 1.0.0
* @apiGroup system
* @apiName get__info
*
* @apiParam {String} key key值
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
* @apiSuccess {Object} data 返回数据
*/
public function get__info()
{
if (Request::input("key") !== env('APP_KEY')) {
return [];
}
return Base::retSuccess('success', [
'ip' => Base::getIp(),
'ip-info' => Base::getIpInfo(Base::getIp()),
'ip-gcj02' => Base::getIpGcj02(Base::getIp()),
'ip-iscn' => Base::isCnIp(Base::getIp()),
'header' => Request::header(),
'token' => Base::getToken(),
'url' => url('') . Base::getUrl(),
]);
}
/**
* @api {get} api/system/get/ip 03. 获取IP地址
*
* @apiVersion 1.0.0
* @apiGroup system
* @apiName get__ip
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
* @apiSuccess {Object} data 返回数据
*/
public function get__ip() {
return Base::getIp();
}
/**
* @api {get} api/system/get/cnip 04. 是否中国IP地址
*
* @apiVersion 1.0.0
* @apiGroup system
* @apiName get__cnip
*
* @apiParam {String} ip IP值
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
* @apiSuccess {Object} data 返回数据
*/
public function get__cnip() {
return Base::isCnIp(Request::input('ip'));
}
/**
* @api {get} api/system/get/ipgcj02 05. 获取IP地址经纬度
*
* @apiVersion 1.0.0
* @apiGroup system
* @apiName get__ipgcj02
*
* @apiParam {String} ip IP值
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
* @apiSuccess {Object} data 返回数据
*/
public function get__ipgcj02() {
return Base::getIpGcj02(Request::input("ip"));
}
/**
* @api {get} api/system/get/ipinfo 06. 获取IP地址详细信息
*
* @apiVersion 1.0.0
* @apiGroup system
* @apiName get__ipinfo
*
* @apiParam {String} ip IP值
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
* @apiSuccess {Object} data 返回数据
*/
public function get__ipinfo() {
return Base::getIpInfo(Request::input("ip"));
}
/**
* @api {post} api/system/imgupload 10. 上传图片
*
* @apiDescription 需要token身份
* @apiVersion 1.0.0
* @apiGroup system
* @apiName imgupload
*
* @apiParam {String} image64 图片base64
* @apiParam {String} filename 文件名
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
* @apiSuccess {Object} data 返回数据
*/
public function imgupload()
{
if (User::token2userid() === 0) {
return Base::retError('身份失效,等重新登录!');
}
$scale = [intval(Request::input('width')), intval(Request::input('height'))];
if (!$scale[0] && !$scale[1]) {
$scale = [2160, 4160, -1];
}
$path = "uploads/picture/" . User::token2userid() . "/" . date("Ym") . "/";
$image64 = trim(Base::getPostValue('image64'));
$fileName = trim(Base::getPostValue('filename'));
if ($image64) {
$data = Base::image64save([
"image64" => $image64,
"path" => $path,
"fileName" => $fileName,
"scale" => $scale
]);
} else {
$data = Base::upload([
"file" => Request::file('image'),
"type" => 'image',
"path" => $path,
"fileName" => $fileName,
"scale" => $scale
]);
}
if (Base::isError($data)) {
return Base::retError($data['msg']);
} else {
return Base::retSuccess('success', $data['data']);
}
}
/**
* @api {get} api/system/get/imgview 11. 浏览图片空间
*
* @apiDescription 需要token身份
* @apiVersion 1.0.0
* @apiGroup system
* @apiName imgview
*
* @apiParam {String} path 路径
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
* @apiSuccess {Object} data 返回数据
*/
public function imgview()
{
if (User::token2userid() === 0) {
return Base::retError('身份失效,等重新登录!');
}
$publicPath = "uploads/picture/" . User::token2userid() . "/";
$dirPath = public_path($publicPath);
$dirs = $files = [];
//
$path = Request::input('path');
if ($path && is_string($path)) {
$path = str_replace(array('||', '|'), '/', $path);
$path = trim($path, '/');
$path = str_replace('..', '', $path);
$path = Base::leftDelete($path, $publicPath);
if ($path) {
$path = $path . '/';
$dirPath .= $path;
//
$dirs[] = [
'type' => 'dir',
'title' => '...',
'path' => substr(substr($path, 0, -1), 0, strripos(substr($path, 0, -1), '/')),
'url' => '',
'thumb' => Base::fillUrl('images/other/dir.png'),
'inode' => 0,
];
}
} else {
$path = '';
}
$list = glob($dirPath . '*', GLOB_BRACE);
foreach ($list as $v) {
$filename = basename($v);
$pathTemp = $publicPath . $path . $filename;
if (is_dir($v)) {
$dirs[] = [
'type' => 'dir',
'title' => $filename,
'path' => $pathTemp,
'url' => Base::fillUrl($pathTemp),
'thumb' => Base::fillUrl('images/other/dir.png'),
'inode' => fileatime($v),
];
} elseif (substr($filename, -10) != "_thumb.jpg") {
$array = [
'type' => 'file',
'title' => $filename,
'path' => $pathTemp,
'url' => Base::fillUrl($pathTemp),
'thumb' => $pathTemp,
'inode' => fileatime($v),
];
//
$extension = pathinfo($dirPath . $filename, PATHINFO_EXTENSION);
if (in_array($extension, array('gif', 'jpg', 'jpeg', 'png', 'bmp'))) {
if (file_exists($dirPath . $filename . '_thumb.jpg')) {
$array['thumb'] .= '_thumb.jpg';
}
$array['thumb'] = Base::fillUrl($array['thumb']);
$files[] = $array;
}
}
}
if ($dirs) {
$inOrder = [];
foreach ($dirs as $key => $item) {
$inOrder[$key] = $item['title'];
}
array_multisort($inOrder, SORT_DESC, $dirs);
}
if ($files) {
$inOrder = [];
foreach ($files as $key => $item) {
$inOrder[$key] = $item['inode'];
}
array_multisort($inOrder, SORT_DESC, $files);
}
//
return Base::retSuccess('success', ['dirs' => $dirs, 'files' => $files]);
}
/**
* @api {post} api/system/fileupload 12. 上传文件
*
* @apiDescription 需要token身份
* @apiVersion 1.0.0
* @apiGroup system
* @apiName fileupload
*
* @apiParam {String} [image64] 图片base64
* @apiParam {String} filename 文件名
* @apiParam {String} [files] 文件名
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
* @apiSuccess {Object} data 返回数据
*/
public function fileupload()
{
if (User::token2userid() === 0) {
return Base::retError('身份失效,等重新登录!');
}
$path = "uploads/files/" . User::token2userid() . "/" . date("Ym") . "/";
$image64 = trim(Base::getPostValue('image64'));
$fileName = trim(Base::getPostValue('filename'));
if ($image64) {
$data = Base::image64save([
"image64" => $image64,
"path" => $path,
"fileName" => $fileName,
]);
} else {
$data = Base::upload([
"file" => Request::file('files'),
"type" => 'file',
"path" => $path,
"fileName" => $fileName,
]);
}
//
return $data;
}
}

View File

@ -28,7 +28,7 @@ class UsersController extends AbstractController
* - login:登录(默认)
* - reg:注册
* @apiParam {String} email 邮箱
* @apiParam {String} userpass 密码
* @apiParam {String} password 密码
* @apiParam {String} [code] 登录验证码
* @apiParam {String} [key] 登陆验证码key
*
@ -40,13 +40,13 @@ class UsersController extends AbstractController
{
$type = trim(Request::input('type'));
$email = trim(Request::input('email'));
$userpass = trim(Request::input('userpass'));
$password = trim(Request::input('password'));
if ($type == 'reg') {
$setting = Base::setting('system');
if ($setting['reg'] == 'close') {
return Base::retError('未开放注册!');
}
$user = User::reg($email, $userpass);
$user = User::reg($email, $password);
if (Base::isError($user)) {
return $user;
} else {
@ -81,7 +81,7 @@ class UsersController extends AbstractController
if (empty($user)) {
return $retError('账号或密码错误!');
}
if ($user->userpass != Base::md52($userpass, $user->encrypt)) {
if ($user->password != Base::md52($password, $user->encrypt)) {
return $retError('账号或密码错误!');
}
Cache::forget("code::" . $email);
@ -96,8 +96,7 @@ class UsersController extends AbstractController
];
$user->updateInstance($array);
$user->save();
//
$user->token = User::token($user);
User::token($user);
return Base::retSuccess($type == 'reg' ? "注册成功" : "登录成功", $user);
}
@ -181,6 +180,8 @@ class UsersController extends AbstractController
$user = User::IDE($user['data']);
}
//
User::token($user);
//
if (strlen($callback) > 3) {
return $callback . '(' . json_encode(Base::retSuccess('success', $user)) . ')';
}
@ -197,6 +198,7 @@ class UsersController extends AbstractController
*
* @apiParam {Object} [userimg] 会员头像(地址)
* @apiParam {String} [nickname] 昵称
* @apiParam {String} [profession] 职位/职称
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
@ -222,14 +224,26 @@ class UsersController extends AbstractController
if ($nickname) {
if (mb_strlen($nickname) < 2) {
return Base::retError('昵称不可以少于2个字');
} elseif (mb_strlen($nickname) > 8) {
return Base::retError('昵称最多只能设置8个字!');
} elseif (mb_strlen($nickname) > 20) {
return Base::retError('昵称最多只能设置20个字!');
} else {
$user->nickname = $nickname;
}
}
//职位/职称
$profession = trim(Request::input('profession'));
if ($profession) {
if (mb_strlen($profession) < 2) {
return Base::retError('职位/职称不可以少于2个字');
} elseif (mb_strlen($profession) > 20) {
return Base::retError('职位/职称最多只能设置20个字');
} else {
$user->profession = $profession;
}
}
//
$user->save();
User::token($user);
return Base::retSuccess('修改成功!', $user);
}
@ -277,15 +291,16 @@ class UsersController extends AbstractController
return Base::retError('当前环境禁止修改密码!');
}
//
$verify = User::whereUserid($user->userid)->whereUserpass(Base::md52($oldpass, User::token2encrypt()))->count();
$verify = User::whereUserid($user->userid)->wherePassword(Base::md52($oldpass, User::token2encrypt()))->count();
if (empty($verify)) {
return Base::retError('请填写正确的旧密码!');
}
//
$user->encrypt = Base::generatePassword(6);
$user->userpass = Base::md52($newpass, $user->encrypt);
$user->password = Base::md52($newpass, $user->encrypt);
$user->changepass = 0;
$user->save();
User::token($user);
return Base::retSuccess('修改成功!', $user);
}

View File

@ -12,6 +12,12 @@ class VerifyCsrfToken extends Middleware
* @var array
*/
protected $except = [
//上传图片
'api/system/imgupload/',
//上传文件
'api/system/fileupload/',
// 添加任务
'api/project/task/add/',
];

View File

@ -49,6 +49,8 @@ use Carbon\Carbon;
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|ProjectTask whereUserid($value)
* @mixin \Eloquent
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectTaskTag[] $taskTag
* @property-read int|null $task_tag_count
*/
class ProjectTask extends AbstractModel
{

View File

@ -16,9 +16,10 @@ use Carbon\Carbon;
* @property string|null $az A-Z
* @property string|null $email 邮箱
* @property string $nickname 昵称
* @property string|null $profession 职位/职称
* @property string $userimg 头像
* @property string|null $encrypt
* @property string|null $userpass 登录密码
* @property string|null $password 登录密码
* @property int|null $changepass 登录需要修改密码
* @property int|null $login_num 累计登录次数
* @property string|null $last_ip 最后登录IP
@ -44,10 +45,11 @@ use Carbon\Carbon;
* @method static \Illuminate\Database\Eloquent\Builder|User whereLineIp($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereLoginNum($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereNickname($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereProfession($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereUserid($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereUserimg($value)
* @method static \Illuminate\Database\Eloquent\Builder|User whereUserpass($value)
* @method static \Illuminate\Database\Eloquent\Builder|User wherePassword($value)
* @mixin \Eloquent
*/
class User extends AbstractModel
@ -55,8 +57,6 @@ class User extends AbstractModel
protected $primaryKey = 'userid';
protected $hidden = [
'encrypt',
'userpass',
'updated_at',
];
@ -119,6 +119,15 @@ class User extends AbstractModel
return WebSocket::whereUserid($this->userid)->exists();
}
/**
* 判断是否管理员
* @return bool
*/
public function isAdmin()
{
return in_array('admin', $this->identity);
}
/** ***************************************************************************************** */
/** ***************************************************************************************** */
@ -127,11 +136,11 @@ class User extends AbstractModel
/**
* 注册会员
* @param $email
* @param $userpass
* @param $password
* @param array $other
* @return array
*/
public static function reg($email, $userpass, $other = [])
public static function reg($email, $password, $other = [])
{
//邮箱
if (!Base::isMail($email)) {
@ -141,9 +150,9 @@ class User extends AbstractModel
return Base::retError('邮箱地址已存在!');
}
//密码
if (strlen($userpass) < 6) {
if (strlen($password) < 6) {
return Base::retError(['密码设置不能小于%位数!', 6]);
} elseif (strlen($userpass) > 32) {
} elseif (strlen($password) > 32) {
return Base::retError(['密码最多只能设置%位数!', 32]);
}
//开始注册
@ -151,7 +160,7 @@ class User extends AbstractModel
$inArray = [
'encrypt' => $encrypt,
'email' => $email,
'userpass' => Base::md52($userpass, $encrypt),
'password' => Base::md52($password, $encrypt),
'created_ip' => Base::getIp(),
];
if ($other) {
@ -293,7 +302,10 @@ class User extends AbstractModel
*/
public static function token($userinfo)
{
return base64_encode($userinfo->userid . '#$' . $userinfo->email . '#$' . $userinfo->encrypt . '#$' . time() . '#$' . Base::generatePassword(6));
$userinfo->token = base64_encode($userinfo->userid . '#$' . $userinfo->email . '#$' . $userinfo->encrypt . '#$' . time() . '#$' . Base::generatePassword(6));
unset($userinfo->encrypt);
unset($userinfo->password);
return $userinfo->token;
}
/**
@ -355,7 +367,7 @@ class User extends AbstractModel
if (isset($_A["__static_userid2basic_" . $userid])) {
return $_A["__static_userid2basic_" . $userid];
}
$fields = ['userid', 'email', 'nickname', 'userimg'];
$fields = ['userid', 'email', 'nickname', 'profession', 'userimg'];
$userInfo = self::whereUserid($userid)->select($fields)->first();
if ($userInfo) {
$userInfo->online = $userInfo->getOnlineStatus();
@ -383,8 +395,8 @@ class User extends AbstractModel
*/
public static function needCode($email)
{
$loginCode = Base::settingFind('system', 'loginCode');
switch ($loginCode) {
$login_code = Base::settingFind('system', 'login_code');
switch ($login_code) {
case 'open':
return Base::retSuccess('need');

View File

@ -1149,6 +1149,7 @@ class Base
if ($array !== false) {
$setting = $array;
$row->updateInstance(['setting' => $array]);
$row->save();
}
$_A["__static_setting_" . $setname] = $setting;
return $setting;

View File

@ -10,7 +10,7 @@
<Icon type="md-speedometer" />
<div class="menu-title">Dashboard</div>
</li>
<li @click="toggleRoute('setting')" :class="classNameRoute('setting')">
<li @click="toggleRoute('setting/personal')" :class="classNameRoute('setting')">
<Icon type="md-cog" />
<div class="menu-title">Setting</div>
</li>
@ -293,9 +293,10 @@ export default {
toggleRoute(path) {
this.goForward({path: '/manage/' + path});
},
classNameRoute(path) {
return {
"active": this.curPath == '/manage/' + path
"active": $A.leftExists(this.curPath, '/manage/' + path)
};
},

View File

@ -652,12 +652,13 @@
> pre {
margin: 0;
padding: 0;
line-height: 1.5;
}
}
.ivu-icon {
font-size: 22px;
color: #666666;
padding-left: 4px;
margin-left: 8px;
}
&.has-desc {
.task-title {
@ -668,7 +669,7 @@
.task-desc {
color: #999999;
margin-top: 10px;
line-height: 18px;
line-height: 20px;
}
.task-tags {
margin-top: 10px;

View File

@ -1,17 +0,0 @@
<template>
<div class="setting">
<PageTitle>{{$L('Setting')}}</PageTitle>
</div>
</template>
<script>
export default {
data() {
return {}
},
mounted() {
},
}
</script>

View File

@ -0,0 +1,150 @@
<template>
<div class="setting">
<PageTitle>{{$L('设置')}}</PageTitle>
<div class="setting-head">
<div class="setting-titbox">
<div class="setting-title">
<h1>{{$L('设置')}}</h1>
</div>
</div>
</div>
<div class="setting-box">
<div class="setting-menu">
<ul>
<li v-for="(item, key) in menu" :key="key" @click="toggleRoute(item.path)" :class="classNameRoute(item.path)">{{$L(item.name)}}</li>
</ul>
</div>
<div class="setting-content">
<div class="setting-content-title">{{$L('密码设置')}}</div>
<div class="setting-content-view"><router-view class="setting-router-view"></router-view></div>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
:global {
.setting {
display: flex;
flex-direction: column;
.setting-head {
display: flex;
align-items: flex-start;
margin: 32px 32px 16px;
border-bottom: 1px solid #F4F4F5;
.setting-titbox {
flex: 1;
margin-bottom: 16px;
.setting-title {
display: flex;
align-items: center;
> h1 {
color: #333333;
font-size: 28px;
font-weight: 600;
}
}
}
}
}
.setting-box {
flex: 1;
height: 0;
display: flex;
margin-bottom: 16px;
.setting-menu {
width: 200px;
flex-shrink: 0;
border-right: 1px solid #F4F4F5;
overflow: auto;
> ul {
padding: 12px 0 0 32px;
> li {
cursor: pointer;
color: #6C7D8C;
list-style: none;
line-height: 42px;
padding: 0 20px;
margin: 5px 0;
position: relative;
&.active,
&:hover {
background-color: #F4F5F7;
}
}
}
}
.setting-content {
flex: 1;
overflow: auto;
position: relative;
display: flex;
flex-direction: column;
.setting-content-title {
font-size: 20px;
font-weight: 500;
padding: 12px 32px;
}
.setting-content-view {
flex: 1;
position: relative;
.setting-router-view {
padding: 24px 40px;
}
}
}
}
}
</style>
<script>
import {mapState} from "vuex";
export default {
data() {
return {
curPath: this.$route.path,
menu: [
{
path: 'personal',
name: '个人设置'
},
{
path: 'password',
name: '密码设置'
},
{
path: 'system',
name: '系统设置'
},
{
path: 'priority',
name: '任务优先级'
}
]
}
},
mounted() {
},
computed: {
...mapState(['userInfo']),
},
watch: {
'$route' (route) {
this.curPath = route.path;
}
},
methods: {
toggleRoute(path) {
this.goForward({path: '/manage/setting/' + path});
},
classNameRoute(path) {
return {
"active": $A.leftExists(this.curPath, '/manage/setting/' + path)
};
},
}
}
</script>

View File

@ -0,0 +1,107 @@
<template>
<div class="setting-item submit">
<Form ref="formDatum" :model="formDatum" :rules="ruleDatum" label-width="auto" @submit.native.prevent>
<FormItem :label="$L('旧密码')" prop="oldpass">
<Input v-model="formDatum.oldpass" type="password"></Input>
</FormItem>
<FormItem :label="$L('新密码')" prop="newpass">
<Input v-model="formDatum.newpass" type="password"></Input>
</FormItem>
<FormItem :label="$L('确认新密码')" prop="checkpass">
<Input v-model="formDatum.checkpass" type="password"></Input>
</FormItem>
</Form>
<div class="setting-footer">
<Button :loading="loadIng > 0" type="primary" @click="submitForm">{{$L('提交')}}</Button>
<Button :loading="loadIng > 0" @click="resetForm" style="margin-left: 8px">{{$L('重置')}}</Button>
</div>
</div>
</template>
<script>
export default {
data() {
return {
loadIng: 0,
formDatum: {
oldpass: '',
newpass: '',
checkpass: '',
},
ruleDatum: { },
}
},
methods: {
initLanguage() {
this.ruleDatum = {
oldpass: [
{ required: true, message: this.$L('请输入旧密码!'), trigger: 'change' },
{ type: 'string', min: 6, message: this.$L('密码长度至少6位'), trigger: 'change' }
],
newpass: [
{
validator: (rule, value, callback) => {
if (value === '') {
callback(new Error(this.$L('请输入新密码!')));
} else {
if (this.formDatum.checkpass !== '') {
this.$refs.formDatum.validateField('checkpass');
}
callback();
}
},
required: true,
trigger: 'change'
},
{ type: 'string', min: 6, message: this.$L('密码长度至少6位'), trigger: 'change' }
],
checkpass: [
{
validator: (rule, value, callback) => {
if (value === '') {
callback(new Error(this.$L('请重新输入新密码!')));
} else if (value !== this.formDatum.newpass) {
callback(new Error(this.$L('两次密码输入不一致!')));
} else {
callback();
}
},
required: true,
trigger: 'change'
}
],
};
},
submitForm() {
this.$refs.formDatum.validate((valid) => {
if (valid) {
this.loadIng++;
$A.apiAjax({
url: 'users/editpass',
data: this.formDatum,
complete: () => {
this.loadIng--;
},
success: ({ret, data, msg}) => {
if (ret === 1) {
$A.messageSuccess('修改成功!');
this.$store.commit('setUserInfo', data);
this.$refs.formDatum.resetFields();
} else {
$A.modalError(msg);
}
}
});
}
})
},
resetForm() {
this.$refs.formDatum.resetFields();
}
}
}
</script>

View File

@ -0,0 +1,99 @@
<template>
<div class="setting-item submit">
<Form ref="formDatum" :model="formDatum" :rules="ruleDatum" label-width="auto" @submit.native.prevent>
<FormItem :label="$L('头像')" prop="userimg">
<ImgUpload v-model="formDatum.userimg" :num="1"></ImgUpload>
<span class="form-tip">{{$L('建议尺寸:%', '200x200')}}</span>
</FormItem>
<FormItem :label="$L('邮箱')">
<Input v-model="userInfo.email" disabled></Input>
</FormItem>
<FormItem :label="$L('昵称')" prop="nickname">
<Input v-model="formDatum.nickname" :maxlength="20"></Input>
</FormItem>
<FormItem :label="$L('职位/职称')" prop="profession">
<Input v-model="formDatum.profession" :maxlength="20"></Input>
</FormItem>
</Form>
<div class="setting-footer">
<Button :loading="loadIng > 0" type="primary" @click="submitForm">{{$L('提交')}}</Button>
<Button :loading="loadIng > 0" @click="resetForm" style="margin-left: 8px">{{$L('重置')}}</Button>
</div>
</div>
</template>
<script>
import ImgUpload from "../../../components/ImgUpload";
import {mapState} from "vuex";
export default {
components: {ImgUpload},
data() {
return {
loadIng: 0,
formDatum: {
userimg: '',
nickname: '',
profession: ''
},
ruleDatum: { },
}
},
mounted() {
this.initData();
},
computed: {
...mapState(['userInfo']),
},
watch: {
userInfo() {
this.initData();
}
},
methods: {
initLanguage() {
this.ruleDatum = {
nickname: [
{required: true, message: this.$L('请输入昵称!'), trigger: 'change'},
{type: 'string', min: 2, message: this.$L('昵称长度至少2位'), trigger: 'change'}
]
};
},
initData() {
this.$set(this.formDatum, 'userimg', this.userInfo.userimg);
this.$set(this.formDatum, 'nickname', this.userInfo.nickname);
this.$set(this.formDatum, 'profession', this.userInfo.profession);
this.formDatum_bak = $A.cloneJSON(this.formDatum);
},
submitForm() {
this.$refs.formDatum.validate((valid) => {
if (valid) {
this.loadIng++;
$A.apiAjax({
url: 'users/editdata',
data: this.formDatum,
complete: () => {
this.loadIng--;
},
success: ({ret, data, msg}) => {
if (ret === 1) {
$A.messageSuccess('修改成功');
this.$store.commit('getUserInfo');
} else {
$A.modalError(msg);
}
}
});
}
})
},
resetForm() {
this.formDatum = $A.cloneJSON(this.formDatum_bak);
}
}
}
</script>

View File

@ -0,0 +1,29 @@
<template>
<div class="setting-item">
asdada
</div>
</template>
<style lang="scss" scoped>
:global {
.setting-item {
}
}
</style>
<script>
export default {
props: {
},
data() {
return {
}
},
computed: {
},
}
</script>

View File

@ -0,0 +1,77 @@
<template>
<div class="setting-item submit">
<Form ref="formDatum" :model="formDatum" label-width="auto" @submit.native.prevent>
<FormItem :label="$L('允许注册')" prop="reg">
<RadioGroup v-model="formDatum.reg">
<Radio label="open">{{$L('允许')}}</Radio>
<Radio label="close">{{$L('禁止')}}</Radio>
</RadioGroup>
</FormItem>
<FormItem :label="$L('登录验证码')" prop="loginCode">
<RadioGroup v-model="formDatum.login_code">
<Radio label="auto">{{$L('自动')}}</Radio>
<Radio label="open">{{$L('开启')}}</Radio>
<Radio label="close">{{$L('关闭')}}</Radio>
</RadioGroup>
</FormItem>
</Form>
<div class="setting-footer">
<Button :loading="loadIng > 0" type="primary" @click="submitForm">{{$L('提交')}}</Button>
<Button :loading="loadIng > 0" @click="resetForm" style="margin-left: 8px">{{$L('重置')}}</Button>
</div>
</div>
</template>
<script>
export default {
data() {
return {
loadIng: 0,
formDatum: {},
}
},
mounted() {
this.systemSetting();
},
methods: {
submitForm() {
this.$refs.formDatum.validate((valid) => {
if (valid) {
this.systemSetting(true);
}
})
},
resetForm() {
this.formDatum = $A.cloneJSON(this.formDatum_bak);
},
systemSetting(save) {
this.loadIng++;
$A.apiAjax({
url: 'system/setting?type=' + (save ? 'save' : 'get'),
data: this.formDatum,
complete: () => {
this.loadIng--;
},
success: (res) => {
if (res.ret === 1) {
this.formDatum = res.data;
this.formDatum_bak = $A.cloneJSON(this.formDatum);
if (save) {
$A.messageSuccess('修改成功');
}
} else {
if (save) {
$A.modalError(res.msg);
}
}
}
});
}
}
}
</script>

View File

@ -25,7 +25,33 @@ export default [
{
name: 'manage-setting',
path: 'setting',
component: () => import('./pages/manage/setting.vue'),
component: () => import('./pages/manage/setting/index.vue'),
children: [
{
path: '',
redirect: 'personal',
},
{
name: 'manage-setting-personal',
path: 'personal',
component: () => import('./pages/manage/setting/personal.vue'),
},
{
name: 'manage-setting-password',
path: 'password',
component: () => import('./pages/manage/setting/password.vue'),
},
{
name: 'manage-setting-personal',
path: 'system',
component: () => import('./pages/manage/setting/system.vue'),
},
{
name: 'manage-setting-personal',
path: 'priority',
component: () => import('./pages/manage/setting/priority.vue'),
},
]
},
{
name: 'manage-project-detail',

View File

@ -23,7 +23,6 @@ export default {
* @param callback
*/
getUserInfo(state, callback) {
if (typeof callback === 'function' || callback === true) {
$A.apiAjax({
url: 'users/info',
error: () => {
@ -36,7 +35,6 @@ export default {
}
},
});
}
return state.userInfo;
},
@ -107,27 +105,45 @@ export default {
return;
}
const {userid, success, complete} = params;
if (typeof success === "function") {
if (state._isArray(userid)) {
userid.forEach((uid) => {
state.cacheUserBasic[uid] && success(state.cacheUserBasic[uid], false)
const time = Math.round(new Date().getTime() / 1000);
const array = [];
(state._isArray(userid) ? userid : [userid]).some((uid) => {
if (state.cacheUserBasic[uid]) {
typeof success === "function" && success(state.cacheUserBasic[uid].data, false);
if (time - state.cacheUserBasic[uid].time <= 10) {
return false;
}
}
array.push(uid);
});
} else {
state.cacheUserBasic[userid] && success(state.cacheUserBasic[userid], false)
if (array.length === 0) {
typeof complete === "function" && complete()
return;
}
//
if (state.cacheUserBasic["::loading"] === true) {
setTimeout(() => {
this.commit('getUserBasic', params);
}, 20);
return;
}
state.cacheUserBasic["::loading"] = true;
$A.apiAjax({
url: 'users/basic',
data: {
userid: userid
userid: array
},
complete: () => {
state.cacheUserBasic["::loading"] = false;
typeof complete === "function" && complete()
},
success: ({ret, data, msg}) => {
if (ret === 1) {
data.forEach((item) => {
state.cacheUserBasic[item.userid] = item;
state.cacheUserBasic[item.userid] = {
time,
data: item
};
typeof success === "function" && success(item, true)
});
} else {

View File

@ -15,6 +15,13 @@
}
}
body {
.ivu-input,
.ivu-select-selection {
border-color: #e8e8e8;
}
}
.ivu-modal-wrap {
&.simple-modal {
.ivu-modal {
@ -328,10 +335,6 @@
.ivu-form-item-label {
font-weight: 600;
}
.ivu-input,
.ivu-select-selection {
border-color: #e8e8e8;
}
.teditor-box {
.tox-tinymce {
border-color: #e8e8e8;
@ -580,5 +583,36 @@
}
}
.setting-item {
.ivu-input,
.ivu-select-selection {
max-width: 460px;
}
.form-tip {
color: #999999;
}
.setting-footer {
> button {
height: 34px;
line-height: 32px;
padding: 0 32px;
}
}
&.submit {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
.setting-footer {
position: absolute;
left: 0;
right: 0;
bottom: 0;
z-index: 1;
padding: 16px 24px 0;
border-top: 1px solid #F4F4F5;
}
}
}

View File

@ -1,6 +1,7 @@
<?php
use App\Http\Controllers\Api\ProjectController;
use App\Http\Controllers\Api\SystemController;
use App\Http\Controllers\Api\UsersController;
use App\Http\Controllers\IndexController;
use Illuminate\Support\Facades\Route;
@ -24,9 +25,12 @@ Route::prefix('api')->middleware(['webapi'])->group(function () {
// 会员
Route::any('users/{method}', UsersController::class);
Route::any('users/{method}/{action}', UsersController::class);
//项目
// 项目
Route::any('project/{method}', ProjectController::class);
Route::any('project/{method}/{action}', ProjectController::class);
// 系统
Route::any('system/{method}', SystemController::class);
Route::any('system/{method}/{action}', SystemController::class);
});
/**