更新dist

This commit is contained in:
zhl 2021-06-08 20:28:23 +08:00
parent 5b238359c4
commit 1756515426
41 changed files with 1289 additions and 67 deletions

View File

@ -1,2 +1,2 @@
VUE_APP_BASE_API = 'http://192.168.100.22:2900'
#VUE_APP_BASE_API = 'https://puzzle-admin.kingsome.cn'
#VUE_APP_BASE_API = 'http://192.168.100.22:2900'
VUE_APP_BASE_API = 'https://puzzle-admin.kingsome.cn'

1
dist/css/chunk-2f070289.dbe3f9b3.css vendored Normal file
View File

@ -0,0 +1 @@
[data-v-76734f22]:export{menuBg:#304156;menuText:#bfcbd9;menuActiveText:#409eff}.action-bar[data-v-76734f22]{margin-bottom:15px}.excel-upload-input[data-v-76734f22]{display:none;z-index:-9999}.el-form-item[data-v-76734f22]{margin-bottom:22px}[data-v-724eecf4]:export{menuBg:#304156;menuText:#bfcbd9;menuActiveText:#409eff}.action-bar[data-v-724eecf4]{margin-bottom:15px}.excel-upload-input[data-v-724eecf4]{display:none;z-index:-9999}

1
dist/css/chunk-e43556be.200293c4.css vendored Normal file
View File

@ -0,0 +1 @@
[data-v-2f4afb68]:export{menuBg:#304156;menuText:#bfcbd9;menuActiveText:#409eff}.pagination-container[data-v-2f4afb68]{background:#fff;padding:32px 16px}.pagination-container.hidden[data-v-2f4afb68]{display:none}

File diff suppressed because one or more lines are too long

2
dist/index.html vendored

File diff suppressed because one or more lines are too long

2
dist/js/app.3528a593.js vendored Normal file

File diff suppressed because one or more lines are too long

1
dist/js/app.3528a593.js.map vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
dist/js/chunk-2d20774c.a3ac0eb6.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
dist/js/chunk-2d218049.cd205531.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

11
dist/js/chunk-2f070289.669d8de6.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
dist/js/chunk-aa8a9846.69e3663c.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
dist/js/chunk-e43556be.bcfd385a.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

11
dist/js/chunk-ff8d6742.dc340a9b.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -8,7 +8,7 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([
"url": "/css/404.96fe1c26.css"
},
{
"revision": "66f67841196f16919c61",
"revision": "1aee25c7e4da16dcee56",
"url": "/css/app.82284a16.css"
},
{
@ -44,12 +44,12 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([
"url": "/css/chunk-21495f61.146db6b7.css"
},
{
"revision": "9b29d65cefffeaee926c",
"url": "/css/chunk-2ffaffe4.d97489d0.css"
"revision": "a392fe277b4efec7fcd4",
"url": "/css/chunk-2f070289.dbe3f9b3.css"
},
{
"revision": "a4c88eb563c1f2a37924",
"url": "/css/chunk-37ee6f14.61483c54.css"
"revision": "9b29d65cefffeaee926c",
"url": "/css/chunk-2ffaffe4.d97489d0.css"
},
{
"revision": "a4a5dae17067fe0692f0",
@ -67,16 +67,12 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([
"revision": "07c88e94c18dd3ea7237",
"url": "/css/chunk-4bf5c744.d25b5fbc.css"
},
{
"revision": "700a1d1f9df53e310dcb",
"url": "/css/chunk-51479e12.309dc905.css"
},
{
"revision": "23983a384e94435dd265",
"url": "/css/chunk-5337e365.9011efc0.css"
},
{
"revision": "590438380b1ae9308289",
"revision": "0679004c97236edb8882",
"url": "/css/chunk-551b767f.00048683.css"
},
{
@ -95,18 +91,26 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([
"revision": "d03993519552478819ff",
"url": "/css/chunk-7ee58394.200293c4.css"
},
{
"revision": "94c9607f2a055d2cc761",
"url": "/css/chunk-aa8a9846.61483c54.css"
},
{
"revision": "08789c99df7d81c3df6f",
"url": "/css/chunk-d4ad27d8.af60e613.css"
},
{
"revision": "1d9905e366cb0a174a8b",
"url": "/css/chunk-ed14ae0c.c6830a95.css"
"revision": "b1c0f901f21e18e6ff76",
"url": "/css/chunk-e43556be.200293c4.css"
},
{
"revision": "23e326fe9f19fb116d1b",
"url": "/css/chunk-fd5993aa.0461aed2.css"
},
{
"revision": "91eec38b69ae49db5bfe",
"url": "/css/chunk-ff8d6742.309dc905.css"
},
{
"revision": "7262578065f7dbcff86e",
"url": "/css/chunk-vendors.dc65e09b.css"
@ -160,7 +164,7 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([
"url": "/img/404.a57b6f31.png"
},
{
"revision": "4b102b2cd29b145c04faf3ecfaf3264a",
"revision": "253b9bc6df7424b16ba296b1af092515",
"url": "/index.html"
},
{
@ -172,8 +176,8 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([
"url": "/js/404.ec607ed7.js"
},
{
"revision": "66f67841196f16919c61",
"url": "/js/app.3da21f4d.js"
"revision": "1aee25c7e4da16dcee56",
"url": "/js/app.3528a593.js"
},
{
"revision": "4308fe0503e593d27da4",
@ -203,10 +207,6 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([
"revision": "65e90e2139aad5204d81",
"url": "/js/chunk-1d3d01ed.3cc37127.js"
},
{
"revision": "78c0ce657b1179d0edf9",
"url": "/js/chunk-1df6ae0e.1f613ee7.js"
},
{
"revision": "1d1a76729fcf54af0bd6",
"url": "/js/chunk-1e67ed7b.03531ba7.js"
@ -219,6 +219,18 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([
"revision": "92a2657a29da835e4503",
"url": "/js/chunk-21495f61.9fe9e46e.js"
},
{
"revision": "40dbb9a22799b1dc088a",
"url": "/js/chunk-2d20774c.a3ac0eb6.js"
},
{
"revision": "7b81fcf47f589e0e7471",
"url": "/js/chunk-2d218049.cd205531.js"
},
{
"revision": "a392fe277b4efec7fcd4",
"url": "/js/chunk-2f070289.669d8de6.js"
},
{
"revision": "9b29d65cefffeaee926c",
"url": "/js/chunk-2ffaffe4.4716b3e3.js"
@ -227,10 +239,6 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([
"revision": "3c546c240bc03eea6711",
"url": "/js/chunk-330c0877.ed1d998d.js"
},
{
"revision": "a4c88eb563c1f2a37924",
"url": "/js/chunk-37ee6f14.ce361267.js"
},
{
"revision": "a4a5dae17067fe0692f0",
"url": "/js/chunk-383c1b34.5048c2ea.js"
@ -251,17 +259,13 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([
"revision": "5fa23cf57b6031529468",
"url": "/js/chunk-50b4ae97.a7df1ae3.js"
},
{
"revision": "700a1d1f9df53e310dcb",
"url": "/js/chunk-51479e12.5e6b7aa5.js"
},
{
"revision": "23983a384e94435dd265",
"url": "/js/chunk-5337e365.7465da3c.js"
},
{
"revision": "590438380b1ae9308289",
"url": "/js/chunk-551b767f.ae1b7e81.js"
"revision": "0679004c97236edb8882",
"url": "/js/chunk-551b767f.e1b85d6a.js"
},
{
"revision": "cb72ebafc6c704c5b40a",
@ -279,6 +283,10 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([
"revision": "d03993519552478819ff",
"url": "/js/chunk-7ee58394.ea49d993.js"
},
{
"revision": "94c9607f2a055d2cc761",
"url": "/js/chunk-aa8a9846.69e3663c.js"
},
{
"revision": "08789c99df7d81c3df6f",
"url": "/js/chunk-d4ad27d8.160a0aa0.js"
@ -288,13 +296,17 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([
"url": "/js/chunk-d5fbf3a2.2d39bc0e.js"
},
{
"revision": "1d9905e366cb0a174a8b",
"url": "/js/chunk-ed14ae0c.49fdc0c2.js"
"revision": "b1c0f901f21e18e6ff76",
"url": "/js/chunk-e43556be.bcfd385a.js"
},
{
"revision": "23e326fe9f19fb116d1b",
"url": "/js/chunk-fd5993aa.7e7015c5.js"
},
{
"revision": "91eec38b69ae49db5bfe",
"url": "/js/chunk-ff8d6742.dc340a9b.js"
},
{
"revision": "7262578065f7dbcff86e",
"url": "/js/chunk-vendors.9100ef44.js"

View File

@ -14,7 +14,7 @@
importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js");
importScripts(
"/precache-manifest.595c5a080aef3d6336684e0b4f5b02b3.js"
"/precache-manifest.c982972dd9e91c9d15c6c6a66f354287.js"
);
workbox.core.setCacheNameDetails({prefix: "pyxis-fe"});

View File

@ -98,7 +98,10 @@ export default {
game_statistics: 'Game Statistics',
shop_puzzles: 'Custom Puzzles',
shop_lottery: 'Lottery Setting',
shop_share: 'Share Setting'
shop_share: 'Share Setting',
shop_mail: 'Mails',
create_mail: 'New Mail',
edit_mail: 'Edit Mail'
},
navbar: {
logOut: 'Log Out',

View File

@ -98,7 +98,10 @@ export default {
game_statistics: '游戏数据',
shop_puzzles: '自定义题库',
shop_lottery: '抽奖转盘',
shop_share: '分享设置'
shop_share: '分享设置',
shop_mail: '邮件',
create_mail: '新邮件',
edit_mail: '编辑邮件'
},
navbar: {
logOut: '退出登录',

View File

@ -136,6 +136,38 @@ const shopRoutes: RouteConfig = {
icon: 'game'
}
},
{
path: 'mail_list',
component: () => import('@/views/mail/list.vue'),
name: 'MailList',
meta: {
title: 'shop_mail',
permissions: ['shopmail:read'],
icon: 'list'
}
},
{
path: 'mail_new',
component: () => import('@/views/mail/edit.vue'),
name: 'CreateMail',
meta: {
title: 'create_mail',
icon: 'edit',
permissions: ['shopmail:edit'],
hidden: true
}
},
{
path: 'mail_edit/:id',
component: () => import('@/views/mail/edit.vue'),
name: 'MailEditor',
meta: {
title: 'edit_mail',
permissions: ['shopmail:read'],
elicon: 'el-icon-arrow-right',
hidden: true
}
}
]
}

831
src/views/mail/edit.vue Normal file
View File

@ -0,0 +1,831 @@
<template>
<div class="app-container">
<el-form
ref="postForm"
:model="postForm"
:rules="rules"
label-width="121px"
class="form-container"
>
<el-tabs v-model="activeName">
<el-tab-pane label="基本信息" name="first">
<el-form-item :label="$t('main.shop')" prop="key" v-if="userLevel === 1">
<el-select
v-model="postForm.shop"
:placeholder="'选择'+$t('main.shop')"
name="shop"
required
class="w100"
>
<el-option
v-for="item in allDepts"
:key="item._id"
:label="item.name"
:value="item._id"
/>
</el-select>
</el-form-item>
<el-form-item
style="margin-bottom: 40px;"
label="活动名称:"
prop="name"
>
<el-input
v-model="postForm.name"
placeholder="输入活动名称"
name="name"
required
/>
</el-form-item>
<el-form-item
label="激活:"
prop="active"
>
<el-switch
v-model="postForm.active"
name="active"
active-color="#13ce66"
inactive-color="#ff4949"
required
/>
</el-form-item>
<el-form-item
prop="desc"
label="活动简介:"
style="margin-bottom: 30px;"
>
<el-input type="textarea" v-model="postForm.desc"></el-input>
</el-form-item>
<el-form-item
prop="icon"
label="活动icon"
>
<upload-corp-image
field="image-file"
@crop-upload-success="iconUploadSuccess"
:width="400"
:height="120"
img-format="png"
v-model="postForm.icon"
>
</upload-corp-image>
</el-form-item>
<el-form-item
prop="banner"
label="活动配图"
>
<upload-corp-image
field="image-file"
@crop-upload-success="bannerUploadSuccess"
:width="400"
:height="260"
img-format="png"
v-model="postForm.banner"
>
</upload-corp-image>
</el-form-item>
<el-form-item label="重复类型" prop="repeatType">
<el-select
v-model="postForm.repeatType"
placeholder="选择"
name="repeatType"
required
class="w100"
>
<el-option
v-for="item in repeatTypes"
:key="item.id"
:label="item.label"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item
label="活动时间"
v-if="postForm.repeatType !== 9"
prop="beginTime">
<el-select
v-model="selectTime"
placeholder="选择或输入时间, 格式 09:15"
name="beginTime"
required
multiple
clearable
filterable
allow-create
style="width: 60%"
default-first-option
@change="timeChange"
>
<el-option
v-for="item in times"
:key="item"
:label="item"
:value="item"
/>
</el-select>
</el-form-item>
<el-form-item
label="周几"
v-if="postForm.repeatType === 2"
prop="weekDays">
<el-select
v-model="postForm.weekDays"
placeholder="选择周几"
name="weekDays"
required
multiple
clearable
style="width: 60%"
default-first-option
>
<el-option
v-for="item in weekDays"
:key="item.id"
:label="item.label"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item
label="选择天"
v-if="postForm.repeatType === 3"
prop="monthDays">
<el-select
v-model="postForm.monthDays"
placeholder="选择每月中需要运行的日子"
name="monthDays"
required
multiple
clearable
style="width: 60%"
@change="monthDaysChange"
default-first-option
>
<el-option
v-for="item in monthDays"
:key="item.id"
:label="item.label"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item
label="指定日期"
prop="selectDate"
v-if="postForm.repeatType === 0"
>
<el-date-picker
v-model="selectDate"
type="dates"
align="right"
@change="dataChange"
style="width: 60%"
placeholder="选择一个或多个日期"
>
</el-date-picker>
</el-form-item>
<el-form-item
label="开始/结束日期"
prop="dataRange"
v-if="postForm.repeatType !== 0 && postForm.repeatType !== 9"
>
<el-date-picker
v-model="dataRange"
type="daterange"
align="right"
style="width: 40%"
unlink-panels
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
>
</el-date-picker>
</el-form-item>
<el-form-item
label="准备时间(分):"
prop="prepareTime"
v-if="postForm.repeatType !== 9"
>
<el-input
v-model="postForm.prepareTime"
placeholder="提前多少时间可进游戏房间(分钟)"
name="prepareTime"
required
/>
</el-form-item>
</el-tab-pane>
<el-tab-pane label="题库设置" name="second">
<el-form-item
label="题目数量:"
prop="qcount"
>
<el-input
v-model="postForm.qcount"
placeholder="本次活动题目数量"
name="qcount"
type="number"
required
/>
</el-form-item>
<el-form-item
label="题库分类"
>
<el-tree
:data="typeOptions"
show-checkbox
accordion
node-key="id"
ref="typeTree"
highlight-current
:default-checked-keys="typeSelected"
:props="defaultProps">
</el-tree>
</el-form-item>
</el-tab-pane>
<el-tab-pane label="奖励设置" name="third">
<el-button
type="primary"
icon="el-icon-edit"
@click="handleCreateReward"
>
添加
</el-button>
<el-table
:data="postForm.rewardInfo"
border
fit
highlight-current-row
>
<el-table-column
label="排名"
prop="rank"
:formatter="formatRank"
>
</el-table-column>
<el-table-column
label="奖励"
prop="coupon"
:formatter = "formatCoupon"
>
</el-table-column>
<el-table-column
align="center"
width="180"
label="操作"
fixed="right"
>
<template slot-scope="scope">
<el-button
type="primary"
size="small"
icon="el-icon-edit"
@click="handleEdit(scope)"
>
编辑
</el-button>
<el-button
type="danger"
size="small"
style="margin-left: 10px"
@click="deleteRank(scope)"
>
{{ $t('permission.delete') }}
</el-button>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
</el-tabs>
<el-form-item>
<el-button
type="primary"
@click="submitForm"
>
保存
</el-button>
<el-button @click="onCancel">
取消
</el-button>
</el-form-item>
</el-form>
<el-dialog
:visible.sync="dialogVisible"
title="编辑奖励"
>
<el-form
:model="record"
ref="modalForm"
:rules="modalRules"
label-width="80px"
label-position="left"
>
<el-form-item label="排名" prop="rank">
<el-input
v-model="record.rank"
placeholder="排名"
type="number"
style="width: 30%"
/>
名至
<el-input
v-model="record.rankEnd"
placeholder="可不填"
type="number"
style="width: 30%"
/>
</el-form-item>
<el-form-item label="奖励" prop="coupon">
<el-select
v-model="record.coupon"
placeholder="选择奖励"
name="coupon"
required
class="w100"
>
<el-option
v-for="item in coupons"
:key="item._id"
:label="item.name"
:value="item._id"
/>
</el-select>
</el-form-item>
<el-form-item label="数量" prop="count">
<el-input
v-model="record.count"
placeholder="数量"
type="number"
/>
</el-form-item>
<el-form-item>
<el-button
type="primary"
@click="saveReward"
v-permission="['activity:edit']"
>
保存
</el-button>
<el-button @click="closeModal">
取消
</el-button>
</el-form-item>
</el-form>
</el-dialog>
</div>
</template>
<script lang="ts">
import { Component, Vue, Watch } from 'vue-property-decorator'
import { AppModule } from '@/store/modules/app'
import { ITagView, TagsViewModule } from '@/store/modules/tags-view'
import MaterialInput from '@/components/MaterialInput/index.vue'
import Sticky from '@/components/Sticky/index.vue'
import UploadImage from '@/components/UploadImage/index.vue'
import RegionPicker from '@/components/RegionPicker/index.vue'
import { getMyShop, getShops } from '@/api/shop'
import { defaultActivityData, defaultRewardData, getActivity, IRewardData, saveActivity } from '@/api/activity'
import { sec2TimeStr, timeStr2Sec } from '@/utils'
import { getAllCategory } from '@/api/question'
import { cloneDeep } from 'lodash'
import { getCoupons, ICouponData } from '@/api/coupon'
import { IShopData } from '@/api/types'
import { ElTree } from 'element-ui/types/tree'
import { UserModule } from '@/store/modules/user'
import UploadCorpImage from '@/components/UploadCorpImage/index.vue'
import { EVENT_ACTIVITY_UPDATE, EVENT_COUPON_UPDATE, EVENT_SHOP_UPDATE, EventBus } from '@/utils/event-bus'
@Component({
name: 'MailEditor',
components: {
MaterialInput,
Sticky,
UploadImage,
RegionPicker,
UploadCorpImage
}
})
export default class extends Vue {
private validateRequire = (rule: any, value: string, callback: Function) => {
if (value === '') {
if (rule.field === 'imageURL') {
this.$message({
message: 'Upload cover image is required',
type: 'error'
})
} else {
this.$message({
message: rule.field + ' 是必填的',
type: 'error'
})
}
callback(new Error(rule.field + ' 是必填的'))
} else {
callback()
}
}
private activeName = 'first'
private monthDays: {id: number, label: string}[] = []
private repeatTypes = [
{ id: 0, label: '指定日期' },
{ id: 1, label: '每日' },
{ id: 2, label: '每周' },
{ id: 3, label: '每月' },
{ id: 9, label: '随时(一般测试用)' }
]
private weekDays = [
{ id: 0, label: '周日' },
{ id: 1, label: '周一' },
{ id: 2, label: '周二' },
{ id: 3, label: '周三' },
{ id: 4, label: '周四' },
{ id: 5, label: '周五' },
{ id: 6, label: '周六' }
]
private dataRange: Date[] = []
private selectDate: Date[] = []
private times: string[] = []
private selectTime: string[] = []
private postForm = Object.assign({}, defaultActivityData)
private loading = false
private allDepts: IShopData[] = []
private typeOptions: {id: string, label: string, children?: any[]}[] = []
private typeSelected: string[] = []
private defaultProps = {
children: 'children',
label: 'label'
}
private rules = {
name: [{ validator: this.validateRequire }]
}
private tempTagView?: ITagView
private dialogType = 'new'
private record: IRewardData = {type: 0}
private dialogVisible = false
private modalRules = {
rank: [{ required: true, message: '请输入排名', trigger: 'blur' }
]
}
private coupons: ICouponData[] = []
$refs!: {
modalForm: HTMLFormElement
postForm: HTMLFormElement
typeTree: ElTree<any, any>
}
get userLevel() {
return UserModule.level
}
get lang() {
return AppModule.language
}
async created() {
this.initTimes()
const id = this.$route.params?.id
await this.getRemoteCategory()
if (id) {
await this.fetchData(id)
}
if (UserModule.level === 1) {
await this.getRemoteDeptList()
EventBus.$on(EVENT_SHOP_UPDATE, () => {
this.getRemoteDeptList()
})
} else {
this.postForm.shop = UserModule.department
await this.fetchMyShop()
}
this.tempTagView = Object.assign({}, this.$route)
EventBus.$on(EVENT_COUPON_UPDATE, () => {
if (this.postForm.shop) {
this.getCouponList(this.postForm.shop)
}
})
}
beforeDestory() {
EventBus.$off(EVENT_COUPON_UPDATE)
if (UserModule.level === 1) {
EventBus.$off(EVENT_SHOP_UPDATE)
}
}
private async fetchData(id: string) {
try {
const { data } = await getActivity(id, { /* Your params here */ })
console.log(data)
this.postForm = data
this.selectTime = []
if (data.beginTime) {
for (const str of data.beginTime) {
this.selectTime.push(sec2TimeStr(str, false))
}
}
this.selectDate = []
if (data.beginDays) {
for (const sub of data.beginDays) {
this.selectDate.push(new Date(sub))
}
}
if (data.beginDay && data.endDay) {
this.dataRange.push(new Date(data.beginDay))
this.dataRange.push(new Date(data.endDay))
}
// Just for test
const title = this.lang === 'zh' ? '编辑活动' : 'Edit Activity'
// Set tagsview title
this.setTagsViewTitle(title)
// Set page title
this.setPageTitle(title)
} catch (err) {
console.error(err)
}
}
private setTagsViewTitle(title: string) {
const tagView = this.tempTagView
if (tagView) {
tagView.title = `${title}-${this.postForm._id}`
TagsViewModule.updateVisitedView(tagView)
}
}
private setPageTitle(title: string) {
document.title = `${title} - ${this.postForm._id}`
}
private async submitForm() {
try {
await this.$refs.postForm.validate()
const times = []
for (const str of this.selectTime) {
times.push(timeStr2Sec(str))
}
this.postForm.beginTime = times
this.postForm.beginDays.length = 0
for (const d of this.selectDate) {
this.postForm.beginDays.push(d.getTime())
}
if (this.dataRange.length > 1) {
this.postForm.beginDay = this.dataRange[0].getTime()
this.postForm.endDay = this.dataRange[1].getTime()
}
this.postForm.qtypes = this.$refs.typeTree.getCheckedKeys()
this.loading = true
const { data } = await saveActivity(this.postForm)
this.postForm = data
this.loading = false
this.$notify({
title: 'Success',
message: 'The post save successfully',
type: 'success',
duration: 2000
})
EventBus.$emit(EVENT_ACTIVITY_UPDATE, {})
} catch (err) {
console.error('Submit Error!')
return false
}
}
private async onCancel() {
try {
await this.$confirm('确认不保存当前活动信息?', 'Warning', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
this.$store.dispatch('delView', this.$route)
this.$router.go(-1)
} catch (e) {
}
}
private async getRemoteDeptList() {
const { data } = await getShops({})
if (!data.records) return
this.allDepts = data.records
}
private async fetchMyShop() {
const { data } = await getMyShop()
this.typeSelected = data.qtypes
console.log(this.typeSelected)
this.$refs.typeTree.setCheckedKeys(this.typeSelected)
}
private dataChange(_: any) {
console.log(this.selectDate)
}
private initTimes() {
for (let i = 0; i < 24; i++) {
for (let j = 0; j < 4; j++) {
const secs = i * 3600 + j * 15 * 60
const label = sec2TimeStr(secs, false)
this.times.push(label)
}
}
this.monthDays.push({ id: 0, label: '全选' })
for (let i = 1; i < 32; i++) {
this.monthDays.push({ id: i, label: i + '' })
}
}
private timeChange(vals: string[]) {
if (vals.length > 0) {
let lastVal = this.selectTime[this.selectTime.length - 1]
if (!/^\d{1,2}:\d{1,2}$/.test(lastVal)) {
this.selectTime.pop()
}
lastVal = sec2TimeStr(timeStr2Sec(lastVal), false)
this.selectTime.splice(this.selectTime.length - 1, 1, lastVal)
console.log(this.selectTime)
}
}
private monthDaysChange(days: number[]) {
if (days.indexOf(0) >= 0) {
this.postForm.monthDays.length = 0
for (let i = 1; i < 32; i++) {
this.postForm.monthDays.push(i)
}
}
}
@Watch('postForm.shop')
private onShopChange() {
if (this.postForm.shop) {
this.getCouponList(this.postForm.shop)
}
if (this.postForm.qtypes?.length > 0) {
this.typeSelected = this.postForm.qtypes
} else if (this.postForm.shop) {
let currentShop
for (const p of this.allDepts) {
if (p._id === this.postForm.shop) {
currentShop = p
break
}
}
if (currentShop) {
this.typeSelected = currentShop.qtypes
} else {
this.typeSelected = []
}
}
this.$refs.typeTree.setCheckedKeys(this.typeSelected)
}
// begin of set puzzle types
private async getRemoteCategory() {
const { data } = await getAllCategory()
for (const cat of data) {
const subArr = []
for (const s of cat.children) {
subArr.push({
id: s._id,
label: s.name
})
}
this.typeOptions.push({
id: cat._id,
label: cat.name,
children: subArr
})
}
}
// begin of award list
private async getCouponList(shop: string) {
const { data } = await getCoupons({ shop })
this.coupons = data.records
}
private formatCoupon(row: number, column: number, cellValue: string, index: number) {
let result = `未知(${cellValue})`
const data = this.postForm.rewardInfo[index]
for (const dep of this.coupons) {
if (dep._id === cellValue) {
result = dep.name
break
}
}
return `${result} x ${data.count}`
}
private formatRank(row: number, column: number, cellValue: string, index: number) {
const data = this.postForm.rewardInfo[index]
let result = `${data.rank}`
if (data.rankEnd) {
result = `${data.rank}${data.rankEnd}`
}
return result
}
private async deleteRank(scope: any) {
const { $index } = scope
try {
await this.$confirm('Confirm to remove the record?', 'Warning', {
confirmButtonText: 'Confirm',
cancelButtonText: 'Cancel',
type: 'warning'
})
this.postForm.rewardInfo.splice($index, 1)
this.$message({
type: 'success',
message: '删除成功, 请点击保存'
})
} catch (err) {
}
}
private handleCreateReward() {
this.record = Object.assign({}, defaultRewardData)
this.record.id = this.postForm.rewardInfo.length
this.dialogType = 'new'
this.dialogVisible = true
}
private handleEdit(scope: any) {
this.dialogType = 'edit'
this.dialogVisible = true
this.record = cloneDeep(scope.row)
}
private closeModal() {
this.dialogVisible = false
this.$refs.modalForm.clearValidate()
}
private saveReward() {
const isEdit = this.dialogType === 'edit';
(this.$refs.modalForm as HTMLFormElement).validate(async(valid: boolean) => {
if (!valid) {
this.$message.error('请按要求填写表单')
return false
}
if (isEdit) {
for (let index = 0; index < this.postForm.rewardInfo.length; index++) {
if (this.postForm.rewardInfo[index].id === this.record.id) {
this.postForm.rewardInfo.splice(index, 1, Object.assign({}, this.record))
break
}
}
} else {
this.postForm.rewardInfo.push(this.record)
}
this.dialogVisible = false
this.$notify({
title: 'Success',
dangerouslyUseHTMLString: true,
message: `
奖励成功保存, 请点击保存
`,
type: 'success'
})
})
}
private iconUploadSuccess(imgUrl: string) {
console.log('upload icon success: ' + imgUrl)
this.postForm.icon = imgUrl
this.$forceUpdate()
}
private bannerUploadSuccess(imgUrl: string) {
console.log('upload banner success: ' + imgUrl)
this.postForm.banner = imgUrl
this.$forceUpdate()
}
}
</script>
<style lang="scss" scoped>
</style>

325
src/views/mail/list.vue Normal file
View File

@ -0,0 +1,325 @@
<template>
<div class="app-container">
<!-- filter -->
<el-form ref="filterForm" :inline="true" :model="filterForm" class="filter">
<el-form-item label="关键字" prop="key">
<el-input v-model="filterForm.key" placeholder="关键字"/>
</el-form-item>
<el-form-item :label="$t('main.shop')" prop="key" v-if="userLevel === 1">
<el-select
v-model="filterForm.shop"
:placeholder="'选择'+$t('main.shop')"
name="shop"
required
class="w100"
>
<el-option
v-for="item in allDepts"
:key="item._id"
:label="item.name"
:value="item._id"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="search">查询</el-button>
<el-button @click="resetFilterForm">重置</el-button>
</el-form-item>
</el-form>
<router-link to="/shop/activity_new">
<el-button
type="primary"
icon="el-icon-edit"
v-permission="['activity:edit']"
>
添加
</el-button>
</router-link>
<el-table
v-loading="listLoading"
:data="list"
border
fit
stripe
highlight-current-row
style="width: 100%;margin-top:30px;"
>
<el-table-column
width="180px"
align="center"
label="添加时间"
>
<template slot-scope="{row}">
<span>{{ row.createdAt | parseTime }}</span>
</template>
</el-table-column>
<el-table-column
:label="$t('main.shop')"
prop="shop"
v-if="userLevel === 1"
:formatter = "formatDept"
>
</el-table-column>
<el-table-column
min-width="200px"
label="名称"
>
<template slot-scope="{row}">
<router-link
:to="'/shop/activity_edit/'+row._id"
class="link-type"
>
<span>{{ row.name }}</span>
</router-link>
</template>
</el-table-column>
<el-table-column
label="是否启用"
prop="active"
:formatter="formatBool"
>
</el-table-column>
<el-table-column
align="center"
width="320"
label="操作"
fixed="right"
>
<template slot-scope="scope">
<el-button
:type="scope.row.active? 'warning': 'success'"
size="small"
style="margin-right: 10px"
v-permission="['activity:edit']"
@click="updateActivityStata(scope)"
>
{{ scope.row.active? '冻结': '激活' }}
</el-button>
<router-link :to="'/shop/activity_edit/'+scope.row._id">
<el-button
type="primary"
size="small"
icon="el-icon-edit"
v-permission="['activity:edit']"
>
编辑
</el-button>
</router-link>
<el-button
type="danger"
size="small"
style="margin-left: 10px"
v-permission="['activity:delete']"
@click="handleDelete(scope)"
>
{{ $t('permission.delete') }}
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="listQuery.page"
:limit.sync="listQuery.limit"
@pagination="getList"
/>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
import { IShopData } from '@/api/types'
import Pagination from '@/components/Pagination/index.vue'
import { getShops } from '@/api/shop'
import { parseTime } from '@/utils'
import { getAllCategory, getAllTags } from '@/api/question'
import { deleteActivity, getActivitys, IActivityData, publishActivity } from '@/api/activity'
import { UserModule } from '@/store/modules/user'
import { EVENT_ACTIVITY_UPDATE, EVENT_SHOP_UPDATE, EventBus } from '@/utils/event-bus'
@Component({
name: 'MailList',
components: {
Pagination
},
filters: {
parseTime: (timestamp: string) => {
return parseTime(timestamp)
},
parseDate: (timestamp: string) => {
if (!timestamp) {
return '-'
}
return parseTime(timestamp, '{y}-{m}-{d}')
},
formatCount: (count: string) => {
if (!count) {
return 0
}
return count
}
}
})
export default class extends Vue {
private total = 0
private list: IActivityData[] = []
private listLoading = true
private allDepts: IShopData[] = []
private listQuery = {
page: 1,
limit: 20,
key: '',
shop: ''
}
private typeOptions: any[] = []
private tagSet: Set<string> = new Set()
private tagOptions: string[] = []
private filterForm = {
key: '',
shop: ''
}
$refs!: {
filterForm: HTMLFormElement
}
get userLevel() {
return UserModule.level
}
async created() {
if (UserModule.level === 1) {
await this.getRemoteDeptList()
EventBus.$on(EVENT_SHOP_UPDATE, () => {
this.getRemoteDeptList()
})
} else {
this.filterForm.shop = UserModule.department
this.listQuery.shop = UserModule.department
}
await this.getRemoteCategory()
await this.getList()
EventBus.$on(EVENT_ACTIVITY_UPDATE, () => {
this.getList()
})
}
beforeDestory() {
EventBus.$off(EVENT_ACTIVITY_UPDATE)
if (UserModule.level === 1) {
EventBus.$off(EVENT_SHOP_UPDATE)
}
}
private async getList() {
this.listLoading = true
const { data } = await getActivitys(this.listQuery)
this.listLoading = false
this.list = data.records
this.total = data.total
}
private async handleDelete(scope: any) {
const { $index, row } = scope
await this.$confirm('确认删除该记录?', 'Warning', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
await deleteActivity(row._id)
this.list.splice($index, 1)
this.$message({
type: 'success',
message: '删除成功!'
})
}
private search() {
this.filterData()
}
private filterData() {
this.listQuery.key = this.filterForm.key
this.listQuery.shop = this.filterForm.shop
this.listQuery.page = 1
this.getList()
}
private resetFilterForm() {
this.$refs.filterForm.resetFields()
}
private async getRemoteDeptList() {
const { data } = await getShops({ })
if (!data.records) return
this.allDepts = data.records
}
private async getRemoteTags() {
const { data } = await getAllTags()
console.log(data)
this.tagSet = new Set(data)
this.tagOptions = data
}
private async getRemoteCategory() {
const { data } = await getAllCategory()
for (const cat of data) {
const subArr = []
for (const s of cat.children) {
subArr.push({
value: s._id,
label: s.name
})
}
this.typeOptions.push({
value: cat._id,
label: cat.name,
children: subArr
})
}
}
private formatDept(row: number, column: number, cellValue: string) {
let result = '未指定'
for (const dep of this.allDepts) {
if (dep._id === cellValue) {
result = dep.name
break
}
}
return result
}
private formatBool(row: number, column: number, cellValue: boolean) {
return cellValue ? '是' : '否'
}
private async updateActivityStata(scope: any) {
const { row } = scope
const str = row.active ? '确认取消冻结该活动?' : '确定激活该活动?'
try {
await this.$confirm(str, 'Warning', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
await publishActivity({ id: row._id, active: !row.active })
row.active = !row.active
if (row.active) {
for (const _d of this.list) {
_d.active = _d._id === row._id
}
}
} catch (err) {
console.log(err)
}
}
}
</script>

View File

@ -294,7 +294,7 @@ export default class extends Vue {
if (this.record.coupon === 'lottery_ticket') {
this.record.rewardType = 1
} else if (this.record.coupon === 'empty') {
this.record.rewardType = 9
this.record.rewardType = 2
} else {
this.record.rewardType = 0
}
@ -381,7 +381,7 @@ export default class extends Vue {
coupon: 'empty',
rank: rank,
count: 1,
rewardType: 9
rewardType: 2
})
}
this.saveing = true