14 Commits a0f4bc1169 ... b16b0f34f4

Tác giả SHA1 Thông báo Ngày
  zweiqin b16b0f34f4 Merge branch 'master' into dev 10 tháng trước cách đây
  zweiqin 8154a93d0c 2024.08.26 10 tháng trước cách đây
  GuYun-D 8d9c98fc63 Merge branch 'feat/v20240706-dashboard' 10 tháng trước cách đây
  GuYun-D 9b0ebcfec6 2024.08.25 - 又把tooltip去掉了 10 tháng trước cách đây
  GuYun-D 556c7e188e Merge branch 'feat/v20240706-dashboard' 10 tháng trước cách đây
  zweiqin c2053e1e21 2024.08.21 10 tháng trước cách đây
  zweiqin 531ed88dc2 2024.08.21 10 tháng trước cách đây
  zweiqin 387ec83f6e 2024.08.20 10 tháng trước cách đây
  zweiqin c35b8864aa Merge branch 'master' of http://159.75.201.17:3000/zwq/tuanfeng-pc-admin 10 tháng trước cách đây
  zweiqin 72206183e2 2024.08.17 10 tháng trước cách đây
  wzy 881b086d41 Merge branch 'master' of http://159.75.201.17:3000/zwq/tuanfeng-pc-admin 10 tháng trước cách đây
  wzy f2b02d20d1 复制商品bug修复 10 tháng trước cách đây
  zweiqin d365f30cc8 2024.08.16 补充提交 10 tháng trước cách đây
  zweiqin 177fde543d 2024.08.16 10 tháng trước cách đây

+ 9 - 0
src/api/application.js

@@ -82,6 +82,15 @@ export function getWaterRecord(params){
   })
 }
 
