mirror of
https://gitee.com/ShopeX/ECShopX_Store-Operations-tools-frontend
synced 2026-08-04 12:06:24 +08:00
merge
This commit is contained in:
@@ -8,6 +8,7 @@ import qs from 'qs'
|
||||
import S from '@/spx'
|
||||
import { isAlipay, isWeixin, isFromWebapp } from '@/utils'
|
||||
import log from '@/utils/log'
|
||||
import { syncCompanyIdFromUrl } from '@/utils/companySync'
|
||||
import { HTTP_STATUS } from './consts'
|
||||
|
||||
const isWeb = true
|
||||
@@ -142,6 +143,9 @@ class API {
|
||||
}
|
||||
|
||||
intereptorReq(params) {
|
||||
// 保证首屏 API(如企微 jssdk config)能带上路由中的 company_id
|
||||
syncCompanyIdFromUrl()
|
||||
|
||||
const { url, data, header = {}, method = 'GET' } = params
|
||||
const { company_id, appid } = this.options
|
||||
const methodIsGet = method.toLowerCase() === 'get'
|
||||
@@ -174,9 +178,8 @@ class API {
|
||||
}
|
||||
|
||||
if (isFromWebapp()) {
|
||||
// if (!query.company_id) {
|
||||
query.company_id = S.get('WEBAPP', true).company_id
|
||||
//}
|
||||
const web = S.get('WEBAPP', true) || {}
|
||||
query.company_id = web.company_id || web.companyId || Taro.getStorageSync('company_id')
|
||||
} else {
|
||||
query.company_id = Taro.getStorageSync('company_id')
|
||||
}
|
||||
@@ -201,12 +204,28 @@ class API {
|
||||
}
|
||||
|
||||
intereptorRes(res) {
|
||||
const { data, statusCode, config } = res
|
||||
const { showError = true } = config
|
||||
if (!res || typeof res !== 'object') {
|
||||
return Promise.reject(this.reqError(res, '请求响应异常'))
|
||||
}
|
||||
const { data, statusCode, config = {} } = res
|
||||
const { showError = true } = config || {}
|
||||
if (statusCode == HTTP_STATUS.SUCCESS) {
|
||||
const { status_code } = data.data
|
||||
if (!data || typeof data !== 'object') {
|
||||
if (showError) {
|
||||
this.errorToast({ message: '服务返回数据为空' })
|
||||
}
|
||||
return Promise.reject(this.reqError(res, '服务返回数据为空'))
|
||||
}
|
||||
const inner = data.data
|
||||
if (inner === undefined || inner === null || typeof inner !== 'object') {
|
||||
if (showError) {
|
||||
this.errorToast({ message: '服务返回数据格式异常' })
|
||||
}
|
||||
return Promise.reject(this.reqError(res, '服务返回数据格式异常'))
|
||||
}
|
||||
const { status_code } = inner
|
||||
if (!status_code) {
|
||||
return data.data
|
||||
return inner
|
||||
} else {
|
||||
// status_code 不为0,表示有错误
|
||||
if (showError) {
|
||||
@@ -217,7 +236,7 @@ class API {
|
||||
}
|
||||
|
||||
if (statusCode === HTTP_STATUS.UNAUTHORIZED) {
|
||||
if ((data.data && data.data.status_code) === HTTP_STATUS.USER_FORBIDDEN) {
|
||||
if (data?.data?.status_code === HTTP_STATUS.USER_FORBIDDEN) {
|
||||
if (showError) {
|
||||
this.errorToast(data)
|
||||
}
|
||||
@@ -297,7 +316,7 @@ class API {
|
||||
res.config = options
|
||||
if (
|
||||
res.statusCode === HTTP_STATUS.UNAUTHORIZED &&
|
||||
(res.data.data && res.data.data.code) === HTTP_STATUS.TOKEN_NEEDS_REFRESH &&
|
||||
res?.data?.data?.code === HTTP_STATUS.TOKEN_NEEDS_REFRESH &&
|
||||
S.getAuthToken()
|
||||
) {
|
||||
// token失效时重造请求,并刷新token
|
||||
@@ -353,7 +372,8 @@ class API {
|
||||
// console.log('reqError.res', res)
|
||||
// console.log('reqError.msg', msg)
|
||||
// if (res && res.statusCode) Taro.navigateTo('pages/auth/login')
|
||||
const errMsg = (res.data && res.data.message) || msg
|
||||
const errMsg =
|
||||
(res && res.data && (res.data.message || res.data.data?.message)) || msg || '请求失败'
|
||||
const err = new Error(errMsg)
|
||||
err.res = res
|
||||
return err
|
||||
|
||||
@@ -9,6 +9,7 @@ import { Provider } from 'react-redux'
|
||||
import { SAPP, SAPPPay, SAPPShare } from './muiApp'
|
||||
import configStore from './store'
|
||||
import { cleanWeapp, isFromWebapp, isIos } from '@/utils'
|
||||
import { syncCompanyIdFromUrl } from '@/utils/companySync'
|
||||
import '@/muiApp/index.scss'
|
||||
import 'default-passive-events'
|
||||
import S from '@/spx'
|
||||
@@ -71,6 +72,8 @@ class App extends Component {
|
||||
}
|
||||
|
||||
componentDidShow(options) {
|
||||
syncCompanyIdFromUrl()
|
||||
|
||||
const { company_id } = options
|
||||
const { userAgent } = window.navigator
|
||||
console.log('userAgent', userAgent)
|
||||
|
||||
@@ -80,13 +80,19 @@ class PageActionButtons extends PureComponent {
|
||||
return buttons.map((button, index) => {
|
||||
const buttonType = button.type
|
||||
const buttonName = button.name
|
||||
// 改价入口(markdown):在图标/文案前统一展示「改价」
|
||||
let displayText = buttonName
|
||||
if (buttonType === 'markdown') {
|
||||
const raw = (buttonName || '').trim()
|
||||
displayText = raw.includes('改价') ? raw : `改价${raw}`
|
||||
}
|
||||
|
||||
return (
|
||||
<CommonButton
|
||||
key={buttonName}
|
||||
key={`${buttonType}-${index}-${buttonName || 'btn'}`}
|
||||
className={classNames('common-button', buttonClassName)}
|
||||
plain
|
||||
text={buttonName}
|
||||
text={displayText}
|
||||
onClick={this.handleFooterButtonClick.bind(this, buttonType)}
|
||||
size='small'
|
||||
// height={this.buttonHeight()}
|
||||
|
||||
@@ -16,12 +16,14 @@ import {
|
||||
cleanWeapp,
|
||||
VERSION_PLATFORM,
|
||||
VERSION_STANDARD,
|
||||
isIos
|
||||
isIos,
|
||||
normalizeWebappRecord
|
||||
} from '@/utils'
|
||||
import { SpToast, SpModal } from '@/components'
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
import S from '@/spx'
|
||||
import { syncCompanyIdFromUrl } from '@/utils/companySync'
|
||||
import './index.scss'
|
||||
|
||||
@connect(({ planSelection }) => ({
|
||||
@@ -61,47 +63,53 @@ class Index extends Component {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// const { href } = window.location
|
||||
// if (S.getAuthToken()) {
|
||||
// qwsdk.register({
|
||||
// url: href
|
||||
// })
|
||||
// }
|
||||
const { href } = window.location
|
||||
if (S.getAuthToken()) {
|
||||
qwsdk.register({
|
||||
url: href
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async componentDidShow() {
|
||||
syncCompanyIdFromUrl()
|
||||
setWeapp()
|
||||
if (isFromWebapp()) {
|
||||
const { app_id, app_type, company_id, openid, unionid, token } = S.get('WEBAPP', true)
|
||||
// let data
|
||||
const { app_id, app_type, company_id, openid, unionid, token } = normalizeWebappRecord(
|
||||
S.get('WEBAPP', true)
|
||||
)
|
||||
let data
|
||||
if (token) {
|
||||
S.setAuthToken(token)
|
||||
// const { href, origin, search } = window.location
|
||||
// const sdkAuthUrlIos = Taro.getStorageSync('sdk_auth_url_ios')
|
||||
// console.log('sdkAuthUrlIos:', sdkAuthUrlIos)
|
||||
// qwsdk.register({
|
||||
// url: isIos() ? `${sdkAuthUrlIos}` : href
|
||||
// })
|
||||
if (company_id != null && company_id !== '') {
|
||||
Taro.setStorageSync('company_id', String(company_id))
|
||||
}
|
||||
const { href, origin, search } = window.location
|
||||
const sdkAuthUrlIos = Taro.getStorageSync('sdk_auth_url_ios')
|
||||
console.log('sdkAuthUrlIos:', sdkAuthUrlIos)
|
||||
qwsdk.register({
|
||||
url: isIos() ? `${sdkAuthUrlIos}` : href
|
||||
})
|
||||
}
|
||||
if (!S.getAuthToken()) {
|
||||
data = await api.weapp.is_bind({
|
||||
app_id,
|
||||
app_type,
|
||||
company_id,
|
||||
openid,
|
||||
unionid
|
||||
})
|
||||
// if (company_id) {
|
||||
// Taro.setStorageSync('company_id', company_id)
|
||||
// }
|
||||
if (data.token) {
|
||||
S.setAuthToken(data.token)
|
||||
const { href } = window.location
|
||||
qwsdk.register({
|
||||
url: href
|
||||
})
|
||||
}
|
||||
}
|
||||
// if (!S.getAuthToken()) {
|
||||
// data = await api.weapp.is_bind({
|
||||
// app_id,
|
||||
// app_type,
|
||||
// company_id,
|
||||
// openid,
|
||||
// unionid
|
||||
// })
|
||||
// // if (company_id) {
|
||||
// // Taro.setStorageSync('company_id', company_id)
|
||||
// // }
|
||||
// if (data.token) {
|
||||
// S.setAuthToken(data.token)
|
||||
// const { href } = window.location
|
||||
// qwsdk.register({
|
||||
// url: href
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
} else {
|
||||
const { href } = window.location
|
||||
const { company_id } = getCurrentInstance().router.params || {}
|
||||
@@ -109,11 +117,13 @@ class Index extends Component {
|
||||
if (company_id) {
|
||||
Taro.setStorageSync('company_id', company_id)
|
||||
}
|
||||
console.log('page_index:componentDidMount:qwsdk.register1', href)
|
||||
if (S.getAuthToken()) {
|
||||
qwsdk.register({ url: href })
|
||||
}
|
||||
}
|
||||
|
||||
this.getConfig()
|
||||
this.salesman()
|
||||
// this.salesman()
|
||||
}
|
||||
|
||||
async salesman() {
|
||||
@@ -136,11 +146,17 @@ class Index extends Component {
|
||||
async getConfig() {
|
||||
let { distributor_id } = this.props.planSelection
|
||||
if (distributor_id != null) {
|
||||
const result = await api.home.getStatistics({ shop_id: distributor_id, is_app: 1 })
|
||||
this.setState({
|
||||
realTimeData: result.today_data,
|
||||
apis: result.apis
|
||||
})
|
||||
try {
|
||||
const result = await api.home.getStatistics({ shop_id: distributor_id, is_app: 1 })
|
||||
this.setState({
|
||||
realTimeData: result?.today_data ?? this.state.realTimeData,
|
||||
apis: result?.apis ?? {},
|
||||
loading: false
|
||||
})
|
||||
} catch (e) {
|
||||
console.log('getConfig', e)
|
||||
this.setState({ loading: false })
|
||||
}
|
||||
} else {
|
||||
Taro.redirectTo({ url: `/pages/planSelection/index` })
|
||||
}
|
||||
@@ -344,14 +360,14 @@ class Index extends Component {
|
||||
<View className='title'>常用功能</View>
|
||||
<View className='list'>
|
||||
{/* {apis.items == 1 && VERSION_PLATFORM && ( */}
|
||||
{apis.items == 1 && VERSION_STANDARD && (
|
||||
{/* {apis.items == 1 && VERSION_STANDARD && (
|
||||
<View className='item' onClick={() => navigateTo('/pages/good/list')}>
|
||||
<View>
|
||||
<Image className='img' src={require('@/assets/imgs/index/good.png')}></Image>
|
||||
</View>
|
||||
<View className='subtitle'>商品管理</View>
|
||||
</View>
|
||||
)}
|
||||
)} */}
|
||||
{apis.order == 1 && (
|
||||
<View className='item' onClick={this.goOrderPageHandle}>
|
||||
<View>
|
||||
@@ -405,21 +421,21 @@ class Index extends Component {
|
||||
<View className='subtitle'>商品查询</View>
|
||||
</View>
|
||||
)} */}
|
||||
{VERSION_STANDARD && (
|
||||
<View
|
||||
className='item'
|
||||
onClick={() => {
|
||||
wx.miniProgram.navigateTo({
|
||||
url: `/subpages/dianwu/cashier?token=${S.getAuthToken()}&distributor_id=${distributor_id}`
|
||||
})
|
||||
}}
|
||||
>
|
||||
<View className='img_'>
|
||||
<Image className='img' src={require('@/assets/imgs/icon_cashier.png')}></Image>
|
||||
</View>
|
||||
<View className='subtitle'>收银台</View>
|
||||
{/* {VERSION_STANDARD && ( */}
|
||||
<View
|
||||
className='item'
|
||||
onClick={() => {
|
||||
wx.miniProgram.navigateTo({
|
||||
url: `/subpages/dianwu/cashier?token=${S.getAuthToken()}&distributor_id=${distributor_id}`
|
||||
})
|
||||
}}
|
||||
>
|
||||
<View className='img_'>
|
||||
<Image className='img' src={require('@/assets/imgs/icon_cashier.png')}></Image>
|
||||
</View>
|
||||
)}
|
||||
<View className='subtitle'>收银台</View>
|
||||
</View>
|
||||
{/* )} */}
|
||||
{/* {VERSION_STANDARD && (
|
||||
<View
|
||||
className='item'
|
||||
|
||||
88
src/utils/companySync.js
Normal file
88
src/utils/companySync.js
Normal file
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* H5 首次进入时,路由参数里的 company_id 可能尚未写入 storage,
|
||||
* 而 componentDidMount 里的 qwsdk.register 会早于 componentDidShow,导致 config 等接口缺少 companyId。
|
||||
*
|
||||
* 同步来源(按序尝试):
|
||||
* 1. window.location 的 search / hash 内查询串(history / hash 路由)
|
||||
* 2. Taro getCurrentInstance().router.params(browser 模式下参数常在路由里)
|
||||
* 3. URL 中 token(JWT)payload 内的 company_id(query 被改写时兜底)
|
||||
*/
|
||||
import Taro, { getCurrentInstance } from '@tarojs/taro'
|
||||
|
||||
export function getCompanyIdFromUrl() {
|
||||
if (typeof window === 'undefined') return ''
|
||||
try {
|
||||
const { search, hash } = window.location
|
||||
const fromSearch = new URLSearchParams(search || '')
|
||||
let id = fromSearch.get('company_id') || fromSearch.get('companyId') || ''
|
||||
|
||||
// hash 形如 #/pages/index?company_id=xx 或 #/?company_id=xx
|
||||
if (!id && hash) {
|
||||
const qInHash = hash.indexOf('?')
|
||||
if (qInHash >= 0) {
|
||||
const hp = new URLSearchParams(hash.slice(qInHash + 1))
|
||||
id = hp.get('company_id') || hp.get('companyId') || ''
|
||||
}
|
||||
}
|
||||
|
||||
return id || ''
|
||||
} catch (e) {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
/** 从当前页路由取 company_id(Taro H5 browser 模式常用) */
|
||||
export function getCompanyIdFromRouter() {
|
||||
try {
|
||||
const router = getCurrentInstance()?.router
|
||||
const p = router?.params || {}
|
||||
const id = p.company_id || p.companyId
|
||||
return id != null && id !== '' ? String(id) : ''
|
||||
} catch (e) {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
/** 解析 JWT payload(仅解码,不校验签名),读 company_id */
|
||||
function decodeJwtPayload(token) {
|
||||
if (!token || typeof token !== 'string') return null
|
||||
const parts = token.split('.')
|
||||
if (parts.length < 2) return null
|
||||
try {
|
||||
const b64 = parts[1].replace(/-/g, '+').replace(/_/g, '/')
|
||||
const pad = b64.length % 4
|
||||
const padded = pad ? b64 + '='.repeat(4 - pad) : b64
|
||||
return JSON.parse(atob(padded))
|
||||
} catch (e) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/** 入口 URL 形如 ?token=eyJ...&company_id=38 时,有时 company_id 未进路由参数,可从 JWT claims 取 */
|
||||
export function getCompanyIdFromJwtInSearch() {
|
||||
if (typeof window === 'undefined') return ''
|
||||
try {
|
||||
const token = new URLSearchParams(window.location.search || '').get('token')
|
||||
if (!token) return ''
|
||||
const payload = decodeJwtPayload(token.trim())
|
||||
if (!payload) return ''
|
||||
const id = payload.company_id ?? payload.companyId
|
||||
return id != null && id !== '' ? String(id) : ''
|
||||
} catch (e) {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
export function syncCompanyIdFromUrl() {
|
||||
let id = getCompanyIdFromUrl()
|
||||
if (!id) {
|
||||
id = getCompanyIdFromRouter()
|
||||
}
|
||||
if (!id) {
|
||||
id = getCompanyIdFromJwtInSearch()
|
||||
}
|
||||
if (id) {
|
||||
Taro.setStorageSync('company_id', id)
|
||||
}
|
||||
return id
|
||||
}
|
||||
@@ -84,6 +84,11 @@ export function getCurrentRoute() {
|
||||
export function setWeapp() {
|
||||
const { params: webappParams } = getCurrentInstance().router || { params: {} }
|
||||
console.log('===setWeapp', webappParams)
|
||||
// 微商城入口 URL 常带 company_id,与 in_shop_wechat 无关也要落盘(接口依赖 Taro storage 的 company_id)
|
||||
const wid = webappParams.company_id || webappParams.companyId
|
||||
if (wid != null && wid !== '') {
|
||||
Taro.setStorageSync('company_id', String(wid))
|
||||
}
|
||||
if (webappParams && webappParams.in_shop_wechat) {
|
||||
S.set('WEBAPP', webappParams, true)
|
||||
}
|
||||
@@ -93,10 +98,23 @@ export function cleanWeapp() {
|
||||
S.delete('WEBAPP', true)
|
||||
S.logout()
|
||||
}
|
||||
/** 判断是否从webapp跳转而来 */
|
||||
export function normalizeWebappRecord(raw) {
|
||||
if (raw == null) return {}
|
||||
if (typeof raw === 'string') {
|
||||
try {
|
||||
return JSON.parse(raw)
|
||||
} catch (e) {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
return raw
|
||||
}
|
||||
|
||||
/** 判断是否从webapp跳转而来(兼容字符串 true 与布尔 true) */
|
||||
export function isFromWebapp() {
|
||||
const webappParams = S.get('WEBAPP', true)
|
||||
return webappParams.in_shop_wechat === 'true'
|
||||
const webappParams = normalizeWebappRecord(S.get('WEBAPP', true))
|
||||
const v = webappParams.in_shop_wechat
|
||||
return v === true || v === 'true' || v === 1 || v === '1'
|
||||
}
|
||||
|
||||
export function getThemeStyle() {
|
||||
|
||||
Reference in New Issue
Block a user