OrderInfo.vue 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. <template>
  2. <view>
  3. <view class="order-info bg-white">
  4. <view class="info-item flex">
  5. <text class="label">订单编号</text>
  6. <text style="color: #22ac38" class="flex-1 text-center content"
  7. @click="copyToClipboard(detail.orderId)">{{ detail.orderId }}</text>
  8. </view>
  9. <view class="info-item">
  10. <text class="label">预估金额</text>
  11. <text class="content">{{ detail.expectMoney }}</text>
  12. <text class="label border-left">审核金额</text>
  13. <text class="content">{{ detail.finalMoney }}</text>
  14. </view>
  15. <view class="info-item">
  16. <text class="label">用户备注</text>
  17. <text class="content">{{ detail.userRemark }}</text>
  18. </view>
  19. <view class="info-item" @click="handleRemark">
  20. <text class="label">内部备注</text>
  21. <text class="content">{{
  22. detail?.manageRemark
  23. ? detail?.manageRemark.length > 0
  24. ? detail?.manageRemark[0]?.remark
  25. : " "
  26. : " "
  27. }}</text>
  28. </view>
  29. <view class="info-item">
  30. <text class="label">订单状态</text>
  31. <text class="content" style="color: #c5493e">[{{ statusText }}]</text>
  32. </view>
  33. <view class="info-item">
  34. <text class="label">快递</text>
  35. <text class="content">{{ finalExpressText
  36. }}<text style="color: #409eef" @click="copyToClipboard(detail.waybillCode)">(单号:{{
  37. detail.waybillCode }})</text></text>
  38. </view>
  39. <view class="info-item">
  40. <text class="label">发件人<text style="color: #e99d42">(所有单)</text></text>
  41. <view class="content flex flex-a-c flex-j-c">
  42. <text class="content-text" @click="copyToClipboard(detail.sendMobile)">复制</text>
  43. <text class="content-text ml-10 mr-10">{{ maskedSendMobile }}</text>
  44. <u-icon v-if="detail.orderFrom == 1" name="weixin-circle-fill" size="18" color="#22ac38"
  45. @click="handleWeixin"></u-icon>
  46. <u-icon v-if="detail.orderFrom == 2" name="zhifubao-circle-fill" size="18" color="#999"
  47. @click="handleWeixin"></u-icon>
  48. </view>
  49. </view>
  50. <view class="info-item">
  51. <text class="label">发货地址</text>
  52. <text class="content">{{ detail.sendAddress }}</text>
  53. </view>
  54. <view class="info-item">
  55. <text class="label">收货仓库</text>
  56. <text class="content">{{ detail.recipientAddress }}-{{ detail.recipientGodown }}-{{
  57. detail.recipientName
  58. }}</text>
  59. </view>
  60. </view>
  61. <u-modal :show="showModal" title="编辑内部备注" :showCancelButton="true" @confirm="confirmRemark"
  62. @cancel="handleCancel">
  63. <view class="modal-content w100" @click="playGlobalSound">
  64. <u-textarea v-model="internalRemark" placeholder="编辑内部备注" autoHeight
  65. style="min-height: 100px"></u-textarea>
  66. <view class="mt-20 common-title">快速填入</view>
  67. <view class="quick-fill mt-16">
  68. <u-tag class="mr-10 mb-10" @click="fillRemark('少书给客服')" text="少书给客服"></u-tag>
  69. <u-tag class="mr-10 mb-10" @click="fillRemark('多书给客服')" text="多书给客服"></u-tag>
  70. <u-tag class="mr-10 mb-10" @click="fillRemark('子母件')" text="子母件"></u-tag>
  71. <u-tag class="mr-10 mb-10" @click="fillRemark('书单不符给客服')" text="书单不符给客服"></u-tag>
  72. <u-tag class="mr-10 mb-10" @click="fillRemark('需理赔给客服')" text="需理赔给客服"></u-tag>
  73. </view>
  74. </view>
  75. </u-modal>
  76. <u-action-sheet :show="showActionSheet" :show-cancel="true" :actions="actionSheetActions" title="发送短信"
  77. @close="closeActionSheet" @select="selectAction">
  78. </u-action-sheet>
  79. <!-- 短信推送弹窗 -->
  80. <SmsModal ref="smsModalRef" v-model="showSmsModal" @success="handleSmsSuccess" />
  81. </view>
  82. </template>
  83. <script setup>
  84. import { defineProps, computed, ref, watch } from "vue";
  85. import SmsModal from "./SmsModal.vue";
  86. const props = defineProps({
  87. orderId: String,
  88. estimatedAmount: Number,
  89. userNote: String,
  90. detail: Object,
  91. // Add more props as needed
  92. });
  93. let finalExpressList = { 1: "顺丰快递", 2: "京东快递", 3: "德邦快递" };
  94. let finalExpressText = computed(() => {
  95. return props.detail.finalExpress
  96. ? finalExpressList[props.detail.finalExpress]
  97. : "";
  98. });
  99. function playGlobalSound() {
  100. uni.$u.playClickSound();
  101. }
  102. const statusEnum = {
  103. 0: "创建",
  104. 1: "用户删除",
  105. 2: "下单(待初审)",
  106. 3: "初审(待取书)",
  107. 4: "初审未通过",
  108. 5: "快递取书(待签收)",
  109. 6: "快递签收(待收货)",
  110. 7: "物流签收(路由异常)",
  111. 8: "仓库收货(待审核)",
  112. 9: "审核中(审核未提交)",
  113. 10: "已审核(待付款)",
  114. 11: "已完成",
  115. };
  116. let statusText = computed(() => {
  117. return statusEnum[props.detail.status] || "未知状态";
  118. });
  119. const maskedSendMobile = computed(() => {
  120. if (props.detail.sendMobile && props.detail.sendMobile.length === 11) {
  121. return props.detail.sendMobile.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2");
  122. }
  123. return props.detail.sendMobile;
  124. });
  125. function copyToClipboard(text) {
  126. uni.setClipboardData({
  127. data: text,
  128. success: function () {
  129. uni.showToast({
  130. title: "复制成功",
  131. icon: "success",
  132. });
  133. },
  134. fail: function (err) {
  135. console.error("Could not copy text: ", err);
  136. },
  137. });
  138. }
  139. const showModal = ref(false);
  140. const internalRemark = ref("");
  141. function fillRemark(text) {
  142. internalRemark.value = text;
  143. }
  144. const remarkInfo = ref({});
  145. function handleRemark() {
  146. showModal.value = true;
  147. remarkInfo.value = props.detail.manageRemark?.[0] || {};
  148. internalRemark.value = remarkInfo.value.remark || "";
  149. }
  150. //关闭弹窗
  151. function handleCancel() {
  152. showModal.value = false;
  153. playGlobalSound();
  154. }
  155. const emit = defineEmits(["refresh"]);
  156. function confirmRemark() {
  157. playGlobalSound();
  158. // Logic to save the remark
  159. uni.$u.http
  160. .post("/app/orderinfo/setManageRemark", {
  161. orderId: props.detail.orderId,
  162. remark: internalRemark.value,
  163. id: remarkInfo.value.id,
  164. })
  165. .then((res) => {
  166. if (res.code == 200) {
  167. uni.$u.toast("保存成功");
  168. uni.$u.ttsModule.speak("保存成功");
  169. showModal.value = false;
  170. emit("refresh");
  171. } else {
  172. uni.$u.toast(res.msg);
  173. }
  174. });
  175. }
  176. // ActionSheet相关变量和方法
  177. const showActionSheet = ref(false);
  178. const actionSheetActions = ref([
  179. {
  180. name: "发送短信(手机发送)",
  181. value: "sms",
  182. },
  183. {
  184. name: "一键发送短信(服务器发送)",
  185. value: "server_sms",
  186. },
  187. {
  188. name: "QQ",
  189. value: "qq",
  190. },
  191. {
  192. name: "微信",
  193. value: "wechat",
  194. },
  195. {
  196. name: "取消",
  197. value: "cancel",
  198. },
  199. ]);
  200. // 处理微信图标点击
  201. function handleWeixin() {
  202. playGlobalSound();
  203. showActionSheet.value = true;
  204. }
  205. // 关闭ActionSheet
  206. function closeActionSheet() {
  207. showActionSheet.value = false;
  208. }
  209. // 选择ActionSheet选项
  210. function selectAction(item) {
  211. playGlobalSound();
  212. showActionSheet.value = false;
  213. if (item.value === "server_sms") {
  214. // 发送短信功能
  215. handleSendSMS();
  216. } else if (item.value == "cancel") {
  217. closeActionSheet()
  218. } else {
  219. // 其他功能暂无开放
  220. uni.showToast({
  221. title: "此功能暂无开放",
  222. icon: "none",
  223. });
  224. }
  225. }
  226. // 短信弹窗相关
  227. const showSmsModal = ref(false);
  228. const smsModalRef = ref();
  229. // 发送短信功能
  230. function handleSendSMS() {
  231. playGlobalSound();
  232. // 打开短信弹窗
  233. if (smsModalRef.value && props.detail.orderId) {
  234. smsModalRef.value.handleOpen(props.detail.orderId);
  235. } else {
  236. uni.showToast({
  237. title: "订单信息异常",
  238. icon: "none",
  239. });
  240. }
  241. }
  242. // 短信发送成功回调
  243. function handleSmsSuccess() {
  244. uni.showToast({
  245. title: "短信发送成功",
  246. icon: "success",
  247. });
  248. uni.$u.ttsModule.speak("短信发送成功");
  249. }
  250. </script>
  251. <style lang="scss" scoped>
  252. .order-info {
  253. .info-item {
  254. display: flex;
  255. align-items: center;
  256. line-height: 42rpx;
  257. border-bottom: 1rpx solid #e5e5e5;
  258. font-size: 28rpx;
  259. }
  260. .label {
  261. width: 120px;
  262. text-align: center;
  263. padding: 20rpx 0;
  264. height: 100%;
  265. }
  266. .content {
  267. text-align: center;
  268. padding: 20rpx 20rpx;
  269. flex: 1;
  270. border-left: 1rpx solid #e5e5e5;
  271. min-height: 42px;
  272. box-sizing: border-box;
  273. }
  274. .border-left {
  275. border-left: 1rpx solid #e5e5e5;
  276. }
  277. .quick-fill {
  278. display: flex;
  279. flex-wrap: wrap;
  280. gap: 20rpx;
  281. .u-tag {
  282. margin: 0 10rpx 10rpx 0;
  283. }
  284. }
  285. }
  286. </style>