Browse Source

第五阶段第二部分完整版

Tang 3 years ago
parent
commit
59b2f6528b
67 changed files with 10022 additions and 509 deletions
  1. 6 1
      src/api/api.js
  2. BIN
      src/assets/images/telPhoto.png
  3. 25 17
      src/assets/styles/index.scss
  4. 34 1
      src/components/searchBoxNew.vue
  5. 26 3
      src/components/tableList.vue
  6. 34 0
      src/newApi/activityRecommend.js
  7. 10 0
      src/newApi/business.js
  8. 69 0
      src/newApi/newOrder.js
  9. 35 0
      src/newApi/refund.js
  10. 1 1
      src/store/modules/tagsView.js
  11. 2 0
      src/utils/request.js
  12. 0 1
      src/views/2Cport/adSlotManagement/index.vue
  13. 62 51
      src/views/2Cport/adSlotManagement/tab1.vue
  14. 648 7
      src/views/2Cport/adSlotManagement/tab2.vue
  15. 36 2
      src/views/2Cport/adv/index.vue
  16. 327 0
      src/views/2Cport/pageSettings/footer.vue
  17. 382 0
      src/views/2Cport/pageSettings/header.vue
  18. 41 0
      src/views/2Cport/pageSettings/index.vue
  19. 356 0
      src/views/2Cport/pageSettings/links.vue
  20. 41 0
      src/views/2Cport/referralManageMent/index.vue
  21. 552 0
      src/views/2Cport/referralManageMent/tab1/addGL.vue
  22. 186 0
      src/views/2Cport/referralManageMent/tab1/tab1.vue
  23. 552 0
      src/views/2Cport/referralManageMent/tab2/addGL.vue
  24. 186 0
      src/views/2Cport/referralManageMent/tab2/tab2.vue
  25. 8 4
      src/views/Marketing/goods/commodityManageMent/add/index.vue
  26. 8 4
      src/views/Marketing/goods/commodityManageMent/edit/index.vue
  27. 11 10
      src/views/Marketing/goods/commodityManageMent/index.vue
  28. 1 0
      src/views/Marketing/goods/courseInquiryList/classNumBox.vue
  29. 5 4
      src/views/Marketing/goods/courseInquiryList/index.vue
  30. 8 1
      src/views/Marketing/order/bill/index.vue
  31. 35 5
      src/views/Marketing/order/offlineOrder/batchRecord/firstStep/index.vue
  32. 57 24
      src/views/Marketing/order/offlineOrder/batchRecord/index.vue
  33. 588 26
      src/views/Marketing/order/offlineOrder/batchRecord/secondStep/index.vue
  34. 226 0
      src/views/Marketing/order/offlineOrder/batchRecord/secondStep/selectClass.vue
  35. 424 0
      src/views/Marketing/order/offlineOrder/batchRecord/secondStep/setGoodsList.vue
  36. 508 3
      src/views/Marketing/order/offlineOrder/batchRecord/thirdStep/index.vue
  37. 337 0
      src/views/Marketing/order/offlineOrder/batchRecord/thirdStep/informationAdd.vue
  38. 493 0
      src/views/Marketing/order/offlineOrder/billingBillCharges/index.vue
  39. 242 268
      src/views/Marketing/order/offlineOrder/index.vue
  40. 250 0
      src/views/Marketing/order/offlineOrder/orderChargeInfo/bodyBox.vue
  41. 301 0
      src/views/Marketing/order/offlineOrder/orderChargeInfo/goodsDocument/costPrice.vue
  42. 427 0
      src/views/Marketing/order/offlineOrder/orderChargeInfo/goodsDocument/goodsInfos.vue
  43. 171 0
      src/views/Marketing/order/offlineOrder/orderChargeInfo/goodsDocument/refundInfos.vue
  44. 294 0
      src/views/Marketing/order/offlineOrder/orderChargeInfo/goodsDocument/studentOrder.vue
  45. 27 0
      src/views/Marketing/order/offlineOrder/orderChargeInfo/index.vue
  46. 150 0
      src/views/Marketing/order/offlineOrder/orderChargeInfo/topBox.vue
  47. 638 0
      src/views/Marketing/order/offlineOrder/orderDetailsT/index.vue
  48. 435 0
      src/views/Marketing/order/offlineOrder/orderDetailsT/refundDocument/index.vue
  49. 20 30
      src/views/Marketing/order/orderList/index.vue
  50. 386 0
      src/views/Marketing/order/pendingRefundOrder/index.vue
  51. 241 0
      src/views/Marketing/order/pendingRefundOrder/refundDia.vue
  52. 3 3
      src/views/education/classManageMent/classHours/index.vue
  53. 10 2
      src/views/education/classManageMent/learningHoursRecordList/index.vue
  54. 3 2
      src/views/education/classManageMent/listOfhoursToBeReviewed/index.vue
  55. 3 3
      src/views/education/classManageMent/studentMenu/index.vue
  56. 6 6
      src/views/education/studentManageMent/studentXQ/studyRecord.vue
  57. 1 1
      src/views/resource/bankManagement/testPaperManagement/editPaper/baseEditPaper/index.vue
  58. 1 1
      src/views/resource/bankManagement/testPaperManagement/editPaper/topicEditPaper/index.vue
  59. 6 2
      src/views/resource/videoManagement/chapter/add/index.vue
  60. 5 1
      src/views/resource/videoManagement/chapter/edit/index.vue
  61. 2 2
      src/views/resource/videoManagement/courseManagement/basicInfoAdd/index.vue
  62. 2 2
      src/views/resource/videoManagement/courseManagement/basicInfoEdit/index.vue
  63. 30 16
      src/views/resource/videoManagement/festival/add/index.vue
  64. 5 1
      src/views/resource/videoManagement/festival/edit/index.vue
  65. 5 1
      src/views/resource/videoManagement/moduleManagement/add/index.vue
  66. 5 1
      src/views/resource/videoManagement/moduleManagement/edit/index.vue
  67. 33 2
      src/views/systemManagement/auditManagement/assignReviewers/index.vue

+ 6 - 1
src/api/api.js

@@ -93,7 +93,9 @@ import reviewer from '../newApi/reviewer'//学时审核用户
 import invoice from '../newApi/invoice'//订单发票
 import orderBusiness from '../newApi/orderBusiness'//录单配置
 import orderConfigBusiness from '../newApi/orderConfigBusiness'//配置详情
-
+import newOrder from '../newApi/newOrder'//录单管理
+import refund from '../newApi/refund'//退费管理
+import activityRecommend from '../newApi/activityRecommend'//商品推荐管理
 
 
 
