iZaiZaiA 3 年之前
父节点
当前提交
3a91ba8bb2

二进制
src/assets/images/Web515.png


+ 28 - 0
src/global/components/hc-img/index.vue

@@ -0,0 +1,28 @@
+<template>
+    <ElImage :class="ui" :src="src" :previewSrcList="srcs" :initial-index="index" :fit="fit" crossOrigin="anonymous"/>
+</template>
+
+<script setup>
+defineProps({
+    ui: {
+        type: String,
+        default: ''
+    },
+    src: {
+        type: String,
+        default: ''
+    },
+    srcs: {
+        type: Array,
+        default: () => ([])
+    },
+    index: {
+        type: [String,Number],
+        default: -1
+    },
+    fit: {
+        type: String,
+        default: 'cover'
+    },
+})
+</script>

+ 2 - 0
src/global/components/index.js

@@ -1,3 +1,4 @@
+import HcImg from './hc-img/index.vue'
 import HcIcon from './hc-icon/index.vue'
 import HcCard from './hc-card/index.vue'
 import HcPages from './hc-page/index.vue'
@@ -7,6 +8,7 @@ import HcNewSwitch from './hc-new-switch/index.vue'
 
 //注册全局组件
 export const setupComponents = (App) => {
+    App.component('HcImg', HcImg)
     App.component('HcIcon', HcIcon)
     App.component('HcCard', HcCard)
     App.component('HcPages', HcPages)

+ 1 - 1
src/router/modules/base.js

@@ -43,7 +43,7 @@ export default [
             {
                 path: '/other/order-service',
                 name: 'order-service',
-                meta: {title: '工单服务-需求反馈'},
+                meta: {title: '工单服务'},
                 component: () => import('~src/views/other/order-service.vue')
             },
             {

+ 74 - 1
src/styles/app/element.scss

@@ -1,6 +1,6 @@
 //饿了么UI组件的样式重绘
 
-.el-button--large[block] {
+.el-button[block] {
     width: 100%;
 }
 
@@ -144,3 +144,76 @@
     }
 }
 
+//下拉框
+.el-select[block] {
+    width: 100%;
+}
+
+
+//工单服务的时间轴
+.time-line-box .el-timeline.hc-time-line {
+    padding-left: 5px;
+    padding-top: 5px;
+    .el-timeline-item {
+        padding-bottom: 24px;
+        .el-timeline-item__tail {
+            top: 28px;
+            left: 6px;
+            height: calc(100% - 36px);
+            border-width: 1px;
+            border-color: #838791;
+        }
+        .el-timeline-item__node {
+            display: none;
+        }
+        .el-timeline-item__wrapper {
+            padding-left: 38px;
+            .el-timeline-item__content {
+                .timeline-item-icon {
+                    position: absolute;
+                    width: 24px;
+                    height: 24px;
+                    left: -5px;
+                    border: 1px solid #838791;
+                    border-radius: 50px;
+                    display: flex;
+                    justify-content: center;
+                    align-items: center;
+                    color: #838791;
+                    .check-icon {
+                        font-size: 18px;
+                    }
+                }
+                .reply-name {
+                    color: #838791;
+                    font-size: 18px;
+                }
+                .reply-content {
+                    color: #838791;
+                    margin-top: 5px;
+                }
+            }
+        }
+        &.success {
+            .el-timeline-item__tail {
+                border-color: var(--el-color-primary);
+            }
+            .el-timeline-item__wrapper .el-timeline-item__content .timeline-item-icon {
+                color: var(--el-color-primary);
+                border: 1px solid var(--el-color-primary);
+            }
+        }
+        &.primary {
+            .el-timeline-item__wrapper .el-timeline-item__content {
+                .reply-name {
+                    color: #1A1A1A;
+                }
+                .timeline-item-icon {
+                    background-color: var(--el-color-primary);
+                    border: 1px solid var(--el-color-primary);
+                    color: #ffffff;
+                }
+            }
+        }
+    }
+}

+ 71 - 47
src/styles/other/order-service.scss

@@ -1,53 +1,55 @@
 .hc-order-service {
     position: relative;
-    background-color: #f7f7f7;
+    height: 100%;
+    display: flex;
     .order-service-content {
         position: relative;
-        overflow: auto;
-        padding: 15px 15px 15px 24px;
-        scroll-behavior: smooth;
+        flex: 1 1 auto;
+        height: 105%;
+        margin: -24px;
         .content-box {
             position: relative;
-            width: 820px;
-            margin: 0 auto;
+            padding: 24px;
             .comment-card-box {
-                background: white;
-                border: 1px solid #efeff5;
-                border-radius: 3px;
+                background: #f1f5f8;
+                border-radius: 10px;
                 margin-bottom: 24px;
+                padding: 24px;
+                position: relative;
+                box-shadow: -2px 0 10px 0 rgba(32,37,50,0.03), 0 10px 21px 20px rgba(32,37,50,0.03);
+                display: flex;
+                align-items: flex-start;
+                .user-avatar-box {
+                    margin-right: 18px;
+                }
                 .card-content-box {
                     position: relative;
-                    padding: 24px;
+                    flex: 1;
                     .user-info-box {
                         position: relative;
-                        display: flex;
-                        align-items: center;
-                        .name-box {
-                            position: relative;
-                            margin-left: 15px;
-                            line-height: 1.6;
-                            flex: auto;
+                        line-height: 1.6;
+                        .text-lg {
+                            color: #1A1A1A;
                         }
-                        .code-status-box {
-                            position: absolute;
-                            transform: rotate(333deg);
-                            width: 115px;
-                            right: 0;
-                            top: 24px;
-                            .widget {
-                                width: 115px;
-                                height: 44px;
-                                border: 2px dashed #15a854;
-                                border-radius: 7px;
-                                font-size: 18px;
-                                display: flex;
-                                align-items: center;
-                                justify-content: center;
-                            }
+                        .text-gray {
+                            color: #838791;
                         }
                     }
                     .desc_para {
-                        margin: 24px 0;
+                        margin: 20px 0 10px;
+                        color: #50545E;
+                    }
+                    .image_desc {
+                        display: flex;
+                        .hc-image-box {
+                            margin-right: 10px;
+                            .hc-image {
+                                display: flex;
+                                width: 120px;
+                                height: 120px;
+                                border-radius: 6px;
+                            }
+                        }
                     }
                     .foot-tools-box {
                         position: relative;
@@ -127,6 +129,17 @@
                         }
                     }
                 }
+                .code-status-box {
+                    position: absolute;
+                    width: 140px;
+                    right: 0;
+                    top: 0;
+                    .widget {
+                        width: 140px;
+                        height: 140px;
+                        display: inline-flex;
+                    }
+                }
                 .collapse-comment-box {
                     position: relative;
                     background-color: #fafafc;
@@ -167,20 +180,16 @@
     }
     .order-service-data {
         position: relative;
-        background-color: #ffffff;
-        border-left: 1px solid #e4e4e4;
-        border-top: 1px solid #e4e4e4;
-        padding: 15px 24px 15px 15px;
-        overflow: hidden;
+        height: 100%;
         width: 500px;
+        margin-left: 50px;
         .time-line-box {
             position: relative;
             padding-top: 2px;
-            overflow: auto;
-            height: auto;
+            height: calc(100% - 60px);
         }
         .time-line-box.time-height {
-            height: calc(100% - 391.2px);
+            height: calc(100% - 376px);
         }
         .evaluation-box {
             position: relative;
@@ -189,20 +198,39 @@
             border-top: 1px solid #e4e4e4;
             .tip-box {
                 margin: 12px 0;
+                color: #50545E;
             }
             .radio-group-box {
                 position: relative;
                 margin-bottom: 15px;
                 line-height: 2.5;
+                .radio-group {
+                    display: inline-block;
+                }
             }
             .btn-box {
                 position: relative;
                 text-align: right;
+                right: 10px;
             }
             &.show {
                 display: block;
             }
         }
+        .hc-add-icon {
+            position: relative;
+            width: 32px;
+            height: 32px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            border-radius: 6px;
+            padding: 0;
+        }
+        .hc-add-icon.el-button[hc-btn] .material-symbols-rounded {
+            font-size: 24px;
+            margin-right: 0;
+        }
         .horizontal-drag-line {
             position: absolute;
             left: 0;
@@ -211,11 +239,7 @@
             height: 100%;
             user-select: none;
             cursor: col-resize;
-            background-color: #e4e4e4;
-            transition: background-color 0.2s;
-            &:hover {
-                background-color: rgba(119, 119, 119, .5);
-            }
+            background-color: transparent;
         }
     }
 }

+ 71 - 107
src/views/other/order-service.vue

@@ -1,27 +1,22 @@
 <template>
-    <n-spin :show="spinShow" class="order-service-spin">
-        <div class="hc-order-service h-full flex">
-            <div class="flex-auto h-full order-service-content" id="order-service-content">
+    <div class="hc-order-service">
+        <div class="order-service-content">
+            <el-scrollbar>
                 <div class="content-box">
                     <div class="comment-card-box" v-for="(item,index) in orderDataList" :key="item.id">
+                        <div class="user-avatar-box">
+                            <el-avatar :size="50" :src="item.avatar || avatarPng" />
+                        </div>
                         <div class="card-content-box">
                             <div class="user-info-box">
-                                <n-avatar round :size="50" :src="item.avatar || avatarPng"/>
-                                <div class="name-box">
-                                    <div class="text-lg">{{item['createUserName']||'用户名异常'}}</div>
-                                    <div class="text-gray">{{item['createTime']}}</div>
-                                </div>
-                                <div class="code-status-box" v-if="parseInt(item['isSolve']) === 1">
-                                    <div class="widget bg-green-thin">已解决</div>
-                                </div>
+                                <div class="text-lg">{{item['createUserName']||'用户名异常'}}</div>
+                                <div class="text-gray">{{item['createTime']}}</div>
                             </div>
                             <div class="desc_para" v-html="item['opinionContent']"></div>
                             <div class="image_desc" v-if="item['returnFiles']?.length > 0">
-                                <n-grid x-gap="12" :cols="3">
-                                    <n-gi v-for="(items,indexs) in item['returnFiles']">
-                                        <HcImage class="el-image-box" ui="el-image-box a" :src="items" :srcs="item['returnFiles']" :index="indexs"/>
-                                    </n-gi>
-                                </n-grid>
+                                <div class="hc-image-box" v-for="(items,indexs) in item['returnFiles']">
+                                    <HcImg class="hc-image" :src="items" :srcs="item['returnFiles']" :index="indexs"/>
+                                </div>
                             </div>
                             <div class="foot-tools-box">
                                 <div class="left-box">
@@ -29,25 +24,27 @@
                                         <div class="input-icon-box">
                                             <i class="hcicon-bianjimian"/>
                                         </div>
-                                        <div class="text-input-box">
+                                        <!--div class="text-input-box">
                                             <n-input type="text" v-model:value="item['replyContent']" size="small" placeholder="我也说一句" @keyup="commentKeyUp($event,item)"/>
-                                        </div>
+                                        </div-->
                                     </div>
                                 </div>
                                 <div class="right-box">
                                     <div class="icon-box" @click="commentExpanded(item)">
-                                        <i class="HIcon-pinglunliebiao"/>
+                                        <HcIcon name="chat"/>
                                         <div class="badge" v-if="item['commentsNumber'] >= 1">{{item['commentsNumber']}}</div>
                                     </div>
                                     <div class="icon-box" :data-index="item['expandedName']" @click="likeClick(item)">
-                                        <i class="HIcon-dianji-dianzan" v-if="item['currentUserGood']"/>
-                                        <i class="HIcon-weidianji-dianzan" v-else/>
+                                        <HcIcon name="thumb_up"/>
                                         <div class="badge" v-if="item['goodNumber'] >= 1">{{item['goodNumber']}}</div>
                                     </div>
                                 </div>
                             </div>
                         </div>
-                        <n-collapse :expanded-names="item['expandedName']" accordion>
+                        <div class="code-status-box" v-if="parseInt(item['isSolve']) === 1">
+                            <img :src="Web515Png" class="widget" alt=""/>
+                        </div>
+                        <!--n-collapse :expanded-names="item['expandedName']" accordion>
                             <n-collapse-item title="评论列表" :name="'commentList-'+item['id']">
                                 <div class="collapse-comment-box">
                                     <n-input type="textarea" v-model:value="item['replyContent']" placeholder="我也说一句"/>
@@ -67,107 +64,69 @@
                                     </div>
                                 </div>
                             </n-collapse-item>
-                        </n-collapse>
+                        </n-collapse-->
                     </div>
                 </div>
-                <div class="page-top-btn" @click="scrollToTop">
-                    <i class="hcicon-fanhuidingbu"/>
-                </div>
-            </div>
-            <!--我的工单服务-->
-            <div class="h-full order-service-data" :style="'width:' + leftWidth + 'px;'">
-                <div class="flex items-center mb-5">
-                    <span class="text-lg font-bold mr-4">我的工单服务进度</span>
-                    <n-button type="primary" size="small" @click="showModal = true">发起新工单服务</n-button>
-                </div>
+            </el-scrollbar>
+        </div>
+        <!--我的工单服务-->
+        <div class="order-service-data" :style="'width:' + leftWidth + 'px;'">
+            <HcCard :scrollbar="false">
+                <template #header>
+                    <el-badge :value="2" class="item-badge">
+                        <div class="font-bold text-lg">我的工单服务进度</div>
+                    </el-badge>
+                </template>
+                <template #extra>
+                    <el-tooltip effect="dark" content="发起新工单服务" placement="top">
+                        <el-button type="primary" hc-btn class="hc-add-icon">
+                            <HcIcon name="add"/>
+                        </el-button>
+                    </el-tooltip>
+                </template>
                 <div class="mb-5">
-                    <n-select v-model:value="nameSelectKey" :options="nameSelectData" placeholder="工单名称" @update:value="nameSelectUpdate"/>
+                    <el-select v-model="nameSelectKey" block placeholder="工单名称" size="large" @change="nameSelectUpdate">
+                        <el-option v-for="item in nameSelectData" :key="item.value" :label="item?.label" :value="item?.value"/>
+                    </el-select>
                 </div>
                 <div class="time-line-box" :class="isCurrentBol?'time-height':''">
-                    <n-timeline :icon-size="20">
-                        <template v-for="(item,index) in orderFlowList">
-                            <n-timeline-item :type="item['currentBol']?'success':item['current']?'info':''" :title="item['replyName']">
-                                <template #icon>
-                                    <i class="_icon-check" v-if="index === 0 || index === 3"/>
-                                    <span v-else>{{index}}</span>
-                                </template>
-                                <div class="text-xs" v-html="item['replyContent']"></div>
-                            </n-timeline-item>
-                        </template>
-                    </n-timeline>
+                    <el-scrollbar>
+                        <el-timeline class="hc-time-line">
+                            <template v-for="(item,index) in orderFlowList" :key="index">
+                                <el-timeline-item :class="item['currentBol']?'success':item['current']?'primary':''" size="large">
+                                    <div class="timeline-item-icon">
+                                        <HcIcon name="done" class="check-icon" v-if="item['currentBol']"/>
+                                        <span v-else>{{index + 1}}</span>
+                                    </div>
+                                    <div class="reply-name">{{item['replyName']}}</div>
+                                    <div class="reply-content" v-html="item['replyContent']"></div>
+                                </el-timeline-item>
+                            </template>
+                        </el-timeline>
+                    </el-scrollbar>
                 </div>
                 <div class="evaluation-box" :class="isCurrentBol?'show':''">
                     <div class="text-lg font-bold">评价</div>
                     <div class="tip-box">请对工单处理评价,若是未解决问题,可进行投诉,平台核实情况,将对相关客服人员绩效考核,并且从新为您自动发起工单解决问题</div>
                     <div class="radio-group-box">
-                        <n-radio-group v-model:value="evaluationKey" name="radiogroup">
+                        <el-radio-group class="radio-group" v-model="evaluationKey">
                             <div class="radio-item" v-for="item in evaluationData" :key="item.value">
-                                <n-radio :value="item.value">{{ item.label }}</n-radio>
+                                <el-radio :label="item.value" size="large" class="size-xl">{{ item.label }}</el-radio>
                             </div>
-                        </n-radio-group>
+                        </el-radio-group>
                     </div>
                     <div class="btn-box">
-                        <n-button type="success" class="w-20" @click="disposeUserFeedback">提交</n-button>
+                        <el-button type="primary" hc-btn @click="disposeUserFeedback">
+                            <HcIcon name="check_circle"/>
+                            <span>提交</span>
+                        </el-button>
                     </div>
                 </div>
-                <!--左右拖动-->
-                <div class="horizontal-drag-line" @mousedown="onmousedown"/>
-            </div>
-            <!--提交工单-->
-            <n-modal v-model:show="showModal">
-                <n-card class="w-606">
-                    <div class="title">请选择您需要反馈的问题类型</div>
-                    <div class="hc-type-tabs my-5">
-                        <n-tabs type="segment" :default-value="typeTabKey" @update:value="typeTabChange">
-                            <n-tab v-for="item in typeTab" :name="item.key" :key="item.id">{{item.name}}</n-tab>
-                        </n-tabs>
-                    </div>
-                    <div class="modal-checkbox-box">
-                        <n-checkbox-group v-model:value="typeCheckBox[typeTabIndex]">
-                            <div class="checkbox-item" v-for="item in typeTab[typeTabIndex]?.children" :key="item.id">
-                                <n-checkbox :value="item['dictValue']" :label="item['dictValue']" />
-                            </div>
-                        </n-checkbox-group>
-                    </div>
-                    <div class="mt-5">
-                        <n-input type="textarea" v-model:value="opinionContent" placeholder="请输入你宝贵的建议,我们将会跟踪解决"/>
-                    </div>
-                    <div class="mt-3 upload-img">
-                        <n-upload :action="uploadAction" :headers="getTokenHeader()" list-type="image-card" :file-list="uploadFileList" :with-credentials="true" :max="3" :accept="uploadAccept"
-                                  multiple @before-upload="beforeUpload" @finish="uploadFinish" @remove="removeUpload" @update:file-list="fileListUpdate" @preview="handlePreview"/>
-                        <div class="text-red mt-3">请上传JPG、PNG格式的图片文件,文件大小不超过30M</div>
-                        <n-modal v-model:show="previewImageModal" preset="card" class="w-606">
-                            <img :src="previewImageUrl" style="width: 100%" alt="">
-                        </n-modal>
-                    </div>
-                    <div class="foot-btn-box">
-                        <n-button type="primary" strong secondary class="w-20 mr-4" @click="showModal = false">取消</n-button>
-                        <n-button type="primary" class="w-20" @click="saveClick">提交</n-button>
-                    </div>
-                </n-card>
-            </n-modal>
-            <!--提示框-->
-            <n-modal v-model:show="showTipModal" :mask-closable="false">
-                <n-card class="w-606">
-                    <div class="tip-modal-icon-box">
-                        <i class="HIcon-xiaolian"/>
-                    </div>
-                    <div class="tip-modal-text-box">感谢您的仗义直言,大恩不言谢,有事联系我们,我们随时都在</div>
-                    <div class="tip-modal-btn-box">
-                        <div class="btn-box">
-                            <n-button strong secondary type="primary" @click="tipModalClick">下次不用感谢了</n-button>
-                        </div>
-                        <div class="btn-box">
-                            <n-button type="primary" @click="showTipModal = false">不客气</n-button>
-                        </div>
-                    </div>
-                </n-card>
-            </n-modal>
+            </HcCard>
+            <!--左右拖动-->
+            <div class="horizontal-drag-line" @mousedown="onmousedown"/>
         </div>
-        <template #description>
-            正在请求中...
-        </template>
-    </n-spin>
+    </div>
 </template>
 
 <script setup>
@@ -177,6 +136,7 @@ import orderServe from '~api/other/orderServe';
 import { getTokenHeader } from '~src/api/request/header';
 import HcImage from "~com/plugins/element/HcImage.vue"
 import avatarPng from '~src/assets/images/avatar.png';
+import Web515Png from '~src/assets/images/Web515.png';
 import {userConfigSave} from "~api/other";
 import {isObjNull} from "~src/utils/lib/isApp";
 import oss from "~api/oss";
@@ -561,7 +521,7 @@ const leftWidth = ref(500);
 const onmousedown = () => {
     const clientWidth = document.body.clientWidth
     document.onmousemove = (ve) => {
-        let diffVal = clientWidth - (ve.clientX - 2);
+        let diffVal = clientWidth - (ve.clientX + 24);
         if (diffVal >= 300 && diffVal <= 1000) {
             leftWidth.value = diffVal;
         }
@@ -578,6 +538,10 @@ const onmousedown = () => {
 </style>
 
 <style lang="scss">
+.item-badge .el-badge__content.is-fixed {
+    top: 4px;
+}
+
 .order-service-spin {
     height: 100%;
     .n-spin-content {