Browse Source

Merge branch 'dev' of http://git.dgtis.com/sunlupeng/pointsMall-admin

sunlupeng 1 year ago
parent
commit
2f0de076c4
45 changed files with 6121 additions and 280 deletions
  1. 1 0
      .gitignore
  2. 1 1
      config/index.js
  3. 12 0
      src/api/answerGame.js
  4. 26 0
      src/api/commendManage.js
  5. 41 0
      src/api/couponsManage.js
  6. 32 5
      src/api/public.js
  7. 83 0
      src/api/raffleManage.js
  8. 161 0
      src/components/Crontab/day.vue
  9. 114 0
      src/components/Crontab/hour.vue
  10. 430 0
      src/components/Crontab/index.vue
  11. 116 0
      src/components/Crontab/min.vue
  12. 114 0
      src/components/Crontab/month.vue
  13. 559 0
      src/components/Crontab/result.vue
  14. 117 0
      src/components/Crontab/second.vue
  15. 202 0
      src/components/Crontab/week.vue
  16. 131 0
      src/components/Crontab/year.vue
  17. 181 0
      src/components/SkuDesc/index.vue
  18. 7 0
      src/components/SkuDesc/plugins.js
  19. 6 0
      src/components/SkuDesc/toolbar.js
  20. 1 1
      src/main.js
  21. 28 2
      src/permission.js
  22. 44 0
      src/router/index.js
  23. 180 19
      src/views/activityManage/activityList.vue
  24. 165 0
      src/views/answerGame/answerList.vue
  25. 354 0
      src/views/commendManage/ceoCiteList.vue
  26. 251 0
      src/views/commendManage/citeList.vue
  27. 1 1
      src/views/commendManage/commendDataList.vue
  28. 332 0
      src/views/commendManage/operateCiteList.vue
  29. 482 0
      src/views/couponsManage/couponsList.vue
  30. 1 1
      src/views/dictManage/dictDataList.vue
  31. 1 1
      src/views/dictManage/dictList.vue
  32. 5 0
      src/views/exchangeManage/approvalList.vue
  33. 5 0
      src/views/exchangeManage/cancelledList.vue
  34. 5 0
      src/views/exchangeManage/exchangeList.vue
  35. 5 0
      src/views/exchangeManage/pasList.vue
  36. 5 0
      src/views/exchangeManage/voidList.vue
  37. 698 0
      src/views/giftManage/giftList copy.vue
  38. 183 240
      src/views/giftManage/giftList.vue
  39. 76 6
      src/views/goodsManage/goodsList.vue
  40. 1 1
      src/views/noticeManage/noticeList.vue
  41. 469 0
      src/views/raffleManage/raffleDataList.vue
  42. 347 0
      src/views/raffleManage/raffleList.vue
  43. 146 0
      src/views/raffleManage/raffleLogsList.vue
  44. 1 1
      src/views/sys/admin.vue
  45. 1 1
      static/tinymce4.7.11/skins/lightgray/skin.min.css

+ 1 - 0
.gitignore

@@ -2,6 +2,7 @@
 node_modules/
 dist/
 dist-admin.zip*
+dist-admin.7z*
 npm-debug.log*
 yarn-debug.log*
 yarn-error.log*

+ 1 - 1
config/index.js

@@ -14,7 +14,7 @@ module.exports = {
 
     // Various Dev Server settings
     // host: 'localhost', // can be overwritten by process.env.HOST
-    host: '192.168.100.185', // can be overwritten by process.env.HOST
+    host: '192.168.100.73', // can be overwritten by process.env.HOST
     port: 8081, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
     autoOpenBrowser: true,
     errorOverlay: true,

+ 12 - 0
src/api/answerGame.js

@@ -0,0 +1,12 @@
+import request from '@/utils/request'
+
+export function answerList(query) {
+  return request({
+    url: '/answer/list',
+    method: 'get',
+    params:query
+  })
+}
+
+
+

+ 26 - 0
src/api/commendManage.js

@@ -73,3 +73,29 @@ export function dataRemove(query) {
   })
 }
 
+// 客户表彰审批列表
+export function customerPage(query) {
+  return request({
+    url: '/customer/commend/page',
+    method: 'get',
+    params:query
+  })
+}
+
+// 客户表彰审批
+export function complete(query) {
+  return request({
+    url: '/customer/commend/complete',
+    method: 'post',
+    params:query
+  })
+}
+
+// 客户表彰详情
+export function detail(query) {
+  return request({
+    url: '/customer/commend/info',
+    method: 'get',
+    params:query
+  })
+}

+ 41 - 0
src/api/couponsManage.js

@@ -0,0 +1,41 @@
+import request from '@/utils/request'
+
+export function createItem(data) {
+  return request({
+    url: '/coupon/add',
+    method: 'post',
+    data
+  })
+}
+
+export function updateItem(data) {
+  return request({
+    url: '/coupon/edit',
+    method: 'post',
+    data
+  })
+}
+
+export function list(query) {
+  return request({
+    url: '/coupon/list',
+    method: 'get',
+    params:query
+  })
+}
+
+export function deleteitem(query) {
+  return request({
+    url: '/coupon/modify',
+    method: 'post',
+    params:query
+  })
+}
+
+export function optionSelect(data) {
+  return request({
+    url: '/system/dict/type/optionselect',
+    method: 'get',
+    data
+  })
+}

+ 32 - 5
src/api/public.js

@@ -1,5 +1,5 @@
 import request from '@/utils/request'
-
+// 添加规则
 export function rulesDetail(query) {
   return request({
     url: '/news/mall/getNotice',
@@ -7,7 +7,7 @@ export function rulesDetail(query) {
     params: query
   })
 }
-
+// 更新规则
 export function updateRule(query) {
   return request({
     url: '/news/update',
@@ -15,7 +15,7 @@ export function updateRule(query) {
     data: query
   })
 }
-
+// 获取全部公司
 export function companyTypeList(query) {
     return request({
       url: '/sys/user/getCompanys',
@@ -23,7 +23,7 @@ export function companyTypeList(query) {
       params:query
     })
   }
-  
+  // 获取全部部门
   export function depTypeList(query) {
     return request({
       url: '/sys/user/getDepts',
@@ -31,7 +31,7 @@ export function companyTypeList(query) {
       params:query
     })
   }
-
+  //获取全部用户
   export function allUserList(query) {
     return request({
       url: '/sys/user/getAll',
@@ -48,3 +48,30 @@ export function companyTypeList(query) {
       params:query
     })
   }
+  // 获取全部商品
+  export function goodsList(query) {
+    return request({
+      url: '/mall-sku/integral/optionselect',
+      method: 'get',
+      params:query
+    })
+  }
+// 获取已开启兑换券下拉
+export function couponsList(query) {
+  return request({
+    url: '/coupon/actOptionselect',
+    method: 'get',
+    params:query
+  })
+}
+
+// 获取已开启奖池下拉
+export function prizePoolList(query) {
+  return request({
+    url: '/mall-pool-type/actOptionselect',
+    method: 'get',
+    params:query
+  })
+}
+  
+  

+ 83 - 0
src/api/raffleManage.js

@@ -0,0 +1,83 @@
+import request from '@/utils/request'
+
+export function createItem(data) {
+  return request({
+    url: '/mall-pool-type/add',
+    method: 'post',
+    data
+  })
+}
+
+export function updateItem(data) {
+  return request({
+    url: '/mall-pool-type/edit',
+    method: 'post',
+    data
+  })
+}
+
+export function list(query) {
+  return request({
+    url: '/mall-pool-type/list',
+    method: 'get',
+    params:query
+  })
+}
+
+export function deleteitem(query) {
+  return request({
+    url: '/mall-pool-type/remove',
+    method: 'post',
+    params:query
+  })
+}
+
+export function optionSelect(data) {
+  return request({
+    url: '/mall-pool-type/optionselect',
+    method: 'get',
+    data
+  })
+}
+export function dataList(query) {
+  return request({
+    url: '/mall-pool-data/list',
+    method: 'get',
+    params:query
+  })
+}
+export function dataAdd(data) {
+  return request({
+    url: '/mall-pool-data/add',
+    method: 'post',
+    data
+  })
+}
+export function dataEdit(data) {
+  return request({
+    url: '/mall-pool-data/edit',
+    method: 'post',
+    data
+  })
+}
+export function dataRemove(query) {
+  return request({
+    url: '/mall-pool-data/remove',
+    method: 'post',
+    params:query
+  })
+}
+
+export function logsList(query) {
+  return request({
+    url: '/mall-prize/prize/log',
+    method: 'get',
+    params:query
+  })
+}
+
+
+
+
+
+

+ 161 - 0
src/components/Crontab/day.vue

@@ -0,0 +1,161 @@
+<template>
+	<el-form size="small">
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="1">
+				日,允许的通配符[, - * ? / L W]
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="2">
+				不指定
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="3">
+				周期从
+				<el-input-number v-model='cycle01' :min="1" :max="30" /> -
+				<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 2" :max="31" /> 日
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="4">
+				从
+				<el-input-number v-model='average01' :min="1" :max="30" /> 号开始,每
+				<el-input-number v-model='average02' :min="1" :max="31 - average01 || 1" /> 日执行一次
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="5">
+				每月
+				<el-input-number v-model='workday' :min="1" :max="31" /> 号最近的那个工作日
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="6">
+				本月最后一天
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="7">
+				指定
+				<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
+					<el-option v-for="item in 31" :key="item" :value="item">{{item}}</el-option>
+				</el-select>
+			</el-radio>
+		</el-form-item>
+	</el-form>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			radioValue: 1,
+			workday: 1,
+			cycle01: 1,
+			cycle02: 2,
+			average01: 1,
+			average02: 1,
+			checkboxList: [],
+			checkNum: this.$options.propsData.check
+		}
+	},
+	name: 'crontab-day',
+	props: ['check', 'cron'],
+	methods: {
+		// 单选按钮值变化时
+		radioChange() {
+			('day rachange');
+			if (this.radioValue !== 2 && this.cron.week !== '?') {
+				this.$emit('update', 'week', '?', 'day')
+			}
+
+			switch (this.radioValue) {
+				case 1:
+					this.$emit('update', 'day', '*');
+					break;
+				case 2:
+					this.$emit('update', 'day', '?');
+					break;
+				case 3:
+					this.$emit('update', 'day', this.cycleTotal);
+					break;
+				case 4:
+					this.$emit('update', 'day', this.averageTotal);
+					break;
+				case 5:
+					this.$emit('update', 'day', this.workday + 'W');
+					break;
+				case 6:
+					this.$emit('update', 'day', 'L');
+					break;
+				case 7:
+					this.$emit('update', 'day', this.checkboxString);
+					break;
+			}
+			('day rachange end');
+		},
+		// 周期两个值变化时
+		cycleChange() {
+			if (this.radioValue == '3') {
+				this.$emit('update', 'day', this.cycleTotal);
+			}
+		},
+		// 平均两个值变化时
+		averageChange() {
+			if (this.radioValue == '4') {
+				this.$emit('update', 'day', this.averageTotal);
+			}
+		},
+		// 最近工作日值变化时
+		workdayChange() {
+			if (this.radioValue == '5') {
+				this.$emit('update', 'day', this.workdayCheck + 'W');
+			}
+		},
+		// checkbox值变化时
+		checkboxChange() {
+			if (this.radioValue == '7') {
+				this.$emit('update', 'day', this.checkboxString);
+			}
+		}
+	},
+	watch: {
+		'radioValue': 'radioChange',
+		'cycleTotal': 'cycleChange',
+		'averageTotal': 'averageChange',
+		'workdayCheck': 'workdayChange',
+		'checkboxString': 'checkboxChange',
+	},
+	computed: {
+		// 计算两个周期值
+		cycleTotal: function () {
+			const cycle01 = this.checkNum(this.cycle01, 1, 30)
+			const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 2, 31, 31)
+			return cycle01 + '-' + cycle02;
+		},
+		// 计算平均用到的值
+		averageTotal: function () {
+			const average01 = this.checkNum(this.average01, 1, 30)
+			const average02 = this.checkNum(this.average02, 1, 31 - average01 || 0)
+			return average01 + '/' + average02;
+		},
+		// 计算工作日格式
+		workdayCheck: function () {
+			const workday = this.checkNum(this.workday, 1, 31)
+			return workday;
+		},
+		// 计算勾选的checkbox值合集
+		checkboxString: function () {
+			let str = this.checkboxList.join();
+			return str == '' ? '*' : str;
+		}
+	}
+}
+</script>

+ 114 - 0
src/components/Crontab/hour.vue

@@ -0,0 +1,114 @@
+<template>
+	<el-form size="small">
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="1">
+				小时,允许的通配符[, - * /]
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="2">
+				周期从
+				<el-input-number v-model='cycle01' :min="0" :max="22" /> -
+				<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 1" :max="23" /> 小时
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="3">
+				从
+				<el-input-number v-model='average01' :min="0" :max="22" /> 小时开始,每
+				<el-input-number v-model='average02' :min="1" :max="23 - average01 || 0" /> 小时执行一次
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="4">
+				指定
+				<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
+					<el-option v-for="item in 24" :key="item" :value="item-1">{{item-1}}</el-option>
+				</el-select>
+			</el-radio>
+		</el-form-item>
+	</el-form>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			radioValue: 1,
+			cycle01: 0,
+			cycle02: 1,
+			average01: 0,
+			average02: 1,
+			checkboxList: [],
+			checkNum: this.$options.propsData.check
+		}
+	},
+	name: 'crontab-hour',
+	props: ['check', 'cron'],
+	methods: {
+		// 单选按钮值变化时
+		radioChange() {
+			switch (this.radioValue) {
+				case 1:
+        	this.$emit('update', 'hour', '*')
+        	break;
+				case 2:
+					this.$emit('update', 'hour', this.cycleTotal);
+					break;
+				case 3:
+					this.$emit('update', 'hour', this.averageTotal);
+					break;
+				case 4:
+					this.$emit('update', 'hour', this.checkboxString);
+					break;
+			}
+		},
+		// 周期两个值变化时
+		cycleChange() {
+			if (this.radioValue == '2') {
+				this.$emit('update', 'hour', this.cycleTotal);
+			}
+		},
+		// 平均两个值变化时
+		averageChange() {
+			if (this.radioValue == '3') {
+				this.$emit('update', 'hour', this.averageTotal);
+			}
+		},
+		// checkbox值变化时
+		checkboxChange() {
+			if (this.radioValue == '4') {
+				this.$emit('update', 'hour', this.checkboxString);
+			}
+		}
+	},
+	watch: {
+		'radioValue': 'radioChange',
+		'cycleTotal': 'cycleChange',
+		'averageTotal': 'averageChange',
+		'checkboxString': 'checkboxChange'
+	},
+	computed: {
+		// 计算两个周期值
+		cycleTotal: function () {
+			const cycle01 = this.checkNum(this.cycle01, 0, 22)
+			const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 1, 23)
+			return cycle01 + '-' + cycle02;
+		},
+		// 计算平均用到的值
+		averageTotal: function () {
+			const average01 = this.checkNum(this.average01, 0, 22)
+			const average02 = this.checkNum(this.average02, 1, 23 - average01 || 0)
+			return average01 + '/' + average02;
+		},
+		// 计算勾选的checkbox值合集
+		checkboxString: function () {
+			let str = this.checkboxList.join();
+			return str == '' ? '*' : str;
+		}
+	}
+}
+</script>

+ 430 - 0
src/components/Crontab/index.vue

@@ -0,0 +1,430 @@
+<template>
+  <div>
+    <el-tabs type="border-card">
+      <el-tab-pane label="秒" v-if="shouldHide('second')">
+        <CrontabSecond
+          @update="updateCrontabValue"
+          :check="checkNumber"
+          :cron="crontabValueObj"
+          ref="cronsecond"
+        />
+      </el-tab-pane>
+
+      <el-tab-pane label="分钟" v-if="shouldHide('min')">
+        <CrontabMin
+          @update="updateCrontabValue"
+          :check="checkNumber"
+          :cron="crontabValueObj"
+          ref="cronmin"
+        />
+      </el-tab-pane>
+
+      <el-tab-pane label="小时" v-if="shouldHide('hour')">
+        <CrontabHour
+          @update="updateCrontabValue"
+          :check="checkNumber"
+          :cron="crontabValueObj"
+          ref="cronhour"
+        />
+      </el-tab-pane>
+
+      <el-tab-pane label="日" v-if="shouldHide('day')">
+        <CrontabDay
+          @update="updateCrontabValue"
+          :check="checkNumber"
+          :cron="crontabValueObj"
+          ref="cronday"
+        />
+      </el-tab-pane>
+
+      <el-tab-pane label="月" v-if="shouldHide('month')">
+        <CrontabMonth
+          @update="updateCrontabValue"
+          :check="checkNumber"
+          :cron="crontabValueObj"
+          ref="cronmonth"
+        />
+      </el-tab-pane>
+
+      <el-tab-pane label="周" v-if="shouldHide('week')">
+        <CrontabWeek
+          @update="updateCrontabValue"
+          :check="checkNumber"
+          :cron="crontabValueObj"
+          ref="cronweek"
+        />
+      </el-tab-pane>
+
+      <el-tab-pane label="年" v-if="shouldHide('year')">
+        <CrontabYear
+          @update="updateCrontabValue"
+          :check="checkNumber"
+          :cron="crontabValueObj"
+          ref="cronyear"
+        />
+      </el-tab-pane>
+    </el-tabs>
+
+    <div class="popup-main">
+      <div class="popup-result">
+        <p class="title">时间表达式</p>
+        <table>
+          <thead>
+            <th v-for="item of tabTitles" width="40" :key="item">{{item}}</th>
+            <th>Cron 表达式</th>
+          </thead>
+          <tbody>
+            <td>
+              <span>{{crontabValueObj.second}}</span>
+            </td>
+            <td>
+              <span>{{crontabValueObj.min}}</span>
+            </td>
+            <td>
+              <span>{{crontabValueObj.hour}}</span>
+            </td>
+            <td>
+              <span>{{crontabValueObj.day}}</span>
+            </td>
+            <td>
+              <span>{{crontabValueObj.month}}</span>
+            </td>
+            <td>
+              <span>{{crontabValueObj.week}}</span>
+            </td>
+            <td>
+              <span>{{crontabValueObj.year}}</span>
+            </td>
+            <td>
+              <span>{{crontabValueString}}</span>
+            </td>
+          </tbody>
+        </table>
+      </div>
+      <!-- <CrontabResult :ex="crontabValueString"></CrontabResult> -->
+
+      <div class="pop_btn">
+        <el-button size="small" type="primary" @click="submitFill">确定</el-button>
+        <el-button size="small" type="warning" @click="clearCron">重置</el-button>
+        <el-button size="small" @click="hidePopup">取消</el-button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import CrontabSecond from "./second.vue";
+import CrontabMin from "./min.vue";
+import CrontabHour from "./hour.vue";
+import CrontabDay from "./day.vue";
+import CrontabMonth from "./month.vue";
+import CrontabWeek from "./week.vue";
+import CrontabYear from "./year.vue";
+import CrontabResult from "./result.vue";
+
+export default {
+  data() {
+    return {
+      tabTitles: ["秒", "分钟", "小时", "日", "月", "周", "年"],
+      tabActive: 0,
+      myindex: 0,
+      crontabValueObj: {
+        second: "*",
+        min: "*",
+        hour: "*",
+        day: "*",
+        month: "*",
+        week: "?",
+        year: "",
+      },
+    };
+  },
+  name: "vcrontab",
+  props: ["expression", "hideComponent"],
+  methods: {
+    shouldHide(key) {
+      if (this.hideComponent && this.hideComponent.includes(key)) return false;
+      return true;
+    },
+    resolveExp() {
+      // 反解析 表达式
+      if (this.expression) {
+        let arr = this.expression.split(" ");
+        if (arr.length >= 6) {
+          //6 位以上是合法表达式
+          let obj = {
+            second: arr[0],
+            min: arr[1],
+            hour: arr[2],
+            day: arr[3],
+            month: arr[4],
+            week: arr[5],
+            year: arr[6] ? arr[6] : "",
+          };
+          this.crontabValueObj = {
+            ...obj,
+          };
+          for (let i in obj) {
+            if (obj[i]) this.changeRadio(i, obj[i]);
+          }
+        }
+      } else {
+        // 没有传入的表达式 则还原
+        this.clearCron();
+      }
+    },
+    // tab切换值
+    tabCheck(index) {
+      this.tabActive = index;
+    },
+    // 由子组件触发,更改表达式组成的字段值
+    updateCrontabValue(name, value, from) {
+      "updateCrontabValue", name, value, from;
+      this.crontabValueObj[name] = value;
+      if (from && from !== name) {
+        console.log(`来自组件 ${from} 改变了 ${name} ${value}`);
+        this.changeRadio(name, value);
+      }
+    },
+    // 赋值到组件
+    changeRadio(name, value) {
+      let arr = ["second", "min", "hour", "month"],
+        refName = "cron" + name,
+        insValue;
+
+      if (!this.$refs[refName]) return;
+
+      if (arr.includes(name)) {
+        if (value === "*") {
+          insValue = 1;
+        } else if (value.indexOf("-") > -1) {
+          let indexArr = value.split("-");
+          isNaN(indexArr[0])
+            ? (this.$refs[refName].cycle01 = 0)
+            : (this.$refs[refName].cycle01 = indexArr[0]);
+          this.$refs[refName].cycle02 = indexArr[1];
+          insValue = 2;
+        } else if (value.indexOf("/") > -1) {
+          let indexArr = value.split("/");
+          isNaN(indexArr[0])
+            ? (this.$refs[refName].average01 = 0)
+            : (this.$refs[refName].average01 = indexArr[0]);
+          this.$refs[refName].average02 = indexArr[1];
+          insValue = 3;
+        } else {
+          insValue = 4;
+          this.$refs[refName].checkboxList = value.split(",");
+        }
+      } else if (name == "day") {
+        if (value === "*") {
+          insValue = 1;
+        } else if (value == "?") {
+          insValue = 2;
+        } else if (value.indexOf("-") > -1) {
+          let indexArr = value.split("-");
+          isNaN(indexArr[0])
+            ? (this.$refs[refName].cycle01 = 0)
+            : (this.$refs[refName].cycle01 = indexArr[0]);
+          this.$refs[refName].cycle02 = indexArr[1];
+          insValue = 3;
+        } else if (value.indexOf("/") > -1) {
+          let indexArr = value.split("/");
+          isNaN(indexArr[0])
+            ? (this.$refs[refName].average01 = 0)
+            : (this.$refs[refName].average01 = indexArr[0]);
+          this.$refs[refName].average02 = indexArr[1];
+          insValue = 4;
+        } else if (value.indexOf("W") > -1) {
+          let indexArr = value.split("W");
+          isNaN(indexArr[0])
+            ? (this.$refs[refName].workday = 0)
+            : (this.$refs[refName].workday = indexArr[0]);
+          insValue = 5;
+        } else if (value === "L") {
+          insValue = 6;
+        } else {
+          this.$refs[refName].checkboxList = value.split(",");
+          insValue = 7;
+        }
+      } else if (name == "week") {
+        if (value === "*") {
+          insValue = 1;
+        } else if (value == "?") {
+          insValue = 2;
+        } else if (value.indexOf("-") > -1) {
+          let indexArr = value.split("-");
+          isNaN(indexArr[0])
+            ? (this.$refs[refName].cycle01 = 0)
+            : (this.$refs[refName].cycle01 = indexArr[0]);
+          this.$refs[refName].cycle02 = indexArr[1];
+          insValue = 3;
+        } else if (value.indexOf("#") > -1) {
+          let indexArr = value.split("#");
+          isNaN(indexArr[0])
+            ? (this.$refs[refName].average01 = 1)
+            : (this.$refs[refName].average01 = indexArr[0]);
+          this.$refs[refName].average02 = indexArr[1];
+          insValue = 4;
+        } else if (value.indexOf("L") > -1) {
+          let indexArr = value.split("L");
+          isNaN(indexArr[0])
+            ? (this.$refs[refName].weekday = 1)
+            : (this.$refs[refName].weekday = indexArr[0]);
+          insValue = 5;
+        } else {
+          this.$refs[refName].checkboxList = value.split(",");
+          insValue = 6;
+        }
+      } else if (name == "year") {
+        if (value == "") {
+          insValue = 1;
+        } else if (value == "*") {
+          insValue = 2;
+        } else if (value.indexOf("-") > -1) {
+          insValue = 3;
+        } else if (value.indexOf("/") > -1) {
+          insValue = 4;
+        } else {
+          this.$refs[refName].checkboxList = value.split(",");
+          insValue = 5;
+        }
+      }
+      this.$refs[refName].radioValue = insValue;
+    },
+    // 表单选项的子组件校验数字格式(通过-props传递)
+    checkNumber(value, minLimit, maxLimit) {
+      // 检查必须为整数
+      value = Math.floor(value);
+      if (value < minLimit) {
+        value = minLimit;
+      } else if (value > maxLimit) {
+        value = maxLimit;
+      }
+      return value;
+    },
+    // 隐藏弹窗
+    hidePopup() {
+      this.$emit("hide");
+    },
+    // 填充表达式
+    submitFill() {
+      this.$emit("fill", this.crontabValueString);
+      this.hidePopup();
+    },
+    clearCron() {
+      // 还原选择项
+      ("准备还原");
+      this.crontabValueObj = {
+        second: "*",
+        min: "*",
+        hour: "*",
+        day: "*",
+        month: "*",
+        week: "?",
+        year: "",
+      };
+      for (let j in this.crontabValueObj) {
+        this.changeRadio(j, this.crontabValueObj[j]);
+      }
+    },
+  },
+  computed: {
+    crontabValueString: function() {
+      let obj = this.crontabValueObj;
+      let str =
+        obj.second +
+        " " +
+        obj.min +
+        " " +
+        obj.hour +
+        " " +
+        obj.day +
+        " " +
+        obj.month +
+        " " +
+        obj.week +
+        (obj.year == "" ? "" : " " + obj.year);
+      return str;
+    },
+  },
+  components: {
+    CrontabSecond,
+    CrontabMin,
+    CrontabHour,
+    CrontabDay,
+    CrontabMonth,
+    CrontabWeek,
+    CrontabYear,
+    CrontabResult,
+  },
+  watch: {
+    expression: "resolveExp",
+    hideComponent(value) {
+      // 隐藏部分组件
+    },
+  },
+  mounted: function() {
+    this.resolveExp();
+  },
+};
+</script>
+<style scoped>
+.pop_btn {
+  text-align: center;
+  margin-top: 20px;
+}
+.popup-main {
+  position: relative;
+  margin: 10px auto;
+  background: #fff;
+  border-radius: 5px;
+  font-size: 12px;
+  overflow: hidden;
+}
+.popup-title {
+  overflow: hidden;
+  line-height: 34px;
+  padding-top: 6px;
+  background: #f2f2f2;
+}
+.popup-result {
+  box-sizing: border-box;
+  line-height: 24px;
+  margin: 25px auto;
+  padding: 15px 10px 10px;
+  border: 1px solid #ccc;
+  position: relative;
+}
+.popup-result .title {
+  position: absolute;
+  top: -28px;
+  left: 50%;
+  width: 140px;
+  font-size: 14px;
+  margin-left: -70px;
+  text-align: center;
+  line-height: 30px;
+  background: #fff;
+}
+.popup-result table {
+  text-align: center;
+  width: 100%;
+  margin: 0 auto;
+}
+.popup-result table span {
+  display: block;
+  width: 100%;
+  font-family: arial;
+  line-height: 30px;
+  height: 30px;
+  white-space: nowrap;
+  overflow: hidden;
+  border: 1px solid #e8e8e8;
+}
+.popup-result-scroll {
+  font-size: 12px;
+  line-height: 24px;
+  height: 10em;
+  overflow-y: auto;
+}
+</style>

+ 116 - 0
src/components/Crontab/min.vue

@@ -0,0 +1,116 @@
+<template>
+	<el-form size="small">
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="1">
+				分钟,允许的通配符[, - * /]
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="2">
+				周期从
+				<el-input-number v-model='cycle01' :min="0" :max="58" /> -
+				<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 1" :max="59" /> 分钟
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="3">
+				从
+				<el-input-number v-model='average01' :min="0" :max="58" /> 分钟开始,每
+				<el-input-number v-model='average02' :min="1" :max="59 - average01 || 0" /> 分钟执行一次
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="4">
+				指定
+				<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
+					<el-option v-for="item in 60" :key="item" :value="item-1">{{item-1}}</el-option>
+				</el-select>
+			</el-radio>
+		</el-form-item>
+	</el-form>
+
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			radioValue: 1,
+			cycle01: 1,
+			cycle02: 2,
+			average01: 0,
+			average02: 1,
+			checkboxList: [],
+			checkNum: this.$options.propsData.check
+		}
+	},
+	name: 'crontab-min',
+	props: ['check', 'cron'],
+	methods: {
+		// 单选按钮值变化时
+		radioChange() {
+			switch (this.radioValue) {
+				case 1:
+					this.$emit('update', 'min', '*', 'min');
+					break;
+				case 2:
+					this.$emit('update', 'min', this.cycleTotal, 'min');
+					break;
+				case 3:
+					this.$emit('update', 'min', this.averageTotal, 'min');
+					break;
+				case 4:
+					this.$emit('update', 'min', this.checkboxString, 'min');
+					break;
+			}
+		},
+		// 周期两个值变化时
+		cycleChange() {
+			if (this.radioValue == '2') {
+				this.$emit('update', 'min', this.cycleTotal, 'min');
+			}
+		},
+		// 平均两个值变化时
+		averageChange() {
+			if (this.radioValue == '3') {
+				this.$emit('update', 'min', this.averageTotal, 'min');
+			}
+		},
+		// checkbox值变化时
+		checkboxChange() {
+			if (this.radioValue == '4') {
+				this.$emit('update', 'min', this.checkboxString, 'min');
+			}
+		},
+
+	},
+	watch: {
+		'radioValue': 'radioChange',
+		'cycleTotal': 'cycleChange',
+		'averageTotal': 'averageChange',
+		'checkboxString': 'checkboxChange',
+	},
+	computed: {
+		// 计算两个周期值
+		cycleTotal: function () {
+			const cycle01 = this.checkNum(this.cycle01, 0, 58)
+			const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 1, 59)
+			return cycle01 + '-' + cycle02;
+		},
+		// 计算平均用到的值
+		averageTotal: function () {
+			const average01 = this.checkNum(this.average01, 0, 58)
+			const average02 = this.checkNum(this.average02, 1, 59 - average01 || 0)
+			return average01 + '/' + average02;
+		},
+		// 计算勾选的checkbox值合集
+		checkboxString: function () {
+			let str = this.checkboxList.join();
+			return str == '' ? '*' : str;
+		}
+	}
+}
+</script>

