Files
QSY-lvjuxcx/api/index.js
liangjian 445bd850f4 feat: 新增工单中心、房间巡查、失物招领等业务模块
- 新增工单中心(ticket_center)与工单工作台(ticket_workbench)页面
- 新增房间巡查(room_inspection)与失物招领发布(lost_found_publish)页面
- 预约看样流程新增房型/楼栋/楼层选择器组件
- 新增工具模块: booking-entry、privacy、reservation-flow
- api/index.js 补充楼层列表、看样提交等接口
- locales/messages.js 补充多语言文案
- manifest.json 开启微信小程序隐私检查
- 完善登录、注册、申请详情、账单等相关页面交互
2026-07-24 09:35:46 +08:00

974 lines
23 KiB
JavaScript

import { API_BASE_URL, request } from '../utils/request'
import { getCurrentLanguage, getLocaleShort } from '@/utils/i18n'
function resolveLanguageHeader(language) {
return getLocaleShort(language || getCurrentLanguage())
}
function resolveIotApiBaseUrl() {
const normalizedBaseUrl = String(API_BASE_URL || '').trim()
if (!normalizedBaseUrl) {
return ''
}
if (normalizedBaseUrl.includes('/admin/')) {
return normalizedBaseUrl.replace('/admin/', '/iot/')
}
if (/\/admin$/i.test(normalizedBaseUrl)) {
return normalizedBaseUrl.replace(/\/admin$/i, '/iot')
}
return normalizedBaseUrl.replace(/\/$/, '') + '/iot'
}
function buildIotGatewayUrl(path = '') {
const iotBaseUrl = resolveIotApiBaseUrl()
const normalizedPath = String(path || '').startsWith('/')
? String(path || '')
: `/${String(path || '')}`
return `${iotBaseUrl}${normalizedPath}`
}
function normalizeUploadResponse(data) {
if (typeof data !== 'string') {
return Promise.resolve(data)
}
const trimmed = data.trim()
const looksLikeJson = (
(trimmed.startsWith('{') && trimmed.endsWith('}'))
|| (trimmed.startsWith('[') && trimmed.endsWith(']'))
)
if (!looksLikeJson) {
return Promise.resolve(data)
}
return Promise.resolve(trimmed)
.then(JSON.parse)
.catch(() => data)
}
function normalizeRequestCacheValue(value) {
if (Array.isArray(value)) {
return value.map(item => normalizeRequestCacheValue(item))
}
if (value && typeof value === 'object') {
return Object.keys(value).sort().reduce((result, key) => {
result[key] = normalizeRequestCacheValue(value[key])
return result
}, {})
}
return value
}
function buildRequestCacheKey(prefix, params = {}, language) {
return `${prefix}:${language}:${JSON.stringify(normalizeRequestCacheValue(params || {}))}`
}
function createJsonPatchRequest(url, data = {}, language) {
return request({
url,
method: 'POST',
data,
header: {
'Content-Type': 'application/json-patch+json',
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
const notificationPageRequestCache = new Map()
const notificationPageResponseCache = new Map()
const NOTIFICATION_PAGE_CACHE_TTL = 1200
function getNotificationPageCachedResponse(requestKey) {
const cachedEntry = notificationPageResponseCache.get(requestKey)
if (!cachedEntry) {
return null
}
if (cachedEntry.expiresAt <= Date.now()) {
notificationPageResponseCache.delete(requestKey)
return null
}
return cachedEntry.response
}
function clearNotificationPageCache() {
notificationPageRequestCache.clear()
notificationPageResponseCache.clear()
}
// --- 字典与枚举 ---
export function sysdictPage(params = {}, language) {
return request({
url: '/sysdict/page',
method: 'GET',
params,
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function getCountryList(language) {
return request({
url: '/sysdict/countries',
method: 'GET',
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function getEnums(params = {}, language) {
return request({
url: '/enums',
method: 'GET',
params,
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function getFloorList(params = {}, language) {
return request({
url: '/floor/list',
method: 'GET',
params,
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
// --- 用户与登录 ---
export function usersLogin(data = {}, language) {
return request({
url: '/user/login',
method: 'POST',
data,
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function userMe(params = {}, language) {
return request({
url: '/user/me',
method: 'GET',
params,
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
// --- 注册与申请 ---
export function submitRegistrationApplication(data = {}, language) {
return request({
url: '/applicationform/registration/submit',
method: 'POST',
data,
header: {
'Content-Type': 'application/json-patch+json',
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function submitApplicationForm(data = {}, language) {
return request({
url: '/applicationform/submit',
method: 'POST',
data,
header: {
'Content-Type': 'application/json-patch+json',
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function submitViewingApplicationForm(data = {}, language) {
return request({
url: '/applicationform/viewing/submit',
method: 'POST',
data,
header: {
'Content-Type': 'application/json-patch+json',
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function registrationApplicationMePage(params = {}, language) {
return request({
url: '/applicationform/registration/me/page',
method: 'GET',
params,
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function registrationMyorder(params = {}, language) {
return request({
url: '/applicationform/registration/myorder',
method: 'GET',
params,
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function applicationFormMePage(params = {}, language) {
return request({
url: '/applicationform/me/page',
method: 'GET',
params,
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
// --- 工单 ---
export function ticketOrderPage(params = {}, language) {
return request({
url: '/ticketorder/page',
method: 'GET',
params,
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function ticketOrderMyPage(params = {}, language) {
return request({
url: '/ticketorder/my/page',
method: 'GET',
params,
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function ticketOrderDetail(flowNo, language) {
return request({
url: `/ticketorder/${flowNo}/flows`,
method: 'GET',
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function ticketOrderFlows(orderNo, language) {
return request({
url: `/ticketorder/${orderNo}/flows`,
method: 'GET',
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function ticketOrderTransitionOptions(flowNo, language) {
return request({
url: `/ticketorder/${flowNo}/transition-options`,
method: 'GET',
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function ticketFlowTransitionStepRuleSelectTypeItems(params = {}, language) {
return request({
url: '/ticketflowtransitionsteprule/selecttypeitems',
method: 'GET',
params,
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function ticketOrderFixonhold(data = {}, language) {
return createJsonPatchRequest('/ticketorder/fixonhold', data, language)
}
export function ticketOrderTransit(data = {}, language) {
return createJsonPatchRequest('/ticketorder/transit', data, language)
}
export function ticketOrderSubmitChangeroom(data = {}, language) {
return createJsonPatchRequest('/ticketordersubmit/changeroom', data, language)
}
export function ticketOrderSubmitCheckout(data = {}, language) {
return createJsonPatchRequest('/ticketordersubmit/checkout', data, language)
}
export function ticketOrderSubmitRepair(data = {}, language) {
return createJsonPatchRequest('/ticketordersubmit/repair', data, language)
}
export function ticketOrderSubmitSuggestion(data = {}, language) {
return createJsonPatchRequest('/ticketordersubmit/suggestion', data, language)
}
export function ticketOrderSubmitRenewal(data = {}, language) {
return createJsonPatchRequest('/ticketordersubmit/renewal', data, language)
}
export function ticketOrderSubmitWaterdelivery(data = {}, language) {
return createJsonPatchRequest('/ticketordersubmit/waterdelivery', data, language)
}
export function ticketOrderSubmitCleaning(data = {}, language) {
return createJsonPatchRequest('/ticketordersubmit/cleaning', data, language)
}
export function lostAndFoundPublish(data = {}, language) {
return createJsonPatchRequest('/lostandfound/publish', data, language)
}
// --- 订单与入住 ---
export function orderSearchedHistoryPage(params = {}, language) {
return request({
url: '/order/searched/history/page',
method: 'GET',
params: params || {},
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function orderSearchedMePage(params = {}, language) {
return request({
url: '/order/searched/me/page',
method: 'GET',
params: params || {},
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function orderSearchedMyPage(params = {}, language) {
return request({
url: '/order/searched/me/page',
method: 'GET',
params: params || {},
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function orderSearchedMeHistoryPage(params = {}, language) {
return request({
url: '/order/searched/me/history/page',
method: 'GET',
params: params || {},
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function orderSearchedDetail(orderNo = '', language) {
return request({
url: `/order/searched/detail/${encodeURIComponent(orderNo || '')}`,
method: 'GET',
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function orderSearchedCheckInPage(params = {}, language) {
return request({
url: '/order/searched/checkin/page',
method: 'GET',
params: params || {},
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function orderSearchedReservationPage(params = {}, language) {
return request({
url: '/order/searched/reservation/page',
method: 'GET',
params: params || {},
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function orderSearchedReservationFlow(data = {}, language) {
return request({
url: '/order/searched/reservation/flow',
method: 'POST',
data,
header: {
'Content-Type': 'application/json-patch+json',
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function roomInspectionMyPage(params = {}, language) {
return request({
url: '/roominspection/my/page',
method: 'GET',
params: params || {},
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function roomInspectionDetail(params = {}, language) {
return request({
url: '/roominspection/detail',
method: 'GET',
params: params || {},
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function roomInspectionUpdateItems(data = {}, language) {
return request({
url: '/roominspection/update/items',
method: 'POST',
data,
header: {
'Content-Type': 'application/json-patch+json',
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function roomInspectionSubmit(data = {}, language) {
return request({
url: '/roominspection/submit',
method: 'POST',
data,
header: {
'Content-Type': 'application/json-patch+json',
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function checkRecordByChecked(params = {}, language) {
const query = params || {}
const orderNo = String(query.orderNo || '').trim()
if (!orderNo) {
return Promise.resolve([])
}
return request({
url: '/checkrecord/by-checked',
method: 'GET',
params: {
...query,
orderNo
},
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function accountQueryBills(params = {}, language) {
const query = params || {}
return request({
url: '/accountquery/bills',
method: 'GET',
params: query,
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function accountQueryBill(params = {}, language) {
const query = params || {}
const billNo = String(query.billNo || query.BillNo || '').trim()
if (!billNo) {
return Promise.reject(new Error('账单号不能为空'))
}
return request({
url: '/accountquery/bill',
method: 'GET',
params: {
billNo
},
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function paymentBillPay(data = {}, language) {
const payload = data || {}
return request({
url: '/payment/bill-pay',
method: 'POST',
data: payload,
header: {
'Content-Type': 'application/json-patch+json',
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function paymentPayingBills(params = {}, language) {
const query = params || {}
const BillNo = String(query.BillNo || query.billNo || '').trim()
if (!BillNo) {
return Promise.reject(new Error('账单号不能为空'))
}
return request({
url: '/payment/paying-bills',
method: 'GET',
params: {
BillNo
},
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function paymentStatusByBillNo(params = {}, language) {
const query = params || {}
const BillNo = String(query.BillNo || query.billNo || '').trim()
if (!BillNo) {
return Promise.reject(new Error('账单号不能为空'))
}
return request({
url: '/payment/status-by-billno',
method: 'GET',
params: {
BillNo
},
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function userDetailCancel(data = {}, language) {
const payload = data || {}
return request({
url: '/ApplicationForm/user/detail/cancel',
method: 'POST',
data: payload,
header: {
'Content-Type': 'application/json-patch+json',
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
// --- 合同 ---
export function getMyPendingSignContracts(params = {}, language) {
return request({
url: '/contract/my/pending-sign',
method: 'GET',
params,
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function getMyEffectiveContracts(params = {}, language) {
return request({
url: '/contract/my/effective',
method: 'GET',
params,
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function contractDetail(params = {}, language) {
return request({
url: '/contract/detail',
method: 'GET',
params,
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function contractPreview(data = {}, language) {
return request({
url: '/contract/preview',
method: 'POST',
data,
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function contractSign(data = {}, language) {
return request({
url: '/contract/sign',
method: 'POST',
data,
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
// --- 消息通知 ---
export function notificationPage(params = {}, language) {
const query = params || {}
const requestKey = buildRequestCacheKey('notificationPage', query, language)
if (notificationPageRequestCache.has(requestKey)) {
return notificationPageRequestCache.get(requestKey)
}
const cachedResponse = getNotificationPageCachedResponse(requestKey)
if (cachedResponse) {
return Promise.resolve(cachedResponse)
}
const requestPromise = request({
url: '/notification/page',
method: 'GET',
params: query,
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
const managedRequestPromise = requestPromise.then((response) => {
notificationPageResponseCache.set(requestKey, {
response,
expiresAt: Date.now() + NOTIFICATION_PAGE_CACHE_TTL
})
return response
})
notificationPageRequestCache.set(requestKey, managedRequestPromise)
return managedRequestPromise.finally(() => {
if (notificationPageRequestCache.get(requestKey) === managedRequestPromise) {
notificationPageRequestCache.delete(requestKey)
}
})
}
export function notificationRead(code, language) {
return request({
url: `/notification/read/${code}`,
method: 'POST',
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
}).finally(() => {
clearNotificationPageCache()
})
}
// --- 房源与区域 ---
export function areaPagination(params = {}, language) {
return request({
url: '/index/pagination',
method: 'GET',
params,
header: {
'X-Requested-Language': resolveLanguageHeader(language)
},
withAuth: false
})
}
export function facilityManagers(params = {}, language) {
return request({
url: '/facility/managers',
method: 'GET',
params,
header: {
'X-Requested-Language': resolveLanguageHeader(language)
},
withAuth: false
})
}
// --- 宿管与管理员联系人 ---
export function myDormitoryManagers(language) {
return request({
url: '/usercampus/my-dormitory-managers',
method: 'GET',
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function myCounselor(language) {
return request({
url: '/usercampus/my-counselor',
method: 'GET',
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function buildingPagination(params = {}, language) {
return request({
url: '/building/pagination',
method: 'GET',
params,
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function roomtypeList(params = {}, language) {
return request({
url: '/roomtype/list',
method: 'GET',
params,
header: {
'X-Requested-Language': resolveLanguageHeader(language)
},
withAuth: false
})
}
export function roomTypeDetail(params = {}, language) {
return request({
url: '/roomtype/detail',
method: 'GET',
params,
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function roomPagination(params = {}, language) {
return request({
url: '/room/pagination',
method: 'GET',
params,
header: {
'X-Requested-Language': resolveLanguageHeader(language)
},
withAuth: false
})
}
export function roomDetail(params = {}, language) {
return request({
url: '/room/detail',
method: 'GET',
params,
header: {
'X-Requested-Language': resolveLanguageHeader(language)
},
withAuth: false
})
}
// --- 智能设备 ---
export function gatewayRoomDeviceList(brandId = '', roomCode = '', language) {
const resolvedBrandId = String(brandId || '').trim()
const resolvedRoomCode = String(roomCode || '').trim()
if (!resolvedBrandId) {
return Promise.reject(new Error('brandId 不能为空'))
}
if (!resolvedRoomCode) {
return Promise.reject(new Error('roomCode 不能为空'))
}
return request({
url: buildIotGatewayUrl(`/gateway/${encodeURIComponent(resolvedBrandId)}/rooms/${encodeURIComponent(resolvedRoomCode)}`),
method: 'POST',
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
function stringifyGatewayExecuteValue(value = '') {
if (value === undefined || value === null) {
return ''
}
if (typeof value === 'object') {
try {
return JSON.stringify(value)
} catch (error) {
return String(value)
}
}
return String(value)
}
function buildGatewayExecuteValues(data = {}) {
if (data === undefined || data === null) {
return ''
}
if (typeof data !== 'object' || Array.isArray(data)) {
return stringifyGatewayExecuteValue(data)
}
const keys = Object.keys(data)
if (!keys.length) {
return ''
}
if (keys.length === 1) {
return stringifyGatewayExecuteValue(data[keys[0]])
}
if (Object.prototype.hasOwnProperty.call(data, 'value')) {
return stringifyGatewayExecuteValue(data.value)
}
if (Object.prototype.hasOwnProperty.call(data, 'command')) {
return stringifyGatewayExecuteValue(data.command)
}
if (Object.prototype.hasOwnProperty.call(data, 'action')) {
return stringifyGatewayExecuteValue(data.action)
}
return stringifyGatewayExecuteValue(data)
}
export function gatewayExecuteDeviceCommand(brandId = '', deviceNo = '', functionCode = '', data = {}, language) {
const resolvedBrandId = String(brandId || '').trim()
const resolvedDeviceNo = String(deviceNo || '').trim()
const resolvedFunctionCode = String(functionCode || '').trim()
if (!resolvedBrandId) {
return Promise.reject(new Error('brandId 不能为空'))
}
if (!resolvedDeviceNo) {
return Promise.reject(new Error('deviceNo 不能为空'))
}
if (!resolvedFunctionCode) {
return Promise.reject(new Error('functionCode 不能为空'))
}
return request({
url: buildIotGatewayUrl(`/gateway/${encodeURIComponent(resolvedBrandId)}/execute`),
method: 'POST',
data: {
deviceNo: resolvedDeviceNo,
cmd: resolvedFunctionCode,
values: buildGatewayExecuteValues(data)
},
header: {
'Content-Type': 'application/json-patch+json',
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
export function gatewaySyncDeviceInfo(brandId = '', deviceNo = '', language) {
const resolvedBrandId = String(brandId || '').trim()
const resolvedDeviceNo = String(deviceNo || '').trim()
if (!resolvedBrandId) {
return Promise.reject(new Error('brandId 不能为空'))
}
if (!resolvedDeviceNo) {
return Promise.reject(new Error('deviceNo 不能为空'))
}
return request({
url: buildIotGatewayUrl(`/gateway/${encodeURIComponent(resolvedBrandId)}/devices/${encodeURIComponent(resolvedDeviceNo)}`),
method: 'POST',
header: {
'X-Requested-Language': resolveLanguageHeader(language)
}
})
}
// --- 内容 ---
export function bannerAll(language) {
return request({
url: '/content/banner/all',
method: 'GET',
header: {
'X-Requested-Language': resolveLanguageHeader(language)
},
withAuth: false
})
}
// --- 上传 ---
export function uploadCommonFile(filePath, formData = {}, name = 'file', header = {}) {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: `${API_BASE_URL}/file/common/upload`,
filePath,
name,
formData: {
...(formData || {}),
ProviderType: 'WechatMiniProgram'
},
header: {
'X-Requested-Language': resolveLanguageHeader(),
...header
},
success: (res) => {
const { statusCode, data } = res
normalizeUploadResponse(data)
.then(parsedData => {
if (statusCode >= 200 && statusCode < 300) {
resolve(parsedData)
return
}
reject(parsedData || res)
})
.catch(() => {
reject(res)
})
},
fail: (error) => {
reject(error)
}
})
})
}