feat:新增功能和接口对接
This commit is contained in:
parent
56d38e8f3d
commit
0793b41818
2
env/.env
vendored
2
env/.env
vendored
@ -8,7 +8,7 @@ VITE_WX_APPID = 'wx327d788d7bd6eddf'
|
||||
# https://uniapp.dcloud.net.cn/collocation/manifest.html#h5-router
|
||||
# 比如你要部署到 https://unibest.tech/doc/ ,则配置为 /doc/
|
||||
VITE_APP_PUBLIC_BASE=/
|
||||
|
||||
# http://192.168.101.18:10010
|
||||
# 后台请求地址
|
||||
VITE_SERVER_BASEURL = 'http://192.168.101.18:10010'
|
||||
# 备注:如果后台带统一前缀,则也要加到后面,eg: https://ukw0y1.laf.run/api
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import { onHide, onLaunch, onShow } from '@dcloudio/uni-app'
|
||||
import { navigateToInterceptor } from '@/router/interceptor'
|
||||
import { useSystemStore } from './store'
|
||||
|
||||
onLaunch((options) => {
|
||||
console.log('App Launch', options)
|
||||
console.log('App Launch213123', options)
|
||||
const systemStore = useSystemStore()
|
||||
systemStore.setDicsValue()
|
||||
})
|
||||
onShow((options) => {
|
||||
console.log('App Show', options)
|
||||
|
||||
9
src/api/malfunction.ts
Normal file
9
src/api/malfunction.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import type { IMalfunctionReport } from './types/malfunction'
|
||||
import { http } from '@/http/http'
|
||||
|
||||
// 保存用户故障上报信息
|
||||
export function saveMalfunctionAPI(data: IMalfunctionReport) {
|
||||
return http.post<any>('/user/ebikeFaultReport/save', data, {
|
||||
noToken: true,
|
||||
})
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
import type { FinishRideParams, StartRideParams, UserOrdersQuery } from './types/order'
|
||||
import type { FinishRideParams, RefundRequestParams, StartRideParams, UserOrdersQuery } from './types/order'
|
||||
import { http } from '@/http/http'
|
||||
|
||||
// 开始骑行(生成订单、开锁)
|
||||
@ -58,3 +58,11 @@ export function getOrderDetailAPI(orderId: string) {
|
||||
noToken: true,
|
||||
})
|
||||
}
|
||||
|
||||
// 退款申请
|
||||
export function applyRefundAPI(data: RefundRequestParams) {
|
||||
return http.post<any>('/user/ebikeRefund/refundApply', data, {
|
||||
noToken: true,
|
||||
hideErrorToast: true,
|
||||
})
|
||||
}
|
||||
|
||||
8
src/api/system.ts
Normal file
8
src/api/system.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { http } from '@/http/http'
|
||||
|
||||
// 获取字典和字典值
|
||||
export function getDictsAndValuesAPI() {
|
||||
return http.get<any>('/user/ebikeDicValue/list', undefined, {
|
||||
noToken: true,
|
||||
})
|
||||
}
|
||||
13
src/api/types/malfunction.ts
Normal file
13
src/api/types/malfunction.ts
Normal file
@ -0,0 +1,13 @@
|
||||
// 保存用户故障上报信息
|
||||
export interface IMalfunctionReport {
|
||||
userId: string
|
||||
bikeCode: string
|
||||
faultPart: number[]
|
||||
faultDescription: string
|
||||
location: {
|
||||
type: 'polygon' | 'point'
|
||||
longitude: number
|
||||
latitude: number
|
||||
}
|
||||
attachmentFiles: any
|
||||
}
|
||||
@ -39,3 +39,11 @@ export interface UserOrdersQuery {
|
||||
pageNum: number
|
||||
pageSize: number
|
||||
}
|
||||
|
||||
// 退款申请
|
||||
export interface RefundRequestParams {
|
||||
orderId: string
|
||||
problemType: number
|
||||
problemDescription: string
|
||||
refundFiles?: any[]
|
||||
}
|
||||
|
||||
99
src/api/upload.ts
Normal file
99
src/api/upload.ts
Normal file
@ -0,0 +1,99 @@
|
||||
// 获取环境变量
|
||||
const { VITE_SERVER_BASEURL } = import.meta.env
|
||||
|
||||
// 故障上传接口
|
||||
export const faultUploadUrl = `${VITE_SERVER_BASEURL}/user/ebikeFaultReport/uploadFile`
|
||||
|
||||
// 退款上传接口
|
||||
export const refundUploadUrl = `${VITE_SERVER_BASEURL}/user/ebikeRefund/uploadFile`
|
||||
|
||||
/**
|
||||
* 从图片URL数组下载并上传图片(严格模式:任一失败则整体失败)
|
||||
* @param {string[]} urls - 图片URL数组,如 ["http://...", "http://..."]
|
||||
* @param {string} uploadUrl - 上传接口地址
|
||||
* @param {object} [options] - 可选配置
|
||||
* @param {string} [options.name] - 表单字段名(后端接收的 key)
|
||||
* @param {object} [options.formData] - 额外表单数据
|
||||
* @param {object} [options.header] - 请求头
|
||||
* @returns {Promise<Array>} - 成功时返回每个文件的上传响应结果数组
|
||||
*/
|
||||
export async function uploadImagesStrict(urls: string[], uploadUrl: string, options: any = {}) {
|
||||
if (!Array.isArray(urls) || urls.length === 0) {
|
||||
throw new Error('urls 必须是非空数组')
|
||||
}
|
||||
|
||||
const {
|
||||
name = 'file',
|
||||
formData = {},
|
||||
header = {},
|
||||
} = options
|
||||
|
||||
// 下载单张图片 → 返回本地临时路径
|
||||
async function downloadImage(url: string) {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.downloadFile({
|
||||
url,
|
||||
success: (res) => {
|
||||
if (res.statusCode === 200) {
|
||||
resolve(res.tempFilePath)
|
||||
}
|
||||
else {
|
||||
reject(new Error(`下载失败 [${url}],状态码: ${res.statusCode}`))
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
reject(new Error(`下载失败 [${url}]:${err.errMsg || err.message}`))
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 上传单张图片
|
||||
async function uploadImage(localPath: any) {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.uploadFile({
|
||||
url: uploadUrl,
|
||||
filePath: localPath,
|
||||
name,
|
||||
formData,
|
||||
header,
|
||||
success: (res) => {
|
||||
// 注意:uni.uploadFile 的 success 不代表业务成功!
|
||||
// 你可能需要解析 res.data 并判断业务状态
|
||||
console.log(res.data)
|
||||
console.log(JSON.parse(res.data))
|
||||
|
||||
try {
|
||||
const data = typeof res.data === 'string' ? JSON.parse(res.data) : res.data
|
||||
// 假设后端返回 { code: 200, data: ... } 表示成功
|
||||
if (data.code === 200 || res.statusCode === 200) {
|
||||
resolve(data.data)
|
||||
}
|
||||
else {
|
||||
reject(new Error(`上传失败:${data.msg || '未知错误'}`))
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
// 如果无法解析 JSON,也视为失败
|
||||
reject(new Error(`上传响应解析失败:${res.data}`))
|
||||
}
|
||||
},
|
||||
fail: (err: any) => {
|
||||
reject(new Error(`上传请求失败:${err.errMsg || err.message}`))
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 并发下载所有图片
|
||||
const localPaths = await Promise.all(
|
||||
urls.map(url => downloadImage(url)),
|
||||
)
|
||||
|
||||
// 并发上传所有图片
|
||||
const uploadResults = await Promise.all(
|
||||
localPaths.map(path => uploadImage(path)),
|
||||
)
|
||||
|
||||
return uploadResults // 全部成功才返回结果数组
|
||||
}
|
||||
@ -1,4 +1,8 @@
|
||||
<script lang="ts" setup>
|
||||
import { saveMalfunctionAPI } from '@/api/malfunction'
|
||||
import { faultUploadUrl, uploadImagesStrict } from '@/api/upload'
|
||||
import { useSystemStore, useUserStore } from '@/store'
|
||||
|
||||
definePage({
|
||||
style: {
|
||||
navigationBarTitleText: '故障反馈',
|
||||
@ -7,83 +11,94 @@ definePage({
|
||||
},
|
||||
})
|
||||
|
||||
const userStore = useUserStore()
|
||||
const systemStore = useSystemStore()
|
||||
const form = ref<any>(null)
|
||||
const formData = reactive({
|
||||
bikeCode: '',
|
||||
faultDescription: '',
|
||||
faultPart: '',
|
||||
faultPart: [],
|
||||
attachmentFiles: [],
|
||||
location: {
|
||||
type: 'point' as const,
|
||||
latitude: 0,
|
||||
longitude: 0,
|
||||
},
|
||||
})
|
||||
const fault_list = ref([
|
||||
{
|
||||
icon: 'cheba',
|
||||
name: '车把',
|
||||
selected: false,
|
||||
},
|
||||
{
|
||||
icon: 'motuochetou',
|
||||
name: '车头',
|
||||
selected: false,
|
||||
},
|
||||
{
|
||||
icon: 'gaoliangchedeng',
|
||||
name: '车灯',
|
||||
selected: false,
|
||||
},
|
||||
{
|
||||
icon: 'ico',
|
||||
name: '二维码',
|
||||
selected: false,
|
||||
},
|
||||
{
|
||||
icon: 'gouwuche',
|
||||
name: '车筐',
|
||||
selected: false,
|
||||
},
|
||||
{
|
||||
icon: 'luxian',
|
||||
name: '线路',
|
||||
selected: false,
|
||||
},
|
||||
{
|
||||
icon: 'chezuo',
|
||||
name: '车座',
|
||||
selected: false,
|
||||
},
|
||||
{
|
||||
icon: 'dianchi',
|
||||
name: '电池',
|
||||
selected: false,
|
||||
},
|
||||
{
|
||||
icon: 'chelun',
|
||||
name: '车轮',
|
||||
selected: false,
|
||||
},
|
||||
{
|
||||
icon: 'izuliao',
|
||||
name: '脚蹬',
|
||||
selected: false,
|
||||
},
|
||||
{
|
||||
icon: 'qichechenggan',
|
||||
name: '车撑',
|
||||
selected: false,
|
||||
},
|
||||
{
|
||||
icon: 'zhedangban-23',
|
||||
name: '挡板',
|
||||
selected: false,
|
||||
},
|
||||
// {
|
||||
// icon: 'cheba',
|
||||
// name: '车把',
|
||||
// selected: false,
|
||||
// },
|
||||
// {
|
||||
// icon: 'motuochetou',
|
||||
// name: '车头',
|
||||
// selected: false,
|
||||
// },
|
||||
// {
|
||||
// icon: 'gaoliangchedeng',
|
||||
// name: '车灯',
|
||||
// selected: false,
|
||||
// },
|
||||
// {
|
||||
// icon: 'ico',
|
||||
// name: '二维码',
|
||||
// selected: false,
|
||||
// },
|
||||
// {
|
||||
// icon: 'gouwuche',
|
||||
// name: '车筐',
|
||||
// selected: false,
|
||||
// },
|
||||
// {
|
||||
// icon: 'luxian',
|
||||
// name: '线路',
|
||||
// selected: false,
|
||||
// },
|
||||
// {
|
||||
// icon: 'chezuo',
|
||||
// name: '车座',
|
||||
// selected: false,
|
||||
// },
|
||||
// {
|
||||
// icon: 'dianchi',
|
||||
// name: '电池',
|
||||
// selected: false,
|
||||
// },
|
||||
// {
|
||||
// icon: 'chelun',
|
||||
// name: '车轮',
|
||||
// selected: false,
|
||||
// },
|
||||
// {
|
||||
// icon: 'izuliao',
|
||||
// name: '脚蹬',
|
||||
// selected: false,
|
||||
// },
|
||||
// {
|
||||
// icon: 'qichechenggan',
|
||||
// name: '车撑',
|
||||
// selected: false,
|
||||
// },
|
||||
// {
|
||||
// icon: 'zhedangban-23',
|
||||
// name: '挡板',
|
||||
// selected: false,
|
||||
// },
|
||||
])
|
||||
|
||||
const fileList = ref([])
|
||||
|
||||
function handleClick(item: any, index: number) {
|
||||
uni.vibrateShort()
|
||||
fault_list.value[index].selected = !item.selected
|
||||
}
|
||||
|
||||
function afterRead(event: any) {
|
||||
async function afterRead(event: any) {
|
||||
const lists = [].concat(event.file)
|
||||
let fileListLen = fileList.value.length
|
||||
|
||||
lists.forEach((item) => {
|
||||
fileList.value.push({
|
||||
...item,
|
||||
@ -91,11 +106,88 @@ function afterRead(event: any) {
|
||||
message: '上传中',
|
||||
})
|
||||
})
|
||||
|
||||
for (let i = 0; i < lists.length; i++) {
|
||||
const item = fileList.value[fileListLen]
|
||||
try {
|
||||
const result: any = await uploadImagesStrict([lists[i].url], faultUploadUrl, {
|
||||
name: 'multipartFile',
|
||||
header: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
})
|
||||
formData.attachmentFiles.push(result[0])
|
||||
fileList.value.splice(fileListLen, 1, Object.assign(item, {
|
||||
status: 'success',
|
||||
message: '',
|
||||
url: result[0].fileUrl,
|
||||
}))
|
||||
fileListLen++
|
||||
}
|
||||
catch (err) {
|
||||
fileList.value.splice(fileListLen, 1, Object.assign(item, {
|
||||
status: 'failed',
|
||||
message: '',
|
||||
url: '',
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function deletePic() {
|
||||
|
||||
function deletePic(e: any) {
|
||||
fileList.value.splice(e.index, 1)
|
||||
formData.attachmentFiles.splice(e.index, 1)
|
||||
}
|
||||
|
||||
async function submit() {
|
||||
console.log('提交表单', formData)
|
||||
try {
|
||||
const selectedFaults = fault_list.value
|
||||
.filter(item => item.selected)
|
||||
.map(item => item.value)
|
||||
console.log(selectedFaults)
|
||||
|
||||
const res = await saveMalfunctionAPI({
|
||||
userId: userStore.userInfo.userId,
|
||||
faultPart: selectedFaults,
|
||||
faultDescription: formData.faultDescription,
|
||||
bikeCode: formData.bikeCode,
|
||||
attachmentFiles: formData.attachmentFiles,
|
||||
location: formData.location,
|
||||
})
|
||||
}
|
||||
catch (err) {
|
||||
console.error('提交失败', err)
|
||||
}
|
||||
}
|
||||
|
||||
onLoad(async () => {
|
||||
const list = await systemStore.getDictValue('inventory_type')
|
||||
console.log(list)
|
||||
if (list?.length > 0) {
|
||||
fault_list.value = list.map((item: any) => ({
|
||||
icon: item.dicIcon || '',
|
||||
name: item.dicValueName,
|
||||
value: Number(item.dicValue),
|
||||
selected: false,
|
||||
}))
|
||||
}
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
uni.getLocation({
|
||||
type: 'gcj02',
|
||||
success(res) {
|
||||
console.log(res, '地理位置')
|
||||
|
||||
formData.location.latitude = res.latitude
|
||||
formData.location.longitude = res.longitude
|
||||
},
|
||||
fail(err) {
|
||||
console.error('获取位置失败:', err)
|
||||
},
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -165,6 +257,7 @@ function deletePic() {
|
||||
<uv-button
|
||||
type="primary"
|
||||
text="上报故障"
|
||||
@click="submit"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@ -73,6 +73,12 @@ function drawLine() {
|
||||
startAndEndMapRef.value && startAndEndMapRef.value.adjustMapView(points.value)
|
||||
}
|
||||
|
||||
function returnFee() {
|
||||
uni.navigateTo({
|
||||
url: `/pages-sub/refundFee/refundFee?orderId=${orderIds.value}`,
|
||||
})
|
||||
}
|
||||
|
||||
onLoad((query) => {
|
||||
const { orderId } = query
|
||||
if (orderId) {
|
||||
@ -115,7 +121,7 @@ onMounted(() => {
|
||||
<view class="price">
|
||||
已支付{{ toFixedString(orderDetail.actualAmount, 2) }}元
|
||||
</view>
|
||||
<view>
|
||||
<view class="icon_box">
|
||||
<view class="icon_bar">
|
||||
<uv-icon
|
||||
size="24"
|
||||
@ -127,6 +133,17 @@ onMounted(() => {
|
||||
故障上报
|
||||
</view>
|
||||
</view>
|
||||
<view class="icon_bar" style="margin-left: 30rpx;" @click="returnFee">
|
||||
<uv-icon
|
||||
size="24"
|
||||
name="shenqingtuikuan"
|
||||
color="#5f5f61"
|
||||
custom-prefix="custom-icon"
|
||||
/>
|
||||
<view style="margin-top: 8rpx; color: #5f5f61;">
|
||||
申请退款
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="middle_info">
|
||||
@ -175,11 +192,16 @@ onMounted(() => {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.icon_bar {
|
||||
.icon_box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
font-size: 24rpx;
|
||||
|
||||
.icon_bar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -15,6 +15,9 @@ const userStore = useUserStore()
|
||||
const list = ref<any>([])
|
||||
const paging = ref<any>(null)
|
||||
async function queryList(pageNum: number, pageSize: number) {
|
||||
uni.showLoading({
|
||||
title: '加载中...',
|
||||
})
|
||||
try {
|
||||
const res = await getUserOrdersAPI({
|
||||
userId: userStore.userInfo.userId,
|
||||
@ -24,9 +27,15 @@ async function queryList(pageNum: number, pageSize: number) {
|
||||
console.log(res)
|
||||
const { records } = res
|
||||
paging.value.complete(records)
|
||||
uni.hideLoading()
|
||||
}
|
||||
catch (err) {
|
||||
console.error('Error fetching user orders:', err)
|
||||
uni.showToast({
|
||||
title: '加载失败,请稍后重试',
|
||||
icon: 'error',
|
||||
})
|
||||
uni.hideLoading()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
305
src/pages-sub/refundFee/refundFee.vue
Normal file
305
src/pages-sub/refundFee/refundFee.vue
Normal file
@ -0,0 +1,305 @@
|
||||
<script lang="ts" setup>
|
||||
import { applyRefundAPI } from '@/api/order'
|
||||
import { refundUploadUrl, uploadImagesStrict } from '@/api/upload'
|
||||
import { useSystemStore, useUserStore } from '@/store'
|
||||
|
||||
definePage({
|
||||
style: {
|
||||
navigationBarTitleText: '申请退款',
|
||||
navigationBarBackgroundColor: '#1488f5',
|
||||
navigationBarTextStyle: 'white',
|
||||
},
|
||||
})
|
||||
|
||||
const userStore = useUserStore()
|
||||
const systemStore = useSystemStore()
|
||||
const fileList = ref([])
|
||||
const problemTypeList = ref([])
|
||||
const formData = reactive({
|
||||
problemDescription: '',
|
||||
refundFiles: [],
|
||||
problemType: undefined,
|
||||
orderId: '',
|
||||
})
|
||||
const btnConfig = reactive({
|
||||
text: '提交申请',
|
||||
loadingText: '提交中...',
|
||||
disabledText: '已提交',
|
||||
loading: false,
|
||||
disabled: false,
|
||||
})
|
||||
|
||||
async function afterRead(event: any) {
|
||||
const lists = [].concat(event.file)
|
||||
let fileListLen = fileList.value.length
|
||||
|
||||
lists.forEach((item) => {
|
||||
fileList.value.push({
|
||||
...item,
|
||||
status: 'uploading',
|
||||
message: '上传中',
|
||||
})
|
||||
})
|
||||
|
||||
for (let i = 0; i < lists.length; i++) {
|
||||
const item = fileList.value[fileListLen]
|
||||
try {
|
||||
const result: any = await uploadImagesStrict([lists[i].url], refundUploadUrl, {
|
||||
name: 'multipartFile',
|
||||
header: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
})
|
||||
formData.refundFiles.push(result[0])
|
||||
fileList.value.splice(fileListLen, 1, Object.assign(item, {
|
||||
status: 'success',
|
||||
message: '',
|
||||
url: result[0].fileUrl,
|
||||
}))
|
||||
fileListLen++
|
||||
}
|
||||
catch (err) {
|
||||
fileList.value.splice(fileListLen, 1, Object.assign(item, {
|
||||
status: 'failed',
|
||||
message: '',
|
||||
url: '',
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function deletePic(e: any) {
|
||||
fileList.value.splice(e.index, 1)
|
||||
formData.refundFiles.splice(e.index, 1)
|
||||
}
|
||||
|
||||
function handleClick(item: any, index: number) {
|
||||
uni.vibrateShort()
|
||||
formData.problemType = item.dicValue
|
||||
}
|
||||
|
||||
// 重置表单数据
|
||||
function resetFormatData() {
|
||||
formData.orderId = ''
|
||||
formData.problemType = undefined
|
||||
formData.problemDescription = ''
|
||||
formData.refundFiles = []
|
||||
fileList.value = []
|
||||
}
|
||||
|
||||
// 提交退款申请
|
||||
async function submit() {
|
||||
btnConfig.loading = true
|
||||
try {
|
||||
const res = await applyRefundAPI(formData)
|
||||
btnConfig.loading = false
|
||||
uni.showToast({
|
||||
title: '提交成功',
|
||||
icon: 'success',
|
||||
})
|
||||
setTimeout(() => {
|
||||
resetFormatData()
|
||||
uni.navigateBack()
|
||||
}, 800)
|
||||
}
|
||||
catch (err) {
|
||||
btnConfig.loading = false
|
||||
console.error('提交退款申请失败:', err)
|
||||
uni.showToast({
|
||||
title: '提交失败',
|
||||
icon: 'error',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
onLoad(async (query) => {
|
||||
const { orderId } = query
|
||||
if (orderId) {
|
||||
formData.orderId = orderId
|
||||
}
|
||||
const list = await systemStore.getDictValue('problem_Type')
|
||||
if (list?.length > 0) {
|
||||
problemTypeList.value = list.map((item: any) => ({
|
||||
...item,
|
||||
dicValue: Number(item.dicValue),
|
||||
}))
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<z-paging
|
||||
ref="paging"
|
||||
>
|
||||
<view class="container">
|
||||
<!-- 退款描述 -->
|
||||
<view class="describe_tips">
|
||||
如果您对此单有异议,请提交相关信息,我们核实后,会退回多扣的费用
|
||||
</view>
|
||||
|
||||
<!-- 问题类型 -->
|
||||
<view class="problemTypes">
|
||||
<view class="titleup">
|
||||
问题类型
|
||||
</view>
|
||||
|
||||
<view class="type_Bar">
|
||||
<view
|
||||
v-for="(item, index) in problemTypeList"
|
||||
:key="item.dicId"
|
||||
class="type_item"
|
||||
:class="[item.dicValue === formData.problemType ? 'type_item_active' : '']"
|
||||
@click="handleClick(item, index)"
|
||||
>
|
||||
{{ item.dicValueName }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 其他问题 -->
|
||||
<view class="oher_question">
|
||||
<view class="titleup" style="margin-bottom: 20rpx;">
|
||||
问题描述
|
||||
</view>
|
||||
<uv-textarea v-model="formData.problemDescription" count :maxlength="200" placeholder="请描述" />
|
||||
</view>
|
||||
|
||||
<!-- 上传图片 -->
|
||||
<view class="upload-img">
|
||||
<view class="titleup" style="margin-bottom: 20rpx;">
|
||||
拍摄照片
|
||||
</view>
|
||||
<uv-upload
|
||||
:file-list="fileList"
|
||||
name="1"
|
||||
multiple
|
||||
:preview-full-image="true"
|
||||
@after-read="afterRead"
|
||||
@delete="deletePic"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<template #bottom>
|
||||
<view class="bottom-button-zaping">
|
||||
<uv-button
|
||||
type="primary"
|
||||
:text="btnConfig.text"
|
||||
:loading="btnConfig.loading"
|
||||
:disabled="btnConfig.disabled"
|
||||
:loading-text="btnConfig.loadingText"
|
||||
@click="submit"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
</z-paging>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
width: calc(100% - 60rpx);
|
||||
padding: 10rpx 30rpx;
|
||||
|
||||
.describe_tips {
|
||||
padding: 15rpx 30rpx;
|
||||
background-color: #effbeb;
|
||||
margin-top: 20rpx;
|
||||
border-radius: 10rpx;
|
||||
font-size: 26rpx;
|
||||
color: #656f63;
|
||||
}
|
||||
|
||||
.problemTypes {
|
||||
margin-top: 20rpx;
|
||||
|
||||
.type_Bar {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 15rpx;
|
||||
|
||||
.type_item {
|
||||
padding: 15rpx;
|
||||
border: 2rpx solid #e5e5e5;
|
||||
font-size: 26rpx;
|
||||
color: #646464;
|
||||
margin: 25rpx 30rpx 0 0;
|
||||
border-radius: 15rpx;
|
||||
}
|
||||
|
||||
.type_item_active {
|
||||
border-color: #1488f5 !important;
|
||||
background-color: #1488f5 !important;
|
||||
color: white !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.titleup {
|
||||
font-size: 30rpx;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 4px; /* 竖线宽度,可调整 */
|
||||
height: 16px; /* 竖线高度,建议和标题文字高度匹配 */
|
||||
margin-right: 8px; /* 竖线和标题的间距 */
|
||||
background: linear-gradient(to bottom, #1488f5, #c0e3f4); /* 渐变颜色,和你之前的背景呼应 */
|
||||
vertical-align: middle; /* 确保竖线和文字垂直居中对齐 */
|
||||
position: relative;
|
||||
top: -1px;
|
||||
}
|
||||
}
|
||||
|
||||
.fault_bar {
|
||||
margin-top: 40rpx;
|
||||
|
||||
.list_grid {
|
||||
margin-top: 20rpx;
|
||||
padding-top: 5rpx;
|
||||
display: grid;
|
||||
overflow-y: auto;
|
||||
grid-template-columns: repeat(4, 1fr); /* 固定5列 */
|
||||
grid-template-rows: auto auto; /* 两行 */
|
||||
gap: 16px; /* 项目之间的间距 */
|
||||
}
|
||||
|
||||
.fault_item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
background-color: #fff;
|
||||
border-radius: 12rpx;
|
||||
|
||||
.icon {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 0 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.text {
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
text-shadow: 0 0 4px rgba(0, 0, 0, 0.1);
|
||||
margin-top: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.no-margin-right {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.oher_question {
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
|
||||
.upload-img {
|
||||
margin-top: 40rpx;
|
||||
margin-bottom: 100px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -46,6 +46,14 @@ const menuItems = ref([
|
||||
icon: 'diyabiao',
|
||||
size: 18,
|
||||
},
|
||||
// {
|
||||
// key: 'returnFee',
|
||||
// title: '申请退款',
|
||||
// isLink: true,
|
||||
// icon: 'shenqingtuikuan',
|
||||
// size: 18,
|
||||
// url: '/pages-sub/refundFee/refundFee',
|
||||
// },
|
||||
{
|
||||
key: 'help',
|
||||
title: '帮助中心',
|
||||
|
||||
@ -14,6 +14,7 @@ store.use(
|
||||
export default store
|
||||
|
||||
export * from './order'
|
||||
export * from './system'
|
||||
// 模块统一导出
|
||||
export * from './token'
|
||||
export * from './user'
|
||||
|
||||
61
src/store/system.ts
Normal file
61
src/store/system.ts
Normal file
@ -0,0 +1,61 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
import { getDictsAndValuesAPI } from '@/api/system'
|
||||
|
||||
export const useSystemStore = defineStore(
|
||||
'system',
|
||||
() => {
|
||||
// 字典数据和系统配置项
|
||||
const dictsAndValues = ref<any>([])
|
||||
|
||||
// 设置字典数据和系统配置项
|
||||
const setDicsValue = async () => {
|
||||
try {
|
||||
// 获取字典数据和系统配置项
|
||||
const res = await getDictsAndValuesAPI()
|
||||
if (res) {
|
||||
dictsAndValues.value = res
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
console.error('字典值异常', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取指定key的字典值
|
||||
const getDictValue = async (key: string) => {
|
||||
const dict = dictsAndValues.value.find((item: any) => item.dicCode === key)
|
||||
return dict?.values || []
|
||||
|
||||
// if (dictsAndValues.value.length === 0) {
|
||||
// try {
|
||||
// // 获取字典数据和系统配置项
|
||||
// const res = await getDictsAndValuesAPI()
|
||||
// if (res) {
|
||||
// dictsAndValues.value = res
|
||||
// console.log('字典值', dictsAndValues.value)
|
||||
// const dict = dictsAndValues.value.find((item: any) => item.dicCode === key)
|
||||
// return dict?.values || []
|
||||
// }
|
||||
// }
|
||||
// catch (err) {
|
||||
// console.error('字典值异常', err)
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// const dict = dictsAndValues.value.find((item: any) => item.dicCode === key)
|
||||
// return dict?.values || []
|
||||
// }
|
||||
}
|
||||
|
||||
return {
|
||||
dictsAndValues,
|
||||
|
||||
setDicsValue,
|
||||
getDictValue,
|
||||
}
|
||||
},
|
||||
{
|
||||
persist: true,
|
||||
},
|
||||
)
|
||||
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user