diff --git a/package.json b/package.json
index fde34d1..e1eccd3 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,7 @@
"preview": "vite preview"
},
"dependencies": {
+ "ahooks": "^3.7.8",
"antd": "^5.12.8",
"mobx": "^6.12.0",
"mobx-react": "^9.1.0",
diff --git a/src/main.jsx b/src/main.jsx
index fc6b817..49bc1b2 100644
--- a/src/main.jsx
+++ b/src/main.jsx
@@ -59,12 +59,12 @@ const router = createBrowserRouter([
const rootStore = new RootStore();
ReactDOM.createRoot(document.getElementById('root')).render(
-
+ //
Loading...
}
/>
-
+ //
)
diff --git a/src/stores/Auth.js b/src/stores/Auth.js
index 14b4ff2..76b02a1 100644
--- a/src/stores/Auth.js
+++ b/src/stores/Auth.js
@@ -1,7 +1,6 @@
import { makeAutoObservable, runInAction } from 'mobx'
const KEY_USER_ID = 'KEY_USER_ID'
-const KEY_WEBSITE = 'KEY_WEBSITE'
class Auth {
@@ -9,22 +8,17 @@ class Auth {
makeAutoObservable(this, { rootStore: false })
this.root = root
this.userId = root.getSession(KEY_USER_ID)
- this.website = root.getSession(KEY_WEBSITE)
}
- setup(userId, website) {
+ setup(userId) {
runInAction(() => {
this.userId = userId
- this.website = website
- });
+ })
this.root.putSession(KEY_USER_ID, userId)
- this.root.putSession(KEY_WEBSITE, website)
}
- // HT 账号 SN
+ // HT 账号 OP_SN
userId = null
- // 从哪个网站打开,HTML 代码应用到哪个网站
- website = ''
}
export default Auth
diff --git a/src/stores/Order.js b/src/stores/Order.js
index a110dab..fbeb0da 100644
--- a/src/stores/Order.js
+++ b/src/stores/Order.js
@@ -73,13 +73,6 @@ class Order {
})
}
- getKeywordHistory() {
- const keywordListText = this.root.getLocal('KEYWORD_LIST')
- const keywordList = isEmpty(keywordListText) ? [] : JSON.parse(keywordListText)
- return keywordList.map(keyword => {
- return {value: keyword}
- })
- }
fetchCityList(countryId) {
const fetchCityUrl =
@@ -103,238 +96,9 @@ class Order {
})
}
- fetchCropImageList(userId) {
- const formData = new FormData()
- formData.append('PII_SN', this.selectedImage.PII_SN)
- formData.append('user_id', userId)
- const postUrl = 'https://p9axztuwd7x8a7.mycht.cn/service-InfoSysSOA/search_cutimage'
-
- return postForm(postUrl, formData)
- .then(json => {
- if (json.errcode == 0) {
- runInAction(() => {
- this.croppedImageList = json.result
- })
- } else {
- throw new Error(json.errmsg + ': ' + json.errcode)
- }
- })
- }
-
- toggleFavorite(image, userId) {
- runInAction(() => {
- image.isFavorite = !image.isFavorite
- })
- const formData = new FormData()
- formData.append('PII_SN', image.PII_SN)
- formData.append('user_id', userId)
- formData.append('addordelete', image.isFavorite ? 1: 0)
- const postUrl = 'https://p9axztuwd7x8a7.mycht.cn/service-InfoSysSOA/favorite_image'
-
- return postForm(postUrl, formData)
- .then(json => {
- if (json.errcode == 0) {
- console.info(json)
- // json.result.PII_SN
- } else {
- throw new Error(json.errmsg + ': ' + json.errcode)
- }
- })
- }
-
- fetchImageList(country, city, keyword, tags, star, type, userId) {
-
- runInAction(() => {
- this.imageSearchList = []
- })
-
- if (isNotEmpty(keyword)) {
- const keywordListText = this.root.getLocal('KEYWORD_LIST')
- const keywordList = isEmpty(keywordListText) ? [] : JSON.parse(keywordListText)
- if (keywordList.indexOf(keyword) == -1) {
-
- keywordList.unshift(keyword)
- }
- if (keywordList.length > 8) {
- keywordList.splice(8, keywordList.length)
- }
- this.root.putLocal('KEYWORD_LIST', JSON.stringify(keywordList))
- }
-
- const formData = new FormData()
- formData.append('CountrySN', country)
- formData.append('citySN', city)
- formData.append('keyword', keyword)
- formData.append('tags', tags)
- formData.append('star', star)
- formData.append('searchType', type)
- formData.append('user_id', userId)
- const postUrl = 'https://p9axztuwd7x8a7.mycht.cn/service-InfoSysSOA/search_image'
-
- return postForm(postUrl, formData)
- .then(json => {
- if (json.errcode == 0) {
- runInAction(() => {
- this.imageSearchList = json.result
- })
- } else {
- throw new Error(json.errmsg + ': ' + json.errcode)
- }
- })
- }
-
- startUpload(userId) {
-
- for (let index = 0; index < this.imageUploadList.length; index++) {
- const element = this.imageUploadList[index];
- this.requiredAlert =
- (element.country === null) ||
- (element.city === null) ||
- (element.description_zh === '') ||
- (element.description_en === '') ||
- (element.photographer === '') ||
- (element.copyright === -1) ||
- (element.star === -1)
-
- if (this.requiredAlert) break
- }
-
- if (this.requiredAlert) return
-
- let successCount = 0
- this.uploadPercent = 0
- const imageCount = this.imageUploadList.length
- const postUrl = 'https://p9axztuwd7x8a7.mycht.cn/service-InfoSysSOA/upload_image'
-
- this.imageUploadList.forEach((element, index) => {
- const formData = new FormData()
- formData.append('image_file', element.image_file)
- formData.append('image_uid', element.image_uid)
- formData.append('country', element.country)
- formData.append('city', element.city)
- formData.append('description_zh', element.description_zh)
- formData.append('description_en', element.description_en)
- formData.append('photographer', element.photographer)
- formData.append('copyright', element.copyright)
- formData.append('labels', element.labelValues.join(','))
- formData.append('user_id', userId)
- formData.append('star', element.star)
-
- return postForm(postUrl, formData)
- .then(json => {
- successCount++
- runInAction(() => {
- this.uploadPercent = parseInt(successCount / imageCount * 100)
- })
- if (json.errcode == 0) {
- runInAction(() => {
- for (var i = this.imageUploadList.length - 1; i >= 0; i--) {
- const current = this.imageUploadList[i]
- if (current.image_uid === json.result.image_uid) {
- current.success = true
- current.image_url = 'https://p9axztuwd7x8a7.mycht.cn/service-fileServer' + json.result.image_path
- break
- }
- }
- })
- } else {
- throw new Error(json.errmsg + ': ' + json.errcode)
- }
- })
- })
- }
-
- startCrop(cropData, resizeWidth, userId, website) {
- const formData = new FormData()
- formData.append('filename', this.selectedImage.PII_Location + this.selectedImage.PII_FileName)
- formData.append('x', cropData.x)
- formData.append('y', cropData.y)
- formData.append('width', Math.trunc(cropData.width))
- formData.append('height', Math.trunc(cropData.height))
- formData.append('resize_width', resizeWidth)
- formData.append('user_id', userId)
- formData.append('webcode', website)
- const postUrl = 'https://p9axztuwd7x8a7.mycht.cn/service-InfoSysSOA/crop_image'
-
- return postForm(postUrl, formData)
- .then(json => {
- if (json.errcode == 0) {
- this.fetchCropImageList()
- const imageHtml = this.generateHtml(json.result, website)
- const cropResult = {
- imageHtml: imageHtml
- }
- return cropResult
- } else {
- throw new Error(json.errmsg + ': ' + json.errcode)
- }
- })
- }
-
- getImageHost(website) {
- let imageHost = ''
- switch (website) {
- case 'ch':
- imageHost = 'https://images.chinahighlights.com'
- break
- case 'ah':
- imageHost = 'https://images.asiahighlights.com'
- break
- case 'gh':
- imageHost = 'https://images.globalhighlights.com'
- break
- case 'chinatravel':
- imageHost = 'https://images.chinatravel.com'
- break
- case 'sht':
- imageHost = 'https://images.shanghaihighlights.com'
- break
- case 'ts':
- imageHost = 'https://images.trainspread.com'
- break
- case 'mbj':
- imageHost = 'https://images.mybeijingchina.com'
- break
- default:
- imageHost = 'https://images.chinahighlights.com'
- break
- }
- return imageHost
- }
-
- generateHtml(imageObj, website) {
- const imageUrl = this.getImageHost(website) + imageObj.PII_Location + imageObj.PII_FileName
- let imageHtml = ''
-
- switch (website) {
- case 'ch':
- imageHtml = '
' + imageObj.PII2_Intro + ' '
- break
- case 'ah':
- imageHtml = '
' + imageObj.PII2_Intro + ' '
- break
- case 'gh':
- imageHtml = '
' + imageObj.PII2_Intro + ' '
- break
- case 'chinatravel':
- case 'sht':
- case 'ts':
- case 'mbj':
- imageHtml = '
'
- break
- default:
- imageHtml = '
'
- break
- }
-
- return imageHtml
- }
-
useImage(imageId, userId, website) {
const formData = new FormData()
formData.append('PII_SN', imageId)
- formData.append('user_id', userId)
- formData.append('Webcode', website)
const postUrl = 'https://p9axztuwd7x8a7.mycht.cn/service-InfoSysSOA/use_image'
return postForm(postUrl, formData)
@@ -346,86 +110,6 @@ class Order {
}
})
}
-
- continueUpload() {
- runInAction(() => {
- this.imageUploadList = []
- this.uploadPercent = -1
- })
- }
-
- initImageList(fileList) {
- runInAction(() => {
- this.imageUploadList = fileList.map(file => {
- return {
- image_file: file,
- image_uid: file.uid,
- country: null,
- city: null,
- description_zh: '',
- description_en: '',
- photographer: '',
- copyright: -1,
- labels: '',
- labelValues: [],
- user_id: -1,
- star: -1,
- success: false,
- image_url: ''
- }
- })
- })
- }
-
- removeUploadImage(fileUid) {
- runInAction(() => {
- this.imageUploadList = this.imageUploadList.filter((image, index) => {
- return image.image_uid != fileUid
- })
- })
- }
-
- syncProperties() {
- if (this.imageUploadList.length > 1) {
- const source = this.imageUploadList[0]
- runInAction(() => {
- for (let index = 1; index < this.imageUploadList.length; index++) {
- const current = this.imageUploadList[index]
- current.country = source.country
- current.city = source.city
- current.description_zh = source.description_zh
- current.description_en = source.description_en
- current.photographer = source.photographer
- current.copyright = source.copyright
- current.labelValues = source.labelValues
- current.user_id = source.user_id
- current.star = source.star
- }
- })
- }
- }
-
- updateImageProperty(uid, name, value) {
- for (var i = this.imageUploadList.length - 1; i >= 0; i--) {
- const current = this.imageUploadList[i]
- if (current.image_file.uid === uid) {
- current[name] = value
- break
- }
- }
- }
-
- selectImage(image) {
- this.selectedImage = image
- }
-
- imageUploadList = []
- imageSearchList = []
- uploadPercent = -1
- selectedImage = null
- croppedImageList = []
- // 上传时数据验证是否通过
- requiredAlert = false
}
export default Order
diff --git a/src/views/App.jsx b/src/views/App.jsx
index a0290cc..edb6a46 100644
--- a/src/views/App.jsx
+++ b/src/views/App.jsx
@@ -2,6 +2,10 @@ import { Outlet, Link, useHref, NavLink } from 'react-router-dom'
import { useRef, useEffect, useState } from 'react'
import { Layout, Menu, ConfigProvider, theme, Empty, Row, Col, Dropdown, Space, Typography, Result, App as AntApp } from 'antd'
import { DownOutlined } from "@ant-design/icons";
+import zhLocale from 'antd/locale/zh_CN';
+import dayjs from 'dayjs';
+import 'dayjs/locale/zh-cn';
+
import '@/assets/App.css'
import AppLogo from '@/assets/logo-gh.png'
import { useStore } from '@/stores/StoreContext.js'
@@ -45,7 +49,7 @@ function App() {
function renderLayout() {
return (
-
+
@@ -121,6 +125,7 @@ function App() {
},
algorithm: theme.defaultAlgorithm,
}}
+ locale={zhLocale}
renderEmpty={globalEmpty}
>
diff --git a/src/views/ChatHistory.jsx b/src/views/ChatHistory.jsx
index 6bb498a..c38fff9 100644
--- a/src/views/ChatHistory.jsx
+++ b/src/views/ChatHistory.jsx
@@ -2,7 +2,7 @@ import { useNavigate } from 'react-router-dom'
import { useRef, useEffect, useState } from 'react'
import { observer } from 'mobx-react'
import { Row, Col, Divider, Table , Card, Button, Input,
- Space, Empty, Radio, Select, DatePicker, Spin, List, Avatar
+ Space, Empty, Radio, AutoComplete, DatePicker, Spin, List, Avatar
} from 'antd'
import {
StarFilled, ZoomInOutlined, StarOutlined, SearchOutlined
@@ -39,15 +39,30 @@ function ChatHistory() {
+
+
+ {
+ setKeyword(value)
+ }}
+ filterOption={(inputValue, option) =>
+ option.value.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1
+ }
+ />
+
+
+
+
+
-
- {}}
- />
+
+ } onClick={() => {
+ search()
+ }}>搜索
diff --git a/src/views/DingdingCallbak.jsx b/src/views/DingdingCallbak.jsx
index 35b3b41..9a82575 100644
--- a/src/views/DingdingCallbak.jsx
+++ b/src/views/DingdingCallbak.jsx
@@ -1,6 +1,7 @@
import React, { useEffect } from 'react'
import { useParams, useNavigate } from "react-router-dom"
-import { Card, Typography, Flex, Button } from 'antd'
+import { Card, Typography, Flex, Result, Button } from 'antd'
+import { useRequest } from 'ahooks'
const { Title } = Typography
const { Meta } = Card
@@ -13,13 +14,28 @@ function DingdingCallbak() {
console.info('code: ' + code)
console.info('state: ' + state)
+ const { data, error, loading } = useRequest(() => {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ resolve('use Request data...');
+ }, 1000);
+ });
+ });
useEffect(() => {
}, [])
return (
- 钉钉 Callbak
+ {error}
+ {loading}
+ {data}
+ 正在获取你的权限,请稍等
+
)
}
diff --git a/src/views/DingdingQRCode.jsx b/src/views/DingdingQRCode.jsx
index c3cebcb..34584e3 100644
--- a/src/views/DingdingQRCode.jsx
+++ b/src/views/DingdingQRCode.jsx
@@ -1,5 +1,5 @@
+import { Card, Flex, Typography } from 'antd'
import React, { useEffect } from 'react'
-import { Card, Typography, Flex, Button } from 'antd'
const { Title } = Typography
const { Meta } = Card
@@ -12,7 +12,7 @@ function DingdingQRCode() {
import('https://g.alicdn.com/dingding/h5-dingtalk-login/0.21.0/ddlogin.js').then((module) => {
window.DTFrameLogin(
{
- id: 'dingdingContainer',
+ id: 'qrCodeContainer',
width: 300,
height: 300,
},
@@ -25,26 +25,26 @@ function DingdingQRCode() {
prompt: 'consent',
},
(loginResult) => {
- const { redirectUrl, authCode, state } = loginResult;
+ const { redirectUrl, authCode, state } = loginResult
// 这里可以直接进行重定向
- window.location.href = redirectUrl;
+ window.location.href = redirectUrl
// 也可以在不跳转页面的情况下,使用code进行授权
- console.log(authCode);
+ console.log(authCode)
},
(errorMsg) => {
// 这里一般需要展示登录失败的具体原因
- alert(`Login Error: ${errorMsg}`);
+ alert(`Login Error: ${errorMsg}`)
},
)
})
}, [])
return (
-
+
使用钉钉扫码
-
+
)
}
-export default DingdingQRCode;
\ No newline at end of file
+export default DingdingQRCode
\ No newline at end of file
diff --git a/src/views/ErrorPage.jsx b/src/views/ErrorPage.jsx
index a0ffe04..76c9dfb 100644
--- a/src/views/ErrorPage.jsx
+++ b/src/views/ErrorPage.jsx
@@ -1,16 +1,15 @@
import { useRouteError } from "react-router-dom";
+import { Card, Typography, Flex, Result, Button } from 'antd'
export default function ErrorPage() {
const errorResponse = useRouteError();
console.error(errorResponse);
return (
-
-
Oops!
-
Sorry, an unexpected error has occurred.
-
- {errorResponse.error.message}
-
-
+
);
}
\ No newline at end of file
diff --git a/src/views/OrderFollow.jsx b/src/views/OrderFollow.jsx
index 3c61118..b748f79 100644
--- a/src/views/OrderFollow.jsx
+++ b/src/views/OrderFollow.jsx
@@ -2,10 +2,10 @@ import { useNavigate } from 'react-router-dom'
import { useRef, useEffect, useState } from 'react'
import { observer } from 'mobx-react'
import { Row, Col, Divider, Table , Card, Button, Input,
- Space, Empty, Radio, Select, AutoComplete, Spin, Typography, Flex
+ Space, Segmented, Radio, Select, AutoComplete, Spin, Typography, Flex
} from 'antd'
import {
- StarFilled, ZoomInOutlined, StarOutlined, SearchOutlined
+ StarFilled, ZoomInOutlined, StarOutlined, BarsOutlined , AppstoreOutlined
} from '@ant-design/icons'
const dataSource = [
@@ -41,7 +41,7 @@ const dataSource = [
orderNumber: 'LU231218115(3)',
fullname: 'Giacomo Guilizzoni(R1)',
orderStatus: '新订单',
- trip: 'Itinerary2: Tkyoto tour',
+ trip: 'Itinerary2: Tkyoto tour 超级无敌长的报价标题',
lastMessage: '2024-03-25 16:02',
comment: '吃素、蜜月',
},
@@ -79,6 +79,30 @@ const columns = [
title: '订单号',
dataIndex: 'orderNumber',
key: 'orderNumber',
+ width: 300,
+ render: (text, record, inde) => {
+ return (
+
+ {text}
+
+
+ )
+ }
},
{
title: '客人姓名',
@@ -89,11 +113,49 @@ const columns = [
title: '订单状态',
dataIndex: 'orderStatus',
key: 'orderStatus',
+ render: (text, record, inde) => {
+ return (
+
+ )
+ }
},
{
title: '报价title',
dataIndex: 'trip',
key: 'trip',
+ ellipsis: true,
},
{
title: '客人最后一次回复时间',
diff --git a/src/views/SalesManagement.jsx b/src/views/SalesManagement.jsx
index d779f74..b85271e 100644
--- a/src/views/SalesManagement.jsx
+++ b/src/views/SalesManagement.jsx
@@ -5,7 +5,7 @@ import { Row, Col, Divider, Table , Card, Button, Input,
Space, Empty, Radio, Select, DatePicker, Spin, List, Avatar
} from 'antd'
import {
- StarFilled, ZoomInOutlined, StarOutlined, SearchOutlined
+ StarFilled, ZoomInOutlined, StarOutlined, SearchOutlined, ImportOutlined
} from '@ant-design/icons'
const { Search } = Input;
@@ -117,6 +117,9 @@ function SalesManagement() {
onSearch={()=>{}}
/>
+
+ }>导入联系人
+