@@ -168,6 +170,9 @@ export default {
     ...invoice,
     ...orderBusiness,
     ...orderConfigBusiness,
+    ...newOrder,
+    ...refund,
+    ...activityRecommend,
 
     // ...login,
     // ...profession,

BIN
src/assets/images/telPhoto.png


+ 25 - 17
src/assets/styles/index.scss

@@ -1,16 +1,17 @@
-@import './variables.scss';
-@import './mixin.scss';
-@import './transition.scss';
-@import './element-ui.scss';
-@import './sidebar.scss';
-@import './btn.scss';
+@import "./variables.scss";
+@import "./mixin.scss";
+@import "./transition.scss";
+@import "./element-ui.scss";
+@import "./sidebar.scss";
+@import "./btn.scss";
 
 body {
   height: 100%;
   -moz-osx-font-smoothing: grayscale;
   -webkit-font-smoothing: antialiased;
   text-rendering: optimizeLegibility;
-  font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
+  font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB,
+    Microsoft YaHei, Arial, sans-serif;
 }
 // 设置全局
 .el-table__fixed-right {
@@ -19,8 +20,8 @@ body {
 label {
   font-weight: 700;
 }
-.myMessageClass{
-  z-index: 3000!important;
+.myMessageClass {
+  z-index: 3000 !important;
 }
 html {
   height: 100%;
@@ -109,7 +110,8 @@ aside {
   display: block;
   line-height: 32px;
   font-size: 16px;
-  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
+  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
+    Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
   color: #2c3e50;
   -webkit-font-smoothing: antialiased;
   -moz-osx-font-smoothing: grayscale;
@@ -139,7 +141,7 @@ aside {
 }
 
 .text-center {
-  text-align: center
+  text-align: center;
 }
 
 .sub-navbar {
@@ -150,7 +152,13 @@ aside {
   text-align: right;
   padding-right: 20px;
   transition: 600ms ease position;
-  background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%);
+  background: linear-gradient(
+    90deg,
+    rgba(32, 182, 249, 1) 0%,
+    rgba(32, 182, 249, 1) 0%,
+    rgba(33, 120, 241, 1) 100%,
+    rgba(33, 120, 241, 1) 100%
+  );
 
   .subtitle {
     font-size: 20px;
@@ -185,10 +193,10 @@ aside {
     margin-bottom: 10px;
   }
 }
-ul{
+ul {
   padding: 0px;
 }
-li{
+li {
   list-style-type: none;
 }
 //refine vue-multiselect plugin
@@ -201,9 +209,9 @@ li{
 }
 
 .activeStyIcons {
-  color: #fff!important;
-  background-color: #f56c6c!important;
-  border-color: #f56c6c!important;
+  color: #fff !important;
+  background-color: #f56c6c !important;
+  border-color: #f56c6c !important;
 }
 .copyDataLi {
   border: 1px solid #999;

+ 34 - 1
src/components/searchBoxNew.vue

@@ -13,6 +13,19 @@
         >
       </div>
     </div>
+    <div class="inputListBox" v-if="pendingType">
+      <div class="fon_s">审核状态:</div>
+      <div>
+        <el-button
+          :type="formData.periodStatus === item.value ? 'primary' : ''"
+          :size="size"
+          v-for="(item, index) in pendlists"
+          :key="index"
+          @click="topPendingType(item.value)"
+          >{{ item.label }}</el-button
+        >
+      </div>
+    </div>
     <div class="inputListBox" v-if="shType">
       <div class="fon_s">审核状态:</div>
       <div>
@@ -450,6 +463,7 @@ export default {
   props: [
     "formList",
     "topType",
+    "pendingType",
     "formData",
     "shType",
     "hoursType",
@@ -482,6 +496,16 @@ export default {
           value: 4,
         },
       ],
+      pendlists: [
+        {
+          label: "初审",
+          value: 0,
+        },
+        {
+          label: "复审",
+          value: "1,2",
+        },
+      ],
       lists5: [
         {
           label: "全部",
@@ -508,7 +532,7 @@ export default {
         {
           label: "审核中",
           value: 3,
-        }
+        },
       ],
       // classLists: [
       //   {
@@ -755,6 +779,15 @@ export default {
       this.formData.goodsType = status;
       this.$emit("search", 3);
     },
+    /**
+     *
+     * @param {int} status
+     * @remark 顶部定制按钮-根据审核状态类型点击快速搜索
+     */
+    topPendingType(status) {
+      this.formData.periodStatus = status;
+      this.$emit("search", 4);
+    },
     /**
      *
      * @param {int} status

+ 26 - 3
src/components/tableList.vue

@@ -680,6 +680,22 @@
           <span v-else-if="item.scope === 'convert'">{{
             $methodsTools.secondToDate(scope.row[item.prop], false)
           }}</span>
+          <div v-else-if="item.scope === 'studentServicePeriod'">
+            <span v-if="scope.row[item.prop1] === 1"
+              >{{ scope.row[item.prop2] }}年</span
+            >
+            <span v-if="scope.row[item.prop1] === 2"
+              >{{ scope.row[item.prop2] }}月</span
+            >
+            <span v-if="scope.row[item.prop1] === 3"
+              >{{ scope.row[item.prop2] }}日</span
+            >
+            <span v-if="scope.row[item.prop1] === 4">
+              {{ $methodsTools.onlyForma(scope.row[item.prop3]) }}
+              {{ scope.row[item.prop3] && scope.row[item.prop4] ? "至" : "" }}
+              {{ $methodsTools.onlyForma(scope.row[item.prop4]) }}
+            </span>
+          </div>
           <span v-else-if="item.scope === 'gfStatus'">{{
             scope.row[item.prop] === 0
               ? "否"
@@ -696,6 +712,9 @@
                 : ""
             }}
           </span>
+          <div v-else-if="item.scope === 'periodStatusShow'">
+            {{ scope.row[item.prop] === 2 ? "同意,待退款" : "待审核" }}
+          </div>
           <span v-else-if="item.scope === 'peopleNum'">{{
             scope.row[item.prop] === 0 ? "不限制" : scope.row[item.prop]
           }}</span>
@@ -1196,6 +1215,9 @@
               scope.row[item.prop3]
             }}{{ scope.row[item.prop4] ? "-" + scope.row[item.prop4] : "" }}
           </span>
+          <span v-else-if="item.scope === 'outStandingAmount'">
+            ¥{{ (scope.row[item.prop1] - scope.row[item.prop2]).toFixed(2) }}
+          </span>
           <span
             v-else-if="item.scope === 'sendStatus'"
             :style="scope.row[item.prop] === 0 ? 'color:red;' : ''"
@@ -1281,9 +1303,10 @@
             </template>
           </div>
           <ul v-else-if="item.scope === 'orderSnList'">
-            <li v-for="(item, index) in scope.row[item.prop]" :key="index">
-              {{ item.goodsName + " - " + item.orderSn
-              }}
+            <li v-for="(ty, index) in scope.row[item.prop]" :key="index">
+              <span v-if="ty">
+                {{ ty.goodsName + " - " + ty.orderSn }}
+              </span>
             </li>
           </ul>
           <div v-else-if="item.scope === 'priceRed'" style="color: red">

+ 34 - 0
src/newApi/activityRecommend.js

@@ -0,0 +1,34 @@
+import request from '@/utils/request' //引入axios请求及拦截器
+export default {
+    //新增商品推荐
+    appactivityrecommend(data) {
+        return request({
+            url: '/activity/recommend',
+            method: 'post',
+            data
+        })
+    },
+    //修改商品推荐
+    editactivityrecommend(data) {
+        return request({
+            url: '/activity/recommend/edit',
+            method: 'post',
+            data
+        })
+    },
+    //查询商品推荐列表
+    inquireactivityrecommendList(data) {
+        return request({
+            url: '/activity/recommend/list',
+            method: 'get',
+            params: data
+        })
+    },
+    //获取商品推荐详细信息
+    obtainactivityrecommend(data) {
+        return request({
+            url: `/activity/recommend/` + data,
+            method: 'get',
+        })
+    },
+}

+ 10 - 0
src/newApi/business.js

@@ -55,4 +55,14 @@ export default {
             data
         })
     },
+
+    //修改业务层次-退款审核
+    editRefundPeriodUserIdsCourseBusiness(data) {
+        return request({
+            url: '/course/business/editRefundPeriodUserIds',
+            method: 'post',
+            data
+        })
+    },
+
 }

+ 69 - 0
src/newApi/newOrder.js

@@ -0,0 +1,69 @@
+import request from '@/utils/request' //引入axios请求及拦截器
+export default {
+    //新增录单
+    apporderinput(data) {
+        return request({
+            url: '/order/input',
+            method: 'post',
+            data
+        })
+    },
+    //新增后台录单
+    apporderinputOrder(data) {
+        return request({
+            url: '/order/inputOrder',
+            method: 'post',
+            data
+        })
+    },
+    //查询录单列表
+    inquireorderinputList(data) {
+        return request({
+            url: '/order/input/list',
+            method: 'get',
+            params: data
+        })
+    },
+    //修改订单计费单-单个
+    editordersheetedit(data) {
+        return request({
+            url: '/order/sheet/edit',
+            method: 'post',
+            data
+        })
+    },
+    //修改录单总单计费单
+    editOrdersheetinput(data) {
+        return request({
+            url: '/order/sheet/input/edit',
+            method: 'post',
+            data
+        })
+    },
+    //获取录单详细信息
+    inquireorderinputdetail(data) {
+        return request({
+            url: '/order/input/detail',
+            method: 'get',
+            params: data
+        })
+    },
+    //查询录单详情用户列表
+    inquireorderinputuserList(data) {
+        return request({
+            url: '/order/input/userList',
+            method: 'get',
+            params: data
+        })
+    },
+    //查询录单用户商品列表
+    inquireorderinputuserGoodsList(data) {
+        return request({
+            url: '/order/input/userGoodsList',
+            method: 'get',
+            params: data
+        })
+    },
+    
+    
+}

+ 35 - 0
src/newApi/refund.js

@@ -0,0 +1,35 @@
+import request from '@/utils/request' //引入axios请求及拦截器
+export default {
+    //批量新增录单订单商品退款
+    apporderinputOrderrefund(data) {
+        return request({
+            url: '/order/refund',
+            method: 'post',
+            data
+        })
+    },
+    //查询订单商品退款列表
+    inquireorderrefundlist(data) {
+        return request({
+            url: '/order/refund/list',
+            method: 'get',
+            params: data
+        })
+    },
+    //初审确认
+    editorderrefundfirstPeriod(data) {
+        return request({
+            url: '/order/refund/firstPeriod',
+            method: 'post',
+            data
+        })
+    },
+    //复审确认
+    editorderrefundconfirmPeriod(data) {
+        return request({
+            url: '/order/refund/confirmPeriod',
+            method: 'post',
+            data
+        })
+    },
+}

+ 1 - 1
src/store/modules/tagsView.js

@@ -2,7 +2,7 @@ import { MessageBox } from 'element-ui';
 const state = {
   visitedViews: [],
   cachedViews: [],
-  alertPage: ["CommodityManageMentAdd", "CommodityManageMentEdit", "FestivalAdd", "FestivalEdit", "ChapterAdd", "ChapterEdit", "ModuleManagementAdd", "ModuleManagementEdit", "BasicInfoEdit", "BasicInfoAdd", "ChapterContent", "EditCourse", "OrderDetail", "OrderPrice", "AddOrder", "EditPaper", "AddPaper", "TopicAddPaper", "ChapterVolumeManagementEdit", "ChapterVolumeManagementAdd", "VolumeManagementAdd", "VolumeManagementEdit", "HandoutListEdit", "HandoutListAdd", "StudentXQ", "AddClass", "ManageClass", "NotificationInfo", "NotificationListAdd", "NotificationEdit", "BulkImportPlan", "MatchInfoData","BatchRecord"],
+  alertPage: ["CommodityManageMentAdd", "CommodityManageMentEdit", "FestivalAdd", "FestivalEdit", "ChapterAdd", "ChapterEdit", "ModuleManagementAdd", "ModuleManagementEdit", "BasicInfoEdit", "BasicInfoAdd", "ChapterContent", "EditCourse", "OrderDetail", "OrderPrice", "AddOrder", "EditPaper", "AddPaper", "TopicAddPaper", "ChapterVolumeManagementEdit", "ChapterVolumeManagementAdd", "VolumeManagementAdd", "VolumeManagementEdit", "HandoutListEdit", "HandoutListAdd", "StudentXQ", "AddClass", "ManageClass", "NotificationInfo", "NotificationListAdd", "NotificationEdit", "BulkImportPlan", "MatchInfoData", "BatchRecord", "OrderChargeInfo", "RefundDocument", "BillingBillCharges"],
 }
 
 const mutations = {

+ 2 - 0
src/utils/request.js

@@ -87,6 +87,8 @@ service.interceptors.response.use(res => {
       showClose: true
     })
     return Promise.reject(new Error(msg))
+  } else if (code === 510 || code === 511) {
+    return res.data
   } else if (code !== 200) {
     Notification.error({
       title: msg

+ 0 - 1
src/views/2Cport/adSlotManagement/index.vue

@@ -11,7 +11,6 @@
         size="mini"
         :type="activeIndex === 2 ? 'primary' : ''"
         @click="activeIndex = 2"
-        disabled
         >PC官网</el-button
       >
     </div>

+ 62 - 51
src/views/2Cport/adSlotManagement/tab1.vue

@@ -43,46 +43,48 @@
           style="width: 100%; margin-top: 10px"
           border
         >
-          <template v-for="(item, index) in tableSet">
-            <el-table-column
-              :width="item.width"
-              :key="index"
-              :prop="item.prop"
-              :label="item.label"
-              align="center"
-            >
-              <template slot-scope="scope">
-                <div v-if="item.scope === 'img'">
-                  <el-image
-                    style="width: 225px; height: 96px"
-                    :src="$methodsTools.splitImgHost(scope.row[item.prop])"
-                    :preview-src-list="[
-                      $methodsTools.splitImgHost(scope.row[item.prop]),
-                    ]"
-                  >
-                  </el-image>
-                </div>
-                <div v-else-if="item.scope === 'input'">
-                  <el-input-number
-                    v-model="scope.row[item.prop]"
-                    :controls="false"
-                    :min="0"
-                    :precision="0"
-                    style="width: 100%"
-                  ></el-input-number>
-                </div>
-                <span v-else-if="item.scope === 'status'">
-                  {{
-                    scope.row[item.prop] === 1
-                      ? "启用"
-                      : scope.row[item.prop] === 0
-                      ? "关闭"
-                      : "未知"
-                  }}
-                </span>
-                <div v-else>{{ scope.row[item.prop] }}</div>
-              </template></el-table-column
-            ></template
+          <el-table-column
+            v-for="(item, index) in tableSet"
+            :width="item.width"
+            :key="index"
+            :prop="item.prop"
+            :label="item.label"
+            align="center"
+          >
+            <template slot-scope="scope">
+              <div
+                v-if="item.scope === 'img'"
+                style="width: 100%; height: 100%"
+              >
+                <el-image
+                  style="width: 100%; height: 100%"
+                  :src="$methodsTools.splitImgHost(scope.row[item.prop])"
+                  :preview-src-list="[
+                    $methodsTools.splitImgHost(scope.row[item.prop]),
+                  ]"
+                >
+                </el-image>
+              </div>
+              <div v-else-if="item.scope === 'input'">
+                <el-input-number
+                  v-model="scope.row[item.prop]"
+                  :controls="false"
+                  :min="0"
+                  :precision="0"
+                  style="width: 100%"
+                ></el-input-number>
+              </div>
+              <span v-else-if="item.scope === 'status'">
+                {{
+                  scope.row[item.prop] === 1
+                    ? "启用"
+                    : scope.row[item.prop] === 0
+                    ? "关闭"
+                    : "未知"
+                }}
+              </span>
+              <div v-else>{{ scope.row[item.prop] }}</div>
+            </template></el-table-column
           >
           <el-table-column
             fixed="right"
@@ -96,8 +98,8 @@
                 size="small"
                 @click="editList(0, scope.row)"
                 >修改</el-button
-              >
-            </template>
+              ></template
+            >
           </el-table-column>
         </el-table>
       </div>
@@ -333,14 +335,16 @@ export default {
       this.disabledBtn = false;
     },
     getInfo() {
-      this.$api.inquireadvlocationlist({ status: 1 }).then((res) => {
-        this.tabList = res.rows;
-        if (res.rows.length) {
-          this.activeid = res.rows[0].locationId + "";
-          this.activeFunc(res.rows[0].locationId);
-          this.second = res.rows[0].intervalTime;
-        }
-      });
+      this.$api
+        .inquireadvlocationlist({ status: 1, platform: 1 })
+        .then((res) => {
+          this.tabList = res.rows;
+          if (res.rows.length) {
+            this.activeid = res.rows[0].locationId + "";
+            this.activeFunc(res.rows[0].locationId);
+            this.second = res.rows[0].intervalTime;
+          }
+        });
     },
     close() {
       this.dialogVisible = false;
@@ -404,7 +408,13 @@ export default {
       var statusNS = false;
       this.tableData.forEach((item) => {
         if (item.status === 1) {
-          anum++;
+          if (this.statusPop === 0) {
+            if (item.id !== this.listData.id) {
+              anum++;
+            }
+          } else {
+            anum++;
+          }
         }
         if (this.statusPop === 1) {
           if (item.sort == this.listData.sort) {
@@ -442,6 +452,7 @@ export default {
         this.$api
           .editbaseadvertising(this.listData)
           .then((res) => {
+            console.log(this.listData);
             this.$message.success("修改成功");
             this.dialogVisible = false;
             this.activeFunc(this.activeid);

+ 648 - 7
src/views/2Cport/adSlotManagement/tab2.vue

@@ -1,21 +1,662 @@
 <template>
   <div id="tab2">
-tab2
+    <el-tabs
+      type="border-card"
+      style="margin-top: 16px"
+      v-model="activeid"
+      @tab-click="activeFunc(activeid)"
+    >
+      <el-tab-pane
+        v-for="(item, index) in tabList"
+        :label="item.name"
+        :name="item.locationId + ''"
+        :key="index"
+      ></el-tab-pane>
+      <div>
+        <div>
+          轮播间隔:{{ second }}S
+          <el-popover placement="bottom" trigger="manual" v-model="visible">
+            <el-input-number
+              v-model="copySecond"
+              :min="1"
+              :max="60"
+              :precision="0"
+            ></el-input-number>
+            <div style="text-align: center; margin-top: 10px">
+              <el-button size="mini" @click="visible = false">取消</el-button
+              ><el-button size="mini" @click="editFun">确定</el-button>
+            </div>
+            <el-button size="mini" slot="reference" @click="visibleFun"
+              >修改</el-button
+            >
+          </el-popover>
+          <el-button
+            size="mini"
+            @click="editList(1)"
+            type="success"
+            style="margin-left: 10px"
+            >添加轮播</el-button
+          >
+        </div>
+        <el-table
+          :data="tableData"
+          style="width: 100%; margin-top: 10px"
+          border
+        >
+          <el-table-column
+            v-for="(item, index) in tableSet"
+            :width="item.width"
+            :key="index"
+            :prop="item.prop"
+            :label="item.label"
+            align="center"
+          >
+            <template slot-scope="scope">
+              <div
+                v-if="item.scope === 'img'"
+                style="width: 100%; height: 100%"
+              >
+                <el-image
+                  style="width: 100%; height: 100%"
+                  :src="$methodsTools.splitImgHost(scope.row[item.prop])"
+                  :preview-src-list="[
+                    $methodsTools.splitImgHost(scope.row[item.prop]),
+                  ]"
+                >
+                </el-image>
+              </div>
+              <div v-else-if="item.scope === 'input'">
+                <el-input-number
+                  v-model="scope.row[item.prop]"
+                  :controls="false"
+                  :min="0"
+                  :precision="0"
+                  style="width: 100%"
+                ></el-input-number>
+              </div>
+              <span v-else-if="item.scope === 'status'">
+                {{
+                  scope.row[item.prop] === 1
+                    ? "启用"
+                    : scope.row[item.prop] === 0
+                    ? "关闭"
+                    : "未知"
+                }}
+              </span>
+              <div v-else>{{ scope.row[item.prop] }}</div>
+            </template></el-table-column
+          >
+          <el-table-column
+            fixed="right"
+            label="操作"
+            width="100"
+            align="center"
+          >
+            <template slot-scope="scope">
+              <el-button
+                type="text"
+                size="small"
+                @click="editList(0, scope.row)"
+                >修改</el-button
+              >
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+    </el-tabs>
+    <el-dialog
+      @closed="loadingClose"
+      :visible.sync="dialogVisible"
+      width="680px"
+      :show-close="false"
+      :close-on-click-modal="false"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">
+          {{ statusPop === 1 ? "添加" : statusPop === 0 ? "修改" : "详情" }}
+        </div>
+        <div class="rightBoxs">
+          <img src="@/assets/images/Close@2x.png" alt="" @click="close" />
+        </div>
+      </div>
+      <div>
+        <el-form
+          label-position="right"
+          label-width="170px"
+          :model="listData"
+          :rules="rules"
+          ref="listData"
+        >
+          <el-form-item label="图片标题" prop="advName">
+            <el-input v-model="listData.advName"></el-input>
+          </el-form-item>
+          <el-form-item label="图片" prop="adverUrl">
+            <div class="dis_fs">
+              <span v-if="!listData.adverUrl">暂无图片</span>
+              <img
+                v-else
+                class="imgBoxs"
+                :src="$methodsTools.splitImgHost(listData.adverUrl)"
+                alt="加载失败"
+              />
+            </div>
+            <div class="styPsty">
+              <label class="btns"
+                >修改封面
+                <input
+                  ref="file"
+                  type="file"
+                  style="display: none"
+                  @change="editImg"
+                />
+              </label>
+              <div style="font-size: 12px; color: #999; line-height: 17px">
+                注:请上传小于300kb,尺寸为
+                <span style="color: red">750*320</span>
+                的像素图片,支持jpg、jpeg、png等类型
+              </div>
+            </div>
+          </el-form-item>
+          <el-form-item label="banner栏两侧颜色填充" prop="color">
+            <el-color-picker
+              v-model="listData.color"
+              show-alpha
+              :predefine="predefineColors"
+            >
+            </el-color-picker>
+          </el-form-item>
+          <el-form-item
+            label="跳转位置"
+            :required="
+              listData.jumpType === 2 ||
+              listData.jumpType === 3 ||
+              listData.jumpType === 4
+                ? true
+                : false
+            "
+          >
+            <el-select
+              v-model="listData.jumpType"
+              placeholder="请选择跳转类型"
+              clearable
+            >
+              <el-option
+                v-for="(item, index) in options"
+                :key="index"
+                :label="item.label"
+                :value="item.value"
+              >
+              </el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item
+            label=""
+            v-if="
+              listData.jumpType === 2 ||
+              listData.jumpType === 3 ||
+              listData.jumpType === 4
+            "
+            :prop="
+              listData.jumpType === 2 ||
+              listData.jumpType === 3 ||
+              listData.jumpType === 4
+                ? 'jumpUrl'
+                : ''
+            "
+          >
+            <el-input
+              v-model="listData.jumpUrl"
+              :placeholder="
+                listData.jumpType === 2
+                  ? '请输入URL'
+                  : listData.jumpType === 3
+                  ? '请输入内部接口地址'
+                  : listData.jumpType === 4
+                  ? '请输入外部接口地址'
+                  : ''
+              "
+            ></el-input>
+          </el-form-item>
+          <el-form-item
+            label="appid"
+            prop="remarks"
+            v-if="listData.jumpType === 4"
+          >
+            <el-input
+              v-model="listData.remarks"
+              placeholder="请输入外部小程序appid"
+            ></el-input>
+          </el-form-item>
+          <el-form-item label="排序" prop="sort">
+            <el-input-number
+              :min="1"
+              v-model="listData.sort"
+              :precision="0"
+              :controls="false"
+            ></el-input-number>
+          </el-form-item>
+          <el-form-item label="发布状态" prop="status">
+            <el-radio-group v-model="listData.status">
+              <el-radio :label="1">启用</el-radio>
+              <el-radio :label="0">关闭</el-radio>
+            </el-radio-group>
+          </el-form-item>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="close">取 消</el-button>
+        <el-button @click="submitForm('listData')" :loading="disabledBtn"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
   </div>
 </template>
 
 <script>
 export default {
-  data () {
+  data() {
+    var valiIcon = (rule, value, callback) => {
+      // 图片验证
+      if (!this.listData.adverUrl) {
+        callback(new Error("请上传图片"));
+      } else {
+        callback();
+      }
+    };
     return {
-    }
+      predefineColors: [
+        "#ff4500",
+        "#ff8c00",
+        "#ffd700",
+        "#90ee90",
+        "#00ced1",
+        "#1e90ff",
+        "#c71585",
+        "rgba(255, 69, 0, 0.68)",
+        "rgb(255, 120, 0)",
+        "hsv(51, 100, 98)",
+        "hsva(120, 40, 94, 0.5)",
+        "hsl(181, 100%, 37%)",
+        "hsla(209, 100%, 56%, 0.73)",
+        "#c7158577",
+      ],
+      disabledBtn: false,
+      activeid: "",
+      visible: false,
+      second: "",
+      copySecond: "",
+      tableSet: [
+        {
+          label: "排序",
+          prop: "sort",
+          width: "120px",
+        },
+        {
+          label: "广告标题",
+          prop: "advName",
+        },
+        {
+          label: "图片",
+          prop: "adverUrl",
+          scope: "img",
+        },
+        {
+          label: "颜色填充值",
+          prop: "color",
+          // scope: "color",
+        },
+        {
+          label: "跳转位置",
+          prop: "jumpUrl",
+        },
+        {
+          label: "发布状态",
+          prop: "status",
+          scope: "status",
+        },
+      ],
+      tabList: [],
+      tableData: [],
+      dialogVisible: false,
+      listData: {},
+      rules: {
+        advName: [
+          { required: true, message: "请输入广告标题", trigger: "blur" },
+        ],
+        jumpUrl: [{ required: true, message: "请输入内容", trigger: "blur" }],
+        remarks: [
+          { required: true, message: "请输入外部小程序appid", trigger: "blur" },
+        ],
+        adverUrl: [{ required: true, validator: valiIcon, trigger: "change" }],
+        status: [
+          { required: true, message: "请选择发布状态", trigger: "change" },
+        ],
+        sort: [{ required: true, message: "请输入图片排序", trigger: "blur" }],
+      },
+      statusPop: 0,
+      options: [
+        {
+          label: "无跳转",
+          value: 1,
+        },
+        {
+          label: "URL",
+          value: 2,
+        },
+        {
+          label: "内部接口地址",
+          value: 3,
+        },
+        {
+          label: "外部接口地址",
+          value: 4,
+        },
+      ],
+    };
+  },
+  mounted() {
+    this.getInfo();
   },
   methods: {
-
-  }
-}
+    loadingClose() {
+      this.$refs["listData"].resetFields();
+      this.disabledBtn = false;
+    },
+    getInfo() {
+      this.$api
+        .inquireadvlocationlist({ status: 1, platform: 2 })
+        .then((res) => {
+          this.tabList = res.rows;
+          if (res.rows.length) {
+            this.activeid = res.rows[0].locationId + "";
+            this.activeFunc(res.rows[0].locationId);
+            this.second = res.rows[0].intervalTime;
+          }
+        });
+    },
+    close() {
+      this.dialogVisible = false;
+    },
+    /**
+     * 修改单条轮播信息
+     */
+    editList(int, v) {
+      if (int === 1) {
+        this.statusPop = 1;
+        this.listData = {
+          adverUrl: "oss/images/avatar/20211013/1634097664410_1397766697",
+          status: 1,
+        };
+      } else {
+        this.statusPop = 0;
+        this.listData = JSON.parse(JSON.stringify(v));
+      }
+      this.listData.locationId = Number(this.activeid);
+      this.dialogVisible = true;
+    },
+    /**
+     * 修改封面
+     */
+    editImg(e) {
+      var file = e.target.files[0];
+      if (file === undefined) {
+        return;
+      }
+      if (file.size > 0.3 * 1024 * 1024) {
+        this.$message.warning("图片不得大于300kb");
+        return;
+      }
+      var type = this.$refs.file.value.toLowerCase().split(".").splice(-1);
+      if (type[0] != "jpg" && type[0] != "png" && type[0] != "jpeg") {
+        this.$message.warning("上传格式需为:.jpg/.png/.jpeg");
+        this.$refs.file.value = "";
+        return;
+      }
+      this.$upload.upload(file, 0).then((res) => {
+        this.$set(this.listData, "adverUrl", res);
+        console.log(this.listData);
+      });
+    },
+    /**
+     * 提交修改/添加 表单验证
+     */
+    submitForm(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          this.submit();
+        } else {
+          console.log("error submit!!");
+          return false;
+        }
+      });
+    },
+    submit() {
+      this.disabledBtn = true;
+      var anum = 0;
+      var statusNS = false;
+      this.tableData.forEach((item) => {
+        if (item.status === 1) {
+          if (this.statusPop === 0) {
+            if (item.id !== this.listData.id) {
+              anum++;
+            }
+          } else {
+            anum++;
+          }
+        }
+        if (this.statusPop === 1) {
+          if (item.sort == this.listData.sort) {
+            statusNS = true;
+          }
+        } else {
+          if (item.sort == this.listData.sort && item.id !== this.listData.id) {
+            statusNS = true;
+          }
+        }
+      });
+      if (anum >= 5 && this.listData.status === 1) {
+        this.$message.error("轮播图启用数量不得大于5个!");
+        this.disabledBtn = false;
+        return;
+      }
+      if (statusNS) {
+        this.$message.warning("存在相同排序,请重新设置排序");
+        this.disabledBtn = false;
+        return;
+      }
+      if (this.statusPop === 1) {
+        this.$api
+          .appbaseadvertising(this.listData)
+          .then((res) => {
+            this.$message.success("新增成功");
+            this.dialogVisible = false;
+            this.activeFunc(this.activeid);
+          })
+          .catch(() => {
+            this.disabledBtn = false;
+          });
+      }
+      if (this.statusPop === 0) {
+        this.$api
+          .editbaseadvertising(this.listData)
+          .then((res) => {
+            console.log(this.listData);
+            this.$message.success("修改成功");
+            this.dialogVisible = false;
+            this.activeFunc(this.activeid);
+          })
+          .catch(() => {
+            this.disabledBtn = false;
+          });
+      }
+    },
+    activeFunc(id) {
+      if (this.visible) {
+        this.visible = false;
+      }
+      this.$api.inquirebaseadvertisinglist({ locationId: id }).then((res) => {
+        this.tabList.forEach((item) => {
+          if (item.locationId == id) {
+            this.second = item.intervalTime;
+          }
+        });
+        this.tableData = res.rows;
+      });
+    },
+    visibleFun() {
+      if (this.visible) {
+        this.visible = false;
+        return;
+      }
+      this.copySecond = this.second;
+      this.visible = true;
+    },
+    /**
+     * 确定修改轮播间隔
+     */
+    editFun() {
+      this.$api
+        .editadvlocation({
+          locationId: this.activeid,
+          intervalTime: this.copySecond,
+        })
+        .then((res) => {
+          this.$api.inquireadvlocationlist({ status: 1 }).then((res) => {
+            this.tabList = res.rows;
+            if (res.rows.length) {
+              this.activeFunc(this.activeid);
+              this.second = res.rows[0].intervalTime;
+              this.$message.success("修改成功");
+              this.visible = false;
+            }
+          });
+        });
+    },
+  },
+};
 </script>
 
 <style lang="less" scoped>
-
+.styFlex {
+  margin-top: 10px;
+  text-align: center;
+}
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+.dis_fs {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 337.5px;
+  height: 144px;
+  border: 1px solid #999;
+  .imgBoxs {
+    width: 100%;
+    height: 100%;
+  }
+}
+.styPsty {
+  margin-top: 10px;
+  display: flex;
+  align-items: center;
+  .btns {
+    border: 1px solid #999;
+    font-size: 12px;
+    height: 28px;
+    line-height: 28px;
+    padding: 0px 10px;
+    border-radius: 4px;
+    cursor: pointer;
+    margin-right: 10px;
+    flex-shrink: 0;
+  }
+}
 </style>

+ 36 - 2
src/views/2Cport/adv/index.vue

@@ -96,7 +96,7 @@
 import tableList from "@/components/tableList";
 import pagination from "@/components/pagination";
 export default {
-  name:"Adv",
+  name: "Adv",
   components: { tableList, pagination },
   data() {
     return {
@@ -131,6 +131,22 @@ export default {
           prop: "intervalTime",
           hidden: true,
         },
+        {
+          label: "适用区域",
+          prop: "platform",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "小程序",
+              value: 1,
+            },
+            {
+              label: "PC网站",
+              value: 2,
+            },
+          ],
+        },
         {
           label: "状态",
           prop: "status",
@@ -157,6 +173,21 @@ export default {
           prop: "intervalTime",
           scope: "Number",
         },
+        {
+          label: "适用区域",
+          prop: "platform",
+          scope: "status",
+          options: [
+            {
+              label: "小程序",
+              value: 1,
+            },
+            {
+              label: "PC网站",
+              value: 2,
+            },
+          ],
+        },
         {
           label: "状态",
           prop: "status",
@@ -188,6 +219,9 @@ export default {
         intervalTime: [
           { required: true, message: "请输入间隔秒数", trigger: "blur" },
         ],
+        platform: [
+          { required: true, message: "请选择适用区域", trigger: "change" },
+        ],
         status: [{ required: true, message: "请选择状态", trigger: "change" }],
       },
     };
@@ -195,7 +229,7 @@ export default {
   mounted() {
     this.search();
   },
-  activated(){
+  activated() {
     this.search();
   },
   methods: {

+ 327 - 0
src/views/2Cport/pageSettings/footer.vue

@@ -0,0 +1,327 @@
+<template>
+  <div id="footer">
+    <div class="smallBox">
+      <div style="text-align: right">
+        <el-button :size="size" @click="add(1)">添加</el-button>
+      </div>
+      <el-table :data="listData" style="width: 700px; margin-top: 10px" border>
+        <el-table-column
+          v-for="(item, index) in tableSet"
+          :width="item.width"
+          :key="index"
+          :prop="item.prop"
+          :label="item.label"
+          align="center"
+        >
+          <template slot-scope="scope">
+            <div v-if="item.scope === 'input'">
+              <el-input-number
+                @blur="changeVal(scope.row)"
+                v-model="scope.row[item.prop]"
+                :controls="false"
+                :min="0"
+                :precision="0"
+                style="width: 80%"
+              ></el-input-number>
+            </div>
+            <div v-else-if="item.scope === 'set'">
+              <el-button type="text" @click="add(0, scope.row, scope.$index)"
+                >修改</el-button
+              >
+              <el-button type="text" @click="del(scope.$index)">删除</el-button>
+            </div>
+            <div v-else>{{ scope.row[item.prop] }}</div>
+          </template></el-table-column
+        >
+      </el-table>
+      <div style="text-align: center; margin-top: 20px">
+        <el-button :size="size">取 消</el-button>
+        <el-button :size="size" type="primary" @click="submit">保 存</el-button>
+      </div>
+    </div>
+    <el-dialog
+      @closed="loadingClose"
+      :visible.sync="dialogVisible"
+      width="680px"
+      :show-close="false"
+      :close-on-click-modal="false"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">
+          {{ statusPop === 1 ? "添加" : statusPop === 0 ? "修改" : "详情" }}
+        </div>
+        <div class="rightBoxs">
+          <img src="@/assets/images/Close@2x.png" alt="" @click="close" />
+        </div>
+      </div>
+      <div>
+        <el-form
+          label-position="right"
+          label-width="170px"
+          :model="boxData"
+          :rules="rules"
+          ref="boxData"
+        >
+          <el-form-item label="文本内容" prop="name">
+            <el-input v-model="boxData.name"></el-input>
+          </el-form-item>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="close">取 消</el-button>
+        <el-button @click="submitForm('boxData')" :loading="disabledBtn"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { listConfig,updateConfig } from "@/api/system/config";
+export default {
+  data() {
+    return {
+      disabledBtn: false,
+      dialogVisible: false,
+      size: "mini",
+      tableSet: [
+        {
+          label: "排序",
+          prop: "sort",
+          scope: "input",
+          width: "120px",
+        },
+        {
+          label: "文本内容",
+          prop: "name",
+        },
+        {
+          label: "操作",
+          scope: "set",
+          width: "160px",
+        },
+      ],
+      Nav: [],
+      initData: {},
+      listData: [],
+      statusPop: "",
+      boxData: {},
+      rules: {
+        name: [{ required: true, message: "请填写文本内容", trigger: "blur" }],
+      },
+      newIndex: "",
+    };
+  },
+  mounted() {
+    this.init();
+  },
+  methods: {
+    changeVal(row) {
+      if (!row.sort && row.sort !== 0) {
+        this.$message.warning("检测到你没有赋值或赋值异常,已自动赋值为0");
+        row.sort = 0;
+      } else {
+        for (let i = 0; i < this.listData.length; i++) {
+          if (
+            this.listData[i].name !== row.name &&
+            this.listData[i].sort == row.sort
+          ) {
+            this.$message.warning("检测到重复值,已自动赋值为0");
+            row.sort = 0;
+          }
+        }
+      }
+      this.listData.sort(this.sort);
+    },
+    sort(a, b) {
+      return a.sort - b.sort;
+    },
+    loadingClose() {
+      this.disabledBtn = false;
+    },
+    del(index) {
+      this.listData.splice(index, 1);
+    },
+    add(int, row, index) {
+      this.statusPop = int;
+      this.newIndex = index;
+      if (int === 0) {
+        this.boxData = JSON.parse(JSON.stringify(row));
+      }
+      if (int === 1) {
+        var indexNum = 0;
+        this.listData.forEach((item) => {
+          if (item.sort >= indexNum) {
+            indexNum = item.sort + 1;
+          }
+        });
+        this.boxData = {};
+        this.boxData.sort = indexNum;
+      }
+      this.dialogVisible = true;
+      this.$nextTick(() => {
+        this.$refs.boxData.clearValidate();
+      });
+    },
+    close() {
+      this.dialogVisible = false;
+    },
+    submitForm(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          if (this.statusPop === 1) {
+            this.listData.push(this.boxData);
+          } else {
+            this.listData.splice(this.newIndex, 1, this.boxData);
+          }
+          this.dialogVisible = false;
+        } else {
+          console.log("error submit!!");
+          return false;
+        }
+      });
+    },
+    init() {
+      listConfig({ configKey: "home.footer" }).then((res) => {
+        if (res.rows.length) {
+          this.initData = res.rows[0];
+          this.listData = JSON.parse(res.rows[0].configValue);
+        }
+      });
+    },
+    submit() {
+      let data = JSON.parse(JSON.stringify(this.listData));
+      let copySubmitData = JSON.parse(JSON.stringify(this.initData));
+      copySubmitData.configValue = JSON.stringify(data);
+      updateConfig(copySubmitData).then((res) => {
+        this.$message.success("保存成功");
+      });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.smallBox {
+  width: 700px;
+}
+
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+.dis_fs {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 337.5px;
+  height: 144px;
+  border: 1px solid #999;
+  .imgBoxs {
+    width: 100%;
+    height: 100%;
+  }
+}
+.styPsty {
+  margin-top: 10px;
+  display: flex;
+  align-items: center;
+  .btns {
+    border: 1px solid #999;
+    font-size: 12px;
+    height: 28px;
+    line-height: 28px;
+    padding: 0px 10px;
+    border-radius: 4px;
+    cursor: pointer;
+    margin-right: 10px;
+    flex-shrink: 0;
+  }
+}
+</style>

+ 382 - 0
src/views/2Cport/pageSettings/header.vue

@@ -0,0 +1,382 @@
+<template>
+  <div id="header">
+    <div>
+      <h5>导航效果预览</h5>
+      <div class="topSty_home">
+        <el-row :gutter="20">
+          <el-col :span="6" style="display: flex; flex-direction: row-reverse">
+            <div v-if="!listData.companyLogo" class="noLogoImg">logo图片</div>
+            <img
+              v-else
+              style="width: 216px; height: 46px"
+              :src="$methodsTools.splitImgHost(listData.companyLogo)"
+              alt="加载失败"
+            />
+          </el-col>
+          <el-col
+            :span="12"
+            style="display: flex; flex-direction: column; align-items: center"
+          >
+            <div>
+              <input class="dzStyInput" type="text" />
+              <div class="btnSty">搜索</div>
+            </div>
+            <div>
+              <ul class="ul_styLI">
+                <li
+                  v-for="(item, index) in compyList(listData.Nav)"
+                  :key="index"
+                >
+                  {{ item.name }}
+                </li>
+              </ul>
+            </div>
+          </el-col>
+          <el-col :span="6" class="flex_sty" style="font-size: 14px">
+            <img
+              style="width: 66px; height: 54px"
+              src="@/assets/images/telPhoto.png"
+              alt=""
+            />
+            <div style="flex: 1">
+              <h4 style="margin: 6px 0px">{{ listData.serviceTel.tel }}</h4>
+              <div>服务时间:周一至周日 {{ listData.serviceTel.time }}</div>
+            </div>
+          </el-col>
+        </el-row>
+      </div>
+    </div>
+    <div>
+      <h5>企业标识</h5>
+      <ul style="margin-left: 20px">
+        <li class="liSty">
+          <span style="align-self: flex-start">LOGO图片</span>
+          <div>
+            <div
+              style="
+                width: 216px;
+                height: 46px;
+                border: 1px dashed #999;
+                border-radius: 28px;
+                line-height: 46px;
+                text-align: center;
+              "
+              v-if="!listData.companyLogo"
+            >
+              <label for="uplose">
+                <i class="el-icon-circle-plus-outline iconStsz"></i
+              ></label>
+              <input
+                ref="file"
+                type="file"
+                style="display: none"
+                id="uplose"
+                @change="getImgFile"
+              />
+            </div>
+            <div v-else class="flex_sty">
+              <el-image
+                style="width: 216px; height: 46px"
+                :src="$methodsTools.splitImgHost(listData.companyLogo)"
+                :preview-src-list="[
+                  $methodsTools.splitImgHost(listData.companyLogo),
+                ]"
+              >
+              </el-image>
+              <el-button
+                @click="listData.companyLogo = ''"
+                style="margin-left: 16px"
+                type="danger"
+                icon="el-icon-delete"
+                circle
+                size="mini"
+              ></el-button>
+            </div>
+            <p style="font-size: 12px; color: #999">
+              注:建议上传logo图片是透明底色的png格式,尺寸为216px * 46px
+            </p>
+          </div>
+        </li>
+        <li class="liSty">
+          <span>公司名称</span>
+          <div>
+            <el-input v-model="listData.companyName" :size="size"></el-input>
+          </div>
+        </li>
+        <li class="liSty">
+          <span>客服电话是否显示</span>
+          <div>
+            <el-radio-group v-model="listData.serviceTel.status">
+              <el-radio :label="1">是</el-radio>
+              <el-radio :label="0">否</el-radio>
+            </el-radio-group>
+          </div>
+        </li>
+        <li class="liSty">
+          <span>电话号码</span>
+          <div>
+            <el-input v-model="listData.serviceTel.tel" :size="size"></el-input>
+          </div>
+        </li>
+        <li class="liSty">
+          <span>客服时间</span>
+          <div>
+            <el-input
+              v-model="listData.serviceTel.time"
+              :size="size"
+            ></el-input>
+          </div>
+        </li>
+      </ul>
+    </div>
+    <div>
+      <h5>导航栏菜单设置</h5>
+      <el-table
+        :data="listData.Nav"
+        style="width: 800px; margin-top: 10px"
+        border
+      >
+        <el-table-column
+          v-for="(item, index) in tableSet"
+          :width="item.width"
+          :key="index"
+          :prop="item.prop"
+          :label="item.label"
+          align="center"
+        >
+          <template slot-scope="scope">
+            <div v-if="item.scope === 'input'">
+              <el-input-number
+                @blur="changeVal(scope.row)"
+                v-model="scope.row[item.prop]"
+                :controls="false"
+                :min="0"
+                :precision="0"
+                style="width: 50%"
+              ></el-input-number>
+            </div>
+            <div v-else-if="item.scope === 'status'" class="disflex_sty">
+              <el-switch
+                :size="size"
+                v-if="scope.row['name'] !== '首页'"
+                :active-value="1"
+                :inactive-value="0"
+                v-model="scope.row[item.prop]"
+                active-color="#13ce66"
+                inactive-color="#ff4949"
+              >
+              </el-switch>
+              <span style="margin-left: 14px">
+                {{
+                  scope.row[item.prop] === 1
+                    ? "开启"
+                    : scope.row[item.prop] === 0
+                    ? "关闭"
+                    : "未知"
+                }}
+              </span>
+            </div>
+            <div v-else>{{ scope.row[item.prop] }}</div>
+          </template></el-table-column
+        >
+      </el-table>
+    </div>
+    <div style="text-align: center; margin-top: 20px">
+      <el-button :size="size">取 消</el-button>
+      <el-button :size="size" type="primary" @click="submit">保 存</el-button>
+    </div>
+  </div>
+</template>
+
+<script>
+import { listConfig, updateConfig } from "@/api/system/config";
+export default {
+  data() {
+    return {
+      size: "mini",
+      listData: {
+        serviceTel: {},
+      },
+      tableSet: [
+        {
+          label: "排序",
+          prop: "sort",
+          scope: "input",
+        },
+        {
+          label: "导航菜单名称",
+          prop: "name",
+        },
+        {
+          label: "状态",
+          prop: "status",
+          scope: "status",
+        },
+      ],
+      initData:{},
+    };
+  },
+  computed: {
+    compyList: function () {
+      return function (arr) {
+        let ary = [];
+        if (arr) {
+          ary = arr.filter((item) => {
+            return item.status === 1;
+          });
+        }
+        return ary;
+      };
+    },
+  },
+  mounted() {
+    this.init();
+  },
+  methods: {
+    changeVal(row) {
+      if (!row.sort && row.sort !== 0) {
+        this.$message.warning("检测到你没有赋值或赋值异常,已自动赋值为0");
+        row.sort = 0;
+      } else {
+        for (let i = 0; i < this.listData.Nav.length; i++) {
+          if (
+            this.listData.Nav[i].name !== row.name &&
+            this.listData.Nav[i].sort == row.sort
+          ) {
+            this.$message.warning("检测到重复值,已自动赋值为0");
+            row.sort = 0;
+          }
+        }
+      }
+      this.listData.Nav.sort(this.sort);
+    },
+    submit() {
+      let data = JSON.parse(JSON.stringify(this.listData));
+      let copySubmitData = JSON.parse(JSON.stringify(this.initData))
+      copySubmitData.configValue = JSON.stringify(data)
+      updateConfig(copySubmitData).then((res) => {
+        this.$message.success("保存成功");
+      });
+    },
+    sort(a, b) {
+      return a.sort - b.sort;
+    },
+    init() {
+      listConfig({ configKey: "home.header" }).then((res) => {
+        if (res.rows.length) {
+          this.initData = res.rows[0];
+          this.listData = JSON.parse(res.rows[0].configValue);
+        }
+      });
+    },
+    getImgFile() {
+      var self = this;
+      var file = self.$refs.file.files[0];
+      if (file === undefined) {
+        self.$set(self.listData, "companyLogo", "");
+        return;
+      }
+      if (file.size > 0.3 * 1024 * 1024) {
+        self.$message.error("图片不得大于300kb");
+        return;
+      }
+      var type = self.$refs.file.value.toLowerCase().split(".").splice(-1);
+      if (
+        type[0] != "jpg" &&
+        type[0] != "png" &&
+        type[0] != "jpeg" &&
+        type[0] != "gif"
+      ) {
+        self.$message.error("上传格式需为:.jpg/.png/.jpeg/gif");
+        self.$refs.file.value = "";
+        return;
+      }
+      this.$upload.upload(file, 0).then((res) => {
+        self.listData.companyLogo = res;
+      });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-input--mini .el-input__inner {
+  max-width: 300px;
+}
+h5 {
+  font-weight: bold;
+}
+.liSty {
+  display: flex;
+  align-items: center;
+  font-size: 14px;
+  margin-bottom: 20px;
+  span {
+    width: 140px;
+    text-align: right;
+    margin-right: 10px;
+  }
+}
+.disflex_sty {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+.flex_sty {
+  display: flex;
+  align-items: center;
+}
+.iconStsz {
+  font-size: 20px;
+  color: #67c23a;
+  cursor: pointer;
+}
+.topSty_home {
+  border-radius: 14px;
+  padding: 10px;
+  border: 1px solid #666;
+}
+.dzStyInput {
+  width: 400px;
+  height: 34px;
+  outline: none;
+  padding-left: 10px;
+  font-size: 14px;
+  border: 1px solid #666;
+  border-top-left-radius: 6px;
+  border-bottom-left-radius: 6px;
+  border-color: rgb(65, 140, 251);
+}
+.btnSty {
+  display: inline-block;
+  height: 34px;
+  padding: 0px 6px;
+  border: 1px solid #666;
+  line-height: 32px;
+  border-left: none;
+  background-color: rgb(65, 140, 251);
+  color: #fff;
+  font-size: 14px;
+  border-color: rgb(65, 140, 251);
+  border-top-right-radius: 6px;
+  border-bottom-right-radius: 6px;
+  cursor: pointer;
+  user-select: none;
+}
+.noLogoImg {
+  border: 1px solid #666;
+  width: 216px;
+  height: 46px;
+  text-align: center;
+  font-size: 14px;
+  line-height: 46px;
+}
+.ul_styLI {
+  width: 400px;
+  display: flex;
+  align-items: center;
+  justify-content: space-around;
+  font-size: 14px;
+  user-select: none;
+}
+</style>

+ 41 - 0
src/views/2Cport/pageSettings/index.vue

@@ -0,0 +1,41 @@
+<template>
+  <div id="pageSettings">
+    <el-tabs v-model="activeName">
+      <el-tab-pane label="页头设置" name="headerPage"></el-tab-pane>
+      <el-tab-pane label="页尾设置" name="footerPage"></el-tab-pane>
+      <el-tab-pane label="友情链接" name="linksPage"></el-tab-pane>
+    </el-tabs>
+    <div class="allSy">
+      <header-page ref="headerPage" v-if="activeName === 'headerPage'" />
+      <footer-page ref="footerPage" v-if="activeName === 'footerPage'" />
+      <links-page ref="linksPage" v-if="activeName === 'linksPage'" />
+    </div>
+  </div>
+</template>
+
+<script>
+import headerPage from "./header.vue";
+import footerPage from "./footer.vue";
+import linksPage from "./links.vue";
+export default {
+  components: { headerPage, footerPage, linksPage },
+  data() {
+    return {
+      activeName: "headerPage",
+    };
+  },
+  methods: {},
+};
+</script>
+
+<style lang="less" scoped>
+#pageSettings {
+  display: flex;
+  flex-direction: column;
+  height: calc(100vh - 130px);
+}
+.allSy {
+  flex: 1;
+  overflow: auto;
+}
+</style>

+ 356 - 0
src/views/2Cport/pageSettings/links.vue

@@ -0,0 +1,356 @@
+<template>
+  <div id="links">
+    <div class="smallBox">
+      <div style="text-align: right">
+        <el-button :size="size" @click="add(1)">添加</el-button>
+      </div>
+      <el-table :data="listData" style="width: 900px; margin-top: 10px" border>
+        <el-table-column
+          v-for="(item, index) in tableSet"
+          :width="item.width"
+          :key="index"
+          :prop="item.prop"
+          :label="item.label"
+          align="center"
+        >
+          <template slot-scope="scope">
+            <div v-if="item.scope === 'input'">
+              <el-input-number
+                @blur="changeVal(scope.row)"
+                v-model="scope.row[item.prop]"
+                :controls="false"
+                :min="0"
+                :precision="0"
+                style="width: 80%"
+              ></el-input-number>
+            </div>
+            <div v-else-if="item.scope === 'set'">
+              <el-button type="text" @click="add(0, scope.row, scope.$index)"
+                >修改</el-button
+              >
+              <el-button type="text" @click="del(scope.$index)">删除</el-button>
+            </div>
+            <div v-else-if="item.scope === 'status'">
+              {{ scope.row[item.prop] == 1 ? "启用" : "关闭" }}
+            </div>
+            <div v-else>{{ scope.row[item.prop] }}</div>
+          </template></el-table-column
+        >
+      </el-table>
+      <div style="text-align: center; margin-top: 20px">
+        <el-button :size="size">取 消</el-button>
+        <el-button :size="size" type="primary" @click="submit">保 存</el-button>
+      </div>
+    </div>
+    <el-dialog
+      @closed="loadingClose"
+      :visible.sync="dialogVisible"
+      width="680px"
+      :show-close="false"
+      :close-on-click-modal="false"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">
+          {{ statusPop === 1 ? "添加" : statusPop === 0 ? "修改" : "详情" }}
+        </div>
+        <div class="rightBoxs">
+          <img src="@/assets/images/Close@2x.png" alt="" @click="close" />
+        </div>
+      </div>
+      <div>
+        <el-form
+          label-position="right"
+          label-width="170px"
+          :model="boxData"
+          :rules="rules"
+          ref="boxData"
+        >
+          <el-form-item label="名称" prop="name">
+            <el-input v-model="boxData.name"></el-input>
+          </el-form-item>
+          <el-form-item label="链接地址" prop="url">
+            <el-input v-model="boxData.url"></el-input>
+          </el-form-item>
+          <el-form-item label="状态" prop="status">
+            <el-radio-group v-model="boxData.status">
+              <el-radio :label="1">启用</el-radio>
+              <el-radio :label="0">关闭</el-radio>
+            </el-radio-group>
+          </el-form-item>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="close">取 消</el-button>
+        <el-button @click="submitForm('boxData')" :loading="disabledBtn"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { listConfig, updateConfig } from "@/api/system/config";
+export default {
+  data() {
+    return {
+      disabledBtn: false,
+      dialogVisible: false,
+      size: "mini",
+      tableSet: [
+        {
+          label: "排序",
+          prop: "sort",
+          scope: "input",
+          width: "120px",
+        },
+        {
+          label: "名称",
+          prop: "name",
+        },
+        {
+          label: "链接地址",
+          prop: "url",
+        },
+        {
+          label: "状态",
+          prop: "status",
+          scope: "status",
+        },
+        {
+          label: "操作",
+          scope: "set",
+          width: "160px",
+        },
+      ],
+      Nav: [],
+      initData: {},
+      listData: [],
+      statusPop: "",
+      boxData: {},
+      rules: {
+        name: [{ required: true, message: "请填写名称", trigger: "blur" }],
+        url: [{ required: true, message: "请填写链接地址", trigger: "blur" }],
+        status: [
+          {
+            required: true,
+            message: "请选择状态",
+            trigger: "change",
+          },
+        ],
+      },
+      newIndex: "",
+    };
+  },
+  mounted() {
+    this.init();
+  },
+  methods: {
+    changeVal(row) {
+      if (!row.sort && row.sort !== 0) {
+        this.$message.warning("检测到你没有赋值或赋值异常,已自动赋值为0");
+        row.sort = 0;
+      } else {
+        for (let i = 0; i < this.listData.length; i++) {
+          if (
+            this.listData[i].name !== row.name &&
+            this.listData[i].sort == row.sort
+          ) {
+            this.$message.warning("检测到重复值,已自动赋值为0");
+            row.sort = 0;
+          }
+        }
+      }
+      this.listData.sort(this.sort);
+    },
+    sort(a, b) {
+      return a.sort - b.sort;
+    },
+    loadingClose() {
+      this.disabledBtn = false;
+    },
+    del(index) {
+      this.listData.splice(index, 1);
+    },
+    add(int, row, index) {
+      this.statusPop = int;
+      this.newIndex = index;
+      if (int === 0) {
+        this.boxData = JSON.parse(JSON.stringify(row));
+      }
+      if (int === 1) {
+        var indexNum = 0;
+        this.listData.forEach((item) => {
+          if (item.sort >= indexNum) {
+            indexNum = item.sort + 1;
+          }
+        });
+        this.boxData = {};
+        this.boxData.sort = indexNum;
+      }
+      this.dialogVisible = true;
+      this.$nextTick(() => {
+        this.$refs.boxData.clearValidate();
+      });
+    },
+    close() {
+      this.dialogVisible = false;
+    },
+    submitForm(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          if (this.statusPop === 1) {
+            this.listData.push(this.boxData);
+          } else {
+            this.listData.splice(this.newIndex, 1, this.boxData);
+          }
+          this.dialogVisible = false;
+        } else {
+          console.log("error submit!!");
+          return false;
+        }
+      });
+    },
+    init() {
+      listConfig({ configKey: "home.links" }).then((res) => {
+        if (res.rows.length) {
+          this.initData = res.rows[0];
+          this.listData = JSON.parse(res.rows[0].configValue);
+        }
+      });
+    },
+    submit() {
+      let data = JSON.parse(JSON.stringify(this.listData));
+      let copySubmitData = JSON.parse(JSON.stringify(this.initData));
+      copySubmitData.configValue = JSON.stringify(data);
+      updateConfig(copySubmitData).then((res) => {
+        this.$message.success("保存成功");
+      });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.smallBox {
+  width: 900px;
+}
+
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+.dis_fs {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 337.5px;
+  height: 144px;
+  border: 1px solid #999;
+  .imgBoxs {
+    width: 100%;
+    height: 100%;
+  }
+}
+.styPsty {
+  margin-top: 10px;
+  display: flex;
+  align-items: center;
+  .btns {
+    border: 1px solid #999;
+    font-size: 12px;
+    height: 28px;
+    line-height: 28px;
+    padding: 0px 10px;
+    border-radius: 4px;
+    cursor: pointer;
+    margin-right: 10px;
+    flex-shrink: 0;
+  }
+}
+</style>

+ 41 - 0
src/views/2Cport/referralManageMent/index.vue

@@ -0,0 +1,41 @@
+<template>
+  <div id="referralManageMent">
+    <div>
+      <el-button
+        size="mini"
+        :type="activeIndex === 1 ? 'primary' : ''"
+        @click="activeIndex = 1"
+        >小程序</el-button
+      >
+      <el-button
+        size="mini"
+        :type="activeIndex === 2 ? 'primary' : ''"
+        @click="activeIndex = 2"
+        >PC官网</el-button
+      >
+    </div>
+    <tab1 v-if="activeIndex === 1" />
+    <tab2 v-if="activeIndex === 2" />
+  </div>
+</template>
+
+<script>
+import tab1 from "./tab1/tab1.vue";
+import tab2 from "./tab2/tab2.vue";
+export default {
+  name:"ReferralManageMent",
+  components: { tab1, tab2 },
+  data() {
+    return {
+      activeIndex: 1,
+    };
+  },
+  mounted(){
+  },
+  methods: {
+  },
+};
+</script>
+
+<style lang="less" scoped>
+</style>

+ 552 - 0
src/views/2Cport/referralManageMent/tab1/addGL.vue

@@ -0,0 +1,552 @@
+<template>
+  <div id="addGL">
+    <el-dialog
+      @closed="loadingClose"
+      :visible.sync="dialogVisible"
+      width="710px"
+      :show-close="false"
+      :close-on-click-modal="false"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">
+          {{ statusPop === 1 ? "添加" : statusPop === 0 ? "修改" : "详情" }}
+        </div>
+        <div class="rightBoxs">
+          <img src="@/assets/images/Close@2x.png" alt="" @click="close" />
+        </div>
+      </div>
+      <div>
+        <el-form
+          label-position="right"
+          label-width="150px"
+          :model="listData"
+          :rules="rules"
+          ref="listData"
+          :size="size"
+        >
+          <el-form-item label="显示标题" prop="name">
+            <el-input v-model="listData.name"></el-input>
+          </el-form-item>
+          <el-form-item label="业务层级" prop="educationTypeId">
+            <el-select
+              v-model="listData.educationTypeId"
+              placeholder="请选择教育类型"
+              @change="activeEdu"
+              :disabled="listData.goodsList.length > 0"
+            >
+              <el-option
+                v-for="(item, index) in educationType"
+                :key="index"
+                :label="item.educationName"
+                :value="item.id"
+              >
+              </el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item
+            label=""
+            prop="businessId"
+            v-if="listData.educationTypeId"
+          >
+            <el-select
+              v-model="listData.businessId"
+              :disabled="listData.goodsList.length > 0"
+              placeholder="请选择业务层级"
+            >
+              <el-option
+                v-for="(item, index) in newBusinessLevel"
+                :key="index"
+                :label="item.projectName + ' - ' + item.businessName"
+                :value="item.id"
+              >
+              </el-option>
+            </el-select>
+          </el-form-item>
+          <div v-if="listData.businessId" style="margin-bottom: 10px">
+            <p class="p_sty">
+              <span style="color: red">注:推荐位最多显示12个商品</span>
+              <el-button :size="size" @click="addList">添加</el-button>
+            </p>
+            <el-table
+              :data="listData.goodsList"
+              style="width: 100%; margin-top: 10px"
+              border
+              :size="size"
+              max-height="400px"
+              :default-sort="{ prop: 'sort', order: 'ascending' }"
+            >
+              <template v-for="(items, indexs) in tableSet">
+                <el-table-column
+                  :width="items.width"
+                  :key="indexs"
+                  :prop="items.prop"
+                  :label="items.label"
+                  align="center"
+                  :sortable="items.scope === 'sort'"
+                >
+                  <template slot-scope="scope">
+                    <div v-if="items.scope === 'sort'">
+                      <el-input-number
+                        style="width: 80px"
+                        :size="size"
+                        :min="1"
+                        v-model="scope.row[items.prop]"
+                        :precision="0"
+                        :controls="false"
+                      ></el-input-number>
+                    </div>
+                    <div v-else>{{ items.ch }}{{ scope.row[items.prop] }}</div>
+                  </template></el-table-column
+                ></template
+              >
+              <el-table-column
+                fixed="right"
+                label="操作"
+                width="100"
+                align="center"
+              >
+                <template slot-scope="scope">
+                  <el-button
+                    type="text"
+                    size="small"
+                    @click="delList(scope.row.goodsId)"
+                    >删除</el-button
+                  >
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+          <el-form-item label="排序" prop="sort">
+            <el-input-number
+              :min="1"
+              v-model="listData.sort"
+              :precision="0"
+              :controls="false"
+            ></el-input-number>
+          </el-form-item>
+          <el-form-item label="状态" prop="status">
+            <el-radio-group v-model="listData.status">
+              <el-radio :label="1">启用</el-radio>
+              <el-radio :label="0">关闭</el-radio>
+            </el-radio-group>
+          </el-form-item>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="close">取 消</el-button>
+        <el-button @click="submitForm('listData')" :loading="disabledBtn"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
+    <el-dialog
+      @closed="loadingClose"
+      :visible.sync="dialogVisibleList"
+      width="710px"
+      :show-close="false"
+      :close-on-click-modal="false"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">选择关联商品</div>
+        <div class="rightBoxs">
+          <img
+            src="@/assets/images/Close@2x.png"
+            alt=""
+            @click="dialogVisibleList = false"
+          />
+        </div>
+      </div>
+      <el-checkbox-group v-model="newActiveNum">
+        <div class="over_sty">
+          <el-checkbox
+            v-for="(item, index) in goodsList"
+            :key="index"
+            :label="item.goodsId"
+            :disabled="activeNum.indexOf(item.goodsId) !== -1"
+            >{{ item.code }} - {{ item.goodsName }}({{
+              item.educationName +
+              " - " +
+              item.projectName +
+              " - " +
+              item.businessName
+            }}) -
+            <span style="color: red">¥{{ item.standPrice }}</span></el-checkbox
+          >
+        </div>
+      </el-checkbox-group>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisibleList = false">取 消</el-button>
+        <el-button
+          @click="submitFormList"
+          :disabled="newActiveNum < 1"
+          :loading="disabledBtn"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from "vuex";
+export default {
+  data() {
+    return {
+      size: "small",
+      dialogVisible: false,
+      dialogVisibleList: false,
+      disabledBtn: false,
+      listData: {
+        businessId: "",
+        goodsList: [],
+      },
+      rules: {
+        name: [{ required: true, message: "请输入显示标题", trigger: "blur" }],
+        educationTypeId: [
+          { required: true, message: "请选择教育类型", trigger: "change" },
+        ],
+        businessId: [
+          {
+            required: true,
+            message: "请选择业务层次",
+            trigger: ["change", "blur"],
+          },
+        ],
+        sort: [{ required: true, message: "请输入排序", trigger: "blur" }],
+        status: [
+          {
+            required: true,
+            message: "请选择状态",
+            trigger: ["change", "blur"],
+          },
+        ],
+      },
+      statusPop: 1,
+      tableSet: [
+        {
+          label: "排序",
+          prop: "sort",
+          width: "120px",
+          scope: "sort",
+        },
+        {
+          label: "商品编码",
+          prop: "code",
+        },
+        {
+          label: "商品名称",
+          prop: "goodsName",
+        },
+        {
+          label: "商品标准价格",
+          prop: "standPrice",
+          ch: "¥",
+        },
+      ],
+      newBusinessLevel: [],
+      activeNum: [], //已选商品ID
+      newActiveNum: [],
+      goodsList: [], //商品列表
+    };
+  },
+  computed: {
+    ...mapGetters(["educationType"]),
+  },
+  watch: {
+    "listData.businessId"(val) {
+      if (val) {
+        for (let i = 0; i < this.newBusinessLevel.length; i++) {
+          if (this.newBusinessLevel[i].id == val) {
+            this.listData.projectId = this.newBusinessLevel[i].projectId;
+            break;
+          }
+        }
+      }
+    },
+  },
+  methods: {
+    openBox(int, id) {
+      this.statusPop = int;
+      if (int === 0) {
+        this.$api.obtainactivityrecommend(id).then((res) => {
+          this.listData = res.data;
+          this.activeEdu(res.data.educationTypeId);
+        });
+      }
+      if (int === 1) {
+        var dy = this.$parent.tableData.map((item) => {
+          return Number(item.sort);
+        });
+        let MAXNUM = Math.max.apply(null, dy);
+        this.listData = { businessId: "", goodsList: [], sort: MAXNUM + 1 };
+      }
+      this.dialogVisible = true;
+      this.$nextTick(() => {
+        this.$refs.listData.clearValidate();
+      });
+    },
+    activeEdu(v) {
+      if (this.statusPop !== 0) {
+        this.listData.businessId = "";
+        this.listData.projectId = "";
+      }
+      this.$api
+        .inquirebusinessList({ status: 1, educationId: v })
+        .then((res) => {
+          this.newBusinessLevel = res.rows;
+        });
+    },
+    loadingClose() {
+      this.disabledBtn = false;
+    },
+    submitForm(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          this.submit();
+        } else {
+          console.log("error submit!!");
+          return false;
+        }
+      });
+    },
+    unique(arr) {
+      var arrs = []
+      for(let i = 0; i < arr.length;i++){
+        if(arr[i] && !arrs.includes(arr[i])){
+          arrs.push(arr[i])
+        }else{
+          return false
+        }
+      }
+      return true
+    },
+    submit() {
+      if (this.listData.goodsList.length) {
+        if (this.listData.goodsList.length >= 13) {
+          this.$message.warning("推荐位最多显示12个商品");
+          return;
+        }
+        var indexNum = this.listData.goodsList.map((item) => {
+          return item.sort;
+        });
+        if (!this.unique(indexNum)) {
+          this.$message.error("推荐位商品排序不允许重复或空");
+          return;
+        }
+      }
+      this.disabledBtn = true;
+      if (this.statusPop === 1) {
+        let data = JSON.parse(JSON.stringify(this.listData));
+        data.platform = 1;
+        data.type = this.$parent.activeName === "first" ? 1 : 2;
+        this.$api
+          .appactivityrecommend(data)
+          .then((res) => {
+            this.$message.success("新增成功");
+            this.$parent.search();
+            this.dialogVisible = false;
+          })
+          .catch((err) => {
+            this.disabledBtn = false;
+          });
+      }
+      if (this.statusPop === 0) {
+        let data = JSON.parse(JSON.stringify(this.listData));
+        this.$api
+          .editactivityrecommend(data)
+          .then((res) => {
+            this.$message.success("修改成功");
+            this.$parent.search();
+            this.dialogVisible = false;
+          })
+          .catch((err) => {
+            this.disabledBtn = false;
+          });
+      }
+    },
+    close() {
+      this.dialogVisible = false;
+    },
+    delList(id) {
+      const Index = this.listData.goodsList.findIndex((item) => {
+        return item.goodsId === id;
+      });
+      this.listData.goodsList.splice(Index, 1);
+    },
+    addList() {
+      this.newActiveNum = [];
+      this.activeNum = this.listData.goodsList.map((item) => {
+        return item.goodsId;
+      });
+      this.$api
+        .inquireGoods({
+          businessId: this.listData.businessId,
+          status: 1,
+          goodsType: this.$parent.activeName === "first" ? 1 : 2,
+        })
+        .then((res) => {
+          this.goodsList = res.rows;
+        });
+      this.dialogVisibleList = true;
+    },
+    submitFormList() {
+      let ary = this.goodsList.filter((item) => {
+        return this.newActiveNum.includes(item.goodsId);
+      });
+      if (this.listData.goodsList.length) {
+        let maxIndex = 0;
+        this.listData.goodsList.forEach((item) => {
+          if (item.sort > maxIndex) {
+            maxIndex = item.sort;
+          }
+        });
+        ary.forEach((item, index) => {
+          item.sort = maxIndex + index + 1;
+        });
+      } else {
+        ary.forEach((item, index) => {
+          item.sort = index + 1;
+        });
+      }
+      let data = this.listData.goodsList.concat(ary);
+      this.$set(this.listData, "goodsList", data);
+      this.dialogVisibleList = false;
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.p_sty {
+  margin: 0px;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+.dis_fs {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 337.5px;
+  height: 144px;
+  border: 1px solid #999;
+  .imgBoxs {
+    width: 100%;
+    height: 100%;
+  }
+}
+.styPsty {
+  margin-top: 10px;
+  display: flex;
+  align-items: center;
+  .btns {
+    border: 1px solid #999;
+    font-size: 12px;
+    height: 28px;
+    line-height: 28px;
+    padding: 0px 10px;
+    border-radius: 4px;
+    cursor: pointer;
+    margin-right: 10px;
+    flex-shrink: 0;
+  }
+}
+.over_sty {
+  max-height: 600px;
+  overflow: auto;
+  background-color: #eee;
+  padding: 20px;
+}
+/deep/ .el-input--small .el-input__inner {
+  max-width: 215px;
+}
+</style>

+ 186 - 0
src/views/2Cport/referralManageMent/tab1/tab1.vue

@@ -0,0 +1,186 @@
+<template>
+  <div id="tab1">
+    <div class="postMs">
+      <el-tabs v-model="activeName">
+        <el-tab-pane label="推荐课程" name="first"></el-tab-pane>
+        <el-tab-pane label="推荐题库" name="second"></el-tab-pane>
+      </el-tabs>
+      <el-button class="topPost" size="mini" type="success" @click="add"
+        >添加</el-button
+      >
+    </div>
+    <div>
+      <el-table
+        v-loading="loading"
+        :data="tableData"
+        style="width: 100%; margin-top: 10px"
+        border
+      >
+        <template v-for="(item, index) in tableSet">
+          <af-table-column
+            :width="item.width"
+            :key="index"
+            :prop="item.prop"
+            :label="item.label"
+            align="center"
+          >
+            <template slot-scope="scope">
+              <span v-if="item.scope === 'status'">
+                {{
+                  scope.row[item.prop] === 1
+                    ? "启用"
+                    : scope.row[item.prop] === 0
+                    ? "关闭"
+                    : "未知"
+                }}
+              </span>
+              <div v-else-if="item.scope === 'businType'">
+                {{ scope.row[item.prop1] + "-" + scope.row[item.prop2] }}
+              </div>
+              <div v-else-if="item.scope === 'aboutChapter'" class="ulAuto">
+                <ul>
+                  <template v-for="(itm, inds) in scope.row[item.prop]">
+                    <li class="jumpStys" :key="inds" v-if="inds === 0">
+                      {{ itm[item.prop1] }}
+                    </li>
+                  </template>
+                </ul>
+                <el-popover
+                  :key="Math.random()"
+                  placement="right"
+                  trigger="click"
+                >
+                  <ul style="overflow: auto; max-height: 500px;margin:0px;">
+                    <li
+                      v-for="(itm, inds) in scope.row[item.prop]"
+                      :key="inds"
+                      class="jumpStys"
+                    >
+                      {{ inds + 1 }}、
+                      {{ itm[item.prop1] }}
+                    </li>
+                  </ul>
+                  <el-button
+                    slot="reference"
+                    style="margin-left: 6px"
+                    type="text"
+                    v-if="scope.row[item.prop].length > 1"
+                    size="mini"
+                    >更多</el-button
+                  >
+                </el-popover>
+              </div>
+              <div v-else>{{ scope.row[item.prop] }}</div>
+            </template></af-table-column
+          ></template
+        >
+        <el-table-column fixed="right" label="操作" width="100" align="center">
+          <template slot-scope="scope">
+            <el-button type="text" size="small" @click="editList(scope.row)"
+              >修改</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <add-gl ref="addGL" />
+  </div>
+</template>
+
+<script>
+import addGl from "./addGL.vue";
+export default {
+  components: { addGl },
+  data() {
+    return {
+      activeName: "first",
+      tableSet: [
+        {
+          label: "排序",
+          prop: "sort",
+          width: "120px",
+        },
+        {
+          label: "名称",
+          prop: "name",
+        },
+        {
+          label: "教育类型",
+          prop: "educationName",
+        },
+        {
+          label: "业务层次",
+          prop1: "projectName",
+          prop2: "businessName",
+          scope: "businType",
+        },
+        {
+          label: "关联商品",
+          prop: "goodsList",
+          prop1: "goodsName",
+          scope: "aboutChapter",
+        },
+        {
+          label: "状态",
+          prop: "status",
+          scope: "status",
+        },
+      ],
+      tableData: [],
+      loading: false,
+    };
+  },
+  watch: {
+    activeName(val) {
+      this.search();
+    },
+  },
+  mounted() {
+    this.search();
+  },
+  methods: {
+    search() {
+      this.loading = true;
+      this.$api
+        .inquireactivityrecommendList({
+          platform: 1,
+          type: this.activeName === "first" ? 1 : 2,
+        })
+        .then((res) => {
+          this.tableData = res.rows;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    /**
+     * 新增
+     */
+    add() {
+      this.$refs.addGL.openBox(1);
+    },
+    editList(row) {
+      this.$refs.addGL.openBox(0, row.recommendId);
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.postMs {
+  position: relative;
+  .topPost {
+    position: absolute;
+    top: 10%;
+    right: 10px;
+  }
+}
+.ulAuto {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  & > ul {
+    margin: 0px;
+  }
+}
+</style>

+ 552 - 0
src/views/2Cport/referralManageMent/tab2/addGL.vue

@@ -0,0 +1,552 @@
+<template>
+  <div id="addGL">
+    <el-dialog
+      @closed="loadingClose"
+      :visible.sync="dialogVisible"
+      width="710px"
+      :show-close="false"
+      :close-on-click-modal="false"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">
+          {{ statusPop === 1 ? "添加" : statusPop === 0 ? "修改" : "详情" }}
+        </div>
+        <div class="rightBoxs">
+          <img src="@/assets/images/Close@2x.png" alt="" @click="close" />
+        </div>
+      </div>
+      <div>
+        <el-form
+          label-position="right"
+          label-width="150px"
+          :model="listData"
+          :rules="rules"
+          ref="listData"
+          :size="size"
+        >
+          <el-form-item label="显示标题" prop="name">
+            <el-input v-model="listData.name"></el-input>
+          </el-form-item>
+          <el-form-item label="业务层级" prop="educationTypeId">
+            <el-select
+              v-model="listData.educationTypeId"
+              placeholder="请选择教育类型"
+              @change="activeEdu"
+              :disabled="listData.goodsList.length > 0"
+            >
+              <el-option
+                v-for="(item, index) in educationType"
+                :key="index"
+                :label="item.educationName"
+                :value="item.id"
+              >
+              </el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item
+            label=""
+            prop="businessId"
+            v-if="listData.educationTypeId"
+          >
+            <el-select
+              v-model="listData.businessId"
+              :disabled="listData.goodsList.length > 0"
+              placeholder="请选择业务层级"
+            >
+              <el-option
+                v-for="(item, index) in newBusinessLevel"
+                :key="index"
+                :label="item.projectName + ' - ' + item.businessName"
+                :value="item.id"
+              >
+              </el-option>
+            </el-select>
+          </el-form-item>
+          <div v-if="listData.businessId" style="margin-bottom: 10px">
+            <p class="p_sty">
+              <span style="color: red">注:推荐位最多显示12个商品</span>
+              <el-button :size="size" @click="addList">添加</el-button>
+            </p>
+            <el-table
+              :data="listData.goodsList"
+              style="width: 100%; margin-top: 10px"
+              border
+              :size="size"
+              max-height="400px"
+              :default-sort="{ prop: 'sort', order: 'ascending' }"
+            >
+              <template v-for="(items, indexs) in tableSet">
+                <el-table-column
+                  :width="items.width"
+                  :key="indexs"
+                  :prop="items.prop"
+                  :label="items.label"
+                  align="center"
+                  :sortable="items.scope === 'sort'"
+                >
+                  <template slot-scope="scope">
+                    <div v-if="items.scope === 'sort'">
+                      <el-input-number
+                        style="width: 80px"
+                        :size="size"
+                        :min="1"
+                        v-model="scope.row[items.prop]"
+                        :precision="0"
+                        :controls="false"
+                      ></el-input-number>
+                    </div>
+                    <div v-else>{{ items.ch }}{{ scope.row[items.prop] }}</div>
+                  </template></el-table-column
+                ></template
+              >
+              <el-table-column
+                fixed="right"
+                label="操作"
+                width="100"
+                align="center"
+              >
+                <template slot-scope="scope">
+                  <el-button
+                    type="text"
+                    size="small"
+                    @click="delList(scope.row.goodsId)"
+                    >删除</el-button
+                  >
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+          <el-form-item label="排序" prop="sort">
+            <el-input-number
+              :min="1"
+              v-model="listData.sort"
+              :precision="0"
+              :controls="false"
+            ></el-input-number>
+          </el-form-item>
+          <el-form-item label="状态" prop="status">
+            <el-radio-group v-model="listData.status">
+              <el-radio :label="1">启用</el-radio>
+              <el-radio :label="0">关闭</el-radio>
+            </el-radio-group>
+          </el-form-item>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="close">取 消</el-button>
+        <el-button @click="submitForm('listData')" :loading="disabledBtn"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
+    <el-dialog
+      @closed="loadingClose"
+      :visible.sync="dialogVisibleList"
+      width="710px"
+      :show-close="false"
+      :close-on-click-modal="false"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">选择关联商品</div>
+        <div class="rightBoxs">
+          <img
+            src="@/assets/images/Close@2x.png"
+            alt=""
+            @click="dialogVisibleList = false"
+          />
+        </div>
+      </div>
+      <el-checkbox-group v-model="newActiveNum">
+        <div class="over_sty">
+          <el-checkbox
+            v-for="(item, index) in goodsList"
+            :key="index"
+            :label="item.goodsId"
+            :disabled="activeNum.indexOf(item.goodsId) !== -1"
+            >{{ item.code }} - {{ item.goodsName }}({{
+              item.educationName +
+              " - " +
+              item.projectName +
+              " - " +
+              item.businessName
+            }}) -
+            <span style="color: red">¥{{ item.standPrice }}</span></el-checkbox
+          >
+        </div>
+      </el-checkbox-group>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisibleList = false">取 消</el-button>
+        <el-button
+          @click="submitFormList"
+          :disabled="newActiveNum < 1"
+          :loading="disabledBtn"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from "vuex";
+export default {
+  data() {
+    return {
+      size: "small",
+      dialogVisible: false,
+      dialogVisibleList: false,
+      disabledBtn: false,
+      listData: {
+        businessId: "",
+        goodsList: [],
+      },
+      rules: {
+        name: [{ required: true, message: "请输入显示标题", trigger: "blur" }],
+        educationTypeId: [
+          { required: true, message: "请选择教育类型", trigger: "change" },
+        ],
+        businessId: [
+          {
+            required: true,
+            message: "请选择业务层次",
+            trigger: ["change", "blur"],
+          },
+        ],
+        sort: [{ required: true, message: "请输入排序", trigger: "blur" }],
+        status: [
+          {
+            required: true,
+            message: "请选择状态",
+            trigger: ["change", "blur"],
+          },
+        ],
+      },
+      statusPop: 1,
+      tableSet: [
+        {
+          label: "排序",
+          prop: "sort",
+          width: "120px",
+          scope: "sort",
+        },
+        {
+          label: "商品编码",
+          prop: "code",
+        },
+        {
+          label: "商品名称",
+          prop: "goodsName",
+        },
+        {
+          label: "商品标准价格",
+          prop: "standPrice",
+          ch: "¥",
+        },
+      ],
+      newBusinessLevel: [],
+      activeNum: [], //已选商品ID
+      newActiveNum: [],
+      goodsList: [], //商品列表
+    };
+  },
+  computed: {
+    ...mapGetters(["educationType"]),
+  },
+  watch: {
+    "listData.businessId"(val) {
+      if (val) {
+        for (let i = 0; i < this.newBusinessLevel.length; i++) {
+          if (this.newBusinessLevel[i].id == val) {
+            this.listData.projectId = this.newBusinessLevel[i].projectId;
+            break;
+          }
+        }
+      }
+    },
+  },
+  methods: {
+    openBox(int, id) {
+      this.statusPop = int;
+      if (int === 0) {
+        this.$api.obtainactivityrecommend(id).then((res) => {
+          this.listData = res.data;
+          this.activeEdu(res.data.educationTypeId);
+        });
+      }
+      if (int === 1) {
+        var dy = this.$parent.tableData.map((item) => {
+          return Number(item.sort);
+        });
+        let MAXNUM = Math.max.apply(null, dy);
+        this.listData = { businessId: "", goodsList: [], sort: MAXNUM + 1 };
+      }
+      this.dialogVisible = true;
+      this.$nextTick(() => {
+        this.$refs.listData.clearValidate();
+      });
+    },
+    activeEdu(v) {
+      if (this.statusPop !== 0) {
+        this.listData.businessId = "";
+        this.listData.projectId = "";
+      }
+      this.$api
+        .inquirebusinessList({ status: 1, educationId: v })
+        .then((res) => {
+          this.newBusinessLevel = res.rows;
+        });
+    },
+    loadingClose() {
+      this.disabledBtn = false;
+    },
+    submitForm(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          this.submit();
+        } else {
+          console.log("error submit!!");
+          return false;
+        }
+      });
+    },
+    unique(arr) {
+      var arrs = [];
+      for (let i = 0; i < arr.length; i++) {
+        if (arr[i] && !arrs.includes(arr[i])) {
+          arrs.push(arr[i]);
+        } else {
+          return false;
+        }
+      }
+      return true;
+    },
+    submit() {
+      if (this.listData.goodsList.length) {
+        if (this.listData.goodsList.length >= 13) {
+          this.$message.warning("推荐位最多显示12个商品");
+          return;
+        }
+        var indexNum = this.listData.goodsList.map((item) => {
+          return item.sort;
+        });
+        if (!this.unique(indexNum)) {
+          this.$message.error("推荐位商品排序不允许重复或空");
+          return;
+        }
+      }
+      this.disabledBtn = true;
+      if (this.statusPop === 1) {
+        let data = JSON.parse(JSON.stringify(this.listData));
+        data.platform = 2;
+        data.type = this.$parent.activeName === "first" ? 1 : 2;
+        this.$api
+          .appactivityrecommend(data)
+          .then((res) => {
+            this.$message.success("新增成功");
+            this.$parent.search();
+            this.dialogVisible = false;
+          })
+          .catch((err) => {
+            this.disabledBtn = false;
+          });
+      }
+      if (this.statusPop === 0) {
+        let data = JSON.parse(JSON.stringify(this.listData));
+        this.$api
+          .editactivityrecommend(data)
+          .then((res) => {
+            this.$message.success("修改成功");
+            this.$parent.search();
+            this.dialogVisible = false;
+          })
+          .catch((err) => {
+            this.disabledBtn = false;
+          });
+      }
+    },
+    close() {
+      this.dialogVisible = false;
+    },
+    delList(id) {
+      const Index = this.listData.goodsList.findIndex((item) => {
+        return item.goodsId === id;
+      });
+      this.listData.goodsList.splice(Index, 1);
+    },
+    addList() {
+      this.newActiveNum = [];
+      this.activeNum = this.listData.goodsList.map((item) => {
+        return item.goodsId;
+      });
+      this.$api
+        .inquireGoods({
+          businessId: this.listData.businessId,
+          status: 1,
+          goodsType: this.$parent.activeName === "first" ? 1 : 2,
+        })
+        .then((res) => {
+          this.goodsList = res.rows;
+        });
+      this.dialogVisibleList = true;
+    },
+    submitFormList() {
+      let ary = this.goodsList.filter((item) => {
+        return this.newActiveNum.includes(item.goodsId);
+      });
+      if (this.listData.goodsList.length) {
+        let maxIndex = 0;
+        this.listData.goodsList.forEach((item) => {
+          if (item.sort > maxIndex) {
+            maxIndex = item.sort;
+          }
+        });
+        ary.forEach((item, index) => {
+          item.sort = maxIndex + index + 1;
+        });
+      } else {
+        ary.forEach((item, index) => {
+          item.sort = index + 1;
+        });
+      }
+      let data = this.listData.goodsList.concat(ary);
+      this.$set(this.listData, "goodsList", data);
+      this.dialogVisibleList = false;
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.p_sty {
+  margin: 0px;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+.dis_fs {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 337.5px;
+  height: 144px;
+  border: 1px solid #999;
+  .imgBoxs {
+    width: 100%;
+    height: 100%;
+  }
+}
+.styPsty {
+  margin-top: 10px;
+  display: flex;
+  align-items: center;
+  .btns {
+    border: 1px solid #999;
+    font-size: 12px;
+    height: 28px;
+    line-height: 28px;
+    padding: 0px 10px;
+    border-radius: 4px;
+    cursor: pointer;
+    margin-right: 10px;
+    flex-shrink: 0;
+  }
+}
+.over_sty {
+  max-height: 600px;
+  overflow: auto;
+  background-color: #eee;
+  padding: 20px;
+}
+/deep/ .el-input--small .el-input__inner {
+  max-width: 215px;
+}
+</style>

+ 186 - 0
src/views/2Cport/referralManageMent/tab2/tab2.vue

@@ -0,0 +1,186 @@
+<template>
+  <div id="tab2">
+    <div class="postMs">
+      <el-tabs v-model="activeName">
+        <el-tab-pane label="推荐课程" name="first"></el-tab-pane>
+        <el-tab-pane label="推荐题库" name="second"></el-tab-pane>
+      </el-tabs>
+      <el-button class="topPost" size="mini" type="success" @click="add"
+        >添加</el-button
+      >
+    </div>
+    <div>
+      <el-table
+        v-loading="loading"
+        :data="tableData"
+        style="width: 100%; margin-top: 10px"
+        border
+      >
+        <template v-for="(item, index) in tableSet">
+          <af-table-column
+            :width="item.width"
+            :key="index"
+            :prop="item.prop"
+            :label="item.label"
+            align="center"
+          >
+            <template slot-scope="scope">
+              <span v-if="item.scope === 'status'">
+                {{
+                  scope.row[item.prop] === 1
+                    ? "启用"
+                    : scope.row[item.prop] === 0
+                    ? "关闭"
+                    : "未知"
+                }}
+              </span>
+              <div v-else-if="item.scope === 'businType'">
+                {{ scope.row[item.prop1] + "-" + scope.row[item.prop2] }}
+              </div>
+              <div v-else-if="item.scope === 'aboutChapter'" class="ulAuto">
+                <ul>
+                  <template v-for="(itm, inds) in scope.row[item.prop]">
+                    <li class="jumpStys" :key="inds" v-if="inds === 0">
+                      {{ itm[item.prop1] }}
+                    </li>
+                  </template>
+                </ul>
+                <el-popover
+                  :key="Math.random()"
+                  placement="right"
+                  trigger="click"
+                >
+                  <ul style="overflow: auto; max-height: 500px;margin:0px;">
+                    <li
+                      v-for="(itm, inds) in scope.row[item.prop]"
+                      :key="inds"
+                      class="jumpStys"
+                    >
+                      {{ inds + 1 }}、
+                      {{ itm[item.prop1] }}
+                    </li>
+                  </ul>
+                  <el-button
+                    slot="reference"
+                    style="margin-left: 6px"
+                    type="text"
+                    v-if="scope.row[item.prop].length > 1"
+                    size="mini"
+                    >更多</el-button
+                  >
+                </el-popover>
+              </div>
+              <div v-else>{{ scope.row[item.prop] }}</div>
+            </template></af-table-column
+          ></template
+        >
+        <el-table-column fixed="right" label="操作" width="100" align="center">
+          <template slot-scope="scope">
+            <el-button type="text" size="small" @click="editList(scope.row)"
+              >修改</el-button
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <add-gl ref="addGL" />
+  </div>
+</template>
+
+<script>
+import addGl from "./addGL.vue";
+export default {
+  components: { addGl },
+  data() {
+    return {
+      activeName: "first",
+      tableSet: [
+        {
+          label: "排序",
+          prop: "sort",
+          width: "120px",
+        },
+        {
+          label: "名称",
+          prop: "name",
+        },
+        {
+          label: "教育类型",
+          prop: "educationName",
+        },
+        {
+          label: "业务层次",
+          prop1: "projectName",
+          prop2: "businessName",
+          scope: "businType",
+        },
+        {
+          label: "关联商品",
+          prop: "goodsList",
+          prop1: "goodsName",
+          scope: "aboutChapter",
+        },
+        {
+          label: "状态",
+          prop: "status",
+          scope: "status",
+        },
+      ],
+      tableData: [],
+      loading: false,
+    };
+  },
+  watch: {
+    activeName(val) {
+      this.search();
+    },
+  },
+  mounted() {
+    this.search();
+  },
+  methods: {
+    search() {
+      this.loading = true;
+      this.$api
+        .inquireactivityrecommendList({
+          platform: 2,
+          type: this.activeName === "first" ? 1 : 2,
+        })
+        .then((res) => {
+          this.tableData = res.rows;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    /**
+     * 新增
+     */
+    add() {
+      this.$refs.addGL.openBox(1);
+    },
+    editList(row) {
+      this.$refs.addGL.openBox(0, row.recommendId);
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.postMs {
+  position: relative;
+  .topPost {
+    position: absolute;
+    top: 10%;
+    right: 10px;
+  }
+}
+.ulAuto {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  & > ul {
+    margin: 0px;
+  }
+}
+</style>

+ 8 - 4
src/views/Marketing/goods/commodityManageMent/add/index.vue

@@ -523,6 +523,7 @@
             ></el-input>
           </el-form-item>
           <el-form-item
+          class="positions"
             label="学习服务期"
             style="margin-top: 12px"
             :prop="
@@ -816,7 +817,7 @@
       :close-on-click-modal="false"
     >
       <div slot="title" class="hearders">
-        <div class="leftTitle">关联讲义</div>
+        <div class="leftTitle">每天学习限制</div>
         <div class="rightBoxs">
           <img
             src="@/assets/images/Close@2x.png"
@@ -826,7 +827,7 @@
         </div>
       </div>
       每天最多学习<el-input
-        style="width: 60px"
+        style="width: 60px;margin:0px 10px;"
         size="mini"
         v-model="everyDaystyleNum"
       />节视频
@@ -1865,7 +1866,7 @@ export default {
       tableSetTSB: [
         { label: "排序", prop: "sort", scope: "inputs", width: "100" },
         { label: "课程编码", prop: "code", width: "140" },
-        { label: "课程名称", prop: "prefixName", width: "190" },
+        { label: "课程名称", prop: "courseName", width: "190" },
         { label: "科目", prop: "subjectName", width: "150" },
         { label: "专业", prop: "categoryName" },
         { label: "院校", prop: "schoolName", width: "150" },
@@ -2603,7 +2604,7 @@ export default {
               this.listData.timeArrays[1] > this.listData.studyTimeArrays[1]
             ) {
               this.$message.warning(
-                "商品有效期范围必须包含在学习有效期范围内,请重新调整"
+                "商品有效期范围必须包含在学习服务期范围内,请重新调整"
               );
               this.disabledBtn = false;
               return;
@@ -3556,4 +3557,7 @@ export default {
   justify-content: center;
   align-items: center;
 }
+/deep/ .positions > .el-form-item__content > .el-form-item__error{
+  left:341px;
+}
 </style>

+ 8 - 4
src/views/Marketing/goods/commodityManageMent/edit/index.vue

@@ -530,6 +530,7 @@
           </el-form-item>
 
           <el-form-item
+          class="positions"
             label="学习服务期"
             style="margin-top: 12px"
             :prop="
@@ -828,7 +829,7 @@
       :close-on-click-modal="false"
     >
       <div slot="title" class="hearders">
-        <div class="leftTitle">关联讲义</div>
+        <div class="leftTitle">每天学习限制</div>
         <div class="rightBoxs">
           <img
             src="@/assets/images/Close@2x.png"
@@ -838,7 +839,7 @@
         </div>
       </div>
       每天最多学习<el-input
-        style="width: 60px"
+        style="width: 60px;margin:10px;"
         size="mini"
         v-model="everyDaystyleNum"
       />节视频
@@ -1843,7 +1844,7 @@ export default {
       tableSetTSB: [
         { label: "排序", prop: "sort", scope: "inputs", width: "100" },
         { label: "课程编码", prop: "code", width: "140" },
-        { label: "课程名称", prop: "prefixName", width: "190" },
+        { label: "课程名称", prop: "courseName", width: "190" },
         { label: "科目", prop: "subjectName", width: "150" },
         { label: "专业", prop: "categoryName" },
         { label: "院校", prop: "schoolName", width: "150" },
@@ -2809,7 +2810,7 @@ export default {
               this.listData.timeArrays[1] > this.listData.studyTimeArrays[1]
             ) {
               this.$message.warning(
-                "商品有效期范围必须包含在学习有效期范围内,请重新调整"
+                "商品有效期范围必须包含在学习服务期范围内,请重新调整"
               );
               this.disabledBtn = false;
               return;
@@ -3777,4 +3778,7 @@ export default {
     margin: 5px 0px;
   }
 }
+/deep/ .positions > .el-form-item__content > .el-form-item__error{
+  left:341px;
+}
 </style>

+ 11 - 10
src/views/Marketing/goods/commodityManageMent/index.vue

@@ -89,7 +89,7 @@ export default {
           prop: "status",
           placeholder: "商品状态",
           scope: "select",
-          noClear:false,
+          noClear: false,
           options: [
             {
               label: "全部状态",
@@ -225,10 +225,11 @@ export default {
         },
         {
           label: "学习服务期",
-          prop1: "studyStartTime",
-          prop2: "studyEndTime",
-          scope: "TimeLists",
-          Diszing: false,
+          prop1: "serviceTimeType",
+          prop2: "serviceTimeNum",
+          prop3: "studyStartTime",
+          prop4: "studyEndTime",
+          scope: "studentServicePeriod",
           hidden: true,
         },
         {
@@ -346,11 +347,11 @@ export default {
       } else {
         const jump = () => {
           this.$router.push({
-          path: "commodityManageMentEdit",
-          query: {
-            id: v.goodsId,
-          },
-        });
+            path: "commodityManageMentEdit",
+            query: {
+              id: v.goodsId,
+            },
+          });
         };
         const statusPage = this.$store.state.tagsView.visitedViews.some(
           (item) => {

+ 1 - 0
src/views/Marketing/goods/courseInquiryList/classNumBox.vue

@@ -7,6 +7,7 @@
       :data="tableData"
       border
       :header-cell-style="{
+        'font-size': '14px',
         'background-color': '#eee',
         padding: '8px',
         color: '#333',

+ 5 - 4
src/views/Marketing/goods/courseInquiryList/index.vue

@@ -279,10 +279,11 @@ export default {
         },
         {
           label: "学习服务期",
-          prop1: "studyStartTime",
-          prop2: "studyEndTime",
-          scope: "TimeLists",
-          Diszing: true,
+          prop1: "serviceTimeType",
+          prop2: "serviceTimeNum",
+          prop3: "studyStartTime",
+          prop4: "studyEndTime",
+          scope: "studentServicePeriod",
           hidden: true,
         },
       ],

+ 8 - 1
src/views/Marketing/order/bill/index.vue

@@ -993,6 +993,7 @@ export default {
           break;
         case 2:
           this.copyData = JSON.parse(JSON.stringify(v));
+          console.log(v, "aaa");
           this.auditData = JSON.parse(JSON.stringify(v));
           this.auditStatus = true;
           break;
@@ -1047,9 +1048,15 @@ export default {
             .editvatInvoiceOCR({ imageUrl: res })
             .then((result) => {
               if (result.data) {
+                if (result.data.invoiceCode || result.data.invoiceNum) {
+                  self.$message.success("自动识别成功");
+                } else {
+                  self.$message.error(
+                    "自动识别失败,请手动输入发票代码及发票号码"
+                  );
+                }
                 self.billSendData.invoiceCode = result.data.invoiceCode;
                 self.billSendData.invoiceNum = result.data.invoiceNum;
-                self.$message.success("自动识别成功");
               } else {
                 self.$message.error(
                   "自动识别失败,请手动输入发票代码及发票号码"

+ 35 - 5
src/views/Marketing/order/offlineOrder/batchRecord/firstStep/index.vue

@@ -5,7 +5,7 @@
         :size="size"
         v-model="topData.educationId"
         placeholder="请选择教育类型"
-        :disabled="tableData.length ? true : false"
+        :disabled="disAbs || tableData.length ? true : false"
       >
         <el-option
           v-for="(items, indexs) in educationType"
@@ -16,7 +16,7 @@
       </el-select>
       <!-- 业务层次 -->
       <el-select
-        :disabled="tableData.length ? true : false"
+        :disabled="disAbs || tableData.length ? true : false"
         v-if="topData.educationId"
         v-model="topData.businessId"
         placeholder="请选择业务层次"
@@ -186,6 +186,8 @@ export default {
         },
       ],
       sujectList: [],
+      businessIdPY: "",
+      disAbs: false,
     };
   },
   watch: {
@@ -198,6 +200,10 @@ export default {
         .inquirebusinessList({ status: 1, educationId: newVal })
         .then((res) => {
           this.newBusinessLevel = res.rows;
+          if (this.$parent.suppleRecord) {
+            this.topData.businessId = this.businessIdPY;
+            this.changeBusinessLevel(this.businessIdPY);
+          }
         });
     },
     "topData.businessId"(newVal, oldVal) {
@@ -207,6 +213,15 @@ export default {
   },
   computed: { ...mapGetters(["educationType"]) },
   mounted() {
+    if (this.$parent.suppleRecord) {
+      this.disAbs = true;
+      this.$api
+        .inquireorderinputdetail({ inputOrderSn: this.$parent.SN })
+        .then((res) => {
+          this.topData.educationId = res.data.educationTypeId;
+          this.businessIdPY = res.data.businessId;
+        });
+    }
     this.getHeightData();
     this.getSujectList();
   },
@@ -223,6 +238,12 @@ export default {
         this.$message.warning("请选择配置及商品类型");
         return;
       }
+      for (let i = 0; i < this.newBusinessLevel.length; i++) {
+        if (this.newBusinessLevel[i].id === this.topData.businessId) {
+          this.topData.projectId = this.newBusinessLevel[i].projectId;
+          break;
+        }
+      }
       let obj = {
         topData: this.topData,
         tableData: this.tableData,
@@ -351,9 +372,18 @@ export default {
     },
     backPage() {
       this.$store.dispatch("tagsView/delView", this.$route).then((res) => {
-        this.$router.push({
-          path: "offlineOrder",
-        });
+        if (this.$parent.suppleRecord) {
+          this.$router.push({
+            path: "orderDetailsT",
+            query: {
+              inputOrderSn: this.$parent.SN,
+            },
+          });
+        } else {
+          this.$router.push({
+            path: "offlineOrder",
+          });
+        }
       });
     },
   },

+ 57 - 24
src/views/Marketing/order/offlineOrder/batchRecord/index.vue

@@ -1,26 +1,32 @@
 <template>
   <div id="batchRecord">
-    <el-tabs v-model="activeName" :before-leave="beforeLeave">
-      <el-tab-pane
-        label="选择商品类型层次"
-        name="first"
-        :disabled="activeName !== 'first'"
-      ></el-tab-pane>
-      <el-tab-pane
-        label="设置商品"
-        name="second"
-        :disabled="activeName !== 'second'"
-      ></el-tab-pane>
-      <el-tab-pane
-        label="下单结果"
-        name="third"
-        :disabled="activeName !== 'third'"
-      ></el-tab-pane>
-    </el-tabs>
+    <div class="dis_sty">
+      <el-tabs v-model="activeName" :before-leave="beforeLeave">
+        <el-tab-pane
+          label="选择商品类型层次"
+          name="first"
+          :disabled="activeName !== 'first'"
+        ></el-tab-pane>
+        <el-tab-pane
+          label="设置商品"
+          name="second"
+          :disabled="activeName !== 'second'"
+        ></el-tab-pane>
+        <el-tab-pane
+          label="下单结果"
+          name="third"
+          :disabled="activeName !== 'third'"
+        ></el-tab-pane>
+      </el-tabs>
+      <span class="spanSty" v-if="suppleRecord"
+        >您当前补录的总订单编码:{{ SN }}</span
+      >
+    </div>
+
     <div class="box-height">
       <first-step v-show="activeName === 'first'" />
-      <second-step v-show="activeName === 'second'" ref="secondStep" />
-      <third-step v-show="activeName === 'third'" />
+      <second-step v-if="activeName === 'second'" ref="secondStep" />
+      <third-step v-if="activeName === 'third'" ref="thirdStep" />
     </div>
   </div>
 </template>
@@ -30,13 +36,21 @@ import firstStep from "./firstStep/index.vue";
 import secondStep from "./secondStep/index.vue";
 import thirdStep from "./thirdStep/index.vue";
 export default {
-    name:"BatchRecord",
+  name: "BatchRecord",
   components: { firstStep, secondStep, thirdStep },
   data() {
     return {
       activeName: "first",
+      SN: "",
+      suppleRecord: false,
     };
   },
+  created() {
+    if (this.$route.query.suppleRecord) {
+      this.suppleRecord = true;
+      this.SN = this.$route.query.inputOrderSn;
+    }
+  },
   methods: {
     beforeLeave(activeName, oldActiveName) {
       if (activeName === oldActiveName) {
@@ -45,15 +59,34 @@ export default {
         return true;
       }
     },
-    changePage(name,obj){
-        this.$refs.secondStep.getInitData(obj)
-        this.activeName = name
-    }
+    changePage(name, obj) {
+      this.activeName = name;
+      this.$nextTick(() => {
+        this.$refs.secondStep.getInitData(obj);
+      });
+    },
+    changePage2(name, successobj, errorobj) {
+      this.activeName = name;
+      this.$nextTick(() => {
+        this.$refs.thirdStep.getInitData(successobj, errorobj);
+      });
+    },
   },
 };
 </script>
 
 <style lang="less" scoped>
+.dis_sty {
+  position: relative;
+  .spanSty {
+    position: absolute;
+    right: 0;
+    top: 50%;
+    transform: translateY(-50%);
+    color: #f56c6c;
+    font-size: 13px;
+  }
+}
 #batchRecord {
   display: flex;
   flex-direction: column;

+ 588 - 26
src/views/Marketing/order/offlineOrder/batchRecord/secondStep/index.vue

@@ -1,64 +1,208 @@
 <template>
   <div id="secondStep">
-    <el-table
-      :data="tableData"
-      :span-method="objectSpanMethod"
-      border
-      style="width: 100%; margin-top: 10px"
-    >
-      <el-table-column
-        align="center"
-        v-for="(item, index) in tableSet"
-        :key="index"
-        :prop="item.prop"
-        :label="item.label"
-        ><template slot-scope="scope">
-          <span>{{ scope.row[item.prop] }}</span>
-        </template>
-      </el-table-column>
-    </el-table>
+    <div class="topS">
+      已选择
+      <strong style="color: red">{{ objCopy.length }}</strong> 人;共<strong
+        style="color: red"
+        >{{ compay(tableData, 6) }}</strong
+      >个商品(<strong style="color: red">{{ compay(tableData, 1) }}</strong
+      >视频、<strong style="color: red">{{ compay(tableData, 2) }}</strong
+      >题库、<strong style="color: red">{{ compay(tableData, 3) }}</strong
+      >补考、<strong style="color: red">{{ compay(tableData, 4) }}</strong
+      >前培);总价<strong style="color: red"
+        >¥{{ compay(tableData, 5).toFixed(2) }}</strong
+      >
+    </div>
+    <div class="bodySy">
+      <el-table
+        :height="heightData"
+        :data="tableData"
+        :span-method="objectSpanMethod"
+        border
+        style="width: 100%"
+      >
+        <el-table-column
+          header-align="center"
+          v-for="(item, index) in compayList(tableSet)"
+          :align="item.noCenter ? 'left' : 'center'"
+          :key="index"
+          :prop="item.prop"
+          :label="item.label"
+          :width="item.width"
+          ><template slot-scope="scope">
+            <span v-if="item.scope === 'subject'">
+              {{ changeSujectName(scope.row[item.prop]) }}
+            </span>
+            <div v-else-if="item.scope === 'goods'" style="white-space: nowrap">
+              <div v-if="!scope.row['subjectId']"></div>
+              <div v-else>
+                <el-checkbox
+                  v-if="!scope.row['success']"
+                  v-model="scope.row[item.prop1]"
+                  style="margin-right: 6px"
+                  >&nbsp;</el-checkbox
+                ><span style="color: rgb(132, 0, 255)">{{
+                  typeChange(scope.row[item.prop2])
+                }}</span
+                >{{ scope.row[item.prop3] }}
+                <el-button
+                  type="text"
+                  :style="
+                    scope.row[item.prop4] === -1 ? 'color:red!important;' : ''
+                  "
+                  style="color: green"
+                  @click="
+                    !scope.row['success']
+                      ? getClass(scope.row, scope.$index)
+                      : ''
+                  "
+                  >{{
+                    scope.row[item.prop4]
+                      ? scope.row[item.prop4] === -1
+                        ? "请选择班级"
+                        : scope.row[item.prop5]
+                      : "自动分班"
+                  }}</el-button
+                >
+              </div>
+            </div>
+            <div v-else-if="item.scope === 'priceInput'">
+              <div v-if="!scope.row['subjectId']"></div>
+              <div v-else>
+                ¥<span v-if="scope.row['success']"
+                  >{{ scope.row[item.prop] }}
+                </span>
+                <el-input-number
+                  v-else
+                  :controls="false"
+                  size="mini"
+                  :min="0"
+                  style="width: 80px"
+                  :precision="2"
+                  v-model="scope.row[item.prop]"
+                  @blur="ChangeData(item.func, scope.row, $event)"
+                ></el-input-number>
+              </div>
+            </div>
+            <span v-else-if="item.scope === 'setOption'"
+              ><el-button
+                v-if="!scope.row['success']"
+                type="text"
+                @click="setOptionsFun(scope.row)"
+                >设置</el-button
+              ><el-button
+                type="text"
+                v-if="!orderSubmitStatus && !scope.row['success']"
+                @click="submitForm(2, scope.row)"
+                >重新提交</el-button
+              ></span
+            >
+            <span v-else-if="item.scope === 'result'">
+              {{
+                scope.row["success"]
+                  ? "提交成功"
+                  : scope.row["errmsg"] || "请设置商品"
+              }}
+            </span>
+            <span v-else
+              >{{ scope.row[item.prop] >= 0 ? item.ch : ""
+              }}{{ scope.row[item.prop] }}</span
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <div class="footS">
+      <el-button size="mini" @click="backToPage">上一步</el-button>
+      <el-button size="mini" @click="backPage">取消</el-button>
+      <el-button
+        size="mini"
+        :loading="disabledBtn"
+        @click="orderSubmitStatus ? submitForm() : submitForm(1)"
+        >{{ orderSubmitStatus ? "提交下单内容" : "继续下一步" }}</el-button
+      >
+    </div>
+    <select-class ref="selectClass" />
+    <set-goods-list ref="setGoodsList" />
   </div>
 </template>
 
 <script>
+import selectClass from "./selectClass.vue";
+import setGoodsList from "./setGoodsList.vue";
 export default {
+  components: { selectClass, setGoodsList },
   data() {
     return {
+      disabledBtn: false,
+      orderSubmitStatus: true, //订单是否可提交
       tableSet: [
         {
           label: "学员姓名",
           prop: "realname",
+          width: "100px",
         },
         {
           label: "学员身份证",
           prop: "idCard",
+          width: "160px",
         },
         {
           label: "手机号码",
           prop: "telphone",
+          width: "140px",
         },
         {
           label: "科目",
-          prop: "subjectIds",
+          prop: "subjectId",
+          scope: "subject",
+          width: "120px",
         },
         {
           label: "所选商品",
-          prop: "goodsName",
+          prop1: "checked",
+          prop2: "goodsType",
+          prop3: "goodsName",
+          prop4: "gradeId",
+          prop5: "gradeName",
+          scope: "goods",
+          noCenter: true,
         },
         {
           label: "商品标准价格",
           prop: "standPrice",
+          width: "120px",
+          ch: "¥",
         },
         {
           label: "商品成交价",
-          prop: "subjectIds",
+          prop: "goodsRealPrice",
+          width: "120px",
+          scope: "priceInput",
+          func: 1,
         },
         {
           label: "本次收费金额",
-          prop: "subjectIds",
+          prop: "goodsReceived",
+          width: "120px",
+          scope: "priceInput",
+          func: 2,
+        },
+        {
+          label: "设置",
+          scope: "setOption",
+          width: "100px",
+        },
+        {
+          label: "提交结果",
+          scope: "result",
+          width: "200px",
         },
       ],
+      objCopy: [],
+      heightData: 0,
       tableData: [],
+      toData: {},
       typeNameArr: [], // 第一列进行合并操作时存放的数组变量
       typeNamePos: 0, // 上面的数组的下标值
       storeArr: [], // 第二列进行合并操作时存放的数组变量
@@ -67,10 +211,213 @@ export default {
       feePos: 0, // 上面的数组的下标值
       fourArr: [], // 第三列进行合并操作时存放的数组变量
       fourPos: 0, // 上面的数组的下标值
+      sujectList: [],
+      SN: "", //总单号
     };
   },
-  mounted() {},
+  mounted() {
+    if (this.$parent.suppleRecord) {
+      this.SN = this.$parent.SN;
+    }
+    this.getHeightData();
+    this.getSujectList();
+  },
+  computed: {
+    compay: function () {
+      return function (data, int) {
+        var num = 0;
+        switch (int) {
+          case 1:
+          case 2:
+          case 3:
+          case 4:
+            data.forEach((item) => {
+              if (item.goodsType === int && item.checked) {
+                num++;
+              }
+            });
+            break;
+          case 5:
+            data.forEach((item) => {
+              if (item.goodsReceived && item.checked) {
+                num += Number(item.goodsReceived);
+              }
+            });
+            break;
+          case 6:
+            data.forEach((item) => {
+              if (
+                item.goodsType &&
+                item.goodsId &&
+                item.goodsName &&
+                item.checked
+              ) {
+                num++;
+              }
+            });
+            break;
+
+          default:
+            break;
+        }
+        return num;
+      };
+    },
+    compayList: function () {
+      return function (list) {
+        var arr = [];
+        if (this.orderSubmitStatus) {
+          arr = this.tableSet.filter((item) => {
+            return item.scope !== "result";
+          });
+        } else {
+          arr = JSON.parse(JSON.stringify(this.tableSet));
+        }
+        return arr;
+      };
+    },
+  },
   methods: {
+    /**
+     * 取消
+     */
+    backPage() {
+      this.$store.dispatch("tagsView/delView", this.$route).then((res) => {
+        if (this.$parent.suppleRecord) {
+          this.$router.push({
+            path: "orderDetailsT",
+            query: {
+              inputOrderSn: this.$parent.SN,
+            },
+          });
+        } else {
+          this.$router.push({
+            path: "offlineOrder",
+          });
+        }
+      });
+    },
+    /**
+     * 修改金额
+     */
+    ChangeData(int, row, e) {
+      if (int === 1) {
+        if (!e.target.value) {
+          row.goodsRealPrice = 0;
+          row.goodsReceived = 0;
+        } else {
+          if (row.goodsReceived > e.target.value) {
+            row.goodsReceived = e.target.value;
+            this.$message.warning(
+              "商品成交价小于本次收费金额,已自动修改本次收费金额"
+            );
+          }
+        }
+      }
+      if (int === 2) {
+        if (!e.target.value) {
+          row.goodsReceived = 0;
+        } else {
+          if (row.goodsRealPrice < e.target.value) {
+            row.goodsReceived = row.goodsRealPrice;
+            this.$message.warning(
+              "本次收费金额大于商品成交价,已自动修改本次收费金额"
+            );
+          }
+        }
+      }
+    },
+    /**
+     * 获取表格初始高度
+     */
+    getHeightData() {
+      this.$nextTick(() => {
+        this.heightData =
+          document.getElementsByClassName("bodySy")[0].clientHeight;
+      });
+    },
+    /**
+     * 设置商品信息
+     */
+    setOptionsFun(row) {
+      let data = this.tableData.filter((item) => {
+        return item.realname === row.realname;
+      });
+      this.$refs.setGoodsList.openBox(this.toData, data);
+    },
+    uploadDatas(list) {
+      if (!list.length) return;
+      const index = this.tableData.findIndex((item) => {
+        return item.realname === list[0].realname;
+      });
+      if (index !== -1) {
+        let arr = this.tableData.filter((item) => {
+          return item.realname !== list[0].realname;
+        });
+        arr.splice(index, 0, ...list);
+        this.tableData = arr;
+      }
+      this.merage();
+    },
+    /**
+     * 选择班级
+     */
+    getClass(row, index) {
+      this.$refs.selectClass.openBox(row, index);
+    },
+    backClassData(obj, index) {
+      this.tableData[index].gradeId = obj.gradeId;
+      this.tableData[index].gradeName = obj.gradeName;
+    },
+    /**
+     * 转换商品类型
+     */
+    typeChange(int) {
+      var str = "";
+      switch (int) {
+        case 1:
+          str = "视:";
+          break;
+        case 2:
+          str = "题:";
+          break;
+        case 3:
+          str = "补:";
+          break;
+        case 4:
+          str = "前:";
+          break;
+
+        default:
+          break;
+      }
+      return str;
+    },
+    /**
+     * 转换科目Id为名称
+     */
+    changeSujectName(id) {
+      var names = "";
+      for (var i = 0; i < this.sujectList.length; i++) {
+        if (this.sujectList[i].id == id) {
+          names = this.sujectList[i].subjectName;
+          break;
+        }
+      }
+      return names;
+    },
+    /**
+     * 获取科目列表
+     */
+    getSujectList() {
+      this.$api
+        .inquireCourseSubject({
+          status: 1,
+        })
+        .then((res) => {
+          this.sujectList = res.rows;
+        });
+    },
     merageInit() {
       // 在下文的时候会用到,对数据进行初始化是很有必要的
       this.typeNameArr = [];
@@ -85,7 +432,6 @@ export default {
     merage() {
       this.merageInit(); // 前文的初始化数据函数
       for (let i = 0; i < this.tableData.length; i += 1) {
-        console.log(this.tableData[i], "aa");
         if (i === 0) {
           // 第一行必须存在
           this.typeNameArr.push(1);
@@ -179,9 +525,18 @@ export default {
           rowspan: row4,
           colspan: col4,
         };
+      } else if (columnIndex >= 8) {
+        // 第一列的合并方法
+        const row8 = this.typeNameArr[rowIndex];
+        const col8 = row8 > 0 ? 1 : 0; // 如果被合并了row = 0; 则他这个列需要取消
+        return {
+          rowspan: row8,
+          colspan: col8,
+        };
       }
     },
     getInitData(obj) {
+      this.toData = JSON.parse(JSON.stringify(obj.topData));
       let data = JSON.parse(JSON.stringify(obj.tableData));
       this.$api
         .inquireorderconfiggoodsList({
@@ -201,6 +556,11 @@ export default {
                       } else {
                         items.checked = false;
                       }
+                      items.goodsRealPrice = items.standPrice;
+                      items.goodsReceived = items.standPrice;
+                      if (!items.gradeId) {
+                        items.gradeId = 0;
+                      }
                       return items;
                     });
                     item.subjectList.push({
@@ -216,6 +576,7 @@ export default {
         });
     },
     decomposeFunc(obj) {
+      this.objCopy = JSON.parse(JSON.stringify(obj));
       var arrays = [];
       obj.forEach((item) => {
         if (item.subjectList.length == 0) {
@@ -223,19 +584,220 @@ export default {
         } else {
           item.subjectList.forEach((items) => {
             items.goodsList.forEach((itemsxs) => {
-              itemsxs.subjectId = items.subjectId;
-              var datas = Object.assign({ ...item, ...itemsxs });
-              arrays.push(datas);
+              if (this.toData.type.indexOf(itemsxs.goodsType) !== -1) {
+                itemsxs.subjectId = items.subjectId;
+                var datas = Object.assign({ ...item, ...itemsxs });
+                arrays.push(datas);
+              }
             });
           });
         }
+        let arry = arrays.some((items) => {
+          return (
+            items.realname == item.realname && items.telphone == item.telphone
+          );
+        });
+        if (!arry) {
+          arrays.push(item);
+        }
       });
       this.tableData = arrays;
       this.merage();
     },
+    backToPage() {
+      this.$alert(
+        "确定返回上一步吗?<br />内容清除后将无法恢复,请慎重考虑",
+        "提示",
+        {
+          dangerouslyUseHTMLString: true,
+        }
+      )
+        .then(() => {
+          this.$parent.activeName = "first";
+        })
+        .catch(() => {});
+    },
+    getOrderSNApi() {
+      return new Promise((resolve, reject) => {
+        this.$api
+          .apporderinput({
+            educationTypeId: this.toData.educationId,
+            projectId: this.toData.projectId,
+            businessId: this.toData.businessId,
+          })
+          .then((res) => {
+            this.SN = res.data;
+            this.$parent.SN = res.data;
+            resolve();
+          });
+      });
+    },
+    async submitForm(int, row) {
+      if (this.orderSubmitStatus) {
+        let py = this.tableData.some((item) => {
+          return item.checked && item.gradeId == -1;
+        });
+        if (py) {
+          this.$message.warning("请选择班级");
+          return;
+        }
+      } else {
+        if (int === 2 && row) {
+          let ary = this.tableData.some((item) => {
+            return (
+              item.userId === row.userId && item.checked && item.gradeId == -1
+            );
+          });
+          if (ary) {
+            this.$message.warning("请选择班级");
+            return;
+          }
+        }
+      }
+      this.disabledBtn = true;
+      if (int === 1 && !this.orderSubmitStatus) {
+        var successList = this.tableData.filter((item) => {
+          return item.checked && item.success;
+        });
+        var errorList = this.tableData.filter((item) => {
+          return item.checked && item.errmsg;
+        });
+        this.$parent.changePage2("third", successList, errorList);
+        this.disabledBtn = false;
+        return;
+      }
+      let submitTable = this.tableData.filter((item) => {
+        if (row && int === 2) {
+          return item.checked && item.userId === row.userId;
+        } else {
+          return item.checked;
+        }
+      });
+      if (!submitTable.length && int === 2) {
+        this.tableData.forEach((items, indexs) => {
+          if (items.userId === row.userId) {
+            this.$set(this.tableData[indexs], "errmsg", "");
+          }
+        });
+      }
+      if (!this.SN) {
+        await this.getOrderSNApi();
+      }
+      let arr = [];
+      submitTable.forEach((item) => {
+        if (!arr.length) {
+          arr.push({
+            inputOrderSn: this.SN,
+            orderFrom: 1,
+            userId: item.userId,
+            goodsList: [
+              {
+                goodsId: item.goodsId,
+                goodsRealPrice: item.goodsRealPrice,
+                goodsReceived: item.goodsReceived,
+                goodsPrice: item.standPrice,
+                goodsInputData: {
+                  gradeId: item.gradeId,
+                },
+              },
+            ],
+          });
+        } else {
+          const findIndex = arr.findIndex((items) => {
+            return items.userId === item.userId;
+          });
+          if (findIndex !== -1) {
+            arr[findIndex].goodsList.push({
+              goodsId: item.goodsId,
+              goodsRealPrice: item.goodsRealPrice,
+              goodsReceived: item.goodsReceived,
+              goodsPrice: item.standPrice,
+              goodsInputData: {
+                gradeId: item.gradeId,
+              },
+            });
+          } else {
+            arr.push({
+              inputOrderSn: this.SN,
+              orderFrom: 1,
+              userId: item.userId,
+              goodsList: [
+                {
+                  goodsId: item.goodsId,
+                  goodsRealPrice: item.goodsRealPrice,
+                  goodsReceived: item.goodsReceived,
+                  goodsPrice: item.standPrice,
+                  goodsInputData: {
+                    gradeId: item.gradeId,
+                  },
+                },
+              ],
+            });
+          }
+        }
+      });
+      arr.forEach(async (item, index) => {
+        await this.submitFunApi(item);
+      });
+      if (arr.length) {
+        this.$message("已提交下单内容");
+      }
+      this.disabledBtn = false;
+      this.orderSubmitStatus = false;
+    },
+    submitFunApi(item) {
+      var self = this;
+      return new Promise((resolve, reject) => {
+        self.$api.apporderinputOrder(item).then((res) => {
+          resolve(res);
+          if (res.code === 510 || res.code === 511) {
+            self.tableData.forEach((items, indexs) => {
+              if (items.userId === item.userId) {
+                self.$set(self.tableData[indexs], "errmsg", res.msg);
+              }
+            });
+          } else {
+            self.tableData.forEach((items, indexs) => {
+              if (items.userId === item.userId) {
+                if (items.errmsg) {
+                  self.$set(self.tableData[indexs], "errmsg", "");
+                }
+                self.$set(self.tableData[indexs], "success", true);
+                self.$set(self.tableData[indexs], "orderId", res.data.orderId);
+                self.$set(self.tableData[indexs], "orderSn", res.data.orderSn);
+                self.$set(self.tableData[indexs], "sheetId", res.data.sheetId);
+                self.$set(self.tableData[indexs], "sheetSn", res.data.sheetSn);
+              }
+            });
+          }
+        });
+      });
+    },
   },
 };
 </script>
 
 <style lang="less" scoped>
+#secondStep {
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+  .topS {
+    flex-shrink: 0;
+    height: 28px;
+    text-align: end;
+    font-size: 14px;
+    line-height: 28px;
+  }
+  .bodySy {
+    flex: 1;
+    margin: 10px 0px;
+    box-shadow: 0px 0px 8px 1px rgba(0, 0, 0, 0.2);
+  }
+  .footS {
+    flex-shrink: 0;
+    height: 34px;
+    text-align: center;
+  }
+}
 </style>

+ 226 - 0
src/views/Marketing/order/offlineOrder/batchRecord/secondStep/selectClass.vue

@@ -0,0 +1,226 @@
+<template>
+  <div id="selectClass">
+    <el-dialog
+      @closed="loadingClose"
+      :visible.sync="dialogCG"
+      width="360px"
+      :show-close="false"
+      :close-on-click-modal="false"
+      class="dialogNew"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">选择班级</div>
+        <div class="rightBoxs">
+          <img
+            src="@/assets/images/Close@2x.png"
+            alt=""
+            @click="dialogCG = false"
+          />
+        </div>
+      </div>
+      <div>
+        <el-radio-group v-model="radio">
+          <ul>
+            <li
+              v-for="(item, index) in classList"
+              :key="index"
+              style="margin-bottom: 20px"
+            >
+              <el-radio
+                :disabled="
+                  !item.studentUpper
+                    ? true
+                    : item.studentNum >= item.studentUpper
+                    ? true
+                    : false
+                "
+                :label="item.gradeId"
+                >{{ item.className }}</el-radio
+              >
+            </li>
+          </ul>
+        </el-radio-group>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogCG = false">取消</el-button>
+        <el-button type="primary" @click="submitCG" :loading="disabledBtn"
+          >确定</el-button
+        >
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      disabledBtn: false,
+      dialogCG: false,
+      radio: "",
+      classList: [],
+      indexResult: "", //记录当前打开的索引
+    };
+  },
+  methods: {
+    loadingClose() {
+      this.disabledBtn = false;
+    },
+    submitCG() {
+      this.disabledBtn = true;
+      var names = "";
+      if (this.radio) {
+        for (let i = 0; i < this.classList.length; i++) {
+          if (this.classList[i].gradeId == this.radio) {
+            names = this.classList[i].className;
+            break;
+          }
+        }
+      }
+      var data = { gradeId: this.radio, gradeName: names };
+      this.$parent.backClassData(data, this.indexResult);
+      this.disabledBtn = false;
+      this.dialogCG = false;
+    },
+    async openBox(row, index) {
+      await this.getClassLists(row);
+      this.radio = row.gradeId;
+      this.indexResult = index;
+      this.dialogCG = true;
+    },
+    getClassLists(item) {
+      return new Promise((resolve, reject) => {
+        this.$api
+          .inquireGradegradeList({
+            status: 1,
+            goodsId: item.goodsId,
+            pastDue: 1,
+          })
+          .then((res) => {
+            if (!res.rows.length) {
+              var ast = [
+                {
+                  className: "自动分配新班级",
+                  gradeId: 0,
+                  status: 1,
+                  studentUpper: 999,
+                  studentNum: 0,
+                },
+              ];
+              this.classList = ast;
+              resolve();
+              // });
+            } else {
+              var astu = res.rows.every((items) => {
+                return items.studentNum >= items.studentUpper;
+              });
+              if (astu) {
+                res.rows.unshift({
+                  className: "自动分配新班级",
+                  gradeId: 0,
+                  status: 1,
+                  studentUpper: 999,
+                  studentNum: 0,
+                });
+              }
+              this.classList = res.rows;
+              resolve();
+            }
+          });
+      });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+</style>

+ 424 - 0
src/views/Marketing/order/offlineOrder/batchRecord/secondStep/setGoodsList.vue

@@ -0,0 +1,424 @@
+<template>
+  <div id="setGoodsList">
+    <el-dialog
+      @closed="loadingClose"
+      :visible.sync="dialogCG"
+      width="660px"
+      :show-close="false"
+      :close-on-click-modal="false"
+      class="dialogNew"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">设置商品</div>
+        <div class="rightBoxs">
+          <img
+            src="@/assets/images/Close@2x.png"
+            alt=""
+            @click="dialogCG = false"
+          />
+        </div>
+      </div>
+      <div>
+        <el-row :gutter="10" style="height: 500px">
+          <el-col :span="6" class="leftStycol">
+            <ul
+              v-for="(item, index) in dataList"
+              :key="index"
+              style="padding-bottom: 10px"
+            >
+              <li style="margin-bottom: 10px">{{ item.subjectName }}</li>
+              <ul>
+                <li
+                  class="liStyLI"
+                  v-for="(items, indexs) in item.options"
+                  :key="indexs"
+                  :style="
+                    active == `${item.id}-${items.value}` ? 'color:red;' : ''
+                  "
+                  @click="activeLi(item.id, items.value)"
+                >
+                  {{ items.label }}
+                </li>
+              </ul>
+            </ul>
+          </el-col>
+          <el-col :span="18">
+            <div>
+              <el-input
+                :size="size"
+                v-model="goodsName"
+                style="width: 170px"
+                placeholder="请输入商品名称"
+              ></el-input>
+              <el-input
+                :size="size"
+                v-model="goodsPrice"
+                style="width: 170px"
+                placeholder="请输入商品标准价格"
+              ></el-input>
+              <el-button
+                :size="size"
+                style="margin-left: 10px"
+                type="primary"
+                @click="searchData"
+                >查询</el-button
+              >
+              <el-button :size="size" @click="init">重置</el-button>
+            </div>
+            <div
+              style="margin-top: 14px; text-align: center"
+              v-if="!goodsList.length"
+            >
+              暂无符合条件商品
+            </div>
+            <ul
+              style="
+                max-height: 240px;
+                overflow: auto;
+                background: #eee;
+                margin-top: 10px;
+              "
+            >
+              <li
+                v-for="(item, index) in goodsList"
+                :key="index"
+                style="padding: 10px; font-size: 13px"
+              >
+                <el-checkbox
+                  v-model="item.checked"
+                  @change="uploadNewData(item, $event)"
+                >
+                  {{ item.code }} - {{ item.goodsName }} -
+                  <span style="color: red">¥{{ item.standPrice }}</span>
+                </el-checkbox>
+              </li>
+            </ul>
+          </el-col>
+        </el-row>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogCG = false">取消</el-button>
+        <el-button type="primary" @click="submitCG" :loading="disabledBtn"
+          >确定</el-button
+        >
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      disabledBtn: false,
+      size: "mini",
+      dialogCG: false,
+      dataList: [],
+      active: "",
+      oldObj: {},
+      goodsList: [],
+      goodsName: "",
+      goodsPrice: "",
+      copynewDatas: [], //备份初始数据
+      newDatas: [], //进入初始数据
+    };
+  },
+  methods: {
+    loadingClose() {
+      this.disabledBtn = false;
+    },
+    uploadNewData(row, status) {
+      const arrStatus = this.newDatas.findIndex((item) => {
+        return (
+          item.goodsId == row.goodsId &&
+          item.subjectId == this.active.split("-").map(Number)[0]
+        );
+      });
+      if (status) {
+        if (arrStatus === -1) {
+          let copyDs = JSON.parse(JSON.stringify(this.newDatas[0]));
+          delete copyDs.standPrice;
+          let copyData = Object.assign({ ...copyDs, ...row });
+          copyData.goodsRealPrice = row.standPrice;
+          copyData.goodsReceived = row.standPrice;
+          copyData.subjectId = this.active.split("-").map(Number)[0];
+          copyData.checked = true;
+          if (row.gradeNum) {
+            copyData.gradeId = -1;
+          } else {
+            copyData.gradeId = 0;
+          }
+          const status = this.newDatas.some((item) => {
+            return item.subjectId == this.active.split("-").map(Number)[0];
+          });
+          const status1 = this.newDatas.some((item) => {
+            return (
+              item.subjectId == this.active.split("-").map(Number)[0] &&
+              item.goodsType == this.active.split("-").map(Number)[1]
+            );
+          });
+          if (status) {
+            if (status1) {
+              for (let i = this.newDatas.length - 1; i >= 0; i--) {
+                if (
+                  this.newDatas[i].subjectId ==
+                    this.active.split("-").map(Number)[0] &&
+                  this.newDatas[i].goodsType ==
+                    this.active.split("-").map(Number)[1]
+                ) {
+                  this.newDatas.splice(i, 0, copyData);
+                  break;
+                }
+              }
+            } else {
+              for (let i = this.newDatas.length - 1; i >= 0; i--) {
+                if (
+                  this.newDatas[i].subjectId ==
+                  this.active.split("-").map(Number)[0]
+                ) {
+                  this.newDatas.splice(i, 0, copyData);
+                  break;
+                }
+              }
+            }
+          } else {
+            this.newDatas.push(copyData);
+          }
+        } else {
+          console.log("不处理");
+        }
+      } else {
+        if (arrStatus !== -1) {
+          console.log(arrStatus, "删除处理");
+          this.newDatas.splice(arrStatus, 1);
+        } else {
+          console.log("不处理");
+        }
+      }
+    },
+    init() {
+      this.goodsName = "";
+      this.goodsPrice = "";
+      this.searchData();
+    },
+    /**
+     * 科目ID,商品类型
+     */
+    activeLi(subjectId, type) {
+      if (this.active == `${subjectId}-${type}`) return;
+      this.active = `${subjectId}-${type}`;
+      this.searchData();
+    },
+    searchData() {
+      var subjectId = this.active.split("-")[0];
+      var type = this.active.split("-")[1];
+      var priceReg = /(^[1-9]\d*(\.\d{1,2})?$)|(^0(\.\d{1,2})?$)/;
+      if (this.goodsPrice && !priceReg.test(this.goodsPrice)) {
+        this.$message.warning("请输入正确价格");
+        return;
+      }
+      var data = {
+        goodsType: type,
+        goodsName: this.goodsName || "",
+        standPrice: this.goodsPrice || "",
+      };
+      if (type == 1 || type == 2) {
+        data.subjectId = subjectId;
+      }
+      if (type == 3 || type == 4) {
+        data.businessIds = this.oldObj.businessId;
+      }
+      this.$api.inquireGoods(data).then((res) => {
+        res.rows.forEach((item) => {
+          item.subjectId = subjectId;
+          item.checked = false;
+          this.newDatas.forEach((items) => {
+            if (
+              items.subjectId == item.subjectId &&
+              items.goodsId == item.goodsId
+            ) {
+              item.checked = true;
+            }
+          });
+        });
+        this.goodsList = res.rows;
+      });
+    },
+    submitCG() {
+      this.disabledBtn = true;
+      let arrays = this.newDatas.filter((item) => {
+        return item.subjectId && item.goodsId;
+      });
+      if (!arrays.length && this.copynewDatas.length) {
+        var data = {};
+        data = JSON.parse(JSON.stringify(this.copynewDatas[0]));
+        delete data.standPrice;
+        delete data.goodsRealPrice;
+        delete data.goodsReceived;
+        delete data.subjectId;
+        delete data.goodsId;
+        delete data.goodsName;
+        delete data.goodsType;
+        delete data.checked;
+        arrays = [data];
+      }
+      arrays.forEach((item, index) => {
+        this.copynewDatas.forEach((items) => {
+          if (
+            item.subjectId == items.subjectId &&
+            item.goodsId == items.goodsId
+          ) {
+            arrays.splice(index, 1, items);
+          }
+        });
+      });
+      this.$parent.uploadDatas(arrays);
+      this.disabledBtn = false;
+      this.dialogCG = false;
+    },
+    openBox(oldObj, datas) {
+      this.newDatas = JSON.parse(JSON.stringify(datas));
+      this.copynewDatas = JSON.parse(JSON.stringify(datas));
+      this.oldObj = JSON.parse(JSON.stringify(oldObj));
+      this.active = "";
+      this.goodsList = [];
+      this.goodsName = "";
+      this.goodsPrice = "";
+      this.$api
+        .inquireCourseSubject({ businessId: Number(oldObj.businessId) })
+        .then((res) => {
+          let options = [];
+          if (oldObj.type.indexOf(1) !== -1) {
+            options.push({ label: "视频商品", value: 1 });
+          }
+          if (oldObj.type.indexOf(2) !== -1) {
+            options.push({ label: "题库商品", value: 2 });
+          }
+          if (oldObj.type.indexOf(3) !== -1) {
+            options.push({ label: "补考商品", value: 3 });
+          }
+          if (oldObj.type.indexOf(4) !== -1) {
+            options.push({ label: "前培商品", value: 4 });
+          }
+          this.dataList = res.rows.map((item) => {
+            return {
+              id: item.id,
+              subjectName: item.subjectName,
+              options: options,
+            };
+          });
+        });
+      this.dialogCG = true;
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.leftStycol {
+  max-height: 100%;
+  overflow: auto;
+  background: #eee;
+  padding: 10px;
+}
+.liStyLI {
+  cursor: pointer;
+  text-align: center;
+  margin-bottom: 10px;
+}
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__body {
+    padding: 10px;
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+ul {
+  margin: 0px;
+}
+</style>

+ 508 - 3
src/views/Marketing/order/offlineOrder/batchRecord/thirdStep/index.vue

@@ -1,15 +1,520 @@
 <template>
-  <div id="thirdStep">thirdStep</div>
+  <div id="thirdStep">
+    <div class="topS">
+      <el-row>
+        <el-col :span="10"
+          ><el-tabs v-model="newActive">
+            <el-tab-pane label="成功录入" name="success"></el-tab-pane>
+            <el-tab-pane label="失败录入" name="error"></el-tab-pane> </el-tabs
+        ></el-col>
+        <el-col :span="14"
+          ><strong style="color: red">{{
+            newActive === "success"
+              ? "下单成功:"
+              : newActive === "error"
+              ? "下单失败:"
+              : ""
+          }}</strong
+          ><strong style="color: red">{{ tableData.length }}</strong>
+          人;共<strong style="color: red">{{ compay(tableData, 6) }}</strong
+          >个商品(<strong style="color: red">{{ compay(tableData, 1) }}</strong
+          >视频、<strong style="color: red">{{ compay(tableData, 2) }}</strong
+          >题库、<strong style="color: red">{{ compay(tableData, 3) }}</strong
+          >补考、<strong style="color: red">{{ compay(tableData, 4) }}</strong
+          >前培)<span v-if="newActive === 'success'"
+            >;总价<strong style="color: red"
+              >¥{{ compay(tableData, 5).toFixed(2) }}</strong
+            ></span
+          ><el-button size="mini" v-if="newActive === 'error'" type="success"
+            >下载失败数据</el-button
+          ><el-button
+            size="mini"
+            style="margin-left: 8px"
+            v-if="newActive === 'success'"
+            type="text"
+            @click="setOptionsFun(1)"
+            >收付款补充信息(总单)</el-button
+          >
+        </el-col>
+      </el-row>
+    </div>
+    <div class="bodySy">
+      <el-table
+        :height="heightData"
+        :data="tableData"
+        :span-method="objectSpanMethod"
+        border
+        style="width: 100%"
+      >
+        <el-table-column
+          header-align="center"
+          v-for="(item, index) in compayType(tableSet)"
+          :align="item.noCenter ? 'left' : 'center'"
+          :key="index"
+          :prop="item.prop"
+          :label="item.label"
+          :width="item.width"
+          ><template slot-scope="scope">
+            <span v-if="item.scope === 'subject'">
+              {{ changeSujectName(scope.row[item.prop]) }}
+            </span>
+            <div v-else-if="item.scope === 'goods'" style="white-space: nowrap">
+              <div v-if="!scope.row['subjectId']"></div>
+              <div v-else>
+                <span style="color: rgb(132, 0, 255)">{{
+                  typeChange(scope.row[item.prop2])
+                }}</span
+                >{{ scope.row[item.prop3] }}
+                <el-button type="text" style="color: green">{{
+                  scope.row[item.prop4] ? scope.row[item.prop5] : "自动分班"
+                }}</el-button>
+              </div>
+            </div>
+            <div v-else-if="item.scope === 'priceInput'">
+              <div v-if="!scope.row['subjectId']"></div>
+              <div v-else>¥{{ scope.row[item.prop] }}</div>
+            </div>
+            <span v-else-if="item.scope === 'success'"
+              ><el-button type="text" @click="setOptionsFun(2, scope.row)"
+                >补充信息</el-button
+              ></span
+            >
+            <span v-else-if="item.scope === 'error'">
+              {{ scope.row[item.prop] }}
+            </span>
+            <span v-else
+              >{{ scope.row[item.prop] >= 0 ? item.ch : ""
+              }}{{ scope.row[item.prop] }}</span
+            >
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <div class="footS">
+      <el-button size="mini" @click="backPage">关闭</el-button>
+    </div>
+    <information-add ref="informationAdd" />
+  </div>
 </template>
 
 <script>
+import informationAdd from "./informationAdd.vue";
 export default {
+  components: { informationAdd },
   data() {
-    return {};
+    return {
+      newActive: "success",
+      tableSet: [
+        {
+          label: "学员姓名",
+          prop: "realname",
+          width: "100px",
+        },
+        {
+          label: "学员身份证",
+          prop: "idCard",
+          width: "160px",
+        },
+        {
+          label: "手机号码",
+          prop: "telphone",
+          width: "140px",
+        },
+        {
+          label: "科目",
+          prop: "subjectId",
+          scope: "subject",
+          width: "120px",
+        },
+        {
+          label: "所选商品",
+          prop1: "checked",
+          prop2: "goodsType",
+          prop3: "goodsName",
+          prop4: "gradeId",
+          prop5: "gradeName",
+          scope: "goods",
+          noCenter: true,
+        },
+        {
+          label: "商品标准价格",
+          prop: "standPrice",
+          width: "120px",
+          ch: "¥",
+        },
+        {
+          label: "商品成交价",
+          prop: "goodsRealPrice",
+          width: "120px",
+          scope: "priceInput",
+          func: 1,
+        },
+        {
+          label: "本次收费金额",
+          prop: "goodsReceived",
+          width: "120px",
+          scope: "priceInput",
+          func: 2,
+        },
+        {
+          label: "收付款",
+          width: "100px",
+          scope: "success",
+        },
+        {
+          label: "出错原因",
+          prop: "errmsg",
+          width: "100px",
+          scope: "error",
+        },
+      ],
+      objCopy: [],
+      heightData: 0,
+      tableData: [],
+      typeNameArr: [], // 第一列进行合并操作时存放的数组变量
+      typeNamePos: 0, // 上面的数组的下标值
+      storeArr: [], // 第二列进行合并操作时存放的数组变量
+      storePos: 0, // 上面的数组的下标值
+      feeArr: [], // 第三列进行合并操作时存放的数组变量
+      feePos: 0, // 上面的数组的下标值
+      fourArr: [], // 第三列进行合并操作时存放的数组变量
+      fourPos: 0, // 上面的数组的下标值
+      sujectList: [],
+      successobj: [], //成功数据
+      errorobj: [], //失败数据
+    };
+  },
+  mounted() {
+    this.getHeightData();
+    this.getSujectList();
+  },
+  watch: {
+    newActive(val) {
+      if (val === "success") {
+        this.tableData = JSON.parse(JSON.stringify(this.successobj));
+      }
+      if (val === "error") {
+        this.tableData = JSON.parse(JSON.stringify(this.errorobj));
+      }
+      this.merage();
+    },
+  },
+  computed: {
+    compay: function () {
+      return function (data, int) {
+        var num = 0;
+        switch (int) {
+          case 1:
+          case 2:
+          case 3:
+          case 4:
+            data.forEach((item) => {
+              if (item.goodsType === int && item.checked) {
+                num++;
+              }
+            });
+            break;
+          case 5:
+            data.forEach((item) => {
+              if (item.goodsReceived && item.checked) {
+                num += Number(item.goodsReceived);
+              }
+            });
+            break;
+          case 6:
+            data.forEach((item) => {
+              if (
+                item.goodsType &&
+                item.goodsId &&
+                item.goodsName &&
+                item.checked
+              ) {
+                num++;
+              }
+            });
+            break;
+
+          default:
+            break;
+        }
+        return num;
+      };
+    },
+    compayType: function () {
+      return function (arr) {
+        var arrs = [];
+        switch (this.newActive) {
+          case "success":
+            arrs = arr.filter((item) => {
+              return item.scope !== "error";
+            });
+            break;
+          case "error":
+            arrs = arr.filter((item) => {
+              return item.scope !== "success";
+            });
+            break;
+
+          default:
+            break;
+        }
+        return arrs;
+      };
+    },
+  },
+  methods: {
+    backSearch() {
+      const jump = () => {
+        this.$router.push({
+          path: "orderDetailsT",
+          query: {
+            inputOrderSn: this.$parent.SN,
+          },
+        });
+      };
+      const statusPage = this.$store.state.tagsView.visitedViews.some(
+        (item) => {
+          return item.name == "OrderDetailsT";
+        }
+      );
+      if (statusPage) {
+        this.$store
+          .dispatch("tagsView/delCachedView", {
+            name: "OrderDetailsT",
+          })
+          .then((res) => {
+            jump();
+          });
+      } else {
+        jump();
+      }
+    },
+    /**
+     * 取消
+     */
+    backPage() {
+      this.$store.dispatch("tagsView/delView", this.$route).then((res) => {
+        if (this.$parent.suppleRecord) {
+          this.backSearch();
+        } else {
+          this.$router.push({
+            path: "offlineOrder",
+          });
+        }
+      });
+    },
+    /**
+     * 获取表格初始高度
+     */
+    getHeightData() {
+      this.$nextTick(() => {
+        this.heightData =
+          document.getElementsByClassName("bodySy")[0].clientHeight;
+      });
+    },
+    /**
+     * 设置商品信息
+     */
+    setOptionsFun(int, row) {
+      this.$refs.informationAdd.openBox(int, row);
+    },
+    /**
+     * 转换商品类型
+     */
+    typeChange(int) {
+      var str = "";
+      switch (int) {
+        case 1:
+          str = "视:";
+          break;
+        case 2:
+          str = "题:";
+          break;
+        case 3:
+          str = "补:";
+          break;
+        case 4:
+          str = "前:";
+          break;
+
+        default:
+          break;
+      }
+      return str;
+    },
+    /**
+     * 转换科目Id为名称
+     */
+    changeSujectName(id) {
+      var names = "";
+      for (var i = 0; i < this.sujectList.length; i++) {
+        if (this.sujectList[i].id == id) {
+          names = this.sujectList[i].subjectName;
+          break;
+        }
+      }
+      return names;
+    },
+    /**
+     * 获取科目列表
+     */
+    getSujectList() {
+      this.$api
+        .inquireCourseSubject({
+          status: 1,
+        })
+        .then((res) => {
+          this.sujectList = res.rows;
+        });
+    },
+    merageInit() {
+      // 在下文的时候会用到,对数据进行初始化是很有必要的
+      this.typeNameArr = [];
+      this.typeNamePos = 0;
+      this.storeArr = [];
+      this.storePos = 0;
+      this.feeArr = [];
+      this.feePos = 0;
+      this.fourArr = [];
+      this.fourPos = 0;
+    },
+    merage() {
+      this.merageInit(); // 前文的初始化数据函数
+      for (let i = 0; i < this.tableData.length; i += 1) {
+        if (i === 0) {
+          // 第一行必须存在
+          this.typeNameArr.push(1);
+          this.typeNamePos = 0;
+          this.storeArr.push(1);
+          this.storePos = 0;
+          this.feeArr.push(1);
+          this.feePos = 0;
+          this.fourArr.push(1);
+          this.fourPos = 0;
+        } else {
+          // 判断当前元素与上一个元素是否相同,eg:this.typeNamePos 是 this.typeNameArr序号
+          // 第一列 下面的是eslint的不限制语法
+          // eslint-disable-next-line no-lonely-if
+          if (this.tableData[i].realname === this.tableData[i - 1].realname) {
+            this.typeNameArr[this.typeNamePos] += 1;
+            this.typeNameArr.push(0);
+          } else {
+            this.typeNameArr.push(1);
+            this.typeNamePos = i;
+          }
+          // 第二列
+          if (
+            this.tableData[i].idCard === this.tableData[i - 1].idCard &&
+            this.tableData[i].realname === this.tableData[i - 1].realname
+          ) {
+            this.storeArr[this.storePos] += 1;
+            this.storeArr.push(0);
+          } else {
+            this.storeArr.push(1);
+            this.storePos = i;
+          }
+          // 第三列
+          if (
+            this.tableData[i].telphone === this.tableData[i - 1].telphone &&
+            this.tableData[i].idCard === this.tableData[i - 1].idCard &&
+            this.tableData[i].realname === this.tableData[i - 1].realname
+          ) {
+            this.feeArr[this.feePos] += 1;
+            this.feeArr.push(0);
+          } else {
+            this.feeArr.push(1);
+            this.feePos = i;
+          }
+          // 第四列
+          if (
+            this.tableData[i].telphone === this.tableData[i - 1].telphone &&
+            this.tableData[i].idCard === this.tableData[i - 1].idCard &&
+            this.tableData[i].realname === this.tableData[i - 1].realname &&
+            this.tableData[i].subjectId === this.tableData[i - 1].subjectId
+          ) {
+            this.fourArr[this.fourPos] += 1;
+            this.fourArr.push(0);
+          } else {
+            this.fourArr.push(1);
+            this.fourPos = i;
+          }
+        }
+      }
+    },
+    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
+      if (columnIndex === 0) {
+        // 第一列的合并方法
+        const row1 = this.typeNameArr[rowIndex];
+        const col1 = row1 > 0 ? 1 : 0; // 如果被合并了row = 0; 则他这个列需要取消
+        return {
+          rowspan: row1,
+          colspan: col1,
+        };
+      } else if (columnIndex === 1) {
+        // 第二列的合并方法
+        const row2 = this.storeArr[rowIndex];
+        const col2 = row2 > 0 ? 1 : 0; // 如果被合并了row = 0; 则他这个列需要取消
+        return {
+          rowspan: row2,
+          colspan: col2,
+        };
+      } else if (columnIndex === 2) {
+        // 第三列的合并方法
+        const row3 = this.feeArr[rowIndex];
+        const col3 = row3 > 0 ? 1 : 0; // 如果被合并了row = 0; 则他这个列需要取消
+        return {
+          rowspan: row3,
+          colspan: col3,
+        };
+      } else if (columnIndex === 3) {
+        // 第四列的合并方法
+        const row4 = this.fourArr[rowIndex];
+        const col4 = row4 > 0 ? 1 : 0; // 如果被合并了row = 0; 则他这个列需要取消
+        return {
+          rowspan: row4,
+          colspan: col4,
+        };
+      } else if (columnIndex >= 8) {
+        // 第一列的合并方法
+        const row8 = this.typeNameArr[rowIndex];
+        const col8 = row8 > 0 ? 1 : 0; // 如果被合并了row = 0; 则他这个列需要取消
+        return {
+          rowspan: row8,
+          colspan: col8,
+        };
+      }
+    },
+    getInitData(successobj, errorobj) {
+      this.successobj = JSON.parse(JSON.stringify(successobj));
+      this.errorobj = JSON.parse(JSON.stringify(errorobj));
+      this.tableData = JSON.parse(JSON.stringify(successobj));
+      this.merage();
+    },
   },
-  methods: {},
 };
 </script>
 
 <style lang="less" scoped>
+#thirdStep {
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+  .topS {
+    flex-shrink: 0;
+    height: 28px;
+    text-align: end;
+    font-size: 14px;
+    line-height: 28px;
+  }
+  .bodySy {
+    flex: 1;
+    margin: 10px 0px;
+    box-shadow: 0px 0px 8px 1px rgba(0, 0, 0, 0.2);
+  }
+  .footS {
+    flex-shrink: 0;
+    height: 34px;
+    text-align: center;
+  }
+}
 </style>

+ 337 - 0
src/views/Marketing/order/offlineOrder/batchRecord/thirdStep/informationAdd.vue

@@ -0,0 +1,337 @@
+<template>
+  <div id="informationAdd">
+    <el-dialog
+      @closed="loadingClose"
+      :visible.sync="dialogCG"
+      width="860px"
+      :show-close="false"
+      :close-on-click-modal="false"
+      class="dialogNew"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">
+          收付款补充信息<span v-if="int === 1">(总单)</span>
+        </div>
+        <div class="rightBoxs">
+          <img
+            src="@/assets/images/Close@2x.png"
+            alt=""
+            @click="dialogCG = false"
+          />
+        </div>
+      </div>
+      <div>
+        <el-form
+          ref="listData"
+          :model="listData"
+          :label-position="position"
+          label-width="130px"
+        >
+          <p class="botSty">付款人</p>
+          <el-row :gutter="10">
+            <el-col :span="12"
+              ><el-form-item label="付款人:">
+                <el-input
+                  v-model="listData.payer"
+                  placeholder="请输入付款人"
+                ></el-input> </el-form-item></el-col
+            ><el-col :span="12"
+              ><el-form-item label="付款人手机号码:">
+                <el-input
+                  v-model="listData.payerTel"
+                  placeholder="请输入付款人手机号码"
+                ></el-input> </el-form-item></el-col
+            ><el-col :span="12"
+              ><el-form-item label="付款方式:">
+                <el-select
+                  v-model="listData.payType"
+                  placeholder="请选择付款方式"
+                >
+                  <el-option
+                    v-for="(item, index) in payType"
+                    :key="index"
+                    :label="item.label"
+                    :value="item.value"
+                  >
+                  </el-option>
+                </el-select> </el-form-item></el-col
+            ><el-col :span="12"
+              ><el-form-item label="付款账号:">
+                <el-input
+                  v-model="listData.payAccount"
+                  placeholder="请输入付款账号"
+                ></el-input> </el-form-item
+            ></el-col>
+          </el-row>
+          <p class="botSty">收款人</p>
+          <el-row>
+            <el-col :span="12"
+              ><el-form-item label="收款方:">
+                <el-select
+                  v-model="listData.payee"
+                  placeholder="请选择收款方"
+                  @change="intePhs"
+                >
+                  <el-option
+                    v-for="(item, index) in paypayee"
+                    :key="index"
+                    :label="item.payeeName"
+                    :value="item.payeeName"
+                  >
+                  </el-option> </el-select></el-form-item></el-col
+            ><el-col :span="12" v-if="listData.payee"
+              ><el-form-item label="收款账号:">
+                <el-select
+                  v-model="listData.collectionAccount"
+                  placeholder="请选择收款账号"
+                >
+                  <el-option
+                    v-for="(item, index) in payeeList"
+                    :key="index"
+                    :label="item.payeeAccount"
+                    :value="item.payeeAccount"
+                  >
+                  </el-option>
+                </el-select> </el-form-item></el-col
+            ><el-col :span="12"
+              ><el-form-item label="支付通道:">
+                <el-select
+                  v-model="listData.payChannel"
+                  placeholder="请选择支付通道"
+                >
+                  <el-option
+                    v-for="(item, index) in payList"
+                    :key="index"
+                    :label="item.payWay"
+                    :value="item.payWay"
+                  >
+                  </el-option>
+                </el-select> </el-form-item></el-col
+            ><el-col :span="12"
+              ><el-form-item label="POS机终端号:">
+                <el-input
+                  v-model="listData.posNumber"
+                  placeholder="请输入POS机终端号"
+                ></el-input> </el-form-item></el-col
+            ><el-col :span="12"
+              ><el-form-item label="凭证号:">
+                <el-input
+                  v-model="listData.voucherNo"
+                  placeholder="请输入凭证号"
+                ></el-input> </el-form-item></el-col
+            ><el-col :span="12"
+              ><el-form-item label="参考号:">
+                <el-input
+                  v-model="listData.refNo"
+                  placeholder="请输入参考号"
+                ></el-input> </el-form-item
+            ></el-col>
+          </el-row>
+        </el-form>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogCG = false">取消</el-button>
+        <el-button type="primary" @click="submitCG" :loading="disabledBtn"
+          >确定</el-button
+        >
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from "vuex";
+export default {
+  data() {
+    return {
+      disabledBtn: false,
+      position: "right",
+      dialogCG: false,
+      obj: {},
+      int: null,
+      listData: { collectionAccount: "" },
+      payeeList: [],
+      payType: [
+        {
+          label: "微信",
+          value: "weChatPay",
+        },
+        {
+          label: "支付宝",
+          value: "aliPay",
+        },
+        {
+          label: "银联",
+          value: "bankCard",
+        },
+        {
+          label: "现金",
+          value: "cash",
+        },
+      ],
+    };
+  },
+  computed: { ...mapGetters(["paypayee", "payList"]) },
+  methods: {
+    loadingClose() {
+      this.disabledBtn = false;
+    },
+    openBox(int, obj) {
+      this.int = int;
+      if (int === 1) {
+        this.listData = {
+          collectionAccount: "",
+        };
+        this.dialogCG = true;
+      }
+      if (int === 2) {
+        this.obj = JSON.parse(JSON.stringify(obj));
+        this.$api.obtainOrdersheet(obj.sheetId).then((res) => {
+          this.listData = res.data;
+          this.dialogCG = true;
+        });
+      }
+    },
+    resetForm(formName) {
+      this.$refs[formName].resetFields();
+    },
+    submitCG() {
+      this.disabledBtn = true;
+      if (this.int === 1) {
+        var data = JSON.parse(JSON.stringify(this.listData));
+        data.inputOrderSn = this.$parent.$parent.SN;
+        this.$api
+          .editOrdersheetinput(data)
+          .then((res) => {
+            this.$message.success("提交成功");
+            this.dialogCG = false;
+          })
+          .catch(() => {
+            this.disabledBtn = false;
+          });
+      }
+      if (this.int === 2) {
+        var data = JSON.parse(JSON.stringify(this.listData));
+        data.sheetId = this.obj.sheetId;
+        this.$api
+          .editordersheetedit(data)
+          .then((res) => {
+            this.$message.success("提交成功");
+            this.dialogCG = false;
+          })
+          .catch(() => {
+            this.disabledBtn = false;
+          });
+      }
+    },
+    //查询收款方账号
+    intePhs() {
+      this.$api
+        .inquirePayeeAisle({ payeeName: this.listData.payee })
+        .then((res) => {
+          this.payeeList = res.rows;
+          this.listData.collectionAccount = "";
+        });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.botSty {
+  border-bottom: 1px dashed #eee;
+  padding-bottom: 6px;
+}
+/deep/ .el-input__inner {
+  width: 240px !important;
+}
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+</style>

+ 493 - 0
src/views/Marketing/order/offlineOrder/billingBillCharges/index.vue

@@ -0,0 +1,493 @@
+<template>
+  <div id="billingBillCharges">
+    <h5 style="margin: 10px 0px">计费单收费</h5>
+    <div class="boxsSTTs">
+      <el-form
+        size="mini"
+        label-position="right"
+        label-width="120px"
+        :model="listData"
+        ref="listData"
+      >
+        <el-row>
+          <el-col :span="12"><h5 class="fengs">付款人</h5></el-col
+          ><el-col :span="12"> <h5 class="fengs">收款人</h5></el-col>
+          <el-col :span="6">
+            <el-form-item label="付款人" prop="payer">
+              <el-input v-model="listData.payer"></el-input>
+            </el-form-item>
+            <el-form-item label="付款方式" prop="payType">
+              <el-select
+                v-model="listData.payType"
+                placeholder="请选择付款方式"
+              >
+                <el-option
+                  v-for="(item, index) in payType"
+                  :key="index"
+                  :label="item.label"
+                  :value="item.value"
+                >
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="付款人手机号码" prop="payerTel">
+              <el-input v-model="listData.payerTel"></el-input>
+            </el-form-item>
+            <el-form-item label="付款账号" prop="payAccount">
+              <el-input v-model="listData.payAccount"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item label="收款方" prop="payee">
+              <el-select
+                v-model="listData.payee"
+                placeholder="请选择收款方"
+                @change="intePhs"
+              >
+                <el-option
+                  v-for="(item, index) in paypayee"
+                  :key="index"
+                  :label="item.payeeName"
+                  :value="item.payeeName"
+                >
+                </el-option>
+              </el-select>
+            </el-form-item>
+            <el-form-item label="支付通道" prop="payChannel">
+              <el-select
+                v-model="listData.payChannel"
+                placeholder="请选择支付通道"
+              >
+                <el-option
+                  v-for="(item, index) in payList"
+                  :key="index"
+                  :label="item.payWay"
+                  :value="item.payWay"
+                >
+                </el-option>
+              </el-select>
+            </el-form-item>
+            <el-form-item label="凭证号" prop="voucherNo">
+              <el-input v-model="listData.voucherNo"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="6">
+            <el-form-item
+              v-if="listData.payee"
+              label="收款账号"
+              prop="collectionAccount"
+            >
+              <el-select
+                v-model="listData.collectionAccount"
+                placeholder="请选择收款账号"
+              >
+                <el-option
+                  v-for="(item, index) in payeeList"
+                  :key="index"
+                  :label="item.payeeAccount"
+                  :value="item.payeeAccount"
+                >
+                </el-option>
+              </el-select>
+            </el-form-item>
+            <el-form-item label="POS机终端号" prop="posNumber">
+              <el-input v-model="listData.posNumber"></el-input>
+            </el-form-item>
+            <el-form-item label="参考号" prop="refNo">
+              <el-input v-model="listData.refNo"></el-input>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <h5 class="fengs">收费总览</h5>
+      <div style="flex: 1; overflow: auto; background: #eee">
+        <table border class="tableSty">
+          <tr style="background: #eee">
+            <th v-for="(items, indexs) in tableSet" :key="indexs">
+              {{ items.label }}
+            </th>
+          </tr>
+          <tr
+            v-for="(itList, idList) in costList"
+            :key="idList"
+            style="background: #fff"
+          >
+            <td v-for="(items, indexs) in tableSet" :key="indexs">
+              <span v-if="items.scope === 'isOptions'">
+                <span v-for="(its, ids) in items.options" :key="ids">
+                  <span v-if="its.value == itList[items.prop]">{{
+                    its.label
+                  }}</span>
+                </span>
+              </span>
+              <span v-else-if="items.scope === 'set'">
+                <el-button type="text" @click="del(idList)">删除</el-button>
+              </span>
+              <span v-else-if="items.scope === 'eduType'">
+                {{ itList[items.prop1] }} - {{ itList[items.prop2] }} -
+                {{ itList[items.prop3] }}
+              </span>
+              <div v-else-if="items.scope === 'price'">
+                <el-input-number
+                  size="mini"
+                  style="width: 80px"
+                  v-model="itList[items.prop]"
+                  :controls="false"
+                  :min="0.01"
+                  :precision="2"
+                  :max="itList['payPrice'] - itList['goodsReceived']"
+                ></el-input-number>
+              </div>
+              <span v-else>
+                <span v-if="items.ch">{{ items.ch }}</span
+                >{{ itList[items.prop] }}
+              </span>
+            </td>
+          </tr>
+        </table>
+      </div>
+      <div class="foty">
+        <span>
+          本次收费总金额:<span style="color: red; font-weight: bold"
+            >¥{{ compay(costList, 5) }}</span
+          >
+        </span>
+        <span style="margin-left: 18px"
+          >视频商品:¥{{ compay(costList, 1) }}</span
+        >
+        <span style="margin-left: 18px"
+          >题库商品:¥{{ compay(costList, 2) }}</span
+        >
+        <span style="margin-left: 18px"
+          >补考商品:¥{{ compay(costList, 3) }}</span
+        >
+        <span style="margin-left: 18px"
+          >前培商品:¥{{ compay(costList, 4) }}</span
+        >
+      </div>
+    </div>
+    <div style="text-align: center; margin-top: 10px">
+      <el-button size="mini" @click="clearBtns">取消</el-button>
+      <el-button
+        v-if="costList.length"
+        size="mini"
+        type="primary"
+        @click="submit"
+        :loading="disabledBtn"
+        >提交计费单</el-button
+      >
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from "vuex";
+export default {
+  name: "BillingBillCharges",
+  data() {
+    return {
+      disabledBtn: false,
+      tableSet: [
+        {
+          label: "商品类型",
+          prop: "goodsType",
+          scope: "isOptions",
+          options: [
+            {
+              label: "视频",
+              value: 1,
+            },
+            {
+              label: "题库",
+              value: 2,
+            },
+            {
+              label: "补考",
+              value: 3,
+            },
+            {
+              label: "前培",
+              value: 4,
+            },
+          ],
+        },
+        {
+          label: "学员姓名",
+          prop: "realname",
+        },
+        {
+          label: "学员身份证号码",
+          prop: "idCard",
+        },
+        {
+          label: "订单编码",
+          prop: "orderSn",
+        },
+        {
+          label: "商品编码",
+          prop: "code",
+        },
+        {
+          label: "商品业务层级",
+          prop1: "educationName",
+          prop2: "projectName",
+          prop3: "businessName",
+          scope: "eduType",
+        },
+        {
+          label: "商品名称",
+          prop: "goodsName",
+        },
+        {
+          label: "商品标价",
+          prop: "orderPrice",
+          ch: "¥",
+        },
+        {
+          label: "商品成交价",
+          prop: "payPrice",
+          ch: "¥",
+        },
+        {
+          label: "已收金额",
+          prop: "goodsReceived",
+          ch: "¥",
+        },
+        {
+          label: "本次收费金额",
+          prop: "amount",
+          scope: "price",
+        },
+        {
+          label: "操作",
+          scope: "set",
+        },
+      ],
+      listData: {
+        collectionAccount: "",
+        goodsList: [],
+      },
+      costList: [],
+      payeeList: [], //收款方账号
+      payType: [
+        {
+          label: "微信",
+          value: "weChatPay",
+        },
+        {
+          label: "支付宝",
+          value: "aliPay",
+        },
+        {
+          label: "银行卡",
+          value: "bankCard",
+        },
+        {
+          label: "现金",
+          value: "cash",
+        },
+      ],
+      tableData: [],
+    };
+  },
+  computed: {
+    ...mapGetters(["paypayee", "payList", "paynature", "paycost"]),
+
+    compay: function () {
+      return function (data, int) {
+        var num = 0;
+        switch (int) {
+          case 1:
+          case 2:
+          case 3:
+          case 4:
+            data.forEach((item) => {
+              if (item.goodsType == int) {
+                if (item.amount) {
+                  num += parseFloat(item.amount);
+                }
+              }
+            });
+            break;
+          case 5:
+            data.forEach((item) => {
+              if (item.amount) {
+                num += parseFloat(item.amount);
+              }
+            });
+            break;
+          default:
+            break;
+        }
+        return parseFloat(num).toFixed(2);
+      };
+    },
+  },
+  created() {
+    if (this.$route.query.toStatus == 1) {
+      this.$api
+        .inquireOrderList({ inputOrderSn: this.$route.query.inputOrderSn })
+        .then((res) => {
+          const ary = res.rows.filter((item) => {
+            item.amount = (item.payPrice - item.goodsReceived).toFixed(2);
+            return (
+              item.refundStatus !== 1 &&
+              item.refundStatus !== 2 &&
+              item.goodsPayStatus !== 3 &&
+              item.goodsPayStatus !== 4
+            );
+          });
+          this.costList = ary;
+        });
+    }
+    if (this.$route.query.toStatus == 2) {
+      this.$api
+        .inquireOrderList({ orderGoodsIds: this.$route.query.orderGoodsIds })
+        .then((res) => {
+          const ary = res.rows.filter((item) => {
+            item.amount = (item.payPrice - item.goodsReceived).toFixed(2);
+            return (
+              item.refundStatus !== 1 &&
+              item.refundStatus !== 2 &&
+              item.goodsPayStatus !== 3 &&
+              item.goodsPayStatus !== 4
+            );
+          });
+          this.costList = ary;
+        });
+    }
+  },
+  mounted() {},
+  methods: {
+    del(index) {
+      this.costList.splice(index, 1);
+      this.$message.success("删除成功");
+    },
+    submit() {
+      this.disabledBtn = true;
+      const status = this.costList.some((item) => {
+        return !item.amount;
+      });
+      if (status) {
+        this.$message.error("请填写本次收费金额");
+        this.disabledBtn = false;
+        return;
+      }
+      let newList = this.costList.map((item) => {
+        return {
+          amount: item.amount,
+          goodsId: item.goodsId,
+          orderSn: item.orderSn,
+        };
+      });
+      this.listData.goodsList = newList;
+      this.$api
+        .appOrdersheet(this.listData)
+        .then((res) => {
+          this.$message.success("提交成功");
+          setTimeout(() => {
+            if (this.$route.query.toStatus == 1) {
+              this.$store
+                .dispatch("tagsView/exitView", this.$route)
+                .then(() => {
+                  this.$router.push({
+                    path: "offlineOrder",
+                  });
+                });
+            }
+            if (this.$route.query.toStatus == 2) {
+              this.$store
+                .dispatch("tagsView/exitView", this.$route)
+                .then((res) => {
+                  this.$router.push({
+                    path: "orderDetailsT",
+                    query: {
+                      inputOrderSn: this.$route.query.inputOrderSn,
+                    },
+                  });
+                });
+            }
+          }, 300);
+        })
+        .catch(() => {
+          this.disabledBtn = false;
+        });
+    },
+    //取消
+    clearBtns() {
+      if (this.$route.query.toStatus == 1) {
+        this.$store.dispatch("tagsView/delView", this.$route).then(() => {
+          this.$router.push({
+            path: "offlineOrder",
+          });
+        });
+      }
+      if (this.$route.query.toStatus == 2) {
+        this.$store.dispatch("tagsView/delView", this.$route).then((res) => {
+          this.$router.push({
+            path: "orderDetailsT",
+            query: {
+              inputOrderSn: this.$route.query.inputOrderSn,
+            },
+          });
+        });
+      }
+    },
+    //查询收款方账号
+    intePhs() {
+      this.$api
+        .inquirePayeeAisle({ payeeName: this.listData.payee })
+        .then((res) => {
+          this.payeeList = res.rows;
+          this.listData.collectionAccount = "";
+        });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+#billingBillCharges {
+  display: flex;
+  flex-direction: column;
+  height: calc(100vh - 130px);
+}
+.tableSty {
+  border-collapse: collapse;
+  width: 100%;
+  font-size: 12px;
+  text-align: center;
+  th,
+  td {
+    padding: 5px;
+    font-weight: 500;
+  }
+}
+.boxsSTTs {
+  display: flex;
+  flex-direction: column;
+  flex: 1;
+  overflow: auto;
+  border: 1px solid #eee;
+  border-top: 2px solid rgb(179, 204, 255);
+  padding: 10px;
+}
+.fengs {
+  border-bottom: 1px dashed #a4a4a4;
+  color: #a4a4a4;
+  padding: 4px 0px;
+  margin: 0px 0px 10px;
+}
+.foty {
+  padding: 6px 0px;
+  background-color: #eee;
+  border: 1px solid #666;
+  text-align: center;
+  font-size: 14px;
+}
+/deep/ .el-input--mini .el-input__inner {
+  max-width: 190px;
+}
+</style>

+ 242 - 268
src/views/Marketing/order/offlineOrder/index.vue

@@ -1,5 +1,12 @@
 <template>
   <div id="offlineOrder">
+    <search-box-new
+      ref="searchBox"
+      :formData="formData"
+      :formList="formList"
+      @search="search"
+      @init="init"
+    />
     <table-list
       :tableSets="tableSet"
       :tableData="tableData"
@@ -14,123 +21,36 @@
         >
       </template>
       <template slot="btn" slot-scope="props">
-        <el-button type="text" @click="del(props.scope.row)">删除</el-button>
+        <el-button type="text" @click="theOrderJump(props.scope.row, 1)"
+          >订单详情</el-button
+        >
+        <el-button type="text" @click="theOrderJump(props.scope.row, 2)"
+          >计费单收费</el-button
+        >
+        <el-button type="text" @click="theOrderJump(props.scope.row, 3)"
+          >订单收费信息</el-button
+        >
       </template>
     </table-list>
     <pagination
       :total="total"
-      :pageSize="pageSize"
-      :currentPage="currentPage"
+      :pageSize="formData.pageSize"
+      :currentPage="formData.pageNum"
       @handleSizeChange="handleSizeChange"
       @handleCurrentChange="handleCurrentChange"
     />
-    <el-dialog
-      @closed="loadingClose"
-      :visible.sync="dialogVisible"
-      width="560px"
-      :show-close="false"
-      :close-on-click-modal="false"
-    >
-      <div slot="title" class="hearders">
-        <div class="leftTitle">
-          {{ statusPop === 1 ? "添加" : statusPop === 0 ? "修改" : "详情" }}
-        </div>
-        <div class="rightBoxs">
-          <img src="@/assets/images/Close@2x.png" alt="" @click="close" />
-        </div>
-      </div>
-      <div>
-        <el-form
-          label-position="right"
-          label-width="130px"
-          :model="listData"
-          :rules="rules"
-          ref="listData"
-        >
-          <el-form-item
-            v-for="(items, indexs) in listitem"
-            :key="indexs"
-            :label="items.label"
-            :prop="items.prop"
-          >
-            <el-radio-group
-              v-if="items.scope === 'status'"
-              v-model="listData[items.prop]"
-            >
-              <el-radio
-                v-for="(item, index) in items.options"
-                :key="index"
-                :label="item.value"
-                :disabled="statusPop === 2"
-                >{{ item.label }}</el-radio
-              >
-            </el-radio-group>
-            <el-input
-              :disabled="statusPop === 2"
-              v-else-if="items.scope === 'textarea'"
-              type="textarea"
-              v-model="listData[items.prop]"
-            ></el-input>
-            <el-select
-              v-model="listData[items.prop]"
-              :disabled="statusPop === 2"
-              v-else-if="items.scope === 'select'"
-            >
-              <el-option
-                v-for="item in items.options"
-                :key="item.value"
-                :label="item.label"
-                :value="item.value"
-              >
-              </el-option>
-            </el-select>
-            <el-select
-              v-model="listData[items.prop]"
-              :disabled="statusPop === 2"
-              v-else-if="items.scope === 'tongdao'"
-            >
-              <el-option
-                v-for="item in payList"
-                :key="item.aisleId"
-                :label="item.payWay"
-                :value="item.aisleId"
-              >
-              </el-option>
-            </el-select>
-
-            <el-input
-              :disabled="statusPop === 2"
-              v-else
-              v-model="listData[items.prop]"
-            ></el-input>
-          </el-form-item>
-        </el-form>
-      </div>
-      <span slot="footer" class="dialog-footer">
-        <el-button @click="close">取 消</el-button>
-        <el-button
-          type="primary"
-          :loading="disabledBtn"
-          v-if="statusPop !== 2"
-          @click="submit('listData')"
-          >确 定</el-button
-        >
-      </span>
-    </el-dialog>
   </div>
 </template>
 
 <script>
-import { mapGetters } from "vuex";
-import searchBox from "@/components/searchBox";
+import searchBoxNew from "@/components/searchBoxNew";
 import tableList from "@/components/tableList";
 import pagination from "@/components/pagination";
 export default {
   name: "OfflineOrder",
-  components: { searchBox, tableList, pagination },
+  components: { searchBoxNew, tableList, pagination },
   data() {
     return {
-      disabledBtn: false,
       loading: false, //当前表单加载是否加载动画
       navText: {
         title: "线下订单",
@@ -139,118 +59,118 @@ export default {
         num: true,
         choice: true,
         addHide: true,
+        changeWidth: "300px",
         backFatherBtn: {
           status: false,
           title: "未定义",
         },
       },
-      // 表单
+      //搜索
+      formList: [
+        {
+          prop: "educationTypeId",
+          placeholder: "教育类型",
+          scope: "educationType",
+        },
+        {
+          prop: "businessId",
+          placeholder: "业务层次",
+          scope: "businessLevel",
+          edu: "educationTypeId",
+        },
+        {
+          prop1: "startTime",
+          prop2: "endTime",
+          placeholder1: "订单开始时间",
+          placeholder2: "订单结束时间",
+          scope: "moreDataPicker",
+          Diszing: true,
+        },
+        {
+          prop: "searchKey",
+          placeholder: "请输入订单编码/录单人姓名",
+        },
+      ],
+      formData: {
+        status: 1,
+        pageSize: 10,
+        pageNum: 1,
+      },
       tableSet: [
         {
-          label: "收款方账号",
-          prop: "payeeAccount",
+          label: "订单时间",
+          prop: "createTime",
           hidden: true,
+          scope: "aTimeList",
         },
         {
-          label: "收款方账号类型",
-          prop: "typeStatus",
+          label: "订单编码",
+          prop: "inputOrderSn",
           hidden: true,
-          scope: "typeStatusName",
         },
         {
-          label: "支付通道",
-          prop: "payWay",
+          label: "学员",
+          prop: "userNum",
           hidden: true,
         },
         {
-          label: "状态",
-          prop: "status",
+          label: "商品数量",
+          prop: "goodsNum",
           hidden: true,
-          scope: "status",
         },
-      ],
-      tableData: [], //表单数据
-      total: 0, //一共多少条
-      pageSize: 10, //每页多少条数据
-      currentPage: 1, //当前页码
-      // 弹窗字段
-      listitem: [
         {
-          label: "收款方账号",
-          prop: "payeeAccount",
+          label: "商品业务层级",
+          prop1: "educationName",
+          prop2: "projectName",
+          prop3: "businessName",
+          hidden: true,
+          scope: "eduTypes",
         },
         {
-          label: "收款方账号类型",
-          prop: "typeStatus",
-          scope: "select",
-          options: [
-            {
-              label: "扫码支付",
-              value: 1,
-            },
-            {
-              label: "刷卡支付",
-              value: 2,
-            },
-            {
-              label: "现金",
-              value: 3,
-            },
-            {
-              label: "转账",
-              value: 4,
-            },
-          ],
+          label: "商品标准价格总金额",
+          prop: "orderPrice",
+          hidden: true,
+          scope: "leftCh",
+          ch: "¥",
+        },
+        {
+          label: "商品成交价格总金额",
+          prop: "payPrice",
+          hidden: true,
+          scope: "leftCh",
+          ch: "¥",
         },
         {
-          label: "支付通道",
-          prop: "aisleId",
-          scope: "tongdao",
+          label: "已收总金额",
+          prop: "goodsReceived",
+          hidden: true,
+          scope: "leftCh",
+          ch: "¥",
         },
         {
-          label: "状态",
-          prop: "status",
-          scope: "status",
-          options: [
-            {
-              label: "启用",
-              value: 1,
-            },
-            {
-              label: "关闭",
-              value: 0,
-            },
-          ],
+          label: "已退总金额",
+          prop: "standPrice",
+          hidden: true,
+          scope: "leftCh",
+          ch: "¥",
+        },
+        {
+          label: "未收总金额",
+          prop1: "payPrice",
+          prop2: "goodsReceived",
+          hidden: true,
+          scope: "outStandingAmount",
+        },
+        {
+          label: "录单人",
+          prop: "createUsername",
+          hidden: true,
         },
       ],
-      //   弹窗数据
-      listData: {},
-      statusPop: -1,
-      dialogVisible: false,
-      //表单验证
-      rules: {
-        payeeAccount: [
-          { required: true, message: "请输入收款方账号", trigger: "blur" },
-        ],
-        typeStatus: [
-          {
-            required: true,
-            message: "请选择收款方账号类型",
-            trigger: ["change", "blur"],
-          },
-        ],
-        aisleId: [
-          {
-            required: true,
-            message: "请选择支付通道",
-            trigger: ["change", "blur"],
-          },
-        ],
-        status: [{ required: true, message: "请选择状态", trigger: "change" }],
-      },
+      tableData: [], //表单数据
+      total: 0, //一共多少条
     };
   },
-  computed: { ...mapGetters(["payList"]) },
   mounted() {
     this.search();
   },
@@ -265,107 +185,161 @@ export default {
         });
       }
       if (int === 2) {
-        this.$router.push({
-          path: "batchRecord",
-        });
+        const jump = () => {
+          this.$router.push({
+            path: "batchRecord",
+          });
+        };
+        const statusPage = this.$store.state.tagsView.visitedViews.some(
+          (item) => {
+            return item.name == "BatchRecord";
+          }
+        );
+        if (statusPage) {
+          this.$store
+            .dispatch("tagsView/delCachedView", {
+              name: "BatchRecord",
+            })
+            .then((res) => {
+              jump();
+            });
+        } else {
+          jump();
+        }
       }
     },
-    loadingClose() {
-      this.disabledBtn = false;
-    },
-    search(v) {
-      //   this.loading = true;
-      //   var data = {
-      //     payeeId: this.$route.query.id,
-      //     status: "0,1",
-      //     pageSize: this.pageSize,
-      //     pageNum: this.currentPage,
-      //   };
-      //   this.$api
-      //     .inquirePayeeAisle(data)
-      //     .then((res) => {
-      //       this.tableData = res.rows;
-      //       this.total = res.total;
-      //       this.navText.index = res.total;
-      //     })
-      //     .finally(() => {
-      //       this.loading = false;
-      //     });
+    search(int) {
+      this.loading = true;
+      if (int === 1) {
+        this.formData.pageNum = 1;
+      }
+      if (int === 2) {
+        this.formData = {
+          status: 1,
+          pageSize: 10,
+          pageNum: 1,
+        };
+      }
+      if (int === 3) {
+        this.formData.pageNum = 1;
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      if (this.formData.startTime) {
+        data.startTime = data.startTime / 1000;
+      }
+      if (this.formData.endTime) {
+        data.endTime = data.endTime / 1000;
+      }
+      this.$api
+        .inquireorderinputList(data)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+          this.navText.index = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
     },
     init() {
-      this.search();
+      this.search(2);
     },
-    del(v) {
-      //   this.$alert(
-      //     "确定删除此内容?<br />内容删除后将无法恢复,请慎重考虑",
-      //     "提示",
-      //     {
-      //       dangerouslyUseHTMLString: true,
-      //     }
-      //   )
-      //     .then(() => {
-      //       var data = {
-      //         accountId: v.accountId,
-      //         status: -1,
-      //       };
-      //       this.$api.editPayeeAisle(data).then((res) => {
-      //         this.$message.success("删除成功");
-      //         this.search();
-      //       });
-      //     })
-      //     .catch(() => {
-      //       this.$message({
-      //         type: "info",
-      //         message: "已取消删除",
-      //       });
-      //     });
-    },
-    submit(formName) {
-      this.$refs[formName].validate((valid) => {
-        if (valid) {
-          this.rulesTableSumbit();
+    /**
+     * int 1订单详情2计费单收费3订单收费信息
+     */
+    theOrderJump(row, int) {
+      if (int === 1) {
+        const jump = () => {
+          this.$router.push({
+            path: "orderDetailsT",
+            query: {
+              inputOrderSn: row.inputOrderSn,
+            },
+          });
+        };
+        const statusPage = this.$store.state.tagsView.visitedViews.some(
+          (item) => {
+            return item.name == "OrderDetailsT";
+          }
+        );
+        if (statusPage) {
+          this.$store
+            .dispatch("tagsView/delCachedView", {
+              name: "OrderDetailsT",
+            })
+            .then((res) => {
+              jump();
+            });
         } else {
-          return false;
+          jump();
         }
-      });
-    },
-    rulesTableSumbit() {
-      this.disabledBtn = true;
-      if (this.statusPop === 1) {
-        this.$api
-          .appPayeeAisle(this.listData)
-          .then((res) => {
-            this.$message.success("新增成功");
-            this.dialogVisible = false;
-            this.search();
-          })
-          .catch(() => {
-            this.disabledBtn = false;
+      }
+      if (int === 2) {
+        const jump = () => {
+          this.$router.push({
+            path: "billingBillCharges",
+            query: {
+              inputOrderSn: row.inputOrderSn,
+              toStatus: 1,
+            },
           });
+        };
+        const statusPage = this.$store.state.tagsView.visitedViews.some(
+          (item) => {
+            return item.name == "BillingBillCharges";
+          }
+        );
+        if (statusPage) {
+          this.$store
+            .dispatch("tagsView/delCachedView", {
+              name: "BillingBillCharges",
+            })
+            .then((res) => {
+              jump();
+            });
+        } else {
+          jump();
+        }
       }
-      if (this.statusPop === 0) {
-        this.$api
-          .editPayeeAisle(this.listData)
-          .then((res) => {
-            this.$message.success("修改成功");
-            this.dialogVisible = false;
-            this.search();
-          })
-          .catch(() => {
-            this.disabledBtn = false;
+      if (int === 3) {
+        if (!row.goodsNum && !row.userNum) {
+          this.$message.error("该订单无学员及商品数量");
+          return;
+        }
+        const jump = () => {
+          this.$router.push({
+            path: "orderChargeInfo",
+            query: {
+              inputOrderSn: row.inputOrderSn,
+              status: 1,
+            },
           });
+        };
+        const statusPage = this.$store.state.tagsView.visitedViews.some(
+          (item) => {
+            return item.name == "OrderChargeInfo";
+          }
+        );
+        if (statusPage) {
+          this.$store
+            .dispatch("tagsView/delCachedView", {
+              name: "OrderChargeInfo",
+            })
+            .then((res) => {
+              jump();
+            });
+        } else {
+          jump();
+        }
       }
     },
-    close() {
-      this.dialogVisible = false;
-    },
     handleSizeChange(v) {
-      this.pageSize = v;
-      this.currentPage = 1;
+      this.formData.pageSize = v;
+      this.formData.pageNum = 1;
       this.search();
     },
     handleCurrentChange(v) {
-      this.currentPage = v;
+      this.formData.pageNum = v;
       this.search();
     },
   },

+ 250 - 0
src/views/Marketing/order/offlineOrder/orderChargeInfo/bodyBox.vue

@@ -0,0 +1,250 @@
+<template>
+  <div id="bodyBox">
+    <el-row style="height: 100%">
+      <el-col :span="4" class="height_sty" style="background: #eee">
+        <div
+          v-for="(item, index) in list"
+          :key="index"
+          style="padding: 10px; padding-bottom: 0px"
+        >
+          <span class="userSty" @click="openActive(item.userId)"
+            >{{ item.realname }}-{{ item.idCard }}</span
+          >
+          <ul v-if="item.checked" style="padding-left: 20px; margin: 0px">
+            <li
+              v-for="(items, indexs) in item.goodsList"
+              :key="indexs"
+              style="margin: 4px 0px"
+            >
+              <span
+                class="userSty"
+                @click="activeUser(items)"
+                :style="
+                  active == `${items.userId}-${items.goodsId}`
+                    ? 'color:red'
+                    : ''
+                "
+              >
+                {{ items.goodsName }}
+              </span>
+            </li>
+          </ul>
+        </div>
+      </el-col>
+      <el-col :span="20" class="height_sty clsy" style="padding-left: 14px">
+        <div class="topStyle">
+          <el-tabs v-model="activeName" style="height: 55px; flex-shrink: 0">
+            <el-tab-pane label="商品信息" name="first"></el-tab-pane>
+            <el-tab-pane label="学员信息" name="second"></el-tab-pane>
+            <el-tab-pane label="收费信息" name="third"></el-tab-pane>
+            <el-tab-pane label="退费信息" name="fourd"></el-tab-pane>
+          </el-tabs>
+          <el-button class="postBtn" size="mini" type="danger" @click="BACK"
+            >返回</el-button
+          >
+        </div>
+
+        <div class="height_sty">
+          <goods-infos
+            :orderSn="orderSn"
+            :goodsId="goodsId"
+            v-if="activeName === 'first'"
+          />
+          <student-order
+            :orderSn="orderSn"
+            :goodsId="goodsId"
+            :userId="userId"
+            v-if="activeName === 'second'"
+          />
+          <cost-price
+            :orderSn="orderSn"
+            :goodsId="goodsId"
+            :orderFrom="orderFrom"
+            v-if="activeName === 'third'"
+          />
+          <refund-infos
+            :orderGoodsId="orderGoodsId"
+            :userId="userId"
+            v-if="activeName === 'fourd'"
+          />
+        </div>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import goodsInfos from "./goodsDocument/goodsInfos.vue";
+import studentOrder from "./goodsDocument/studentOrder.vue";
+import costPrice from "./goodsDocument/costPrice.vue";
+import refundInfos from "./goodsDocument/refundInfos.vue";
+export default {
+  components: { goodsInfos, studentOrder, costPrice, refundInfos },
+  data() {
+    return {
+      list: [], //学员列表
+      active: "",
+      activeName: "",
+      goodsId: "",
+      orderSn: "",
+      userId: "",
+      orderGoodsId: "",
+      orderFrom: "", //订单来源
+      initActive: true, //初始是否执行过选中状态
+    };
+  },
+  created() {
+    this.getInfo();
+  },
+  methods: {
+    /**
+     * 获取学员列表
+     */
+    getInfo() {
+      this.$api
+        .inquireorderinputuserList({
+          inputOrderSn: this.$route.query.inputOrderSn,
+        })
+        .then((res) => {
+          this.list = res.rows;
+          if (res.rows.length) {
+            console.log(this.$route.query.status);
+            if (this.$route.query.status == 1) {
+              this.openActive(res.rows[0].userId);
+            }
+            if (this.$route.query.status == 2) {
+              this.openActive(Number(this.$route.query.userId));
+            }
+          }
+        });
+    },
+    /**
+     * 选中
+     */
+    activeUser(item) {
+      console.log(item);
+      this.active = `${item.userId}-${item.goodsId}`;
+      this.goodsId = item.goodsId;
+      this.orderSn = item.orderSn;
+      this.orderGoodsId = item.orderGoodsId;
+      this.userId = item.userId;
+      this.orderFrom = item.orderFrom;
+      this.activeName = "first";
+    },
+    /**
+     * 展开学员商品信息
+     */
+    openActive(id) {
+      var self = this;
+      for (let i = 0; i < this.list.length; i++) {
+        if (this.list[i].userId === id && this.list[i].apiYes) {
+          this.list[i].checked = !this.list[i].checked;
+          return;
+        }
+      }
+      this.$api
+        .inquireorderinputuserGoodsList({
+          userId: id,
+          inputOrderSn: self.$route.query.inputOrderSn,
+        })
+        .then((res) => {
+          this.list.forEach((item, index) => {
+            if (item.userId === id) {
+              self.$set(self.list[index], "goodsList", res.rows);
+              self.$set(self.list[index], "apiYes", true);
+              self.$set(self.list[index], "checked", true);
+              if (self.initActive) {
+                if (self.$route.query.status == 1) {
+                  self.activeUser(res.rows[0]);
+                }
+                if (self.$route.query.status == 2) {
+                  const indexNum = res.rows.findIndex((its, ids) => {
+                    return its.orderGoodsId == self.$route.query.orderGoodsId;
+                  });
+                  self.activeUser(res.rows[indexNum]);
+                }
+                self.initActive = false;
+              }
+            }
+          });
+        });
+    },
+    /**
+     * 返回上一级
+     */
+    BACK() {
+      if (this.$route.query.status == 1) {
+        this.$store.dispatch("tagsView/delView", this.$route).then((res) => {
+          this.$router.push({
+            path: "offlineOrder",
+          });
+        });
+      }
+      if (this.$route.query.status == 2) {
+        this.$store.dispatch("tagsView/delView", this.$route).then((res) => {
+          const jump = () => {
+            this.$router.push({
+              path: "orderDetailsT",
+              query: {
+                inputOrderSn: this.$route.query.inputOrderSn,
+              },
+            });
+          };
+          const statusPage = this.$store.state.tagsView.visitedViews.some(
+            (item) => {
+              return item.name == "OrderDetailsT";
+            }
+          );
+          if (statusPage) {
+            this.$store
+              .dispatch("tagsView/delCachedView", {
+                name: "OrderDetailsT",
+              })
+              .then((res) => {
+                jump();
+              });
+          } else {
+            jump();
+          }
+        });
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+#bodyBox {
+  flex: 1;
+  overflow: auto;
+  border: 1px solid #999;
+}
+.topStyle {
+  position: relative;
+  .postBtn {
+    position: absolute;
+    top: 9%;
+    right: 20px;
+  }
+}
+.ulSty {
+  margin: 0px;
+}
+.height_sty {
+  height: 100%;
+  overflow: auto;
+}
+.userSty {
+  font-size: 14px;
+  cursor: pointer;
+  user-select: none;
+  &:hover {
+    color: red;
+    transition: all 0.3s;
+  }
+}
+.clsy {
+  display: flex;
+  flex-direction: column;
+}
+</style>

+ 301 - 0
src/views/Marketing/order/offlineOrder/orderChargeInfo/goodsDocument/costPrice.vue

@@ -0,0 +1,301 @@
+<template>
+  <div id="costPrice">
+    <el-row
+      v-if="orderFrom == 2 || orderFrom == 3 || orderFrom == 4"
+      style="background-color: #eee"
+    >
+      <!-- <el-form>
+        <el-col :span="8">
+          <el-form-item label="付款方式">
+            <el-input  value="微信"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="付款凭证">
+            <el-input  v-model="listInfos.transid"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="付款时间">
+            <el-input
+              
+              :value="$methodsTools.onlyForma(listInfos.payTime)"
+            ></el-input>
+          </el-form-item>
+        </el-col>
+      </el-form> -->
+    </el-row>
+    <el-row v-else>
+      <el-col :span="5" v-if="orderList.length">
+        <div>
+          <ul class="ulChildSty">
+            <header class="hearderStys" @click="isShow = !isShow">
+              计费单收费 (点击{{ isShow ? "展开" : "收起" }})
+            </header>
+            <li
+              v-for="(item, index) in orderList"
+              :style="
+                isShow
+                  ? 'height:0px;padding:0px;overflow:hidden'
+                  : 'text-align:center;'
+              "
+              :class="index + 1 == activeList ? 'active' : ''"
+              :key="index"
+              @click="changeLi(index)"
+            >
+              {{ item.sheetSn }}
+            </li>
+          </ul>
+        </div>
+      </el-col>
+      <el-col :span="19" class="YZsty" v-if="orderList.length">
+        <el-form
+          label-position="right"
+          label-width="120px"
+          :model="listData"
+          ref="listData"
+          :rules="rules"
+        >
+          <el-col :span="24" class="fgx">付款人</el-col>
+          <el-col :span="12">
+            <el-form-item label="付款人" prop="payer">
+              <el-input v-model="listData.payer"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="付款人手机号码" prop="payerTel">
+              <el-input v-model="listData.payerTel"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="付款方式" prop="payType">
+              <el-input v-model="listData.payType"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="付款账号" prop="payAccount">
+              <el-input v-model="listData.payAccount"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="付款时间">
+              <el-input
+                disabled
+                :value="$methodsTools.onlyForma(listData.payTime)"
+              ></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24" class="fgx">收款人</el-col>
+          <el-col :span="12">
+            <el-form-item label="收款方" prop="payee">
+              <el-input v-model="listData.payee"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="收款账号" prop="collectionAccount">
+              <el-input v-model="listData.collectionAccount"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="支付通道" prop="payChannel">
+              <el-input v-model="listData.payChannel"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="POS机终端号" prop="posNumber">
+              <el-input v-model="listData.posNumber"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="凭证号" prop="voucherNo">
+              <el-input v-model="listData.voucherNo"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="参考号" prop="refNo">
+              <el-input v-model="listData.refNo"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="收款时间">
+              <el-input
+                disabled
+                :value="$methodsTools.onlyForma(listData.collectionTime)"
+              ></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24" class="fgx">收费总览</el-col>
+          <el-col :span="12">
+            <el-form-item label="收费性质" prop="natureCharges">
+              <el-select
+                v-model="costList.natureCharges"
+                placeholder="请选择收费性质"
+              >
+                <el-option
+                  v-for="(item, index) in paynature"
+                  :key="index"
+                  :label="item.natureName"
+                  :value="item.natureName"
+                >
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="费用类型" prop="costType">
+              <el-select
+                v-model="costList.costType"
+                placeholder="请选择费用类型"
+              >
+                <el-option
+                  v-for="(item, index) in paycost"
+                  :key="index"
+                  :label="item.costName"
+                  :value="item.costName"
+                >
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="收费金额" prop="amount">
+              <el-input disabled v-model="costList.amount"></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="收费说明" prop="description">
+              <el-input
+                type="textarea"
+                v-model="costList.description"
+              ></el-input>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24" style="text-align: center">
+            <el-button size="mini" type="primary" @click="submit"
+              >保存</el-button
+            >
+          </el-col>
+        </el-form>
+      </el-col>
+      <el-col :span="24" class="YZsty" v-else>
+        <p style="text-align: center">暂无收费订单信息</p>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from "vuex";
+export default {
+  props: ["goodsId", "orderSn", "orderFrom"],
+  data() {
+    return {
+      isShow: false,
+      activeList: 1,
+      listData: {},
+      rules: {},
+      orderList: [],
+      costList: {},
+    };
+  },
+  mounted() {
+    this.getInfoUser();
+  },
+  computed: { ...mapGetters(["paynature", "paycost"]) },
+  methods: {
+    //保存
+    submit() {
+      this.$api.editordersheetedit(this.listData).then((res) => {
+        this.$api.editordersheetgoods(this.costList).then((result) => {
+          this.$message.success("成功");
+        });
+      });
+    },
+    //返回
+    backPage() {
+      this.$store.dispatch("tagsView/delView", this.$route).then((res) => {
+        this.$router.push({
+          path: "orderList",
+        });
+      });
+    },
+    //切换list
+    changeLi(int) {
+      if (int + 1 === this.activeList) {
+        return;
+      }
+      this.listData = this.orderList[int];
+      this.activeList = int + 1;
+      this.getCostInfos(this.orderList[int].sheetSn);
+    },
+    getInfoUser() {
+      this.$api
+        .inquireOrdersheetsheetList({
+          orderSn: this.orderSn,
+          goodsId: this.goodsId,
+        })
+        .then((res) => {
+          this.orderList = res.data;
+          if (res.data.length) {
+            console.log(res.data, "计费单列表");
+            this.getCostInfos(res.data[0].sheetSn);
+          }
+        });
+    },
+    getCostInfos(v) {
+      this.orderList.map((item) => {
+        if (item.sheetSn === v) {
+          this.costList = item;
+        }
+      });
+      this.$api.obtainOrdersheetSn(v).then((res) => {
+        this.listData = res.data;
+      });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+#costPrice {
+  background: #eee;
+}
+.hearderStys {
+  text-align: center;
+  background-color: rgb(218, 218, 218);
+  border: 1px solid #666;
+  padding: 6px 10px;
+  font-size: 15px;
+  font-weight: bold;
+  cursor: pointer;
+}
+.ulChildSty {
+  margin: 0;
+  & > li {
+    border: 1px solid #666;
+    border-top: transparent;
+    font-size: 14px;
+    padding: 6px 10px;
+    word-wrap: break-word;
+    word-break: normal;
+    cursor: pointer;
+    &:hover {
+      color: red;
+    }
+  }
+}
+.active {
+  color: blue !important;
+}
+.YZsty {
+  background-color: #eee;
+  padding: 30px;
+}
+.fgx {
+  border-bottom: 1px dotted #9a9a9a;
+  padding-bottom: 4px;
+  font-size: 14px;
+  color: #666;
+  margin-bottom: 10px;
+}
+</style>

+ 427 - 0
src/views/Marketing/order/offlineOrder/orderChargeInfo/goodsDocument/goodsInfos.vue

@@ -0,0 +1,427 @@
+<template>
+  <div id="goodsInfos">
+    <el-form
+      label-position="right"
+      label-width="130px"
+      :model="listData"
+      ref="listData"
+    >
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="订单编码" prop="orderSn">
+            <el-input
+              disabled
+              v-model="listData.orderSn"
+              :size="size"
+            ></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="订单时间" prop="createTime">
+            <el-input
+              :size="size"
+              disabled
+              :value="$methodsTools.onlyForma(listData.createTime)"
+            ></el-input>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <div class="fgx"></div>
+      <el-row>
+        <el-col
+          v-for="(item, index) in lists"
+          :key="index"
+          :span="item.col ? item.col : 12"
+          :offset="item.offset ? item.offset : 0"
+        >
+          <el-form-item
+            :label="item.label"
+            :prop="item.prop"
+            label-width="130px"
+          >
+            <template v-if="item.dataType === 'listData'">
+              <el-select
+                :size="size"
+                disabled
+                v-if="item.scope === 'payType'"
+                v-model="listData[item.prop]"
+                :placeholder="item.placeholder"
+              >
+                <el-option
+                  v-for="item in payType"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                >
+                </el-option>
+              </el-select>
+              <el-input
+                :size="size"
+                :disabled="item.disabled ? false : true"
+                v-else
+                v-model="listData[item.prop]"
+              ></el-input>
+            </template>
+            <template v-else>
+              <div v-if="item.scope === 'table'">
+                <el-table
+                  :size="size"
+                  :data="goodsData.standPriceJson"
+                  show-summary
+                  border
+                  :header-cell-style="{
+                    'background-color': '#eee',
+                    padding: '8px',
+                    color: '#333',
+                  }"
+                >
+                  <el-table-column
+                    type="index"
+                    label="序号"
+                    width="80"
+                    align="center"
+                  >
+                  </el-table-column>
+                  <el-table-column
+                    v-for="(items, indexs) in tableSet"
+                    :width="items.width"
+                    :key="indexs"
+                    :label="items.label"
+                    align="center"
+                    :show-overflow-tooltip="true"
+                    header-align="center"
+                    :prop="items.prop"
+                  >
+                    <template slot-scope="scope">
+                      <span>{{ scope.row[items.prop] }}</span></template
+                    >
+                  </el-table-column>
+                </el-table>
+              </div>
+              <el-select
+                :size="size"
+                disabled
+                v-else-if="item.scope === 'select'"
+                v-model="goodsData[item.prop]"
+              >
+                <el-option
+                  v-for="item in optionsType"
+                  :key="item.value"
+                  :label="item.label"
+                  :value="item.value"
+                ></el-option>
+              </el-select>
+              <el-date-picker
+                :size="size"
+                disabled
+                v-else-if="item.scope === 'startEndTime'"
+                v-model="goodsData[item.prop]"
+                type="daterange"
+                value-format="timestamp"
+                range-separator="至"
+                start-placeholder="开始日期"
+                end-placeholder="结束日期"
+              >
+              </el-date-picker>
+              <el-input
+                :size="size"
+                disabled
+                v-else-if="item.scope === 'yecj'"
+                :value="
+                  goodsData[item.prop1] +
+                  '-' +
+                  goodsData[item.prop2] +
+                  '-' +
+                  goodsData[item.prop3]
+                "
+              ></el-input>
+              <el-input
+                :size="size"
+                :disabled="item.disabled ? false : true"
+                v-else
+                v-model="goodsData[item.prop]"
+              ></el-input>
+            </template>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <div class="fgx"></div>
+      <el-row>
+        <el-col
+          v-for="(item, index) in lists2"
+          :key="index"
+          :span="item.col ? item.col : 12"
+          :offset="item.offset ? item.offset : 0"
+        >
+          <el-form-item :label="item.label" :prop="item.prop">
+            <el-select
+              :size="size"
+              v-if="item.scope === 'select1'"
+              v-model="listData[item.prop]"
+              :placeholder="item.placeholder"
+            >
+              <el-option
+                v-for="(item, index) in paysource"
+                :key="index"
+                :label="item.sourceName"
+                :value="item.sourceName"
+              >
+              </el-option>
+            </el-select>
+            <el-select
+              :size="size"
+              v-else-if="item.scope === 'select2'"
+              v-model="listData[item.prop]"
+              :placeholder="item.placeholder"
+            >
+              <el-option
+                v-for="(item, index) in payvisit"
+                :key="index"
+                :label="item.visitName"
+                :value="item.visitName"
+              >
+              </el-option>
+            </el-select>
+            <el-input
+              :size="size"
+              :disabled="item.noDisabled ? false : true"
+              v-else
+              v-model="listData[item.prop]"
+            ></el-input>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <div class="fgx"></div>
+      <el-form-item label="订单备注" prop="remark">
+        <el-input
+          type="textarea"
+          v-model="listData.remark"
+          :rows="4"
+        ></el-input>
+      </el-form-item>
+      <div style="text-align: center; padding-bottom: 10px">
+        <el-button size="mini" type="primary" @click="submit">保存</el-button>
+      </div>
+    </el-form>
+  </div>
+</template>
+
+
+<script>
+import { mapGetters } from "vuex";
+export default {
+  props: ["goodsId", "orderSn"],
+  data() {
+    return {
+      size: "",
+      tableSet: [
+        {
+          label: "费用类型",
+          prop: "priceTypeName",
+        },
+        {
+          label: "费用金额(元)",
+          prop: "price",
+        },
+      ],
+      goodsData: {}, //商品信息---部分
+      listData: {},
+      options: [],
+      optionsType: [
+        {
+          label: "视频",
+          value: 1,
+        },
+        {
+          label: "题库",
+          value: 2,
+        },
+        {
+          label: "补考",
+          value: 3,
+        },
+        {
+          label: "前培",
+          value: 4,
+        },
+        {
+          label: "组合",
+          value: 5,
+        },
+      ],
+      payType: [
+        {
+          label: "未收费",
+          value: 1,
+        },
+        {
+          label: "部分收费",
+          value: 2,
+        },
+        {
+          label: "完全收费",
+          value: 3,
+        },
+        {
+          label: "免费",
+          value: 4,
+        },
+      ],
+      lists: [
+        {
+          label: "商品标准价格",
+          prop: "standPrice",
+        },
+        {
+          label: "商品年份",
+          prop: "year",
+        },
+        {
+          label: "商品最低价格",
+          prop: "lowestPrice",
+        },
+        {
+          label: "供应方(服务)",
+          prop: "supplyName",
+        },
+        {
+          label: "支付金额",
+          prop: "goodsReceived",
+          dataType: "listData",
+        },
+        {
+          label: "商品类型",
+          prop: "goodsType",
+          scope: "select",
+        },
+        {
+          label: "商品编码",
+          prop: "code",
+        },
+        {
+          label: "支付状态",
+          prop: "payStatus",
+          dataType: "listData",
+          scope: "payType",
+        },
+        {
+          label: "商品名称",
+          prop: "goodsName",
+        },
+        {
+          label: "业务层级",
+          prop1: "educationName",
+          prop2: "projectName",
+          prop3: "businessName",
+          scope: "yecj",
+        },
+        {
+          label: "学时",
+          prop: "classHours",
+        },
+        {
+          label: "商品有效期",
+          prop: "validity",
+          scope: "startEndTime",
+        },
+        {
+          label: "商品标准价格明细",
+          prop: "payer",
+          scope: "table",
+        },
+        {
+          label: "学习服务期",
+          prop: "studentTime",
+          scope: "startEndTime",
+        },
+      ],
+      lists2: [
+        {
+          label: "业务归属人",
+          prop: "businessOwner",
+          noDisabled: true,
+        },
+        {
+          label: "归属部门",
+          prop: "dept",
+          noDisabled: true,
+        },
+        {
+          label: "渠道来源",
+          prop: "source",
+          scope: "select1",
+          noDisabled: true,
+        },
+        {
+          label: "到访校区",
+          prop: "school",
+          scope: "select2",
+          noDisabled: true,
+        },
+        {
+          label: "录单人",
+          prop: "createBy",
+        },
+      ],
+    };
+  },
+  computed: { ...mapGetters(["paysource", "payvisit"]) },
+  watch: {
+    orderSn() {
+      this.search();
+    },
+  },
+  mounted() {
+    this.search();
+  },
+  methods: {
+    submit() {
+      var data = JSON.parse(JSON.stringify(this.listData));
+      data.goodsInputData = JSON.parse(data.goodsInputData);
+      this.$api.editordergoods(data).then((res) => {
+        this.$message.success("保存成功");
+      });
+    },
+    backPage() {
+      this.$store.dispatch("tagsView/delView", this.$route).then((res) => {
+        this.$router.push({
+          path: "orderList",
+        });
+      });
+    },
+    search() {
+      this.$api.obtainGoods(this.goodsId).then((res) => {
+        res.data.validity = [
+          this.$methodsTools.time10to13(res.data.validityStartTime, 2),
+          this.$methodsTools.time10to13(res.data.validityEndTime, 2),
+        ];
+        res.data.studentTime = [
+          this.$methodsTools.time10to13(res.data.validityStartTime, 2),
+          this.$methodsTools.time10to13(res.data.validityEndTime, 2),
+        ];
+        res.data.standPriceJson = JSON.parse(res.data.standPriceJson);
+        this.goodsData = res.data;
+      });
+      this.$api
+        .inquireOrderinfoList({
+          orderSn: this.orderSn,
+          goodsId: this.goodsId,
+        })
+        .then((res) => {
+          this.listData = res.data;
+          this.$refs["listData"].resetFields();
+        });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.fgx {
+  border-bottom: 1px dotted #9a9a9a;
+  margin-bottom: 12px;
+}
+/deep/ .el-input__inner{
+  width: 350px;
+}
+</style>

+ 171 - 0
src/views/Marketing/order/offlineOrder/orderChargeInfo/goodsDocument/refundInfos.vue

@@ -0,0 +1,171 @@
+<template>
+  <div id="refundInfos">
+    <div v-if="!listData.length">暂无退费记录</div>
+    <el-tabs v-else type="border-card">
+      <el-tab-pane
+        v-for="(item, index) in listData"
+        :label="`第${index + 1}次退款记录`"
+        :key="index"
+      >
+        <div>
+          <div v-if="item.periodStatus === 0" style="color: red">待审核</div>
+          <div v-else>
+            <div v-if="item.periodStatus === -1 || item.periodStatus === 1">
+              <p>{{ $methodsTools.onlyForma(item.periodTime) }}</p>
+              <p>
+                <strong>初审审核人:</strong
+                ><span style="color: red">{{ item.periodUsername }}</span>
+              </p>
+              <p>
+                <strong>审核结果:</strong
+                ><span style="color: red">{{
+                  item.periodStatus === 1 ? "同意" : "拒绝"
+                }}</span>
+              </p>
+              <p>
+                <strong>审核意见:</strong
+                ><span style="color: red">{{ item.periodReason }}</span>
+              </p>
+            </div>
+            <div v-if="item.periodStatus === -2 || item.periodStatus === 2 || item.periodStatus === 3">
+              <div v-if="item.periodStatus === 3">
+                <p>{{ $methodsTools.onlyForma(item.refundTime) }}</p>
+                <p style="color: red">
+                  已退款,交易金额:¥{{ item.refundFee }}
+                </p>
+              </div>
+              <div v-if="item.periodStatus === 2">
+                <p style="color: red">
+                  审核已通过,待退款
+                </p>
+              </div>
+              <p>{{ $methodsTools.onlyForma(item.periodReviewTime) }}</p>
+              <p>
+                <strong>复审审核人:</strong
+                ><span style="color: red">{{ item.periodReviewUsername }}</span>
+              </p>
+              <p>
+                <strong>审核结果:</strong
+                ><span style="color: red">{{
+                  item.periodStatus === 2 || item.periodStatus === 3 ? "同意" : "拒绝"
+                }}</span>
+              </p>
+              <p>
+                <strong>审核意见:</strong
+                ><span style="color: red">{{ item.periodReviewReason }}</span>
+              </p>
+              <p>{{ $methodsTools.onlyForma(item.periodTime) }}</p>
+              <p>
+                <strong>初审审核人:</strong
+                ><span style="color: red">{{ item.periodUsername }}</span>
+              </p>
+              <p>
+                <strong>审核结果:</strong><span style="color: red">同意</span>
+              </p>
+              <p>
+                <strong>审核意见:</strong
+                ><span style="color: red">{{ item.periodReason }}</span>
+              </p>
+            </div>
+          </div>
+          <el-divider></el-divider>
+          <p>{{ $methodsTools.onlyForma(item.createTime) }}</p>
+          <p>
+            <strong style="color: red">{{ item.realname }}</strong
+            >,发起退款申请
+          </p>
+          <ul class="ul_sty">
+            <li>
+              <strong>本次退费金额:</strong><span>¥{{ item.refundFee }}</span>
+            </li>
+            <li>
+              <strong>退款理由:</strong><span>{{ item.applyReason }}</span>
+            </li>
+            <li>
+              <strong>证明:</strong>
+              <ul style="margin-top: 10px">
+                <li
+                  class="float_li"
+                  v-for="(items, indexs) in item.applyImgs"
+                  :key="indexs"
+                >
+                  <el-image
+                    style="width: 100%; height: 100%"
+                    :src="$methodsTools.splitImgHost(items)"
+                    :preview-src-list="[$methodsTools.splitImgHost(items)]"
+                  >
+                  </el-image>
+                </li>
+                <div style="clear: both"></div>
+              </ul>
+            </li>
+          </ul>
+        </div>
+      </el-tab-pane>
+    </el-tabs>
+  </div>
+</template>
+
+<script>
+export default {
+  props: ["orderGoodsId", "userId"],
+  data() {
+    return {
+      active: "",
+      listData: [],
+    };
+  },
+  mounted() {
+    this.$api
+      .inquireorderrefundlist({
+        orderGoodsId: this.orderGoodsId,
+        userId: this.userId,
+      })
+      .then((res) => {
+        res.rows.forEach((item) => {
+          if (item.applyImgs) {
+            item.applyImgs = item.applyImgs.split(",");
+          } else {
+            item.applyImgs = [];
+          }
+        });
+        this.listData = res.rows;
+      });
+  },
+  methods: {},
+};
+</script>
+
+<style lang="less" scoped>
+#refundInfos {
+  padding-right: 10px;
+  font-size: 14px;
+  height: 100%;
+}
+.ul_sty {
+  padding: 10px;
+  background-color: rgb(252, 234, 236);
+  li {
+    margin-bottom: 10px;
+  }
+}
+.float_li {
+  width: 110px;
+  height: 110px;
+  float: left;
+  border: 1px solid #696969;
+  margin-right: 10px;
+}
+/deep/.el-tabs--border-card {
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+}
+/deep/.el-tabs--border-card > .el-tabs__content {
+  flex: 1;
+  overflow: auto;
+}
+p{
+  margin: 7px 0px;
+}
+</style>

+ 294 - 0
src/views/Marketing/order/offlineOrder/orderChargeInfo/goodsDocument/studentOrder.vue

@@ -0,0 +1,294 @@
+<template>
+  <div id="studentOrder">
+    <el-form
+      label-position="right"
+      label-width="120px"
+      :model="listDataSubmitForm"
+      ref="listDataSubmitForm"
+      :rules="rules"
+    >
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="手机号码" prop="telphone">
+            <el-input disabled v-model="listData.telphone"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="选择班级" prop="gradeId">
+            <!-- <el-select
+                v-model="listDataSubmitForm.gradeId"
+                placeholder="请选择班级"
+                :disabled="true"
+              >
+                <el-option
+                  v-for="(item, index) in classList"
+                  :key="index"
+                  :disabled="item.studentNum >= item.studentUpper"
+                  :label="item.className"
+                  :value="item.gradeId"
+                >
+                </el-option>
+              </el-select> -->
+            <el-input :value="listDataSubmitForm.gradeName" disabled></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="姓名" prop="realname">
+            <el-input disabled v-model="listData.realname"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="选择考期" prop="examDateJson">
+            <el-select
+              v-model="listDataSubmitForm.goodsInputData.examDateJsonName"
+              placeholder="请选择考期"
+            >
+              <el-option
+                v-for="(item, index) in courseExamine"
+                :key="index"
+                :label="item.examineName"
+                :value="item.examineName"
+              >
+              </el-option>
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="身份证号码" prop="idCard">
+            <el-input disabled v-model="listData.idCard"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item
+            label="选择报考地区"
+            :prop="listDataSubmitForm.areaId ? 'cityId' : ''"
+          >
+            <el-col :span="12"
+              ><el-select
+                v-model="listDataSubmitForm.areaId"
+                placeholder="选择省"
+                @change="changeArea"
+              >
+                <el-option
+                  v-for="(item, index) in areas"
+                  :key="index"
+                  :label="item.areaName"
+                  :value="item.areaId"
+                >
+                </el-option> </el-select
+            ></el-col>
+            <el-col :span="12"
+              ><el-select
+                v-model="listDataSubmitForm.cityId"
+                placeholder="选择地市"
+              >
+                <el-option
+                  v-for="(item, index) in newCityList"
+                  :key="index"
+                  :label="item.areaName"
+                  :value="item.areaId"
+                >
+                </el-option> </el-select
+            ></el-col>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="微信绑定">
+            <el-input disabled v-model="listData.wechatCode"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="所在公司" prop="company">
+            <el-input v-model="listDataSubmitForm.company"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12" :offset="12">
+          <el-form-item label="收件地址" prop="address">
+            <el-input
+              type="textarea"
+              :rows="4"
+              v-model="listDataSubmitForm.address"
+              placeholder="请输入收件地址"
+            ></el-input>
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+    <div style="text-align: center">
+      <el-button
+        size="mini"
+        type="primary"
+        @click="submit('listDataSubmitForm')"
+        >保存</el-button
+      >
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from "vuex";
+export default {
+  props: ["goodsId", "orderSn", "userId"],
+  data() {
+    return {
+      listData: {},
+      listDataSubmitForm: {
+        cityId: "",
+        className: "",
+        goodsInputData: {
+          applyAreasJson: {},
+        },
+      },
+      options: [],
+      cityList: [],
+      newCityList: [],
+      classList: [],
+      rules: {
+        cityId: [
+          {
+            required: true,
+            message: "请选择城市",
+            trigger: ["blur", "changes"],
+          },
+        ],
+      },
+    };
+  },
+  computed: { ...mapGetters(["courseExamine", "areas"]) },
+  mounted() {
+    this.getClassInfos();
+    this.getInfoCity();
+    this.search();
+  },
+  methods: {
+    getClassInfos() {
+      this.$api.inquireGradegradeList({ goodsId: this.goodsId }).then((res) => {
+        if (res.rows.length) {
+          this.classList = res.rows;
+        }
+      });
+    },
+    getInfoCity() {
+      this.$api.inquireapplyCityList({ status: 1, areaType: 2 }).then((res) => {
+        this.cityList = res.rows;
+      });
+    },
+    //选择省改变市
+    changeArea() {
+      this.newCityList = this.cityList.filter((item) => {
+        return item.parentId == this.listDataSubmitForm.areaId;
+      });
+      this.listDataSubmitForm.cityId = "";
+    },
+    search() {
+      this.$api.obtainappuser(this.userId).then((res) => {
+        this.listData = res.data;
+      });
+      this.$api
+        .inquireOrderinfoList({
+          orderSn: this.orderSn,
+          goodsId: this.goodsId,
+        })
+        .then((res) => {
+          res.data.goodsInputData = JSON.parse(res.data.goodsInputData);
+          if (res.data.goodsInputData) {
+            if (res.data.goodsInputData.applyAreasJson) {
+              res.data.goodsInputData.applyAreasJson = JSON.parse(
+                res.data.goodsInputData.applyAreasJson
+              );
+              res.data.areaId = res.data.goodsInputData.applyAreasJson.areaId;
+              res.data.cityId = res.data.goodsInputData.applyAreasJson.cityId;
+              this.newCityList = this.cityList.filter((item) => {
+                return item.parentId == res.data.areaId;
+              });
+            } else {
+              res.data.cityId = "";
+            }
+            if (res.data.goodsInputData.examDateJson) {
+              res.data.goodsInputData.examDateJson = JSON.parse(
+                res.data.goodsInputData.examDateJson
+              );
+              res.data.goodsInputData.examDateJsonName =
+                res.data.goodsInputData.examDateJson.examineName;
+            }
+            if (res.data.goodsInputData.gradeJson) {
+              res.data.goodsInputData.gradeJson = JSON.parse(
+                res.data.goodsInputData.gradeJson
+              );
+              res.data.goodsInputData.gradeId =
+                res.data.goodsInputData.gradeJson.gradeId;
+            }
+          } else {
+            res.data.goodsInputData = {};
+          }
+
+          this.listDataSubmitForm = res.data;
+          this.$refs["listDataSubmitForm"].resetFields();
+        });
+    },
+    backPage() {
+      this.$store.dispatch("tagsView/delView", this.$route).then((res) => {
+        this.$router.push({
+          path: "orderList",
+        });
+      });
+    },
+    submit(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          this.submitForm();
+        } else {
+          console.log("error submit!!");
+          return false;
+        }
+      });
+    },
+    submitForm() {
+      if (this.listDataSubmitForm.areaId && !this.listDataSubmitForm.cityId) {
+        this.$message.error("请选择报考地市");
+        return;
+      }
+      let data = JSON.parse(JSON.stringify(this.listDataSubmitForm));
+      for (let i = 0; i < this.cityList.length; i++) {
+        if (this.cityList[i].areaId == data.cityId) {
+          data.goodsInputData.applyAreasJson = {
+            areaId: this.cityList[i].parentId,
+            areaName: this.cityList[i].parentName,
+            cityId: this.cityList[i].areaId,
+            cityName: this.cityList[i].areaName,
+          };
+        }
+      }
+      data.goodsInputData.examDateJson = "";
+      this.courseExamine.forEach((item) => {
+        if (item.examineName == data.goodsInputData.examDateJsonName) {
+          data.goodsInputData.examDateJson = JSON.stringify(item);
+        }
+      });
+      data.goodsInputData.gradeJson = "";
+      this.classList.forEach((item) => {
+        if (item.gradeId == data.gradeId) {
+          data.goodsInputData.gradeJson = JSON.stringify(item);
+          data.goodsInputData.gradeId = item.gradeId;
+        }
+      });
+      data.orderSn = this.orderSn;
+      data.goodsId = this.goodsId;
+      data.goodsInputData.applyAreasJson = JSON.stringify(
+        data.goodsInputData.applyAreasJson
+      );
+      data.gradeId = this.listDataSubmitForm.gradeId;
+      this.$api.editordergoods(data).then((res) => {
+        this.$message.success("保存成功");
+      });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.fgx {
+  border-bottom: 1px dotted #9a9a9a;
+  margin-bottom: 12px;
+}
+</style>

+ 27 - 0
src/views/Marketing/order/offlineOrder/orderChargeInfo/index.vue

@@ -0,0 +1,27 @@
+<template>
+  <div id="orderChargeInfo">
+    <top-box ref="topBox" />
+    <body-box ref="bodyBox" />
+  </div>
+</template>
+
+<script>
+import topBox from "./topBox.vue";
+import bodyBox from "./bodyBox.vue";
+export default {
+  name: "OrderChargeInfo",
+  components: { topBox, bodyBox },
+  data() {
+    return {};
+  },
+  methods: {},
+};
+</script>
+
+<style lang="less" scoped>
+#orderChargeInfo {
+  display: flex;
+  flex-direction: column;
+  height: calc(100vh - 130px);
+}
+</style>

+ 150 - 0
src/views/Marketing/order/offlineOrder/orderChargeInfo/topBox.vue

@@ -0,0 +1,150 @@
+<template>
+  <div id="topBox">
+    <el-form label-position="right" label-width="180px" :model="formData">
+      <el-row :gutter="10">
+        <el-col :span="8" v-for="(item, index) in formSet" :key="index">
+          <el-form-item
+            v-if="item.scope === 'comput'"
+            :label="item.label"
+            size="mini"
+          >
+            <el-input
+              readonly
+              :value="formData[item.prop1] - formData[item.prop2]"
+            ></el-input>
+          </el-form-item>
+          <el-form-item
+            v-else-if="item.scope === 'busin'"
+            :label="item.label"
+            size="mini"
+          >
+            <el-input
+              readonly
+              :value="
+                formData[item.prop1] +
+                '-' +
+                formData[item.prop2] +
+                '-' +
+                formData[item.prop3]
+              "
+            ></el-input>
+          </el-form-item>
+          <el-form-item
+            v-else-if="item.scope === 'time'"
+            :label="item.label"
+            size="mini"
+          >
+            <el-input
+              readonly
+              :value="$methodsTools.onlyForma(formData[item.prop])"
+            ></el-input>
+          </el-form-item>
+          <el-form-item
+            v-else-if="item.scope === 'zdy'"
+            :label="item.label"
+            size="mini"
+          >
+            <el-input
+              readonly
+              :value="formData[item.prop1]"
+              style="width: 50px"
+            ></el-input
+            ><span style="margin: 0px 6px">人</span>
+            <el-input
+              readonly
+              :value="formData[item.prop2]"
+              style="width: 50px"
+            ></el-input
+            ><span style="margin: 0px 6px">商品</span>
+          </el-form-item>
+          <el-form-item v-else :label="item.label" size="mini">
+            <el-input readonly :value="formData[item.prop]"></el-input>
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      formSet: [
+        {
+          label: "订单编码:",
+          prop: "inputOrderSn",
+        },
+        {
+          label: "商品业务层级:",
+          prop1: "businessName",
+          prop2: "businessName",
+          prop3: "businessName",
+          scope: "busin",
+        },
+        {
+          label: "已收金额:",
+          prop: "goodsReceived",
+        },
+        {
+          label: "订单时间:",
+          prop: "createTime",
+          socpe: "time",
+        },
+        {
+          label: "商品标准价格总金额:",
+          prop: "orderPrice",
+        },
+        {
+          label: "已退金额:",
+          prop: "aaa",
+        },
+        {
+          label: "录单人:",
+          prop: "createUsername",
+        },
+        {
+          label: "商品成交价格总金额:",
+          prop: "payPrice",
+        },
+        {
+          label: "未收金额:",
+          prop1: "payPrice",
+          prop2: "goodsReceived",
+          scope: "comput",
+        },
+        {
+          label: "下单结果:",
+          prop1: "userNum",
+          prop2: "goodsNum",
+          scope: "zdy",
+        },
+      ],
+      formData: {},
+    };
+  },
+  created() {
+    this.getInfo();
+  },
+  methods: {
+    /**
+     * 获取该订单数据
+     */
+    getInfo() {
+      this.$api
+        .inquireorderinputdetail({
+          inputOrderSn: this.$route.query.inputOrderSn,
+        })
+        .then((res) => {
+          this.formData = res.data;
+        });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+#topBox {
+  flex-shrink: 0;
+}
+</style>

+ 638 - 0
src/views/Marketing/order/offlineOrder/orderDetailsT/index.vue

@@ -0,0 +1,638 @@
+<template>
+  <div id="orderDetailsT">
+    <search-box-new
+      ref="searchBox"
+      :formData="formData"
+      :formList="formList"
+      @search="search"
+      @init="init"
+      :topType="topType"
+    />
+    <table-list
+      rowKey="orderGoodsId"
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      :loading="loading"
+      ref="tableList"
+    >
+      <template slot="customize">
+        <el-button size="medium" type="warning" @click="setGoodsOptions(1)"
+          >计费单收费</el-button
+        ><el-button size="medium" type="success" @click="setGoodsOptions(2)"
+          >退款申请</el-button
+        ><el-button size="medium" @click="setGoodsOptions(3)"
+          >补录订单</el-button
+        >
+      </template>
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="adds(props.scope.row)"
+          >订单收费信息</el-button
+        >
+        <el-button type="text" @click="del(props.scope.row)"
+          >删除订单</el-button
+        >
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="formData.pageSize"
+      :currentPage="formData.pageNum"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+  </div>
+</template>
+
+<script>
+import searchBoxNew from "@/components/searchBoxNew";
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+export default {
+  name: "OrderDetailsT",
+  components: { searchBoxNew, tableList, pagination },
+  data() {
+    return {
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "订单详情",
+        index: 0,
+        ch: "条",
+        num: false,
+        border: true,
+        choice: true,
+        openCheckMore: true,
+        addHide: true,
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      topType: true,
+
+      //搜索
+      formList: [
+        {
+          prop: "educationTypeId",
+          placeholder: "教育类型",
+          scope: "educationType",
+        },
+        {
+          prop: "businessId",
+          placeholder: "业务层次",
+          scope: "businessLevel",
+          edu: "educationTypeId",
+        },
+        {
+          prop1: "startTime",
+          prop2: "endTime",
+          placeholder1: "订单开始时间",
+          placeholder2: "订单结束时间",
+          scope: "moreDataPicker",
+          Diszing: true,
+        },
+        {
+          prop: "goodsPayStatus",
+          placeholder: "支付状态",
+          scope: "select",
+          options: [
+            {
+              label: "未收费",
+              value: 1,
+            },
+            {
+              label: "部分收费",
+              value: 2,
+            },
+            {
+              label: "完全收费",
+              value: 3,
+            },
+            {
+              label: "免费",
+              value: 4,
+            },
+          ],
+        },
+        {
+          prop: "status",
+          placeholder: "订单状态",
+          scope: "select",
+          options: [
+            {
+              label: "有效",
+              value: 1,
+            },
+            {
+              label: "无效",
+              value: 0,
+            },
+          ],
+        },
+        {
+          prop: "refundStatus",
+          placeholder: "退款状态",
+          scope: "select",
+          options: [
+            {
+              label: "退款中",
+              value: 1,
+            },
+            {
+              label: "已退款",
+              value: 2,
+            },
+            {
+              label: "拒绝退款",
+              value: 3,
+            },
+          ],
+        },
+        {
+          prop: "searchKey",
+          placeholder: "订单编码/商品名/姓名/身份证",
+        },
+      ],
+      formData: {
+        goodsType: "",
+        pageSize: 10,
+        pageNum: 1,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "订单时间",
+          prop: "createTime",
+          hidden: true,
+          scope: "aTimeList",
+          width: "180px",
+        },
+        {
+          label: "订单编码",
+          prop: "orderSn",
+          hidden: true,
+          width: "210px",
+        },
+        {
+          label: "手机号码",
+          prop: "telphone",
+          hidden: true,
+          width: "120px",
+        },
+        {
+          label: "学员姓名",
+          prop: "realname",
+          hidden: true,
+        },
+        {
+          label: "学员身份证",
+          prop: "idCard",
+          hidden: true,
+          width: "190px",
+        },
+        {
+          label: "商品名称",
+          prop: "goodsName",
+          hidden: true,
+          width: "280px",
+        },
+        {
+          label: "商品业务层级",
+          prop1: "educationName",
+          prop2: "projectName",
+          prop3: "businessName",
+          hidden: true,
+          scope: "eduTypes",
+          width: "380px",
+        },
+        {
+          label: "商品年份",
+          prop: "year",
+          hidden: true,
+          ch: "年",
+        },
+        {
+          label: "商品标准价格",
+          prop: "orderPrice",
+          hidden: true,
+          scope: "leftCh",
+          ch: "¥",
+        },
+        {
+          label: "商品成交价格",
+          prop: "payPrice",
+          hidden: true,
+          scope: "leftCh",
+          ch: "¥",
+        },
+        {
+          label: "支付状态",
+          prop: "goodsPayStatus",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "未收费",
+              value: 1,
+            },
+            {
+              label: "部分收费",
+              value: 2,
+            },
+            {
+              label: "完全收费",
+              value: 3,
+            },
+            {
+              label: "免费",
+              value: 4,
+            },
+          ],
+        },
+        {
+          label: "已收金额",
+          prop: "goodsReceived",
+          hidden: true,
+          scope: "leftCh",
+          ch: "¥",
+        },
+        {
+          label: "未收金额",
+          prop1: "payPrice",
+          prop2: "goodsReceived",
+          hidden: true,
+          scope: "outStandingAmount",
+        },
+        {
+          label: "订单状态",
+          prop: "status",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "无效",
+              value: 0,
+            },
+            {
+              label: "有效",
+              value: 1,
+            },
+          ],
+        },
+        {
+          label: "退款状态",
+          prop: "refundStatus",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "无",
+              value: 0,
+            },
+            {
+              label: "退款中",
+              value: 1,
+            },
+            {
+              label: "已退款",
+              value: 2,
+            },
+            {
+              label: "拒绝退款",
+              value: 3,
+            },
+          ],
+        },
+        {
+          label: "复购-学时冲突",
+          width: "120px",
+          prop: "rebuy",
+          hidden: true,
+          scope: "rebuy",
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+    };
+  },
+  mounted() {
+    this.search();
+  },
+  activated() {
+    this.search();
+  },
+  methods: {
+    /**
+     * 1计费单收费2退费申请3补录
+     */
+    setGoodsOptions(int) {
+      if (int === 1) {
+        if (!this.$refs.tableList.allCheckData.length) {
+          this.$message.warning("请选择订单");
+          return;
+        }
+        const status = this.$refs.tableList.allCheckData.every((item) => {
+          return (
+            item.refundStatus !== 1 &&
+            item.refundStatus !== 2 &&
+            item.goodsPayStatus !== 3 &&
+            item.goodsPayStatus !== 4
+          );
+        });
+        if (!status) {
+          this.$message.error(
+            "请勿选择(完全收费、免费)或退款状态为(退款中、已退款)的订单"
+          );
+          return;
+        }
+        const data = this.$refs.tableList.allCheckData.map((item) => {
+          return item.orderGoodsId;
+        });
+        const jump = () => {
+          this.$router.push({
+            path: "billingBillCharges",
+            query: {
+              inputOrderSn: this.$route.query.inputOrderSn,
+              orderGoodsIds: data,
+              toStatus: 2,
+            },
+          });
+        };
+        const statusPage = this.$store.state.tagsView.visitedViews.some(
+          (item) => {
+            return item.name == "BillingBillCharges";
+          }
+        );
+        if (statusPage) {
+          this.$store
+            .dispatch("tagsView/delCachedView", {
+              name: "BillingBillCharges",
+            })
+            .then((res) => {
+              jump();
+            });
+        } else {
+          jump();
+        }
+      }
+      if (int === 2) {
+        console.log(this.$refs.tableList.allCheckData);
+        if (!this.$refs.tableList.allCheckData.length) {
+          this.$message.warning("请选择订单");
+          return;
+        }
+        const status = this.$refs.tableList.allCheckData.some((item) => {
+          return (
+            item.refundStatus == 1 ||
+            item.refundStatus == 2 ||
+            item.goodsPayStatus == 1 ||
+            item.goodsPayStatus == 4
+          );
+        });
+        if (status) {
+          this.$message.error(
+            "请勿选择(未收费、免费)或退款状态为(退款中、已退款)的订单"
+          );
+          return;
+        }
+        const data = this.$refs.tableList.allCheckData.map((item) => {
+          return item.orderGoodsId;
+        });
+        const jump = () => {
+          this.$router.push({
+            path: "refundDocument",
+            query: {
+              orderGoodsIds: data,
+              inputOrderSn: this.$route.query.inputOrderSn,
+            },
+          });
+        };
+        const statusPage = this.$store.state.tagsView.visitedViews.some(
+          (item) => {
+            return item.name == "RefundDocument";
+          }
+        );
+        if (statusPage) {
+          this.$store
+            .dispatch("tagsView/delCachedView", {
+              name: "RefundDocument",
+            })
+            .then((res) => {
+              jump();
+            });
+        } else {
+          jump();
+        }
+      }
+      if (int === 3) {
+        const jump = () => {
+          this.$router.push({
+            path: "batchRecord",
+            query: {
+              inputOrderSn: this.$route.query.inputOrderSn,
+              suppleRecord: 1,
+            },
+          });
+        };
+        const statusPage = this.$store.state.tagsView.visitedViews.some(
+          (item) => {
+            return item.name == "BatchRecord";
+          }
+        );
+        if (statusPage) {
+          this.$store
+            .dispatch("tagsView/delCachedView", {
+              name: "BatchRecord",
+            })
+            .then((res) => {
+              jump();
+            });
+        } else {
+          jump();
+        }
+      }
+    },
+    adds(row) {
+      const jump = () => {
+        this.$router.push({
+          path: "orderChargeInfo",
+          query: {
+            inputOrderSn: this.$route.query.inputOrderSn,
+            status: 2,
+            orderGoodsId: row.orderGoodsId,
+            userId: row.userId,
+          },
+        });
+      };
+      const statusPage = this.$store.state.tagsView.visitedViews.some(
+        (item) => {
+          return item.name == "OrderChargeInfo";
+        }
+      );
+      if (statusPage) {
+        this.$store
+          .dispatch("tagsView/delCachedView", {
+            name: "OrderChargeInfo",
+          })
+          .then((res) => {
+            jump();
+          });
+      } else {
+        jump();
+      }
+    },
+    search(int) {
+      this.loading = true;
+      if (int === 1) {
+        this.formData.pageNum = 1;
+      }
+      if (int === 2) {
+        this.formData = {
+          goodsType: "",
+          pageSize: 10,
+          pageNum: 1,
+        };
+      }
+      if (int === 3) {
+        this.formData.pageNum = 1;
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      data.inputOrderSn = this.$route.query.inputOrderSn;
+      if (this.formData.startTime) {
+        data.startTime = data.startTime / 1000;
+      }
+      if (this.formData.endTime) {
+        data.endTime = data.endTime / 1000;
+      }
+      this.$api
+        .inquireOrderList(data)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+          this.navText.index = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    init() {
+      this.search(2);
+    },
+    del(v) {},
+    handleSizeChange(v) {
+      this.formData.pageSize = v;
+      this.formData.pageNum = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.formData.pageNum = v;
+      this.search();
+    },
+    changeStatus(item) {
+      var items = JSON.parse(JSON.stringify(item));
+      items.goodsStatus = items.goodsStatus === 1 ? 0 : 1;
+      this.$api.editGoods(items).then((res) => {
+        if (item.goodsStatus === 1) {
+          this.$message.success("下架成功");
+        } else {
+          this.$message.success("上架成功");
+        }
+        this.search();
+      });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+</style>
+

+ 435 - 0
src/views/Marketing/order/offlineOrder/orderDetailsT/refundDocument/index.vue

@@ -0,0 +1,435 @@
+<template>
+  <div id="refundDocument">
+    <h5 style="margin: 6px 0px">退费内容</h5>
+    <div class="refundBox">
+      <p>
+        您当前共选择了<span style="color: red">{{ listData.length }}</span
+        >个商品:<span style="color: red">{{ computedGoods(1) }}</span
+        >视频商品、<span style="color: red">{{ computedGoods(2) }}</span
+        >题库商品、<span style="color: red">{{ computedGoods(3) }}</span
+        >补考商品、<span style="color: red">{{ computedGoods(4) }}</span
+        >前培商品
+      </p>
+      <div
+        v-for="(item, index) in listData"
+        :key="index"
+        style="margin-bottom: 20px"
+      >
+        <table border class="tableSty">
+          <tr style="background: #eee">
+            <th v-for="(items, indexs) in tableSet" :key="indexs">
+              {{ items.label }}
+            </th>
+          </tr>
+          <tr>
+            <td v-for="(items, indexs) in tableSet" :key="indexs">
+              <span v-if="items.scope === 'isOptions'">
+                <span v-for="(its, ids) in items.options" :key="ids">
+                  <span v-if="its.value == item[items.prop]">{{
+                    its.label
+                  }}</span>
+                </span>
+              </span>
+              <span v-else-if="items.scope === 'set'">
+                <el-button type="text" @click="del(index)">删除</el-button>
+              </span>
+              <span v-else-if="items.scope === 'eduType'">
+                {{ item[items.prop1] }} - {{ item[items.prop2] }} -
+                {{ item[items.prop3] }}
+              </span>
+              <span v-else>
+                <span v-if="items.ch">{{ items.ch }}</span
+                >{{ item[items.prop] }}
+              </span>
+            </td>
+          </tr>
+        </table>
+        <div>
+          <p>
+            <span class="labelSty">本次退费金额:</span
+            ><el-input
+              readonly
+              :size="size"
+              style="width: 200px"
+              :value="'¥' + item.goodsReceived"
+            ></el-input>
+          </p>
+          <p>
+            <span class="labelSty">退费原因:</span
+            ><el-input
+              :size="size"
+              style="width: 500px"
+              type="textarea"
+              v-model="item.applyReason"
+            ></el-input>
+          </p>
+          <div class="Foot">
+            <span class="labelSty">证明:</span>
+            <div class="imgBox">
+              <div
+                v-if="listData[index].applyImgs.length <= 5"
+                style="margin-bottom: 10px"
+              >
+                <label :for="`uplose${index}`">
+                  <i
+                    class="el-button el-button--default el-button--mini"
+                    style="font-style: normal"
+                    >上传图片</i
+                  >
+                </label>
+                <input
+                  ref="file"
+                  type="file"
+                  style="display: none"
+                  :id="`uplose${index}`"
+                  @change="getImgFile(index, $event)"
+                />
+              </div>
+              <ul style="margin: 0px">
+                <li
+                  class="liFloat"
+                  v-for="(items, indexs) in listData[index].applyImgs"
+                  :key="indexs"
+                >
+                  <el-image
+                    style="width: 100%; height: 100%"
+                    :src="$methodsTools.splitImgHost(items)"
+                    :preview-src-list="[$methodsTools.splitImgHost(items)]"
+                  >
+                  </el-image>
+                  <el-button
+                    class="delete_sty"
+                    type="danger"
+                    icon="el-icon-delete"
+                    size="mini"
+                    circle
+                    @click="deleteImg(index, indexs)"
+                  ></el-button>
+                </li>
+                <div style="clear: both"></div>
+              </ul>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="footerSty">
+      <p style="text-align: center">
+        您申请的退款总金额:<span style="color: red; font-weight: bold"
+          >¥{{ comPrice(listData) }}</span
+        >
+      </p>
+      <div style="text-align: center">
+        <el-button size="mini" @click="BACK">取消</el-button>
+        <el-button
+          size="mini"
+          @click="refundForm"
+          :loading="disabledBtn"
+          v-if="listData.length"
+          >提交退费申请</el-button
+        >
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      disabledBtn: false,
+      size: "small",
+      listData: [],
+      tableSet: [
+        {
+          label: "商品类型",
+          prop: "goodsType",
+          scope: "isOptions",
+          options: [
+            {
+              label: "视频",
+              value: 1,
+            },
+            {
+              label: "题库",
+              value: 2,
+            },
+            {
+              label: "补考",
+              value: 3,
+            },
+            {
+              label: "前培",
+              value: 4,
+            },
+          ],
+        },
+        {
+          label: "学员姓名",
+          prop: "realname",
+        },
+        {
+          label: "学员身份证号码",
+          prop: "idCard",
+        },
+        {
+          label: "订单编码",
+          prop: "orderSn",
+        },
+        {
+          label: "商品编码",
+          prop: "code",
+        },
+        {
+          label: "商品业务层级",
+          prop1: "educationName",
+          prop2: "projectName",
+          prop3: "businessName",
+          scope: "eduType",
+        },
+        {
+          label: "商品名称",
+          prop: "goodsName",
+        },
+        {
+          label: "商品标价",
+          prop: "orderPrice",
+          ch: "¥",
+        },
+        {
+          label: "商品成交价",
+          prop: "payPrice",
+          ch: "¥",
+        },
+        {
+          label: "已收金额",
+          prop: "goodsReceived",
+          ch: "¥",
+        },
+        {
+          label: "操作",
+          scope: "set",
+        },
+      ],
+    };
+  },
+  computed: {
+    computedGoods: function () {
+      return function (int) {
+        var num = 0;
+        this.listData.forEach((item) => {
+          if (item.goodsType == int) {
+            num++;
+          }
+        });
+        return num;
+      };
+    },
+    comPrice: function () {
+      return function (arr) {
+        var num = 0;
+        arr.forEach((item) => {
+          num += item.goodsReceived;
+        });
+        return num.toFixed(2);
+      };
+    },
+  },
+  created() {
+    this.init();
+  },
+  methods: {
+    deleteImg(index, indexs) {
+      this.listData[index].applyImgs.splice(indexs, 1);
+    },
+    refundForm() {
+      this.disabledBtn = true;
+      const dataList = this.listData.map((item) => {
+        var data = {
+          applyReason: item.applyReason,
+          goodsId: item.goodsId,
+          orderSn: item.orderSn,
+        };
+        if (item.applyImgs.length) {
+          data.applyImgs = item.applyImgs.toString();
+        } else {
+          data.applyImgs = "";
+        }
+        return data;
+      });
+      this.$api
+        .apporderinputOrderrefund(dataList)
+        .then((res) => {
+          this.$message.success("退费申请成功");
+          setTimeout(() => {
+            this.backSearch();
+          }, 300);
+        })
+        .catch(() => {
+          this.disabledBtn = false;
+        });
+    },
+    backSearch() {
+      this.$store.dispatch("tagsView/exitView", this.$route).then((res) => {
+        const jump = () => {
+          this.$router.push({
+            path: "orderDetailsT",
+            query: {
+              inputOrderSn: this.$route.query.inputOrderSn,
+            },
+          });
+        };
+        const statusPage = this.$store.state.tagsView.visitedViews.some(
+          (item) => {
+            return item.name == "OrderDetailsT";
+          }
+        );
+        if (statusPage) {
+          this.$store
+            .dispatch("tagsView/delCachedView", {
+              name: "OrderDetailsT",
+            })
+            .then((res) => {
+              jump();
+            });
+        } else {
+          jump();
+        }
+      });
+    },
+    del(index) {
+      this.$alert(
+        "确定删除此订单?<br />内容删除后将无法恢复,请慎重考虑",
+        "提示",
+        {
+          dangerouslyUseHTMLString: true,
+        }
+      )
+        .then(() => {
+          this.listData.splice(index, 1);
+          this.$message.success("删除成功");
+        })
+        .catch(() => {});
+    },
+    init() {
+      this.$api
+        .inquireOrderList({ orderGoodsIds: this.$route.query.orderGoodsIds })
+        .then((res) => {
+          console.log(res, "ggg");
+          res.rows.forEach((item) => {
+            item.applyImgs = [];
+          });
+          this.listData = res.rows;
+        });
+    },
+    /**
+     * 上传图片
+     */
+    getImgFile(index, e) {
+      var self = this;
+      var file = self.$refs.file[index].files[0];
+      if (file === undefined) {
+        return;
+      }
+      if (file.size > 0.3 * 1024 * 1024) {
+        self.$message.error("图片不得大于300kb");
+        return;
+      }
+      var type = self.$refs.file[index].value
+        .toLowerCase()
+        .split(".")
+        .splice(-1);
+      if (type[0] != "jpg" && type[0] != "png" && type[0] != "jpeg") {
+        self.$message.error("上传格式需为:.jpg/.png/.jpeg");
+        self.$refs.file[index].value = "";
+        return;
+      }
+      this.$upload
+        .upload(file, 5)
+        .then((res) => {
+          //   self.billSendData.invoiceImg = res;
+          self.listData[index].applyImgs.push(res);
+          console.log(res);
+        })
+        .finally(() => {
+          self.$refs.file[index].value = "";
+        });
+    },
+    /**
+     * 返回上一级
+     */
+    BACK() {
+      this.$store.dispatch("tagsView/delView", this.$route).then((res) => {
+        this.$router.push({
+          path: "orderDetailsT",
+          query: {
+            inputOrderSn: this.$route.query.inputOrderSn,
+          },
+        });
+      });
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+#refundDocument {
+  display: flex;
+  flex-direction: column;
+  height: calc(100vh - 130px);
+}
+.refundBox {
+  flex: 1;
+  overflow: auto;
+  border: 1px solid #eee;
+  border-top: 2px solid rgb(179, 204, 255);
+  padding: 10px;
+}
+.tableSty {
+  border-collapse: collapse;
+  width: 100%;
+  font-size: 13px;
+  text-align: center;
+  th,
+  td {
+    padding: 8px;
+    font-weight: 500;
+  }
+}
+.labelSty {
+  font-size: 14px;
+  display: inline-block;
+  width: 140px;
+  text-align: right;
+  vertical-align: top;
+}
+.Foot {
+  display: flex;
+  .labelSty {
+    flex-shrink: 0;
+  }
+  .imgBox {
+    flex: 1;
+  }
+}
+.liFloat {
+  width: 130px;
+  height: 130px;
+  float: left;
+  border: 1px solid #696969;
+  margin-right: 10px;
+  margin-bottom: 10px;
+  position: relative;
+  .delete_sty {
+    display: none;
+    position: absolute;
+    top: 3px;
+    right: 3px;
+    z-index: 3;
+    transition: all 0.3s;
+  }
+  &:hover .delete_sty {
+    display: block;
+  }
+}
+</style>

+ 20 - 30
src/views/Marketing/order/orderList/index.vue

@@ -20,7 +20,7 @@
     >
       <template slot="btn" slot-scope="props">
         <el-button type="text" @click="jumpDetail(props.scope.row)"
-          >详情</el-button
+          >订单收费信息</el-button
         >
         <!-- <el-button type="text" @click="del(props.scope.row)">删除</el-button> -->
       </template>
@@ -52,9 +52,9 @@ export default {
         num: false,
         border: true,
         choice: true,
-        addHide: false,
+        addHide: true,
         backFatherBtn: {
-          status: true,
+          status: false,
           title: "计费单收费",
         },
       },
@@ -143,6 +143,7 @@ export default {
         },
       ],
       formData: {
+        orderFroms:"2,3,4",
         goodsType: "",
         pageSize: 10,
         pageNum: 1,
@@ -183,7 +184,7 @@ export default {
           label: "商品名称",
           prop: "goodsName",
           hidden: true,
-          width:"280px"
+          width: "280px",
         },
         {
           label: "商品业务层级",
@@ -259,53 +260,41 @@ export default {
           width: "130px",
           options: [
             {
-              label: "业务员单",
+              label: "业务员普通单",
               value: 1,
             },
             {
-              label: "小程序",
+              label: "祥粤云学堂小程序",
               value: 2,
             },
-          ],
-        },
-        {
-          label: "订单状态",
-          prop: "status",
-          hidden: true,
-          scope: "isOptions",
-          options: [
             {
-              label: "无效",
-              value: 0,
+              label: "祥粤云学堂网站",
+              value: 3,
             },
             {
-              label: "有效",
-              value: 1,
+              label: "祥粤e管证小程序",
+              value: 4,
+            },
+            {
+              label: "业务员录单",
+              value: 5,
             },
           ],
         },
         {
-          label: "退款状态",
-          prop: "refundStatus",
+          label: "订单状态",
+          prop: "status",
           hidden: true,
           scope: "isOptions",
           options: [
             {
-              label: "无",
+              label: "无",
               value: 0,
             },
             {
-              label: "退款中",
+              label: "有效",
               value: 1,
             },
-            {
-              label: "已退款",
-              value: 2,
-            },
-            {
-              label: "拒绝退款",
-              value: 3,
-            },
           ],
         },
         {
@@ -380,6 +369,7 @@ export default {
       }
       if (int === 2) {
         this.formData = {
+          orderFroms:"2,3,4",
           goodsType: "",
           pageSize: 10,
           pageNum: 1,

+ 386 - 0
src/views/Marketing/order/pendingRefundOrder/index.vue

@@ -0,0 +1,386 @@
+<template>
+  <div id="pendingRefundOrder">
+    <search-box-new
+      ref="searchBox"
+      :formData="formData"
+      :formList="formList"
+      @search="search"
+      @init="init"
+      :topType="topType"
+      :pendingType="pendingType"
+    />
+    <table-list
+      rowKey="refundId"
+      :tableSets="tableSet"
+      :tableData="tableData"
+      :navText="navText"
+      :loading="loading"
+      ref="tableList"
+    >
+      <template slot="customize">
+        <el-button size="medium" type="success" @click="setGoodsOptions"
+          >批量审核</el-button
+        >
+      </template>
+      <template slot="btn" slot-scope="props">
+        <el-button type="text" @click="audit(props.scope.row)">审核</el-button>
+      </template>
+    </table-list>
+    <pagination
+      :total="total"
+      :pageSize="formData.pageSize"
+      :currentPage="formData.pageNum"
+      @handleSizeChange="handleSizeChange"
+      @handleCurrentChange="handleCurrentChange"
+    />
+    <refund-dia ref="refundDia" />
+  </div>
+</template>
+
+<script>
+import searchBoxNew from "@/components/searchBoxNew";
+import tableList from "@/components/tableList";
+import pagination from "@/components/pagination";
+import refundDia from "./refundDia.vue";
+export default {
+  name: "PendingRefundOrder",
+  components: { searchBoxNew, tableList, pagination, refundDia },
+  data() {
+    return {
+      loading: false, //当前表单加载是否加载动画
+      navText: {
+        title: "待审退款订单",
+        index: 0,
+        ch: "条",
+        num: false,
+        border: true,
+        choice: true,
+        addHide: true,
+        changeWidth: "120px",
+        openCheckMore: true,
+        backFatherBtn: {
+          status: false,
+          title: "未定义",
+        },
+      },
+      topType: true,
+      pendingType: true,
+      //搜索
+      formList: [
+        {
+          prop: "educationTypeId",
+          placeholder: "教育类型",
+          scope: "educationType",
+        },
+        {
+          prop: "businessId",
+          placeholder: "业务层次",
+          scope: "businessLevel",
+          edu: "educationTypeId",
+        },
+        {
+          prop1: "startTime",
+          prop2: "endTime",
+          placeholder1: "订单开始时间",
+          placeholder2: "订单结束时间",
+          scope: "moreDataPicker",
+          Diszing: true,
+        },
+        {
+          prop: "searchKey",
+          placeholder: "订单编码/商品名/姓名/身份证",
+        },
+      ],
+      formData: {
+        goodsType: "",
+        periodStatus: 0,
+        pageSize: 10,
+        pageNum: 1,
+        type: 2,
+      },
+      // 表单
+      tableSet: [
+        {
+          label: "订单时间",
+          prop: "createTime",
+          hidden: true,
+          scope: "aTimeList",
+          width: "180px",
+        },
+        {
+          label: "订单编码",
+          prop: "orderSn",
+          hidden: true,
+          width: "210px",
+        },
+        {
+          label: "手机号码",
+          prop: "telphone",
+          hidden: true,
+          width: "120px",
+        },
+        {
+          label: "学员姓名",
+          prop: "realname",
+          hidden: true,
+        },
+        {
+          label: "学员身份证",
+          prop: "idCard",
+          hidden: true,
+          width: "190px",
+        },
+        {
+          label: "商品名称",
+          prop: "goodsName",
+          hidden: true,
+          width: "280px",
+        },
+        {
+          label: "商品业务层级",
+          prop1: "educationName",
+          prop2: "projectName",
+          prop3: "businessName",
+          hidden: true,
+          scope: "eduTypes",
+          width: "380px",
+        },
+        {
+          label: "商品年份",
+          prop: "year",
+          hidden: true,
+          ch: "年",
+        },
+        {
+          label: "商品标准价格",
+          prop: "goodsPrice",
+          hidden: true,
+          scope: "leftCh",
+          ch: "¥",
+        },
+        {
+          label: "商品成交价格",
+          prop: "goodsRealPrice",
+          hidden: true,
+          scope: "leftCh",
+          ch: "¥",
+        },
+        {
+          label: "支付状态",
+          prop: "payStatus",
+          hidden: true,
+          scope: "isOptions",
+          options: [
+            {
+              label: "未收费",
+              value: 1,
+            },
+            {
+              label: "部分收费",
+              value: 2,
+            },
+            {
+              label: "完全收费",
+              value: 3,
+            },
+          ],
+        },
+        {
+          label: "已收金额",
+          prop: "goodsReceived",
+          hidden: true,
+          scope: "leftCh",
+          ch: "¥",
+        },
+        {
+          label: "未收金额",
+          prop1: "goodsRealPrice",
+          prop2: "goodsReceived",
+          hidden: true,
+          scope: "outStandingAmount",
+        },
+        {
+          label: "审核结果",
+          prop: "periodStatus",
+          hidden: true,
+          scope: "periodStatusShow",
+        },
+      ],
+      tableData: [], //表单数据
+      total: 0, //一共多少条
+    };
+  },
+  mounted() {
+    this.search();
+  },
+  activated() {
+    this.search();
+  },
+  methods: {
+    /**
+     * 批量审核
+     */
+    setGoodsOptions() {
+      if (!this.$refs.tableList.allCheckData.length) {
+        this.$message.warning("请选择订单");
+        return;
+      }
+      this.$refs.refundDia.openBox(
+        this.$refs.tableList.allCheckData,
+        this.formData.periodStatus
+      );
+    },
+    search(int) {
+      this.loading = true;
+      if (int === 1) {
+        this.formData.pageNum = 1;
+      }
+      if (int === 2) {
+        this.formData = {
+          type: 2,
+          goodsType: "",
+          periodStatus: this.formData.periodStatus,
+          pageSize: 10,
+          pageNum: 1,
+        };
+      }
+      if (int === 3) {
+        this.formData.pageNum = 1;
+      }
+      if (int === 4) {
+        this.formData.pageNum = 1;
+        this.$refs.tableList.clearMoreActive();
+      }
+      var data = JSON.parse(JSON.stringify(this.formData));
+      data.inputOrderSn = this.$route.query.inputOrderSn;
+      if (this.formData.startTime) {
+        data.startTime = data.startTime / 1000;
+      }
+      if (this.formData.endTime) {
+        data.endTime = data.endTime / 1000;
+      }
+      this.$api
+        .inquireorderrefundlist(data)
+        .then((res) => {
+          this.tableData = res.rows;
+          this.total = res.total;
+          this.navText.index = res.total;
+        })
+        .finally(() => {
+          this.loading = false;
+        });
+    },
+    init() {
+      this.search(2);
+    },
+    audit(v) {
+      this.$refs.refundDia.openBox([v], this.formData.periodStatus);
+    },
+    handleSizeChange(v) {
+      this.formData.pageSize = v;
+      this.formData.pageNum = 1;
+      this.search();
+    },
+    handleCurrentChange(v) {
+      this.formData.pageNum = v;
+      this.search();
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+/deep/.el-button {
+  border-radius: 8px;
+}
+/deep/.el-dialog {
+  border-radius: 8px;
+  .el-dialog__header {
+    padding: 0;
+    .hearders {
+      height: 40px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      padding: 0px 18px 0px 20px;
+      border-bottom: 1px solid #e2e2e2;
+      .leftTitle {
+        font-size: 14px;
+        font-weight: bold;
+        color: #2f4378;
+      }
+      .rightBoxs {
+        display: flex;
+        align-items: center;
+        img {
+          width: 14px;
+          height: 14px;
+          margin-left: 13px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+  .el-dialog__body {
+    padding: 10px 20px;
+  }
+  .el-dialog__footer {
+    padding: 0;
+    .dialog-footer {
+      padding: 0px 40px;
+      height: 70px;
+      border-top: 1px solid #e2e2e2;
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+    }
+  }
+}
+.imgBox {
+  width: 100%;
+  // height: 210px;
+  border: 1px solid #e2e2e2;
+  border-radius: 8px;
+  padding: 8px 8px 3px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  .imgLabel {
+    flex: 1;
+    width: 100%;
+    border: 1px dotted #e2e2e2;
+    color: #999;
+    font-size: 14px;
+    cursor: pointer;
+    border-radius: 8px;
+    .msPhoto {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      max-width: 100%;
+      max-height: 270px;
+      img {
+        max-width: 100%;
+        max-height: 270px;
+      }
+    }
+    .imgbbx {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 100%;
+      i {
+        font-weight: bold;
+        margin: 14px 0;
+        font-size: 24px;
+      }
+    }
+  }
+  p {
+    margin: 5px 0px;
+  }
+}
+</style>
+

+ 241 - 0
src/views/Marketing/order/pendingRefundOrder/refundDia.vue

@@ -0,0 +1,241 @@
+<template>
+  <div id="refundDia">
+    <el-dialog
+      @closed="loadingClose"
+      :visible.sync="dialogVisible"
+      width="780px"
+      :show-close="false"
+      :close-on-click-modal="false"
+    >
+      <div slot="title" class="hearders">
+        <div class="leftTitle">退款审核</div>
+        <div class="rightBoxs">
+          <img src="@/assets/images/Close@2x.png" alt="" @click="close" />
+        </div>
+      </div>
+      <div class="over_sty">
+        <div v-for="(item, index) in listData" :key="index">
+          <el-divider v-if="index !== 0"></el-divider>
+          <p>{{ $methodsTools.onlyForma(item.createTime) }}</p>
+          <p>
+            <strong style="color: red">{{ item.realname }}</strong
+            >,发起退款申请
+          </p>
+          <ul class="ul_sty">
+            <li>
+              <strong>本次退费金额:</strong><span>¥{{ item.refundFee }}</span>
+            </li>
+            <li>
+              <strong>退款理由:</strong><span>{{ item.applyReason }}</span>
+            </li>
+            <li>
+              <strong>证明:</strong>
+              <ul style="margin-top: 10px">
+                <li
+                  class="float_li"
+                  v-for="(items, indexs) in listData[index].applyImgs"
+                  :key="indexs"
+                >
+                  <el-image
+                    style="width: 100%; height: 100%"
+                    :src="$methodsTools.splitImgHost(items)"
+                    :preview-src-list="[$methodsTools.splitImgHost(items)]"
+                  >
+                  </el-image>
+                </li>
+                <div style="clear: both"></div>
+              </ul>
+            </li>
+          </ul>
+          <ul v-if="int === 1" class="ul_sty">
+            <strong>初审结果</strong>
+            <li>审核人:{{ item.periodUsername }}</li>
+            <li>
+              审核结果:{{ item.copyperiodStatus === 1 ? "同意" : "拒绝" }}
+            </li>
+            <li>审核意见:{{ item.periodReason }}</li>
+          </ul>
+          <p v-if="int === 1">复审意见</p>
+          <div v-if="int === 0">
+            <div class="disflex_sty">
+              <span class="spanSty">审核结果:</span>
+              <el-radio-group v-model="item.periodStatus" :size="size">
+                <el-radio :label="1">同意</el-radio>
+                <el-radio :label="-1">拒绝</el-radio>
+              </el-radio-group>
+            </div>
+            <div class="disflex_sty">
+              <span class="spanSty">审核意见:</span>
+              <el-input
+                type="textarea"
+                v-model="item.periodReason"
+                :size="size"
+              ></el-input>
+            </div>
+          </div>
+
+          <div v-if="int === 1">
+            <div class="disflex_sty">
+              <span class="spanSty">审核结果:</span>
+              <el-radio-group
+                v-model="item.periodStatus"
+                :size="size"
+                @change="item.periodStatusLine = ''"
+              >
+                <el-radio :label="2">同意</el-radio>
+                <el-radio :label="-2">拒绝</el-radio>
+              </el-radio-group>
+            </div>
+            <div class="disflex_sty" v-if="item.periodStatus === 2">
+              <span class="spanSty"></span>
+              <el-radio-group v-model="item.periodStatusLine" :size="size">
+                <el-radio :label="2">待退款</el-radio>
+                <el-radio :label="3">已退款</el-radio>
+              </el-radio-group>
+            </div>
+            <div class="disflex_sty">
+              <span class="spanSty">审核意见:</span>
+              <el-input
+                type="textarea"
+                v-model="item.periodReviewReason"
+                :size="size"
+              ></el-input>
+            </div>
+          </div>
+        </div>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="close">取 消</el-button>
+        <el-button type="primary" :loading="disabledBtn" @click="submit"
+          >确 定</el-button
+        >
+      </span>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      size: "mini",
+      dialogVisible: false,
+      disabledBtn: false,
+      listData: [],
+      int: null, //0初审 1复审
+    };
+  },
+  methods: {
+    openBox(arr, int) {
+      this.int = int;
+      let newles = JSON.parse(JSON.stringify(arr));
+      this.listData = newles.map((item) => {
+        if (item.applyImgs) {
+          item.applyImgs = item.applyImgs.split(",");
+        } else {
+          item.applyImgs = [];
+        }
+        if (int === 1) {
+          item.copyperiodStatus = item.periodStatus;
+          item.periodStatusLine = ""
+        }
+        return item;
+      });
+      this.dialogVisible = true;
+    },
+    loadingClose() {
+      this.disabledBtn = false;
+    },
+    close() {
+      this.dialogVisible = false;
+    },
+    submit() {
+      this.disabledBtn = true;
+      let data = JSON.parse(JSON.stringify(this.listData));
+      let status = data.every((item) => {
+        if (this.int === 0) {
+          return item.periodStatus == 1 || item.periodStatus == -1;
+        }
+        if (this.int === 1) {
+          if (item.periodStatus == 2 || item.periodStatus == -2) {
+            if (item.periodStatus == -2) {
+              return true;
+            } else {
+              if (item.periodStatusLine) {
+                return true;
+              } else {
+                return false;
+              }
+            }
+          } else {
+            return false;
+          }
+        }
+      });
+      if (!status) {
+        this.$message.error("请勾选审核结果");
+        this.disabledBtn = false;
+        return;
+      }
+      data.forEach((item) => {
+        if (item.applyImgs.length) {
+          item.applyImgs = item.applyImgs.toString();
+        }
+      });
+      if (this.int === 0) {
+        this.$api
+          .editorderrefundfirstPeriod(data)
+          .then((res) => {
+            this.dialogVisible = false;
+            this.$parent.$refs.tableList.clearMoreActive();
+            this.$parent.search();
+          })
+          .catch((err) => {
+            this.disabledBtn = false;
+          });
+      }
+      if (this.int === 1) {
+        this.$api
+          .editorderrefundconfirmPeriod(data)
+          .then((res) => {
+            this.dialogVisible = false;
+            this.$parent.$refs.tableList.clearMoreActive();
+            this.$parent.search();
+          })
+          .catch((err) => {
+            this.disabledBtn = false;
+          });
+      }
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped>
+.ul_sty {
+  padding: 10px;
+  background-color: rgb(252, 234, 236);
+}
+.float_li {
+  width: 110px;
+  height: 110px;
+  float: left;
+  border: 1px solid #696969;
+  margin-right: 10px;
+}
+li {
+  margin-bottom: 6px;
+}
+.disflex_sty {
+  display: flex;
+  align-items: center;
+  margin-bottom: 10px;
+  .spanSty {
+    width: 100px;
+  }
+}
+.over_sty {
+  max-height: 600px;
+  overflow: auto;
+}
+</style>

+ 3 - 3
src/views/education/classManageMent/classHours/index.vue

@@ -272,11 +272,11 @@ export default {
         },
         {
           label: "学习服务期",
-          prop1: "studyStartTime",
-          prop2: "studyEndTime",
+          prop1: "serviceStartTime",
+          prop2: "serviceEndTime",
           hidden: true,
+          Diszing: true,
           scope: "TimeLists",
-          width: "310px",
         },
         {
           label: "填写资料审核状态",

+ 10 - 2
src/views/education/classManageMent/learningHoursRecordList/index.vue

@@ -291,6 +291,14 @@ export default {
           prop: "className",
           hidden: true,
         },
+        {
+          label: "学习服务期",
+          prop1: "serviceStartTime",
+          prop2: "serviceEndTime",
+          hidden: true,
+          Diszing: true,
+          scope: "TimeLists",
+        },
         {
           label: "班级有效期",
           prop1: "classStartTime",
@@ -301,8 +309,8 @@ export default {
         },
         {
           label: "学习时间",
-          prop1: "studyStartTime",
-          prop2: "studyEndTime",
+          prop1: "startTime",
+          prop2: "endTime",
           scope: "TimeLists",
           hidden: true,
         },

+ 3 - 2
src/views/education/classManageMent/listOfhoursToBeReviewed/index.vue

@@ -190,9 +190,10 @@ export default {
         },
         {
           label: "学习服务期",
-          prop1: "studyStartTime",
-          prop2: "studyEndTime",
+          prop1: "serviceStartTime",
+          prop2: "serviceEndTime",
           hidden: true,
+          Diszing: true,
           scope: "TimeLists",
         },
         {

+ 3 - 3
src/views/education/classManageMent/studentMenu/index.vue

@@ -660,10 +660,10 @@ export default {
         },
         {
           label: "学习服务期",
-          prop1: "studyStartTime",
-          prop2: "studyEndTime",
+          prop1: "serviceStartTime",
+          prop2: "serviceEndTime",
           hidden: true,
-          Diszing: false,
+          Diszing: true,
           scope: "TimeLists",
         },
         {

+ 6 - 6
src/views/education/studentManageMent/studentXQ/studyRecord.vue

@@ -94,8 +94,8 @@
             {{ $methodsTools.onlyForma(scope.row[item.prop]) }}
           </span>
           <span v-else-if="item.scope === 'moreTime'">
-            {{ $methodsTools.onlyForma(scope.row[item.prop1]) }}
-            {{ $methodsTools.onlyForma(scope.row[item.prop2]) }}-
+            {{ $methodsTools.onlyForma(scope.row[item.prop1]) }} -
+            {{ $methodsTools.onlyForma(scope.row[item.prop2]) }}
           </span>
           <span v-else>
             {{ scope.row[item.prop] }}{{ item.ch ? item.ch : "" }}
@@ -272,8 +272,8 @@ export default {
         },
         {
           label: "学习服务期",
-          prop1: "studyStartTime",
-          prop2: "studyEndTime",
+          prop1: "serviceStartTime",
+          prop2: "serviceEndTime",
           scope: "moreTime",
           width: "140px",
         },
@@ -352,9 +352,9 @@ export default {
         return;
       }
       let result = (int1 / int2) * 100;
-      if(result == 0 || result == 100){
+      if (result == 0 || result == 100) {
         return result + "%";
-      }else{
+      } else {
         return result.toFixed(2) + "%";
       }
     },

+ 1 - 1
src/views/resource/bankManagement/testPaperManagement/editPaper/baseEditPaper/index.vue

@@ -227,7 +227,7 @@ export default {
   mounted() {
     this.$modal.loading("正在导入数据,请稍后...");
     this.$api
-      .gradecheckGoodsChange({ examId: this.$route.query.id })
+      .gradecheckGoodsChange({ chapterExamId: this.$route.query.id })
       .then((res) => {
         console.log(res.data);
         if (res.data > 0) {

+ 1 - 1
src/views/resource/bankManagement/testPaperManagement/editPaper/topicEditPaper/index.vue

@@ -1040,7 +1040,7 @@ export default {
       }
     }
     this.$api
-      .gradecheckGoodsChange({ examId: this.$route.query.id })
+      .gradecheckGoodsChange({ chapterExamId: this.$route.query.id })
       .then((res) => {
         if (res.data > 0) {
           this.noStudent = false;

+ 6 - 2
src/views/resource/videoManagement/chapter/add/index.vue

@@ -8,7 +8,7 @@
       ref="listData"
     >
       <div class="boxWidth">
-        <el-form-item label="适用业务层级">
+        <el-form-item label="适用业务层级" required>
           <el-select
             v-model="eduType"
             placeholder="请选择教育类型"
@@ -617,7 +617,7 @@ export default {
   },
   methods: {
     seeTheVideo(item) {
-      this.$refs.preview.diavosFun(item)
+      this.$refs.preview.diavosFun(item);
     },
     getDowm() {
       let url =
@@ -954,6 +954,10 @@ export default {
     submit(formName) {
       this.$refs[formName].validate((valid) => {
         if (valid) {
+          if (!this.newSujectApis.length) {
+            this.$message.error("请选择适用业务层级");
+            return;
+          }
           // if (
           //   this.listData.coverUrl === "" ||
           //   this.listData.coverUrl === null ||

+ 5 - 1
src/views/resource/videoManagement/chapter/edit/index.vue

@@ -8,7 +8,7 @@
       ref="listData"
     >
       <div class="boxWidth">
-        <el-form-item label="适用业务层级">
+        <el-form-item label="适用业务层级" required>
           <el-select
             v-model="eduType"
             placeholder="请选择教育类型"
@@ -1001,6 +1001,10 @@ export default {
     submit(formName) {
       this.$refs[formName].validate((valid) => {
         if (valid) {
+          if (!this.newSujectApis.length) {
+            this.$message.error("请选择适用业务层级")
+            return
+          }
           // if (
           //   this.listData.coverUrl === "" ||
           //   this.listData.coverUrl === null ||

+ 2 - 2
src/views/resource/videoManagement/courseManagement/basicInfoAdd/index.vue

@@ -73,11 +73,11 @@
           </el-select>
         </el-form-item>
         <el-form-item
-          label="科目/类目"
+          label="科目"
           prop="subjectId"
           v-if="listData.businessId"
         >
-          <el-select v-model="listData.subjectId" placeholder="请选择科目/类目">
+          <el-select v-model="listData.subjectId" placeholder="请选择科目">
             <el-option
               v-for="(item, index) in newSujectOption"
               :key="index"

+ 2 - 2
src/views/resource/videoManagement/courseManagement/basicInfoEdit/index.vue

@@ -71,13 +71,13 @@
           </el-select>
         </el-form-item>
         <el-form-item
-          label="科目/类目"
+          label="科目"
           prop="subjectId"
           v-if="listData.businessId"
         >
           <el-select
             v-model="listData.subjectId"
-            placeholder="请选择科目/类目"
+            placeholder="请选择科目"
             disabled
           >
             <el-option

+ 30 - 16
src/views/resource/videoManagement/festival/add/index.vue

@@ -8,7 +8,7 @@
         :rules="rules"
         ref="listData"
       >
-        <el-form-item label="适用业务层级">
+        <el-form-item label="适用业务层级" required>
           <el-select
             v-model="eduType"
             placeholder="请选择教育类型"
@@ -346,7 +346,12 @@
         </el-form-item>
         <el-form-item>
           <el-button @click="backPage">取消</el-button>
-          <el-button type="primary" @click="submit('listData')" :loading="disabledBtn">确定</el-button>
+          <el-button
+            type="primary"
+            @click="submit('listData')"
+            :loading="disabledBtn"
+            >确定</el-button
+          >
         </el-form-item>
       </el-form>
     </div>
@@ -902,6 +907,10 @@ export default {
     submit(formName) {
       this.$refs[formName].validate((valid) => {
         if (valid) {
+          if (!this.newSujectApis.length) {
+            this.$message.error("请选择适用业务层级");
+            return;
+          }
           // if (
           //   this.listData.coverUrl === "" ||
           //   this.listData.coverUrl === null ||
@@ -917,7 +926,7 @@ export default {
       });
     },
     async rulesTableSumbit() {
-      this.disabledBtn = true
+      this.disabledBtn = true;
       var dataInfos = {
         status: 1,
         businessList: this.newSujectApis,
@@ -944,7 +953,7 @@ export default {
           dataInfos.liveEndTime < dataInfos.liveStartTime
         ) {
           this.$message.warning("请检查直播开始与结束时间范围");
-          this.disabledBtn = false
+          this.disabledBtn = false;
           return;
         }
         dataInfos.durationTime =
@@ -964,19 +973,24 @@ export default {
           this.listData.durationTime
         );
       }
-      this.$api.appCourseSection(dataInfos).then((res) => {
-        this.$methodsTools.cacheBusinessList(this.newSujectApis);
-        this.$message.success("新增成功");
-        setTimeout(() => {
-          this.$store.dispatch("tagsView/exitView", this.$route).then((res) => {
-            this.$router.push({
-              path: "festival",
-            });
-          });
-        }, 500);
-      }).catch(()=>{
-          this.disabledBtn = false
+      this.$api
+        .appCourseSection(dataInfos)
+        .then((res) => {
+          this.$methodsTools.cacheBusinessList(this.newSujectApis);
+          this.$message.success("新增成功");
+          setTimeout(() => {
+            this.$store
+              .dispatch("tagsView/exitView", this.$route)
+              .then((res) => {
+                this.$router.push({
+                  path: "festival",
+                });
+              });
+          }, 500);
         })
+        .catch(() => {
+          this.disabledBtn = false;
+        });
     },
     backPage() {
       this.$store.dispatch("tagsView/delView", this.$route).then((res) => {

+ 5 - 1
src/views/resource/videoManagement/festival/edit/index.vue

@@ -8,7 +8,7 @@
         :rules="rules"
         ref="listData"
       >
-        <el-form-item label="适用业务层级">
+        <el-form-item label="适用业务层级" required>
           <el-select
             v-model="eduType"
             placeholder="请选择教育类型"
@@ -954,6 +954,10 @@ export default {
     submit(formName) {
       this.$refs[formName].validate((valid) => {
         if (valid) {
+          if (!this.newSujectApis.length) {
+            this.$message.error("请选择适用业务层级")
+            return
+          }
           // if (
           //   this.listData.coverUrl === "" ||
           //   this.listData.coverUrl === null ||

+ 5 - 1
src/views/resource/videoManagement/moduleManagement/add/index.vue

@@ -8,7 +8,7 @@
         :rules="rules"
         ref="listData"
       >
-        <el-form-item label="适用业务层级">
+        <el-form-item label="适用业务层级" required>
           <el-select
             v-model="eduType"
             placeholder="请选择教育类型"
@@ -770,6 +770,10 @@ export default {
     submit(formName) {
       this.$refs[formName].validate((valid) => {
         if (valid) {
+          if (!this.newSujectApis.length) {
+            this.$message.error("请选择适用业务层级")
+            return
+          }
           // if (
           //   this.listData.coverUrl === "" ||
           //   this.listData.coverUrl === null ||

+ 5 - 1
src/views/resource/videoManagement/moduleManagement/edit/index.vue

@@ -8,7 +8,7 @@
         :rules="rules"
         ref="listData"
       >
-        <el-form-item label="适用业务层级">
+        <el-form-item label="适用业务层级" required>
           <el-select
             v-model="eduType"
             placeholder="请选择教育类型"
@@ -742,6 +742,10 @@ export default {
     submit(formName) {
       this.$refs[formName].validate((valid) => {
         if (valid) {
+          if (!this.newSujectApis.length) {
+            this.$message.error("请选择适用业务层级")
+            return
+          }
           // if (
           //   this.listData.coverUrl === "" ||
           //   this.listData.coverUrl === null ||

+ 33 - 2
src/views/systemManagement/auditManagement/assignReviewers/index.vue

@@ -13,6 +13,12 @@
         <div class="btnSty" @click="getInfo(2)">学时审核</div>
       </div>
     </div>
+    <div class="floatSty">
+      <div class="headsty">订单管理</div>
+      <div class="dis_sty">
+        <div class="btnSty" @click="getInfo(3)">退款审核</div>
+      </div>
+    </div>
     <div style="clear: both"></div>
     <el-dialog
       :visible.sync="dialogVisible"
@@ -99,7 +105,7 @@
                 <div style="clear: both"></div>
               </li>
             </ul>
-            <div v-if="statePop === 2">
+            <div v-if="statePop === 2 || statePop === 3">
               <el-select
                 v-model="activeUserid"
                 placeholder="请选择复审人"
@@ -182,7 +188,7 @@ export default {
         return;
       }
 
-      if (this.statePop === 2) {
+      if (this.statePop === 2 || this.statePop === 3) {
         if (!this.userList2.length) {
           this.$message.warning("请选择指派复审人");
           return;
@@ -211,6 +217,16 @@ export default {
           this.$message.success("指派成功");
         });
       }
+      if (this.statePop === 3) {
+        let ays = {
+          id: this.businessId,
+          refundUserIds: this.userList1.toString(),
+          refundConfirmUserIds: this.userList2.toString(),
+        };
+        this.$api.editRefundPeriodUserIdsCourseBusiness(ays).then((res) => {
+          this.$message.success("指派成功");
+        });
+      }
     },
     /**
      *
@@ -264,6 +280,18 @@ export default {
                   .map(Number);
               }
             }
+            if (this.statePop === 3) {
+              if (result.data.refundUserIds) {
+                this.userList1 = result.data.refundUserIds
+                  .split(",")
+                  .map(Number);
+              }
+              if (result.data.refundConfirmUserIds) {
+                this.userList2 = result.data.refundConfirmUserIds
+                  .split(",")
+                  .map(Number);
+              }
+            }
           });
         });
     },
@@ -302,6 +330,9 @@ export default {
         case 2:
           ast = "学时审核-指派审核人";
           break;
+        case 2:
+          ast = "退款审核-指派审核人";
+          break;
         default:
           break;
       }