Migrate legacy relative API imports to consistent absolute @/api paths across all components Remove unnecessary .js file extensions from ES module imports Add new StreamManager utility and base client configuration constants file Clean up unused imports and dynamic config calls in ChatGuide and ChatInputArea components Update the index.html page title to "nianxx" Replace dynamic OSS URL and local text imports in ChatGuide with hardcoded static values
239 lines
7.3 KiB
Vue
239 lines
7.3 KiB
Vue
<template>
|
||
<div class="create-service-order">
|
||
<div class="w-full bg-white border-box border-ff overflow-hidden rounded-20">
|
||
<div class="border-box order-header w-vw flex flex-items-center flex-justify-between bg-theme-color-50">
|
||
<span class="font-size-18 font-500 color-171717 text-left ml-12">
|
||
{{ isCallSuccess ? "服务已创建" : "呼叫服务" }}
|
||
</span>
|
||
<img class="header-icon" src="https://oss.nianxx.cn/mp/static/version_101/home/feedback.png" />
|
||
</div>
|
||
|
||
<div v-if="!isCallSuccess" class="border-box p-12">
|
||
<div class="bg-F5F7FA border-box flex flex-items-center p-12 rounded-10 font-size-14 color-171717 mb-12">
|
||
<span class="font-500 line-height-22 mr-20">所在位置</span>
|
||
<input placeholder="请填写所在位置" v-model="roomId" />
|
||
</div>
|
||
|
||
<div class="bg-F5F7FA border-box flex flex-items-center p-12 rounded-10 font-size-14 color-171717 mb-12">
|
||
<span class="font-500 line-height-22 mr-20">联系电话</span>
|
||
<input placeholder="请填写联系电话" v-model="contactPhone" @input="handleContactPhoneInput" />
|
||
</div>
|
||
|
||
<div class="bg-F5F7FA border-box p-12 rounded-10 font-size-14 font-500 color-171717 mb-12">
|
||
<div class="font-500 line-height-22 mb-12">需求信息描述</div>
|
||
<textarea class="h-80" placeholder="请输入需求信息描述" placeholder-class="font-size-14 font-400" maxlength="100"
|
||
v-model="contactText" />
|
||
</div>
|
||
|
||
<div class="bg-F5F7FA border-box p-12 rounded-10 font-size-14 font-500 color-171717 mb-12">
|
||
<div class="font-500 line-height-22 mb-12">照片上传</div>
|
||
|
||
<div class="w-80 h-80 bg-white rounded-8 overflow-hidden flex flex-items-center flex-justify-center">
|
||
<div v-if="contentImgUrl" class="w-full h-full relative inline-block">
|
||
<img 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>
|
||
</div>
|
||
|
||
<div 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>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div v-else class="border-box card-content flex flex-items-center p-12">
|
||
<div class="border-box left flex-full pr-20">
|
||
<div class="font-size-12 color-525866 line-height-20 mb-4">
|
||
所在位置:{{ roomId }}
|
||
</div>
|
||
<div class="font-size-12 color-525866 line-height-20 mb-4">
|
||
联系方式: {{ contactPhone }}
|
||
</div>
|
||
<div class="font-size-12 color-525866 line-height-20 ellipsis-2">
|
||
需求描述: {{ contactspan }}
|
||
</div>
|
||
</div>
|
||
|
||
<img v-if="contentImgUrl" class="right rounded-6" :src="contentImgUrl" mode="aspectFill" />
|
||
</div>
|
||
|
||
<div class="btn rounded-50 color-white bg-button flex flex-items-center flex-justify-center ml-12 mr-12 mb-12"
|
||
@click="handleCall">
|
||
{{ isCallSuccess ? "查看服务" : "立即呼叫" }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, computed, onMounted, nextTick, defineProps, watch } from "vue";
|
||
import { SCROLL_TO_BOTTOM } from "@/constants/constant";
|
||
import { createWorkOrder } from "@/api/workOrder";
|
||
import { updateImageFile } from "@/api/upload";
|
||
import { zniconsMap } from "@/assets/fonts/znicons";
|
||
|
||
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 contactspan = 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) {
|
||
// 查看工单
|
||
divWorkOrder();
|
||
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 divWorkOrder = () => {
|
||
// 这里可以跳转到工单详情页面
|
||
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>
|