+ 114 - 0
src/components/Crontab/month.vue

@@ -0,0 +1,114 @@
+<template>
+	<el-form size='small'>
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="1">
+				月,允许的通配符[, - * /]
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="2">
+				周期从
+				<el-input-number v-model='cycle01' :min="1" :max="11" /> -
+				<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 2" :max="12" /> 月
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="3">
+				从
+				<el-input-number v-model='average01' :min="1" :max="11" /> 月开始,每
+				<el-input-number v-model='average02' :min="1" :max="12 - average01 || 0" /> 月月执行一次
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="4">
+				指定
+				<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
+					<el-option v-for="item in 12" :key="item" :value="item">{{item}}</el-option>
+				</el-select>
+			</el-radio>
+		</el-form-item>
+	</el-form>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			radioValue: 1,
+			cycle01: 1,
+			cycle02: 2,
+			average01: 1,
+			average02: 1,
+			checkboxList: [],
+			checkNum: this.check
+		}
+	},
+	name: 'crontab-month',
+	props: ['check', 'cron'],
+	methods: {
+		// 单选按钮值变化时
+		radioChange() {
+			switch (this.radioValue) {
+				case 1:
+					this.$emit('update', 'month', '*');
+					break;
+				case 2:
+					this.$emit('update', 'month', this.cycleTotal);
+					break;
+				case 3:
+					this.$emit('update', 'month', this.averageTotal);
+					break;
+				case 4:
+					this.$emit('update', 'month', this.checkboxString);
+					break;
+			}
+		},
+		// 周期两个值变化时
+		cycleChange() {
+			if (this.radioValue == '2') {
+				this.$emit('update', 'month', this.cycleTotal);
+			}
+		},
+		// 平均两个值变化时
+		averageChange() {
+			if (this.radioValue == '3') {
+				this.$emit('update', 'month', this.averageTotal);
+			}
+		},
+		// checkbox值变化时
+		checkboxChange() {
+			if (this.radioValue == '4') {
+				this.$emit('update', 'month', this.checkboxString);
+			}
+		}
+	},
+	watch: {
+		'radioValue': 'radioChange',
+		'cycleTotal': 'cycleChange',
+		'averageTotal': 'averageChange',
+		'checkboxString': 'checkboxChange'
+	},
+	computed: {
+		// 计算两个周期值
+		cycleTotal: function () {
+			const cycle01 = this.checkNum(this.cycle01, 1, 11)
+			const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 2, 12)
+			return cycle01 + '-' + cycle02;
+		},
+		// 计算平均用到的值
+		averageTotal: function () {
+			const average01 = this.checkNum(this.average01, 1, 11)
+			const average02 = this.checkNum(this.average02, 1, 12 - average01 || 0)
+			return average01 + '/' + average02;
+		},
+		// 计算勾选的checkbox值合集
+		checkboxString: function () {
+			let str = this.checkboxList.join();
+			return str == '' ? '*' : str;
+		}
+	}
+}
+</script>

+ 559 - 0
src/components/Crontab/result.vue

@@ -0,0 +1,559 @@
+<template>
+	<div class="popup-result">
+		<p class="title">最近5次运行时间</p>
+		<ul class="popup-result-scroll">
+			<template v-if='isShow'>
+				<li v-for='item in resultList' :key="item">{{item}}</li>
+			</template>
+			<li v-else>计算结果中...</li>
+		</ul>
+	</div>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			dayRule: '',
+			dayRuleSup: '',
+			dateArr: [],
+			resultList: [],
+			isShow: false
+		}
+	},
+	name: 'crontab-result',
+	methods: {
+		// 表达式值变化时,开始去计算结果
+		expressionChange() {
+
+			// 计算开始-隐藏结果
+			this.isShow = false;
+			// 获取规则数组[0秒、1分、2时、3日、4月、5星期、6年]
+			let ruleArr = this.$options.propsData.ex.split(' ');
+			// 用于记录进入循环的次数
+			let nums = 0;
+			// 用于暂时存符号时间规则结果的数组
+			let resultArr = [];
+			// 获取当前时间精确至[年、月、日、时、分、秒]
+			let nTime = new Date();
+			let nYear = nTime.getFullYear();
+			let nMonth = nTime.getMonth() + 1;
+			let nDay = nTime.getDate();
+			let nHour = nTime.getHours();
+			let nMin = nTime.getMinutes();
+			let nSecond = nTime.getSeconds();
+			// 根据规则获取到近100年可能年数组、月数组等等
+			this.getSecondArr(ruleArr[0]);
+			this.getMinArr(ruleArr[1]);
+			this.getHourArr(ruleArr[2]);
+			this.getDayArr(ruleArr[3]);
+			this.getMonthArr(ruleArr[4]);
+			this.getWeekArr(ruleArr[5]);
+			this.getYearArr(ruleArr[6], nYear);
+			// 将获取到的数组赋值-方便使用
+			let sDate = this.dateArr[0];
+			let mDate = this.dateArr[1];
+			let hDate = this.dateArr[2];
+			let DDate = this.dateArr[3];
+			let MDate = this.dateArr[4];
+			let YDate = this.dateArr[5];
+			// 获取当前时间在数组中的索引
+			let sIdx = this.getIndex(sDate, nSecond);
+			let mIdx = this.getIndex(mDate, nMin);
+			let hIdx = this.getIndex(hDate, nHour);
+			let DIdx = this.getIndex(DDate, nDay);
+			let MIdx = this.getIndex(MDate, nMonth);
+			let YIdx = this.getIndex(YDate, nYear);
+			// 重置月日时分秒的函数(后面用的比较多)
+			const resetSecond = function () {
+				sIdx = 0;
+				nSecond = sDate[sIdx]
+			}
+			const resetMin = function () {
+				mIdx = 0;
+				nMin = mDate[mIdx]
+				resetSecond();
+			}
+			const resetHour = function () {
+				hIdx = 0;
+				nHour = hDate[hIdx]
+				resetMin();
+			}
+			const resetDay = function () {
+				DIdx = 0;
+				nDay = DDate[DIdx]
+				resetHour();
+			}
+			const resetMonth = function () {
+				MIdx = 0;
+				nMonth = MDate[MIdx]
+				resetDay();
+			}
+			// 如果当前年份不为数组中当前值
+			if (nYear !== YDate[YIdx]) {
+				resetMonth();
+			}
+			// 如果当前月份不为数组中当前值
+			if (nMonth !== MDate[MIdx]) {
+				resetDay();
+			}
+			// 如果当前“日”不为数组中当前值
+			if (nDay !== DDate[DIdx]) {
+				resetHour();
+			}
+			// 如果当前“时”不为数组中当前值
+			if (nHour !== hDate[hIdx]) {
+				resetMin();
+			}
+			// 如果当前“分”不为数组中当前值
+			if (nMin !== mDate[mIdx]) {
+				resetSecond();
+			}
+
+			// 循环年份数组
+			goYear: for (let Yi = YIdx; Yi < YDate.length; Yi++) {
+				let YY = YDate[Yi];
+				// 如果到达最大值时
+				if (nMonth > MDate[MDate.length - 1]) {
+					resetMonth();
+					continue;
+				}
+				// 循环月份数组
+				goMonth: for (let Mi = MIdx; Mi < MDate.length; Mi++) {
+					// 赋值、方便后面运算
+					let MM = MDate[Mi];
+					MM = MM < 10 ? '0' + MM : MM;
+					// 如果到达最大值时
+					if (nDay > DDate[DDate.length - 1]) {
+						resetDay();
+						if (Mi == MDate.length - 1) {
+							resetMonth();
+							continue goYear;
+						}
+						continue;
+					}
+					// 循环日期数组
+					goDay: for (let Di = DIdx; Di < DDate.length; Di++) {
+						// 赋值、方便后面运算
+						let DD = DDate[Di];
+						let thisDD = DD < 10 ? '0' + DD : DD;
+
+						// 如果到达最大值时
+						if (nHour > hDate[hDate.length - 1]) {
+							resetHour();
+							if (Di == DDate.length - 1) {
+								resetDay();
+								if (Mi == MDate.length - 1) {
+									resetMonth();
+									continue goYear;
+								}
+								continue goMonth;
+							}
+							continue;
+						}
+
+						// 判断日期的合法性,不合法的话也是跳出当前循环
+						if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true && this.dayRule !== 'workDay' && this.dayRule !== 'lastWeek' && this.dayRule !== 'lastDay') {
+							resetDay();
+							continue goMonth;
+						}
+						// 如果日期规则中有值时
+						if (this.dayRule == 'lastDay') {
+							// 如果不是合法日期则需要将前将日期调到合法日期即月末最后一天
+
+							if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
+								while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
+									DD--;
+
+									thisDD = DD < 10 ? '0' + DD : DD;
+								}
+							}
+						} else if (this.dayRule == 'workDay') {
+							// 校验并调整如果是2月30号这种日期传进来时需调整至正常月底
+							if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
+								while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
+									DD--;
+									thisDD = DD < 10 ? '0' + DD : DD;
+								}
+							}
+							// 获取达到条件的日期是星期X
+							let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week');
+							// 当星期日时
+							if (thisWeek == 1) {
+								// 先找下一个日,并判断是否为月底
+								DD++;
+								thisDD = DD < 10 ? '0' + DD : DD;
+								// 判断下一日已经不是合法日期
+								if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
+									DD -= 3;
+								}
+							} else if (thisWeek == 7) {
+								// 当星期6时只需判断不是1号就可进行操作
+								if (this.dayRuleSup !== 1) {
+									DD--;
+								} else {
+									DD += 2;
+								}
+							}
+						} else if (this.dayRule == 'weekDay') {
+							// 如果指定了是星期几
+							// 获取当前日期是属于星期几
+							let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week');
+							// 校验当前星期是否在星期池(dayRuleSup)中
+							if (this.dayRuleSup.indexOf(thisWeek) < 0) {
+								// 如果到达最大值时
+								if (Di == DDate.length - 1) {
+									resetDay();
+									if (Mi == MDate.length - 1) {
+										resetMonth();
+										continue goYear;
+									}
+									continue goMonth;
+								}
+								continue;
+							}
+						} else if (this.dayRule == 'assWeek') {
+							// 如果指定了是第几周的星期几
+							// 获取每月1号是属于星期几
+							let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + DD + ' 00:00:00'), 'week');
+							if (this.dayRuleSup[1] >= thisWeek) {
+								DD = (this.dayRuleSup[0] - 1) * 7 + this.dayRuleSup[1] - thisWeek + 1;
+							} else {
+								DD = this.dayRuleSup[0] * 7 + this.dayRuleSup[1] - thisWeek + 1;
+							}
+						} else if (this.dayRule == 'lastWeek') {
+							// 如果指定了每月最后一个星期几
+							// 校验并调整如果是2月30号这种日期传进来时需调整至正常月底
+							if (this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
+								while (DD > 0 && this.checkDate(YY + '-' + MM + '-' + thisDD + ' 00:00:00') !== true) {
+									DD--;
+									thisDD = DD < 10 ? '0' + DD : DD;
+								}
+							}
+							// 获取月末最后一天是星期几
+							let thisWeek = this.formatDate(new Date(YY + '-' + MM + '-' + thisDD + ' 00:00:00'), 'week');
+							// 找到要求中最近的那个星期几
+							if (this.dayRuleSup < thisWeek) {
+								DD -= thisWeek - this.dayRuleSup;
+							} else if (this.dayRuleSup > thisWeek) {
+								DD -= 7 - (this.dayRuleSup - thisWeek)
+							}
+						}
+						// 判断时间值是否小于10置换成“05”这种格式
+						DD = DD < 10 ? '0' + DD : DD;
+
+						// 循环“时”数组
+						goHour: for (let hi = hIdx; hi < hDate.length; hi++) {
+							let hh = hDate[hi] < 10 ? '0' + hDate[hi] : hDate[hi]
+
+							// 如果到达最大值时
+							if (nMin > mDate[mDate.length - 1]) {
+								resetMin();
+								if (hi == hDate.length - 1) {
+									resetHour();
+									if (Di == DDate.length - 1) {
+										resetDay();
+										if (Mi == MDate.length - 1) {
+											resetMonth();
+											continue goYear;
+										}
+										continue goMonth;
+									}
+									continue goDay;
+								}
+								continue;
+							}
+							// 循环"分"数组
+							goMin: for (let mi = mIdx; mi < mDate.length; mi++) {
+								let mm = mDate[mi] < 10 ? '0' + mDate[mi] : mDate[mi];
+
+								// 如果到达最大值时
+								if (nSecond > sDate[sDate.length - 1]) {
+									resetSecond();
+									if (mi == mDate.length - 1) {
+										resetMin();
+										if (hi == hDate.length - 1) {
+											resetHour();
+											if (Di == DDate.length - 1) {
+												resetDay();
+												if (Mi == MDate.length - 1) {
+													resetMonth();
+													continue goYear;
+												}
+												continue goMonth;
+											}
+											continue goDay;
+										}
+										continue goHour;
+									}
+									continue;
+								}
+								// 循环"秒"数组
+								goSecond: for (let si = sIdx; si <= sDate.length - 1; si++) {
+									let ss = sDate[si] < 10 ? '0' + sDate[si] : sDate[si];
+									// 添加当前时间(时间合法性在日期循环时已经判断)
+									if (MM !== '00' && DD !== '00') {
+										resultArr.push(YY + '-' + MM + '-' + DD + ' ' + hh + ':' + mm + ':' + ss)
+										nums++;
+									}
+									// 如果条数满了就退出循环
+									if (nums == 5) break goYear;
+									// 如果到达最大值时
+									if (si == sDate.length - 1) {
+										resetSecond();
+										if (mi == mDate.length - 1) {
+											resetMin();
+											if (hi == hDate.length - 1) {
+												resetHour();
+												if (Di == DDate.length - 1) {
+													resetDay();
+													if (Mi == MDate.length - 1) {
+														resetMonth();
+														continue goYear;
+													}
+													continue goMonth;
+												}
+												continue goDay;
+											}
+											continue goHour;
+										}
+										continue goMin;
+									}
+								} //goSecond
+							} //goMin
+						}//goHour
+					}//goDay
+				}//goMonth
+			}
+			// 判断100年内的结果条数
+			if (resultArr.length == 0) {
+				this.resultList = ['没有达到条件的结果!'];
+			} else {
+				this.resultList = resultArr;
+				if (resultArr.length !== 5) {
+					this.resultList.push('最近100年内只有上面' + resultArr.length + '条结果!')
+				}
+			}
+			// 计算完成-显示结果
+			this.isShow = true;
+
+
+		},
+		// 用于计算某位数字在数组中的索引
+		getIndex(arr, value) {
+			if (value <= arr[0] || value > arr[arr.length - 1]) {
+				return 0;
+			} else {
+				for (let i = 0; i < arr.length - 1; i++) {
+					if (value > arr[i] && value <= arr[i + 1]) {
+						return i + 1;
+					}
+				}
+			}
+		},
+		// 获取"年"数组
+		getYearArr(rule, year) {
+			this.dateArr[5] = this.getOrderArr(year, year + 100);
+			if (rule !== undefined) {
+				if (rule.indexOf('-') >= 0) {
+					this.dateArr[5] = this.getCycleArr(rule, year + 100, false)
+				} else if (rule.indexOf('/') >= 0) {
+					this.dateArr[5] = this.getAverageArr(rule, year + 100)
+				} else if (rule !== '*') {
+					this.dateArr[5] = this.getAssignArr(rule)
+				}
+			}
+		},
+		// 获取"月"数组
+		getMonthArr(rule) {
+			this.dateArr[4] = this.getOrderArr(1, 12);
+			if (rule.indexOf('-') >= 0) {
+				this.dateArr[4] = this.getCycleArr(rule, 12, false)
+			} else if (rule.indexOf('/') >= 0) {
+				this.dateArr[4] = this.getAverageArr(rule, 12)
+			} else if (rule !== '*') {
+				this.dateArr[4] = this.getAssignArr(rule)
+			}
+		},
+		// 获取"日"数组-主要为日期规则
+		getWeekArr(rule) {
+			// 只有当日期规则的两个值均为“”时则表达日期是有选项的
+			if (this.dayRule == '' && this.dayRuleSup == '') {
+				if (rule.indexOf('-') >= 0) {
+					this.dayRule = 'weekDay';
+					this.dayRuleSup = this.getCycleArr(rule, 7, false)
+				} else if (rule.indexOf('#') >= 0) {
+					this.dayRule = 'assWeek';
+					let matchRule = rule.match(/[0-9]{1}/g);
+					this.dayRuleSup = [Number(matchRule[1]), Number(matchRule[0])];
+					this.dateArr[3] = [1];
+					if (this.dayRuleSup[1] == 7) {
+						this.dayRuleSup[1] = 0;
+					}
+				} else if (rule.indexOf('L') >= 0) {
+					this.dayRule = 'lastWeek';
+					this.dayRuleSup = Number(rule.match(/[0-9]{1,2}/g)[0]);
+					this.dateArr[3] = [31];
+					if (this.dayRuleSup == 7) {
+						this.dayRuleSup = 0;
+					}
+				} else if (rule !== '*' && rule !== '?') {
+					this.dayRule = 'weekDay';
+					this.dayRuleSup = this.getAssignArr(rule)
+				}
+			}
+		},
+		// 获取"日"数组-少量为日期规则
+		getDayArr(rule) {
+			this.dateArr[3] = this.getOrderArr(1, 31);
+			this.dayRule = '';
+			this.dayRuleSup = '';
+			if (rule.indexOf('-') >= 0) {
+				this.dateArr[3] = this.getCycleArr(rule, 31, false)
+				this.dayRuleSup = 'null';
+			} else if (rule.indexOf('/') >= 0) {
+				this.dateArr[3] = this.getAverageArr(rule, 31)
+				this.dayRuleSup = 'null';
+			} else if (rule.indexOf('W') >= 0) {
+				this.dayRule = 'workDay';
+				this.dayRuleSup = Number(rule.match(/[0-9]{1,2}/g)[0]);
+				this.dateArr[3] = [this.dayRuleSup];
+			} else if (rule.indexOf('L') >= 0) {
+				this.dayRule = 'lastDay';
+				this.dayRuleSup = 'null';
+				this.dateArr[3] = [31];
+			} else if (rule !== '*' && rule !== '?') {
+				this.dateArr[3] = this.getAssignArr(rule)
+				this.dayRuleSup = 'null';
+			} else if (rule == '*') {
+				this.dayRuleSup = 'null';
+			}
+		},
+		// 获取"时"数组
+		getHourArr(rule) {
+			this.dateArr[2] = this.getOrderArr(0, 23);
+			if (rule.indexOf('-') >= 0) {
+				this.dateArr[2] = this.getCycleArr(rule, 24, true)
+			} else if (rule.indexOf('/') >= 0) {
+				this.dateArr[2] = this.getAverageArr(rule, 23)
+			} else if (rule !== '*') {
+				this.dateArr[2] = this.getAssignArr(rule)
+			}
+		},
+		// 获取"分"数组
+		getMinArr(rule) {
+			this.dateArr[1] = this.getOrderArr(0, 59);
+			if (rule.indexOf('-') >= 0) {
+				this.dateArr[1] = this.getCycleArr(rule, 60, true)
+			} else if (rule.indexOf('/') >= 0) {
+				this.dateArr[1] = this.getAverageArr(rule, 59)
+			} else if (rule !== '*') {
+				this.dateArr[1] = this.getAssignArr(rule)
+			}
+		},
+		// 获取"秒"数组
+		getSecondArr(rule) {
+			this.dateArr[0] = this.getOrderArr(0, 59);
+			if (rule.indexOf('-') >= 0) {
+				this.dateArr[0] = this.getCycleArr(rule, 60, true)
+			} else if (rule.indexOf('/') >= 0) {
+				this.dateArr[0] = this.getAverageArr(rule, 59)
+			} else if (rule !== '*') {
+				this.dateArr[0] = this.getAssignArr(rule)
+			}
+		},
+		// 根据传进来的min-max返回一个顺序的数组
+		getOrderArr(min, max) {
+			let arr = [];
+			for (let i = min; i <= max; i++) {
+				arr.push(i);
+			}
+			return arr;
+		},
+		// 根据规则中指定的零散值返回一个数组
+		getAssignArr(rule) {
+			let arr = [];
+			let assiginArr = rule.split(',');
+			for (let i = 0; i < assiginArr.length; i++) {
+				arr[i] = Number(assiginArr[i])
+			}
+			arr.sort(this.compare)
+			return arr;
+		},
+		// 根据一定算术规则计算返回一个数组
+		getAverageArr(rule, limit) {
+			let arr = [];
+			let agArr = rule.split('/');
+			let min = Number(agArr[0]);
+			let step = Number(agArr[1]);
+			while (min <= limit) {
+				arr.push(min);
+				min += step;
+			}
+			return arr;
+		},
+		// 根据规则返回一个具有周期性的数组
+		getCycleArr(rule, limit, status) {
+			// status--表示是否从0开始(则从1开始)
+			let arr = [];
+			let cycleArr = rule.split('-');
+			let min = Number(cycleArr[0]);
+			let max = Number(cycleArr[1]);
+			if (min > max) {
+				max += limit;
+			}
+			for (let i = min; i <= max; i++) {
+				let add = 0;
+				if (status == false && i % limit == 0) {
+					add = limit;
+				}
+				arr.push(Math.round(i % limit + add))
+			}
+			arr.sort(this.compare)
+			return arr;
+		},
+		// 比较数字大小(用于Array.sort)
+		compare(value1, value2) {
+			if (value2 - value1 > 0) {
+				return -1;
+			} else {
+				return 1;
+			}
+		},
+		// 格式化日期格式如:2017-9-19 18:04:33
+		formatDate(value, type) {
+			// 计算日期相关值
+			let time = typeof value == 'number' ? new Date(value) : value;
+			let Y = time.getFullYear();
+			let M = time.getMonth() + 1;
+			let D = time.getDate();
+			let h = time.getHours();
+			let m = time.getMinutes();
+			let s = time.getSeconds();
+			let week = time.getDay();
+			// 如果传递了type的话
+			if (type == undefined) {
+				return Y + '-' + (M < 10 ? '0' + M : M) + '-' + (D < 10 ? '0' + D : D) + ' ' + (h < 10 ? '0' + h : h) + ':' + (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
+			} else if (type == 'week') {
+				// 在quartz中 1为星期日
+				return week + 1;
+			}
+		},
+		// 检查日期是否存在
+		checkDate(value) {
+			let time = new Date(value);
+			let format = this.formatDate(time)
+			return value === format;
+		}
+	},
+	watch: {
+		'ex': 'expressionChange'
+	},
+	props: ['ex'],
+	mounted: function () {
+		// 初始化 获取一次结果
+		this.expressionChange();
+	}
+}
+
+</script>

+ 117 - 0
src/components/Crontab/second.vue

@@ -0,0 +1,117 @@
+<template>
+	<el-form size="small">
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="1">
+				秒,允许的通配符[, - * /]
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="2">
+				周期从
+				<el-input-number v-model='cycle01' :min="0" :max="58" /> -
+				<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : 1" :max="59" /> 秒
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="3">
+				从
+				<el-input-number v-model='average01' :min="0" :max="58" /> 秒开始,每
+				<el-input-number v-model='average02' :min="1" :max="59 - average01 || 0" /> 秒执行一次
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="4">
+				指定
+				<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
+					<el-option v-for="item in 60" :key="item" :value="item-1">{{item-1}}</el-option>
+				</el-select>
+			</el-radio>
+		</el-form-item>
+	</el-form>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			radioValue: 1,
+			cycle01: 1,
+			cycle02: 2,
+			average01: 0,
+			average02: 1,
+			checkboxList: [],
+			checkNum: this.$options.propsData.check
+		}
+	},
+	name: 'crontab-second',
+	props: ['check', 'radioParent'],
+	methods: {
+		// 单选按钮值变化时
+		radioChange() {
+			switch (this.radioValue) {
+				case 1:
+					this.$emit('update', 'second', '*', 'second');
+					break;
+				case 2:
+					this.$emit('update', 'second', this.cycleTotal);
+					break;
+				case 3:
+					this.$emit('update', 'second', this.averageTotal);
+					break;
+				case 4:
+					this.$emit('update', 'second', this.checkboxString);
+					break;
+			}
+		},
+		// 周期两个值变化时
+		cycleChange() {
+			if (this.radioValue == '2') {
+				this.$emit('update', 'second', this.cycleTotal);
+			}
+		},
+		// 平均两个值变化时
+		averageChange() {
+			if (this.radioValue == '3') {
+				this.$emit('update', 'second', this.averageTotal);
+			}
+		},
+		// checkbox值变化时
+		checkboxChange() {
+			if (this.radioValue == '4') {
+				this.$emit('update', 'second', this.checkboxString);
+			}
+		}
+	},
+	watch: {
+		'radioValue': 'radioChange',
+		'cycleTotal': 'cycleChange',
+		'averageTotal': 'averageChange',
+		'checkboxString': 'checkboxChange',
+		radioParent() {
+			this.radioValue = this.radioParent
+		}
+	},
+	computed: {
+		// 计算两个周期值
+		cycleTotal: function () {
+			const cycle01 = this.checkNum(this.cycle01, 0, 58)
+			const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : 1, 59)
+			return cycle01 + '-' + cycle02;
+		},
+		// 计算平均用到的值
+		averageTotal: function () {
+			const average01 = this.checkNum(this.average01, 0, 58)
+			const average02 = this.checkNum(this.average02, 1, 59 - average01 || 0)
+			return average01 + '/' + average02;
+		},
+		// 计算勾选的checkbox值合集
+		checkboxString: function () {
+			let str = this.checkboxList.join();
+			return str == '' ? '*' : str;
+		}
+	}
+}
+</script>

+ 202 - 0
src/components/Crontab/week.vue

