Files
YGChatCS/src/components/CreateServiceOrder/index.vue
duanshuwen e174e3b726 style: remove redundant box-border utility classes
Remove the unnecessary box-border CSS class from component template class lists across the codebase, cleaning up styling without altering any component functionality.
2026-07-24 16:50:53 +08:00

234 lines
7.6 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-ff overflow-hidden rounded-20">
<view class="border-box order-header w-vw flex flex-items-center flex-justify-between bg-[#F0F8F3]">
<text class="font-size-18 font-500 color-171717 text-left ml-[12px]">
{{ 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-[12px]">
<view class="bg-[#f5f7fa] flex flex-items-center p-[12px] 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] flex flex-items-center p-[12px] 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] p-[12px] 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] p-[12px] 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-[12px]">
<view class="border-box left flex-full pr-[20px]">
<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-gradient-to-r from-[#0CCD58] to-[#4de4ff] flex flex-items-center flex-justify-center ml-[12px] 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>