Files
YGChatCS/src/components/CreateServiceOrder/index.vue

288 lines
8.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="create-service-order">
<view
class="w-full bg-white border-box border-ff overflow-hidden rounded-20"
>
<view
class="border-box order-header w-vw flex flex-items-center flex-justify-between bg-EEF8FF"
>
<text class="font-size-18 font-500 color-171717 text-left ml-12">
{{ isCallSuccess ? "服务已创建" : "呼叫服务" }}
</text>
<image
class="header-icon"
src="https://oss.nianxx.cn/mp/static/version_101/home/feedback.png"
/>
</view>
<view v-if="!isCallSuccess" class="border-box p-12">
<view
class="bg-F5F7FA border-box flex flex-items-center p-12 rounded-10 font-size-14 color-171717 mb-12"
>
<text class="font-500 line-height-22 mr-20">房间号</text>
<input placeholder="请填写房间号" v-model="roomId" />
</view>
<view
class="bg-F5F7FA border-box flex flex-items-center p-12 rounded-10 font-size-14 color-171717 mb-12"
>
<text class="font-500 line-height-22 mr-20">联系电话</text>
<input
placeholder="请填写联系电话"
v-model="contactPhone"
@input="handleContactPhoneInput"
/>
</view>
<view
class="bg-F5F7FA border-box p-12 rounded-10 font-size-14 font-500 color-171717 mb-12"
>
<view class="font-500 line-height-22 mb-12">需求信息描述</view>
<textarea
class="h-80"
placeholder="请输入需求信息描述"
placeholder-class="font-size-14 font-400"
maxlength="100"
v-model="contactText"
/>
</view>
<view
class="bg-F5F7FA border-box p-12 rounded-10 font-size-14 font-500 color-171717 mb-12"
>
<view class="font-500 line-height-22 mb-12">照片上传</view>
<view
class="w-80 h-80 bg-white rounded-8 overflow-hidden flex flex-items-center flex-justify-center"
>
<view
v-if="contentImgUrl"
class="w-full h-full relative inline-block"
>
<image
class="w-full h-full block"
:src="contentImgUrl"
mode="aspectFill"
/>
<uni-icons
class="close-btn absolute z-10"
type="close"
size="20"
color="#6A717F"
@click="handleDeleteImage"
>
</uni-icons>
</view>
<view
v-else
class="w-full h-full flex flex-items-center flex-justify-center"
@click="handleChooseImage"
>
<uni-icons fontFamily="znicons" size="24" color="#6A717F">
{{ zniconsMap["zn-camera"] }}
</uni-icons>
</view>
</view>
</view>
</view>
<view v-else class="border-box card-content flex flex-items-center p-12">
<view class="border-box left flex-full pr-20">
<view class="font-size-12 color-525866 line-height-20 mb-4"
>房间号{{ roomId }}</view
>
<view class="font-size-12 color-525866 line-height-20 mb-4"
>联系方式: {{ contactPhone }}</view
>
<view class="font-size-12 color-525866 line-height-20 ellipsis-2"
>需求描述: {{ contactText }}</view
>
</view>
<image
v-if="contentImgUrl"
class="right rounded-6"
:src="contentImgUrl"
mode="aspectFill"
/>
</view>
<view
class="btn rounded-50 color-white bg-button flex flex-items-center flex-justify-center ml-12 mr-12 mb-12"
@click="handleCall"
>
{{ isCallSuccess ? "查看服务" : "立即呼叫" }}
</view>
</view>
</view>
</template>
<script setup>
import { ref, computed, onMounted, nextTick, defineProps, watch } from "vue";
import { SCROLL_TO_BOTTOM } from "@/constant/constant";
import { createWorkOrder } from "@/request/api/WorkOrderApi";
import { updateImageFile } from "@/request/api/UpdateFile";
import { zniconsMap } from "@/static/fonts/znicons.js";
const props = defineProps({
toolCall: {
type: Object,
default: () => ({}),
},
});
const workOrderTypeId = ref("");
const roomId = ref("");
const contentImgUrl = ref("");
const isCallSuccess = ref(false); // 呼叫成功状态
const workOrderId = ref(0); // 工单ID
const toolResult = computed(() => {
if (props.toolCall?.toolResult) {
return JSON.parse(props.toolCall?.toolResult);
} else {
return {};
}
});
// 原始手机号(未脱敏)
const originalPhone = ref("");
// 展示与输入绑定的手机号(初始为脱敏)
const contactPhone = ref("");
// 是否用户已编辑过手机号(一旦编辑则不再脱敏)
const hasEditedPhone = ref(false);
// 需求信息描述:使用可写的 ref并从工具结果初始化
const contactText = ref("");
// 手机号脱敏138****1234仅对11位数字进行处理
const maskPhone = (phone) => {
if (!phone) return "";
return String(phone).replace(/(\d{3})\d{4}(\d{4})/, "$1****$2");
};
// 监听工具返回结果,初始化原始与脱敏显示
watch(
toolResult,
(val) => {
originalPhone.value = val?.userPhone || "";
hasEditedPhone.value = false;
contactPhone.value = maskPhone(originalPhone.value);
contactText.value = val?.callServiceContent || "";
},
{ immediate: true }
);
// 处理图片上传
const handleChooseImage = () => {
uni.chooseImage({
count: 1,
success: (res) => {
const file = res.tempFilePaths[0];
updateImagehandle(file);
},
fail: () => {
uni.showToast({ title: "选择图片失败", icon: "none" });
},
});
};
// 标记用户已编辑手机号
const handleContactPhoneInput = () => {
hasEditedPhone.value = true;
};
const handleDeleteImage = () => {
contentImgUrl.value = "";
};
const updateImagehandle = (file) => {
if (!file) {
return;
}
updateImageFile(file).then((res) => {
contentImgUrl.value = res.data;
});
};
const handleCall = async () => {
if (isCallSuccess.value) {
// 查看工单
viewWorkOrder();
return;
}
if (!roomId.value.trim()) {
uni.showToast({ title: "请填写房间号", icon: "none" });
return;
}
const phoneToSubmit = hasEditedPhone.value
? contactPhone.value
: originalPhone.value;
if (!phoneToSubmit.trim()) {
uni.showToast({ title: "请填写联系电话", icon: "none" });
return;
}
if (!contactText.value.trim()) {
uni.showToast({ title: "请填写需求信息描述内容", icon: "none" });
return;
}
sendCreateWorkOrder(phoneToSubmit);
};
/// 创建工单
const sendCreateWorkOrder = async (phoneToSubmit) => {
try {
const params = {
workOrderTypeId: workOrderTypeId.value,
roomNo: roomId.value,
userPhone: phoneToSubmit,
content: contactText.value,
contentImgUrl: contentImgUrl.value,
};
console.log("🚀 ~ sendCreateWorkOrder ~ params:", params);
const res = await createWorkOrder(params);
if (res.code === 0) {
// 保存工单ID
workOrderId.value = res.data?.id || "";
// 设置成功状态
isCallSuccess.value = true;
uni.showToast({ title: "呼叫成功", icon: "success" });
} else {
uni.showToast({ title: res.message || "呼叫失败", icon: "none" });
}
} catch (error) {
uni.showToast({ title: "网络错误,请重试", icon: "none" });
}
};
// 查看工单
const viewWorkOrder = () => {
// 这里可以跳转到工单详情页面
uni.navigateTo({
url: `/pages-service/order/list`,
});
};
onMounted(() => {
nextTick(() => {
setTimeout(() => {
uni.$emit(SCROLL_TO_BOTTOM, true);
}, 200);
});
});
</script>
<style scoped lang="scss">
@import "./styles/index.scss";
.close-btn {
top: 0;
right: 0;
}
</style>