mayf
2024-08-26 4f92f67026dbb26b208e59105bebe206b71e43c8
订单,售后部分同步
已修改7个文件
已添加3个文件
506 ■■■■ 文件已修改
assets/main.scss 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assets/variable.scss 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
components/order/after-sale-table.vue 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components/order/video-list.vue 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
components/simple-text.vue 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
layouts/default.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/order/after-sale/_action/_id.vue 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/order/after-sale/index.vue 53 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/order/list/_id.vue 49 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/shop/list.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assets/main.scss
@@ -120,4 +120,10 @@
  background-color: #fff;
  padding: 24px;
  border-radius: 4px;
  &__line {
    width: calc(100% + 48px);
    height: 10px;
    background-color: $bg-color;
    margin: 20px -24px;
  }
}
assets/variable.scss
@@ -6,7 +6,7 @@
$success-color: #67c23a;
$padding-vertical: 24px;
$padding-horizontal: 24px;
$bg-color: #f5f6fa;
$bg-color: #ebf2f9;
$page-padding: 20px;
$danger-color: rgb(245, 108, 108);
$warning-color: #e6a23c;
components/order/after-sale-table.vue
对比新文件
@@ -0,0 +1,144 @@
<template>
  <div class="after-sale-table">
    <div class="table-header">
      <div class="table-th">商品信息</div>
      <div class="table-th">合计详情</div>
      <div class="table-th !flex-none w-120">供应商信息</div>
      <div class="table-th">收货人信息</div>
      <div class="table-th !flex-none w-180">操作</div>
    </div>
    <div v-for="item in list" :key="item.id" class="table-item">
      <div class="table-item__title">
        <span class="font-bold">订单号:{{ item.orderNo }}</span>
        <span class="font-bold">售后单号:{{ item.salesNo }}</span>
        <span>申请时间:{{ item.createTime }}</span>
        <span
          >售后状态:<span
            :class="{ 'text-primary': item.status === 'PENDING' }"
            >{{ item.statusStr }}</span
          ></span
        >
        <el-tag v-if="item.title" type="danger" size="mini" class="ml-4"
          >第二次售后</el-tag
        >
      </div>
      <div class="table-body">
        <div class="table-td">
          <div class="flex">
            <el-bus-image :src="item.flowerCover" class="w-60 h-60 mr-8" />
            <div class="leading-20">
              <div class="text-14 font-bold">
                {{ item.flowerName }} × {{ item.flowerNum }}
              </div>
              <div class="leading-20">
                <span>等级:{{ item.flowerLevelStr }}</span>
                <span class="ml-8">颜色:{{ item.flowerColor }}</span>
              </div>
              <div class="leading-20">
                <span>单价:¥{{ item.price }}</span>
                <span class="ml-8">订单总额:¥{{ item.total }}</span>
              </div>
            </div>
          </div>
        </div>
        <div class="table-td">
          <div class="leading-20">申请数量:{{ item.num }}</div>
          <div class="leading-20">实际退款:{{ item.totalFee }}</div>
          <div class="leading-20 flex">
            申请理由:
            <div class="flex-1 text-overflow-2 w-0">{{ item.reason }}</div>
          </div>
        </div>
        <div class="table-td !flex-none w-120 flex items-center">
          {{ item.supplierName }}
        </div>
        <div class="table-td">
          <div class="leading-20">姓名:{{ item.customer }}</div>
          <div class="leading-20">联系方式:{{ item.customerTel }}</div>
          <div class="leading-20 flex">
            用户地址:
            <div class="flex-1 w-0">
              {{ item.customerProvince }}{{ item.customerCity
              }}{{ item.customerRegion }}{{ item.customerAddress }}
            </div>
          </div>
        </div>
        <div class="table-td !flex-none w-180 flex items-center">
          <el-button type="text" @click="onDetail(item)">查看详情</el-button>
          <el-button
            v-if="item.status === 'PENDING'"
            type="text"
            @click="onHandle(item)"
            >售后处理</el-button
          >
        </div>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  props: {
    list: {
      type: Array,
      default: () => [],
    },
  },
  methods: {
    onDetail(item) {
      this.$emit('detail', item)
    },
    onHandle(item) {
      this.$emit('handle', item)
    },
  },
}
</script>
<style lang="scss" scoped>
.after-sale-table {
  .table-header {
    display: flex;
    align-items: center;
    font-size: 14px;
    color: $main-title-color;
    background-color: #f4f4f5;
    .table-th {
      flex: 1;
      height: 45px;
      line-height: 45px;
      padding: 0 10px;
      font-weight: bold;
    }
  }
  .table-item {
    margin-top: 10px;
    border-bottom: 1px solid #eee;
    &__title {
      height: 35px;
      line-height: 35px;
      background-color: #f4f4f5;
      font-size: 14px;
      color: $main-title-color;
      padding: 0 10px;
      & > span {
        margin-right: 10px;
      }
    }
    .table-body {
      display: flex;
      align-items: stretch;
      font-size: 12px;
      color: $main-title-color;
      .table-td {
        flex: 1;
        padding: 15px 10px;
        &:not(:last-child) {
          border-right: 1px solid #eee;
        }
      }
    }
  }
}
</style>
components/order/video-list.vue
对比新文件
@@ -0,0 +1,30 @@
<template>
  <div class="video-list">
    <video
      v-for="(item, index) in value"
      :key="index"
      controls
      width="300px"
      height="200"
      class="mr-20 mb-15"
    >
      <source :src="item" />
    </video>
  </div>