@@ -0,0 +1,202 @@
+<template>
+	<el-form size='small'>
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="1">
+				周,允许的通配符[, - * ? / L #]
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="2">
+				不指定
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="3">
+				周期从星期
+				<el-select clearable v-model="cycle01">
+					<el-option
+						v-for="(item,index) of weekList"
+						:key="index"
+						:label="item.value"
+						:value="item.key"
+						:disabled="item.key === 1"
+					>{{item.value}}</el-option>
+				</el-select>
+				-
+				<el-select clearable v-model="cycle02">
+					<el-option
+						v-for="(item,index) of weekList"
+						:key="index"
+						:label="item.value"
+						:value="item.key"
+						:disabled="item.key < cycle01 && item.key !== 1"
+					>{{item.value}}</el-option>
+				</el-select>
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="4">
+				第
+				<el-input-number v-model='average01' :min="1" :max="4" /> 周的星期
+				<el-select clearable v-model="average02">
+					<el-option v-for="(item,index) of weekList" :key="index" :label="item.value" :value="item.key">{{item.value}}</el-option>
+				</el-select>
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="5">
+				本月最后一个星期
+				<el-select clearable v-model="weekday">
+					<el-option v-for="(item,index) of weekList" :key="index" :label="item.value" :value="item.key">{{item.value}}</el-option>
+				</el-select>
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio v-model='radioValue' :label="6">
+				指定
+				<el-select clearable v-model="checkboxList" placeholder="可多选" multiple style="width:100%">
+					<el-option v-for="(item,index) of weekList" :key="index" :label="item.value" :value="String(item.key)">{{item.value}}</el-option>
+				</el-select>
+			</el-radio>
+		</el-form-item>
+
+	</el-form>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			radioValue: 2,
+			weekday: 2,
+			cycle01: 2,
+			cycle02: 3,
+			average01: 1,
+			average02: 2,
+			checkboxList: [],
+			weekList: [
+				{
+					key: 2,
+					value: '星期一'
+				},
+				{
+					key: 3,
+					value: '星期二'
+				},
+				{
+					key: 4,
+					value: '星期三'
+				},
+				{
+					key: 5,
+					value: '星期四'
+				},
+				{
+					key: 6,
+					value: '星期五'
+				},
+				{
+					key: 7,
+					value: '星期六'
+				},
+				{
+					key: 1,
+					value: '星期日'
+				}
+			],
+			checkNum: this.$options.propsData.check
+		}
+	},
+	name: 'crontab-week',
+	props: ['check', 'cron'],
+	methods: {
+		// 单选按钮值变化时
+		radioChange() {
+			if (this.radioValue !== 2 && this.cron.day !== '?') {
+				this.$emit('update', 'day', '?', 'week');
+			}
+			switch (this.radioValue) {
+				case 1:
+					this.$emit('update', 'week', '*');
+					break;
+				case 2:
+					this.$emit('update', 'week', '?');
+					break;
+				case 3:
+					this.$emit('update', 'week', this.cycleTotal);
+					break;
+				case 4:
+					this.$emit('update', 'week', this.averageTotal);
+					break;
+				case 5:
+					this.$emit('update', 'week', this.weekdayCheck + 'L');
+					break;
+				case 6:
+					this.$emit('update', 'week', this.checkboxString);
+					break;
+			}
+		},
+
+		// 周期两个值变化时
+		cycleChange() {
+			if (this.radioValue == '3') {
+				this.$emit('update', 'week', this.cycleTotal);
+			}
+		},
+		// 平均两个值变化时
+		averageChange() {
+			if (this.radioValue == '4') {
+				this.$emit('update', 'week', this.averageTotal);
+			}
+		},
+		// 最近工作日值变化时
+		weekdayChange() {
+			if (this.radioValue == '5') {
+				this.$emit('update', 'week', this.weekday + 'L');
+			}
+		},
+		// checkbox值变化时
+		checkboxChange() {
+			if (this.radioValue == '6') {
+				this.$emit('update', 'week', this.checkboxString);
+			}
+		},
+	},
+	watch: {
+		'radioValue': 'radioChange',
+		'cycleTotal': 'cycleChange',
+		'averageTotal': 'averageChange',
+		'weekdayCheck': 'weekdayChange',
+		'checkboxString': 'checkboxChange',
+	},
+	computed: {
+		// 计算两个周期值
+		cycleTotal: function () {
+			this.cycle01 = this.checkNum(this.cycle01, 1, 7)
+			this.cycle02 = this.checkNum(this.cycle02, 1, 7)
+			return this.cycle01 + '-' + this.cycle02;
+		},
+		// 计算平均用到的值
+		averageTotal: function () {
+			this.average01 = this.checkNum(this.average01, 1, 4)
+			this.average02 = this.checkNum(this.average02, 1, 7)
+			return this.average02 + '#' + this.average01;
+		},
+		// 最近的工作日(格式)
+		weekdayCheck: function () {
+			this.weekday = this.checkNum(this.weekday, 1, 7)
+			return this.weekday;
+		},
+		// 计算勾选的checkbox值合集
+		checkboxString: function () {
+			let str = this.checkboxList.join();
+			return str == '' ? '*' : str;
+		}
+	}
+}
+</script>

+ 131 - 0
src/components/Crontab/year.vue

@@ -0,0 +1,131 @@
+<template>
+	<el-form size="small">
+		<el-form-item>
+			<el-radio :label="1" v-model='radioValue'>
+				不填,允许的通配符[, - * /]
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio :label="2" v-model='radioValue'>
+				每年
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio :label="3" v-model='radioValue'>
+				周期从
+				<el-input-number v-model='cycle01' :min='fullYear' :max="2098" /> -
+				<el-input-number v-model='cycle02' :min="cycle01 ? cycle01 + 1 : fullYear + 1" :max="2099" />
+			</el-radio>
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio :label="4" v-model='radioValue'>
+				从
+				<el-input-number v-model='average01' :min='fullYear' :max="2098"/> 年开始,每
+				<el-input-number v-model='average02' :min="1" :max="2099 - average01 || fullYear" /> 年执行一次
+			</el-radio>
+
+		</el-form-item>
+
+		<el-form-item>
+			<el-radio :label="5" v-model='radioValue'>
+				指定
+				<el-select clearable v-model="checkboxList" placeholder="可多选" multiple>
+					<el-option v-for="item in 9" :key="item" :value="item - 1 + fullYear" :label="item -1 + fullYear" />
+				</el-select>
+			</el-radio>
+		</el-form-item>
+	</el-form>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			fullYear: 0,
+			radioValue: 1,
+			cycle01: 0,
+			cycle02: 0,
+			average01: 0,
+			average02: 1,
+			checkboxList: [],
+			checkNum: this.$options.propsData.check
+		}
+	},
+	name: 'crontab-year',
+	props: ['check', 'month', 'cron'],
+	methods: {
+		// 单选按钮值变化时
+		radioChange() {
+			switch (this.radioValue) {
+				case 1:
+					this.$emit('update', 'year', '');
+					break;
+				case 2:
+					this.$emit('update', 'year', '*');
+					break;
+				case 3:
+					this.$emit('update', 'year', this.cycleTotal);
+					break;
+				case 4:
+					this.$emit('update', 'year', this.averageTotal);
+					break;
+				case 5:
+					this.$emit('update', 'year', this.checkboxString);
+					break;
+			}
+		},
+		// 周期两个值变化时
+		cycleChange() {
+			if (this.radioValue == '3') {
+				this.$emit('update', 'year', this.cycleTotal);
+			}
+		},
+		// 平均两个值变化时
+		averageChange() {
+			if (this.radioValue == '4') {
+				this.$emit('update', 'year', this.averageTotal);
+			}
+		},
+		// checkbox值变化时
+		checkboxChange() {
+			if (this.radioValue == '5') {
+				this.$emit('update', 'year', this.checkboxString);
+			}
+		}
+	},
+	watch: {
+		'radioValue': 'radioChange',
+		'cycleTotal': 'cycleChange',
+		'averageTotal': 'averageChange',
+		'checkboxString': 'checkboxChange'
+	},
+	computed: {
+		// 计算两个周期值
+		cycleTotal: function () {
+			const cycle01 = this.checkNum(this.cycle01, this.fullYear, 2098)
+			const cycle02 = this.checkNum(this.cycle02, cycle01 ? cycle01 + 1 : this.fullYear + 1, 2099)
+			return cycle01 + '-' + cycle02;
+		},
+		// 计算平均用到的值
+		averageTotal: function () {
+			const average01 = this.checkNum(this.average01, this.fullYear, 2098)
+			const average02 = this.checkNum(this.average02, 1, 2099 - average01 || this.fullYear)
+			return average01 + '/' + average02;
+		},
+		// 计算勾选的checkbox值合集
+		checkboxString: function () {
+			let str = this.checkboxList.join();
+			return str;
+		}
+	},
+	mounted: function () {
+		// 仅获取当前年份
+		this.fullYear = Number(new Date().getFullYear());
+		this.cycle01 = this.fullYear
+		this.average01 = this.fullYear
+	}
+}
+</script>

+ 181 - 0
src/components/SkuDesc/index.vue

@@ -0,0 +1,181 @@
+<template>
+  <div class="tinymce-container editor-container">
+    <textarea class="tinymce-textarea" :id="tinymceId"></textarea>
+  </div>
+</template>
+
+<script>
+import plugins from './plugins'
+import toolbar from './toolbar'
+import { uploadPic } from '@/api/storage'
+
+export default {
+  name: 'tinymce',
+  props: {
+    id: {
+      type: String
+    },
+    value: {
+      type: String,
+      default: ''
+    },
+    toolbar: {
+      type: Array,
+      required: false,
+      default() {
+        return []
+      }
+    },
+    menubar: {
+      default: 'file edit insert view format table'
+    },
+    height: {
+      type: Number,
+      required: false,
+      default: 360
+    }
+  },
+  data() {
+    return {
+      hasChange: false,
+      hasInit: false,
+      tinymceId: this.id || 'vue-tinymce-' + +new Date()
+    }
+  },
+  watch: {
+    value(val) {
+      if (!this.hasChange && this.hasInit) {
+        this.$nextTick(() => window.tinymce.get(this.tinymceId).setContent(val))
+      }
+    }
+  },
+  mounted() {
+    this.initTinymce()
+  },
+  activated() {
+    this.initTinymce()
+  },
+  deactivated() {
+    this.destroyTinymce()
+  },
+  methods: {
+    initTinymce() {
+      const _this = this
+      window.tinymce.init({
+        selector: `#${this.tinymceId}`,
+        height: this.height,
+        language: 'zh_CN',
+        body_class: 'panel-body ',
+        object_resizing: false,
+        toolbar: this.toolbar.length > 0 ? this.toolbar : toolbar,
+        menubar: this.menubar,
+        plugins: plugins,
+        end_container_on_empty_block: true,
+        powerpaste_word_import: 'clean',
+        code_dialog_height: 450,
+        code_dialog_width: 1000,
+        advlist_bullet_styles: 'square',
+        advlist_number_styles: 'default',
+        default_link_target: '_blank',
+        relative_urls : false,
+		remove_script_host : false,
+		document_base_url : 'http://xiaoyou.dgtis.com/',
+        link_title: false,
+        init_instance_callback: editor => {
+          if (_this.value) {
+            editor.setContent(_this.value)
+          }
+          _this.hasInit = true
+          editor.on('NodeChange Change KeyUp', () => {
+            this.hasChange = true
+            this.$emit('input', editor.getContent({ format: 'raw' }))
+          })
+        },
+        images_upload_handler: function(blobInfo, success, failure) {
+          const formData = new FormData()
+          formData.append('file', blobInfo.blob())
+          uploadPic(formData).then(res => {
+          var resurl=res.data.data.url;
+          console.log(resurl);
+            success(resurl)
+          }).catch(() => {
+            failure('上传失败,请重新上传')
+          })
+        }
+        // 整合七牛上传
+        // images_dataimg_filter(img) {
+        //   setTimeout(() => {
+        //     const $image = $(img);
+        //     $image.removeAttr('width');
+        //     $image.removeAttr('height');
+        //     if ($image[0].height && $image[0].width) {
+        //       $image.attr('data-wscntype', 'image');
+        //       $image.attr('data-wscnh', $image[0].height);
+        //       $image.attr('data-wscnw', $image[0].width);
+        //       $image.addClass('wscnph');
+        //     }
+        //   }, 0);
+        //   return img
+        // },
+        // images_upload_handler(blobInfo, success, failure, progress) {
+        //   progress(0);
+        //   const token = _this.$store.getters.token;
+        //   getToken(token).then(response => {
+        //     const url = response.data.qiniu_url;
+        //     const formData = new FormData();
+        //     formData.append('token', response.data.qiniu_token);
+        //     formData.append('key', response.data.qiniu_key);
+        //     formData.append('file', blobInfo.blob(), url);
+        //     upload(formData).then(() => {
+        //       success(url);
+        //       progress(100);
+        //     })
+        //   }).catch(err => {
+        //     failure('出现未知问题,刷新页面,或者联系程序员')
+        //     console.log(err);
+        //   });
+        // },
+      })
+    },
+    destroyTinymce() {
+      if (window.tinymce.get(this.tinymceId)) {
+        window.tinymce.get(this.tinymceId).destroy()
+      }
+    },
+    setContent(value) {
+      window.tinymce.get(this.tinymceId).setContent(value)
+    },
+    getContent() {
+      window.tinymce.get(this.tinymceId).getContent()
+    },
+    imageSuccessCBK(arr) {
+      const _this = this
+      arr.forEach(v => {
+        window.tinymce.get(_this.tinymceId).insertContent(`<img class="wscnph" src="${v.url}" >`)
+      })
+    }
+  },
+  destroyed() {
+    this.destroyTinymce()
+  }
+}
+</script>
+
+<style scoped>
+.tinymce-container {
+  position: relative
+}
+.tinymce-textarea {
+  visibility: hidden;
+  z-index: -1;
+}
+.editor-custom-btn-container {
+  position: absolute;
+  right: 4px;
+  top: 4px;
+  /*z-index: 2005;*/
+}
+.editor-upload-btn {
+  display: inline-block;
+}
+</style>

+ 7 - 0
src/components/SkuDesc/plugins.js

@@ -0,0 +1,7 @@
+// Any plugins you want to use has to be imported
+// Detail plugins list see https://www.tinymce.com/docs/plugins/
+// Custom builds see https://www.tinymce.com/download/custom-builds/
+
+const plugins = ['advlist anchor autolink autoresize autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr image imagetools importcss insertdatetime legacyoutput link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars wordcount']
+
+export default plugins

+ 6 - 0
src/components/SkuDesc/toolbar.js

@@ -0,0 +1,6 @@
+// Here is a list of the toolbar
+// Detail list see https://www.tinymce.com/docs/advanced/editor-control-identifiers/#toolbarcontrols
+
+const toolbar = ['fontsizeselect bold italic underline strikethrough alignleft aligncenter alignright outdent indent  blockquote undo redo removeformat subscript superscript code codesample', 'hr bullist numlist link image charmap preview anchor pagebreak fullscreen insertdatetime media table emoticons forecolor backcolor']
+
+export default toolbar

+ 1 - 1
src/main.js

@@ -17,7 +17,7 @@ import './permission' // permission control
 Vue.use(Element, {
   size: 'medium' // set element-ui default size
 })
-const prodUrl = 'https://xiaoyou.dgtis.com/admin/storage/create';//正式地址
+const prodUrl = 'http://47.103.79.143:9085/admin/storage/create';//正式地址
 
 const devUrl = 'http://47.103.79.143:9085/admin/storage/create';//阿里云地址
 

+ 28 - 2
src/permission.js

