diff --git a/doc/RBAC 权限.sql b/doc/RBAC 权限.sql
new file mode 100644
index 0000000..6e70db9
--- /dev/null
+++ b/doc/RBAC 权限.sql
@@ -0,0 +1,66 @@
+CREATE TABLE auth_role
+(
+ [role_id] [int] IDENTITY(1,1) NOT NULL,
+ [role_name] [nvarchar](255) NOT NULL,
+ [created_on] [datetime] NOT NULL,
+ CONSTRAINT [PK_auth_role] PRIMARY KEY CLUSTERED
+(
+ [role_id] ASC
+)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
+) ON [PRIMARY]
+
+ALTER TABLE auth_role ADD CONSTRAINT [DF_auth_role_created_on] DEFAULT (getdate()) FOR [created_on]
+
+CREATE TABLE auth_permission
+(
+ [role_id] [int] NOT NULL,
+ [res_id] [int] NOT NULL
+) ON [PRIMARY]
+
+CREATE TABLE auth_resource
+(
+ [res_id] [int] IDENTITY(1,1) NOT NULL,
+ [res_name] [nvarchar](255) NOT NULL,
+ [res_pattern] [nvarchar](255) NOT NULL,
+ [res_category] [nvarchar](255) NOT NULL,
+ CONSTRAINT [PK_auth_resource] PRIMARY KEY CLUSTERED
+(
+ [res_id] ASC
+)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
+) ON [PRIMARY]
+
+INSERT INTO [dbo].[auth_role] ([role_name])
+VALUES ('系统管理员')
+INSERT INTO [dbo].[auth_role] ([role_name])
+VALUES ('国内供应商')
+INSERT INTO [dbo].[auth_role] ([role_name])
+VALUES ('海外供应商')
+INSERT INTO [dbo].[auth_role] ([role_name])
+VALUES ('客服组')
+INSERT INTO [dbo].[auth_role] ([role_name])
+VALUES ('产品组')
+INSERT INTO [dbo].[auth_role] ([role_name])
+VALUES ('技术研发部')
+
+INSERT INTO [dbo].[auth_resource] ([res_name] ,[res_pattern], [res_category])
+VALUES ('所有权限', '*', 'system')
+INSERT INTO [dbo].[auth_resource] ([res_name] ,[res_pattern], [res_category])
+VALUES ('最新团计划', '/reservation/newest', 'oversea')
+INSERT INTO [dbo].[auth_resource] ([res_name] ,[res_pattern], [res_category])
+VALUES ('账单', '/invoice', 'oversea')
+
+INSERT INTO [dbo].[auth_resource] ([res_name] ,[res_pattern], [res_category])
+VALUES ('账号权限管理', '/account/management', 'system')
+INSERT INTO [dbo].[auth_resource] ([res_name] ,[res_pattern], [res_category])
+VALUES ('新增角色', '/account/new-role', 'system')
+
+INSERT INTO [dbo].[auth_permission] ([role_id] ,[res_id])
+VALUES (1, 1)
+INSERT INTO [dbo].[auth_permission] ([role_id] ,[res_id])
+VALUES (6, 2)
+INSERT INTO [dbo].[auth_permission] ([role_id] ,[res_id])
+VALUES (6, 3)
+INSERT INTO [dbo].[auth_permission] ([role_id] ,[res_id])
+VALUES (6, 4)
+INSERT INTO [dbo].[auth_permission] ([role_id] ,[res_id])
+VALUES (6, 5)
diff --git a/doc/价格管理平台.bmpr b/doc/价格管理平台.bmpr
index f82ae80..2e3bd02 100644
Binary files a/doc/价格管理平台.bmpr and b/doc/价格管理平台.bmpr differ
diff --git a/public/locales/en/common.json b/public/locales/en/common.json
index 4ad6ddc..a513e2a 100644
--- a/public/locales/en/common.json
+++ b/public/locales/en/common.json
@@ -18,6 +18,7 @@
"Download": "Download",
"Upload": "Upload",
"preview": "Preview",
+ "Total": "Total",
"Login": "Login",
"Username": "Username",
diff --git a/public/locales/zh/common.json b/public/locales/zh/common.json
index f6c273c..59c417e 100644
--- a/public/locales/zh/common.json
+++ b/public/locales/zh/common.json
@@ -18,6 +18,7 @@
"Download": "下载",
"Upload": "上传",
"preview": "预览",
+ "Total": "总数",
"Login": "登录",
"Username": "账号",
diff --git a/src/stores/Reservation.js b/src/stores/Reservation.js
index 686d191..8990ae7 100644
--- a/src/stores/Reservation.js
+++ b/src/stores/Reservation.js
@@ -1,4 +1,3 @@
-import { makeAutoObservable, runInAction } from "mobx"
import { create } from 'zustand'
import { fetchJSON, postForm } from '@/utils/request'
import { HT_HOST } from "@/config"
@@ -211,88 +210,65 @@ const useReservationStore = create((set, get) => ({
return json
}
});
- }
-}))
+ },
+
+ setupCityGuide: (cityId, guideId) => {
+ const { selectedReservation } = get()
+ const { userId, travelAgencyId } = usingStorage()
+ const formData = new FormData()
+ formData.append('GRI_SN', selectedReservation.reservationId)
+ formData.append('VEI_SN', travelAgencyId)
+ formData.append('TGI_SN', guideId)
+ formData.append('CII_SN', cityId)
+ formData.append('GetDate', selectedReservation.reservationDate)
+ formData.append('LMI_SN', userId)
+ const postUrl = HT_HOST + '/service-cusservice/PTAddGuide'
-export default useReservationStore
+ return postForm(postUrl, formData)
+ .then(json => {
+ if (json.errcode != 0) {
+ throw new Error(json.errmsg + ': ' + json.errcode)
+ }
+ });
+ },
-export class Reservation {
- constructor(root) {
- makeAutoObservable(this, { rootStore: false });
- this.root = root;
- }
- updateReservationGuide() {
+ updateReservationGuide: () => {
+ const { selectedReservation } = get()
+ const { travelAgencyId } = usingStorage()
const fetchUrl = prepareUrl(HT_HOST + '/service-cusservice/PTGetCityGuide')
- .append('VEI_SN', this.root.authStore.login.travelAgencyId)
- .append('GRI_SN', this.selectedReservation.reservationId)
+ .append('VEI_SN', travelAgencyId)
+ .append('GRI_SN', selectedReservation.reservationId)
.append('LGC', 1)
- .append("token", this.root.authStore.login.token)
.build();
return fetchJSON(fetchUrl)
.then(json => {
if (json.errcode == 0) {
const reservationGuide = (json?.Result??[]).filter((data) => {
- return data.TGI_SN != 0;
+ return data.TGI_SN != 0
}).map((data) => {
- return data.GuideName;
- }).join(',');
+ return data.GuideName
+ }).join(',')
+
runInAction(() => {
- this.selectedReservation.guide = reservationGuide;
- });
- return reservationGuide;
- } else {
- throw new Error(json.errmsg + ': ' + json.errcode);
- }
- });
- }
+ selectedReservation.guide = reservationGuide
+ })
- setupCityGuide(cityId, guideId) {
- let formData = new FormData();
- formData.append('GRI_SN', this.selectedReservation.reservationId);
- formData.append('VEI_SN', this.root.authStore.login.travelAgencyId);
- formData.append('TGI_SN', guideId);
- formData.append('CII_SN', cityId);
- formData.append('GetDate', this.selectedReservation.reservationDate);
- formData.append('LMI_SN', this.root.authStore.login.userId);
- formData.append("token", this.root.authStore.login.token);
- const postUrl = HT_HOST + '/service-cusservice/PTAddGuide';
+ set((state) => ({
+ selectedReservation: {
+ ...state.selectedReservation,
+ guide: reservationGuide,
+ },
+ }))
- return postForm(postUrl, formData)
- .then(json => {
- if (json.errcode != 0) {
- throw new Error(json.errmsg + ': ' + json.errcode);
+ return reservationGuide
+ } else {
+ throw new Error(json.errmsg + ': ' + json.errcode)
}
- });
- }
-
- updatePropertyValue(name, value) {
- runInAction(() => {
- this[name] = value;
- });
- }
-
- cityList = [];
-
- selectedReservation = null;
- selectedConfirmation = null;
- arrivalDateRange = [];
- referenceNo = '';
-
- reservationList = [];
-
- reservationDetail = {
- referenceNumber: '', arrivalDate: '', tourGuide: ''
- };
-
- reservationPage = {
- current: 1,
- size: 10,
- total: 0
+ })
}
+}))
- confirmationList = [
- ];
-}
\ No newline at end of file
+export default useReservationStore
\ No newline at end of file
diff --git a/src/stores/Root.js b/src/stores/Root.js
index 57645f4..d8369f5 100644
--- a/src/stores/Root.js
+++ b/src/stores/Root.js
@@ -1,11 +1,9 @@
import { makeAutoObservable } from "mobx";
-import { Reservation } from "./Reservation";
import { Auth } from "./Auth";
import {Invoice} from "./Invoice";
class Root {
constructor() {
- this.reservationStore = new Reservation(this);
this.authStore = new Auth(this);
this.invoiceStore = new Invoice(this);
makeAutoObservable(this);
diff --git a/src/views/App.jsx b/src/views/App.jsx
index 0d11cd0..dd2dec6 100644
--- a/src/views/App.jsx
+++ b/src/views/App.jsx
@@ -148,8 +148,9 @@ function App() {
items: [...[
{ label: {t('ChangePassword')}, key: '0' },
{ label: {t('Profile')}, key: '1' },
+ { label: {t('account:management.tile')}, key: '3' },
{ type: 'divider' },
- { label: {t('Logout')}, key: '3' },
+ { label: {t('Logout')}, key: '4' },
],
{ type: 'divider' },
{ label: <>v{BUILD_VERSION}>, key: 'BUILD_VERSION' },
diff --git a/src/views/Standlone.jsx b/src/views/Standlone.jsx
index e13fd85..24acad3 100644
--- a/src/views/Standlone.jsx
+++ b/src/views/Standlone.jsx
@@ -1,42 +1,37 @@
-import { Outlet, Link, useHref, useLocation } from "react-router-dom";
-import { useEffect } from "react";
-import { observer } from "mobx-react";
-import { Layout, Menu, ConfigProvider, theme, Typography, Space, Row, Col, Alert, App as AntApp } from "antd";
-import { DownOutlined } from "@ant-design/icons";
-import "antd/dist/reset.css";
-import AppLogo from "@/assets/logo-gh.png";
-import { useStore } from "@/stores/StoreContext.js";
-import Language from "../i18n/LanguageSwitcher";
+import { Outlet } from 'react-router-dom'
+import { Layout, ConfigProvider, theme, Typography, Row, Col, App as AntApp } from 'antd'
+import 'antd/dist/reset.css'
+import AppLogo from '@/assets/logo-gh.png'
+import Language from '../i18n/LanguageSwitcher'
-const { Title } = Typography;
-const { Header, Content, Footer } = Layout;
+const { Title } = Typography
+const { Header, Content, Footer } = Layout
function Standlone() {
- const { authStore } = useStore();
const {
token: { colorBgContainer },
- } = theme.useToken();
+ } = theme.useToken()
return (
+
-