5个文件已修改
497 ■■■■■ 已修改文件
manager/src/api/customer.js 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
manager/src/api/order.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
manager/src/views/activity/index.vue 139 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
manager/src/views/customer/index.vue 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
manager/src/views/order/order/orderDetail.vue 175 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
manager/src/api/customer.js
@@ -78,3 +78,9 @@
  })
}
export const getCustomerInfo= (params) =>{
  return service({
    url: '/customerManager/'+ params,
    method: 'GET'
  })
}
manager/src/api/order.js
@@ -130,6 +130,10 @@
export const getLogisticsChecked = () => {
  return getRequest(`/other/logistics/getChecked`)
}
//查询包裹列表
export const getPackage = (orderSn) => {
  return getRequest(`/order/order/getPackage/${orderSn}`);
}
//查询物流
export const getTraces = (sn, params) => {
manager/src/views/activity/index.vue
@@ -136,6 +136,11 @@
            <Button
              type="info"
              size="small"
              @click="detail(row)"
            >详情</Button>
            <Button
              type="info"
              size="small"
              @click="openEdit(row)"
            >编辑</Button>
            <Button
@@ -336,6 +341,82 @@
        </Row>
      </Modal>
      <Modal
        v-model="infoModelShow"
        :title="modelTitle"
        @on-cancel="infoModelClose"
        width="800"
        :mask-closable="false"
      >
        <div class="detail-container">
          <Row :gutter="16">
            <Col span="12">
              <div class="detail-item">
                <label>活动名称:</label>
                <span>{{ activityInfo.activityName || '-' }}</span>
              </div>
            </Col>
            <Col span="12">
              <div class="detail-item">
                <label>活动类型:</label>
                <span>{{activityInfo.activityType === 'online' ? '线上':'线下'}}</span>
              </div>
            </Col>
            <Col span="12">
              <div class="detail-item">
                <label>报名时间段:</label>
                <span>{{ activityInfo.reportStartTime }} - {{ activityInfo.reportEndTime }}</span>
              </div>
            </Col>
            <Col span="12">
              <div class="detail-item">
                <label>活动时间段:</label>
                <span>{{ activityInfo.startTime }} - {{ activityInfo.endTime }}</span>
              </div>
            </Col>
            <Col span="24" v-if="coverType === '输入文字封面'">
              <div class="detail-item">
                <label>封面文字:</label>
                <span>{{ activityInfo.cover || '-' }}</span>
              </div>
            </Col>
            <Col span="24" v-if="coverType === '选择文件封面'">
              <div class="detail-item">
                <label>上传封面:</label>
                <span>{{ activityInfo.cover }}</span>
              </div>
            </Col>
            <Col span="12">
              <div class="detail-item">
                <label>人数限制:</label>
                <span>{{ activityInfo.limitUserNum || '无限制' }}</span>
              </div>
            </Col>
            <Col span="12">
              <div class="detail-item">
                <label>活动地点:</label>
                <span>{{ activityInfo.activityLocation || '-' }}</span>
              </div>
            </Col>
            <Col span="24">
              <div class="detail-item">
                <label>活动内容:</label>
                <div
                  class="activity-content"
                  v-html="activityInfo.activityContent || '无内容'"
                ></div>
              </div>
            </Col>
          </Row>
        </div>
        <div slot="footer">
          <Button @click="infoModelClose">关闭</Button>
        </div>
      </Modal>
      <!-- 图片预览模态框 -->
      <Modal v-model="previewVisible" title="图片预览" footer-hide>
        <img :src="previewImageUrl" style="width: 100%">
@@ -361,6 +442,8 @@
  components: {Editor},
  data() {
    return {
      infoModelShow:false,
      loading: false,
      membersLoading: false,
      submitLoading: false,
@@ -397,6 +480,24 @@
      // 活动表单
      activityFrom: {
        id: '',
        activityName: '',
        activityType: '',
        reportTime: [],
        time: [],
        activityContent: '',
        cover: '',
        coverType: '',
        status: '',
        reportStartTime: '',
        reportEndTime: '',
        startTime: '',
        endTime: '',
        recommend: false,
        limitUserNum: 0,
        activityLocation: '',
      },
      activityInfo: {
        id: '',
        activityName: '',
        activityType: '',
@@ -645,6 +746,11 @@
    this.init()
  },
  methods: {
    detail(row){
      this.modelTitle = '活动详情'
      this.infoModelShow = true
      this.activityInfo = row
    },
    // 获取富文本编辑器的内容
    getReason(content) {
      this.activityFrom.activityContent = content
@@ -757,7 +863,9 @@
        this.coverType = row.coverType === 'text' ? '输入文字封面' : '选择文件封面'
      })
    },
    infoModelClose(){
      this.infoModelShow = false
    },
    // 关闭模态框
    modelClose() {
      this.modelShow = false
@@ -1183,4 +1291,33 @@
    margin-top: 4px;
  }
}
.detail-container {
  padding: 16px;
}
.detail-item {
  margin-bottom: 18px;
  line-height: 1.5;
  label {
    display: inline-block;
    width: 100px;
    color: #666;
    font-weight: bold;
    vertical-align: top;
  }
  span {
    display: inline-block;
    width: calc(100% - 110px);
  }
}
.activity-content {
  border: 1px solid #dcdee2;
  border-radius: 4px;
  padding: 12px;
  min-height: 100px;
  margin-top: 8px;
}
</style>
manager/src/views/customer/index.vue
@@ -68,6 +68,7 @@
        @on-selection-change="showSelect"
      >
        <template slot-scope="{ row, index }" slot="action">
          <Button type="info" size="small" style="margin-right: 5px" @click="openInfo(row)">查看详情</Button>
          <Button type="info" size="small" style="margin-right: 5px" @click="openEdit(row)">编辑标签</Button>
          <Button type="error" size="small" style="margin-right: 5px" @click="joinBlack(row)">加入黑名单</Button>
        </template>
@@ -87,6 +88,82 @@
        ></Page>
      </Row>
      <Modal
        v-model="showCustomerInfo"
        :title="modelTitle"
        width="700"
        :mask-closable="false"
      >
        <div class="customer-detail">
          <div class="avatar-section">
            <Avatar :src="customerInfo.face" size="large" />
            <div class="basic-info">
              <h3>{{ customerInfo.nickName || '微信用户' }}</h3>
              <p>ID: {{ customerInfo.id }}</p>
              <p>用户名: {{ customerInfo.username }}</p>
            </div>
          </div>
          <Divider />
          <div class="detail-grid">
            <div class="detail-row">
              <span class="detail-label">性别:</span>
              <span class="detail-value">{{ customerInfo.sex === 0 ? "女" : "男"}}</span>
            </div>
            <div class="detail-row">
              <span class="detail-label">地区:</span>
              <span class="detail-value">{{ customerInfo.region || '未设置' }}</span>
            </div>
            <div class="detail-row">
              <span class="detail-label">手机号:</span>
              <span class="detail-value">{{ customerInfo.mobile || '未绑定' }}</span>
            </div>
            <div class="detail-row">
              <span class="detail-label">当前积分:</span>
              <span class="detail-value">{{ customerInfo.point }}</span>
            </div>
            <div class="detail-row">
              <span class="detail-label">总积分:</span>
              <span class="detail-value">{{ customerInfo.totalPoint }}</span>
            </div>
            <div class="detail-row">
              <span class="detail-label">账号状态:</span>
              <span class="detail-value">
          <Tag :color="customerInfo.disabled ? 'error' : 'success'">
            {{ customerInfo.disabled ? '已禁用' : '正常' }}
          </Tag>
        </span>
            </div>
            <div class="detail-row">
              <span class="detail-label">是否关联店铺:</span>
              <span class="detail-value">{{ customerInfo.haveStore ? '是' : '否' }}</span>
            </div>
            <div class="detail-row">
              <span class="detail-label">注册时间:</span>
              <span class="detail-value">{{ customerInfo.createTime }}</span>
            </div>
            <div class="detail-row">
              <span class="detail-label">最后登录时间:</span>
              <span class="detail-value">{{ customerInfo.lastLoginDate }}</span>
            </div>
          </div>
          <div v-if="customerInfo.customerTagList && customerInfo.customerTagList.length > 0" class="tags-section">
            <h4>用户标签</h4>
            <div>
              <Tag v-for="tag in customerInfo.customerTagList" :key="tag" color="default" style="margin-right: 8px;">
                {{ tag }}
              </Tag>
            </div>
          </div>
        </div>
        <div slot="footer">
          <Button type="primary" @click="showCustomerInfo = false">关闭</Button>
        </div>
      </Modal>
<!--      标签弹窗-->
      <Modal
        v-model="showCustomerTag"
        :title="modelTitle"
@@ -125,7 +202,7 @@
<script>
import JsonExcel from "vue-json-excel";
import {getCustomerList,addCustomerTag,saveCustomerTagById,getTagList,getStoreSelectOptions} from "@/api/customer";
import {getCustomerList,addCustomerTag,saveCustomerTagById,getTagList,getStoreSelectOptions,getCustomerInfo} from "@/api/customer";
import {addCustomerBlackByPC} from "@/api/customer-black.js"
export default {
@@ -135,6 +212,30 @@
  },
  data(){
    return{
      customerInfo: {
        birthday: null,
        blackId: null,
        clientEnum: null,
        createTime: "",
        customerTagList: [],
        disabled: true,
        experience: null,
        face: "",
        gradeId: null,
        haveStore: false,
        id: "",
        lastLoginDate: "",
        mobile: null,
        nickName: "",
        openId: null,
        point: 10,
        region: "",
        regionId: "",
        sex: 0,
        storeId: null,
        totalPoint: 0,
        username: ""
      },
      loading: false, // 表单加载状态
      //查询客户列表请求参数
      searchForm:{
@@ -225,8 +326,9 @@
      selectCount: 0, // 已选数量
      selectList: [], // 已选数据列表
      //客户详情对话框---
      showCustomerInfo:false,
      //客户标签对话框---
      showCustomerTag:false,
      submitLoading:false,
      selectLoading:false,
@@ -301,6 +403,39 @@
      this.selectList = e.map(d => d.id);
      this.selectCount = e.length;
    },
    //查看详情
    openInfo(row){
      this.showCustomerInfo = true;
      this.modelTitle = "用户详情"
      getCustomerInfo(row.id).then(res =>{
        if(res.code === 200){
          this.customerInfo = {
            birthday: res.data.birthday || null,
            blackId: res.data.blackId || null,
            clientEnum: res.data.clientEnum || null,
            createTime: res.data.createTime || '',
            customerTagList: res.data.customerTagList || [],
            disabled: res.data.disabled || false,
            experience: res.data.experience || null,
            face: res.data.face || '默认头像URL',
            gradeId: res.data.gradeId || null,
            haveStore: res.data.haveStore || false,
            id: res.data.id || '',
            lastLoginDate: res.data.lastLoginDate || '',
            mobile: res.data.mobile || null,
            nickName: res.data.nickName || '微信用户',
            openId: res.data.openId || null,
            point: res.data.point || 0,
            region: res.data.region || '',
            regionId: res.data.regionId || '',
            sex: res.data.sex || 0,
            storeId: res.data.storeId || null,
            totalPoint: res.data.totalPoint || 0,
            username: res.data.username || ''
          };
        }
      })
    },
    // 编辑标签
    openEdit(row){
      this.showCustomerTag = true
@@ -360,6 +495,40 @@
</script>
<style lang="scss" scoped>
.customer-detail {
  padding: 16px;
}
.avatar-section {
  display: flex;
  align-items: center;
  margin-bottom: 16px;
}
.basic-info {
  margin-left: 16px;
}
.basic-info h3 {
  margin: 0 0 8px 0;
  font-size: 18px;
}
.basic-info p {
  margin: 6px 0;
  color: #808695;
  font-size: 14px;
}
.tags-section {
  margin-top: 16px;
  padding-top: 16px;
}
.tags-section h4 {
  margin-bottom: 12px;
  color: #17233d;
}
.export {
  margin: 10px 20px 10px 0;
}
manager/src/views/order/order/orderDetail.vue
@@ -7,6 +7,7 @@
          <Button v-if="allowOperation.editConsignee" @click="editAddress" type="primary" ghost>修改收货地址</Button>
          <Button v-if="allowOperation.cancel" @click="orderCancel" type="warning" ghost>订单取消</Button>
          <Button v-if="orderInfo.order.orderStatus === 'UNPAID'" @click="confirmPrice" type="primary">收款</Button>
          <Button v-if="allowOperation.showLogistics || orderPackage.length > 0" @click="checkLogistics" type="primary">查看物流</Button>
          <Button @click="orderLog" type="info" ghost>订单日志</Button>
          <Button @click="printOrder" type="primary" ghost style="float:right;"
            v-if="$route.query.orderType != 'VIRTUAL'">打印发货单</Button>
@@ -310,6 +311,74 @@
        <Button type="primary" @click="modifyPriceSubmit">调整</Button>
      </div>
    </Modal>
    <!-- 查询物流 -->
    <Modal v-model="logisticsModal" width="40">
      <p slot="header">
        <span>查询物流</span>
      </p>
      <div class="layui-layer-wrap">
        <dl>
          <dt>订单号:</dt>
          <dd>
            <div class="text-box">{{ sn }}</div>
          </dd>
        </dl>
      </div>
      <div v-if="packageTraceList.length > 0" v-for="(packageItem, packageIndex) in packageTraceList" :key="packageIndex">
        <div class="layui-layer-wrap">
          <dl>
            <dt>物流公司:</dt>
            <dd><div class="text-box">{{ packageItem.logisticsName }}</div></dd>
          </dl>
          <dl>
            <dt>快递单号:</dt>
            <dd><div nctype="ordersSn" class="text-box">{{ packageItem.logisticsNo }}</div></dd>
          </dl>
          <div class="div-express-log">
            <ul class="express-log express-log-name">
              <li v-for="(item, index) in packageItem.orderPackageItemList" :key="index">
                <span class="time" style="width: 50%;"><span>商品名称:</span><span>{{ item.goodsName }}</span></span>
                <span class="time" style="width: 30%;"><span>发货时间:</span><span>{{ item.logisticsTime }}</span></span>
                <span class="time" style="width: 20%;"><span>发货数量:</span><span>{{ item.deliverNumber }}</span></span>
              </li>
            </ul>
          </div>
          <div class="div-express-log">
            <ul class="express-log" v-if="packageItem.traces && packageItem.traces.traces">
              <li v-for="(item, index) in packageItem.traces.traces" :key="index">
                <span class="time">{{ item.AcceptTime || item.acceptTime }}</span>
                <span class="detail">{{ item.AcceptStation || item.remark }}</span>
              </li>
            </ul>
            <ul class="express-log" v-else><li>暂无物流信息</li></ul>
          </div>
        </div>
      </div>
      <div v-if = "packageTraceList.length == 0 && logisticsInfo">
        <div class="layui-layer-wrap">
          <dl>
            <dt>物流公司:</dt>
            <dd><div class="text-box">{{ logisticsInfo.shipper }}</div></dd>
          </dl>
          <dl>
            <dt>快递单号:</dt>
            <dd><div nctype="ordersSn" class="text-box">{{ logisticsInfo.logisticCode }}</div></dd>
          </dl>
          <div class="div-express-log">
            <ul class="express-log" v-if="logisticsInfo && logisticsInfo.traces">
              <li v-for="(item, index) in logisticsInfo.traces" :key="index">
                <span class="time">{{ item.AcceptTime }}</span>
                <span class="detail">{{ item.AcceptStation }}</span>
              </li>
            </ul>
            <ul class="express-log" v-else><li>暂无物流信息</li></ul>
          </div>
        </div>
      </div>
      <div slot="footer" style="text-align: right">
        <Button @click="logisticsModal = false">取消</Button>
      </div>
    </Modal>
    <!-- 订单取消模态框 -->
    <Modal v-model="orderCancelModal" width="530">
      <p slot="header">
@@ -468,6 +537,12 @@
      orderLogModal: false, //弹出调整价格框
      checkedLogistics: [], //选中的物流公司集合
      allowOperation: {}, //订单可才做选项
      logisticsModal: false, //弹出查询物流框
      packageTraceList: [],
      orderPackage: [],
      logisticsInfo: {
        shipper: "",
      }, //物流信息
      sn: "", //订单编号
      orderInfo: {
        order: {
@@ -645,7 +720,39 @@
    gotoHomes () {
      return false
    },
    getOrderPackage() {
      API_Order.getPackage(this.sn).then(res => {
        if (res.success) {
          this.orderPackage = res.result;
          console.log('this.orderPackage',this.orderPackage);
        }
      })
    },
    //查询物流
    checkLogistics () {
      this.logisticsModal = true;
      if (this.orderPackage.length > 0) {
        this.logisticsList();
      } else {
        this.logistics();
      }
    },
    logisticsList () {
      this.logisticsModal = true;
      API_Order.getPackage(this.sn).then((res) => {
        if (res.success && res.result != null) {
          this.packageTraceList = res.result;
        }
      });
    },
    logistics () {
      this.logisticsModal = true;
      API_Order.getTraces(this.sn).then((res) => {
        if (res.success && res.result != null) {
          this.logisticsInfo = res.result;
        }
      });
    },
    //确认收款
    confirmPrice () {
      this.$Modal.confirm({
@@ -805,6 +912,7 @@
  mounted () {
    this.sn = this.$route.query.sn;
    this.getDataList();
    this.getOrderPackage();
  },
};
</script>
@@ -910,7 +1018,72 @@
    }
  }
}
.div-express-log {
  max-height: 300px;
  border: solid 1px #e7e7e7;
  background: #fafafa;
  overflow-y: auto;
  overflow-x: auto;
}
.layui-layer-wrap {
  dl {
    border-top: solid 1px #f5f5f5;
    margin-top: -1px;
    overflow: hidden;
    dt {
      font-size: 14px;
      line-height: 28px;
      display: inline-block;
      padding: 8px 1% 8px 0;
      color: #999;
    }
    dd {
      font-size: 14px;
      line-height: 28px;
      display: inline-block;
      padding: 8px 0 8px 8px;
      border-left: solid 1px #f5f5f5;
      .text-box {
        line-height: 40px;
        color: #333;
        word-break: break-all;
      }
    }
  }
}
.express-log {
  /*margin: 5px -10px 5px 5px;*/
  padding: 10px;
  list-style-type: none;
  .time {
    width: 30%;
    display: inline-block;
    float: left;
  }
  .detail {
    width: 60%;
    margin-left: 30px;
    display: inline-block;
  }
  li {
    line-height: 30px;
  }
}
.express-log-name {
  li {
    display: flex;
    span  {
      display: flex;
    }
  }
}
.f14 {
  font-size: 14px;
  color: #333;