+// 分页查询佣金流水记录(新)
+export function getCommissionAll(params){
+  return request({
+    url:"/buyerCommissionEntryRecord/getCommissionAll",
+    method:"get",
+    params
+  })
+}
+
 //  通联查询
 export function getTonglian(data){
   return request({

+ 9 - 0
src/api/user.js

@@ -57,3 +57,12 @@ export function changeHeader(data) {
     data
   })
 }
+
+//  获取验证码
+export function getVerificationImageCaptchaApi(params) {
+  return request({
+    url: '/captcha/get/verification/image',
+    method: 'get',
+    params
+  })
+}

+ 483 - 0
src/components/GraphicVerificationCode/SliderCaptcha.vue

@@ -0,0 +1,483 @@
+<template>
+  <div class="slider-captcha-container">
+    <div v-if="dialogVisible" class="lang-dialog">
+      <div class="lang-dialog__header">
+        <div class="lang-dialog__title">
+          <slot name="title">{{ title }}</slot>
+        </div>
+        <div type="button" class="lang-dialog-header-btn" @click="close"> <i class="lang-icon-close"></i> </div>
+      </div>
+      <div class="lang-dialog__body">
+        <div v-show="failed" class="tips">
+          <slot name="errorText">{{ errorText }}</slot>
+        </div>
+        <div v-show="!failed" class="tips">
+          <slot name="tips">{{ tips }}</slot>
+        </div>
+        <div class="slider-body" :class="{ 'slider-shock': shock }">
+          <div v-show="mask" class="loading-transparent-mask"></div>
+          <div v-if="loading" class="loading-body">
+            <div class="loading slider-loading"></div>
+          </div>
+          <div
+            v-show="!loading" class="slider-bg slider-img"
+            :style="{ 'background-image': 'url(data:image/png;base64,' + shadeImage + ')' }"
+          >
+          </div>
+          <div
+            v-show="!loading" class="slider-draw slider-move-draw slider-img"
+            :style="{ 'background-image': 'url(data:image/png;base64,' + cutoutImage + ')', 'top': sliderY + 'px', 'left': sliderMoveDrawLeft }"
+            @touchstart.stop="sliderTouchStart" @touchmove.stop="sliderTouchMove" @touchend.stop="sliderEnd"
+            @mousedown="sliderDown"
+          >
+          </div>
+          <div class="slider-progress"></div>
+          <div v-show="success" class="slider-success">
+            <div class="slider-success-icon">
+              成功
+            </div>
+            <div class="slider-success-text">
+              <slot name="successText">{{ successText }}</slot>
+            </div>
+          </div>
+          <div
+            class="slider-btn slider-move-btn" :style="{ 'left': sliderMoveLeft }"
+            :class="{ 'slider-shock': shock }" @touchstart.stop="sliderTouchStart" @touchmove.stop="sliderTouchMove"
+            @touchend.stop="sliderEnd" @mousedown="sliderDown"
+          >
+            <i>&nbsp;</i>
+            <span style="width: 100%;color: #ffffff;">● ● ●</span>
+          </div>
+        </div>
+        <div style="position:relative;display: flex;align-items: center;width: 280px;margin: 0 auto;">
+          <div class="slider-refresh" @click.stop="questionMessage = !questionMessage">
+            说明
+          </div>
+          <div class="slider-refresh" @click.stop="refresh">
+            刷新
+          </div>
+        </div>
+        <div v-if="questionMessage">
+          <slot name="question">
+            <div v-if="question">{{ question }}</div>
+            <div v-else>无注意事项</div>
+          </slot>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'SliderCaptcha',
+  props:
+    {
+      value: {
+        type: Boolean,
+        defalut: false
+      },
+      loading: {
+        type: Boolean,
+        defalut: false
+      },
+      title: {
+        type: String,
+        default: '滑块安全验证'
+      },
+      tips: {
+        type: String,
+        default: '拖动下方滑块完成拼图'
+      },
+      successText: {
+        type: String,
+        default: '验证成功'
+      },
+      errorText: {
+        type: String,
+        default: '是不是太难了,咱换一个'
+      },
+      question: {
+        type: String,
+        default: ''
+      },
+      options: {
+        type: Object,
+        default() {
+          return {
+            cutoutImage: '',
+            shadeImage: '',
+            sliderKey: '',
+            sliderY: ''
+          }
+        }
+      }
+    },
+  data() {
+    return {
+      dialogVisible: false,
+      mask: false,
+      success: false,
+      failed: false,
+      cutoutImage: '',
+      shadeImage: '',
+      sliderKey: '',
+      sliderX: 26,
+      sliderY: '',
+      sliderMoveDrawLeft: '26px',
+      sliderMoveLeft: '20px',
+      shock: false,
+      tipEvents: {},
+      sliderMoveX: 0,
+      questionMessage: false
+    }
+  },
+  watch: {
+    value: {
+      handler(val) {
+        this.init(val)
+      },
+      immediate: true
+    },
+    options: {
+      handler(option) {
+        this.clear()
+        this.cutoutImage = option.cutoutImage
+        this.shadeImage = option.shadeImage
+        this.sliderKey = option.sliderKey
+        this.sliderY = option.sliderY
+      },
+      deep: true,
+      immediate: true
+    }
+  },
+  methods: {
+    init(open) {
+      this.dialogVisible = open
+      if (open) {
+        this.clear()
+      }
+    },
+    clear() {
+      this.mask = false
+      this.success = false
+      this.failed = false
+      this.cutoutImage = ''
+      this.shadeImage = ''
+      this.sliderKey = ''
+      this.sliderX = 26
+      this.sliderMoveDrawLeft = '26px',
+      this.sliderMoveLeft = '20px',
+      this.sliderY = ''
+    },
+    check(sliderKey, sliderX) {
+      this.$emit('check', { sliderKey, sliderX, done: this.done, error: this.error })
+    },
+    done() {
+      this.success = true
+    },
+    error() {
+      this.failed = true
+      this.mask = true
+      this.shock = true
+      setTimeout(() => {
+        this.shock = false
+        this.$emit('error')
+      }, 1000)
+    },
+    close() {
+      this.dialogVisible = false
+      this.$emit('input', this.dialogVisible)
+      this.$emit('close')
+    },
+    refresh() {
+      this.$emit('refresh')
+    },
+    sliderTouchStart(e) {
+      // 移动触摸移动
+      const that = this
+      const slider = e.target
+      that.sliderMoveX = e.touches[0].clientX - slider.offsetLeft
+      console.log(e, e.touches[0].clientX, slider.offsetLeft)
+    },
+    sliderTouchMove(e) {
+      const that = this
+      const left = e.touches[0].clientX - that.sliderMoveX
+      if (left >= 20 && left <= 280) {
+        that.sliderMoveDrawLeft = 5 + left + 'px'
+        that.sliderMoveLeft = left + 'px'
+        that.sliderX = 5 + left
+      }
+    },
+    sliderEnd() {
+      this.check(this.sliderKey, this.sliderX)
+    },
+    sliderDown(e) {
+      console.log(e)
+      const that = this
+      const slider = e.target // 获取目标元素
+      // 算出鼠标相对元素的位置
+      that.sliderMoveX = e.clientX - slider.offsetLeft
+      document.onmousemove = (e) => {
+        const left = e.clientX - that.sliderMoveX
+        if (left >= 20 && left <= 280) {
+          //   slider.style.left = left + 'px'
+          that.sliderMoveDrawLeft = 5 + left + 'px'
+          that.sliderMoveLeft = left + 'px'
+          that.sliderX = 5 + left
+        }
+      }
+      document.onmouseup = () => {
+        document.onmousemove = null
+        document.onmouseup = null
+        this.check(this.sliderKey, this.sliderX)
+      }
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.slider-captcha-container {
+	box-sizing: border-box;
+
+	.slider-shock {
+		animation-delay: 0s;
+		animation-name: shock;
+		animation-duration: .1s;
+		animation-iteration-count: 5;
+		animation-direction: normal;
+		animation-timing-function: linear;
+	}
+
+	@keyframes shock {
+		0% {
+			transform: translateX(2px);
+		}
+
+		100% {
+			transform: translateX(-2px);
+		}
+	}
+
+	/* 弹窗开始  */
+	.lang-dialog {
+		position: relative;
+		border-radius: 2px;
+		box-shadow: 0 1px 3px rgba(0, 0, 0, 30%);
+		box-sizing: border-box;
+		background: #FFF;
+	}
+
+	.lang-dialog__header {
+		padding: 20px 20px 10px;
+	}
+
+	.lang-dialog__title {
+		line-height: 20px;
+		font-size: 18px;
+		color: #525252;
+	}
+
+	.lang-dialog-header-btn {
+		position: absolute;
+		top: 20px;
+		right: 20px;
+		padding: 0;
+		background: 0 0;
+		border: none;
+		outline: 0;
+		cursor: pointer;
+		font-size: 16px
+	}
+
+	.lang-icon-close {
+		color: rgba(0, 0, 0, 0.68);
+		font-size: 20px;
+	}
+
+	.lang-icon-close:before {
+		content: '×';
+	}
+
+	.lang-icon-close:hover {
+		color: rgba(0, 0, 0, 0.88);
+	}
+
+	.lang-dialog__body {
+		padding: 0 0 6px;
+		color: #828282;
+		font-size: 14px;
+		text-align: center;
+		word-break: break-all;
+	}
+
+	.loading-transparent-mask {
+		position: absolute;
+		top: 0;
+		left: 0;
+		width: 100%;
+		height: 100%;
+		background: transparent;
+		z-index: 999;
+	}
+
+	/* 弹窗结束  */
+	/* loading start */
+	.loading-body {
+		position: absolute;
+		top: 0;
+		left: 0;
+		width: 100%;
+		height: 100%;
+		background: rgba(255, 255, 255, 0.6);
+		z-index: 999;
+	}
+
+	.loading {
+		position: relative;
+		display: inline-block;
+		width: 30px;
+		height: 30px;
+		border-radius: 50%;
+		border-top: 2px solid transparent;
+		border-bottom: 2px solid transparent;
+		border-left: 2px solid #409eff;
+		border-right: 2px solid #409eff;
+		animation: loading 1s infinite linear;
+	}
+
+	@keyframes loading {
+		to {
+			transform: rotate(360deg);
+		}
+	}
+
+	.slider-loading {
+		position: absolute;
+		top: calc(50% - 15px);
+		left: calc(50% - 15px);
+		z-index: 999;
+	}
+
+	/* loading end */
+	.lang-dialog__header {
+		padding: 20px 10px 10px;
+	}
+
+	.tips {
+		color: #525252;
+		line-height: 36px;
+		font-size: 18px;
+	}
+
+	.slider-body {
+		position: relative;
+		width: 280px;
+		height: 230px;
+		margin: 0 auto;
+	}
+
+	.slider-bg {
+		position: relative;
+		width: 280px;
+		height: 171px;
+		overflow: hidden;
+		background-position: top left;
+		// background-size: cover;
+		background-size: auto auto;
+		background-repeat: no-repeat;
+	}
+
+	.slider-draw {
+		position: absolute;
+		z-index: 1;
+		left: 26px;
+		width: 50px;
+		height: 50px;
+		background-position: top left;
+		background-size: cover;
+		background-repeat: no-repeat;
+		cursor: pointer;
+		opacity: 1;
+		box-shadow: 0px 0px 10px 2px #000000;
+	}
+
+	.slider-progress {
+		position: relative;
+		z-index: 1;
+		width: 280px;
+		height: 16px;
+		margin-top: 22px;
+		background-color: #c8c8c8;
+		border-radius: 8px;
+		opacity: 1;
+	}
+
+	.slider-btn {
+		position: absolute;
+		top: 184px;
+		z-index: 1;
+		width: 65px;
+		height: 35px;
+		line-height: 35px;
+		background-color: rgb(0, 87, 212);
+		box-shadow: rgba(0, 87, 212, 50%) 0px 0px 5.05952px 0.505952px;
+		text-align: center;
+		border-radius: 999px;
+		cursor: pointer;
+		opacity: 1;
+		-moz-user-select: none;
+		/* 禁止双击节点被选中 */
+		-o-user-select: none;
+		-khtml-user-select: none;
+		-webkit-user-select: none;
+		-ms-user-select: none;
+		user-select: none;
+		-moz-user-drag: none;
+		/* 禁止被拖动 */
+		-webkit-user-drag: none;
+		/* 禁止被拖动 */
+		// pointer-events: none;
+		// display: inline-block;
+		// vertical-align: middle;
+	}
+
+	.slider-btn i {
+		display: inline-block;
+		width: 0;
+		vertical-align: middle;
+	}
+
+	.slider-success {
+		position: absolute;
+		top: 0;
+		left: 0;
+		width: 100%;
+		height: 100%;
+		z-index: 4;
+		background: hsla(0, 0%, 100%, .8);
+	}
+
+	.slider-success .slider-success-icon {
+		width: 64px;
+		height: 64px;
+		margin: 15px auto 0;
+	}
+
+	.slider-success .slider-success-text {
+		color: #1bc300;
+		text-align: center;
+		margin-top: 16px;
+		font-size: 18px;
+	}
+
+	.slider-refresh {
+		margin: 0 16px 0 0;
+		cursor: pointer;
+		font-size: 18px;
+		height: 30px;
+		line-height: 30px;
+	}
+}
+</style>

+ 204 - 0
src/components/GraphicVerificationCode/index.vue

@@ -0,0 +1,204 @@
+<template>
+  <div class="graphic-verification-code-container">
+    <div style="display: flex;align-items: center;">
+      <el-input
+        :value="inputCode" maxlength="6" type="text" auto-complete="off"
+        style="width: 63%;max-width: 200px;"
+        placeholder="请输入验证码" @input="handleCodeInput" @keyup.enter.native="$emit('enter-down')"
+      >
+        <template #prefix>
+          <svg-icon icon-class="password" class="el-input__icon input-icon" />
+        </template>
+      </el-input>
+      <div style="margin-left: 8px;">
+        <el-button type="primary" :loading="codeLoading" @click="handleGainVerify">
+          <span v-if="!codeLoading">获取验证码</span>
+          <span v-else>{{ codeCount }} s</span>
+        </el-button>
+      </div>
+    </div>
+    <el-dialog
+      :visible.sync="isShowGraphicVerificationDialog" v-bind="{ closeOnClickModal: false, width: '600px', title: '滑动码验证' }"
+      append-to-body
+    >
+      <div>
+        <div style="margin: 28rpx 0 0;">
+          <SliderCaptcha
+            v-model="slideVisible" :options="slideOptions" :loading="slideLoading"
+            @check="handleConfirmSlide" @close="isShowGraphicVerificationDialog = false" @refresh="getSliderOptions"
+            @error="getSliderOptions"
+          >
+            <template #title>安全验证</template>
+            <template #successText>验证通过</template>
+            <template #errorText>
+              <text style="color: #dc362e;">是不是太难了,换一个</text>
+            </template>
+            <template #tips>拖动下方滑块完成拼图</template>
+            <template #question>请尽快完成滑动自定义提示</template>
+          </SliderCaptcha>
+        </div>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import SliderCaptcha from './SliderCaptcha'
+import { getCode, getVerificationImageCaptchaApi } from '@/api/user'
+import { getUpdatePhoneCode, getPrivacyCode } from '@/api/privacy'
+
+export default {
+  name: 'GraphicVerificationCode',
+  components: {
+    SliderCaptcha
+  },
+  props: {
+    phone: {
+      type: [String, Number],
+      default: ''
+    },
+    apiType: {
+      type: [String, Number],
+      default: 'default' // default, update, privacy
+    }
+  },
+  data() {
+    return {
+      inputCode: '',
+      codeTimer: '',
+      codeLoading: false,
+      codeCount: '',
+
+      isShowGraphicVerificationDialog: false,
+      slideVisible: false,
+      slideLoading: false,
+      slideOptions: {
+        cutoutImage: '',
+        shadeImage: '',
+        sliderKey: '',
+        sliderY: ''
+      }
+    }
+  },
+  mounted() { },
+  methods: {
+    handleCodeInput(e) {
+      console.log(e)
+      this.inputCode = e
+      this.$emit('input', this.inputCode)
+    },
+    // 获取验证码
+    async getVerificationCode() {
+      if (!this.phone) {
+        this.$message.error('请填写电话号码')
+        return
+      }
+      try {
+        let _api
+        if (this.apiType === 'update') {
+          _api = getUpdatePhoneCode
+        } else if (this.apiType === 'privacy') {
+          _api = getPrivacyCode
+        } else {
+          _api = getCode
+        }
+        const res = await _api({ phone: this.phone, x: '0', y: '0' })
+        this.$message({
+          message: '发送成功,请注意查看手机短信',
+          type: 'success'
+        })
+        if (!this.codeTimer) {
+          this.codeLoading = true
+          this.codeTimer = setInterval(() => {
+            if (this.codeCount > 1 && this.codeCount <= 60) {
+              this.codeCount--
+            } else {
+              clearInterval(this.codeTimer) // 清除定时器
+              this.codeTimer = null
+              this.codeLoading = false
+            }
+          }, 1000)
+        }
+      } catch (e) {
+        console.log(e)
+      }
+    },
+
+    async handleGainVerify() {
+      if (!this.phone) {
+        this.$message.error('请填写电话号码')
+        return
+      } else if (!/^1[3-9]\d{9}$/.test(this.phone)) {
+        this.$message({
+          message: '请输入正确手机号',
+          type: 'warning'
+        })
+        return
+      }
+      this.isShowGraphicVerificationDialog = true
+      this.slideVisible = true
+      this.getSliderOptions()
+    },
+    getSliderOptions() {
+      this.slideLoading = true
+      getVerificationImageCaptchaApi({ type: 'slide' })
+        .then((res) => {
+          this.slideOptions = {
+            cutoutImage: res.data.cutoutImage,
+            shadeImage: res.data.shadeImage,
+            sliderKey: 'key',
+            sliderY: res.data.y
+          }
+          this.slideLoading = false
+        })
+    },
+    handleConfirmSlide({ sliderKey, sliderX, done, error }) {
+      this.slideLoading = true
+      console.log(sliderX, this.slideOptions.sliderY)
+      let _api
+      if (this.apiType === 'update') {
+        _api = getUpdatePhoneCode
+      } else if (this.apiType === 'privacy') {
+        _api = getPrivacyCode
+      } else {
+        _api = getCode
+      }
+      _api({ phone: this.phone, x: sliderX, y: this.slideOptions.sliderY, xxx: sliderKey })
+        .then((res) => {
+          this.$emit('success-verify', true)
+          this.slideLoading = false
+          done()
+          if (!this.codeTimer) {
+            this.codeLoading = true
+            this.codeCount = 60
+            this.codeTimer = setInterval(() => {
+              if (this.codeCount > 1 && this.codeCount <= 60) {
+                this.codeCount--
+              } else {
+                clearInterval(this.codeTimer) // 清除定时器
+                this.codeTimer = null
+                this.codeLoading = false
+              }
+            }, 1000)
+          }
+          this.isShowGraphicVerificationDialog = false
+          this.$message({
+            message: '发送成功,请注意查看手机短信',
+            type: 'success'
+          })
+        })
+        .catch(() => {
+          this.slideLoading = false
+          error()
+        })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.graphic-verification-code-container {
+	width: 100%;
+	box-sizing: border-box;
+}
+</style>

+ 1 - 1
src/views/active/combinationActivities/components/RegistrationReview.vue

@@ -76,12 +76,12 @@ export default {
     initList() {
     },
     handleOpen(params = {}) {
+      this.$refs.formData && this.$refs.formData.resetFields()
       this.modalOptions.title = '店铺的报名审核'
       this.formData.signId = params.signId
       // this.formData = Object.assign(this.$options.data().formData, params)
       this.visible = true
       this.initList()
-      this.$refs.formData && this.$refs.formData.resetFields()
     },
     handleSubmit() {
       this.$refs.formData.validate(async (valid) => {

+ 1 - 1
src/views/business/settlement/components/ApplicationProcessing.vue

@@ -129,11 +129,11 @@ export default {
     },
     handleOpen(params = {}) {
       this.modalOptions.title = '申请处理'
+      this.$refs.formData && this.$refs.formData.resetFields()
       // this.formData = Object.assign(this.$options.data().formData, params)
       this.formData.shopId = params.shopId
       this.visible = true
       this.initList()
-      this.$refs.formData && this.$refs.formData.resetFields()
     },
     handleSubmit() {
       this.$refs.formData.validate(async (valid) => {

+ 1 - 8
src/views/dashboard/data/dashboard.js

@@ -5,14 +5,7 @@ export const statisticalArea = [
     icon: require('../../../assets/images/dashboard/member.png'),
     children: [
       { label: '会员总数', field: 'memberTotal' },
-      {
-        label: '会员同比增长率',
-        field: 'memberIncreaseRate',
-        tooltip: true,
-        format(value) {
-          return { count: value * 100 + '', unit: '%' }
-        }
-      },
+      { label: '今日新增会员数', field: 'todayMember' },
       { label: '普通会员数量', field: 'normalMemberTotal' },
       { label: '团长数量', field: 'headquarterTotal' },
       { label: '合伙人数量', field: 'partnerTotal' }

+ 2 - 15
src/views/dashboard/index.vue

@@ -26,20 +26,7 @@
           :key="item.label + index"
           :meta="item"
           :itemData="statisticalRegionData[item.itemData]"
-        >
-          <template #memberIncreaseRate>
-            <div class="memberIncreaseRate-tooltip">
-              <div class="item">
-                <div>昨日新增会员:</div>
-                <div>{{ statisticalRegionData.memberStatistics.yesterdayMember || 0 }} 个</div>
-              </div>
-              <div class="item">
-                <div>今日新增会员:</div>
-                <div>{{ statisticalRegionData.memberStatistics.todayMember || 0 }} 个</div>
-              </div>
-            </div>
-          </template>
-        </StatisticsSection>
+        ></StatisticsSection>
       </div>
     </StatisticsPanel>
 
@@ -199,7 +186,7 @@ export default {
           normalMemberTotal: 0, // 普通会员数量
           headquarterTotal: 0, // 团长数量
           partnerTotal: 0, // 合伙人数量
-          memberIncreaseRate: 0 // 会员增长率
+          todayMember: 0 // 今日新增会员数
         },
         orderStatistics: {
           // 订单统计

+ 225 - 0
src/views/finance/application/components/DetailModal.vue

@@ -0,0 +1,225 @@
+<template>
+  <el-dialog :visible.sync="visible" v-bind="modalOptions">
+    <div>
+      <el-descriptions title="" :column="2" border>
+        <el-descriptions-item label="手机号码:">
+          {{ withdrawalInfo.phone }}
+        </el-descriptions-item>
+        <el-descriptions-item label="银行名称:">
+          {{ withdrawalInfo.bankName }}
+        </el-descriptions-item>
+        <el-descriptions-item label="银行卡号:">
+          {{ withdrawalInfo.bankCard }}
+        </el-descriptions-item>
+        <el-descriptions-item label="收款人姓名:">
+          {{ withdrawalInfo.name }}
+        </el-descriptions-item>
+        <el-descriptions-item label="提现金额:">
+          {{ withdrawalInfo.withdrawalMoney }}
+        </el-descriptions-item>
+        <el-descriptions-item label="实际到账:">
+          {{ withdrawalInfo.actualReceipt }}
+        </el-descriptions-item>
+        <el-descriptions-item label="申请时间:">
+          {{ withdrawalInfo.applyTime }}
+        </el-descriptions-item>
+        <el-descriptions-item label="处理时间:">
+          {{ withdrawalInfo.handleTime }}
+        </el-descriptions-item>
+        <el-descriptions-item label="拒绝打款理由:">
+          {{ withdrawalInfo.rejectReason || '--' }}
+        </el-descriptions-item>
+
+        <el-descriptions-item label="账户可提现金额:">
+          {{ watherInfo.price }}
+        </el-descriptions-item>
+        <el-descriptions-item label="账户总金额:">
+          {{ watherInfo.totalPrice }}
+        </el-descriptions-item>
+        <el-descriptions-item label="提现中:">
+          {{ watherInfo.pendingWithdrawal }}
+        </el-descriptions-item>
+        <el-descriptions-item label="已提现:">
+          {{ watherInfo.alreadyPrice }}
+        </el-descriptions-item>
+      </el-descriptions>
+    </div>
+
+    <el-tabs value="relatedSettlement">
+      <el-tab-pane label="金流水记录列表" name="relatedSettlement">
+        <div v-if="recordList && recordList.length" style="margin-top: 32px;">
+          <el-table
+            v-loading="!recordList.length" height="60vh" element-loading-text="暂无金流水记录数据" :data="recordList"
+            v-bind="{ stripe: true, size: 'small', border: true, fit: true, highlightCurrentRow: true }"
+          >
+            <!-- <el-table-column align="center" min-width="80" prop="price" label="支付金额" show-overflow-tooltip></el-table-column>
+              <el-table-column align="center" width="150" prop="paymentTime" label="支付时间" show-overflow-tooltip />
+              <el-table-column prop="customerName" label="支付名称" width="120" />
+              <el-table-column prop="customerPhone" label="支付电话" />
+              <el-table-column prop="transactionId" label="通联流水号" />
+              <el-table-column label="来源类型">
+              <template slot-scope="{ row }">
+              <span v-if="row.type == 1">关系链</span>
+              <span v-if="row.type == 2">商城</span>
+              <span v-if="row.type == 3">本地</span>
+              <span v-if="row.type == 4">服务</span>
+              </template>
+              </el-table-column>
+              <el-table-column label="状态">
+              <template slot-scope="{ row }">
+              <span v-if="row.isTo == 0">订单</span>
+              <span v-if="row.isTo == 1">确认收货</span>
+              </template>
+              </el-table-column>
+              <el-table-column prop="proportion" label="佣金比例" />
+              <el-table-column prop="amount" label="分配的佣金" />
+              <el-table-column prop="totalAmount" label="佣金总金额" /> -->
+            <el-table-column align="center" min-width="80" prop="id" label="ID" show-overflow-tooltip></el-table-column>
+            <el-table-column align="center" min-width="80" prop="buyerUserId" label="入账用户Id" show-overflow-tooltip></el-table-column>
+            <el-table-column align="center" label="来源类型" prop="sourceType">
+              <template slot-scope="{ row }">
+                <el-tag v-if="row.sourceType === 1" effect="plain" type="info">平台</el-tag>
+                <el-tag v-else-if="row.sourceType === 2" effect="plain" type="success">商圈</el-tag>
+                <el-tag v-else-if="row.sourceType === 3" effect="plain" type="success">用户</el-tag>
+                <el-tag v-else-if="row.sourceType === 4" effect="plain" type="success">社区</el-tag>
+                <el-tag v-else-if="row.sourceType === 5" effect="plain" type="success">商城</el-tag>
+                <span v-else>--</span>
+              </template>
+            </el-table-column>
+            <el-table-column align="center" min-width="80" prop="sourceId" label="来源Id" show-overflow-tooltip></el-table-column>
+            <el-table-column align="center" width="150" prop="orderFormid" label="来源订单编号" show-overflow-tooltip />
+            <el-table-column align="center" width="150" prop="commissionNumber" label="入账数量" show-overflow-tooltip />
+            <el-table-column align="center" label="活动配置类型" prop="waterType">
+              <template slot-scope="{ row }">
+                <el-tag v-if="row.waterType === -1" effect="plain" type="info">退款退回</el-tag>
+                <el-tag v-else-if="row.waterType === 1" effect="plain" type="success">升级活动</el-tag>
+                <el-tag v-else-if="row.waterType === 2" effect="plain" type="success">分佣活动</el-tag>
+                <el-tag v-else-if="row.waterType === 3" effect="plain" type="success">社区活动</el-tag>
+                <el-tag v-else-if="row.waterType === 4" effect="plain" type="success">赠券活动</el-tag>
+                <el-tag v-else-if="row.waterType === 5" effect="plain" type="success">赠金活动</el-tag>
+                <el-tag v-else-if="row.waterType === 6" effect="plain" type="success">商圈订单</el-tag>
+                <el-tag v-else-if="row.waterType === 7" effect="plain" type="success">爆款家具</el-tag>
+                <el-tag v-else-if="row.waterType === 8" effect="plain" type="success">社区订单</el-tag>
+                <el-tag v-else-if="row.waterType === 9" effect="plain" type="success">用户代金券转赠</el-tag>
+                <el-tag v-else-if="row.waterType === 0" effect="plain" type="success">商家代金券转赠</el-tag>
+                <el-tag v-else-if="row.waterType === 11" effect="plain" type="success">同城联盟卡</el-tag>
+                <span v-else>--</span>
+              </template>
+            </el-table-column>
+            <el-table-column align="center" width="150" prop="effectiveTime" label="有效时间" show-overflow-tooltip />
+            <el-table-column align="center" min-width="80" prop="isProportion" label="佣金比例" show-overflow-tooltip></el-table-column>
+            <el-table-column align="center" min-width="120" prop="commissionTotal" label="佣金总额" show-overflow-tooltip></el-table-column>
+            <el-table-column align="center" label="受益用户类型" prop="buyerUserType">
+              <template slot-scope="{ row }">
+                <el-tag v-if="row.buyerUserType == 100" effect="plain" type="info">代理商</el-tag>
+                <el-tag v-else-if="row.buyerUserType == 200" effect="plain" type="success">加盟商</el-tag>
+                <el-tag v-else-if="row.buyerUserType == 300" effect="plain" type="success">小区店</el-tag>
+                <el-tag v-else-if="row.buyerUserType == 400" effect="plain" type="success">本系统</el-tag>
+                <span v-else>{{ row.buyerUserType }}</span>
+              </template>
+            </el-table-column>
+            <el-table-column align="center" min-width="120" prop="withdrawalId" label="提现Id" show-overflow-tooltip></el-table-column>
+            <el-table-column align="center" width="150" prop="createTime" label="创建时间" show-overflow-tooltip />
+          </el-table>
+        </div>
+        <div v-else style="font-size: 16px;font-weight: bold;">无佣金流水记录数据</div>
+      </el-tab-pane>
+    </el-tabs>
+  </el-dialog>
+</template>
+
+<script>
+import { applicationGetById, getUserWater, getCommissionAll } from '@/api/application'
+
+export default {
+  name: 'DetailModal',
+  components: {
+  },
+  data() {
+    return {
+      modalOptions: {
+        closeOnClickModal: false,
+        width: '1220px',
+        title: '查看提现详情'
+      },
+      visible: false,
+      formData: {
+        withdrawalId: ''
+      },
+      withdrawalInfo: {
+        actualReceipt: '',
+        applyTime: '',
+        bankCard: '',
+        bankName: '',
+        batchId: '',
+        buyerUserId: '',
+        cost: '',
+        handleTime: '',
+        isConfirm: '',
+        name: '',
+        orderSn: '',
+        phone: '',
+        rejectReason: '',
+        state: '',
+        withdrawalId: '',
+        withdrawalMoney: ''
+      },
+      watherInfo: {},
+      recordQuery: {
+        // page: 1,
+        // pageSize: 20,
+        // acquirerId: '',
+        withdrawalId: ''
+      },
+      recordList: []
+    }
+  },
+  methods: {
+    handleClose() {
+      this.visible = false
+    },
+    async initList() {
+      const res1 = await applicationGetById({ withdrawalId: this.formData.withdrawalId })
+      this.withdrawalInfo = res1.data
+      const res2 = await getUserWater({ userId: this.withdrawalInfo.buyerUserId })
+      this.watherInfo = res2.data
+      const res3 = await getCommissionAll({ ...this.recordQuery, withdrawalId: this.withdrawalInfo.withdrawalId })
+      this.recordList = res3.data
+    },
+    handleOpen(params = {}) {
+      this.formData = Object.assign(this.$options.data().formData, params)
+      this.initList()
+      if (params.withdrawalId) {
+        // this.getInfo(params.withdrawalId)
+      }
+      this.visible = true
+    },
+    async getInfo(id) {
+      const loading = this.$loading({ text: '加载中' })
+      try {
+        const res = await xxx({ withdrawalId: id })
+        this.formData = Object.assign(this.$options.data().formData, res.data, {
+          withdrawalId: res.data.withdrawalId || ''
+        })
+      } finally {
+        loading.close()
+      }
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.small-padding {
+	.cell {
+		padding-left: 5px;
+		padding-right: 5px;
+	}
+}
+
+.fixed-width {
+	.el-button--mini {
+		padding: 7px 10px;
+	}
+}
+</style>

+ 181 - 0
src/views/finance/application/components/WithdrawalProcessing.vue

@@ -0,0 +1,181 @@
+<template>
+  <el-dialog
+    :visible.sync="visible"
+    v-bind="modalOptions"
+  >
+    <div>
+      <el-descriptions title="" :column="2" border>
+        <el-descriptions-item label="手机号码:">
+          {{ formData.phone }}
+        </el-descriptions-item>
+        <el-descriptions-item label="银行名称:">
+          {{ formData.bankName }}
+        </el-descriptions-item>
+        <el-descriptions-item label="银行卡号:">
+          {{ formData.bankCard }}
+        </el-descriptions-item>
+        <el-descriptions-item label="收款人姓名:">
+          {{ formData.name }}
+        </el-descriptions-item>
+        <el-descriptions-item label="提现金额:">
+          {{ formData.withdrawalMoney }}
+        </el-descriptions-item>
+        <el-descriptions-item label="实际到账:">
+          {{ formData.actualReceipt }}
+        </el-descriptions-item>
+        <el-descriptions-item label="申请时间:">
+          {{ formData.applyTime }}
+        </el-descriptions-item>
+        <el-descriptions-item label="处理时间:">
+          {{ formData.handleTime }}
+        </el-descriptions-item>
+      </el-descriptions>
+    </div>
+    <el-input v-show="formData.state == 2" v-model="formData.rejectReason" type="textarea" autosize placeholder="请输入拒绝打款理由">
+    </el-input>
+
+    <template #footer>
+      <span>
+        <el-button @click="visible = false">取 消</el-button>
+        <el-button v-if="formData.state === 3" type="danger" @click="handleRefuse">确认拒绝打款</el-button>
+        <el-button v-else type="danger" @click="handleRefuse">拒绝打款</el-button>
+        <el-button v-if="formData.state === 0" type="primary" @click="handleExamine">确认用户信息</el-button>
+        <el-button v-else-if="formData.state === 1" type="primary" @click="handleConfirm">确认打款</el-button>
+      </span>
+    </template>
+  </el-dialog>
+</template>
+
+<script>
+import { applicationGetById, applicationHandle } from '@/api/application'
+
+export default {
+  name: 'WithdrawalProcessing',
+  components: {
+  },
+  data() {
+    return {
+      modalOptions: {
+        closeOnClickModal: false,
+        width: '820px',
+        title: '提现处理'
+      },
+      visible: false,
+      formData: {
+        actualReceipt: '',
+        applyTime: '',
+        bankCard: '',
+        bankName: '',
+        batchId: '',
+        buyerUserId: '',
+        cost: '',
+        handleTime: '',
+        isConfirm: '',
+        name: '',
+        orderSn: '',
+        phone: '',
+        rejectReason: '',
+        state: '',
+        withdrawalId: '',
+        withdrawalMoney: ''
+      }
+    }
+  },
+  methods: {
+    handleClose() {
+      this.visible = false
+    },
+    async initList() {
+    },
+    handleOpen(params = {}) {
+      this.modalOptions.title = '提现处理'
+      this.formData = Object.assign(this.$options.data().formData, params)
+      this.visible = true
+      this.initList()
+      if (params.withdrawalId) {
+        this.getInfo(params.withdrawalId)
+      } else {
+        this.$refs.formData && this.$refs.formData.resetFields()
+      }
+    },
+    async getInfo(id) {
+      const loading = this.$loading({ text: '加载中' })
+      try {
+        const res = await applicationGetById({ withdrawalId: id })
+        this.formData = Object.assign(this.$options.data().formData, res.data, {
+          withdrawalId: res.data.withdrawalId || '',
+          actualReceipt: res.data.actualReceipt || '',
+          applyTime: res.data.applyTime || '',
+          bankCard: res.data.bankCard || '',
+          bankName: res.data.bankName || '',
+          batchId: res.data.batchId || '',
+          buyerUserId: res.data.buyerUserId || '',
+          cost: res.data.cost,
+          handleTime: res.data.handleTime || '',
+          isConfirm: res.data.isConfirm,
+          name: res.data.name || '',
+          orderSn: res.data.orderSn || '',
+          phone: res.data.phone || '',
+          rejectReason: res.data.rejectReason || '',
+          state: res.data.state,
+          withdrawalMoney: res.data.withdrawalMoney
+        })
+        this.$nextTick(() => {
+          this.$refs.formData && this.$refs.formData.validate()
+        })
+      } finally {
+        loading.close()
+      }
+    },
+    //  拒绝打款
+    async handleRefuse() {
+      if (this.formData.state == 2) {
+        if (!this.formData.rejectReason) return this.$message.error('拒绝理由不能为空')
+        const res = await applicationHandle({
+          withdrawalId: this.formData.withdrawalId,
+          state: '2',
+          rejectReason: this.formData.rejectReason
+        })
+        if (res.code == '') {
+          this.$message.success('成功拒绝打款!!!')
+        }
+        this.visible = false
+        this.$emit('success')
+      } else {
+        this.formData.state = 2
+        this.$message.warning('请填写理由并确定拒绝打款!!!')
+      }
+    },
+    // 确认审核
+    handleExamine() {
+      this.$confirm('确定审核通过吗?')
+        .then(async () => {
+          await applicationHandle({
+            withdrawalId: this.formData.withdrawalId,
+            state: '1'
+          })
+          this.$message.success('操作成功!请再次确认!')
+          this.getInfo(this.formData.withdrawalId)
+          this.$emit('success')
+        })
+        .catch(() => {})
+    },
+    // 确认打款
+    handleConfirm() {
+      this.$confirm('确定打款吗?')
+        .then(async () => {
+          await applicationHandle({
+            withdrawalId: this.formData.withdrawalId,
+            withdrawalType: 1, // 1佣金
+            state: '3'
+          })
+          this.$message.success('打款成功!!!')
+          this.visible = false
+          this.$emit('success')
+        })
+        .catch(() => {})
+    }
+  }
+}
+</script>
+

+ 144 - 410
src/views/finance/application/index.vue

@@ -1,457 +1,191 @@
 <template>
-  <div class="custom_page">
-    <div class="content">
-      <!-- 顶部搜索 -->
-      <div class="toolbar">
-        <!-- 顶部搜索 -->
-        <el-form :inline="true" :model="formInline">
-          <el-form-item label="用户名称">
-            <el-input v-model="formInline.name" maxlength="20" placeholder="请输入" />
-          </el-form-item>
-          <el-form-item label="手机号">
-            <el-input v-model="formInline.phone" maxlength="11" placeholder="请输入" />
-          </el-form-item>
-          <el-form-item label="提现状态">
-            <el-select v-model="formInline.state" placeholder="请选择">
-              <el-option label="全部" :value="null" />
-              <el-option label="待审核" value="0" />
-              <el-option label="打款中" value="1" />
-              <el-option label="通过" value="1" />
-              <el-option label="拒绝" value="2" />
-              <el-option label="打款成功" value="3" />
-              <el-option label="打款失败" value="4" />
-              <el-option label="待确认" value="5" />
-            </el-select>
-          </el-form-item>
-          <el-form-item label-width="0">
-            <el-button type="primary" plain @click="search">查询</el-button>
-            <el-button plain @click="clear">重置</el-button>
-          </el-form-item>
-        </el-form>
-      </div>
-      <!--  表格 -->
-      <div class="content_table">
-        <div class="table">
-          <el-table
-            v-loading="tableLoading" :data="tableData" border
-            :header-cell-style="{ background: '#EEF3FF', color: '#333333' }" style="width: 100%"
-          >
-            >
-            <el-table-column prop="orderSn" label="流水号"></el-table-column>
-            <el-table-column prop="name" label="用户名称" />
-            <el-table-column prop="phone" label="手机号码" />
-            <el-table-column prop="withdrawalMoney" label="提现金额" />
-            <el-table-column prop="cost" label="手续费"></el-table-column>
-            <el-table-column label="处理状态">
-              <template slot-scope="scope">
-                <span v-if="scope.row.state == 0">审核中</span>
-                <!-- <span v-if="scope.row.state == 1">打款中</span> -->
-                <span v-if="scope.row.state == 1">通过</span>
-                <span v-if="scope.row.state == 2">拒绝</span>
-                <span v-if="scope.row.state == 3">打款成功</span>
-                <span v-if="scope.row.state == 4">打款失败</span>
-                <span v-if="scope.row.state == 5">待确认</span>
-              </template>
-            </el-table-column>
-            <el-table-column prop="applyTime" label="申请时间"></el-table-column>
-            <el-table-column label="操作" show-overflow-tooltip>
-              <template slot-scope="scope">
-                <div class="btnList">
-                  <el-button v-if="scope.row.state == 1" type="text" @click="del(scope.row)">处理</el-button>
-                  <el-button v-else-if="scope.row.state !== 0" type="text" @click="seeMore(scope.row)">查看</el-button>
-                  <el-button v-else type="text" @click="del(scope.row)">处理</el-button>
-                  <el-button v-if="scope.row.state !== 3" type="text" @click="confirmTong(scope.row)">通联确认</el-button>
-                </div>
-              </template>
-            </el-table-column>
-          </el-table>
-          <div class="fenye">
-            <el-pagination
-              :current-page="currentPage" :page-sizes="[10, 20, 50, 100]" :page-size="10"
-              layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handleSizeChange"
-              @current-change="handleCurrentChange"
-            />
-          </div>
-        </div>
-      </div>
+  <div class="app-container">
+    <!-- 查询和其他操作 -->
+    <div class="filter-container">
+      <el-input
+        v-model="listQuery.name" clearable size="mini" class="filter-item"
+        style="width: 200px;"
+        placeholder="请输入用户名称"
+      />
+      <el-input
+        v-model="listQuery.phone" clearable size="mini" class="filter-item"
+        style="width: 200px;margin-left: 10px;" placeholder="请输入手机号"
+      />
+      <el-select
+        v-model="listQuery.state" clearable size="mini" class="filter-item"
+        style="width: 200px;margin-left: 10px;" placeholder="请选择提现状态"
+      >
+        <el-option label="全部" :value="null" />
+        <el-option label="待审核" value="0" />
+        <el-option label="打款中" value="1" />
+        <el-option label="通过" value="1" />
+        <el-option label="拒绝" value="2" />
+        <el-option label="打款成功" value="3" />
+        <el-option label="打款失败" value="4" />
+        <el-option label="待确认" value="5" />
+      </el-select>
+      <el-button
+        size="mini" class="filter-item" type="primary" icon="el-icon-search"
+        style="margin-left: 10px;"
+        @click="handleSearch"
+      >
+        查找
+      </el-button>
+      <el-button size="mini" type="info" class="filter-item" @click="handleReset">
+        重置
+      </el-button>
     </div>
 
-    <!-- 详情弹框 -->
-    <el-dialog
-      :visible.sync="dioObj.show" :title="dioObj.title" width="40%" center
-      :close-on-click-modal="false"
-      @close="closeDialog"
-    >
-      <div class="box">
-        <div class="dioBox">
-          <div v-for="(item, index) in infoList" :key="index" class="inner">{{ item.name }}:{{ item.value }}</div>
-        </div>
-        <div v-if="dioObj.type === 2" class="botTitle">*请确认您已转账成功,再点击确认</div>
-      </div>
-      <template #footer>
-        <span class="dialog-footer">
-          <el-button v-if="dioObj.type === 2" type="primary" @click="agreeEn(1)">{{ confirmInfo }}</el-button>
-          <el-button v-if="dioObj.type === 2" type="danger" @click="agreeEn(2)">拒绝打款</el-button>
-          <el-button v-if="dioObj.type === 1" @click="closeDialog">关 闭</el-button>
-        </span>
-      </template>
-      <div class="statistics">
-        <div class="statistics-item">
-          <h1>{{ watherInfo.price }}</h1>
-          <p>账户可提现金额</p>
-        </div>
-        <div class="statistics-item">
-          <h1>{{ watherInfo.totalPrice }}</h1>
-          <p>账户总金额</p>
-        </div>
-        <div class="statistics-item">
-          <h1>{{ watherInfo.pendingWithdrawal }}</h1>
-          <p>提现中</p>
-        </div>
-        <div class="statistics-item">
-          <h1>{{ watherInfo.alreadyPrice }}</h1>
-          <p>已提现</p>
-        </div>
-      </div>
-      <div class="tabbar-list">
-        <el-table
-          v-loading="watherFlag" :data="waterData" border
-          :header-cell-style="{ background: '#EEF3FF', color: '#333333' }" style="width: 100%"
-        >
-          >
-          <el-table-column prop="price" label="支付金额"></el-table-column>
-          <el-table-column prop="paymentTime" label="支付时间" />
-          <el-table-column prop="customerName" label="支付名称" />
-          <el-table-column prop="customerPhone" label="支付电话" />
-          <el-table-column prop="transactionId" label="通联流水号" />
-          <el-table-column label="来源类型">
-            <template slot-scope="scope">
-              <span v-if="scope.row.type == 1">关系链</span>
-              <span v-if="scope.row.type == 2">商城</span>
-              <span v-if="scope.row.type == 3">本地</span>
-              <span v-if="scope.row.type == 4">服务</span>
-            </template>
-          </el-table-column>
-          <el-table-column label="状态">
-            <template slot-scope="scope">
-              <span v-if="scope.row.isTo == 0">订单</span>
-              <span v-if="scope.row.isTo == 1">确认收货</span>
-            </template>
-          </el-table-column>
-          <el-table-column prop="proportion" label="佣金比例" />
-          <el-table-column prop="amount" label="分配的佣金" />
-          <el-table-column prop="totalAmount" label="佣金总金额" />
-        </el-table>
-      </div>
-      <div class="dialog-pagination">
-        <el-pagination layout="prev, pager, next" :total="waterTotal" :page-size="5" @current-change="waterChange">
-        </el-pagination>
-      </div>
-    </el-dialog>
+    <!-- 查询结果 -->
+    <div v-tableHeight>
+      <el-table
+        v-loading="listLoading" height="100%" element-loading-text="正在查询中。。。" :data="list"
+        v-bind="{ stripe: true, size: 'small', border: true, fit: true, highlightCurrentRow: true }"
+      >
+        <el-table-column align="center" width="150" label="流水号" prop="orderSn"></el-table-column>
+        <el-table-column align="center" min-width="150" label="用户名称" prop="name" show-overflow-tooltip />
+        <el-table-column prop="phone" label="手机号码" />
+        <el-table-column prop="withdrawalMoney" label="提现金额" />
+        <el-table-column prop="cost" label="手续费"></el-table-column>
+        <el-table-column label="处理状态">
+          <template slot-scope="scope">
+            <span v-if="scope.row.state == 0">审核中</span>
+            <!-- <span v-if="scope.row.state == 1">打款中</span> -->
+            <span v-if="scope.row.state == 1">通过</span>
+            <span v-if="scope.row.state == 2">拒绝</span>
+            <span v-if="scope.row.state == 3">打款成功</span>
+            <span v-if="scope.row.state == 4">打款失败</span>
+            <span v-if="scope.row.state == 5">待确认</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="applyTime" label="申请时间"></el-table-column>
+        <el-table-column align="center" width="150" label="备注" prop="cause" show-overflow-tooltip />
+        <el-table-column label="操作" width="180" fixed="right" class-name="small-padding fixed-width">
+          <template slot-scope="{ row }">
+            <el-button type="warning" size="mini" @click="handleDetail(row)">
+              详情
+            </el-button>
+            <el-button v-if="(row.state == 0) || (row.state == 1)" size="mini" @click="handleResolve(row)">
+              处理
+            </el-button>
+            <el-button v-if="row.state !== 3" type="text" @click="handleConfirmTong(row)">
+              通联确认
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+
+    <div>
+      <el-pagination
+        :current-page="listQuery.page" :page-sizes="[10, 20, 50, 100]" :page-size="listQuery.pageSize"
+        layout="total, sizes, prev, pager, next, jumper" :total="total"
+        @size-change="(val) => ((listQuery.pageSize = val) && getList())"
+        @current-change="(val) => ((listQuery.page = val) && getList())"
+      />
+    </div>
+
+    <!-- 提现处理 -->
+    <WithdrawalProcessing ref="WithdrawalProcessing" @success="getList" />
+    <!-- 查看详情 -->
+    <DetailModal ref="DetailModal" />
   </div>
 </template>
 
 <script>
 import {
   applicationGetAll,
-  applicationGetById,
-  applicationHandle,
-  getUserWater,
-  getWaterRecord,
   getTonglian
 } from '@/api/application'
+import WithdrawalProcessing from './components/WithdrawalProcessing'
+import DetailModal from './components/DetailModal'
 export default {
   name: 'Application',
+  components: {
+    WithdrawalProcessing,
+    DetailModal
+  },
   data() {
     return {
-      formInline: {
+      listQuery: {
         name: '', // 用户名称
         phone: '', // 手机号码
         state: null, // 提现状态 空-全部 0-待审核 1-通过 2-拒绝
         page: 1,
         pageSize: 10
       },
-      total: 1,
-      tableData: [],
-      //  控制表格的加载
-      tableLoading: true,
-      infoList: [
-        { name: '手机号码', value: '', fields: 'phone' },
-        { name: '银行名称', value: '', fields: 'bankName' },
-        { name: '银行卡号', value: '', fields: 'bankCard' },
-        { name: '收款人姓名', value: '', fields: 'name' },
-        { name: '提现金额', value: '', fields: 'withdrawalMoney' },
-        { name: '实际到账', value: '', fields: 'actualReceipt' },
-        { name: '申请时间', value: '', fields: 'applyTime' },
-        { name: '处理时间', value: '', fields: 'handleTime' }
-      ],
-      currentPage: 1,
-      multipleSelection: [],
-      dioObj: {},
-      //  拒绝打款理由
-      rejectReason: '',
-      //  控制确认信息和确认打款
-      confirmInfo: '确认信息',
-      // 流水信息表格数据
-      waterData: [],
-      waterTotal: null,
-      watherInfo: {},
-      // 获取流水数据参数
-      watherParameter: {
-        page: 1,
-        pageSize: 5,
-        acquirerId: ''
-      },
-      watherFlag: true
+      list: [],
+      total: 0,
+      listLoading: true
     }
   },
-  created() {
-    this.getAll(this.formInline)
+  mounted() {
+    this.getList()
   },
   methods: {
-    handleSizeChange(val) {
-      this.formInline.pageSize = val
-      this.getAll(this.formInline)
-    },
-    handleCurrentChange(val) {
-      this.formInline.page = val
-      this.getAll(this.formInline)
-    },
-    handleSelectionChange(val) {
-      this.multipleSelection = val
-    },
-    // 查询
-    search() {
-      this.total = 1
-      this.formInline.page = 1
-      this.getAll(this.formInline)
-    },
-    // 清除
-    clear() {
-      this.formInline = {
-        name: '', // 用户名称
-        phone: '', // 手机号码
-        state: null, // 提现状态 空-全部 0-待审核 1-通过 2-拒绝
-        page: 1,
-        pageSize: 10
+    async getList() {
+      this.listLoading = true
+      try {
+        const res = await applicationGetAll(this.listQuery)
+        this.list = res.data.list
+        this.total = res.data.total
+      } finally {
+        this.listLoading = false
       }
-      this.getAll(this.formInline)
     },
-    // 查看
-    seeMore(row) {
-      this.dioObj = {
-        title: '查看',
-        show: true,
-        arr: row,
-        type: 1
-      }
-      this.getDetails(row.withdrawalId)
+    handleSearch() {
+      this.listQuery.page = 1
+      this.getList()
     },
-    // 处理
-    del(row) {
-      this.dioObj = {
-        title: '处理',
-        show: true,
-        arr: row,
-        type: 2
-      }
-      this.getDetails(row.withdrawalId)
+    handleReset() {
+      this.listQuery = { name: '', phone: '', state: null, page: 1, pageSize: 10 }
+      this.getList()
     },
-    // 确认
-    async agreeEn(index) {
-      // console.log(index)
-      if (index === 1 && this.confirmInfo == '确认信息') {
-        const res = await applicationHandle({
-          withdrawalId: this.dioObj.arr.withdrawalId,
-          state: 1
-        })
-        this.$message.success('确认信息成功,请确认打款')
-        this.confirmInfo = '确认打款'
-      } else if (index === 1 && this.confirmInfo == '确认打款') {
-        this.$confirm('此操作将把款项打给用户, 是否继续?', '打款', {
-          confirmButtonText: '确定',
-          cancelButtonText: '取消',
-          type: 'warning'
-        }).then(async () => {
-          const res = await applicationHandle({
-            withdrawalId: this.dioObj.arr.withdrawalId,
-            withdrawalType: 1, // 1佣金
-            state: 3
-          })
-          if (res.code === '') {
-            this.$message.success('确认打款成功')
-            this.dioObj.show = false
-            this.getAll(this.formInline)
-          }
-        })
-          .catch(() => {
-            this.$message({
-              type: 'info',
-              message: '已取消打款'
-            })
-          })
-      } else if (index === 2) {
-        if (this.rejectReason == '') {
-          this.$prompt('请输入拒绝打款理由', '提示', {
-            confirmButtonText: '确定',
-            cancelButtonText: '取消',
-            inputPattern: /^\s*[\S]+\s*$/,
-            inputErrorMessage: '输入的拒绝打款理由不能为空!!!'
-          }).then(({ value }) => {
-            this.rejectReason = value
-            //  二次确认是否拒绝打款
-            this.$confirm('此操作将决绝为该用户打款, 是否继续?', '提示', {
-              confirmButtonText: '确定',
-              cancelButtonText: '取消',
-              type: 'warning'
-            }).then(async () => {
-              const res = await applicationHandle({
-                withdrawalId: this.dioObj.arr.withdrawalId,
-                state: 2,
-                rejectReason: this.rejectReason
-              })
-              if (res.code === '') {
-                this.$message.success('成功拒绝打款')
-                this.dioObj.show = false
-                this.getAll(this.formInline)
-              }
-            })
-              .catch(() => {
-                this.$message({
-                  type: 'info',
-                  message: '已取消拒绝打款'
-                })
-              })
-            this.infoList.push({ name: '拒绝打款理由', value, fields: 'rejectReason' })
-          })
-            .catch(() => {
-              this.rejectReason = ''
-            })
-          return false
-        }
-      }
+    handleDetail(row) {
+      this.$refs.DetailModal && this.$refs.DetailModal.handleOpen(row)
     },
-    // 查询详情
-    async getDetails(withdrawalId) {
-      const res = await applicationGetById({ withdrawalId })
-      if (res.code === '') {
-        this.details = res.data
-        this.getTopList(res.data)
-      }
-      //  判断是不是有拒绝打款理由
-      if (res.data.rejectReason && res.data.state == 2 || res.data.rejectReason && res.data.state == 4) {
-        this.infoList.push({ name: '拒绝打款理由', value: res.data.rejectReason, fields: 'rejectReason' })
-      }
-    },
-    async getTopList(o) {
-      this.infoList.map((item) => {
-        item.value = o[item.fields]
-      })
-      //  在这里获取统计的流水
-      const res = await getUserWater({ userId: o.buyerUserId })
-      this.watherInfo = res.data
-      this.getWatherTable(o.buyerUserId)
-    },
-
-    //  通联确认
-    async confirmTong(item) {
-      const obj = {
-        orderSn: item.orderSn,
-        withdrawalId: item.withdrawalId
-      }
-      await getTonglian(obj)
-      this.$message.success('通联确认成功')
-      this.getAll(this.formInline)
-    },
-    // 初始化查询所有数据
-    async getAll(formInline) {
-      //  加载状态
-      this.tableLoading = true
-      const res = await applicationGetAll(formInline)
-      //  清除加载状态
-      this.tableLoading = false
-      this.tableData = res.data.list
-      this.tableData.forEach((item) => {
-        item.phone = item.phone.replace(/(\d{3})\d+(\d{4})$/, '$1****$2')
-      })
-      this.total = res.data.total
+    handleResolve(row) {
+      this.$refs.WithdrawalProcessing && this.$refs.WithdrawalProcessing.handleOpen(row)
     },
-    //  获取流水表格数据
-    async getWatherTable(id) {
-      this.watherFlag = true
-      //  获取流水表格数据
-      this.watherParameter.acquirerId = id
-      const res = await getWaterRecord(this.watherParameter)
-      this.waterData = res.data.list
-      this.waterTotal = res.data.total
-      this.watherFlag = false
-    },
-    //  表格分页
-    waterChange(e) {
-      this.watherParameter.page = e
-      this.getWatherTable(this.watherParameter.acquirerId)
-    },
-    //  关闭弹窗的回调
-    closeDialog() {
-      this.dioObj.show = false
-      this.rejectReason = ''
-      this.confirmInfo = '确认信息'
-      // 清除流水表格信息 以及 load加载状态
-      this.waterData = []
-      console.log(this.dioObj)
-      this.infoList = this.infoList.filter((item) => item.fields != 'rejectReason')
+    // 通联确认
+    handleConfirmTong(row) {
+      this.$confirm('确定此项通联确认?')
+        .then(async () => {
+          await getTonglian({ orderSn: row.orderSn, withdrawalId: row.withdrawalId })
+          this.$message({ message: '操作成功!', type: 'success' })
+          this.handleSearch()
+        })
+        .catch(() => { })
     }
   }
 }
 </script>
 
-<style lang='scss' scoped>
-@import url("../../../styles/elDialog.scss");
-
-.custom_page {
+<style lang="scss" scoped>
+.app-container {
 	padding: 20px;
-}
-
-.box {
-	.dioBox {
-		display: flex;
-		justify-content: flex-start;
-		align-items: center;
-		flex-wrap: wrap;
+	display: flex;
+	flex-direction: column;
 
-		.inner {
-			width: 50%;
-			padding: 20px;
+	.filter-container {
+		.filter-item {
+			display: inline-block;
+			vertical-align: middle;
+			margin-bottom: 10px;
 		}
 	}
 
-	.botTitle {
-		color: red;
-		text-align: center;
+	.small-padding {
+		.cell {
+			padding-left: 5px;
+			padding-right: 5px;
+		}
 	}
-}
-
-.statistics {
-	display: flex;
-	align-items: center;
-	justify-content: space-around;
-	width: 100%;
-	margin: 10px 0 15px;
-
-	.statistics-item {
-		text-align: center;
 
-		h1 {
-			color: #ffae11;
-			font-size: 20px;
+	.fixed-width {
+		.el-button--mini {
+			padding: 7px 10px;
 		}
 	}
 }
-
-.dialog-pagination {
-	display: flex;
-	align-items: center;
-	justify-content: center;
-	margin-top: 15px;
-}
 </style>

+ 0 - 13
src/views/finance/withdrawal/components/LedgerInformation.vue

@@ -199,18 +199,5 @@ export default {
 		padding: 7px 10px;
 	}
 }
-
-.small-padding {
-	.cell {
-		padding-left: 5px;
-		padding-right: 5px;
-	}
-}
-
-.fixed-width {
-	.el-button--mini {
-		padding: 7px 10px;
-	}
-}
 </style>
 

+ 58 - 105
src/views/login/index.vue

@@ -64,17 +64,11 @@
               />
             </el-form-item>
             <el-form-item prop="code">
-              <el-input
-                v-model="anthorForm.code" maxlength="6" type="text" class="iptHeight"
-                auto-complete="off"
-                style="width: 63%" placeholder="请输入验证码" @keyup.enter.native="anhandleLogin"
-              />
-              <div class="login-code">
-                <el-button class="codeBtn" type="primary" :loading="codeloading" @click="getCode(anthorForm.username)">
-                  <span v-if="!codeloading">获取验证码</span>
-                  <span v-else>{{ count }} s</span>
-                </el-button>
-              </div>
+              <GraphicVerificationCode
+                :phone="anthorForm.username"
+                @input="(e) => anthorForm.code = e"
+                @enter-down="anhandleLogin"
+              ></GraphicVerificationCode>
             </el-form-item>
             <div class="boxBottom">
               <el-checkbox v-model="loginForm.rememberMe" style="margin: 0 0 25px 0">自动登录</el-checkbox>
@@ -98,66 +92,60 @@
     <div v-else class="loginBoxs">
       <div class="topback">找回密码</div>
       <el-card class="box-card">
-        <div slot="header" class="clearfix">
-          <span style="margin-left: 25px">找回密码</span>
-          <el-button
-            style="float: right; padding: 3px 0" type="text" @click=" {
-              getPassword = true;
-            }
-            "
-          >
-            返回登录
-          </el-button>
-          <div class="cardBox">
-            <el-form
-              ref="forgotForm" :model="forgotPasswordForm" :rules="forgotPasswordRules" label-position="left"
-              label-width="0px" class="login-form"
+        <template #header>
+          <div class="clearfix">
+            <span style="margin-left: 25px">找回密码</span>
+            <el-button
+              style="float: right; padding: 3px 0" type="text" @click=" {
+                getPassword = true;
+              }
+              "
             >
-              <el-form-item prop="phone">
-                <el-input
-                  v-model="forgotPasswordForm.phone" type="text" maxlength="11" auto-complete="off"
-                  placeholder="请输入手机号码" class="iptHeight"
-                />
-              </el-form-item>
-              <el-form-item prop="code">
-                <el-input
-                  v-model="forgotPasswordForm.code" maxlength="6" type="text" class="iptHeight"
-                  auto-complete="off" style="width: 63%" placeholder="请输入验证码"
-                />
-                <div class="login-code">
+              返回登录
+            </el-button>
+            <div class="cardBox">
+              <el-form
+                ref="forgotForm" :model="forgotPasswordForm" :rules="forgotPasswordRules" label-position="left"
+                label-width="0px" class="login-form"
+              >
+                <el-form-item prop="phone">
+                  <el-input
+                    v-model="forgotPasswordForm.phone" type="text" maxlength="11" auto-complete="off"
+                    placeholder="请输入手机号码" class="iptHeight"
+                  />
+                </el-form-item>
+                <el-form-item prop="code">
+                  <GraphicVerificationCode
+                    :phone="forgotPasswordForm.phone"
+                    @input="(e) => forgotPasswordForm.code = e"
+                    @enter-down="anhandleLogin"
+                  ></GraphicVerificationCode>
+                </el-form-item>
+                <el-form-item prop="password">
+                  <el-input
+                    v-model="forgotPasswordForm.password" type="password" maxlength="16" auto-complete="off"
+                    placeholder="请输入密码" class="iptHeight"
+                  />
+                </el-form-item>
+                <el-form-item prop="newPassword">
+                  <el-input
+                    v-model="forgotPasswordForm.newPassword" type="password" maxlength="16" auto-complete="off"
+                    placeholder="请再次输入密码" class="iptHeight"
+                  />
+                </el-form-item>
+                <el-form-item style="width: 100%">
                   <el-button
-                    class="codeBtn" type="primary" :loading="codeloading"
-                    @click="getCode(forgotPasswordForm.phone)"
+                    :loading="loading" size="medium" type="primary" style="width: 100%; border-radius: 20px"
+                    @click.native.prevent="resetPassword"
                   >
-                    <span v-if="!codeloading">获取验证码</span>
-                    <span v-else>{{ count }} s</span>
+                    <span v-if="!loading">重 置 密 码</span>
+                    <span v-else>重 置 中...</span>
                   </el-button>
-                </div>
-              </el-form-item>
-              <el-form-item prop="password">
-                <el-input
-                  v-model="forgotPasswordForm.password" type="password" maxlength="16" auto-complete="off"
-                  placeholder="请输入密码" class="iptHeight"
-                />
-              </el-form-item>
-              <el-form-item prop="newPassword">
-                <el-input
-                  v-model="forgotPasswordForm.newPassword" type="password" maxlength="16" auto-complete="off"
-                  placeholder="请再次输入密码" class="iptHeight"
-                />
-              </el-form-item>
-              <el-form-item style="width: 100%">
-                <el-button
-                  :loading="loading" size="medium" type="primary" style="width: 100%; border-radius: 20px"
-                  @click.native.prevent="resetPassword"
-                >
-                  <span v-if="!loading">重 置 密 码</span>
-                  <span v-else>重 置 中...</span>
-                </el-button>
-              </el-form-item>
-            </el-form>
+                </el-form-item>
+              </el-form>
+            </div>
           </div>
-        </div>
+        </template>
       </el-card>
     </div>
     <!--  底部  -->
@@ -166,11 +154,13 @@
 </template>
 
 <script>
-import { getCode } from '@/api/user'
-const TIME_COUNT = 60 // 更改倒计时时间
+import GraphicVerificationCode from '@/components/GraphicVerificationCode/index.vue'
 const JM = require('@/utils/rsaEncrypt.js')
 export default {
   name: 'Login',
+  components: {
+    GraphicVerificationCode
+  },
   data() {
     var validateNewPassword = (rule, value, callback) => {
       if (value !== this.forgotPasswordForm.password) {
@@ -240,9 +230,6 @@ export default {
         ]
       },
       loading: false,
-      codeloading: false,
-      count: '',
-      timer: null,
       redirect: null,
       getPassword: true
     }
@@ -260,40 +247,6 @@ export default {
     touchTab(index) {
       this.tabIndex = index
     },
-    // 获取验证码
-    async getCode(phone) {
-      console.log(phone)
-      if (phone === '' || phone === undefined) {
-        this.$message.error('请填写电话号码')
-        return
-      }
-      if (/^1[3456789]\d{9}$/.test(phone) === false) {
-        this.$message.error('请填写正确手机号')
-        return false
-      }
-      if (!this.timer) {
-        this.codeloading = true
-        this.count = TIME_COUNT
-        this.show = false
-        const res = await getCode({ phone })
-        if (res.code === '') {
-          this.$message({
-            message: '发送成功,请注意查看手机短信',
-            type: 'success'
-          })
-        }
-        this.timer = setInterval(() => {
-          if (this.count > 0 && this.count <= TIME_COUNT) {
-            this.count--
-          } else {
-            this.show = true
-            clearInterval(this.timer) // 清除定时器
-            this.timer = null
-            this.codeloading = false
-          }
-        }, 1000)
-      }
-    },
     // 忘记密码
     runForgetPassord() {
       this.getPassword = false

+ 1 - 1
src/views/renovation/commoditySystem/components/AddSelection.vue

@@ -194,7 +194,7 @@ export default {
       if (params.productId) {
         this.getInfo(params.productId)
       }
-      this.$refs.formData && this.$refs.formData.resetFields()
+      // this.$refs.formData && this.$refs.formData.resetFields()
     },
     async getInfo(id) {
       const loading = this.$loading({ text: '加载中' })

+ 1 - 1
src/views/renovation/commoditySystem/components/VirtualSales.vue

@@ -67,12 +67,12 @@ export default {
     },
     handleOpen(params = {}) {
       this.modalOptions.title = '自定义虚拟销量'
+      this.$refs.formData && this.$refs.formData.resetFields()
       this.formData.productId = params.productId
       this.formData.fictitiousNumber = params.fictitiousNumber || 0
       // this.formData = Object.assign(this.$options.data().formData, params)
       this.visible = true
       this.initList()
-      this.$refs.formData && this.$refs.formData.resetFields()
     },
     handleSubmit() {
       this.$refs.formData.validate(async (valid) => {

+ 4 - 4
src/views/renovation/commoditySystem/index.vue

@@ -124,7 +124,7 @@
     <!-- 设置虚拟销量 -->
     <VirtualSales ref="VirtualSales" @success="getList" />
     <!-- 加入选品 -->
-    <AddSelection ref="AddSelection" @success="getList" :isCopy="isCopy" @changeIsCopy="isCopy=false" />
+    <AddSelection ref="AddSelection" :is-copy="isCopy" @success="getList" @changeIsCopy="isCopy = false" />
     <!-- 查看详情 -->
     <DetailModal ref="DetailModal" />
   </div>
@@ -163,7 +163,7 @@ export default {
         pageSize: 20
       },
       //   控制是否是复制商品
-      isCopy:false,
+      isCopy: false
     }
   },
   created() {
@@ -185,7 +185,7 @@ export default {
       this.getList()
     },
     handleReset() {
-      this.listQuery = { shelveState: '', productName: '', productId: '', shopName: '', page: 1, pageSize: 5 }
+      this.listQuery = { shelveState: '', productName: '', productId: '', shopName: '', page: 1, pageSize: 20 }
       this.getList()
     },
     handleDetail(row) {
@@ -201,7 +201,7 @@ export default {
         .catch(() => { })
     },
     //  复制商品
-    copyShelf(row){
+    copyShelf(row) {
       this.$refs.AddSelection && this.$refs.AddSelection.handleOpen(row)
       this.isCopy = true
     },

+ 9 - 44
src/views/setup/phone/index.vue

@@ -13,11 +13,11 @@
           <el-input v-model="ruleForm.newPhone" maxlength="11" style="width: 70%" placeholder="请输入新手机号" />
         </el-form-item>
         <el-form-item label="验证码" prop="code">
-          <el-input v-model="ruleForm.code" maxlength="6" style="width: 40%; margin-right: 38px" placeholder="请输入验证码" />
-          <el-button class="codeBtn" type="primary" :loading="codeloading" @click="getCode(oldPhone)">
-            <span v-if="!codeloading">获取验证码</span>
-            <span v-else>{{ count }} s</span>
-          </el-button>
+          <GraphicVerificationCode
+            api-type="update"
+            :phone="ruleForm.newPhone"
+            @input="(e) => ruleForm.code = e"
+          ></GraphicVerificationCode>
         </el-form-item>
         <el-form-item>
           <el-button type="primary" @click="submint"> 确定 </el-button>
@@ -28,14 +28,16 @@
 </template>
 
 <script>
+import GraphicVerificationCode from '@/components/GraphicVerificationCode/index.vue'
 import {
   getAdminPhone,
-  getUpdatePhoneCode,
   updatePhone
 } from '@/api/privacy'
 const JM = require('@/utils/rsaEncrypt.js')
-const TIME_COUNT = 120 // 更改倒计时时间
 export default {
+  components: {
+    GraphicVerificationCode
+  },
   data() {
     // 旧手机号
     const oldPhone = (rule, value, callback) => {
@@ -73,9 +75,6 @@ export default {
         newPhone: [ { required: true, validator: newPhone, trigger: 'blur' } ],
         code: [ { required: true, validator: code, trigger: 'blur' } ]
       },
-      codeloading: false,
-      count: '',
-      timer: null,
       privacyTime: 0
     }
   },
@@ -91,40 +90,6 @@ export default {
         this.oldPhone = res.data
       })
     },
-    // 获取验证码
-    async getCode(phone) {
-      console.log(phone)
-      if (phone === '' || phone === undefined) {
-        this.$message.error('请填写新手机号')
-        return
-      }
-      if (/^1[3456789]\d{9}$/.test(phone) === false) {
-        this.$message.error('请填写正确手机号')
-        return false
-      }
-      if (!this.timer) {
-        this.codeloading = true
-        this.count = TIME_COUNT
-        this.show = false
-        const res = await getUpdatePhoneCode({ phone })
-        if (res.code === '') {
-          this.$message({
-            message: '发送成功,请注意查看手机短信',
-            type: 'success'
-          })
-        }
-        this.timer = setInterval(() => {
-          if (this.count > 0 && this.count <= TIME_COUNT) {
-            this.count--
-          } else {
-            this.show = true
-            clearInterval(this.timer) // 清除定时器
-            this.timer = null
-            this.codeloading = false
-          }
-        }, 1000)
-      }
-    },
     submint() {
       if (this.ruleForm.newPhone === '' || this.ruleForm.newPhone === undefined) {
         this.$message.error('请填写新手机号')

+ 9 - 46
src/views/setup/privacy/index.vue

@@ -13,11 +13,11 @@
           <el-input v-else v-model="ruleForm.newPhone" disabled style="width: 70%" placeholder="请输入管理员电话" />
         </el-form-item>
         <el-form-item label="验证码" prop="code">
-          <el-input v-model="ruleForm.code" maxlength="6" style="width: 40%; margin-right: 38px" placeholder="请输入验证码" />
-          <el-button class="codeBtn" type="primary" :loading="codeloading" @click="getCode(ruleForm.newPhone)">
-            <span v-if="!codeloading">获取验证码</span>
-            <span v-else>{{ count }} s</span>
-          </el-button>
+          <GraphicVerificationCode
+            api-type="update"
+            :phone="ruleForm.newPhone"
+            @input="(e) => ruleForm.code = e"
+          ></GraphicVerificationCode>
         </el-form-item>
         <el-form-item>
           <el-button type="primary" @click="submint(ruleForm.newPhone)">
@@ -30,14 +30,16 @@
 </template>
 
 <script>
+import GraphicVerificationCode from '@/components/GraphicVerificationCode/index.vue'
 import {
   getAdminPhone,
-  getPrivacyCode,
   verifyPrivacyCode
 } from '@/api/privacy'
-const TIME_COUNT = 120 // 更改倒计时时间
 const JM = require('@/utils/rsaEncrypt.js')
 export default {
+  components: {
+    GraphicVerificationCode
+  },
   data() {
     // 管理员手机号码
     const newPhone = (rule, value, callback) => {
@@ -65,9 +67,6 @@ export default {
         newPhone: [ { required: true, validator: newPhone, trigger: 'blur' } ],
         code: [ { required: true, validator: code, trigger: 'blur' } ]
       },
-      codeloading: false,
-      count: '',
-      timer: null,
       privacyTime: 0,
       now_time: ''
     }
@@ -99,44 +98,8 @@ export default {
         // this.newPhone = res.data.substr(0, 3) + "****" + res.data.substr(7);
       })
     },
-    // 获取验证码
-    async getCode(phone) {
-      console.log(phone)
-      if (phone === '' || phone === undefined) {
-        this.$message.error('请填写手机号')
-        return
-      }
-      if (/^1[3456789]\d{9}$/.test(phone) === false) {
-        this.$message.error('请填写正确手机号')
-        return false
-      }
-      if (!this.timer) {
-        this.codeloading = true
-        this.count = TIME_COUNT
-        this.show = false
-        const res = await getPrivacyCode({ phone })
-        if (res.code === '') {
-          this.$message({
-            message: '发送成功,请注意查看手机短信',
-            type: 'success'
-          })
-        }
-        this.timer = setInterval(() => {
-          if (this.count > 0 && this.count <= TIME_COUNT) {
-            this.count--
-          } else {
-            this.show = true
-            clearInterval(this.timer) // 清除定时器
-            this.timer = null
-            this.codeloading = false
-          }
-        }, 1000)
-      }
-    },
     // 确定
     async submint() {
-      this.timer = null
-      this.codeloading = false
       if (this.ruleForm.code === '' || this.ruleForm.code === undefined) {
         this.$message.error('请填写验证码')
         return