</template>
<script>
export default {
  props: {
    value: {
      type: Array,
      default: () => [],
    },
  },
}
</script>
<style lang="scss" scoped>
.video-list {
}
</style>
components/simple-text.vue
对比新文件
@@ -0,0 +1,29 @@
<template>
  <div class="simple-text" :class="{ 'is-primary': type === 'primary' }">
    {{ value }}
  </div>
</template>
<script>
export default {
  props: {
    value: {
      type: [String, Number],
      default: null,
    },
    type: {
      type: String,
      default: '',
    },
  },
}
</script>
<style lang="scss" scoped>
.simple-text {
  display: inline-block;
  &.is-primary {
    color: $primary-color;
  }
}
</style>
layouts/default.vue
@@ -67,7 +67,7 @@
  }
  &__main {
    flex: 1;
    background-color: #ebf2f9;
    background-color: $bg-color;
    overflow: auto;
    padding: 20px;
  }
pages/order/after-sale/_action/_id.vue
@@ -1,43 +1,18 @@
<template>
  <div v-loading="wholeLoading" class="base-page-wrapper sale-detail">
    <el-bus-title title="订单信息" size="small"></el-bus-title>
    <el-bus-form
      ref="form"
      label-width="auto"
      :content="formContent"
      readonly
    ></el-bus-form>
    <div
      v-if="detail.imageListFormat && detail.imageListFormat.length > 0"
      class="mb-20"
    >
      <el-bus-title title="售后图片" size="small"></el-bus-title>
      <el-bus-upload
        :value="detail.imageListFormat"
        disabled
        list-type="picture-card"
      ></el-bus-upload>
    </div>
    <div v-if="detail.videoList && detail.videoList.length > 0" class="mb-20">
      <el-bus-title title="售后视频" size="small"></el-bus-title>
      <video
        v-for="(item, index) in detail.videoList"
        :key="index"
        controls
        width="300px"
        height="200"
        class="mr-20 mb-15"
      >
        <source :src="item" />
      </video>
    </div>
    <el-bus-title title="售后处理" size="small"></el-bus-title>
    <el-bus-form
      ref="auditForm"
      label-width="auto"
      :content="auditFormContent"
      :readonly="!editable"
    ></el-bus-form>
    <el-bus-form ref="form" label-width="auto" :content="formContent" readonly>
      <template #id:baseInfo>
        <el-bus-title title="基本信息" size="small"></el-bus-title>
      </template>
      <template #id:refundInfo>
        <div class="base-page-wrapper__line"></div>
        <el-bus-title title="退款信息" size="small"></el-bus-title>
      </template>
      <template #id:goodsInfo>
        <div class="base-page-wrapper__line"></div>
        <el-bus-title title="商品信息" size="small"></el-bus-title>
      </template>
    </el-bus-form>
    <div class="text-center mt-20">
      <el-button class="min-w-100" @click="goBack">返回</el-button>
    </div>
