mirror of
https://github.com/casdoor/casdoor.git
synced 2025-05-24 08:20:31 +08:00
Add address to user.
This commit is contained in:
parent
7434d0f3d3
commit
081da18403
@ -27,22 +27,23 @@ type User struct {
|
|||||||
CreatedTime string `xorm:"varchar(100)" json:"createdTime"`
|
CreatedTime string `xorm:"varchar(100)" json:"createdTime"`
|
||||||
UpdatedTime string `xorm:"varchar(100)" json:"updatedTime"`
|
UpdatedTime string `xorm:"varchar(100)" json:"updatedTime"`
|
||||||
|
|
||||||
Id string `xorm:"varchar(100)" json:"id"`
|
Id string `xorm:"varchar(100)" json:"id"`
|
||||||
Type string `xorm:"varchar(100)" json:"type"`
|
Type string `xorm:"varchar(100)" json:"type"`
|
||||||
Password string `xorm:"varchar(100)" json:"password"`
|
Password string `xorm:"varchar(100)" json:"password"`
|
||||||
DisplayName string `xorm:"varchar(100)" json:"displayName"`
|
DisplayName string `xorm:"varchar(100)" json:"displayName"`
|
||||||
Avatar string `xorm:"varchar(255)" json:"avatar"`
|
Avatar string `xorm:"varchar(255)" json:"avatar"`
|
||||||
Email string `xorm:"varchar(100)" json:"email"`
|
Email string `xorm:"varchar(100)" json:"email"`
|
||||||
Phone string `xorm:"varchar(100)" json:"phone"`
|
Phone string `xorm:"varchar(100)" json:"phone"`
|
||||||
Affiliation string `xorm:"varchar(100)" json:"affiliation"`
|
Address []string `json:"address"`
|
||||||
Tag string `xorm:"varchar(100)" json:"tag"`
|
Affiliation string `xorm:"varchar(100)" json:"affiliation"`
|
||||||
Language string `xorm:"varchar(100)" json:"language"`
|
Tag string `xorm:"varchar(100)" json:"tag"`
|
||||||
Score int `json:"score"`
|
Language string `xorm:"varchar(100)" json:"language"`
|
||||||
IsAdmin bool `json:"isAdmin"`
|
Score int `json:"score"`
|
||||||
IsGlobalAdmin bool `json:"isGlobalAdmin"`
|
IsAdmin bool `json:"isAdmin"`
|
||||||
IsForbidden bool `json:"isForbidden"`
|
IsGlobalAdmin bool `json:"isGlobalAdmin"`
|
||||||
Hash string `xorm:"varchar(100)" json:"hash"`
|
IsForbidden bool `json:"isForbidden"`
|
||||||
PreHash string `xorm:"varchar(100)" json:"preHash"`
|
Hash string `xorm:"varchar(100)" json:"hash"`
|
||||||
|
PreHash string `xorm:"varchar(100)" json:"preHash"`
|
||||||
|
|
||||||
Github string `xorm:"varchar(100)" json:"github"`
|
Github string `xorm:"varchar(100)" json:"github"`
|
||||||
Google string `xorm:"varchar(100)" json:"google"`
|
Google string `xorm:"varchar(100)" json:"google"`
|
||||||
@ -113,7 +114,7 @@ func UpdateUser(id string, user *User) bool {
|
|||||||
|
|
||||||
user.UpdateUserHash()
|
user.UpdateUserHash()
|
||||||
|
|
||||||
affected, err := adapter.Engine.ID(core.PK{owner, name}).Cols("display_name", "avatar", "affiliation", "tag", "is_admin", "is_global_admin", "is_forbidden", "hash").Update(user)
|
affected, err := adapter.Engine.ID(core.PK{owner, name}).Cols("display_name", "avatar", "address", "affiliation", "tag", "is_admin", "is_global_admin", "is_forbidden", "hash").Update(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ import * as ApplicationBackend from "./backend/ApplicationBackend";
|
|||||||
import * as Provider from "./auth/Provider";
|
import * as Provider from "./auth/Provider";
|
||||||
import PasswordModal from "./PasswordModal";
|
import PasswordModal from "./PasswordModal";
|
||||||
import ResetModal from "./ResetModal";
|
import ResetModal from "./ResetModal";
|
||||||
|
import AffiliationSelect from "./common/AffiliationSelect";
|
||||||
|
|
||||||
import {Controlled as CodeMirror} from 'react-codemirror2'
|
import {Controlled as CodeMirror} from 'react-codemirror2'
|
||||||
import "codemirror/lib/codemirror.css"
|
import "codemirror/lib/codemirror.css"
|
||||||
@ -319,24 +320,11 @@ class UserEditPage extends React.Component {
|
|||||||
{ this.state.user.id === this.props.account?.id ? (<ResetModal org={this.state.application?.organizationObj} buttonText={i18next.t("user:Reset Phone...")} destType={"phone"} coolDownTime={60}/>) : null}
|
{ this.state.user.id === this.props.account?.id ? (<ResetModal org={this.state.application?.organizationObj} buttonText={i18next.t("user:Reset Phone...")} destType={"phone"} coolDownTime={60}/>) : null}
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row style={{marginTop: '20px'}} >
|
{
|
||||||
<Col style={{marginTop: '5px'}} span={2}>
|
(this.state.application === null || this.state.user === null) ? null : (
|
||||||
{i18next.t("user:Affiliation")}:
|
<AffiliationSelect application={this.state.application} user={this.state.user} onUpdateUserField={(key, value) => { return this.updateUserField(key, value)}} />
|
||||||
</Col>
|
)
|
||||||
<Col span={22} >
|
}
|
||||||
{
|
|
||||||
this.state.application?.affiliationUrl === "" ? (
|
|
||||||
<Input value={this.state.user.affiliation} onChange={e => {
|
|
||||||
this.updateUserField('affiliation', e.target.value);
|
|
||||||
}} />
|
|
||||||
) : (
|
|
||||||
<Button key="home" onClick={() => Setting.goToLink(this.state.application.affiliationUrl)}>
|
|
||||||
{`${i18next.t("user:Modify affiliation")}...`}
|
|
||||||
</Button>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
<Row style={{marginTop: '20px'}} >
|
<Row style={{marginTop: '20px'}} >
|
||||||
<Col style={{marginTop: '5px'}} span={2}>
|
<Col style={{marginTop: '5px'}} span={2}>
|
||||||
{i18next.t("user:Tag")}:
|
{i18next.t("user:Tag")}:
|
||||||
|
@ -53,6 +53,7 @@ class UserListPage extends React.Component {
|
|||||||
avatar: "https://casbin.org/img/casbin.svg",
|
avatar: "https://casbin.org/img/casbin.svg",
|
||||||
email: "user@example.com",
|
email: "user@example.com",
|
||||||
phone: "12345678",
|
phone: "12345678",
|
||||||
|
address: [],
|
||||||
affiliation: "Example Inc.",
|
affiliation: "Example Inc.",
|
||||||
tag: "staff",
|
tag: "staff",
|
||||||
isAdmin: false,
|
isAdmin: false,
|
||||||
|
@ -64,6 +64,18 @@ export function deleteUser(user) {
|
|||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getAddressOptions(url) {
|
||||||
|
return fetch(url, {
|
||||||
|
method: "GET",
|
||||||
|
}).then(res => res.json());
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getAffiliationOptions(url, code) {
|
||||||
|
return fetch(`${url}/${code}`, {
|
||||||
|
method: "GET",
|
||||||
|
}).then(res => res.json());
|
||||||
|
}
|
||||||
|
|
||||||
export function uploadAvatar(avatar) {
|
export function uploadAvatar(avatar) {
|
||||||
let account;
|
let account;
|
||||||
AuthBackend.getAccount("").then((res) => {
|
AuthBackend.getAccount("").then((res) => {
|
||||||
|
106
web/src/common/AffiliationSelect.js
Normal file
106
web/src/common/AffiliationSelect.js
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
import React from "react";
|
||||||
|
import {Cascader, Col, Input, Row, Select} from 'antd';
|
||||||
|
import * as Setting from "../Setting";
|
||||||
|
import i18next from "i18next";
|
||||||
|
import * as UserBackend from "../backend/UserBackend";
|
||||||
|
|
||||||
|
const { Option } = Select;
|
||||||
|
|
||||||
|
class AffiliationSelect extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
classes: props,
|
||||||
|
addressOptions: [],
|
||||||
|
affiliationOptions: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillMount() {
|
||||||
|
this.getAddressOptions(this.props.application);
|
||||||
|
this.getAffiliationOptions(this.props.application, this.props.user);
|
||||||
|
}
|
||||||
|
|
||||||
|
getAddressOptions(application) {
|
||||||
|
if (application.affiliationUrl === "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const addressUrl = application.affiliationUrl.split("|")[0];
|
||||||
|
UserBackend.getAddressOptions(addressUrl)
|
||||||
|
.then((addressOptions) => {
|
||||||
|
this.setState({
|
||||||
|
addressOptions: addressOptions,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getAffiliationOptions(application, user) {
|
||||||
|
if (application.affiliationUrl === "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const affiliationUrl = application.affiliationUrl.split("|")[1];
|
||||||
|
const code = user.address[user.address.length - 1];
|
||||||
|
UserBackend.getAffiliationOptions(affiliationUrl, code)
|
||||||
|
.then((affiliationOptions) => {
|
||||||
|
this.setState({
|
||||||
|
affiliationOptions: affiliationOptions,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
updateUserField(key, value) {
|
||||||
|
this.props.onUpdateUserField(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let options = this.state.addressOptions;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
{
|
||||||
|
this.props.application?.affiliationUrl === "" ? null : (
|
||||||
|
<Row style={{marginTop: '20px'}} >
|
||||||
|
<Col style={{marginTop: '5px'}} span={2}>
|
||||||
|
{i18next.t("user:Address")}:
|
||||||
|
</Col>
|
||||||
|
<Col span={22} >
|
||||||
|
<Cascader style={{width: '400px'}} value={this.props.user.address} options={options} onChange={value => {
|
||||||
|
this.updateUserField('address', value);
|
||||||
|
this.updateUserField('affiliation', '');
|
||||||
|
this.getAffiliationOptions(this.props.application, this.props.user);
|
||||||
|
}} placeholder={i18next.t("signup:Please input your address!")} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
<Row style={{marginTop: '20px'}} >
|
||||||
|
<Col style={{marginTop: '5px'}} span={2}>
|
||||||
|
{i18next.t("user:Affiliation")}:
|
||||||
|
</Col>
|
||||||
|
<Col span={22} >
|
||||||
|
{
|
||||||
|
this.props.application?.affiliationUrl === "" ? (
|
||||||
|
<Input value={this.props.user.affiliation} onChange={e => {
|
||||||
|
this.updateUserField('affiliation', e.target.value);
|
||||||
|
}} />
|
||||||
|
) : (
|
||||||
|
<Select virtual={false} style={{width: '400px'}} value={Setting.myParseInt(this.props.user.affiliation)} onChange={(value => {this.updateUserField('affiliation', value.toString());})}>
|
||||||
|
{
|
||||||
|
<Option key={0} value={0}>(空)</Option>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
this.state.affiliationOptions.map((affiliationOption, index) => <Option key={affiliationOption.id} value={affiliationOption.id}>{affiliationOption.name}</Option>)
|
||||||
|
}
|
||||||
|
</Select>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</React.Fragment>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AffiliationSelect;
|
@ -37,6 +37,7 @@
|
|||||||
{
|
{
|
||||||
"Username": "Username",
|
"Username": "Username",
|
||||||
"Please input your display name!": "Please input your display name!",
|
"Please input your display name!": "Please input your display name!",
|
||||||
|
"Please input your address!": "Please input your address!",
|
||||||
"Please input your affiliation!": "Please input your affiliation!",
|
"Please input your affiliation!": "Please input your affiliation!",
|
||||||
"The input is not valid Email!": "The input is not valid Email!",
|
"The input is not valid Email!": "The input is not valid Email!",
|
||||||
"Please input your Email!": "Please input your Email!",
|
"Please input your Email!": "Please input your Email!",
|
||||||
@ -113,6 +114,7 @@
|
|||||||
"Set new profile picture": "Set new profile picture",
|
"Set new profile picture": "Set new profile picture",
|
||||||
"Set password...": "Set password...",
|
"Set password...": "Set password...",
|
||||||
"Modify password...": "Modify password...",
|
"Modify password...": "Modify password...",
|
||||||
|
"Address": "Address",
|
||||||
"Affiliation": "Affiliation",
|
"Affiliation": "Affiliation",
|
||||||
"Modify affiliation": "Modify affiliation",
|
"Modify affiliation": "Modify affiliation",
|
||||||
"Tag": "Tag",
|
"Tag": "Tag",
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
{
|
{
|
||||||
"Username": "用户名",
|
"Username": "用户名",
|
||||||
"Please input your display name!": "请输入您的姓名!",
|
"Please input your display name!": "请输入您的姓名!",
|
||||||
|
"Please input your address!": "请输入您的地址!",
|
||||||
"Please input your affiliation!": "请输入您所在的工作单位!",
|
"Please input your affiliation!": "请输入您所在的工作单位!",
|
||||||
"The input is not valid Email!": "您输入的电子邮箱格式错误!",
|
"The input is not valid Email!": "您输入的电子邮箱格式错误!",
|
||||||
"Please input your Email!": "请输入您的电子邮箱!",
|
"Please input your Email!": "请输入您的电子邮箱!",
|
||||||
@ -113,6 +114,7 @@
|
|||||||
"Set new profile picture": "设置新头像",
|
"Set new profile picture": "设置新头像",
|
||||||
"Set password...": "设置密码...",
|
"Set password...": "设置密码...",
|
||||||
"Modify password...": "修改密码...",
|
"Modify password...": "修改密码...",
|
||||||
|
"Address": "地址",
|
||||||
"Affiliation": "工作单位",
|
"Affiliation": "工作单位",
|
||||||
"Modify affiliation": "修改工作单位",
|
"Modify affiliation": "修改工作单位",
|
||||||
"Tag": "标签",
|
"Tag": "标签",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user