@@ -17,16 +17,31 @@ function hasPermission(roles, permissionRoles) {
 const whiteList = ['/login', '/authredirect']// no redirect whitelist
 //自定义路由
 const myRoles = [
+  'couponsManage', 
+  'couponsList', 
+
+  'answerGame', 
+  'answerList', 
+  
+  'raffleManage', 
+  'raffleList', 
+  'raffleDataList', 
+  'raffleLogsList',
+
   'goodsManage', 
   'goodsExchangeRules', 
   'goodsList', 
+
   'giftManage', 
   'giftExchangeRules', 
   'giftList', 
+
   'welfareManage', 
   'welfareList', 
+
   'exchangeManage', 
   'exchangeList',
+
   'cancelledList',
   'approvalList',
   'pasList',
@@ -37,23 +52,34 @@ const myRoles = [
   'pointRulesList', 
   'pointList', 
   'pointsDetailList',
+
   'activityManage', 
   'activityList', 
+
   'noticeManage', 
-  'noticeList', 
+  'noticeList', 
+
   'ranking',
   'rankingList',
+
   'medalManage', 
   'medalList', 
-  'medalDataList', 
+  'medalDataList',
+
   'commendManage', 
   'commendList',
   'commendDataList', 
+  'citeList',
+  'operateCiteList',
+  'ceoCiteList',
+
   'festivalManage', 
   'festivalList', 
+
   'certManage', 
   'certRules',
   'certList', 
+
   'dictManage', 
   'dictList', 
   'dictDataList', 

+ 44 - 0
src/router/index.js

@@ -141,6 +141,19 @@ export const asyncRouterMap = [
       // { path: 'activityList', component: _import('activityManage/activityList'), name: 'activityList', meta: { title: '活动列表', noCache: false, hideTag: true, hidden: true}},
     ]
   },
+  {
+    path: '/answerGame',
+    component: Layout,
+    redirect: 'noredirect',
+    name: 'answerGame',
+    meta: {
+      title: '答题管理',
+      icon: 'huodong'
+    },
+    children: [
+      { path: 'answerList', component: _import('answerGame/answerList'), name: 'answerList', meta: { title: '答题列表', icon: 'huodong', noCache: true }},
+    ]
+  },
   {
     path: '/noticeManage',
     component: Layout,
@@ -182,6 +195,34 @@ export const asyncRouterMap = [
       { path: 'medalDataList/:id', component: _import('medalManage/medalDataList'), name: 'medalDataList', meta: { title: '勋章等级列表', noCache: false, hideTag: true, hidden: true }},
     ]
   },
+  {
+    path: '/raffleManage',
+    component: Layout,
+    redirect: 'noredirect',
+    name: 'raffleManage',
+    meta: {
+      title: '抽奖管理',
+      icon: 'huodong'
+    },
+    children: [
+      { path: 'raffleList', component: _import('raffleManage/raffleList'), name: 'raffleList', meta: { title: '奖池列表', noCache: true }},
+      { path: 'raffleLogsList', component: _import('raffleManage/raffleLogsList'), name: 'raffleLogsList', meta: { title: '抽奖记录', noCache: true }},
+      { path: 'raffleDataList/:id', component: _import('raffleManage/raffleDataList'), name: 'raffleDataList', meta: { title: '奖池奖品', noCache: false, hideTag: true, hidden: true }},
+    ]
+  },
+  {
+    path: '/couponsManage',
+    component: Layout,
+    redirect: 'noredirect',
+    name: 'couponsManage',
+    meta: {
+      title: '兑换卷管理',
+      icon: 'huodong'
+    },
+    children: [
+      { path: 'couponsList', component: _import('couponsManage/couponsList'), name: 'couponsList', meta: { title: '兑换卷列表', icon: 'huodong', noCache: true }},
+    ]
+  },
   {
     path: '/commendManage',
     component: Layout,
@@ -194,6 +235,9 @@ export const asyncRouterMap = [
     children: [
       { path: 'commendList', component: _import('commendManage/commendList'), name: 'commendList', meta: { title: '表彰列表', noCache: true }},
       { path: 'commendDataList/:id', component: _import('commendManage/commendDataList'), name: 'commendDataList', meta: { title: '表彰人员', noCache: false, hideTag: true, hidden: true }},
+      { path: 'citeList', component: _import('commendManage/citeList'), name: 'citeList', meta: { title: '客户表彰列表', noCache: true }},
+      { path: 'operateCiteList', component: _import('commendManage/operateCiteList'), name: 'operateCiteList', meta: { title: '客户表彰审批列表', noCache: true }},
+      { path: 'ceoCiteList', component: _import('commendManage/ceoCiteList'), name: 'ceoCiteList', meta: { title: '客户表彰确认列表', noCache: true }},
     ]
   },
   {

+ 180 - 19
src/views/activityManage/activityList.vue

@@ -25,11 +25,9 @@
 
             <el-table-column align="center" min-width="100px" label="活动名称" prop="title">
             </el-table-column>
-            <el-table-column align="center" min-width="100px" label="活动开始结束时间">
-                <template slot-scope="props">
-                   {{ props.row.startTime }}~{{ props.row.endTime }}
-                </template>
-            </el-table-column>
+            <el-table-column align="center" min-width="150px" label="开始日期" prop="startTime"/>
+            <el-table-column align="center" min-width="150px" label="结束日期" prop="endTime"/>
+           
             <el-table-column align="center" min-width="80px" label="创建人" prop="creater">
             </el-table-column>
             <el-table-column align="center" min-width="150px" label="创建时间" prop="createTime">
@@ -43,7 +41,7 @@
                         @click="changeState(scope.row.actId, 1)">开启</el-button>
                     <el-button v-if="scope.row.status == 1" type="warning" size="small"
                         @click="changeState(scope.row.actId, 0)">关闭</el-button>
-                    <el-button type="danger" size="mini" @click="handleDelete(scope.row.actId, -1)">删除</el-button>
+                    <el-button type="danger" size="small" @click="handleDelete(scope.row.actId, -1)">删除</el-button>
                 </template>
             </el-table-column>
         </el-table>
@@ -57,13 +55,18 @@
         </div>
         <!-- 添加或修改对话框 -->
         <el-dialog :close-on-click-modal="false" :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible" width="70%">
-            <el-form :rules="rules" ref="dataForm" :model="dataForm" status-icon label-position="left" label-width="100px" style='width:700px; margin-left:50px;'>
+            <el-form :rules="rules" ref="dataForm" :model="dataForm" status-icon label-position="left" label-width="110px" style='width:700px; margin-left:50px;'>
+                <el-form-item label="活动类型" prop="type">
+                    <el-select v-model="dataForm.type" filterable placeholder="请选择" style="width: 350px"
+                        value-key="value"  @change="clickType">
+                        <el-option :key="item.dictValue" v-for="item in typeList" :label="item.dictLabel"
+                            :value="item.dictValue">
+                        </el-option>
+                    </el-select>
+                </el-form-item>
                 <el-form-item label="活动名称" prop="title">
                     <el-input v-model="dataForm.title" style="width: 350px"></el-input>
                 </el-form-item>
-                <el-form-item label="活动连接">
-                    <el-input v-model="dataForm.activityUrl" style="width: 350px"></el-input>
-                </el-form-item>
                 <el-form-item style="width: 800px" label="活动图片" prop="imgUrl">
                     <el-tooltip content="建议图片宽高比260*200" placement="top-start">
                         <el-upload :action="fileImgUrl" list-type="picture-card" :file-list="dataForm.images" :limit="1"
@@ -73,13 +76,66 @@
                         </el-upload>
                     </el-tooltip>
                 </el-form-item>
-                <el-form-item label="开始日期" prop="startTime">
+                <!-- <el-form-item label="开始日期" prop="startTime">
                     <el-date-picker value-format="yyyy-MM-dd" :picker-options="setDisabled" v-model="dataForm.startTime" type="date" placeholder="请选择开始时间" style="width: 350px">
                     </el-date-picker>
                 </el-form-item>
                 <el-form-item label="结束日期" prop="endTime">
                     <el-date-picker value-format="yyyy-MM-dd" :picker-options="setDisabled" v-model="dataForm.endTime" type="date" placeholder="请选择结束时间" style="width: 350px">
                     </el-date-picker>
+                </el-form-item> -->
+                <el-form-item label="开始日期" prop="startCron">
+                <el-input v-model="dataForm.startCron" placeholder="请输入cron执行表达式" style="width: 350px">
+                    <template slot="append">
+                    <el-button type="primary" @click="handleShowCronStart">
+                        生成表达式
+                        <i class="el-icon-time el-icon--right"></i>
+                    </el-button>
+                    </template>
+                </el-input>
+                </el-form-item>
+                <el-form-item label="结束日期" prop="endCron">
+                    <el-input v-model="dataForm.endCron" placeholder="请输入cron执行表达式" style="width: 350px">
+                        <template slot="append">
+                            <el-button type="primary" @click="handleShowCronEnd">
+                                生成表达式
+                                <i class="el-icon-time el-icon--right"></i>
+                            </el-button>
+                        </template>
+                    </el-input>
+                </el-form-item>
+                <el-form-item v-if="dataForm.type=='3'"  label="关联奖池" prop="prizePoolId">
+                    <el-select v-model="dataForm.prizePoolId" clearable placeholder="请选择奖池" class="filter-item" style="width: 350px">
+                        <el-option :key="item.id" v-for="item in prizePoolList" :label="item.title" :value="item.id">
+                        </el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item v-else label="关联兑换卷" prop="relationCoupon">
+                    <el-radio-group v-model="dataForm.relationCoupon">
+                        <el-radio :label="'0'">否</el-radio>
+                        <el-radio :label="'1'">是</el-radio>
+                    </el-radio-group>
+                </el-form-item>
+                <el-form-item v-if="dataForm.type!='3' && dataForm.relationCoupon=='1'"  label="兑换券" prop="couponIds">
+                    <el-select v-model="dataForm.couponIds" clearable multiple collapse-tags placeholder="请选择兑换券" class="filter-item" style="width: 350px">
+                        <el-option :key="item.id" v-for="item in couponsList" :label="item.couponName" :value="item.id">
+                        </el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item v-if="dataForm.type=='3'" label="抽奖次数" prop="prizeNum">
+                    <el-input-number style="width: 350px" :min="1" :step="1" v-model="dataForm.prizeNum"></el-input-number>
+                </el-form-item>
+                <el-form-item v-if="dataForm.relationCoupon=='1' || dataForm.type=='3'" label="兑换截至时间" prop="couponEndTime">
+                    <el-date-picker 
+                    format="yyyy-MM-dd HH:mm:ss"
+                    value-format="yyyy-MM-dd HH:mm:ss"
+                    type="datetime" v-model="dataForm.couponEndTime" 
+                    placeholder="请选择兑换截至时间" 
+                    style="width: 350px">
+                    </el-date-picker>
+                </el-form-item>
+                <el-form-item label="活动连接">
+                    <el-input v-model="dataForm.activityUrl" style="width: 350px"></el-input>
                 </el-form-item>
                 <el-form-item label="参与人">
                     <el-select v-model="dataForm.participants" multiple filterable placeholder="请选择" style="width: 350px">
@@ -97,7 +153,12 @@
                 <el-button v-else type="primary" @click="updateData">确定</el-button>
             </div>
         </el-dialog>
-
+        <el-dialog title="开始日期Cron表达式生成器" :visible.sync="openCronStart" append-to-body destroy-on-close class="scrollbar">
+            <crontab @hide="openCronStart=false" @fill="crontabFillStart" :expression="expressionStart"></crontab>
+        </el-dialog>
+        <el-dialog title="结束日期Cron表达式生成器" :visible.sync="openCronEnd" append-to-body destroy-on-close class="scrollbar">
+            <crontab @hide="openCronEnd=false" @fill="crontabFillEnd" :expression="expressionEnd"></crontab>
+        </el-dialog>
     </div>
 </template>
   
@@ -119,15 +180,26 @@
   
 <script>
 import { createItem, updateItem, activityList, activityState } from "@/api/activityManage";
-import { allUserList } from "@/api/public";
+import Crontab from '@/components/Crontab'
+import { allUserList,dataTypeList,couponsList,prizePoolList } from "@/api/public";
 import waves from "@/directive/waves"; // 水波纹指令
 import Tinymce from '@/components/Tinymce'
 
 export default {
-    components: { Tinymce },
+    components: { Tinymce,Crontab },
     directives: { waves },
     data() {
         return {
+            prizePoolList:[],
+            couponsList:[],
+             // 是否显示Cron表达式弹出层
+            openCronStart: false,
+            openCronEnd: false,
+            openEndCron: false,
+            // 传入的表达式
+            expressionStart: "",
+            expressionEnd: "",
+            expressionEndCron: "",
             setDisabled: {
                 disabledDate(time) {
                     // return time.getTime() > Date.now();  // 可选历史天、可选当前天、不可选未来天
@@ -147,11 +219,17 @@ export default {
                 createTime: '',
             },
             dataForm: {
+                type:'',
                 title: '',
                 imgUrl: '',
                 activityUrl: '',
-                startTime: '',
-                endTime: '',
+                startCron: '',
+                endCron: '',
+                couponEndTime:'',
+                prizePoolId:'',
+                relationCoupon:'0',
+                couponIds:[],
+                prizeNum:'',
                 participants: [],
                 content: '',
                 images: [],
@@ -163,6 +241,7 @@ export default {
                 create: "创建",
             },
             rules: {
+                type: [{ required: true, message: "请选择活动类型", trigger: "blur" }],
                 title: [{ required: true, message: "请填写活动名称", trigger: "blur" }],
                 imgUrl: [{ required: true, message: "图片不能为空", trigger: "blur" }],
                 startTime: [
@@ -174,15 +253,88 @@ export default {
                     { validator: this.checkEndTime, trigger: 'change' }
                 ],
                 content: [{ required: true, message: "内容不能为空", trigger: "blur" }],
+                startCron: [
+                    { required: true, message: "cron执行表达式不能为空", trigger: "blur" }
+                ],
+                endCron: [
+                    { required: true, message: "cron执行表达式不能为空", trigger: "blur" }
+                ],
+                couponEndTime:[
+                    { required: true, message: "请选择兑换截止日期", trigger: "blur" }
+                ],
+                prizePoolId: [
+                    { required: true, message: "请选择奖池", trigger: "blur" }
+                ],
+                relationCoupon: [
+                    { required: true, message: "请选择是否关联兑换卷", trigger: "blur" }
+                ],
+                couponIds: [
+                    { required: true, message: "请关联兑换券", trigger: "blur" }
+                ],
+                prizeNum: [
+                    { required: true, message: "请设置抽奖次数", trigger: "blur" }
+                ],
             },
             fileImgUrl: this.upLoadUrl,
+            typeList:[],
         }
     },
     created() {
+        this.getPrizePoolList();
+        this.getCouponsList();
+        this.getTypeList();
         this.getAllUserList(); 
         this.getList();
     },
     methods: {
+        clickType(){
+            this.dataForm.title = undefined; 
+            this.dataForm.imgUrl = undefined;
+            this.dataForm.activityUrl = undefined;
+            this.dataForm.startCron = undefined;
+            this.dataForm.endCron = undefined;
+
+            this.dataForm.couponEndTime = undefined;
+            this.dataForm.prizePoolId = undefined;
+            this.dataForm.relationCoupon = '0';
+            this.dataForm.couponIds = [];
+            this.dataForm.prizeNum = undefined;
+
+            this.dataForm.participants = [];
+            this.dataForm.content = undefined;
+            this.dataForm.images = [];
+        },
+        getPrizePoolList() {
+            prizePoolList({}).then(response => {
+                this.prizePoolList = response.data.data;
+            }).catch(() => { });
+        },
+        getCouponsList() {
+            couponsList({}).then(response => {
+                this.couponsList = response.data.data;
+            }).catch(() => { });
+        },
+        getTypeList(){
+            dataTypeList({dictType:'act_type'}).then(response => {
+                this.typeList = response.data.data;
+            }).catch(() => {});
+        },
+          /** cron表达式按钮操作 */
+        handleShowCronStart() {
+            this.expressionStart = this.dataForm.startCron;
+            this.openCronStart = true;
+        },
+        handleShowCronEnd() {
+            this.expressionEnd = this.dataForm.endCron;
+            this.openCronEnd = true;
+        },
+        /** 确定后回传值 */
+        crontabFillStart(value) {
+            this.dataForm.startCron = value;
+        },
+        crontabFillEnd(value) {
+            this.dataForm.endCron = value;
+        },
         //校验开始时间
         checkStartTime(rule, value, callback) {
             if (!value) {
@@ -252,12 +404,18 @@ export default {
         },
         resetForm() {
             this.dataForm = {
+                type:'',
                 title: '',
                 imgUrl: '',
                 activityUrl: '',
-                startTime: '',
-                endTime: '',
-                participants: undefined,
+                startCron: '',
+                endCron: '',
+                couponEndTime:'',
+                prizePoolId:'',
+                relationCoupon:'0',
+                couponIds:[],
+                prizeNum:'',
+                participants: [],
                 content: '',
                 images: [],
             };
@@ -294,6 +452,9 @@ export default {
         },
         handleUpdate(row) {
             this.dataForm = Object.assign({}, row);
+            if(this.dataForm.couponIds==null){
+                this.dataForm.couponIds = [];
+            }
             let content = this.dataForm.content;
             if (this.dataForm.imgUrl) {
                 let images = this.dataForm.imgUrl.split(",");

+ 165 - 0
src/views/answerGame/answerList.vue

@@ -0,0 +1,165 @@
+<template>
+    <div class="app-container calendar-list-container">
+
+        <!-- 查询和其他操作 -->
+        <div class="filter-container">
+            <el-input clearable class="filter-item" style="width: 200px;" placeholder="员工姓名"
+                v-model="listQuery.userName"></el-input>
+            <el-date-picker
+            class="filter-item"
+            value-format="yyyy-MM-dd"
+            v-model="listQuery.createTime"
+            type="date"
+            placeholder="创建日期">
+            </el-date-picker>
+            <el-button class="filter-item" type="primary" v-waves icon="el-icon-search" @click="handleFilter">查找</el-button>
+
+        </div>
+
+        <!-- 查询结果 -->
+        <el-table size="small" :data="list" v-loading="listLoading" element-loading-text="正在查询中。。。" border fit
+            highlight-current-row>
+            <el-table-column type="index" label="序号" header-align="center" align="center">
+            </el-table-column>
+            <el-table-column align="center" min-width="180px" label="部门" prop="deptName">
+            </el-table-column>
+            <el-table-column align="center" min-width="80px" label="员工" prop="userName">
+            </el-table-column>
+            <el-table-column align="center" min-width="80px" label="正确数" prop="rightQuantities">
+            </el-table-column>
+            <el-table-column align="center" min-width="80px" label="用时(毫秒)" prop="answerTime">
+            </el-table-column>
+            
+            <el-table-column align="center" min-width="150px" label="答题时间" prop="answerDate">
+            </el-table-column>
+            <el-table-column align="center" min-width="150px" label="日期" prop="createTime">
+            </el-table-column>
+            <el-table-column align="center" min-width="80px" label="答题记录">
+                <template slot-scope="scope">
+                    <el-button type="primary" size="small" @click="handleView(scope.row.answerLogs)">查看</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+
+        <!-- 分页 -->
+        <div class="pagination-container">
+            <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange"
+                :current-page="listQuery.page" :page-sizes="[10, 20, 30, 50]" :page-size="listQuery.limit"
+                layout="total, sizes, prev, pager, next, jumper" :total="total">
+            </el-pagination>
+        </div>
+        <!-- 答题记录列表 -->
+        <el-dialog :close-on-click-modal="false" title="答题记录" :visible.sync="dialogFormVisible" width="70%">
+            <!-- 查询结果 -->
+            <el-table size="small" :data="itemList" element-loading-text="正在查询中。。。" border fit
+                highlight-current-row>
+                <el-table-column align="center" min-width="150px" label="题目" prop="ask">
+                </el-table-column>
+                <el-table-column align="center" min-width="100px" label="员工答案" prop="userAnswer">
+                </el-table-column>
+                <el-table-column align="center" min-width="200px" label="正确答案" prop="answer">
+                </el-table-column>
+            </el-table>
+        </el-dialog>
+    </div>
+</template>
+  
+<style>
+.demo-table-expand {
+    font-size: 0;
+}
+
+.demo-table-expand label {
+    width: 200px;
+    color: #99a9bf;
+}
+
+.demo-table-expand .el-form-item {
+    margin-right: 0;
+    margin-bottom: 0;
+}
+</style>
+  
+<script>
+import { answerList } from "@/api/answerGame";
+import waves from "@/directive/waves"; // 水波纹指令
+
+export default {
+    directives: { waves },
+    data() {
+        return {
+            list: [],
+            itemList:[],
+            total: 0,
+            listLoading: false,
+            listQuery: {
+                page: 1,
+                limit: 10,
+                userName: '',
+                createTime: '',
+            },
+            dialogFormVisible: false,
+        }
+    },
+    created() {
+        this.getList();
+    },
+    methods: {
+        handleView(row) {
+            this.itemList = row;
+            this.dialogFormVisible = true
+        },
+        getList() {
+            this.listLoading = true
+            answerList(this.listQuery).then(response => {
+                this.list = response.data.data.items
+                this.total = response.data.data.total
+                this.listLoading = false
+            }).catch(() => {})
+        },
+       
+
+        handleFilter() {
+            this.listQuery.page = 1
+            this.getList()
+        },
+        handleSizeChange(val) {
+            this.listQuery.limit = val
+            this.getList()
+        },
+        handleCurrentChange(val) {
+            this.listQuery.page = val
+            this.getList()
+        },
+
+        
+    }
+}
+</script>
+<style>
+.ad-avatar-uploader .el-upload {
+    border: 1px dashed #d9d9d9;
+    border-radius: 6px;
+    cursor: pointer;
+    position: relative;
+    overflow: hidden;
+}
+
+.ad-avatar-uploader .el-upload:hover {
+    border-color: #409EFF;
+}
+
+.ad-avatar-uploader-icon {
+    font-size: 28px;
+    color: #8c939d;
+    width: 178px;
+    height: 178px;
+    line-height: 178px;
+    text-align: center;
+}
+
+.ad-avatar {
+    display: block;
+}
+</style>
+  

+ 354 - 0
src/views/commendManage/ceoCiteList.vue

@@ -0,0 +1,354 @@
+<template>
+  <div class="app-container calendar-list-container">
+    <!-- 查询和其他操作 -->
+    <div class="filter-container">
+      <el-select v-model="listQuery.type" clearable placeholder="表彰类型" class="filter-item" style="width: 200px">
+        <el-option :key="item.dictValue" v-for="item in typeList" :label="item.dictLabel" :value="item.dictValue">
+        </el-option>
+      </el-select>
+      <el-select v-model="listQuery.category" clearable placeholder="表彰类别" class="filter-item" style="width: 200px">
+        <el-option :key="item.dictValue" v-for="item in categoryList" :label="item.dictLabel" :value="item.dictValue">
+        </el-option>
+      </el-select>
+      <el-input clearable class="filter-item" style="width: 200px;" placeholder="客户名称"
+        v-model="listQuery.customerName"></el-input>
+      <el-input clearable class="filter-item" style="width: 200px;" placeholder="表彰名称"
+        v-model="listQuery.title"></el-input>
+      <el-input clearable class="filter-item" style="width: 200px;" placeholder="上传人"
+        v-model="listQuery.userName"></el-input>
+      <!-- <el-select v-model="listQuery.status" clearable placeholder="审批状态" style="top: -4px; width: 200px">
+        <el-option :key="item.dictValue" v-for="item in statusTypeList" :label="item.dictLabel" :value="item.dictValue">
+        </el-option>
+      </el-select> -->
+      <el-button class="filter-item" type="primary" v-waves icon="el-icon-search" @click="handleFilter">查找</el-button>
+      <!-- <el-button class="filter-item" type="primary" v-waves icon="el-icon-download" @click="handleDownLoad">导出</el-button> -->
+    </div>
+
+    <!-- 查询结果 -->
+    <el-table size="small" :data="list" v-loading="listLoading" element-loading-text="正在查询中。。。" border fit
+      highlight-current-row>
+      <el-table-column type="index" label="序号" header-align="center" align="center">
+      </el-table-column>
+      <el-table-column align="center" min-width="200px" label="附件">
+        <template slot-scope="props">
+          <div v-for="(item, index) in props.row.files" :key="index">
+            <a style="color: #1e80ff;" target="_blank" :href="item.url">{{ item.oldName }}</a>
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column align="center" prop="typeName" min-width="100" label="表彰类型">
+      </el-table-column>
+      <el-table-column align="center" prop="categoryName" min-width="100" label="表彰类别">
+      </el-table-column>
+      <el-table-column align="center" min-width="100" label="表彰人员">
+        <template slot-scope="props">
+          <el-popover trigger="hover">
+            <el-table :data="props.row.groupUsers" border size="mini">
+              <el-table-column min-width="200" align="center" prop="deptName" label="部门"></el-table-column>
+              <el-table-column min-width="100" align="center" prop="userName" label="姓名"></el-table-column>
+              <el-table-column min-width="100" align="center" prop="employeNo" label="员工号"></el-table-column>
+            </el-table>
+            <span style="color: #1e80ff;cursor: pointer;" slot="reference">
+              {{ props.row.userName }}
+            </span>
+          </el-popover>
+        </template>
+      </el-table-column>
+      <el-table-column align="center" min-width="150" label="客户名称">
+        <template slot-scope="props">
+          <el-popover width="200" trigger="hover" :content="props.row.customerName">
+            <div slot="reference" class="text-overflow">{{ props.row.customerName }}</div>
+          </el-popover>
+        </template>
+      </el-table-column>
+      <el-table-column align="center" min-width="150" label="表彰名称">
+        <template slot-scope="props">
+          <el-popover width="200" trigger="hover" :content="props.row.title">
+            <div slot="reference" class="text-overflow">{{ props.row.title }}</div>
+          </el-popover>
+        </template>
+      </el-table-column>
+      <el-table-column min-width="100" align="center" label="表彰描述">
+        <template slot-scope="props">
+          <el-popover width="400" trigger="hover" :content="props.row.content">
+            <div slot="reference" class="text-overflow">{{ props.row.content }}</div>
+          </el-popover>
+        </template>
+      </el-table-column>
+      <el-table-column align="center" min-width="250px" label="部门" prop="deptName">
+      </el-table-column>
+      <el-table-column align="center" min-width="80px" label="上传人" prop="userName">
+      </el-table-column>
+      <el-table-column align="center" min-width="80px" label="获得积分" prop="integral">
+      </el-table-column>
+      <el-table-column align="center" min-width="120px" label="审核状态">
+        <template slot-scope="props">
+                <el-popover trigger="hover">
+                  <el-table :data="props.row.logs" border size="mini">
+                    <el-table-column min-width="120" align="center" prop="auditor" label="处理人"></el-table-column>
+                    <el-table-column min-width="160" align="center" prop="comment" label="处理结果"></el-table-column>
+                    <el-table-column min-width="180" align="center" prop="createTime" label="处理时间"></el-table-column>
+                  </el-table>
+                  <span style="color: #1e80ff;cursor: pointer;" slot="reference">{{ props.row.statusName }}</span>
+                </el-popover>
+              </template>
+      </el-table-column>
+      <el-table-column align="center" min-width="100px" label="日期" prop="createTime">
+      </el-table-column>
+      <el-table-column align="center" label="操作" width="80px" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button type="success" size="small"
+            @click="handleClick(scope.row)">处理</el-button>
+          </template>
+      </el-table-column>
+    </el-table>
+    <el-dialog :close-on-click-modal="false" title="表彰审批" :visible.sync="dialogFormVisible" width="40%">
+            <el-form :rules="rules" ref="dataForm" :model="dataForm" status-icon label-position="left" label-width="80px">
+                <el-form-item label="表彰类型">
+                  <el-input disabled class="filter-item" v-model="dataForm.typeName"></el-input>
+                </el-form-item>
+                <el-form-item label="表彰类别" prop="category">
+                  <el-select v-model="dataForm.category" clearable placeholder="表彰类别" class="filter-item" style="width: 100%" @change="handleClickChangeType">
+                    <el-option :key="item.dictValue" v-for="item in categoryList" :label="item.dictLabel" :value="item.dictValue">
+                    </el-option>
+                  </el-select>
+                </el-form-item>
+                <el-form-item label="奖励积分" prop="integral">
+                  <el-input-number style="width: 100%;" :disabled="dataForm.category=='30' && dataForm.type!='1'?false:true" :min="0" :step="1" v-model="dataForm.integral"></el-input-number>
+                </el-form-item>
+                <el-form-item label="审批内容" prop="content">
+                  <el-input type="textarea" :rows="2" placeholder="请输入审批内容" v-model="dataForm.content"></el-input>
+                </el-form-item>
+            </el-form>
+            <div slot="footer" class="dialog-footer">
+                <el-button type="primary" @click="complete(true)">同意</el-button>
+                <el-button type="danger" @click="complete(false)">驳回</el-button>
+            </div>
+        </el-dialog>
+    <!-- 分页 -->
+    <div class="pagination-container">
+      <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange"
+        :current-page="listQuery.page" :page-sizes="[10, 20, 30, 50]" :page-size="listQuery.limit"
+        layout="total, sizes, prev, pager, next, jumper" :total="total">
+      </el-pagination>
+    </div>
+  </div>
+</template>
+    
+<style>
+.text-overflow {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  display: -webkit-box;
+  -webkit-box-orient: vertical;
+  -webkit-line-clamp: 1;
+}
+.demo-table-expand {
+  font-size: 0;
+}
+
+.demo-table-expand label {
+  width: 200px;
+  color: #99a9bf;
+}
+
+.demo-table-expand .el-form-item {
+  margin-right: 0;
+  margin-bottom: 0;
+}
+</style>
+    
+<script>
+import {
+  complete,
+  customerPage,
+} from "@/api/commendManage.js";
+import { dataTypeList } from "@/api/public";
+import waves from "@/directive/waves"; // 水波纹指令
+import Tinymce from "@/components/Tinymce";
+
+export default {
+  components: { Tinymce },
+  directives: { waves },
+  data() {
+    return {
+      id:'',
+      integral:'',
+      dataForm: {
+        category: '',
+        integral:'',
+        content: ''
+      },
+      rules: {
+        category: [{ required: true, message: "请选择表彰类别", trigger: "blur" }],
+        integral: [{ required: true, message: "请填写积分", trigger: "blur" }],
+      },
+      dialogFormVisible: false,
+      dialogVisible: false,
+      categoryList: [],
+      typeList: [],
+      statusTypeList: [],
+      list: [],
+      total: 0,
+      listLoading: false,
+      listQuery: {
+        page: 1,
+        limit: 10,
+        type: '',
+        category: '',
+        customerName: '',
+        title: '',
+        userName: '',
+        status: "20",
+      },
+    };
+  },
+  created() {
+    this.getTypeList();
+    this.getCategoryList();
+    this.getStatusTypeList();
+    this.getList();
+  },
+  methods: {
+    handleClickChangeType(val){
+      if(val=='30'&&this.dataForm.type=='1'){
+        this.dataForm.integral = this.integral;
+      }else{
+        this.dataForm.integral = this.categoryList.find(item => item.dictValue == val).remark;
+      }
+      
+    },
+    checked(val){
+            if(val.flag == false){
+                if(!val.content){
+                    this.$alert("请输入审批内容", "提示", {
+                        confirmButtonText: "确定",
+                    });
+                    return false;
+                }
+            }
+            if(val.flag == true){
+                if(!val.category){
+                    this.$alert("请选择表彰类别", "提示", {
+                        confirmButtonText: "确定",
+                    });
+                    return false;
+                }
+            }
+            return true;
+        },
+    complete(flag) {
+            const parms = {
+                id:this.id,
+                addIntergral:this.dataForm.integral,
+                category:this.dataForm.category,
+                content: this.dataForm.content,
+                flag:flag,
+            }
+            const isChecked = this.checked(parms);
+            if(isChecked){
+                complete(parms).then((response) => {
+                    this.$notify({
+                        title: "成功",
+                        message: "操作成功",
+                        type: "success",
+                        duration: 2000,
+                    });
+                    this.dialogFormVisible = false;
+                    this.getList();
+                })
+                .catch(() => { });
+            }
+            
+        },
+      handleClick(val) {
+        this.dialogFormVisible = true;
+        this.id = val.id;
+        this.integral = val.integral;
+        
+        this.dataForm.typeName = val.typeName;
+        this.dataForm.category = val.category;
+        this.dataForm.integral = val.integral;
+        this.dataForm.type = val.type;
+        this.$nextTick(() => {
+            this.dataForm.content = '';
+            this.$refs["dataForm"].clearValidate();
+        });
+      },
+    getCategoryList() {
+      dataTypeList({ dictType: 'customer_treward_category' }).then(response => {
+        this.categoryList = response.data.data;
+      }).catch(() => { });
+    },
+    getTypeList() {
+      dataTypeList({ dictType: 'customer_treward_type' }).then(response => {
+        this.typeList = response.data.data;
+      }).catch(() => { });
+    },
+    getStatusTypeList() {
+      dataTypeList({ dictType: 'customer_treward_status' }).then(response => {
+        this.statusTypeList = response.data.data;
+      }).catch(() => { });
+    },
+    handleDownLoad() {
+      window.location.href = process.env.BASE_API + '/mall-integral-obtain/export/certificate?name=' + this.listQuery.name + '&title=' + this.listQuery.title + '&userName=' + this.listQuery.userName + '&status=' + this.listQuery.status;
+    },
+    getList() {
+      this.listLoading = true;
+      customerPage(this.listQuery)
+        .then((response) => {
+          this.list = response.data.data.items;
+          this.total = response.data.data.total;
+          this.listLoading = false;
+        })
+        .catch(() => {
+          this.list = [];
+          this.total = 0;
+          this.listLoading = false;
+        });
+    },
+
+    handleFilter() {
+      this.listQuery.page = 1;
+      this.getList();
+    },
+
+    handleSizeChange(val) {
+      this.listQuery.limit = val;
+      this.getList();
+    },
+
+    handleCurrentChange(val) {
+      this.listQuery.page = val;
+      this.getList();
+    },
+  },
+};
+</script>
+<style>
+.ad-avatar-uploader .el-upload {
+  border: 1px dashed #d9d9d9;
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+}
+
+.ad-avatar-uploader .el-upload:hover {
+  border-color: #409eff;
+}
+
+.ad-avatar-uploader-icon {
+  font-size: 28px;
+  color: #8c939d;
+  width: 178px;
+  height: 178px;
+  line-height: 178px;
+  text-align: center;
+}
+
+.ad-avatar {
+  display: block;
+}
+</style>
+    

+ 251 - 0
src/views/commendManage/citeList.vue

@@ -0,0 +1,251 @@
+<template>
+  <div class="app-container calendar-list-container">
+    <!-- 查询和其他操作 -->
+    <div class="filter-container">
+      <el-select v-model="listQuery.type" clearable placeholder="表彰类型" class="filter-item" style="width: 200px">
+        <el-option :key="item.dictValue" v-for="item in typeList" :label="item.dictLabel" :value="item.dictValue">
+        </el-option>
+      </el-select>
+      <el-select v-model="listQuery.category" clearable placeholder="表彰类别" class="filter-item" style="width: 200px">
+        <el-option :key="item.dictValue" v-for="item in categoryList" :label="item.dictLabel" :value="item.dictValue">
+        </el-option>
+      </el-select>
+      <el-input clearable class="filter-item" style="width: 200px;" placeholder="客户名称"
+        v-model="listQuery.customerName"></el-input>
+      <el-input clearable class="filter-item" style="width: 200px;" placeholder="表彰名称"
+        v-model="listQuery.title"></el-input>
+      <el-input clearable class="filter-item" style="width: 200px;" placeholder="上传人"
+        v-model="listQuery.userName"></el-input>
+      <el-select v-model="listQuery.status" clearable placeholder="审批状态" style="top: -4px; width: 200px">
+        <el-option :key="item.dictValue" v-for="item in statusTypeList" :label="item.dictLabel" :value="item.dictValue">
+        </el-option>
+      </el-select>
+      <el-button class="filter-item" type="primary" v-waves icon="el-icon-search" @click="handleFilter">查找</el-button>
+      <!-- <el-button class="filter-item" type="primary" v-waves icon="el-icon-download" @click="handleDownLoad">导出</el-button> -->
+    </div>
+
+    <!-- 查询结果 -->
+    <el-table size="small" :data="list" v-loading="listLoading" element-loading-text="正在查询中。。。" border fit
+      highlight-current-row>
+      <el-table-column type="index" label="序号" header-align="center" align="center">
+      </el-table-column>
+      <el-table-column align="center" min-width="200px" label="附件">
+        <template slot-scope="props">
+          <div v-for="(item, index) in props.row.files" :key="index">
+            <a style="color: #1e80ff;" target="_blank" :href="item.url">{{ item.oldName }}</a>
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column align="center" prop="typeName" min-width="100" label="表彰类型">
+      </el-table-column>
+      <el-table-column align="center" prop="categoryName" min-width="100" label="表彰类别">
+      </el-table-column>
+      <el-table-column align="center" min-width="100" label="表彰人员">
+        <template slot-scope="props">
+          <el-popover trigger="hover">
+            <el-table :data="props.row.groupUsers" border size="mini">
+              <el-table-column min-width="200" align="center" prop="deptName" label="部门"></el-table-column>
+              <el-table-column min-width="100" align="center" prop="userName" label="姓名"></el-table-column>
+              <el-table-column min-width="100" align="center" prop="employeNo" label="员工号"></el-table-column>
+            </el-table>
+            <span style="color: #1e80ff;cursor: pointer;" slot="reference">
+              {{ props.row.userName }}
+            </span>
+          </el-popover>
+        </template>
+      </el-table-column>
+      <el-table-column align="center" min-width="150" label="客户名称">
+        <template slot-scope="props">
+          <el-popover width="200" trigger="hover" :content="props.row.customerName">
+            <div slot="reference" class="text-overflow">{{ props.row.customerName }}</div>
+          </el-popover>
+        </template>
+      </el-table-column>
+      <el-table-column align="center" min-width="150" label="表彰名称">
+        <template slot-scope="props">
+          <el-popover width="200" trigger="hover" :content="props.row.title">
+            <div slot="reference" class="text-overflow">{{ props.row.title }}</div>
+          </el-popover>
+        </template>
+      </el-table-column>
+      <el-table-column min-width="100" align="center" label="表彰描述">
+        <template slot-scope="props">
+          <el-popover width="400" trigger="hover" :content="props.row.content">
+            <div slot="reference" class="text-overflow">{{ props.row.content }}</div>
+          </el-popover>
+        </template>
+      </el-table-column>
+      <el-table-column align="center" min-width="250px" label="部门" prop="deptName">
+      </el-table-column>
+      <el-table-column align="center" min-width="80px" label="上传人" prop="userName">
+      </el-table-column>
+      <el-table-column align="center" min-width="80px" label="获得积分" prop="integral">
+      </el-table-column>
+      <el-table-column align="center" min-width="120px" label="审核状态">
+        <template slot-scope="props">
+          <el-popover trigger="hover">
+            <el-table :data="props.row.logs" border size="mini">
+              <el-table-column min-width="120" align="center" prop="auditor" label="处理人"></el-table-column>
+              <el-table-column min-width="160" align="center" prop="comment" label="处理结果"></el-table-column>
+              <el-table-column min-width="180" align="center" prop="createTime" label="处理时间"></el-table-column>
+            </el-table>
+            <span style="color: #1e80ff;cursor: pointer;" slot="reference">{{ props.row.statusName }}</span>
+          </el-popover>
+        </template>
+      </el-table-column>
+      <el-table-column align="center" min-width="100px" label="日期" prop="createTime">
+      </el-table-column>
+    </el-table>
+
+    <!-- 分页 -->
+    <div class="pagination-container">
+      <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange"
+        :current-page="listQuery.page" :page-sizes="[10, 20, 30, 50]" :page-size="listQuery.limit"
+        layout="total, sizes, prev, pager, next, jumper" :total="total">
+      </el-pagination>
+    </div>
+  </div>
+</template>
+    
+<style>
+.text-overflow {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  display: -webkit-box;
+  -webkit-box-orient: vertical;
+  -webkit-line-clamp: 1;
+}
+
+.demo-table-expand {
+  font-size: 0;
+}
+
+.demo-table-expand label {
+  width: 200px;
+  color: #99a9bf;
+}
+
+.demo-table-expand .el-form-item {
+  margin-right: 0;
+  margin-bottom: 0;
+}
+</style>
+    
+<script>
+import {
+  customerPage,
+} from "@/api/commendManage.js";
+import { dataTypeList } from "@/api/public";
+import waves from "@/directive/waves"; // 水波纹指令
+import Tinymce from "@/components/Tinymce";
+
+export default {
+  components: { Tinymce },
+  directives: { waves },
+  data() {
+    return {
+      detailData: {},
+      tableData: [],
+      dialogVisible: false,
+      categoryList: [],
+      typeList: [],
+      statusTypeList: [],
+      list: [],
+      total: 0,
+      listLoading: false,
+      listQuery: {
+        page: 1,
+        limit: 10,
+        type: '',
+        category: '',
+        customerName: '',
+        title: '',
+        userName: '',
+        status: "",
+      },
+    };
+  },
+  created() {
+    this.getTypeList();
+    this.getCategoryList();
+    this.getStatusTypeList();
+    this.getList();
+  },
+  methods: {
+    getCategoryList() {
+      dataTypeList({ dictType: 'customer_treward_category' }).then(response => {
+        this.categoryList = response.data.data;
+      }).catch(() => { });
+    },
+    getTypeList() {
+      dataTypeList({ dictType: 'customer_treward_type' }).then(response => {
+        this.typeList = response.data.data;
+      }).catch(() => { });
+    },
+    getStatusTypeList() {
+      dataTypeList({ dictType: 'customer_treward_status' }).then(response => {
+        this.statusTypeList = response.data.data;
+      }).catch(() => { });
+    },
+    handleDownLoad() {
+      window.location.href = process.env.BASE_API + '/mall-integral-obtain/export/certificate?name=' + this.listQuery.name + '&title=' + this.listQuery.title + '&userName=' + this.listQuery.userName + '&status=' + this.listQuery.status;
+    },
+    getList() {
+      this.listLoading = true;
+      customerPage(this.listQuery)
+        .then((response) => {
+          this.list = response.data.data.items;
+          this.total = response.data.data.total;
+          this.listLoading = false;
+        })
+        .catch(() => {
+          this.list = [];
+          this.total = 0;
+          this.listLoading = false;
+        });
+    },
+
+    handleFilter() {
+      this.listQuery.page = 1;
+      this.getList();
+    },
+
+    handleSizeChange(val) {
+      this.listQuery.limit = val;
+      this.getList();
+    },
+
+    handleCurrentChange(val) {
+      this.listQuery.page = val;
+      this.getList();
+    },
+  },
+};
+</script>
+<style>
+.ad-avatar-uploader .el-upload {
+  border: 1px dashed #d9d9d9;
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+}
+
+.ad-avatar-uploader .el-upload:hover {
+  border-color: #409eff;
+}
+
+.ad-avatar-uploader-icon {
+  font-size: 28px;
+  color: #8c939d;
+  width: 178px;
+  height: 178px;
+  line-height: 178px;
+  text-align: center;
+}
+
+.ad-avatar {
+  display: block;
+}
+</style>
+    

+ 1 - 1
src/views/commendManage/commendDataList.vue

@@ -46,7 +46,7 @@
         <el-form :rules="rules" ref="dataForm" :model="dataForm" status-icon label-position="left" label-width="80px" style='width: 700px; margin-left:50px;'>
             <el-form-item label="表彰人" prop="loginId">
                 <el-select v-model="dataForm.loginId" clearable filterable placeholder="请选择" style="width: 350px">
-                    <el-option :key="item.loginId" v-for="item in recipientsList" :label="item.userName" :value="item.loginId">
+                    <el-option :key="item.loginId" v-for="item in recipientsList" :label="item.deptName+'_'+item.userName+'_'+item.employeNo" :value="item.loginId">
                     </el-option>
                 </el-select>
             </el-form-item>

+ 332 - 0
src/views/commendManage/operateCiteList.vue

@@ -0,0 +1,332 @@
+<template>
+  <div class="app-container calendar-list-container">
+    <!-- 查询和其他操作 -->
+    <div class="filter-container">
+      <el-select v-model="listQuery.type" clearable placeholder="表彰类型" class="filter-item" style="width: 200px">
+        <el-option :key="item.dictValue" v-for="item in typeList" :label="item.dictLabel" :value="item.dictValue">
+        </el-option>
+      </el-select>
+      <!-- <el-select v-model="listQuery.category" clearable placeholder="表彰类别" class="filter-item" style="width: 200px">
+        <el-option :key="item.dictValue" v-for="item in categoryList" :label="item.dictLabel" :value="item.dictValue">
+        </el-option>
+      </el-select> -->
+      <el-input clearable class="filter-item" style="width: 200px;" placeholder="客户名称"
+        v-model="listQuery.customerName"></el-input>
+      <el-input clearable class="filter-item" style="width: 200px;" placeholder="表彰名称"
+        v-model="listQuery.title"></el-input>
+      <el-input clearable class="filter-item" style="width: 200px;" placeholder="上传人"
+        v-model="listQuery.userName"></el-input>
+      <!-- <el-select v-model="listQuery.status" clearable placeholder="审批状态" style="top: -4px; width: 200px">
+        <el-option :key="item.dictValue" v-for="item in statusTypeList" :label="item.dictLabel" :value="item.dictValue">
+        </el-option>
+      </el-select> -->
+      <el-button class="filter-item" type="primary" v-waves icon="el-icon-search" @click="handleFilter">查找</el-button>
+      <!-- <el-button class="filter-item" type="primary" v-waves icon="el-icon-download" @click="handleDownLoad">导出</el-button> -->
+    </div>
+
+    <!-- 查询结果 -->
+    <el-table size="small" :data="list" v-loading="listLoading" element-loading-text="正在查询中。。。" border fit
+      highlight-current-row>
+      <el-table-column type="index" label="序号" header-align="center" align="center">
+      </el-table-column>
+      <el-table-column align="center" min-width="200px" label="附件">
+        <template slot-scope="props">
+          <div v-for="(item, index) in props.row.files" :key="index">
+            <a style="color: #1e80ff;" target="_blank" :href="item.url">{{ item.oldName }}</a>
+          </div>
+        </template>
+      </el-table-column>
+      <el-table-column align="center" prop="typeName" min-width="100" label="表彰类型">
+      </el-table-column>
+      <!-- <el-table-column align="center" prop="categoryName" min-width="100" label="表彰类别">
+      </el-table-column> -->
+      <el-table-column align="center" min-width="100" label="表彰人员">
+        <template slot-scope="props">
+          <el-popover trigger="hover">
+            <el-table :data="props.row.groupUsers" border size="mini">
+              <el-table-column min-width="200" align="center" prop="deptName" label="部门"></el-table-column>
+              <el-table-column min-width="100" align="center" prop="userName" label="姓名"></el-table-column>
+              <el-table-column min-width="100" align="center" prop="employeNo" label="员工号"></el-table-column>
+            </el-table>
+            <span style="color: #1e80ff;cursor: pointer;" slot="reference">
+              {{ props.row.userName }}
+            </span>
+          </el-popover>
+        </template>
+      </el-table-column>
+      <el-table-column align="center" min-width="150" label="客户名称">
+        <template slot-scope="props">
+          <el-popover width="200" trigger="hover" :content="props.row.customerName">
+            <div slot="reference" class="text-overflow">{{ props.row.customerName }}</div>
+          </el-popover>
+        </template>
+      </el-table-column>
+      <el-table-column align="center" min-width="150" label="表彰名称">
+        <template slot-scope="props">
+          <el-popover width="200" trigger="hover" :content="props.row.title">
+            <div slot="reference" class="text-overflow">{{ props.row.title }}</div>
+          </el-popover>
+        </template>
+      </el-table-column>
+      <el-table-column min-width="100" align="center" label="表彰描述">
+        <template slot-scope="props">
+          <el-popover width="400" trigger="hover" :content="props.row.content">
+            <div slot="reference" class="text-overflow">{{ props.row.content }}</div>
+          </el-popover>
+        </template>
+      </el-table-column>
+      <el-table-column align="center" min-width="250px" label="部门" prop="deptName">
+      </el-table-column>
+      <el-table-column align="center" min-width="80px" label="上传人" prop="userName">
+      </el-table-column>
+      <el-table-column align="center" min-width="80px" label="获得积分" prop="integral">
+      </el-table-column>
+      <el-table-column align="center" min-width="120px" label="审核状态">
+        <template slot-scope="props">
+                <el-popover trigger="hover">
+                  <el-table :data="props.row.logs" border size="mini">
+                    <el-table-column min-width="120" align="center" prop="auditor" label="处理人"></el-table-column>
+                    <el-table-column min-width="160" align="center" prop="comment" label="处理结果"></el-table-column>
+                    <el-table-column min-width="180" align="center" prop="createTime" label="处理时间"></el-table-column>
+                  </el-table>
+                  <span style="color: #1e80ff;cursor: pointer;" slot="reference">{{ props.row.statusName }}</span>
+                </el-popover>
+              </template>
+      </el-table-column>
+      <el-table-column align="center" min-width="100px" label="日期" prop="createTime">
+      </el-table-column>
+      <el-table-column align="center" label="操作" width="80px" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button type="success" size="small"
+            @click="handleClick(scope.row.id)">处理</el-button>
+          </template>
+      </el-table-column>
+    </el-table>
+    <el-dialog :close-on-click-modal="false" title="表彰审批" :visible.sync="dialogFormVisible" width="40%">
+            <el-form :rules="rules" ref="dataForm" :model="dataForm" status-icon label-position="left" label-width="80px">
+              
+                <el-form-item label="表彰类别" prop="category">
+                  <el-select v-model="dataForm.category" clearable placeholder="表彰类别" class="filter-item" style="width: 100%">
+                    <el-option :key="item.dictValue" v-for="item in categoryList" :label="item.dictLabel" :value="item.dictValue">
+                    </el-option>
+                  </el-select>
+                </el-form-item>
+                <el-form-item label="审批内容" prop="content">
+                  <el-input type="textarea" :rows="2" placeholder="请输入审批内容" v-model="dataForm.content"></el-input>
+                </el-form-item>
+            </el-form>
+            <div slot="footer" class="dialog-footer">
+                <el-button type="primary" @click="complete(true)">同意</el-button>
+                <el-button type="danger" @click="complete(false)">驳回</el-button>
+            </div>
+        </el-dialog>
+    <!-- 分页 -->
+    <div class="pagination-container">
+      <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange"
+        :current-page="listQuery.page" :page-sizes="[10, 20, 30, 50]" :page-size="listQuery.limit"
+        layout="total, sizes, prev, pager, next, jumper" :total="total">
+      </el-pagination>
+    </div>
+  </div>
+</template>
+    
+<style>
+.text-overflow {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  display: -webkit-box;
+  -webkit-box-orient: vertical;
+  -webkit-line-clamp: 1;
+}
+.demo-table-expand {
+  font-size: 0;
+}
+
+.demo-table-expand label {
+  width: 200px;
+  color: #99a9bf;
+}
+
+.demo-table-expand .el-form-item {
+  margin-right: 0;
+  margin-bottom: 0;
+}
+</style>
+    
+<script>
+import {
+  complete,
+  customerPage,
+} from "@/api/commendManage.js";
+import { dataTypeList } from "@/api/public";
+import waves from "@/directive/waves"; // 水波纹指令
+import Tinymce from "@/components/Tinymce";
+
+export default {
+  components: { Tinymce },
+  directives: { waves },
+  data() {
+    return {
+      id:'',
+      dataForm: {
+        category: '',
+        content: ''
+      },
+      rules: {
+        category: [{ required: true, message: "请选择表彰类别", trigger: "blur" }],
+      },
+      dialogFormVisible: false,
+      dialogVisible: false,
+      categoryList: [],
+      typeList: [],
+      statusTypeList: [],
+      list: [],
+      total: 0,
+      listLoading: false,
+      listQuery: {
+        page: 1,
+        limit: 10,
+        type: '',
+        category: '',
+        customerName: '',
+        title: '',
+        userName: '',
+        status: "10",
+      },
+    };
+  },
+  created() {
+    this.getTypeList();
+    this.getCategoryList();
+    this.getStatusTypeList();
+    this.getList();
+  },
+  methods: {
+    checked(val){
+            if(val.flag == false){
+                if(!val.content){
+                    this.$alert("请输入审批内容", "提示", {
+                        confirmButtonText: "确定",
+                    });
+                    return false;
+                }
+            }
+            if(val.flag == true){
+                if(!val.category){
+                    this.$alert("请选择表彰类别", "提示", {
+                        confirmButtonText: "确定",
+                    });
+                    return false;
+                }
+            }
+            return true;
+        },
+    complete(flag) {
+            const parms = {
+                id:this.id,
+                category:this.dataForm.category,
+                content: this.dataForm.content,
+                flag:flag,
+            }
+            const isChecked = this.checked(parms);
+            if(isChecked){
+                complete(parms).then((response) => {
+                    this.$notify({
+                        title: "成功",
+                        message: "操作成功",
+                        type: "success",
+                        duration: 2000,
+                    });
+                    this.dialogFormVisible = false;
+                    this.getList();
+                })
+                .catch(() => { });
+            }
+            
+        },
+      handleClick(id) {
+        this.dialogFormVisible = true;
+        this.id = id;
+        this.$nextTick(() => {
+            this.dataForm.category = '';
+            this.dataForm.content = '';
+            this.$refs["dataForm"].clearValidate();
+        });
+      },
+    getCategoryList() {
+      dataTypeList({ dictType: 'customer_treward_category' }).then(response => {
+        this.categoryList = response.data.data;
+      }).catch(() => { });
+    },
+    getTypeList() {
+      dataTypeList({ dictType: 'customer_treward_type' }).then(response => {
+        this.typeList = response.data.data;
+      }).catch(() => { });
+    },
+    getStatusTypeList() {
+      dataTypeList({ dictType: 'customer_treward_status' }).then(response => {
+        this.statusTypeList = response.data.data;
+      }).catch(() => { });
+    },
+    handleDownLoad() {
+      window.location.href = process.env.BASE_API + '/mall-integral-obtain/export/certificate?name=' + this.listQuery.name + '&title=' + this.listQuery.title + '&userName=' + this.listQuery.userName + '&status=' + this.listQuery.status;
+    },
+    getList() {
+      this.listLoading = true;
+      customerPage(this.listQuery)
+        .then((response) => {
+          this.list = response.data.data.items;
+          this.total = response.data.data.total;
+          this.listLoading = false;
+        })
+        .catch(() => {
+          this.list = [];
+          this.total = 0;
+          this.listLoading = false;
+        });
+    },
+
+    handleFilter() {
+      this.listQuery.page = 1;
+      this.getList();
+    },
+
+    handleSizeChange(val) {
+      this.listQuery.limit = val;
+      this.getList();
+    },
+
+    handleCurrentChange(val) {
+      this.listQuery.page = val;
+      this.getList();
+    },
+  },
+};
+</script>
+<style>
+.ad-avatar-uploader .el-upload {
+  border: 1px dashed #d9d9d9;
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+}
+
+.ad-avatar-uploader .el-upload:hover {
+  border-color: #409eff;
+}
+
+.ad-avatar-uploader-icon {
+  font-size: 28px;
+  color: #8c939d;
+  width: 178px;
+  height: 178px;
+  line-height: 178px;
+  text-align: center;
+}
+
+.ad-avatar {
+  display: block;
+}
+</style>
+    

+ 482 - 0
src/views/couponsManage/couponsList.vue

@@ -0,0 +1,482 @@
+<template>
+  <div class="app-container calendar-list-container">
+
+    <!-- 查询和其他操作 -->
+    <div class="filter-container">
+      <el-input clearable class="filter-item" style="width: 200px;" placeholder="请输入名称"
+        v-model="listQuery.couponName"></el-input>
+      <el-select v-model="listQuery.couponType" clearable placeholder="请选择类型" class="filter-item" style="width: 200px">
+        <el-option :key="item.type" v-for="item in typeList" :label="item.name" :value="item.type">
+        </el-option>
+      </el-select>
+      <el-date-picker class="filter-item" value-format="yyyy-MM-dd" v-model="listQuery.enableEndTime" type="date"
+        placeholder="截止日期">
+      </el-date-picker>
+      <el-date-picker class="filter-item" value-format="yyyy-MM-dd" v-model="listQuery.createTime" type="date"
+        placeholder="创建日期">
+      </el-date-picker>
+      <el-button class="filter-item" type="primary" v-waves icon="el-icon-search" @click="handleFilter">查找</el-button>
+      <el-button class="filter-item" type="primary" @click="handleCreate" icon="el-icon-edit">添加</el-button>
+      <!-- <el-button class="filter-item" type="warning" icon="el-icon-delete" @click="delAll">批量删除</el-button> -->
+    </div>
+
+    <!-- 查询结果 -->
+    <el-table size="small" :data="list" @selection-change="handleSelectionChange" v-loading="listLoading"
+      element-loading-text="正在查询中。。。" border fit highlight-current-row>
+      <el-table-column type="selection" width="55px"> </el-table-column>
+      <el-table-column type="index" label="序号" header-align="center" align="center">
+      </el-table-column>
+
+      <el-table-column align="center" min-width="100px" label="名称" prop="couponName">
+      </el-table-column>
+      <el-table-column align="center" min-width="80px" label="类型" prop="couponTypeName">
+      </el-table-column>
+      <el-table-column align="center" min-width="80px" label="数量" prop="num">
+      </el-table-column>
+      <el-table-column align="center" min-width="150px" label="截止日期" prop="enableEndTime">
+      </el-table-column>
+      <el-table-column align="center" min-width="100px" label="状态" prop="statusName">
+      </el-table-column>
+      <el-table-column align="center" min-width="150px" label="创建时间" prop="createTime">
+      </el-table-column>
+      <el-table-column align="center" label="操作" width="240px" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button type="primary" size="small" @click="handleUpdate(scope.row, false)">编辑</el-button>
+
+          <el-button type="danger" size="small" @click="handleDelete(scope.row)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 分页 -->
+    <div class="pagination-container">
+      <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange"
+        :current-page="listQuery.page" :page-sizes="[10, 20, 30, 50]" :page-size="listQuery.limit"
+        layout="total, sizes, prev, pager, next, jumper" :total="total">
+      </el-pagination>
+    </div>
+
+    <!-- 添加或修改对话框 -->
+    <el-dialog :close-on-click-modal="false" :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible" width="40%">
+      <el-form :rules="rules" ref="dataForm" :model="dataForm" status-icon label-position="left" label-width="80px"
+        style='width: 700px; margin-left:50px;'>
+        <el-form-item label="名称" prop="couponName">
+          <el-input style="width: 300px" v-model="dataForm.couponName"></el-input>
+        </el-form-item>
+        <el-form-item style="width: 800px" label="图片" prop="couponImg">
+                    <el-upload :limit="1" :action="fileImgUrl" list-type="picture-card" :file-list="dataForm.images"
+                            :on-success="handleGallerySucess" :on-exceed="handleExceed" :before-upload="uploadBannerImg"
+                            :on-remove="handleRemove">
+                            <i class="el-icon-plus"></i>
+                        </el-upload>
+                </el-form-item>
+        <el-form-item label="类型" prop="couponType">
+          <el-select v-model="dataForm.couponType" clearable placeholder="请选择类型" class="filter-item" style="width: 300px">
+            <el-option :key="item.type" v-for="item in typeList" :label="item.name" :value="item.type">
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="使用类型" prop="useType">
+          <el-select v-model="dataForm.useType" clearable placeholder="请选择类型" class="filter-item" style="width: 300px">
+            <el-option :key="item.dictValue" v-for="item in dataTypeList" :label="item.dictLabel" :value="item.dictValue">
+                        </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item v-if="dataForm.useType=='1'" label="商品" prop="skuIds">
+          <el-select v-model="dataForm.skuIds" clearable multiple collapse-tags placeholder="请选择商品" class="filter-item" style="width: 300px">
+            <el-option :key="item.skuId" v-for="item in goodsList" :label="item.name" :value="item.skuId">
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item v-else label="分类" prop="categorys">
+          <el-select v-model="dataForm.categorys" clearable  multiple collapse-tags placeholder="请选择分类" class="filter-item" style="width: 300px">
+            <el-option :key="item.dictValue" v-for="item in categorysList" :label="item.dictLabel" :value="item.dictValue">
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item v-if="dataForm.couponType=='2'" label="截止日期" prop="enableEndTime">
+          <el-date-picker style="width: 300px" class="filter-item" value-format="yyyy-MM-dd"
+            v-model="dataForm.enableEndTime" type="date" placeholder="截止日期">
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="数量" prop="num">
+          <el-input-number :min="1" :precision="0" :step="1" v-model="dataForm.num"></el-input-number>
+        </el-form-item>
+        <el-form-item label="状态">
+          <el-radio-group v-model="dataForm.status">
+            <el-radio :label="'0'">关闭</el-radio>
+            <el-radio :label="'1'">开启</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <!-- <el-form-item label="备注">
+          <el-input type="textarea" :rows="2" style="width: 300px" v-model="dataForm.remark"></el-input>
+        </el-form-item> -->
+
+
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="dialogFormVisible = false">取消</el-button>
+        <el-button v-if="dialogStatus == 'create'" type="primary" @click="createData">确定</el-button>
+        <el-button v-else type="primary" @click="updateData">确定</el-button>
+      </div>
+    </el-dialog>
+
+  </div>
+</template>
+  
+<style>
+.demo-table-expand {
+  font-size: 0;
+}
+
+.demo-table-expand label {
+  width: 200px;
+  color: #99a9bf;
+}
+
+.demo-table-expand .el-form-item {
+  margin-right: 0;
+  margin-bottom: 0;
+}
+</style>
+  
+<script>
+import { list, createItem, updateItem, deleteitem } from "@/api/couponsManage";
+import { goodsList,dataTypeList } from "@/api/public";
+import waves from "@/directive/waves"; // 水波纹指令
+import Tinymce from '@/components/Tinymce'
+
+export default {
+  components: { Tinymce },
+  directives: { waves },
+  data() {
+    return {
+      fileImgUrl: this.upLoadUrl,
+      categorysList:[],
+      dataTypeList:[],
+      goodsList:[],
+      typeList: [
+        {
+          type: "1",
+          name: "永久",
+        },
+        {
+          type: "2",
+          name: "有效",
+        },
+      ],
+      list: [
+
+      ],
+      delarr: [],
+      multipleSelection: [],
+      total: 0,
+      listLoading: false,
+      listQuery: {
+        page: 1,
+        limit: 10,
+        couponName: '',
+        couponType: '',
+        enableEndTime: '',
+        createTime: '',
+      },
+      dataForm: {
+        couponImg: undefined,
+        images: [],
+        couponName: undefined,
+        couponType: undefined,
+        useType:undefined,
+        categorys:[],
+        skuIds: [],
+        enableEndTime: undefined,
+        num: undefined,
+        status: '1',
+        remark: undefined,
+      },
+      dialogFormVisible: false,
+      dialogStatus: '',
+      textMap: {
+        update: "编辑",
+        create: "创建",
+      },
+      imageUrl: undefined,
+      rules: {
+        couponImg: [{ required: true, message: "请上传奖品图片", trigger: "blur" }],
+        couponName: [{ required: true, message: "名称不能为空", trigger: "blur" }],
+        couponType: [{ required: true, message: "请选择类型", trigger: "blur" }],
+        useType: [{ required: true, message: "请选择使用类型", trigger: "blur" }],
+        categorys: [{ required: true, message: "请选择分类", trigger: "blur" }],
+        skuIds: [{ required: true, message: "请选择商品", trigger: "blur" }],
+        enableEndTime: [{ required: true, message: "请选择截止日期", trigger: "blur" }],
+        num: [{ required: true, message: "数量不能为空", trigger: "blur" }],
+      },
+    }
+  },
+  created() {
+    this.getList();
+    this.getGoodsList();
+    this.getDataTypeList();
+    this.getCategorysList();
+  },
+  methods: {
+    handleRemove(file, fileList) {
+            console.log(file, fileList);
+            let images = [];
+            for (let i in fileList) {
+                let response = fileList[i].response;
+                let url = response.data.url;
+                images.push(url);
+            }
+            this.dataForm.images = images;
+            this.dataForm.couponImg = images.join(",");
+        },
+        uploadBannerImg(file) {
+            const isJPGs = file.type === "image/jpeg";
+            console.log(isJPGs);
+        },
+        handleExceed(files, fileList) {
+            this.$message.warning(
+                `当前限制选择 1 个文件,本次选择了 ${files.length} 个文件!,共选择了 ${files.length + fileList.length
+                } 个文件`
+            );
+        },
+        handleGallerySucess(res, file, fileList) {
+            this.dataForm.couponImg = ""; // 清空画廊图片数组
+
+            let images = [];
+            for (let i in fileList) {
+                let response = fileList[i].response;
+                if (response.errno && response.errno != "0") {
+                    this.$message.error("该图片上传失败,已被移除,请重新上传!");
+                    // 上传失败移除该 file 对象
+                    fileList.splice(i, 1);
+                } else {
+                    let url = response.data.url;
+                    images.push(url);
+                }
+            }
+            this.dataForm.images = images;
+            this.dataForm.couponImg = images.join(",");
+            console.log(this.dataForm.couponImg)
+        },
+    getCategorysList() {
+            dataTypeList({dictType:'mall_sku_attribute'}).then(response => {
+                this.categorysList = response.data.data;
+            }).catch(() => {});
+        },
+    getDataTypeList() {
+            dataTypeList({dictType:'coupon_use_type'}).then(response => {
+                this.dataTypeList = response.data.data;
+            }).catch(() => {});
+        },
+    getGoodsList() {
+      goodsList({}).then(response => {
+        this.goodsList = response.data.data;
+      }).catch(() => { });
+    },
+    resetForm() {
+      this.dataForm = {
+        couponImg: undefined,
+        images: [],
+        couponName: undefined,
+        couponType: undefined,
+        useType:undefined,
+        categorys:[],
+        skuIds: [],
+        enableEndTime: undefined,
+        num: undefined,
+        status: '1',
+        remark: undefined,
+      };
+    },
+    handleCreate() {
+      this.resetForm();
+      this.dialogFormVisible = true;
+      this.dialogStatus = "create";
+      this.$nextTick(() => {
+        this.$refs["dataForm"].clearValidate();
+      });
+    },
+    createData() {
+      this.$refs["dataForm"].validate((valid) => {
+        if (valid) {
+          createItem(this.dataForm)
+            .then(() => {
+              this.getList();
+              this.dialogFormVisible = false;
+
+              this.$notify({
+                title: "成功",
+                message: "创建成功",
+                type: "success",
+                duration: 2000,
+              });
+              this.getList()
+            })
+        }
+      });
+    },
+    getList() {
+      this.listLoading = true
+      list(this.listQuery).then(response => {
+        this.list = response.data.data.items
+        this.total = response.data.data.total
+        this.listLoading = false
+      }).catch(() => {
+        this.list = []
+        this.total = 0
+        this.listLoading = false
+      })
+    },
+
+    handleFilter() {
+      this.listQuery.page = 1
+      this.getList()
+    },
+
+    handleSizeChange(val) {
+      this.listQuery.limit = val
+      this.getList()
+    },
+
+    handleCurrentChange(val) {
+      this.listQuery.page = val
+      this.getList()
+    },
+
+    handleUpdate(row) {
+      this.dataForm = Object.assign({}, row);
+      if (this.dataForm.couponImg) {
+                let images = this.dataForm.couponImg.split(",");
+                this.dataForm.images = [];
+                for (let i in images) {
+                    let url = images[i];
+                    let name = "image_" + i;
+
+                    this.dataForm.images.push({
+                        name: name,
+                        url: url,
+                        response: { error: "0", data: { url: url } },
+                    });
+                }
+            }
+      if(this.dataForm.categorys==null){
+        this.dataForm.categorys=[];
+      }
+      if(this.dataForm.skuIds==null){
+        this.dataForm.skuIds=[];
+      }
+      this.dialogStatus = 'update'
+      this.dialogFormVisible = true
+      this.$nextTick(() => {
+        this.$refs['dataForm'].clearValidate()
+      })
+    },
+
+    updateData() {
+      this.$refs['dataForm'].validate((valid) => {
+        if (valid) {
+          updateItem(this.dataForm).then(() => {
+            this.dialogFormVisible = false
+            this.$notify({
+              title: '成功',
+              message: '更新成功',
+              type: 'success',
+              duration: 2000
+            })
+            this.getList()
+          })
+
+        }
+      })
+    },
+
+    handleDelete(row) {
+
+      this.$confirm('确认删除吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        deleteitem({ couponId: row.id,status:-1 }).then(response => {
+          this.$notify({
+            title: '成功',
+            message: '删除成功',
+            type: 'success',
+            duration: 2000
+          })
+          this.getList()
+        })
+      }).catch(() => {
+
+      })
+
+    },
+    delAll() {
+      this.$confirm("确认删除吗?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning",
+      })
+        .then(() => {
+          const length = this.multipleSelection.length;
+
+          if (length > 0) {
+            for (let i = 0; i < length; i++) {
+              this.delarr.push(this.multipleSelection[i].dictId);
+            }
+            const dictIds = this.delarr.join(",");
+            deleteitem({ dictIds: dictIds })
+              .then(() => {
+                this.$notify({
+                  title: "成功",
+                  message: "删除成功",
+                  type: "success",
+                  duration: 2000,
+                });
+                this.getList();
+              })
+              .catch(() => { });
+          } else {
+            this.$notify({
+              title: "警告提示",
+              message: "请选择要删除的信息!",
+              type: "warning",
+            });
+          }
+        })
+        .catch(() => { });
+    },
+    handleSelectionChange(val) {
+      this.multipleSelection = val;
+    },
+  }
+}
+</script>
+<style>
+.ad-avatar-uploader .el-upload {
+  border: 1px dashed #d9d9d9;
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+}
+
+.ad-avatar-uploader .el-upload:hover {
+  border-color: #409EFF;
+}
+
+.ad-avatar-uploader-icon {
+  font-size: 28px;
+  color: #8c939d;
+  width: 178px;
+  height: 178px;
+  line-height: 178px;
+  text-align: center;
+}
+
+.ad-avatar {
+  display: block;
+}
+</style>
+  

+ 1 - 1
src/views/dictManage/dictDataList.vue

@@ -45,7 +45,7 @@
                 <template slot-scope="scope">
                     <el-button type="primary" size="small" @click="handleUpdate(scope.row, false)">编辑</el-button>
 
-                    <el-button type="danger" size="mini" @click="handleDelete(scope.row)">删除</el-button>
+                    <el-button type="danger" size="small" @click="handleDelete(scope.row)">删除</el-button>
                 </template>
             </el-table-column>
         </el-table>

+ 1 - 1
src/views/dictManage/dictList.vue

@@ -58,7 +58,7 @@
               >编辑</el-button
             >
   
-            <el-button type="danger" size="mini"  @click="handleDelete(scope.row)">删除</el-button>
+            <el-button type="danger" size="small"  @click="handleDelete(scope.row)">删除</el-button>
           </template>
         </el-table-column>
       </el-table>

+ 5 - 0
src/views/exchangeManage/approvalList.vue

@@ -131,6 +131,11 @@
                         <el-input type="textarea" :rows="2" disabled v-model="addressStr"></el-input>
                     </el-form-item>
                 </div>
+                <div style="display: flex;">
+                    <el-form-item label="支付类型">
+                        <el-input disabled v-model="detailData.payTypeName"></el-input>
+                    </el-form-item>
+                </div>
             </el-form>
             <h3>商品信息</h3>
             <el-form status-icon label-position="center" label-width="100px" style="width:100%;">

+ 5 - 0
src/views/exchangeManage/cancelledList.vue

@@ -128,6 +128,11 @@
                         <el-input type="textarea" :rows="2" disabled v-model="addressStr"></el-input>
                     </el-form-item>
                 </div>
+                <div style="display: flex;">
+                    <el-form-item label="支付类型">
+                        <el-input disabled v-model="detailData.payTypeName"></el-input>
+                    </el-form-item>
+                </div>
             </el-form>
             <h3>商品信息</h3>
             <el-form status-icon label-position="center" label-width="100px" style="width:100%;">

+ 5 - 0
src/views/exchangeManage/exchangeList.vue

@@ -132,6 +132,11 @@
                         <el-input type="textarea" :rows="2" disabled v-model="addressStr"></el-input>
                     </el-form-item>
                 </div>
+                <div style="display: flex;">
+                    <el-form-item label="支付类型">
+                        <el-input disabled v-model="detailData.payTypeName"></el-input>
+                    </el-form-item>
+                </div>
             </el-form>
             <h3>商品信息</h3>
             <el-form status-icon label-position="center" label-width="100px" style="width:100%;">

+ 5 - 0
src/views/exchangeManage/pasList.vue

@@ -129,6 +129,11 @@
                         <el-input type="textarea" :rows="2" disabled v-model="addressStr"></el-input>
                     </el-form-item>
                 </div>
+                <div style="display: flex;">
+                    <el-form-item label="支付类型">
+                        <el-input disabled v-model="detailData.payTypeName"></el-input>
+                    </el-form-item>
+                </div>
             </el-form>
             <h3>商品信息</h3>
             <el-form status-icon label-position="center" label-width="100px" style="width:100%;">

+ 5 - 0
src/views/exchangeManage/voidList.vue

@@ -129,6 +129,11 @@
                         <el-input type="textarea" :rows="2" disabled v-model="addressStr"></el-input>
                     </el-form-item>
                 </div>
+                <div style="display: flex;">
+                    <el-form-item label="支付类型">
+                        <el-input disabled v-model="detailData.payTypeName"></el-input>
+                    </el-form-item>
+                </div>
             </el-form>
             <h3>商品信息</h3>
             <el-form status-icon label-position="center" label-width="100px" style="width:100%;">

+ 698 - 0
src/views/giftManage/giftList copy.vue

@@ -0,0 +1,698 @@
+<template>
+    <div class="app-container calendar-list-container">
+
+        <!-- 查询和其他操作 -->
+        <div class="filter-container">
+            <el-input clearable class="filter-item" style="width: 200px;" placeholder="礼品名称"
+                v-model="listQuery.name"></el-input>
+            <el-input clearable class="filter-item" style="width: 200px;" placeholder="礼品编号"
+                v-model="listQuery.seq"></el-input>
+            <el-select v-model="listQuery.status" clearable placeholder="状态" style="top: -4px;width: 200px;">
+                <el-option :key="item.type" v-for="item in goodsStatusList" :label="item.name" :value="item.type">
+                </el-option>
+            </el-select>
+            <el-select v-model="listQuery.productAttribute" clearable placeholder="商品属性" class="filter-item" style="width: 200px">
+                        <el-option :key="item.dictValue" v-for="item in productAttributeList" :label="item.dictLabel"
+                            :value="item.dictValue">
+                        </el-option>
+                    </el-select>
+            <el-select v-model="listQuery.deliveryType" clearable placeholder="兑换方式" class="filter-item" style="width: 200px">
+                        <el-option :key="item.type" v-for="item in deliveryTypeList" :label="item.name" :value="item.type">
+                        </el-option>
+            </el-select>
+            <el-button class="filter-item" type="primary" v-waves icon="el-icon-search" @click="handleFilter">查找</el-button>
+            <el-button class="filter-item" type="primary" @click="handleCreate" icon="el-icon-edit">添加</el-button>
+
+        </div>
+
+        <!-- 查询结果 -->
+        <el-table size="small" :data="list" v-loading="listLoading" element-loading-text="正在查询中。。。" border fit
+            highlight-current-row>
+            <el-table-column type="index" label="序号" header-align="center" align="center">
+            </el-table-column>
+
+            <el-table-column align="center" min-width="200px" label="礼品名称" prop="name">
+            </el-table-column>
+
+            <el-table-column align="center" min-width="120px" label="礼品编号" prop="seq">
+            </el-table-column>
+
+            <el-table-column align="center" min-width="80px" label="礼品属性" prop="productAttributeName">
+            </el-table-column>
+            <el-table-column align="center" min-width="100px" label="库存量" prop="actualStock">
+            </el-table-column>
+            <el-table-column align="center" min-width="100px" label="可兑换库存量" prop="stock">
+            </el-table-column>
+            <el-table-column align="center" min-width="150px" label="兑换方式" prop="deliveryTypeName">
+            </el-table-column>
+            <el-table-column align="center" min-width="100px" label="礼品所在地" prop="location">
+            </el-table-column>
+            <el-table-column align="center" min-width="80px" label="礼品状态">
+                <template slot-scope="props">
+                    <span v-if="props.row.status == 1">上架</span>
+                    <span v-if="props.row.status == 0">下架</span>
+                </template>
+            </el-table-column>
+            <el-table-column align="center" min-width="80px" label="兑换记录">
+                <template slot-scope="props">
+                    <span @click="handleView(props.row)" style="color:green;cursor: pointer;">查看</span>
+                </template>
+            </el-table-column>
+            <el-table-column align="center" min-width="80px" label="福利名称" prop="title">
+            </el-table-column>
+            <el-table-column align="center" label="操作" width="350px" class-name="small-padding fixed-width">
+                <template slot-scope="scope">
+                    <el-button type="primary" size="small" @click="handleUpdate(scope.row)">编辑</el-button>
+                    <el-button v-if="scope.row.status == 0" type="success" size="small"
+                        @click="changeGoodsState(scope.row.skuId, 1)">上架</el-button>
+                    <el-button v-if="scope.row.status == 1" type="warning" size="small"
+                        @click="changeGoodsState(scope.row.skuId, 0)">下架</el-button>
+                    <el-button type="primary" size="small" @click="handleRelated(scope.row)">关联福利</el-button>
+                    <el-button type="danger" size="mini" @click="handleDelete(scope.row.skuId, -1)">删除</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+
+        <!-- 分页 -->
+        <div class="pagination-container">
+            <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange"
+                :current-page="listQuery.page" :page-sizes="[10, 20, 30, 50]" :page-size="listQuery.limit"
+                layout="total, sizes, prev, pager, next, jumper" :total="total">
+            </el-pagination>
+        </div>
+
+        <!-- 员工积分记录列表 -->
+        <el-dialog :close-on-click-modal="false" title="兑换记录" :visible.sync="dialogListVisible" width="70%">
+            <div class="filter-container">
+                <el-select filterable v-model="itemListQuery.deptId" clearable placeholder="部门" style="top: -4px;width: 200px;">
+                    <el-option :key="item.deptId" v-for="item in depTypeList" :label="item.deptName" :value="item.deptId">
+                    </el-option>
+                </el-select>
+                <el-input clearable class="filter-item" style="width: 200px;" placeholder="员工名称"
+                    v-model="itemListQuery.purchaserName"></el-input>
+                <el-button class="filter-item" type="primary" v-waves icon="el-icon-search"
+                    @click="itemHandleFilter">查找</el-button>
+                <el-button class="filter-item" type="primary" v-waves icon="el-icon-download">导出</el-button>
+
+            </div>
+            <!-- 查询结果 -->
+            <el-table size="small" :data="itemList" v-loading="listLoading" element-loading-text="正在查询中。。。" border fit
+                highlight-current-row>
+                <el-table-column type="index" label="序号" header-align="center" align="center">
+                </el-table-column>
+                <el-table-column align="center" width="200px" label="部门" prop="deptName">
+                </el-table-column>
+                <el-table-column align="center" label="员工姓名" prop="purchaser">
+                </el-table-column>
+                <el-table-column align="center" label="兑换方式" prop="deliveryTypeName">
+                </el-table-column>
+                <el-table-column align="center" label="兑换数量" prop="skuCount">
+                </el-table-column>
+                <el-table-column align="center" label="联系人" prop="contact">
+                </el-table-column>
+                <el-table-column align="center" width="120px" label="联系方式" prop="contactPhone">
+                </el-table-column>
+                <el-table-column align="center" width="200px" label="地址" prop="contactAddr">
+                </el-table-column>
+                <el-table-column align="center" width="200px" label="邮箱" prop="contactEmail">
+                </el-table-column>
+                <el-table-column align="center" width="150px" label="兑换时间" prop="createTime">
+                </el-table-column>
+            </el-table>
+
+            <!-- 分页 -->
+            <div class="pagination-container">
+                <el-pagination background @size-change="itemHandleSizeChange" @current-change="itemHandleCurrentChange"
+                    :current-page="itemListQuery.page" :page-sizes="[10, 20, 30, 50]" :page-size="itemListQuery.limit"
+                    layout="total, sizes, prev, pager, next, jumper" :total="itemTotal">
+                </el-pagination>
+            </div>
+        </el-dialog>
+        <!-- 添加或修改对话框 -->
+        <el-dialog :close-on-click-modal="false" :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible" width="70%">
+            <el-form :rules="rules" ref="dataForm" :model="dataForm" status-icon label-position="left" label-width="100px" style='width:700px;margin-left:50px;'>
+                <el-form-item label="礼品编号" prop="seq">
+                    <el-input disabled placeholder="添加成功后自动生成" readonly v-model="dataForm.seq"></el-input>
+                </el-form-item>
+                <el-form-item label="礼品名称" prop="name">
+                    <el-input v-model="dataForm.name"></el-input>
+                </el-form-item>
+
+               
+
+                <el-form-item label="礼品属性" prop="productAttribute">
+                    <el-select v-model="dataForm.productAttribute" filterable placeholder="请选择" style="width: 350px"
+                        value-key="value" @change="changeProductAttribute">
+                        <el-option :key="item.dictValue" v-for="item in productAttributeList" :label="item.dictLabel"
+                            :value="item.dictValue">
+                        </el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="兑换方式" prop="deliveryType">
+                    <el-select v-model="dataForm.deliveryType" filterable placeholder="请选择" style="width: 350px">
+                        <el-option :key="item.type" v-for="item in deliveryTypeList" :label="item.name" :value="item.type">
+                        </el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item v-if="dataForm.deliveryType==0" label="礼品所在地" prop="location">
+                    <el-select v-model="dataForm.location" filterable placeholder="请选择" style="width: 350px">
+                        <el-option :key="item.dictLabel" v-for="item in locationList" :label="item.dictLabel" :value="item.dictLabel">
+                        </el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item style="width: 800px" label="礼品图片" prop="imgUrl">
+                    <el-upload :action="fileImgUrl" list-type="picture-card" :file-list="dataForm.images"
+                            :on-success="handleGallerySucess" :on-exceed="handleExceed" :before-upload="uploadBannerImg"
+                            :on-remove="handleRemove">
+                            <i class="el-icon-plus"></i>
+                        </el-upload>
+                </el-form-item>
+                <el-form-item label="库存量" prop="actualStock">
+                    <el-input-number :precision="0" :step="1" v-model="dataForm.actualStock"></el-input-number>
+                </el-form-item>
+                <el-form-item
+                    style="width: 800px"
+                    label="礼品说明"
+                    prop="comment"
+                    >
+                <tinymce v-model="dataForm.comment" ref="tinymce"></tinymce>
+                </el-form-item>
+            </el-form>
+            <div slot="footer" class="dialog-footer">
+                <el-button @click="dialogFormVisible = false">取消</el-button>
+                <el-button v-if="dialogStatus == 'create'" type="primary" @click="createData">确定</el-button>
+                <el-button v-else type="primary" @click="updateData">确定</el-button>
+            </div>
+        </el-dialog>
+
+         <!-- 关联福利操作 -->
+        <el-dialog :close-on-click-modal="false" title="关联福利" :visible.sync="dialogRelatedVisible" width="40%">
+            <div class="filter-container">
+                <el-select clearable v-model="welfareId" style="width: 100%;" placeholder="请选择">
+                    <el-option v-for="item in options" :key="item.id" :label="item.title" :value="item.id">
+                    </el-option>
+                </el-select>
+            </div>
+            <div slot="footer" class="dialog-footer">
+                <el-button @click="dialogRelatedVisible = false">取消</el-button>
+                <el-button type="primary" @click="handleRelatedWelfare">确定</el-button>
+            </div>
+        </el-dialog>
+    </div>
+</template>
+  
+<style>
+.demo-table-expand {
+    font-size: 0;
+}
+
+.demo-table-expand label {
+    width: 200px;
+    color: #99a9bf;
+}
+
+.demo-table-expand .el-form-item {
+    margin-right: 0;
+    margin-bottom: 0;
+}
+</style>
+  
+<script>
+import { createItem, updateItem, giftList, giftState, exchangeHistory, relatedWelfare, welfareList } from "@/api/giftManage";
+import { depTypeList,dataTypeList } from "@/api/public";
+import waves from "@/directive/waves"; // 水波纹指令
+import Tinymce from '@/components/Tinymce'
+
+export default {
+    name: 'giftList',
+    components: { Tinymce },
+    directives: { waves },
+    data() {
+        return {
+            welfareId:'',
+            skuId:'',
+            options: [],
+            locationList:[],
+            productAttributeList: [],
+            deliveryTypeList: [
+            {
+                    type: 0,
+                    name: '办公室领取'
+                },
+                {
+                    type: 1,
+                    name: '快递'
+                },
+                {
+                    type: 2,
+                    name: '卷码兑换'
+                },
+                {
+                    type: 3,
+                    name: '线下组织'
+                },
+               
+            ],
+            goodsStatusList: [
+                {
+                    type: 1,
+                    name: '上架'
+                },
+                {
+                    type: 0,
+                    name: '下架'
+                },
+            ],
+            depTypeList: [],
+            list: [],
+            itemList: [
+                
+            ],
+            total: 0,
+            itemTotal: 0,
+            listLoading: false,
+            downloadLoading: false,
+            listQuery: {
+                page: 1,
+                limit: 10,
+                name: '',
+                seq: '',
+                status: '',
+                productAttribute:'',
+                deliveryType:'',
+            },
+            itemListQuery: {
+                page: 1,
+                limit: 10,
+                deptId: '',
+                purchaserName: '',
+            },
+            dataForm: {
+                comment: undefined,
+                name: undefined,
+                seq: undefined,
+                productAttribute: undefined,
+                imgUrl: undefined,
+                integral: undefined,
+                actualStock: undefined,
+                deliveryType: undefined,
+                location: undefined,
+                images: [],
+            },
+            dialogFormVisible: false,
+            dialogStatus: '',
+            textMap: {
+                update: "编辑",
+                create: "创建",
+            },
+            rules: {
+                name: [{ required: true, message: "请填写礼品名称", trigger: "blur" }],
+                imgUrl: [{ required: true, message: "请上传礼品图片", trigger: "blur" }],
+                productAttribute: [{ required: true, message: "请选择礼品属性", trigger: "blur" }],
+                integral: [{ required: true, message: "请填写礼品积分", trigger: "blur" }],
+                actualStock: [{ required: true, message: "请设置库存量", trigger: "blur" }],
+                deliveryType: [{ required: true, message: "请选择兑换方式", trigger: "blur" }],
+                location: [{ required: true, message: "请选择礼品所在地", trigger: "blur" }],
+                comment: [{ required: true, message: "说明不能为空", trigger: "blur" }],
+            },
+            dialogListVisible: false,
+            dialogRelatedVisible:false,
+            fileImgUrl: this.upLoadUrl,
+        }
+    },
+    created() {
+        this.getProductAttributeList();
+        this.getDataTypeList(); 
+        this.getDepTypeList(); 
+        this.getList();
+    },
+    methods: {
+        getDataTypeList() {
+            dataTypeList({dictType:'mall_sku_location'}).then(response => {
+                this.locationList = response.data.data;
+            }).catch(() => {});
+        },
+        getProductAttributeList(){
+            dataTypeList({dictType:'mall_sku_attribute'}).then(response => {
+                this.productAttributeList = response.data.data;
+            }).catch(() => {});
+        },
+        getWelfareList(){
+            welfareList({status:1}).then(response => {
+                this.options = response.data.data;
+            }).catch(() => {});
+        },
+        changeProductAttribute(val) {
+            this.dataForm.deliveryType = undefined;
+            this.dataForm.location = undefined;
+            this.deliveryTypeList = [
+                {
+                    type: 0,
+                    name: '办公室领取'
+                },
+                {
+                    type: 1,
+                    name: '快递'
+                },
+                {
+                    type: 2,
+                    name: '卷码兑换'
+                },
+                {
+                    type: 3,
+                    name: '线下组织'
+                },
+               
+            ];
+            if (val == 1) {
+                this.deliveryTypeList = [
+                    {
+                        type: 1,
+                        name: '快递'
+                    },
+                    {
+                        type: 0,
+                        name: '办公室领取'
+                    },
+                ]
+            } 
+            if (val == 2 || val == 3)  {
+                this.deliveryTypeList = [
+                    {
+                        type: 2,
+                        name: '卷码兑换'
+                    },
+                ]
+            }
+            if (val == 5)  {
+                this.deliveryTypeList = [
+                    {
+                        type: 3,
+                        name: '线下组织'
+                    },
+                ]
+            }
+        },
+        handleRemove(file, fileList) {
+            console.log(file, fileList);
+            let images = [];
+            for (let i in fileList) {
+                let response = fileList[i].response;
+                let url = response.data.url;
+                images.push(url);
+                this.dataForm.imgUrl = images.join(",");
+            }
+        },
+        uploadBannerImg(file) {
+            const isJPGs = file.type === "image/jpeg";
+            console.log(isJPGs);
+        },
+        handleExceed(files, fileList) {
+            this.$message.warning(
+                `当前限制选择 5 个文件,本次选择了 ${files.length} 个文件!,共选择了 ${files.length + fileList.length
+                } 个文件`
+            );
+        },
+        handleGallerySucess(res, file, fileList) {
+            this.dataForm.imgUrl = ""; // 清空画廊图片数组
+
+            let images = [];
+            for (let i in fileList) {
+                let response = fileList[i].response;
+                if (response.errno && response.errno != "0") {
+                    this.$message.error("该图片上传失败,已被移除,请重新上传!");
+                    // 上传失败移除该 file 对象
+                    fileList.splice(i, 1);
+                } else {
+                    let url = response.data.url;
+                    images.push(url);
+                }
+            }
+
+            this.dataForm.imgUrl = images.join(",");
+        },
+        resetForm() {
+            this.dataForm = {
+                comment: undefined,
+                name: undefined,
+                seq: undefined,
+                productAttribute: undefined,
+                imgUrl: undefined,
+                integral: undefined,
+                actualStock: undefined,
+                deliveryType: undefined,
+                location: undefined,
+                images: [],
+            };
+        },
+        handleCreate() {
+            this.resetForm();
+
+            this.dialogFormVisible = true;
+            this.dialogStatus = "create";
+
+            this.$nextTick(() => {
+                this.$refs.tinymce.setContent("");
+                this.$refs["dataForm"].clearValidate();
+            });
+        },
+        createData() {
+            
+            this.$refs["dataForm"].validate((valid) => {
+                if (valid) {
+                    createItem(this.dataForm)
+                            .then((response) => {
+                                this.getList();
+                                this.dialogFormVisible = false;
+                                this.$notify({
+                                    title: "成功",
+                                    message: "创建成功",
+                                    type: "success",
+                                    duration: 2000,
+                                });
+                                this.reload();
+                            })
+                            .catch(() => { });
+                }
+            });
+        },
+        handleUpdate(row) {
+            this.dataForm = Object.assign({}, row);
+            this.dataForm.productAttribute = row.productAttribute.toString();
+            let comment = this.dataForm.comment;
+            let val = row.productAttribute;
+            this.deliveryTypeList = [
+                {
+                    type: 0,
+                    name: '办公室领取'
+                },
+                {
+                    type: 1,
+                    name: '快递'
+                },
+                {
+                    type: 2,
+                    name: '卷码兑换'
+                },
+                {
+                    type: 3,
+                    name: '线下组织'
+                },
+               
+            ];
+            if (val == 1) {
+                this.deliveryTypeList = [
+                    {
+                        type: 1,
+                        name: '快递'
+                    },
+                    {
+                        type: 0,
+                        name: '办公室领取'
+                    },
+                ]
+            } 
+            if (val == 2 || val == 3)  {
+                this.deliveryTypeList = [
+                    {
+                        type: 2,
+                        name: '卷码兑换'
+                    },
+                ]
+            }
+            if (val == 5)  {
+                this.deliveryTypeList = [
+                    {
+                        type: 3,
+                        name: '线下组织'
+                    },
+                ]
+            }
+            if (this.dataForm.imgUrl) {
+                let images = this.dataForm.imgUrl.split(",");
+                this.dataForm.images = [];
+                for (let i in images) {
+                    let url = images[i];
+                    let name = "image_" + i;
+
+                    this.dataForm.images.push({
+                        name: name,
+                        url: url,
+                        response: { error: "0", data: { url: url } },
+                    });
+                }
+            }
+            this.dialogStatus = 'update'
+            this.dialogFormVisible = true
+            this.$nextTick(() => {
+                this.$refs.tinymce.setContent(comment);
+                this.$refs['dataForm'].clearValidate()
+            })
+        },
+        updateData() {
+            this.$refs['dataForm'].validate((valid) => {
+                if (valid) {
+                    updateItem(this.dataForm).then(() => {
+                            this.dialogFormVisible = false
+                            this.$notify({
+                                title: '成功',
+                                message: '更新成功',
+                                type: 'success',
+                                duration: 2000
+                            })
+                            this.getList()
+                        })
+
+                }
+
+            })
+        },
+        handleRelated(row) {
+            this.welfareId = '';
+            this.skuId = row.skuId;
+            this.getWelfareList();
+            this.dialogRelatedVisible = true
+        },
+        handleRelatedWelfare(){
+            relatedWelfare({ skuId: this.skuId, welfareId: this.welfareId }).then(response => {
+                this.dialogRelatedVisible = false;
+                this.$notify({
+                    title: '成功',
+                    message: '福利关联成功',
+                    type: 'success',
+                    duration: 2000
+                })
+                this.getList()
+            })
+        },
+        changeGoodsState(id, index) {
+            giftState({ skuId: id, status: index }).then(response => {
+                this.$notify({
+                    title: '成功',
+                    message: '礼品状态修改成功',
+                    type: 'success',
+                    duration: 2000
+                })
+                this.getList()
+            })
+        },
+        handleDelete(id, index) {
+            this.$confirm('确认删除吗?', '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning'
+            }).then(() => {
+                giftState({ skuId: id, status: index }).then(response => {
+                    this.$notify({
+                        title: '成功',
+                        message: '删除成功',
+                        type: 'success',
+                        duration: 2000
+                    })
+                    this.getList();
+                })
+            }).catch(() => {})
+        },
+        getDepTypeList() {
+            depTypeList().then(response => {
+                this.depTypeList = response.data.data;
+            }).catch(() => {});
+        },
+        getList() {
+            this.listLoading = true
+            giftList(this.listQuery).then(response => {
+                this.list = response.data.data.items
+                this.total = response.data.data.total
+                this.listLoading = false
+            }).catch(() => {})
+        },
+        getItemList() {
+            this.listLoading = true
+            exchangeHistory(this.itemListQuery).then(response => {
+                this.itemList = response.data.data.items
+                this.itemLotal = response.data.data.total
+                this.listLoading = false
+            }).catch(() => {})
+        },
+
+        handleFilter() {
+            this.listQuery.page = 1
+            this.getList()
+        },
+        handleSizeChange(val) {
+            this.listQuery.limit = val
+            this.getList()
+        },
+        handleCurrentChange(val) {
+            this.listQuery.page = val
+            this.getList()
+        },
+
+        itemHandleFilter() {
+            this.itemListQuery.page = 1
+            this.getItemList()
+        },
+        itemHandleSizeChange(val) {
+            this.itemListQuery.limit = val
+            this.getItemList()
+        },
+        itemHandleCurrentChange(val) {
+            this.itemListQuery.page = val
+            this.getItemList()
+        },
+
+        handleView(row) {
+            this.itemListQuery.id = row.id;
+            this.getItemList()
+            this.dialogListVisible = true
+        },
+    }
+}
+</script>
+<style>
+.ad-avatar-uploader .el-upload {
+    border: 1px dashed #d9d9d9;
+    border-radius: 6px;
+    cursor: pointer;
+    position: relative;
+    overflow: hidden;
+}
+
+.ad-avatar-uploader .el-upload:hover {
+    border-color: #409EFF;
+}
+
+.ad-avatar-uploader-icon {
+    font-size: 28px;
+    color: #8c939d;
+    width: 178px;
+    height: 178px;
+    line-height: 178px;
+    text-align: center;
+}
+
+.ad-avatar {
+    display: block;
+}
+</style>
+  

+ 183 - 240
src/views/giftManage/giftList.vue

@@ -3,11 +3,11 @@
 
         <!-- 查询和其他操作 -->
         <div class="filter-container">
-            <el-input clearable class="filter-item" style="width: 200px;" placeholder="品名称"
+            <el-input clearable class="filter-item" style="width: 200px;" placeholder="品名称"
                 v-model="listQuery.name"></el-input>
-            <el-input clearable class="filter-item" style="width: 200px;" placeholder="品编号"
+            <el-input clearable class="filter-item" style="width: 200px;" placeholder="品编号"
                 v-model="listQuery.seq"></el-input>
-            <el-select v-model="listQuery.status" clearable placeholder="状态" style="top: -4px;width: 200px;">
+            <el-select v-model="listQuery.status" clearable placeholder="状态" class="filter-item" style="width: 200px;">
                 <el-option :key="item.type" v-for="item in goodsStatusList" :label="item.name" :value="item.type">
                 </el-option>
             </el-select>
@@ -16,10 +16,6 @@
                             :value="item.dictValue">
                         </el-option>
                     </el-select>
-            <el-select v-model="listQuery.deliveryType" clearable placeholder="兑换方式" class="filter-item" style="width: 200px">
-                        <el-option :key="item.type" v-for="item in deliveryTypeList" :label="item.name" :value="item.type">
-                        </el-option>
-            </el-select>
             <el-button class="filter-item" type="primary" v-waves icon="el-icon-search" @click="handleFilter">查找</el-button>
             <el-button class="filter-item" type="primary" @click="handleCreate" icon="el-icon-edit">添加</el-button>
 
@@ -31,23 +27,25 @@
             <el-table-column type="index" label="序号" header-align="center" align="center">
             </el-table-column>
 
-            <el-table-column align="center" min-width="200px" label="品名称" prop="name">
+            <el-table-column align="center" min-width="200px" label="品名称" prop="name">
             </el-table-column>
 
-            <el-table-column align="center" min-width="120px" label="品编号" prop="seq">
+            <el-table-column align="center" min-width="120px" label="品编号" prop="seq">
             </el-table-column>
 
-            <el-table-column align="center" min-width="80px" label="品属性" prop="productAttributeName">
+            <el-table-column align="center" min-width="80px" label="品属性" prop="productAttributeName">
             </el-table-column>
-            <el-table-column align="center" min-width="100px" label="库存量" prop="actualStock">
+            <el-table-column align="center" min-width="80px" label="积分" prop="price">
             </el-table-column>
-            <el-table-column align="center" min-width="100px" label="可兑换库存量" prop="stock">
+            <el-table-column align="center" min-width="80px" label="参考价格" prop="hisPrice">
             </el-table-column>
-            <el-table-column align="center" min-width="150px" label="兑换方式" prop="deliveryTypeName">
+            <el-table-column align="center" min-width="100px" label="库存量" prop="actualStock">
             </el-table-column>
-            <el-table-column align="center" min-width="100px" label="礼品所在地" prop="location">
+            <el-table-column align="center" min-width="100px" label="可兑换库存量" prop="stock">
             </el-table-column>
-            <el-table-column align="center" min-width="80px" label="礼品状态">
+            <!-- <el-table-column align="center" min-width="100px" label="商品所在地" prop="location">
+            </el-table-column> -->
+            <el-table-column align="center" min-width="80px" label="商品状态">
                 <template slot-scope="props">
                     <span v-if="props.row.status == 1">上架</span>
                     <span v-if="props.row.status == 0">下架</span>
@@ -58,17 +56,15 @@
                     <span @click="handleView(props.row)" style="color:green;cursor: pointer;">查看</span>
                 </template>
             </el-table-column>
-            <el-table-column align="center" min-width="80px" label="福利名称" prop="title">
-            </el-table-column>
-            <el-table-column align="center" label="操作" width="350px" class-name="small-padding fixed-width">
+            <!-- fixed="right" -->
+            <el-table-column align="center" label="操作" width="240px" class-name="small-padding fixed-width">
                 <template slot-scope="scope">
                     <el-button type="primary" size="small" @click="handleUpdate(scope.row)">编辑</el-button>
                     <el-button v-if="scope.row.status == 0" type="success" size="small"
                         @click="changeGoodsState(scope.row.skuId, 1)">上架</el-button>
                     <el-button v-if="scope.row.status == 1" type="warning" size="small"
                         @click="changeGoodsState(scope.row.skuId, 0)">下架</el-button>
-                    <el-button type="primary" size="small" @click="handleRelated(scope.row)">关联福利</el-button>
-                    <el-button type="danger" size="mini" @click="handleDelete(scope.row.skuId, -1)">删除</el-button>
+                    <el-button type="danger" size="small" @click="handleDelete(scope.row.skuId, -1)">删除</el-button>
                 </template>
             </el-table-column>
         </el-table>
@@ -82,30 +78,28 @@
         </div>
 
         <!-- 员工积分记录列表 -->
-        <el-dialog :close-on-click-modal="false" title="兑换记录" :visible.sync="dialogListVisible" width="70%">
+        <el-dialog :close-on-click-modal="false" title="兑换记录" :visible.sync="dialogListVisible" width="70%" style="overflow: auto;">
             <div class="filter-container">
                 <el-select filterable v-model="itemListQuery.deptId" clearable placeholder="部门" style="top: -4px;width: 200px;">
                     <el-option :key="item.deptId" v-for="item in depTypeList" :label="item.deptName" :value="item.deptId">
                     </el-option>
                 </el-select>
                 <el-input clearable class="filter-item" style="width: 200px;" placeholder="员工名称"
-                    v-model="itemListQuery.purchaserName"></el-input>
+                    v-model="itemListQuery.userName"></el-input>
                 <el-button class="filter-item" type="primary" v-waves icon="el-icon-search"
                     @click="itemHandleFilter">查找</el-button>
-                <el-button class="filter-item" type="primary" v-waves icon="el-icon-download">导出</el-button>
+                <el-button class="filter-item" type="primary" @click="handleDownLoad" v-waves icon="el-icon-download">导出</el-button>
 
             </div>
             <!-- 查询结果 -->
             <el-table size="small" :data="itemList" v-loading="listLoading" element-loading-text="正在查询中。。。" border fit
-                highlight-current-row>
-                <el-table-column type="index" label="序号" header-align="center" align="center">
+            highlight-current-row>
+            <el-table-column type="index" label="序号" header-align="center" align="center">
                 </el-table-column>
                 <el-table-column align="center" width="200px" label="部门" prop="deptName">
                 </el-table-column>
                 <el-table-column align="center" label="员工姓名" prop="purchaser">
                 </el-table-column>
-                <el-table-column align="center" label="兑换方式" prop="deliveryTypeName">
-                </el-table-column>
                 <el-table-column align="center" label="兑换数量" prop="skuCount">
                 </el-table-column>
                 <el-table-column align="center" label="联系人" prop="contact">
@@ -114,12 +108,11 @@
                 </el-table-column>
                 <el-table-column align="center" width="200px" label="地址" prop="contactAddr">
                 </el-table-column>
-                <el-table-column align="center" width="200px" label="邮箱" prop="contactEmail">
-                </el-table-column>
+                <!-- <el-table-column align="center" width="200px" label="邮箱" prop="contactEmail">
+                </el-table-column> -->
                 <el-table-column align="center" width="150px" label="兑换时间" prop="createTime">
                 </el-table-column>
-            </el-table>
-
+        </el-table>
             <!-- 分页 -->
             <div class="pagination-container">
                 <el-pagination background @size-change="itemHandleSizeChange" @current-change="itemHandleCurrentChange"
@@ -130,17 +123,17 @@
         </el-dialog>
         <!-- 添加或修改对话框 -->
         <el-dialog :close-on-click-modal="false" :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible" width="70%">
-            <el-form :rules="rules" ref="dataForm" :model="dataForm" status-icon label-position="left" label-width="100px" style='width:700px;margin-left:50px;'>
-                <el-form-item label="品编号" prop="seq">
+            <el-form :rules="rules" ref="dataForm" :model="dataForm" status-icon label-position="left" label-width="100px" style='width:700px; margin-left:50px;'>
+                <el-form-item label="品编号" prop="seq">
                     <el-input disabled placeholder="添加成功后自动生成" readonly v-model="dataForm.seq"></el-input>
                 </el-form-item>
-                <el-form-item label="品名称" prop="name">
+                <el-form-item label="品名称" prop="name">
                     <el-input v-model="dataForm.name"></el-input>
                 </el-form-item>
 
-               
+                
 
-                <el-form-item label="品属性" prop="productAttribute">
+                <el-form-item label="品属性" prop="productAttribute">
                     <el-select v-model="dataForm.productAttribute" filterable placeholder="请选择" style="width: 350px"
                         value-key="value" @change="changeProductAttribute">
                         <el-option :key="item.dictValue" v-for="item in productAttributeList" :label="item.dictLabel"
@@ -148,35 +141,63 @@
                         </el-option>
                     </el-select>
                 </el-form-item>
-                <el-form-item label="兑换方式" prop="deliveryType">
-                    <el-select v-model="dataForm.deliveryType" filterable placeholder="请选择" style="width: 350px">
-                        <el-option :key="item.type" v-for="item in deliveryTypeList" :label="item.name" :value="item.type">
+                <el-form-item label="兑换方式" prop="deliveryTypes">
+                    <el-select v-model="dataForm.deliveryTypes" multiple filterable placeholder="请选择" style="width: 350px">
+                        <el-option :key="item.dictValue" v-for="item in deliveryTypeList" :label="item.dictLabel" :value="item.dictValue">
                         </el-option>
                     </el-select>
                 </el-form-item>
-                <el-form-item v-if="dataForm.deliveryType==0" label="礼品所在地" prop="location">
-                    <el-select v-model="dataForm.location" filterable placeholder="请选择" style="width: 350px">
-                        <el-option :key="item.dictLabel" v-for="item in locationList" :label="item.dictLabel" :value="item.dictLabel">
-                        </el-option>
-                    </el-select>
+                <el-form-item v-if="dataForm.deliveryTypes.includes('1')" label="快递方式">
+                    <el-radio-group v-model="dataForm.freightType">
+                        <el-radio :label="'0'">不包邮</el-radio>
+                        <el-radio :label="'1'">包邮</el-radio>
+                    </el-radio-group>
                 </el-form-item>
-                <el-form-item style="width: 800px" label="品图片" prop="imgUrl">
-                    <el-upload :action="fileImgUrl" list-type="picture-card" :file-list="dataForm.images"
+                <el-form-item style="width: 800px" label="品图片" prop="imgUrl">
+                    <el-upload :limit="1" :action="fileImgUrl" list-type="picture-card" :file-list="dataForm.images"
                             :on-success="handleGallerySucess" :on-exceed="handleExceed" :before-upload="uploadBannerImg"
                             :on-remove="handleRemove">
                             <i class="el-icon-plus"></i>
                         </el-upload>
                 </el-form-item>
+                <el-form-item style="width: 800px" label="商品副图">
+                    <el-upload :action="fileImgUrl" list-type="picture-card" :file-list="dataForm.imgUrls"
+                            :on-success="handleAvatarSuccess"
+                            :on-remove="handleRemoveImgs">
+                            <i class="el-icon-plus"></i>
+                        </el-upload>
+                </el-form-item>
+
+                <el-form-item label="积分" prop="price">
+                    <el-input v-model="dataForm.price"></el-input>
+                </el-form-item>
+                <el-form-item label="参考价格" prop="hisPrice">
+                    <el-input v-model="dataForm.hisPrice"></el-input>
+                </el-form-item>
                 <el-form-item label="库存量" prop="actualStock">
                     <el-input-number :precision="0" :step="1" v-model="dataForm.actualStock"></el-input-number>
                 </el-form-item>
                 <el-form-item
                     style="width: 800px"
-                    label="礼品说明"
+                    label="品说明"
                     prop="comment"
                     >
                 <tinymce v-model="dataForm.comment" ref="tinymce"></tinymce>
                 </el-form-item>
+                <el-form-item style="width: 800px" label="商品副图">
+                    <el-upload :action="fileImgUrl" list-type="picture-card" :file-list="dataForm.imgUrls"
+                            :on-success="handleAvatarSuccess"
+                            :on-remove="handleRemoveImgs">
+                            <i class="el-icon-plus"></i>
+                        </el-upload>
+                </el-form-item>
+                <el-form-item
+                    style="width: 800px"
+                    label="商品介绍"
+                    prop="skuDesc"
+                    >
+                <skuDesc v-model="dataForm.skuDesc" ref="skuDesc"></skuDesc>
+                </el-form-item>
             </el-form>
             <div slot="footer" class="dialog-footer">
                 <el-button @click="dialogFormVisible = false">取消</el-button>
@@ -185,19 +206,6 @@
             </div>
         </el-dialog>
 
-         <!-- 关联福利操作 -->
-        <el-dialog :close-on-click-modal="false" title="关联福利" :visible.sync="dialogRelatedVisible" width="40%">
-            <div class="filter-container">
-                <el-select clearable v-model="welfareId" style="width: 100%;" placeholder="请选择">
-                    <el-option v-for="item in options" :key="item.id" :label="item.title" :value="item.id">
-                    </el-option>
-                </el-select>
-            </div>
-            <div slot="footer" class="dialog-footer">
-                <el-button @click="dialogRelatedVisible = false">取消</el-button>
-                <el-button type="primary" @click="handleRelatedWelfare">确定</el-button>
-            </div>
-        </el-dialog>
     </div>
 </template>
   
@@ -218,41 +226,21 @@
 </style>
   
 <script>
-import { createItem, updateItem, giftList, giftState, exchangeHistory, relatedWelfare, welfareList } from "@/api/giftManage";
+import { createItem, updateItem, goodsList, goodsState, exchangeHistory } from "@/api/goodsManage";
 import { depTypeList,dataTypeList } from "@/api/public";
 import waves from "@/directive/waves"; // 水波纹指令
-import Tinymce from '@/components/Tinymce'
+import Tinymce from '@/components/Tinymce';
+import SkuDesc from '@/components/SkuDesc'
 
 export default {
-    name: 'giftList',
-    components: { Tinymce },
+    name: 'goodsList',
+    components: { Tinymce,SkuDesc },
     directives: { waves },
     data() {
         return {
-            welfareId:'',
-            skuId:'',
-            options: [],
             locationList:[],
             productAttributeList: [],
-            deliveryTypeList: [
-            {
-                    type: 0,
-                    name: '办公室领取'
-                },
-                {
-                    type: 1,
-                    name: '快递'
-                },
-                {
-                    type: 2,
-                    name: '卷码兑换'
-                },
-                {
-                    type: 3,
-                    name: '线下组织'
-                },
-               
-            ],
+            deliveryTypeList: [],
             goodsStatusList: [
                 {
                     type: 1,
@@ -265,39 +253,43 @@ export default {
             ],
             depTypeList: [],
             list: [],
-            itemList: [
-                
-            ],
+            itemList: [],
             total: 0,
             itemTotal: 0,
             listLoading: false,
             downloadLoading: false,
             listQuery: {
+                skuType:1,
                 page: 1,
                 limit: 10,
                 name: '',
                 seq: '',
                 status: '',
                 productAttribute:'',
-                deliveryType:'',
             },
             itemListQuery: {
+                skuType:1,
                 page: 1,
                 limit: 10,
+                skuId:'',
                 deptId: '',
-                purchaserName: '',
+                userName: '',
             },
             dataForm: {
-                comment: undefined,
+                skuType:1,
                 name: undefined,
                 seq: undefined,
                 productAttribute: undefined,
                 imgUrl: undefined,
-                integral: undefined,
+                price: undefined,
+                hisPrice:undefined,
                 actualStock: undefined,
-                deliveryType: undefined,
-                location: undefined,
+                deliveryTypes: [],
+                freightType:'0',
+                // location: undefined,
                 images: [],
+                imgIds: '',
+                imgUrls:[],
             },
             dialogFormVisible: false,
             dialogStatus: '',
@@ -306,17 +298,19 @@ export default {
                 create: "创建",
             },
             rules: {
-                name: [{ required: true, message: "请填写礼品名称", trigger: "blur" }],
-                imgUrl: [{ required: true, message: "请上传礼品图片", trigger: "blur" }],
-                productAttribute: [{ required: true, message: "请选择礼品属性", trigger: "blur" }],
-                integral: [{ required: true, message: "请填写礼品积分", trigger: "blur" }],
+                name: [{ required: true, message: "请填写商品名称", trigger: "blur" }],
+                imgUrl: [{ required: true, message: "请上传商品图片", trigger: "blur" }],
+                imgIds: [{ required: true, message: "请上传商品副图", trigger: "blur" }],
+                productAttribute: [{ required: true, message: "请选择商品属性", trigger: "blur" }],
+                price: [{ required: true, message: "请填写商品积分", trigger: "blur" }],
+                hisPrice: [{ required: true, message: "请填写商品参考价格", trigger: "blur" }],
                 actualStock: [{ required: true, message: "请设置库存量", trigger: "blur" }],
-                deliveryType: [{ required: true, message: "请选择兑换方式", trigger: "blur" }],
-                location: [{ required: true, message: "请选择礼品所在地", trigger: "blur" }],
+                deliveryTypes: [{ required: true, message: "请选择兑换方式", trigger: "blur" }],
+                // location: [{ required: true, message: "请选择商品所在地", trigger: "blur" }],
                 comment: [{ required: true, message: "说明不能为空", trigger: "blur" }],
+                skuDesc: [{ required: true, message: "商品介绍不能为空", trigger: "blur" }],
             },
             dialogListVisible: false,
-            dialogRelatedVisible:false,
             fileImgUrl: this.upLoadUrl,
         }
     },
@@ -327,71 +321,19 @@ export default {
         this.getList();
     },
     methods: {
-        getDataTypeList() {
-            dataTypeList({dictType:'mall_sku_location'}).then(response => {
-                this.locationList = response.data.data;
-            }).catch(() => {});
-        },
-        getProductAttributeList(){
-            dataTypeList({dictType:'mall_sku_attribute'}).then(response => {
-                this.productAttributeList = response.data.data;
-            }).catch(() => {});
+        getDeliveryTypeList(val){
+            dataTypeList({dictType:val}).then(response => {
+                this.deliveryTypeList = response.data.data;
+            });
         },
-        getWelfareList(){
-            welfareList({status:1}).then(response => {
-                this.options = response.data.data;
-            }).catch(() => {});
+        handleDownLoad(){
+            window.location.href = process.env.BASE_API + '/mall-sku/exportSkuLog?skuId=' + this.itemListQuery.skuId + '&deptId=' + this.itemListQuery.deptId + '&userName=' + this.itemListQuery.userName;
         },
         changeProductAttribute(val) {
-            this.dataForm.deliveryType = undefined;
-            this.dataForm.location = undefined;
-            this.deliveryTypeList = [
-                {
-                    type: 0,
-                    name: '办公室领取'
-                },
-                {
-                    type: 1,
-                    name: '快递'
-                },
-                {
-                    type: 2,
-                    name: '卷码兑换'
-                },
-                {
-                    type: 3,
-                    name: '线下组织'
-                },
-               
-            ];
-            if (val == 1) {
-                this.deliveryTypeList = [
-                    {
-                        type: 1,
-                        name: '快递'
-                    },
-                    {
-                        type: 0,
-                        name: '办公室领取'
-                    },
-                ]
-            } 
-            if (val == 2 || val == 3)  {
-                this.deliveryTypeList = [
-                    {
-                        type: 2,
-                        name: '卷码兑换'
-                    },
-                ]
-            }
-            if (val == 5)  {
-                this.deliveryTypeList = [
-                    {
-                        type: 3,
-                        name: '线下组织'
-                    },
-                ]
-            }
+            debugger
+            this.dataForm.deliveryTypes = [];
+            // this.dataForm.location = undefined;
+            this.getDeliveryTypeList(val);
         },
         handleRemove(file, fileList) {
             console.log(file, fileList);
@@ -403,13 +345,41 @@ export default {
                 this.dataForm.imgUrl = images.join(",");
             }
         },
+        handleAvatarSuccess(res, file, fileList) {
+            console.log(file, fileList);
+            console.log("------", "==========");
+            console.log("res = ", res);
+
+            let fileIds = [];
+            for (let i in fileList) {
+                let response = fileList[i].response;
+                if (response.errno && response.errno != "0") {
+                this.$message.error("该文件上传失败,已被移除,请重新上传!");
+                // 上传失败移除该 file 对象
+                fileList.splice(i, 1);
+                } else {
+                let id = fileList[i].response.data.id;
+                fileIds.push(id);
+                }
+            }
+            this.dataForm.imgIds = fileIds.join(",");
+        },
+        handleRemoveImgs(file, fileList) {
+            console.log(file, fileList);
+            let fileIds = [];
+            for (let i in fileList) {
+                let id = fileList[i].response.data.id;
+                fileIds.push(id);
+            }
+            this.dataForm.imgIds = fileIds.join(",");
+        },
         uploadBannerImg(file) {
             const isJPGs = file.type === "image/jpeg";
             console.log(isJPGs);
         },
         handleExceed(files, fileList) {
             this.$message.warning(
-                `当前限制选择 5 个文件,本次选择了 ${files.length} 个文件!,共选择了 ${files.length + fileList.length
+                `当前限制选择 1 个文件,本次选择了 ${files.length} 个文件!,共选择了 ${files.length + fileList.length
                 } 个文件`
             );
         },
@@ -433,16 +403,22 @@ export default {
         },
         resetForm() {
             this.dataForm = {
+                skuType:1,
                 comment: undefined,
+                skuDesc: undefined,
                 name: undefined,
                 seq: undefined,
                 productAttribute: undefined,
                 imgUrl: undefined,
-                integral: undefined,
+                price: undefined,
+                hisPrice:undefined,
                 actualStock: undefined,
-                deliveryType: undefined,
-                location: undefined,
+                deliveryTypes: [],
+                freightType:'0',
+                // location: undefined,
                 images: [],
+                imgIds: '',
+                imgUrls:[],
             };
         },
         handleCreate() {
@@ -453,6 +429,7 @@ export default {
 
             this.$nextTick(() => {
                 this.$refs.tinymce.setContent("");
+                this.$refs.skuDesc.setContent("");
                 this.$refs["dataForm"].clearValidate();
             });
         },
@@ -460,6 +437,7 @@ export default {
             
             this.$refs["dataForm"].validate((valid) => {
                 if (valid) {
+                    console.log(this.dataForm);
                     createItem(this.dataForm)
                             .then((response) => {
                                 this.getList();
@@ -480,54 +458,9 @@ export default {
             this.dataForm = Object.assign({}, row);
             this.dataForm.productAttribute = row.productAttribute.toString();
             let comment = this.dataForm.comment;
+            let skuDesc = this.dataForm.skuDesc?this.dataForm.skuDesc:'';
             let val = row.productAttribute;
-            this.deliveryTypeList = [
-                {
-                    type: 0,
-                    name: '办公室领取'
-                },
-                {
-                    type: 1,
-                    name: '快递'
-                },
-                {
-                    type: 2,
-                    name: '卷码兑换'
-                },
-                {
-                    type: 3,
-                    name: '线下组织'
-                },
-               
-            ];
-            if (val == 1) {
-                this.deliveryTypeList = [
-                    {
-                        type: 1,
-                        name: '快递'
-                    },
-                    {
-                        type: 0,
-                        name: '办公室领取'
-                    },
-                ]
-            } 
-            if (val == 2 || val == 3)  {
-                this.deliveryTypeList = [
-                    {
-                        type: 2,
-                        name: '卷码兑换'
-                    },
-                ]
-            }
-            if (val == 5)  {
-                this.deliveryTypeList = [
-                    {
-                        type: 3,
-                        name: '线下组织'
-                    },
-                ]
-            }
+            this.getDeliveryTypeList(val);
             if (this.dataForm.imgUrl) {
                 let images = this.dataForm.imgUrl.split(",");
                 this.dataForm.images = [];
@@ -542,10 +475,25 @@ export default {
                     });
                 }
             }
+            if (this.dataForm.imgs) {
+                let imgs = this.dataForm.imgs;
+                this.dataForm.imgUrls = [];
+                for (let i in imgs) {
+                    let url = imgs[i].url;
+                    let name = "image_" + i;
+
+                    this.dataForm.imgUrls.push({
+                        name: name,
+                        url: url,
+                        response: { error: "0", data: imgs[i] },
+                    });
+                }
+            }
             this.dialogStatus = 'update'
             this.dialogFormVisible = true
             this.$nextTick(() => {
                 this.$refs.tinymce.setContent(comment);
+                this.$refs.skuDesc.setContent(skuDesc);
                 this.$refs['dataForm'].clearValidate()
             })
         },
@@ -567,29 +515,11 @@ export default {
 
             })
         },
-        handleRelated(row) {
-            this.welfareId = '';
-            this.skuId = row.skuId;
-            this.getWelfareList();
-            this.dialogRelatedVisible = true
-        },
-        handleRelatedWelfare(){
-            relatedWelfare({ skuId: this.skuId, welfareId: this.welfareId }).then(response => {
-                this.dialogRelatedVisible = false;
-                this.$notify({
-                    title: '成功',
-                    message: '福利关联成功',
-                    type: 'success',
-                    duration: 2000
-                })
-                this.getList()
-            })
-        },
         changeGoodsState(id, index) {
-            giftState({ skuId: id, status: index }).then(response => {
+            goodsState({ skuType:1, skuId: id, status: index }).then(response => {
                 this.$notify({
                     title: '成功',
-                    message: '品状态修改成功',
+                    message: '商品状态修改成功',
                     type: 'success',
                     duration: 2000
                 })
@@ -602,7 +532,7 @@ export default {
                 cancelButtonText: '取消',
                 type: 'warning'
             }).then(() => {
-                giftState({ skuId: id, status: index }).then(response => {
+                goodsState({ skuType:1, skuId: id, status: index }).then(response => {
                     this.$notify({
                         title: '成功',
                         message: '删除成功',
@@ -611,7 +541,20 @@ export default {
                     })
                     this.getList();
                 })
-            }).catch(() => {})
+            }).catch(() => {
+
+            })
+
+        },
+        getDataTypeList() {
+            dataTypeList({dictType:'mall_sku_location'}).then(response => {
+                this.locationList = response.data.data;
+            }).catch(() => {});
+        },
+        getProductAttributeList(){
+            dataTypeList({dictType:'mall_sku_attribute'}).then(response => {
+                this.productAttributeList = response.data.data;
+            }).catch(() => {});
         },
         getDepTypeList() {
             depTypeList().then(response => {
@@ -620,7 +563,7 @@ export default {
         },
         getList() {
             this.listLoading = true
-            giftList(this.listQuery).then(response => {
+            goodsList(this.listQuery).then(response => {
                 this.list = response.data.data.items
                 this.total = response.data.data.total
                 this.listLoading = false
@@ -662,8 +605,8 @@ export default {
         },
 
         handleView(row) {
-            this.itemListQuery.id = row.id;
-            this.getItemList()
+            this.itemListQuery.skuId = row.skuId;
+            this.getItemList();
             this.dialogListVisible = true
         },
     }

+ 76 - 6
src/views/goodsManage/goodsList.vue

@@ -64,7 +64,7 @@
                         @click="changeGoodsState(scope.row.skuId, 1)">上架</el-button>
                     <el-button v-if="scope.row.status == 1" type="warning" size="small"
                         @click="changeGoodsState(scope.row.skuId, 0)">下架</el-button>
-                    <el-button type="danger" size="mini" @click="handleDelete(scope.row.skuId, -1)">删除</el-button>
+                    <el-button type="danger" size="small" @click="handleDelete(scope.row.skuId, -1)">删除</el-button>
                 </template>
             </el-table-column>
         </el-table>
@@ -160,7 +160,6 @@
                             <i class="el-icon-plus"></i>
                         </el-upload>
                 </el-form-item>
-
                 <el-form-item label="积分" prop="price">
                     <el-input v-model="dataForm.price"></el-input>
                 </el-form-item>
@@ -177,6 +176,20 @@
                     >
                 <tinymce v-model="dataForm.comment" ref="tinymce"></tinymce>
                 </el-form-item>
+                <el-form-item style="width: 800px" label="商品副图">
+                    <el-upload :action="fileImgUrl" list-type="picture-card" :file-list="dataForm.imgUrls"
+                            :on-success="handleAvatarSuccess"
+                            :on-remove="handleRemoveImgs">
+                            <i class="el-icon-plus"></i>
+                        </el-upload>
+                </el-form-item>
+                <el-form-item
+                    style="width: 800px"
+                    label="商品介绍"
+                    prop="skuDesc"
+                    >
+                <skuDesc v-model="dataForm.skuDesc" ref="skuDesc"></skuDesc>
+                </el-form-item>
             </el-form>
             <div slot="footer" class="dialog-footer">
                 <el-button @click="dialogFormVisible = false">取消</el-button>
@@ -208,11 +221,12 @@
 import { createItem, updateItem, goodsList, goodsState, exchangeHistory } from "@/api/goodsManage";
 import { depTypeList,dataTypeList } from "@/api/public";
 import waves from "@/directive/waves"; // 水波纹指令
-import Tinymce from '@/components/Tinymce'
+import Tinymce from '@/components/Tinymce';
+import SkuDesc from '@/components/SkuDesc'
 
 export default {
     name: 'goodsList',
-    components: { Tinymce },
+    components: { Tinymce,SkuDesc },
     directives: { waves },
     data() {
         return {
@@ -237,6 +251,7 @@ export default {
             listLoading: false,
             downloadLoading: false,
             listQuery: {
+                skuType:0,
                 page: 1,
                 limit: 10,
                 name: '',
@@ -245,6 +260,7 @@ export default {
                 productAttribute:'',
             },
             itemListQuery: {
+                skuType:0,
                 page: 1,
                 limit: 10,
                 skuId:'',
@@ -252,6 +268,7 @@ export default {
                 userName: '',
             },
             dataForm: {
+                skuType:0,
                 name: undefined,
                 seq: undefined,
                 productAttribute: undefined,
@@ -262,6 +279,8 @@ export default {
                 deliveryTypes: [],
                 // location: undefined,
                 images: [],
+                imgIds: '',
+                imgUrls:[],
             },
             dialogFormVisible: false,
             dialogStatus: '',
@@ -272,6 +291,7 @@ export default {
             rules: {
                 name: [{ required: true, message: "请填写商品名称", trigger: "blur" }],
                 imgUrl: [{ required: true, message: "请上传商品图片", trigger: "blur" }],
+                imgIds: [{ required: true, message: "请上传商品副图", trigger: "blur" }],
                 productAttribute: [{ required: true, message: "请选择商品属性", trigger: "blur" }],
                 price: [{ required: true, message: "请填写商品积分", trigger: "blur" }],
                 hisPrice: [{ required: true, message: "请填写商品参考价格", trigger: "blur" }],
@@ -279,6 +299,7 @@ export default {
                 deliveryTypes: [{ required: true, message: "请选择兑换方式", trigger: "blur" }],
                 // location: [{ required: true, message: "请选择商品所在地", trigger: "blur" }],
                 comment: [{ required: true, message: "说明不能为空", trigger: "blur" }],
+                skuDesc: [{ required: true, message: "商品介绍不能为空", trigger: "blur" }],
             },
             dialogListVisible: false,
             fileImgUrl: this.upLoadUrl,
@@ -315,6 +336,34 @@ export default {
                 this.dataForm.imgUrl = images.join(",");
             }
         },
+        handleAvatarSuccess(res, file, fileList) {
+            console.log(file, fileList);
+            console.log("------", "==========");
+            console.log("res = ", res);
+
+            let fileIds = [];
+            for (let i in fileList) {
+                let response = fileList[i].response;
+                if (response.errno && response.errno != "0") {
+                this.$message.error("该文件上传失败,已被移除,请重新上传!");
+                // 上传失败移除该 file 对象
+                fileList.splice(i, 1);
+                } else {
+                let id = fileList[i].response.data.id;
+                fileIds.push(id);
+                }
+            }
+            this.dataForm.imgIds = fileIds.join(",");
+        },
+        handleRemoveImgs(file, fileList) {
+            console.log(file, fileList);
+            let fileIds = [];
+            for (let i in fileList) {
+                let id = fileList[i].response.data.id;
+                fileIds.push(id);
+            }
+            this.dataForm.imgIds = fileIds.join(",");
+        },
         uploadBannerImg(file) {
             const isJPGs = file.type === "image/jpeg";
             console.log(isJPGs);
@@ -345,7 +394,9 @@ export default {
         },
         resetForm() {
             this.dataForm = {
+                skuType:0,
                 comment: undefined,
+                skuDesc: undefined,
                 name: undefined,
                 seq: undefined,
                 productAttribute: undefined,
@@ -356,6 +407,8 @@ export default {
                 deliveryTypes: [],
                 // location: undefined,
                 images: [],
+                imgIds: '',
+                imgUrls:[],
             };
         },
         handleCreate() {
@@ -366,6 +419,7 @@ export default {
 
             this.$nextTick(() => {
                 this.$refs.tinymce.setContent("");
+                this.$refs.skuDesc.setContent("");
                 this.$refs["dataForm"].clearValidate();
             });
         },
@@ -394,6 +448,7 @@ export default {
             this.dataForm = Object.assign({}, row);
             this.dataForm.productAttribute = row.productAttribute.toString();
             let comment = this.dataForm.comment;
+            let skuDesc = this.dataForm.skuDesc?this.dataForm.skuDesc:'';
             let val = row.productAttribute;
             this.getDeliveryTypeList(val);
             if (this.dataForm.imgUrl) {
@@ -410,10 +465,25 @@ export default {
                     });
                 }
             }
+            if (this.dataForm.imgs) {
+                let imgs = this.dataForm.imgs;
+                this.dataForm.imgUrls = [];
+                for (let i in imgs) {
+                    let url = imgs[i].url;
+                    let name = "image_" + i;
+
+                    this.dataForm.imgUrls.push({
+                        name: name,
+                        url: url,
+                        response: { error: "0", data: imgs[i] },
+                    });
+                }
+            }
             this.dialogStatus = 'update'
             this.dialogFormVisible = true
             this.$nextTick(() => {
                 this.$refs.tinymce.setContent(comment);
+                this.$refs.skuDesc.setContent(skuDesc);
                 this.$refs['dataForm'].clearValidate()
             })
         },
@@ -436,7 +506,7 @@ export default {
             })
         },
         changeGoodsState(id, index) {
-            goodsState({ skuId: id, status: index }).then(response => {
+            goodsState({ skuType:0,skuId: id, status: index }).then(response => {
                 this.$notify({
                     title: '成功',
                     message: '商品状态修改成功',
@@ -452,7 +522,7 @@ export default {
                 cancelButtonText: '取消',
                 type: 'warning'
             }).then(() => {
-                goodsState({ skuId: id, status: index }).then(response => {
+                goodsState({skuType:0, skuId: id, status: index }).then(response => {
                     this.$notify({
                         title: '成功',
                         message: '删除成功',

+ 1 - 1
src/views/noticeManage/noticeList.vue

@@ -73,7 +73,7 @@
                 </el-form-item>
                 <el-form-item label="参与人">
                     <el-select v-model="dataForm.recipients" multiple filterable placeholder="请选择" style="width: 350px">
-                        <el-option :key="item.loginId" v-for="item in recipientsList" :label="item.userName" :value="item.loginId">
+                        <el-option :key="item.loginId" v-for="item in recipientsList" :label="item.deptName+'_'+item.userName+'_'+item.employeNo" :value="item.loginId">
                         </el-option>
                     </el-select>
                 </el-form-item>

+ 469 - 0
src/views/raffleManage/raffleDataList.vue

@@ -0,0 +1,469 @@
+<template>
+    <div class="app-container calendar-list-container">
+
+        <!-- 查询和其他操作 -->
+        <div class="filter-container">
+            <el-select @change="changepoolId" v-model="listQuery.poolId" placeholder="奖池" class="filter-item" style="width: 200px">
+                <el-option :key="item.id" v-for="item in dictNameList" :label="item.title" :value="item.id">
+                </el-option>
+            </el-select>
+            <el-button class="filter-item" type="primary" v-waves icon="el-icon-search" @click="handleFilter">查找</el-button>
+            <el-button class="filter-item" type="primary" @click="handleCreate" icon="el-icon-edit">添加</el-button>
+            <!-- <el-button class="filter-item" type="warning" icon="el-icon-delete" @click="delAll">批量删除</el-button> -->
+
+        </div>
+
+        <!-- 查询结果 -->
+        <el-table size="small" :data="list" v-loading="listLoading" @selection-change="handleSelectionChange"
+            element-loading-text="正在查询中。。。" border fit highlight-current-row>
+            <!-- <el-table-column type="selection" width="55px"> </el-table-column> -->
+            <el-table-column align="center" min-width="100px" label="奖品类型" prop="prizeTypeName">
+            </el-table-column>
+            <el-table-column align="center" min-width="150px" label="奖品名称" prop="prizeName">
+            </el-table-column>
+            <el-table-column align="center" min-width="150px" label="商品券">
+                <template slot-scope="scope">
+                    <span v-if="scope.row.couponVo">{{ scope.row.couponVo.couponName }}</span>
+                    <span v-else>无</span>
+                </template>
+            </el-table-column>
+            <el-table-column align="center" min-width="100px" label="奖励积分" prop="integral">
+            </el-table-column>
+            <el-table-column align="center" min-width="100px" label="奖品权重" prop="prizeWeight">
+            </el-table-column>
+            <el-table-column align="center" min-width="100px" label="奖品数量" prop="prizeActualStock">
+            </el-table-column>
+            <el-table-column align="center" min-width="100px" label="剩余数量" prop="prizeStock">
+            </el-table-column>
+            <el-table-column align="center" min-width="100px" label="状态">
+            <template slot-scope="scope">
+                <span v-if="scope.row.status == '0'">关闭</span>
+                <span v-else>开启</span>
+            </template>
+        </el-table-column>
+            <el-table-column align="center" label="操作" width="240px" class-name="small-padding fixed-width">
+                <template slot-scope="scope">
+                    <el-button type="primary" size="small" @click="handleUpdate(scope.row, false)">编辑</el-button>
+
+                    <el-button type="danger" size="small" @click="handleDelete(scope.row)">删除</el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+
+        <!-- 分页 -->
+        <div class="pagination-container">
+            <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange"
+                :current-page="listQuery.page" :page-sizes="[10, 20, 30, 50]" :page-size="listQuery.limit"
+                layout="total, sizes, prev, pager, next, jumper" :total="total">
+            </el-pagination>
+        </div>
+
+        <!-- 添加或修改对话框 -->
+        <el-dialog
+        :close-on-click-modal="false"
+        :title="textMap[dialogStatus]"
+        :visible.sync="dialogFormVisible"
+        width="40%"
+      >
+        <el-form :rules="rules" ref="dataForm" :model="dataForm" status-icon label-position="left" label-width="80px" style='width: 700px; margin-left:50px;'>
+            <el-form-item  label="奖品类型" prop="prizeType">
+              <el-select v-model="dataForm.prizeType" clearable placeholder="请选择类型" class="filter-item" style="width: 300px" @change="clickPrizeType">
+                <el-option :key="item.dictValue" v-for="item in dataTypeList" :label="item.dictLabel" :value="item.dictValue">
+                        </el-option>
+                </el-select>
+            </el-form-item>
+            <el-form-item  label="奖品名称" prop="prizeName">
+              <el-input style="width: 300px" v-model="dataForm.prizeName"></el-input>
+            </el-form-item>
+            <el-form-item v-if="dataForm.prizeType=='10'"  label="兑换券" prop="couponId">
+                <el-select v-model="dataForm.couponId" clearable placeholder="请选择兑换券" class="filter-item" style="width: 300px">
+                    <el-option :key="item.id" v-for="item in couponsList" :label="item.couponName" :value="item.id">
+                    </el-option>
+                </el-select>
+            </el-form-item>
+            <el-form-item style="width: 800px" label="商品图片" prop="imgUrl">
+                    <el-upload :limit="1" :action="fileImgUrl" list-type="picture-card" :file-list="dataForm.images"
+                            :on-success="handleGallerySucess" :on-exceed="handleExceed" :before-upload="uploadBannerImg"
+                            :on-remove="handleRemove">
+                            <i class="el-icon-plus"></i>
+                        </el-upload>
+                </el-form-item>
+            <el-form-item v-if="dataForm.prizeType=='20'" label="奖励积分" prop="integral">
+                <el-input-number style="width: 300px" :precision="0" :step="1" v-model="dataForm.integral"></el-input-number>
+            </el-form-item>
+            <el-form-item  label="奖品权重" prop="prizeWeight">
+                <el-input-number style="width: 300px" :precision="0" :step="1" v-model="dataForm.prizeWeight"></el-input-number>
+            </el-form-item>
+            <el-form-item  label="奖品数量" prop="prizeActualStock">
+                <el-input-number style="width: 300px" :precision="0" :step="1" v-model="dataForm.prizeActualStock"></el-input-number>
+            </el-form-item>
+            <el-form-item  label="状态">
+                <el-radio-group v-model="dataForm.status">
+                    <el-radio :label="'0'">关闭</el-radio>
+                    <el-radio :label="'1'">开启</el-radio>
+                </el-radio-group>
+            </el-form-item>
+            
+            
+        </el-form>
+        <div slot="footer" class="dialog-footer">
+          <el-button @click="dialogFormVisible = false">取消</el-button>
+          <el-button v-if="dialogStatus == 'create'" type="primary" @click="createData">确定</el-button>
+          <el-button v-else type="primary" @click="updateData">确定</el-button>
+        </div>
+      </el-dialog>
+
+    </div>
+</template>
+  
+<style>
+.demo-table-expand {
+    font-size: 0;
+}
+
+.demo-table-expand label {
+    width: 200px;
+    color: #99a9bf;
+}
+
+.demo-table-expand .el-form-item {
+    margin-right: 0;
+    margin-bottom: 0;
+}
+</style>
+  
+<script>
+import { dataList, dataAdd, dataEdit, dataRemove, optionSelect } from "@/api/raffleManage";
+import { dataTypeList,couponsList } from "@/api/public";
+import waves from "@/directive/waves"; // 水波纹指令
+import Tinymce from '@/components/Tinymce'
+
+export default {
+    components: { Tinymce },
+    directives: { waves },
+    data() {
+        return {
+            couponsList:[],
+            dataTypeList:[],
+            isCoupon:false,
+            poolId:'',
+            dictNameList: [],
+            list: [
+            ],
+            delarr: [],
+            multipleSelection: [],
+            total: 0,
+            listLoading: false,
+            listQuery: {
+                page: 1,
+                limit: 10,
+                poolId: '',
+            },
+            dataForm: {
+                prizeType: undefined,
+                couponId:undefined,
+                prizeName: undefined,
+                imgUrl: undefined,
+                integral: undefined,
+                prizeWeight: undefined,
+                prizeActualStock: undefined,
+                prizeStock: undefined,
+                status: '0',
+                images: [],
+            },
+            dialogFormVisible: false,
+            dialogStatus: '',
+            textMap: {
+                update: "编辑",
+                create: "创建",
+            },
+            rules: {
+                prizeType: [{ required: true, message: "请选择奖品类型", trigger: "blur" }],
+                couponId: [{ required: true, message: "请选择兑换卷", trigger: "blur" }],
+                prizeName: [{ required: true, message: "奖品名称不能为空", trigger: "blur" }],
+                imgUrl: [{ required: true, message: "请上传奖品图片", trigger: "blur" }],
+                integral: [{ required: true, message: "奖励积分不能为空", trigger: "blur" }],
+                prizeWeight: [{ required: true, message: "奖品权重不能为空", trigger: "blur" }],
+                prizeActualStock: [{ required: true, message: "奖品数量不能为空", trigger: "blur" }],
+                prizeStock: [{ required: true, message: "剩余数量不能为空", trigger: "blur" }],
+            },
+            fileImgUrl: this.upLoadUrl,
+        }
+    },
+    created() {
+        this.poolId = this.$route.params.id;
+        this.getOptionSelect();
+        this.getDataTypeList();
+        this.getCouponsList();
+    },
+    methods: {
+        clickPrizeType(){
+            this.dataForm.couponId = undefined; 
+            this.dataForm.prizeName = undefined;
+            this.dataForm.imgUrl = undefined;
+            this.dataForm.integral = undefined;
+            this.dataForm.prizeActualStock = undefined;
+            this.dataForm.prizeStock = undefined;
+            this.dataForm.status = '0';
+            this.dataForm.images = [];
+        },
+        handleRemove(file, fileList) {
+            console.log(file, fileList);
+            let images = [];
+            for (let i in fileList) {
+                let response = fileList[i].response;
+                let url = response.data.url;
+                images.push(url);
+            }
+            this.dataForm.images = images;
+            this.dataForm.imgUrl = images.join(",");
+        },
+        uploadBannerImg(file) {
+            const isJPGs = file.type === "image/jpeg";
+            console.log(isJPGs);
+        },
+        handleExceed(files, fileList) {
+            this.$message.warning(
+                `当前限制选择 1 个文件,本次选择了 ${files.length} 个文件!,共选择了 ${files.length + fileList.length
+                } 个文件`
+            );
+        },
+        handleGallerySucess(res, file, fileList) {
+            this.dataForm.imgUrl = ""; // 清空画廊图片数组
+
+            let images = [];
+            for (let i in fileList) {
+                let response = fileList[i].response;
+                if (response.errno && response.errno != "0") {
+                    this.$message.error("该图片上传失败,已被移除,请重新上传!");
+                    // 上传失败移除该 file 对象
+                    fileList.splice(i, 1);
+                } else {
+                    let url = response.data.url;
+                    images.push(url);
+                }
+            }
+            this.dataForm.images = images;
+            this.dataForm.imgUrl = images.join(",");
+        },
+        getCouponsList() {
+            couponsList({}).then(response => {
+                this.couponsList = response.data.data;
+            }).catch(() => { });
+        },
+        getDataTypeList() {
+            dataTypeList({dictType:'prize_type'}).then(response => {
+                this.dataTypeList = response.data.data;
+            }).catch(() => {});
+        },
+        changepoolId(val){
+            this.poolId = val;
+            this.listQuery.poolId = val;
+            this.getList();
+        },
+        getOptionSelect(){
+            optionSelect().then(response => {
+                this.dictNameList = response.data.data;
+                this.listQuery.poolId = this.poolId;
+                this.getList();
+            }).catch(() => {})
+        },
+        resetForm() {
+            this.dataForm = {
+                prizeType: undefined,
+                couponId:undefined,
+                prizeName: undefined,
+                imgUrl: undefined,
+                integral: undefined,
+                prizeWeight: undefined,
+                prizeActualStock: undefined,
+                prizeStock: undefined,
+                status: '0',
+                images: [],
+            };
+        },
+        handleCreate() {
+            this.resetForm();
+            this.dataForm.poolId = this.poolId;
+            this.dialogFormVisible = true;
+            this.dialogStatus = "create";
+            this.$nextTick(() => {
+                this.$refs["dataForm"].clearValidate();
+            });
+        },
+        createData() {
+            this.$refs["dataForm"].validate((valid) => {
+                if (valid) {
+                    dataAdd(this.dataForm)
+                        .then(() => {
+                            this.dialogFormVisible = false;
+                            this.$notify({
+                                title: "成功",
+                                message: "创建成功",
+                                type: "success",
+                                duration: 2000,
+                            });
+                            this.getList()
+                        })
+                }
+            });
+        },
+        getList() {
+            this.listLoading = true
+            dataList(this.listQuery).then(response => {
+                this.list = response.data.data.items
+                this.total = response.data.data.total
+                this.listLoading = false
+            }).catch(() => {
+                this.list = []
+                this.total = 0
+                this.listLoading = false
+            })
+        },
+
+        handleFilter() {
+            this.listQuery.page = 1
+            this.getList()
+        },
+
+        handleSizeChange(val) {
+            this.listQuery.limit = val
+            this.getList()
+        },
+
+        handleCurrentChange(val) {
+            this.listQuery.page = val
+            this.getList()
+        },
+
+        handleUpdate(row) {
+            this.dataForm = Object.assign({}, row);
+            if (this.dataForm.imgUrl) {
+                let images = this.dataForm.imgUrl.split(",");
+                this.dataForm.images = [];
+                for (let i in images) {
+                    let url = images[i];
+                    let name = "image_" + i;
+
+                    this.dataForm.images.push({
+                        name: name,
+                        url: url,
+                        response: { error: "0", data: { url: url } },
+                    });
+                }
+            }
+            this.dialogStatus = 'update'
+            this.dialogFormVisible = true
+            this.$nextTick(() => {
+                this.$refs['dataForm'].clearValidate()
+            })
+        },
+
+        updateData() {
+            this.$refs['dataForm'].validate((valid) => {
+                if (valid) {
+                    dataEdit(this.dataForm).then(() => {
+                        this.dialogFormVisible = false
+                        this.$notify({
+                            title: '成功',
+                            message: '更新成功',
+                            type: 'success',
+                            duration: 2000
+                        })
+                        this.getList()
+                    })
+
+                }
+            })
+        },
+
+        handleDelete(row) {
+
+            this.$confirm('确认删除吗?', '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning'
+            }).then(() => {
+                dataRemove({ prizeIds:row.id}).then(response => {
+                    this.$notify({
+                        title: '成功',
+                        message: '删除成功',
+                        type: 'success',
+                        duration: 2000
+                    })
+                    const index = this.list.indexOf(row)
+                    this.list.splice(index, 1)
+                })
+            }).catch(() => {
+
+            })
+
+        },
+        delAll() {
+            this.$confirm("确认删除吗?", "提示", {
+                confirmButtonText: "确定",
+                cancelButtonText: "取消",
+                type: "warning",
+            })
+                .then(() => {
+                    const length = this.multipleSelection.length;
+
+                    if (length > 0) {
+                        for (let i = 0; i < length; i++) {
+                            this.delarr.push(this.multipleSelection[i].id);
+                        }
+                        const  ids = this.delarr.join(",");
+                        dataRemove({  prizeIds:  ids })
+                            .then(() => {
+                                this.$notify({
+                                    title: "成功",
+                                    message: "删除成功",
+                                    type: "success",
+                                    duration: 2000,
+                                });
+                                this.getList();
+                            })
+                            .catch(() => { });
+                    } else {
+                        this.$notify({
+                            title: "警告提示",
+                            message: "请选择要删除的信息!",
+                            type: "warning",
+                        });
+                    }
+                })
+                .catch(() => { });
+        },
+        handleSelectionChange(val) {
+            this.multipleSelection = val;
+        },
+    }
+}
+</script>
+<style>
+.ad-avatar-uploader .el-upload {
+    border: 1px dashed #d9d9d9;
+    border-radius: 6px;
+    cursor: pointer;
+    position: relative;
+    overflow: hidden;
+}
+
+.ad-avatar-uploader .el-upload:hover {
+    border-color: #409EFF;
+}
+
+.ad-avatar-uploader-icon {
+    font-size: 28px;
+    color: #8c939d;
+    width: 178px;
+    height: 178px;
+    line-height: 178px;
+    text-align: center;
+}
+
+.ad-avatar {
+    display: block;
+}
+</style>
+  

+ 347 - 0
src/views/raffleManage/raffleList.vue

@@ -0,0 +1,347 @@
+<template>
+  <div class="app-container calendar-list-container">
+
+    <!-- 查询和其他操作 -->
+    <div class="filter-container">
+      <el-input clearable class="filter-item" style="width: 200px;" placeholder="请输入奖池名称" v-model="listQuery.title"></el-input>
+      <el-select v-model="listQuery.status" clearable placeholder="状态" class="filter-item" style="width: 200px">
+          <el-option :key="item.type" v-for="item in typeList" :label="item.name" :value="item.type">
+          </el-option>
+      </el-select>
+      <el-button class="filter-item" type="primary" v-waves icon="el-icon-search" @click="handleFilter">查找</el-button>
+      <el-button class="filter-item" type="primary" @click="handleCreate" icon="el-icon-edit">添加</el-button>
+      <!-- <el-button class="filter-item" type="warning" icon="el-icon-delete" @click="delAll">批量删除</el-button> -->
+    </div>
+
+    <!-- 查询结果 -->
+    <el-table
+      size="small"
+      :data="list"
+      @selection-change="handleSelectionChange"
+      v-loading="listLoading"
+      element-loading-text="正在查询中。。。"
+      border
+      fit
+      highlight-current-row
+    >
+      <!-- <el-table-column type="selection" width="55px"> </el-table-column> -->
+      <el-table-column type="index" label="序号" header-align="center" align="center">
+      </el-table-column>
+
+      <el-table-column align="center" min-width="100px" label="奖池名称">
+        <template slot-scope="scope">
+              <router-link :to="{name: 'raffleDataList', params: { id: scope.row.id }}">
+                  <div style="color: #337ab7;cursor: pointer;">{{ scope.row.title }}</div>
+              </router-link>
+          </template>
+      </el-table-column>
+      <el-table-column align="center" min-width="100px" label="状态">
+            <template slot-scope="scope">
+                <span v-if="scope.row.status === '1'">开启</span>
+                <span v-else>关闭</span>
+            </template>
+            
+        </el-table-column>
+      <el-table-column align="center" min-width="200px" label="备注" prop="content">
+      </el-table-column>
+      <el-table-column align="center" min-width="150px" label="创建时间" prop="createTime">
+      </el-table-column>
+      <el-table-column align="center" label="操作" width="240px" class-name="small-padding fixed-width">
+        <template slot-scope="scope">
+          <el-button
+            type="primary"
+            size="small"
+            @click="handleUpdate(scope.row, false)"
+            >编辑</el-button
+          >
+
+          <el-button type="danger" size="mini"  @click="handleDelete(scope.row)">删除</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <!-- 分页 -->
+    <div class="pagination-container">
+      <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="listQuery.page"
+        :page-sizes="[10,20,30,50]" :page-size="listQuery.limit" layout="total, sizes, prev, pager, next, jumper" :total="total">
+      </el-pagination>
+    </div>
+
+    <!-- 添加或修改对话框 -->
+    <el-dialog
+    :close-on-click-modal="false"
+      :title="textMap[dialogStatus]"
+      :visible.sync="dialogFormVisible"
+      width="40%"
+    >
+      <el-form :rules="rules" ref="dataForm" :model="dataForm" status-icon label-position="left" label-width="80px" style='width: 700px; margin-left:50px;'>
+          <el-form-item  label="奖池名称" prop="title">
+            <el-input style="width: 300px" v-model="dataForm.title"></el-input>
+          </el-form-item>
+          <el-form-item  label="状态">
+              <el-radio-group v-model="dataForm.status">
+                  <el-radio :label="'0'">关闭</el-radio>
+                  <el-radio :label="'1'">开启</el-radio>
+              </el-radio-group>
+          </el-form-item>
+          <el-form-item  label="备注">
+            <el-input type="textarea" :rows="2" style="width: 300px" v-model="dataForm.content"></el-input>
+          </el-form-item>
+          
+          
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="dialogFormVisible = false">取消</el-button>
+        <el-button v-if="dialogStatus == 'create'" type="primary" @click="createData">确定</el-button>
+        <el-button v-else type="primary" @click="updateData">确定</el-button>
+      </div>
+    </el-dialog>
+
+  </div>
+</template>
+
+<style>
+  .demo-table-expand {
+    font-size: 0;
+  }
+  .demo-table-expand label {
+    width: 200px;
+    color: #99a9bf;
+  }
+  .demo-table-expand .el-form-item {
+    margin-right: 0;
+    margin-bottom: 0;
+  }
+</style>
+
+<script>
+  import { list, createItem, updateItem, deleteitem } from "@/api/raffleManage";
+  import waves from "@/directive/waves"; // 水波纹指令
+  import Tinymce from '@/components/Tinymce'
+
+export default {
+  components: { Tinymce },
+  directives: { waves },
+  data() {
+    return {
+      typeList: [
+      {
+        type: "0",
+        name: "正常",
+      },
+      {
+        type: "1",
+        name: "停用",
+      },
+    ],
+      list: [
+        
+      ],
+      delarr: [],
+      multipleSelection: [],
+      total: 0,
+      listLoading: false,
+      listQuery: {
+        page: 1,
+        limit: 10,
+        title: '',
+        status: '',
+      },
+      dataForm: {
+        title: undefined,
+        status: '1',
+        content: undefined,
+      },
+      dialogFormVisible: false,
+      dialogStatus: '',
+      textMap: {
+        update: "编辑",
+        create: "创建",
+      },
+      imageUrl: undefined,
+      rules: {
+        title: [{ required: true, message: "字典名称不能为空", trigger: "blur" }],
+      },
+    }
+  },
+  created() {
+      this.getList();
+  },
+  methods: {
+      handleDictData(row){
+
+      },
+    resetForm() {
+      this.dataForm = {
+          title: undefined,
+          status: '1',
+          content: undefined,
+      };
+    },
+    handleCreate() {
+      this.resetForm();
+      this.dialogFormVisible = true;
+      this.dialogStatus = "create";
+      this.$nextTick(() => {
+        this.$refs["dataForm"].clearValidate();
+      });
+    },
+    createData() {
+      this.$refs["dataForm"].validate((valid) => {
+        if (valid) {
+          createItem(this.dataForm)
+                .then(() => {
+                  this.getList();
+                  this.dialogFormVisible = false;
+
+                  this.$notify({
+                    title: "成功",
+                    message: "创建成功",
+                    type: "success",
+                    duration: 2000,
+                  });
+                  this.getList()
+                })
+        }
+      });
+    },
+    getList() {
+      this.listLoading = true
+      list(this.listQuery).then(response => {
+        this.list = response.data.data.items
+        this.total = response.data.data.total
+        this.listLoading = false
+      }).catch(() => {
+        this.list = []
+        this.total = 0
+        this.listLoading = false
+      })
+    },
+
+    handleFilter() {
+      this.listQuery.page = 1
+      this.getList()
+    },
+
+    handleSizeChange(val) {
+      this.listQuery.limit = val
+      this.getList()
+    },
+
+    handleCurrentChange(val) {
+      this.listQuery.page = val
+      this.getList()
+    },
+
+    handleUpdate(row) {
+      this.dataForm = Object.assign({}, row);
+      this.dialogStatus = 'update'
+      this.dialogFormVisible = true
+      this.$nextTick(() => {
+        this.$refs['dataForm'].clearValidate()
+      })
+    },
+
+    updateData() {
+      this.$refs['dataForm'].validate((valid) => {
+        if (valid) {
+          updateItem(this.dataForm).then(() => {
+              this.dialogFormVisible = false
+              this.$notify({
+                title: '成功',
+                message: '更新成功',
+                type: 'success',
+                duration: 2000
+              })
+              this.getList()
+            })
+          
+        }
+      })
+    },
+
+    handleDelete(row) {
+
+      this.$confirm('确认删除吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        deleteitem({dictIds:row.dictId}).then(response => {
+          this.$notify({
+            title: '成功',
+            message: '删除成功',
+            type: 'success',
+            duration: 2000
+          })
+          this.getList()
+        })
+      }).catch(() => {
+
+      })
+
+    },
+    delAll() {
+          this.$confirm("确认删除吗?", "提示", {
+              confirmButtonText: "确定",
+              cancelButtonText: "取消",
+              type: "warning",
+          })
+              .then(() => {
+                  const length = this.multipleSelection.length;
+
+                  if (length > 0) {
+                      for (let i = 0; i < length; i++) {
+                          this.delarr.push(this.multipleSelection[i].dictId);
+                      }
+                      const dictIds = this.delarr.join(",");
+                      deleteitem({ dictIds: dictIds })
+                          .then(() => {
+                              this.$notify({
+                                  title: "成功",
+                                  message: "删除成功",
+                                  type: "success",
+                                  duration: 2000,
+                              });
+                              this.getList();
+                          })
+                          .catch(() => { });
+                  } else {
+                      this.$notify({
+                          title: "警告提示",
+                          message: "请选择要删除的信息!",
+                          type: "warning",
+                      });
+                  }
+              })
+              .catch(() => { });
+      },
+      handleSelectionChange(val) {
+          this.multipleSelection = val;
+      },
+  }
+}
+</script>
+<style>
+  .ad-avatar-uploader .el-upload {
+    border: 1px dashed #d9d9d9;
+    border-radius: 6px;
+    cursor: pointer;
+    position: relative;
+    overflow: hidden;
+  }
+  .ad-avatar-uploader .el-upload:hover {
+    border-color: #409EFF;
+  }
+  .ad-avatar-uploader-icon {
+    font-size: 28px;
+    color: #8c939d;
+    width: 178px;
+    height: 178px;
+    line-height: 178px;
+    text-align: center;
+  }
+  .ad-avatar {
+    display: block;
+  }
+</style>

+ 146 - 0
src/views/raffleManage/raffleLogsList.vue

@@ -0,0 +1,146 @@
+<template>
+    <div class="app-container calendar-list-container">
+
+        <!-- 查询和其他操作 -->
+        <div class="filter-container">
+            <el-input clearable class="filter-item" style="width: 200px;" placeholder="员工"
+                v-model="listQuery.userName"></el-input>
+            <el-input clearable class="filter-item" style="width: 200px;" placeholder="活动名称"
+                v-model="listQuery.actTitle"></el-input>
+            <el-date-picker
+            class="filter-item"
+            value-format="yyyy-MM-dd"
+            v-model="listQuery.createTime"
+            type="date"
+            placeholder="创建日期">
+            </el-date-picker>
+            <el-button class="filter-item" type="primary" v-waves icon="el-icon-search" @click="handleFilter">查找</el-button>
+            <el-button class="filter-item" type="primary"  :loading="downloadLoading" v-waves icon="el-icon-download" @click="handleDownload">导出</el-button>
+        </div>
+
+        <!-- 查询结果 -->
+        <el-table size="small" :data="list" v-loading="listLoading" element-loading-text="正在查询中。。。" border fit
+            highlight-current-row>
+            <el-table-column type="index" label="序号" header-align="center" align="center">
+            </el-table-column>
+            <el-table-column align="center" min-width="180px" label="部门" prop="deptName">
+            </el-table-column>
+            <el-table-column align="center" min-width="80px" label="员工" prop="userName">
+            </el-table-column>
+            <el-table-column align="center" min-width="80px" label="活动名称" prop="actTitle">
+            </el-table-column>
+            <el-table-column align="center" min-width="80px" label="奖品" prop="prizeName">
+            </el-table-column>
+            <el-table-column align="center" min-width="150px" label="获取日期" prop="createTime">
+            </el-table-column>
+           
+        </el-table>
+
+        <!-- 分页 -->
+        <div class="pagination-container">
+            <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange"
+                :current-page="listQuery.page" :page-sizes="[10, 20, 30, 50]" :page-size="listQuery.limit"
+                layout="total, sizes, prev, pager, next, jumper" :total="total">
+            </el-pagination>
+        </div>
+    </div>
+</template>
+  
+<style>
+.demo-table-expand {
+    font-size: 0;
+}
+
+.demo-table-expand label {
+    width: 200px;
+    color: #99a9bf;
+}
+
+.demo-table-expand .el-form-item {
+    margin-right: 0;
+    margin-bottom: 0;
+}
+</style>
+  
+<script>
+import { logsList } from "@/api/raffleManage";
+import waves from "@/directive/waves"; // 水波纹指令
+
+export default {
+    directives: { waves },
+    data() {
+        return {
+            list: [],
+            total: 0,
+            listLoading: false,
+            downloadLoading: false,
+            listQuery: {
+                page: 1,
+                limit: 10,
+                userName: '',
+                actTitle:'',
+                createTime: '',
+            },
+        }
+    },
+    created() {
+        this.getList();
+    },
+    methods: {
+        handleDownload() {
+            window.location.href = process.env.BASE_API + '/mall-prize/export/log?userName=' + this.listQuery.userName + '&actTitle=' + this.listQuery.actTitle + '&createTime=' + this.listQuery.createTime;
+        },
+        getList() {
+            this.listLoading = true
+            logsList(this.listQuery).then(response => {
+                this.list = response.data.data.items
+                this.total = response.data.data.total
+                this.listLoading = false
+            }).catch(() => {})
+        },
+       
+
+        handleFilter() {
+            this.listQuery.page = 1
+            this.getList()
+        },
+        handleSizeChange(val) {
+            this.listQuery.limit = val
+            this.getList()
+        },
+        handleCurrentChange(val) {
+            this.listQuery.page = val
+            this.getList()
+        },
+
+        
+    }
+}
+</script>
+<style>
+.ad-avatar-uploader .el-upload {
+    border: 1px dashed #d9d9d9;
+    border-radius: 6px;
+    cursor: pointer;
+    position: relative;
+    overflow: hidden;
+}
+
+.ad-avatar-uploader .el-upload:hover {
+    border-color: #409EFF;
+}
+
+.ad-avatar-uploader-icon {
+    font-size: 28px;
+    color: #8c939d;
+    width: 178px;
+    height: 178px;
+    line-height: 178px;
+    text-align: center;
+}
+
+.ad-avatar {
+    display: block;
+}
+</style>
+  

+ 1 - 1
src/views/sys/admin.vue

@@ -52,7 +52,7 @@
           </el-form-item> -->
           <el-form-item label="管理员" prop="username">
                     <el-select :disabled="dialogStatus=='create'?false:true" v-model="dataForm.username" filterable clearable placeholder="请选择" style="width: 280px">
-                        <el-option :key="item.loginId" v-for="item in recipientsList" :label="item.userName" :value="item.loginId">
+                        <el-option :key="item.loginId" v-for="item in recipientsList" :label="item.deptName+'_'+item.userName+'_'+item.employeNo" :value="item.loginId">
                         </el-option>
                     </el-select>
           </el-form-item>

File diff suppressed because it is too large
+ 1 - 1
static/tinymce4.7.11/skins/lightgray/skin.min.css