Pārlūkot izejas kodu

feat:运单列表修改,创建订单功能完成,首页banner接口对接,个人寄件页面UI功能完成,地址管理列表调整完成

颜琼丽 2 dienas atpakaļ
vecāks
revīzija
a557301809

+ 10 - 0
jd-logistics-ui-v3/src/api/logistics/banner.js

@@ -42,3 +42,13 @@ export function delBanner(bannerId) {
     method: 'delete'
   })
 }
+
+
+// 查询轮播图列表
+export function listIndexBanner(query) {
+  return request({
+    url: '/banner/listByType',
+    method: 'get',
+    params: query
+  })
+}

+ 10 - 0
jd-logistics-ui-v3/src/api/logistics/order.js

@@ -42,3 +42,13 @@ export function delOrder(waybillId) {
     method: 'delete'
   })
 }
+
+
+// 取消下单
+export function cancelOrder(data) {
+  return request({
+    url: '/system/order',
+    method: 'put',
+    data: data
+  })
+}

+ 32 - 20
jd-logistics-ui-v3/src/views/index.vue

@@ -19,29 +19,30 @@
               >
                 <!-- 背景图片 -->
                 <img
-                    :src="item.image"
-                    :alt="item.title"
+                    :src="item.imageUrl"
+                    :alt="item.bannerName"
                     class="carousel-bg-img"
                 />
                 <!-- 遮罩层 -->
                 <div class="carousel-overlay"></div>
 
                 <!-- 内容 -->
-                <div class="carousel-content">
-                  <h2 class="carousel-title">{{ item.title }}</h2>
-                  <p class="carousel-desc">{{ item.desc }}</p>
-                  <el-button
-                      type="primary"
-                      size="large"
-                      class="carousel-button"
-                      @click.stop="handleQueryClick(item)"
-                  >
-                    <span style="font-weight: 500;">立即查询</span>
-                    <el-icon style="margin-left: 8px;">
-                      <ArrowRight />
-                    </el-icon>
-                  </el-button>
-                </div>
+<!--                <div class="carousel-content">-->
+<!--                  <h2 class="carousel-title">{{ item.title }}</h2>-->
+<!--                  <p class="carousel-desc">{{ item.desc }}</p>-->
+<!--                  <el-button-->
+<!--                      type="primary"-->
+<!--                      size="large"-->
+<!--                      class="carousel-button"-->
+<!--                      @click.stop="handleQueryClick(item)"-->
+<!--                  >-->
+<!--                    <span style="font-weight: 500;">立即查询</span>-->
+<!--                    <el-icon style="margin-left: 8px;">-->
+<!--                      <ArrowRight />-->
+<!--                    </el-icon>-->
+<!--                  </el-button>-->
+<!--                </div>-->
+
               </div>
             </div>
 
@@ -117,6 +118,8 @@ import PieChart from './dashboard/PieChart.vue'
 import PieChartOne from "./dashboard/PieChart-one.vue";
 import BarChart from './dashboard/BarChart.vue'
 
