Files
nianxx-h5/src/components/CreateServiceOrder/index.vue
DEV_DSW a131531a81 style: replace legacy typography classes with modern utilities
Convert all legacy font-size-*, font-weight-*, and line-height-* CSS utility classes to modern inline utility formats (text-[Xpx], font-{weight}, leading-[Xpx]). Also remove unused GoodsInfo component SCSS file, its associated image asset, and clean up the stale style import in GoodsInfo.vue.
2026-05-29 09:48:59 +08:00

237 lines
7.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>
<div class="create-service-order">
<div class="w-full bg-white border-ff overflow-hidden rounded-20">
<div class=" order-header w-vw flex flex-items-center flex-justify-between bg-theme-color-50">
<span class="text-[18px] font-medium 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=" p-[12px]">
<div class="bg-F5F7FA flex flex-items-center p-[12px] rounded-10 text-[14px] color-171717 mb-12">
<span class="font-medium line-height-22 mr-20">所在位置</span>
<input placeholder="请填写所在位置" v-model="roomId" />
</div>
<div class="bg-F5F7FA flex flex-items-center p-[12px] rounded-10 text-[14px] color-171717 mb-12">
<span class="font-medium line-height-22 mr-20">联系电话</span>
<input placeholder="请填写联系电话" v-model="contactPhone" @input="handleContactPhoneInput" />
</div>
<div class="bg-F5F7FA p-[12px] rounded-10 text-[14px] font-medium color-171717 mb-12">
<div class="font-medium line-height-22 mb-12">需求信息描述</div>
<textarea class="h-80" placeholder="请输入需求信息描述" placeholder-class="text-[14px] font-400" maxlength="100"
v-model="contactText" />
</div>
<div class="bg-F5F7FA p-[12px] rounded-10 text-[14px] font-medium color-171717 mb-12">
<div class="font-medium 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">
<zn-icon name="zn-camera" size="24" color="#6A717F"></zn-icon>
</div>
</div>
</div>
</div>
<div v-else class=" card-content flex flex-items-center p-[12px]">
<div class=" left flex-full pr-20">
<div class="text-[12px] text-ink-600 leading-[20px] mb-4">
所在位置{{ roomId }}
</div>
<div class="text-[12px] text-ink-600 leading-[20px] mb-4">
联系方式: {{ contactPhone }}
</div>
<div class="text-[12px] text-ink-600 leading-[20px] ellipsis-2">
需求描述: {{ contactspan }}
</div>
</div>
<img v-if="contentImgUrl" class="right rounded-6" :src="contentImgUrl" mode="aspectFill" />
</div>
<div class="btn rounded-[5px]0 text-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 { uploadFile } from "@/api/upload";
import ZnIcon from "@/components/ZnIcon/index.vue";
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;
}
uploadFile(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>