@@ -45,68 +20,110 @@
</template>
<script>
import AfterSaleItems from '@/components/order/after-sale-items.vue'
import VideoList from '@/components/order/video-list'
export default {
  data() {
    return {
      editable: false,
      detail: {},
      wholeLoading: false,
      loading: false,
      formContent: [
        {
          type: 'row',
          id: 'baseInfo',
          items: [
            { label: '订单号:', id: 'orderNo', type: 'input' },
            { label: '售后单号:', id: 'salesNo', type: 'input' },
            { label: '用户账号:', id: 'createName', type: 'input' },
            { label: '下单时间:', id: 'orderTime', type: 'input' },
            { label: '申请时间:', id: 'createTime', type: 'input' },
            { label: '审核时间:', id: 'auditTime', type: 'input' },
            { label: '收货人:', id: 'customer', type: 'input' },
            { label: '收货人电话:', id: 'customerTel', type: 'input' },
            { label: '收货地址:', id: 'customerWholeAddress', type: 'input' },
            { label: '下单时间:', id: 'createTime', type: 'input' },
            { label: '订单金额:', id: 'totalOrderAmount', type: 'input' },
            { label: '售后状态:', id: 'statusStr', type: 'input' },
            { label: '售后理由:', id: 'reason', type: 'input', span: 24 },
            { label: '处理时间:', id: 'auditTime', type: 'input' },
          ],
        },
      ],
      auditFormContent: [
        {
          label: '处理意见:',
          id: 'auditStatus',
          type: 'bus-radio',
          el: {
            code: 'SALES_AUDIT_STATUS',
          },
          rules: { required: true, message: '请选择处理意见' },
          on: {
            change: (e, updateForm) => {
              updateForm({ auditRemarks: '' })
          type: 'row',
          id: 'refundInfo',
          items: [
            { id: 'status', type: 'input', hidden: () => true },
            {
              label: '订单状态:',
              id: 'statusStr',
              component: 'simple-text',
              el: (row) => ({
                type: row.status === 'PENDING' ? 'primary' : '',
              }),
              forceDisabled: true,
            },
          },
          str: true,
            { label: '售后单号:', id: 'salesNo', type: 'input' },
            { label: '退款金额(元):', id: 'totalFee', type: 'input' },
            { label: '供应商扣款(元):', id: 'feeSupplier', type: 'input' },
            { label: '平台扣款(元):', id: 'feePlatform', type: 'input' },
            { label: '合伙人扣款(元):', id: 'feePartner', type: 'input' },
            { label: '打包扣款(元):', id: 'feePlatformPack', type: 'input' },
            { label: '质检扣款(元):', id: 'feePlatformCheck', type: 'input' },
            {
              label: '物流扣款(元):',
              id: 'feePlatformTransport',
              type: 'input',
            },
            { label: '实际总扣款(元):', id: 'totalFee', type: 'input' },
            {
              label: '申请理由:',
              id: 'reason',
              type: 'input',
              el: { type: 'textarea' },
              span: 24,
            },
            {
              label: '平台回复:',
              id: 'remarks',
              type: 'input',
              el: { type: 'textarea' },
              span: 24,
            },
            {
              label: '退款图片:',
              id: 'pictureList',
              type: 'bus-upload',
              el: {
                listType: 'picture-card',
                size: 'small',
              },
              forceDisabled: true,
              span: 24,
              inputFormat: (row) => {
                if ('pictureList' in row) {
                  return row?.pictureList?.length
                    ? row.pictureList.map((i) => ({ url: i }))
                    : []
                }
              },
            },
            {
              label: '退款视频:',
              id: 'videoList',
              component: VideoList,
              forceDisabled: true,
              span: 24,
            },
          ],
        },
        {
          label: '不通过原因:',
          id: 'auditRemarks',
          type: 'input',
          el: {
            type: 'textarea',
            rows: 6,
          },
          rules: {
            required: true,
            message: '请输入不通过原因',
            trigger: 'blur',
          },
          hidden: (row) => row.auditStatus !== 'REJECT',
        },
        {
          label: '',
          id: 'items',
          component: AfterSaleItems,
          forceDisabled: true,
          type: 'row',
          id: 'goodsInfo',
          items: [
            { label: '商品名称:', id: 'flowerName' },
            { label: '商品分类:', id: 'flowerCategory' },
            { label: '级别:', id: 'flowerLevelStr' },
            { label: '颜色:', id: 'flowerColor' },
            { label: '规格:', id: 'flowerUnit' },
            { label: '商品价格(元):', id: 'price' },
            { label: '供应商价格(元):', id: 'supplierPrice' },
            { label: '合伙人加价(元):', id: 'markupPartner' },
            { label: '申请数量:', id: 'num' },
            { label: '实际退款(元):', id: 'totalFee' },
          ],
        },
      ],
    }
@@ -115,6 +132,14 @@
    return {
      title: '售后详情',
    }
  },
  computed: {
    editable() {
      return (
        this.$route.params.action === 'handle' &&
        this.detail?.status === 'PENDING'
      )
    },
  },
  mounted() {
    this.getDetail()
@@ -133,12 +158,8 @@
        data.customerWholeAddress = `${data.customerProvince || ''}${
          data.customerCity || ''
        }${data.customerRegion || ''}${data.customerAddress || ''}`
        data.imageListFormat = Array.isArray(data.imageList)
          ? data.imageList.map((i) => ({ url: i }))
          : []
        this.detail = data || {}
        this.$refs.form.updateForm(data)
        this.$refs.auditForm.updateForm(data)
      }
      this.wholeLoading = false
    },
@@ -148,6 +169,7 @@
<style lang="scss" scoped>
.sale-detail {
  border-radius: 0;
  .el-bus-title {
    margin-bottom: 10px;
  }
pages/order/after-sale/index.vue
@@ -1,9 +1,20 @@
<template>
  <el-bus-crud ref="crud" v-bind="tableConfig"></el-bus-crud>
  <el-bus-crud ref="crud" v-bind="tableConfig">
    <template #table="{ list }">
      <template v-if="list && list.length > 0">
        <after-sale-table :list="list" @detail="onDetail" />
      </template>
      <el-bus-empty v-else />
    </template>
  </el-bus-crud>
</template>
<script>
import AfterSaleTable from '@/components/order/after-sale-table'
export default {
  components: {
    AfterSaleTable,
  },
  data() {
    return {
      tableConfig: {
@@ -52,27 +63,34 @@
                el: {
                  hasAll: true,
                  childType: 'el-radio-button',
                  code: 'SALES_STATUS',
                  code: 'ORDER_SALES_STATUS',
                },
                default: '',
                span: 24,
                searchImmediately: true,
              },
              {
                label: '审核状态:',
                id: 'auditStatus',
                type: 'bus-radio',
                el: {
                  hasAll: true,
                  childType: 'el-radio-button',
                  code: 'SALES_AUDIT_STATUS',
                },
                default: '',
                span: 24,
                searchImmediately: true,
              },
              { label: '商品名称:', id: 'flowerName', type: 'input' },
              { label: '订单号:', id: 'orderNo', type: 'input' },
              { label: '售后单号:', id: 'salesNo', type: 'input' },
              { label: '收货人姓名:', id: 'customer', type: 'input' },
              { label: '收货人电话:', id: 'customerTel', type: 'input' },
              { label: '供应商:', id: 'supplierName', type: 'input' },
              {
                label: '下单时间:',
                id: 'orderStartDateStr',
                component: 'el-bus-date-range',
                commonFormat: true,
                commonFormatProps: ['orderStartDateStr', 'orderEndDateStr'],
                customClass: 'in-bus-form',
              },
              {
                label: '售后时间:',
                id: 'salesStartDateStr',
                component: 'el-bus-date-range',
                commonFormat: true,
                commonFormatProps: ['salesStartDateStr', 'salesEndDateStr'],
                customClass: 'in-bus-form',
              },
            ],
          },
        ],
@@ -84,6 +102,11 @@
      title: '售后理赔',
    }
  },
  methods: {
    onDetail(item) {
      this.$router.push(`${this.$route.path}/view/${item.id}`)
    },
  },
}
</script>
pages/order/list/_id.vue
@@ -21,18 +21,51 @@
    <template v-if="afterSaleList && afterSaleList.length > 0">
      <el-bus-title title="售后信息" size="small" class="mt-20"></el-bus-title>
      <el-table :data="afterSaleList">
        <el-table-column label="原因" prop="reason"></el-table-column>
        <el-table-column label="售后时间" prop="createTime"></el-table-column>
        <el-table-column label="处理时间" prop="auditTime"></el-table-column>
        <el-table-column label="处理状态" prop="statusStr"></el-table-column>
        <el-table-column
          label="处理结果"
          prop="auditStatusStr"
          label="商品名称"
          prop="flowerName"
          min-width="150"
          fixed="left"
        ></el-table-column>
        <el-table-column label="操作">
        <el-table-column
          label="级别"
          prop="flowerLevelStr"
          min-width="120"
        ></el-table-column>
        <el-table-column
          label="颜色"
          prop="flowerColor"
          min-width="120"
        ></el-table-column>
        <el-table-column
          label="原因"
          prop="reason"
          min-width="200"
        ></el-table-column>
        <el-table-column
          label="售后时间"
          prop="createTime"
          min-width="180"
        ></el-table-column>
        <el-table-column
          label="处理时间"
          prop="auditTime"
          min-width="180"
        ></el-table-column>
        <el-table-column
          label="处理状态"
          prop="statusStr"
          min-width="120"
        ></el-table-column>
        <el-table-column
          label="实际退款"
          prop="totalFee"
          min-width="120"
        ></el-table-column>
        <el-table-column label="操作" width="120" fixed="right">
          <template #default="{ row }">
            <el-button type="text" @click="toDetail(row.id)"
              >查看详情</el-button
            >查看详情</el-button
            >
          </template>
        </el-table-column>
pages/shop/list.vue
@@ -38,6 +38,7 @@
                commonFormatProps: ['province', 'city', 'region'],
                customClass: 'in-bus-form',
              },
              { label: '手机号', id: 'tel', type: 'input' },
            ],
          },
        ],