+import {listIndexBanner} from "../api/logistics/banner.js";
+
 // 轮播图数据
 const bannerList = ref([
   {
@@ -232,8 +235,9 @@ const resetAutoPlay = () => {
 // 点击事件
 const handleBannerClick = (item) => {
   console.log('Banner clicked:', item)
-  // 这里可以添加跳转逻辑
-  // window.location.href = item.link
+  if(item.linkUrl && item.linkUrl.startsWith('http')){
+    window.open(item.linkUrl, '_blank')
+  }
 }
 
 const handleQueryClick = (item) => {
@@ -242,9 +246,17 @@ const handleQueryClick = (item) => {
   // 例如:emit('query', item.queryType)
 }
 
+const getBannerList = () =>{
+  // const params = {sysType:0,delFlag:0 } //系统类型(0PC管理、1小程) 删除标志(0代表存在 2代表删除
+  listIndexBanner().then(response => {
+    bannerList.value = response.rows
+    startAutoPlay()
+  })
+}
+
 // 生命周期
 onMounted(() => {
-  startAutoPlay()
+  getBannerList()
 })
 
 onUnmounted(() => {

+ 2 - 2
jd-logistics-ui-v3/src/views/login.vue

@@ -82,8 +82,8 @@ const router = useRouter()
 const { proxy } = getCurrentInstance()
 
 const loginForm = ref({
-  username: "admin",
-  password: "admin123",
+  username: "",
+  password: "",
   rememberMe: false,
   code: "",
   uuid: ""

+ 171 - 139
jd-logistics-ui-v3/src/views/logistics/book/index.vue

@@ -1,85 +1,42 @@
 <template>
   <div class="app-container">
-    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
+    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="120px">
       <el-form-item label="公司名称" prop="companyName">
         <el-input
-          v-model="queryParams.companyName"
-          placeholder="请输入公司名称"
-          clearable
-          @keyup.enter="handleQuery"
+            v-model="queryParams.companyName"
+            placeholder="请输入公司名称"
+            clearable
+            @keyup.enter="handleQuery"
         />
       </el-form-item>
       <el-form-item label="联系人姓名" prop="contactName">
         <el-input
-          v-model="queryParams.contactName"
-          placeholder="请输入联系人姓名"
-          clearable
-          @keyup.enter="handleQuery"
+            v-model="queryParams.contactName"
+            placeholder="请输入联系人姓名"
+            clearable
+            @keyup.enter="handleQuery"
         />
       </el-form-item>
       <el-form-item label="联系人电话" prop="contactPhone">
         <el-input
-          v-model="queryParams.contactPhone"
-          placeholder="请输入联系人电话"
-          clearable
-          @keyup.enter="handleQuery"
+            v-model="queryParams.contactPhone"
+            placeholder="请输入联系人电话"
+            clearable
+            @keyup.enter="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="省" prop="provinceName">
-        <el-input
-          v-model="queryParams.provinceName"
-          placeholder="请输入省"
-          clearable
-          @keyup.enter="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="市" prop="cityName">
-        <el-input
-          v-model="queryParams.cityName"
-          placeholder="请输入市"
-          clearable
-          @keyup.enter="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="区/县" prop="countyName">
-        <el-input
-          v-model="queryParams.countyName"
-          placeholder="请输入区/县"
-          clearable
-          @keyup.enter="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="详细地址" prop="detailedAddress">
-        <el-input
-          v-model="queryParams.detailedAddress"
-          placeholder="请输入详细地址"
-          clearable
-          @keyup.enter="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="是否默认 0非默认1默认" prop="defaultFlag">
-        <el-input
-          v-model="queryParams.defaultFlag"
-          placeholder="请输入是否默认 0非默认1默认"
-          clearable
-          @keyup.enter="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="部门ID" prop="deptId">
-        <el-input
-          v-model="queryParams.deptId"
-          placeholder="请输入部门ID"
-          clearable
-          @keyup.enter="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="用户ID" prop="userId">
-        <el-input
-          v-model="queryParams.userId"
-          placeholder="请输入用户ID"
-          clearable
-          @keyup.enter="handleQuery"
-        />
+      <el-form-item label="是否默认" prop="defaultFlag">
+        <el-select
+            v-model="queryParams.defaultFlag"
+            placeholder="请选择是否是默认地址"
+        >
+          <el-option
+              v-for="dict in yes_or_no"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+          ></el-option>
+        </el-select>
       </el-form-item>
       <el-form-item>
         <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
@@ -90,40 +47,40 @@
     <el-row :gutter="10" class="mb8">
       <el-col :span="1.5">
         <el-button
-          type="primary"
-          plain
-          icon="Plus"
-          @click="handleAdd"
-          v-hasPermi="['system:book:add']"
+            type="primary"
+            plain
+            icon="Plus"
+            @click="handleAdd"
+            v-hasPermi="['system:book:add']"
         >新增</el-button>
       </el-col>
       <el-col :span="1.5">
         <el-button
-          type="success"
-          plain
-          icon="Edit"
-          :disabled="single"
-          @click="handleUpdate"
-          v-hasPermi="['system:book:edit']"
+            type="success"
+            plain
+            icon="Edit"
+            :disabled="single"
+            @click="handleUpdate"
+            v-hasPermi="['system:book:edit']"
         >修改</el-button>
       </el-col>
       <el-col :span="1.5">
         <el-button
-          type="danger"
-          plain
-          icon="Delete"
-          :disabled="multiple"
-          @click="handleDelete"
-          v-hasPermi="['system:book:remove']"
+            type="danger"
+            plain
+            icon="Delete"
+            :disabled="multiple"
+            @click="handleDelete"
+            v-hasPermi="['system:book:remove']"
         >删除</el-button>
       </el-col>
       <el-col :span="1.5">
         <el-button
-          type="warning"
-          plain
-          icon="Download"
-          @click="handleExport"
-          v-hasPermi="['system:book:export']"
+            type="warning"
+            plain
+            icon="Download"
+            @click="handleExport"
+            v-hasPermi="['system:book:export']"
         >导出</el-button>
       </el-col>
       <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
@@ -131,72 +88,79 @@
 
     <el-table v-loading="loading" :data="bookList" @selection-change="handleSelectionChange">
       <el-table-column type="selection" width="55" align="center" />
-      <el-table-column label="地址薄id" align="center" prop="addressId" />
-      <el-table-column label="公司名称" align="center" prop="companyName" />
-      <el-table-column label="联系人姓名" align="center" prop="contactName" />
-      <el-table-column label="联系人电话" align="center" prop="contactPhone" />
-      <el-table-column label="省" align="center" prop="provinceName" />
-      <el-table-column label="市" align="center" prop="cityName" />
-      <el-table-column label="区/县" align="center" prop="countyName" />
-      <el-table-column label="详细地址" align="center" prop="detailedAddress" />
-      <el-table-column label="是否默认 0非默认1默认" align="center" prop="defaultFlag" />
-      <el-table-column label="部门ID" align="center" prop="deptId" />
-      <el-table-column label="用户ID" align="center" prop="userId" />
-      <el-table-column label="备注" align="center" prop="remark" />
-      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+      <el-table-column label="联系人姓名" align="center" prop="contactName" width="120"/>
+      <el-table-column label="联系人电话" align="center" prop="contactPhone" width="120"/>
+      <el-table-column label="公司名称" align="center" prop="companyName" width="180"/>
+      <el-table-column label="省/市/区(县)" align="center"  width="200">
+        <template #default="scope">
+          {{scope.row.provinceName}}/{{scope.row.cityName}}/{{scope.row.countyName}}
+        </template>
+      </el-table-column>
+      <el-table-column label="详细地址" align="center" prop="detailedAddress" width="250"/>
+      <el-table-column label="是否默认" align="center" prop="defaultFlag" width="80" >
+        <template #default="scope">
+          <dict-tag :options="yes_or_no" :value="scope.row.defaultFlag" />
+        </template>
+      </el-table-column>
+      <el-table-column label="创建时间" align="center" prop="createTime" width="180"/>
+      <el-table-column label="更新时间" align="center" prop="updateTime" width="180"/>
+      <el-table-column label="备注" align="center" prop="remark" width="180"/>
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" min-width="180">
         <template #default="scope">
           <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:book:edit']">修改</el-button>
           <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:book:remove']">删除</el-button>
         </template>
       </el-table-column>
     </el-table>
-    
+
     <pagination
-      v-show="total>0"
-      :total="total"
-      v-model:page="queryParams.pageNum"
-      v-model:limit="queryParams.pageSize"
-      @pagination="getList"
+        v-show="total>0"
+        :total="total"
+        v-model:page="queryParams.pageNum"
+        v-model:limit="queryParams.pageSize"
+        @pagination="getList"
     />
 
     <!-- 添加或修改地址簿管理对话框 -->
-    <el-dialog :title="title" v-model="open" width="500px" append-to-body>
-      <el-form ref="bookRef" :model="form" :rules="rules" label-width="80px">
+    <el-dialog :title="title" v-model="open" width="800px" append-to-body>
+      <el-form ref="bookRef" :model="form" :rules="rules" label-width="120px">
         <el-form-item label="公司名称" prop="companyName">
-          <el-input v-model="form.companyName" placeholder="请输入公司名称" />
+          <el-input v-model="form.companyName" placeholder="请输入公司名称" maxlength="20" show-word-limit />
         </el-form-item>
         <el-form-item label="联系人姓名" prop="contactName">
-          <el-input v-model="form.contactName" placeholder="请输入联系人姓名" />
+          <el-input v-model="form.contactName" placeholder="请输入联系人姓名" maxlength="20" show-word-limit />
         </el-form-item>
         <el-form-item label="联系人电话" prop="contactPhone">
-          <el-input v-model="form.contactPhone" placeholder="请输入联系人电话" />
+          <el-input v-model="form.contactPhone" placeholder="请输入联系人电话"  show-word-limit />
         </el-form-item>
-        <el-form-item label="省" prop="provinceName">
-          <el-input v-model="form.provinceName" placeholder="请输入省" />
-        </el-form-item>
-        <el-form-item label="市" prop="cityName">
-          <el-input v-model="form.cityName" placeholder="请输入市" />
-        </el-form-item>
-        <el-form-item label="区/县" prop="countyName">
-          <el-input v-model="form.countyName" placeholder="请输入区/县" />
+        <el-form-item label="省市区" prop="region">
+          <RegionCascader
+              v-model="form.region"
+              placeholder="请选择省市区"
+              size="large"
+              :clearable="true"
+              @change="handleRegionChange"
+          />
         </el-form-item>
         <el-form-item label="详细地址" prop="detailedAddress">
-          <el-input v-model="form.detailedAddress" placeholder="请输入详细地址" />
-        </el-form-item>
-        <el-form-item label="是否默认 0非默认1默认" prop="defaultFlag">
-          <el-input v-model="form.defaultFlag" placeholder="请输入是否默认 0非默认1默认" />
+          <el-input v-model="form.detailedAddress" placeholder="请输入详细地址" maxlength="100" show-word-limit />
         </el-form-item>
-        <el-form-item label="部门ID" prop="deptId">
-          <el-input v-model="form.deptId" placeholder="请输入部门ID" />
-        </el-form-item>
-        <el-form-item label="用户ID" prop="userId">
-          <el-input v-model="form.userId" placeholder="请输入用户ID" />
+        <el-form-item label="是否默认" prop="defaultFlag">
+          <el-select
+              v-model="form.defaultFlag"
+              placeholder="请选择是否是默认地址"
+              size="large"
+          >
+            <el-option
+                v-for="dict in yes_or_no"
+                :key="dict.value"
+                :label="dict.label"
+                :value="dict.value"
+            ></el-option>
+          </el-select>
         </el-form-item>
         <el-form-item label="备注" prop="remark">
-          <el-input v-model="form.remark" placeholder="请输入备注" />
-        </el-form-item>
-        <el-form-item label="删除标志" prop="delFlag">
-          <el-input v-model="form.delFlag" placeholder="请输入删除标志" />
+          <el-input v-model="form.remark" placeholder="请输入备注" maxlength="500" show-word-limit type="textarea" :rows="3" />
         </el-form-item>
       </el-form>
       <template #footer>
@@ -211,8 +175,12 @@
 
 <script setup name="Book">
 import { listBook, getBook, delBook, addBook, updateBook } from "@/api/logistics/book"
+import RegionCascader from '@/components/RegionCascader.vue'
+// 导入本地 JSON 数据
+import { getCodesByNames  } from '@/utils/area-data.js'
 
 const { proxy } = getCurrentInstance()
+const {  yes_or_no } = proxy.useDict("yes_or_no")
 
 const bookList = ref([])
 const open = ref(false)
@@ -224,6 +192,26 @@ const multiple = ref(true)
 const total = ref(0)
 const title = ref("")
 
+// 手机号校验规则
+const validatePhone = (rule, value, callback) => {
+  if (!value) {
+    callback(new Error('联系人电话不能为空'))
+  } else if (!/^1[3-9]\d{9}$/.test(value)) {
+    callback(new Error('请输入正确的手机号格式'))
+  } else {
+    callback()
+  }
+}
+
+// 省市区校验规则
+const validateRegion = (rule, value, callback) => {
+  if (!value || value.length !== 3) {
+    callback(new Error('请选择完整的省市区'))
+  } else {
+    callback()
+  }
+}
+
 const data = reactive({
   form: {},
   queryParams: {
@@ -241,6 +229,30 @@ const data = reactive({
     userId: null,
   },
   rules: {
+    companyName: [
+      { required: true, message: '公司名称不能为空', trigger: 'blur' },
+      { min: 1, max: 100, message: '公司名称长度在 1 到 100 个字符', trigger: 'blur' }
+    ],
+    contactName: [
+      { required: true, message: '联系人姓名不能为空', trigger: 'blur' },
+      { min: 1, max: 50, message: '联系人姓名长度在 1 到 50 个字符', trigger: 'blur' }
+    ],
+    contactPhone: [
+      { required: true, validator: validatePhone, trigger: 'blur' }
+    ],
+    region: [
+      { required: true, validator: validateRegion, trigger: 'change' }
+    ],
+    detailedAddress: [
+      { required: true, message: '详细地址不能为空', trigger: 'blur' },
+      { min: 1, max: 200, message: '详细地址长度在 1 到 200 个字符', trigger: 'blur' }
+    ],
+    defaultFlag: [
+      { required: true, message: '是否默认不能为空', trigger: 'change' }
+    ],
+    remark: [
+      { max: 500, message: '备注长度不能超过 500 个字符', trigger: 'blur' }
+    ]
   }
 })
 
@@ -272,6 +284,7 @@ function reset() {
     provinceName: null,
     cityName: null,
     countyName: null,
+    region:[],
     detailedAddress: null,
     defaultFlag: null,
     deptId: null,
@@ -305,6 +318,14 @@ function handleSelectionChange(selection) {
   multiple.value = !selection.length
 }
 
+const handleRegionChange = (regionInfo) => {
+  console.log('地区信息:', regionInfo)
+  form.value.provinceName = regionInfo.provinceName || ''
+  form.value.cityName = regionInfo.cityName || ''
+  form.value.countyName = regionInfo.districtName || ''
+  form.value.region = [regionInfo.provinceCode,regionInfo.cityCode,regionInfo.districtCode]
+}
+
 /** 新增按钮操作 */
 function handleAdd() {
   reset()
@@ -318,6 +339,8 @@ function handleUpdate(row) {
   const _addressId = row.addressId || ids.value
   getBook(_addressId).then(response => {
     form.value = response.data
+    form.value.region = getCodesByNames(response.data.provinceName,response.data.cityName,response.data.countyName)
+    form.value.defaultFlag = form.value.defaultFlag + ''
     open.value = true
     title.value = "修改地址簿管理"
   })
@@ -327,18 +350,27 @@ function handleUpdate(row) {
 function submitForm() {
   proxy.$refs["bookRef"].validate(valid => {
     if (valid) {
+      // 确保省市区信息正确设置
+      if (form.value.region && form.value.region.length === 3) {
+        // 这里确保省市区名称已通过handleRegionChange设置
+        if (!form.value.provinceName || !form.value.cityName || !form.value.countyName) {
+          proxy.$modal.msgError("请选择完整的省市区信息")
+          return
+        }
+      }
+
       if (form.value.addressId != null) {
         updateBook(form.value).then(response => {
           proxy.$modal.msgSuccess("修改成功")
           open.value = false
           getList()
-        })
+        }).catch(() => {})
       } else {
         addBook(form.value).then(response => {
           proxy.$modal.msgSuccess("新增成功")
           open.value = false
           getList()
-        })
+        }).catch(() => {})
       }
     }
   })
@@ -347,7 +379,7 @@ function submitForm() {
 /** 删除按钮操作 */
 function handleDelete(row) {
   const _addressIds = row.addressId || ids.value
-  proxy.$modal.confirm('是否确认删除地址簿管理编号为"' + _addressIds + '"的数据项?').then(function() {
+  proxy.$modal.confirm('是否确认删除地址').then(function() {
     return delBook(_addressIds)
   }).then(() => {
     getList()
@@ -363,4 +395,4 @@ function handleExport() {
 }
 
 getList()
-</script>
+</script>

+ 20 - 21
jd-logistics-ui-v3/src/views/logistics/order/createOrder.vue

@@ -335,7 +335,7 @@
       </div>
       <div class="form-content">
         <div class="value-services-grid">
-          <div class="service-item" v-if="productType == '1'">
+          <div class="service-item" v-if="productType == '1' || productType == '2'">
             <span class="service-label">包装服务</span>
             <el-switch
                 v-model="valueServices.packaging"
@@ -550,11 +550,6 @@ const deliveryRules = {
 // 寄件方式表单引用
 const deliveryFormRef = ref(null)
 
-const deliveryType = [
-  { label: '特快', value: 'express' },
-  { label: '标快', value: 'standard' }
-]
-
 // 物品信息
 const itemInfo = reactive({
   type: '',
@@ -756,7 +751,7 @@ const handleSenderRegionChange = (regionInfo) => {
   // 同时更新省份、城市、区县名称
   sender.provinceName = regionInfo.provinceName || ''
   sender.cityName = regionInfo.cityName || ''
-  sender.countyName = regionInfo.countyName || ''
+  sender.countyName = regionInfo.districtName || ''
   sender.region = [regionInfo.provinceCode,regionInfo.cityCode,regionInfo.districtCode]
 
   // 如果是从地址簿选择的地址,修改后清空addressId
@@ -770,7 +765,7 @@ const handleReceiverRegionChange = (regionInfo) => {
   console.log('收件人地区信息:', regionInfo)
   receiver.provinceName = regionInfo.provinceName || ''
   receiver.cityName = regionInfo.cityName || ''
-  receiver.countyName = regionInfo.countyName || ''
+  receiver.countyName = regionInfo.districtName || ''
   receiver.region = [regionInfo.provinceCode,regionInfo.cityCode,regionInfo.districtCode]
 
   // 如果是从地址簿选择的地址,修改后清空addressId
@@ -1129,17 +1124,17 @@ const submitOrder = async () => {
     isReceiptCollect: valueServices.signReturn ? signReturnType.value : null
   }
 
-  if(productType == '1'){ //京东
+  if(productType.value == '1'){ //京东
     services = {
-      isPack:valueServices.isPack,
+      isPack:valueServices.packaging ? true : null,
       guaranteeMoney:valueServices.insurance ? insuranceAmount.value : null,
-      isReceiptCollect: valueServices.signReturn ? signReturnType.value : null
+      isReceiptCollect: valueServices.signReturn ? true : null
     }
   }else {
     services = {
-      ...valueServices,
-      insuranceAmount: valueServices.insurance ? insuranceAmount.value : null,
-      signReturnType: valueServices.signReturn ? signReturnType.value : null
+      isPack:valueServices.packaging ? true : null,
+      guaranteeMoney:valueServices.insurance ? insuranceAmount.value : null,
+      isReceiptCollect: valueServices.signReturn ? true : null
     }
   }
 
@@ -1152,12 +1147,12 @@ const submitOrder = async () => {
     senderCity:sender.cityName,
     senderCounty:sender.countyName,
     senderAddress:sender.detailedAddress,
-    receiverName:sender.contactName,
-    receiverPhone:sender.contactPhone,
-    receiverProvince:sender.provinceName,
-    receiverCity:sender.cityName,
-    receiverCounty:sender.countyName,
-    receiverAddress:sender.detailedAddress,
+    receiverName:receiver.contactName,
+    receiverPhone:receiver.contactPhone,
+    receiverProvince:receiver.provinceName,
+    receiverCity:receiver.cityName,
+    receiverCounty:receiver.countyName,
+    receiverAddress:receiver.detailedAddress,
 
     goodsName:itemInfo.type,
     goodsWeight:itemInfo.weight,
@@ -1310,7 +1305,7 @@ onMounted(() => {
   border: none;
   box-shadow: none !important;
 }
-el-input-group__append
+
 :deep(.fixed-input .el-input__inner),
 :deep(.fixed-input .el-cascader .el-input__inner),
 :deep(.fixed-input .el-select .el-select__wrapper),
@@ -1610,6 +1605,10 @@ el-input-group__append
 .insurance-input-wrapper {
   flex: 1;
   min-width: 200px;
+
+  :deep(.el-input-group__append){
+    box-shadow: none;
+  }
 }
 
 .insurance-input {

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 575 - 436
jd-logistics-ui-v3/src/views/logistics/order/index.vue


+ 386 - 0
jd-logistics-ui-v3/src/views/logistics/order/personal.vue

@@ -0,0 +1,386 @@
+<template>
+  <div class="personal-shipping-container">
+    <div class="page-header">
+      <h2 class="page-title">个人寄件物流公司选择</h2>
+      <!--      <p class="page-description">请选择您要使用的物流服务</p>-->
+    </div>
+
+    <div class="logistics-company-list">
+      <!-- 顺丰物流 -->
+      <div class="company-card" :class="{ 'selected': selectedCompany === 'sf' }" @click="selectCompany('sf')">
+        <div class="company-header">
+          <div class="company-logo sf-logo">
+            <img src="../../../assets/images/logo-sf.png"/>
+          </div>
+          <div class="company-name">
+            <h3>顺丰物流</h3>
+            <!--            <el-tag type="success" size="small" class="recommend-tag">推荐</el-tag>-->
+          </div>
+          <div class="selection-indicator" v-if="selectedCompany === 'sf'">
+<!--            <el-icon color="#409EFF" size="24">-->
+<!--              <Select />-->
+<!--            </el-icon>-->
+          </div>
+        </div>
+
+        <div class="company-intro">
+          <span>顺丰物流提供高效、安全、便捷的快递服务,覆盖全国各大城市,支持次日达、隔日达等多种时效选择,是个人寄件的优质选择。</span>
+        </div>
+
+        <div class="company-footer">
+          <el-button type="primary" @click.stop="goToSFWebsite" class="jump-btn">
+            点击跳转
+          </el-button>
+        </div>
+      </div>
+
+      <!-- 京东物流 -->
+      <div class="company-card" :class="{ 'selected': selectedCompany === 'jd' }" @click="selectCompany('jd')">
+        <div class="company-header">
+          <div class="company-logo jd-logo">
+            <img src="../../../assets/images/logo-jd.png"/>
+          </div>
+          <div class="company-name">
+            <h3>京东物流</h3>
+          </div>
+          <div class="selection-indicator" v-if="selectedCompany === 'jd'">
+<!--            <el-icon color="#409EFF" size="24">-->
+<!--              <Select />-->
+<!--            </el-icon>-->
+          </div>
+        </div>
+
+        <div class="company-intro">
+          <span>京东物流提供快速、可靠的快递服务,依托京东强大的物流网络,覆盖全国各级城市,支持上门取件、快递跟踪等全方位服务,满足个人寄件需求。</span>
+        </div>
+
+        <div class="company-footer">
+          <el-button type="primary" @click.stop="goToJDWebsite" class="jump-btn">
+            点击跳转
+          </el-button>
+        </div>
+      </div>
+    </div>
+
+
+  </div>
+</template>
+
+<script setup>
+import { ref, computed } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import { Select, ArrowRight, InfoFilled } from '@element-plus/icons-vue'
+
+// 选中的物流公司
+const selectedCompany = ref('')
+const confirmDialogVisible = ref(false)
+
+// 选择物流公司
+const selectCompany = (company) => {
+  selectedCompany.value = company
+  if(company === 'sf'){
+    goToSFWebsite()
+  }else {
+    goToJDWebsite()
+  }
+  // ElMessage.success(`已选择${company === 'sf' ? '顺丰物流' : '京东物流'}`)
+}
+
+// 跳转到顺丰物流网站
+const goToSFWebsite = () => {
+  // 实际项目中这里应该是顺丰物流的跳转链接
+  window.open('https://www.sf-express.com', '_blank')
+}
+
+// 跳转到京东物流网站
+const goToJDWebsite = () => {
+  // 实际项目中这里应该是京东物流的跳转链接
+  window.open('https://www.jdl.cn', '_blank')
+}
+
+// 确认选择
+const confirmSelection = () => {
+  if (!selectedCompany.value) {
+    ElMessage.warning('请先选择物流公司')
+    return
+  }
+
+  confirmDialogVisible.value = true
+}
+
+// 重置选择
+const resetSelection = () => {
+  if (selectedCompany.value) {
+    ElMessageBox.confirm('确定要重置选择的物流公司吗?', '重置确认', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning',
+    })
+        .then(() => {
+          selectedCompany.value = ''
+          ElMessage.info('已重置选择')
+        })
+        .catch(() => {
+          // 用户取消操作
+        })
+  } else {
+    ElMessage.info('当前未选择任何物流公司')
+  }
+}
+
+// 处理对话框关闭
+const handleDialogClose = (done) => {
+  ElMessageBox.confirm('确定要取消选择吗?', '提示', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    type: 'warning',
+  })
+      .then(() => {
+        done()
+      })
+      .catch(() => {
+        // 用户取消操作
+      })
+}
+
+// 跳转到物流公司寄件页面
+const proceedToShipping = () => {
+  confirmDialogVisible.value = false
+
+  // 模拟跳转逻辑
+  ElMessage.success(`正在跳转到${selectedCompanyText.value}寄件页面...`)
+
+  // 实际项目中这里应该是路由跳转或打开新页面
+  setTimeout(() => {
+    if (selectedCompany.value === 'sf') {
+      window.open('https://www.sf-express.com/cn/sc/dynamic_function/waybill/waybill_standard/', '_blank')
+    } else if (selectedCompany.value === 'jd') {
+      window.open('https://www.jdl.cn/#/', '_blank')
+    }
+  }, 1000)
+}
+
+// 计算选中的物流公司文本
+const selectedCompanyText = computed(() => {
+  return selectedCompany.value === 'sf' ? '顺丰物流' :
+      selectedCompany.value === 'jd' ? '京东物流' : ''
+})
+</script>
+
+<style scoped>
+.personal-shipping-container {
+  padding: 20px;
+  width: 100%;
+  height: 100%;
+  background: #F5F7FA;
+}
+
+.page-header {
+  text-align: center;
+  margin-bottom: 40px;
+  padding-bottom: 20px;
+}
+
+.page-title {
+  font-size: 40px;
+  color: #333;
+  margin-bottom: 10px;
+  font-weight: bold;
+}
+
+.page-description {
+  font-size: 16px;
+  color: #666;
+}
+
+.logistics-company-list {
+  display: flex;
+  gap: 50px;
+  justify-content: center;
+  margin-bottom: 40px;
+}
+
+.company-card {
+  width: 432px;
+  height: 270px;
+  padding: 24px;
+  background: #FFFFFF;
+  border-radius: 16px;
+  transition: all 0.3s ease;
+  cursor: pointer;
+  display: flex;
+  flex-direction: column;
+  position: relative;
+  border: 2px solid transparent;
+}
+
+.company-card:hover {
+  //border-color: #c0e0ff;
+  transform: translateY(-5px);
+  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
+}
+
+.company-card.selected {
+  //border-color: #409EFF;
+  //background-color: #f5f9ff;
+}
+
+.company-header {
+  display: flex;
+  align-items: center;
+  margin-bottom: 20px;
+  flex-shrink: 0;
+}
+
+.company-logo {
+  width: 60px;
+  height: 60px;
+  border-radius: 10px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-right: 20px;
+  font-weight: bold;
+  font-size: 22px;
+  color: white;
+  img{
+    width: 60px;
+    height: 60px;
+  }
+}
+
+.sf-logo {
+  width: 60px;
+  height: 60px;
+  /*background: linear-gradient(135deg, #1e5dd9, #2a7fff);*/
+}
+
+.jd-logo {
+  width: 60px;
+  height: 60px;
+  /*background: linear-gradient(135deg, #e6181c, #ff3b30);*/
+}
+
+.company-name {
+  flex: 1;
+  display: flex;
+  align-items: center;
+}
+
+.company-name h3 {
+  font-size: 20px;
+  font-weight: bold;
+  color: #333;
+  margin: 0 15px 0 0;
+}
+
+.recommend-tag {
+  font-size: 12px;
+}
+
+.selection-indicator {
+  color: #409EFF;
+}
+
+.company-intro {
+  flex: 1;
+  overflow: hidden;
+  margin-bottom: 20px;
+}
+
+.company-intro span {
+  display: -webkit-box;
+  -webkit-line-clamp: 4;
+  -webkit-box-orient: vertical;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  font-weight: 400;
+  font-size: 16px;
+  color: #666666;
+  line-height: 24px;
+  text-align: left;
+}
+
+.company-footer {
+  flex-shrink: 0;
+  text-align: center;
+  margin-top: auto;
+}
+
+.jump-btn {
+  width: 100%;
+  padding: 12px;
+  font-size: 16px;
+}
+
+.action-buttons {
+  display: flex;
+  justify-content: center;
+  gap: 20px;
+  padding-top: 30px;
+  border-top: 1px solid #eaeaea;
+}
+
+.confirm-dialog-content {
+  text-align: center;
+  padding: 20px 0;
+}
+
+.confirm-icon {
+  margin-bottom: 20px;
+}
+
+.selected-company-name {
+  color: #409EFF;
+  font-weight: bold;
+  font-size: 18px;
+}
+
+/* 响应式设计 */
+@media (max-width: 768px) {
+  .logistics-company-list {
+    flex-direction: column;
+    align-items: center;
+  }
+
+  .company-card {
+    width: 100%;
+    max-width: 432px;
+    margin-bottom: 20px;
+  }
+}
+
+@media (max-width: 576px) {
+  .personal-shipping-container {
+    padding: 15px;
+  }
+
+  .page-title {
+    font-size: 24px;
+  }
+
+  .logistics-company-list {
+    gap: 20px;
+  }
+
+  .company-card {
+    padding: 20px;
+    height: 250px;
+  }
+
+  .company-logo {
+    width: 50px;
+    height: 50px;
+    margin-right: 15px;
+  }
+
+  .company-logo img {
+    width: 50px;
+    height: 50px;
+  }
+
+  .company-name h3 {
+    font-size: 18px;
+  }
+}
+</style>