index.vue 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852
  1. <template>
  2. <div class="app-container">
  3. <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="85px" @submit.native.prevent>
  4. <el-form-item label="活动名称" prop="activityName">
  5. <el-input v-model="queryParams.activityName"
  6. placeholder="请输入活动名称"
  7. clearable
  8. size="small"
  9. @keyup.enter.native="handleQuery" />
  10. </el-form-item>
  11. <el-form-item label="活动状态" prop="status">
  12. <el-select v-model="queryParams.status" placeholder="请选择活动状态" clearable size="small">
  13. <el-option label="未开始" :value="0" />
  14. <el-option label="进行中" :value="1" />
  15. <el-option label="已结束" :value="2" />
  16. <el-option label="已停用" :value="3" />
  17. </el-select>
  18. </el-form-item>
  19. <el-form-item label="奖品类型" prop="prizeType">
  20. <el-select v-model="queryParams.prizeType" placeholder="请选择奖品类型" clearable size="small">
  21. <el-option label="红包" :value="1" />
  22. <el-option label="积分商品免单券" :value="2" />
  23. <el-option label="大礼品" :value="3" />
  24. <el-option label="门店核销券" :value="4" />
  25. </el-select>
  26. </el-form-item>
  27. <el-form-item>
  28. <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  29. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  30. </el-form-item>
  31. </el-form>
  32. <el-row :gutter="10" class="mb8">
  33. <el-col :span="1.5">
  34. <el-button type="primary"
  35. icon="el-icon-plus"
  36. size="mini"
  37. @click="handleAdd"
  38. v-has-permi="['course:checkinActivity:add']">活动配置</el-button>
  39. </el-col>
  40. <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
  41. </el-row>
  42. <el-table v-loading="loading" :data="list" border style="width: 100%">
  43. <el-table-column label="活动ID" align="center" prop="activityId" min-width="80" />
  44. <el-table-column label="活动名称" align="center" prop="activityName" min-width="150" show-overflow-tooltip />
  45. <el-table-column label="活动时间" align="center" min-width="200">
  46. <template slot-scope="scope">
  47. <span>{{ scope.row.startTime }} 至 {{ scope.row.endTime }}</span>
  48. </template>
  49. </el-table-column>
  50. <el-table-column label="需要打卡天数" align="center" prop="checkinDays" min-width="100" />
  51. <el-table-column label="参与公司" align="center" prop="companyNames" min-width="150" show-overflow-tooltip />
  52. <el-table-column label="参与项目" align="center" prop="projectNames" min-width="150" show-overflow-tooltip />
  53. <el-table-column label="奖品类型" align="center" prop="prizeType" min-width="120">
  54. <template slot-scope="scope">
  55. <el-tag v-if="scope.row.prizeType === 1" type="warning">红包</el-tag>
  56. <el-tag v-else-if="scope.row.prizeType === 2" type="success">积分商品免单券</el-tag>
  57. <el-tag v-else-if="scope.row.prizeType === 3" type="primary">大礼品</el-tag>
  58. <el-tag v-else-if="scope.row.prizeType === 4" type="">门店核销券</el-tag>
  59. <span v-else>-</span>
  60. </template>
  61. </el-table-column>
  62. <el-table-column label="活动状态" align="center" prop="status" min-width="100">
  63. <template slot-scope="scope">
  64. <el-tag v-if="scope.row.status === 0" type="info">未开始</el-tag>
  65. <el-tag v-else-if="scope.row.status === 1" type="success">进行中</el-tag>
  66. <el-tag v-else-if="scope.row.status === 2" type="danger">已结束</el-tag>
  67. <el-tag v-else-if="scope.row.status === 3" type="warning">已停用</el-tag>
  68. </template>
  69. </el-table-column>
  70. <el-table-column label="创建时间" align="center" prop="createTime" min-width="160" />
  71. <el-table-column label="操作" align="center" class-name="small-padding fixed-width" min-width="150">
  72. <template slot-scope="scope">
  73. <el-button size="mini"
  74. type="text"
  75. icon="el-icon-edit"
  76. @click="handleUpdate(scope.row)"
  77. v-has-permi="['course:checkinActivity:edit']"
  78. :disabled="scope.row.status === 1">修改</el-button>
  79. <el-button size="mini"
  80. type="text"
  81. icon="el-icon-delete"
  82. @click="handleDelete(scope.row)"
  83. v-has-permi="['course:checkinActivity:remove']"
  84. :disabled="scope.row.status === 1">删除</el-button>
  85. <el-button size="mini"
  86. type="text"
  87. icon="el-icon-document-copy"
  88. @click="handleCopy(scope.row)"
  89. v-has-permi="['course:checkinActivity:add']"
  90. v-if="scope.row.status === 2">复制活动</el-button>
  91. <el-button size="mini"
  92. type="text"
  93. icon="el-icon-gift"
  94. @click="handlePrizeRecord(scope.row)"
  95. v-has-permi="['course:checkinReceive:query']">奖品记录</el-button>
  96. </template>
  97. </el-table-column>
  98. </el-table>
  99. <pagination
  100. v-show="total>0"
  101. :total="total"
  102. :page.sync="queryParams.pageNum"
  103. :limit.sync="queryParams.pageSize"
  104. @pagination="getList"
  105. />
  106. <!-- 添加或修改活动配置对话框 -->
  107. <el-dialog :title="title" :visible.sync="open" width="900px" append-to-body>
  108. <el-form :model="form" ref="form" :rules="rules" label-width="120px">
  109. <el-form-item label="活动名称" prop="activityName">
  110. <el-input v-model="form.activityName" placeholder="请输入活动名称" clearable size="small" />
  111. </el-form-item>
  112. <el-form-item label="活动时间" prop="timeRange">
  113. <el-date-picker
  114. v-model="form.timeRange"
  115. type="daterange"
  116. range-separator="至"
  117. start-placeholder="开始日期"
  118. end-placeholder="结束日期"
  119. value-format="yyyy-MM-dd"
  120. size="small"
  121. style="width: 100%">
  122. </el-date-picker>
  123. </el-form-item>
  124. <el-form-item label="打卡天数" prop="checkinDays">
  125. <el-input-number v-model="form.checkinDays" :min="1" :max="365" :precision="0" size="small" style="width: 200px" placeholder="请输入打卡天数" />
  126. <span style="margin-left: 10px; color: #999;">天</span>
  127. </el-form-item>
  128. <el-form-item label="参与公司" prop="companyIds">
  129. <el-select filterable multiple v-model="form.companyIds" placeholder="请选择参与公司" size="small" style="width: 100%">
  130. <el-option
  131. v-for="item in companys"
  132. :key="item.companyId"
  133. :label="item.companyName"
  134. :value="item.companyId"
  135. />
  136. </el-select>
  137. </el-form-item>
  138. <el-form-item label="参与项目" prop="projectIds">
  139. <el-select filterable multiple v-model="form.projectIds" placeholder="请选择参与项目" size="small" style="width: 100%">
  140. <el-option
  141. v-for="item in projects"
  142. :key="item.dictValue"
  143. :label="item.dictLabel"
  144. :value="item.dictValue"
  145. />
  146. </el-select>
  147. </el-form-item>
  148. <el-form-item label="通知模板" prop="notifyTemplate">
  149. <el-input
  150. v-model="form.notifyTemplate"
  151. type="textarea"
  152. :rows="3"
  153. placeholder="请输入通知模板"
  154. size="small" />
  155. </el-form-item>
  156. <el-form-item label="活动状态" prop="status">
  157. <el-select v-model="form.status" placeholder="请选择活动状态" size="small" style="width: 200px">
  158. <el-option label="未开始" :value="0" />
  159. <el-option label="进行中" :value="1" />
  160. <el-option label="已结束" :value="2" />
  161. <el-option label="已停用" :value="3" />
  162. </el-select>
  163. </el-form-item>
  164. <el-form-item label="奖品类型" prop="prizeType">
  165. <el-select v-model="form.prizeType" placeholder="请选择奖品类型" size="small" style="width: 200px">
  166. <el-option :label="'红包'" :value="1" />
  167. <el-option :label="'积分商品免单券'" :value="2" />
  168. <el-option label="大礼品" :value="3" />
  169. <el-option label="门店核销券" :value="4" />
  170. </el-select>
  171. </el-form-item>
  172. <el-form-item v-if="form.prizeType === 1" label="红包金额" prop="redpacketAmount"
  173. :rules="{ required: true, message: '红包金额不能为空', trigger: 'blur' }">
  174. <el-input-number v-model="form.redpacketAmount" :min="0.1" :precision="2" :step="0.1" size="small" style="width: 200px" />
  175. <span style="margin-left: 10px; color: #999;">元</span>
  176. </el-form-item>
  177. <el-form-item v-if="form.prizeType === 2" label="免单券" prop="freeCouponId"
  178. :rules="{ required: true, message: '免单券不能为空', trigger: 'change' }">
  179. <el-select
  180. ref="customSelectCoupon"
  181. v-model="form.freeCouponId"
  182. placeholder="请选择优惠券"
  183. @click.native.stop="openCouponDrawer"
  184. clearable
  185. style="width: 100%;">
  186. <el-option
  187. v-for="item in couponList"
  188. :key="item.id"
  189. :label="item.name"
  190. :value="item.id">
  191. </el-option>
  192. </el-select>
  193. </el-form-item>
  194. <el-form-item v-if="form.prizeType === 3" label="大礼品配置" prop="grandGiftId"
  195. :rules="{ required: true, message: '大礼品配置不能为空', trigger: 'change' }">
  196. <el-select
  197. ref="customSelectReward"
  198. v-model="form.grandGiftId"
  199. placeholder="请选择大礼品奖励"
  200. @click.native.stop="openRewardDrawer"
  201. clearable
  202. style="width: 100%;">
  203. <el-option
  204. v-for="item in rewardList"
  205. :key="item.id"
  206. :label="item.name"
  207. :value="item.id">
  208. </el-option>
  209. </el-select>
  210. </el-form-item>
  211. <el-form-item v-if="form.prizeType === 4" label="门店核销券" prop="freeCouponId"
  212. :rules="{ required: true, message: '门店核销券不能为空', trigger: 'change' }">
  213. <el-select
  214. ref="customSelectVerifyCoupon"
  215. v-model="form.freeCouponId"
  216. placeholder="请选择门店核销券"
  217. @click.native.stop="openVerifyCouponDrawer"
  218. clearable
  219. style="width: 100%;">
  220. <el-option
  221. v-for="item in verifyCouponList"
  222. :key="item.id"
  223. :label="item.name"
  224. :value="item.id">
  225. </el-option>
  226. </el-select>
  227. </el-form-item>
  228. <el-form-item label="备注" prop="remark">
  229. <el-input v-model="form.remark" type="textarea" :rows="2" placeholder="请输入备注" size="small" />
  230. </el-form-item>
  231. </el-form>
  232. <div slot="footer" class="dialog-footer">
  233. <el-button @click="cancel">取 消</el-button>
  234. <el-button type="primary" @click="submitForm">确 定</el-button>
  235. </div>
  236. </el-dialog>
  237. <!-- 复制活动对话框 -->
  238. <el-dialog title="复制活动" :visible.sync="copyOpen" width="500px" append-to-body>
  239. <el-form :model="copyForm" ref="copyForm" :rules="copyRules" label-width="120px">
  240. <el-form-item label="新活动时间" prop="timeRange">
  241. <el-date-picker
  242. v-model="copyForm.timeRange"
  243. type="daterange"
  244. range-separator="至"
  245. start-placeholder="开始日期"
  246. end-placeholder="结束日期"
  247. value-format="yyyy-MM-dd"
  248. size="small"
  249. style="width: 100%">
  250. </el-date-picker>
  251. </el-form-item>
  252. </el-form>
  253. <div slot="footer" class="dialog-footer">
  254. <el-button @click="copyOpen = false">取 消</el-button>
  255. <el-button type="primary" @click="submitCopy">确 定</el-button>
  256. </div>
  257. </el-dialog>
  258. <!-- 奖品领取记录对话框 -->
  259. <el-dialog :title="'奖品领取记录 - ' + prizeRecordTitle" :visible.sync="prizeRecordOpen" width="900px" append-to-body>
  260. <el-tabs v-model="prizeRecordType">
  261. <el-tab-pane label="红包记录" name="1" v-if="prizeRecordType === '1'">
  262. <el-table v-loading="prizeRecordLoading" :data="prizeRecordList" border style="width: 100%">
  263. <el-table-column label="ID" align="center" prop="receiveId" min-width="80" />
  264. <el-table-column label="用户昵称" align="center" prop="userNickName" min-width="120" show-overflow-tooltip />
  265. <el-table-column label="企业名" align="center" prop="companyName" min-width="150" show-overflow-tooltip />
  266. <el-table-column label="红包金额" align="center" prop="redpacketAmount" min-width="100">
  267. <template slot-scope="scope">
  268. <span>{{ scope.row.redpacketAmount }} 元</span>
  269. </template>
  270. </el-table-column>
  271. <el-table-column label="领取状态" align="center" prop="receiveStatus" min-width="100">
  272. <template slot-scope="scope">
  273. <el-tag v-if="scope.row.receiveStatus === 0" type="info">未领取</el-tag>
  274. <el-tag v-else-if="scope.row.receiveStatus === 1" type="success">已领取</el-tag>
  275. <el-tag v-else-if="scope.row.receiveStatus === 2" type="danger">领取失败</el-tag>
  276. </template>
  277. </el-table-column>
  278. <el-table-column label="领取时间" align="center" prop="receiveTime" min-width="160" />
  279. </el-table>
  280. </el-tab-pane>
  281. <el-tab-pane label="积分商品免单券领取记录" name="2" v-if="prizeRecordType === '2'">
  282. <el-table v-loading="prizeRecordLoading" :data="prizeRecordList" border style="width: 100%">
  283. <el-table-column label="ID" align="center" prop="receiveId" min-width="80" />
  284. <el-table-column label="用户昵称" align="center" prop="userNickName" min-width="120" show-overflow-tooltip />
  285. <el-table-column label="企业名" align="center" prop="companyName" min-width="150" show-overflow-tooltip />
  286. <el-table-column label="积分商品名" align="center" prop="goodsName" min-width="150" show-overflow-tooltip />
  287. <el-table-column label="领取状态" align="center" prop="receiveStatus" min-width="100">
  288. <template slot-scope="scope">
  289. <el-tag v-if="scope.row.receiveStatus === 0" type="info">未领取</el-tag>
  290. <el-tag v-else-if="scope.row.receiveStatus === 1" type="success">已领取</el-tag>
  291. <el-tag v-else-if="scope.row.receiveStatus === 2" type="danger">领取失败</el-tag>
  292. </template>
  293. </el-table-column>
  294. <el-table-column label="领取时间" align="center" prop="receiveTime" min-width="160" />
  295. </el-table>
  296. </el-tab-pane>
  297. <el-tab-pane label="大礼品转盘领取记录" name="3" v-if="prizeRecordType === '3'">
  298. <el-table v-loading="prizeRecordLoading" :data="prizeRecordList" border style="width: 100%">
  299. <el-table-column label="ID" align="center" prop="receiveId" min-width="80" />
  300. <el-table-column label="用户昵称" align="center" prop="userNickName" min-width="120" show-overflow-tooltip />
  301. <el-table-column label="企业名" align="center" prop="companyName" min-width="150" show-overflow-tooltip />
  302. <el-table-column label="奖励名称" align="center" prop="goodsName" min-width="150" show-overflow-tooltip />
  303. <el-table-column label="领取状态" align="center" prop="receiveStatus" min-width="100">
  304. <template slot-scope="scope">
  305. <el-tag v-if="scope.row.receiveStatus === 0" type="info">未领取</el-tag>
  306. <el-tag v-else-if="scope.row.receiveStatus === 1" type="success">已领取</el-tag>
  307. <el-tag v-else-if="scope.row.receiveStatus === 2" type="danger">领取失败</el-tag>
  308. </template>
  309. </el-table-column>
  310. <el-table-column label="领取时间" align="center" prop="receiveTime" min-width="160" />
  311. </el-table>
  312. </el-tab-pane>
  313. <el-tab-pane label="门店核销券领取记录" name="4" v-if="prizeRecordType === '4'">
  314. <el-table v-loading="prizeRecordLoading" :data="prizeRecordList" border style="width: 100%">
  315. <el-table-column label="ID" align="center" prop="receiveId" min-width="80" />
  316. <el-table-column label="用户昵称" align="center" prop="userNickName" min-width="120" show-overflow-tooltip />
  317. <el-table-column label="企业名" align="center" prop="companyName" min-width="150" show-overflow-tooltip />
  318. <el-table-column label="优惠券名称" align="center" prop="prizeName" min-width="150" show-overflow-tooltip />
  319. <el-table-column label="领取状态" align="center" prop="receiveStatus" min-width="100">
  320. <template slot-scope="scope">
  321. <el-tag v-if="scope.row.receiveStatus === 0" type="info">未领取</el-tag>
  322. <el-tag v-else-if="scope.row.receiveStatus === 1" type="success">已领取</el-tag>
  323. <el-tag v-else-if="scope.row.receiveStatus === 2" type="danger">领取失败</el-tag>
  324. </template>
  325. </el-table-column>
  326. <el-table-column label="领取时间" align="center" prop="receiveTime" min-width="160" />
  327. </el-table>
  328. </el-tab-pane>
  329. </el-tabs>
  330. <pagination
  331. v-show="prizeRecordTotal>0"
  332. :total="prizeRecordTotal"
  333. :page.sync="prizeRecordQuery.pageNum"
  334. :limit.sync="prizeRecordQuery.pageSize"
  335. @pagination="getPrizeRecordList"
  336. />
  337. </el-dialog>
  338. <!-- 选择大礼品 -->
  339. <el-drawer :append-to-body="true" :with-header="false" size="75%" :visible.sync="rewardDrawerOpen">
  340. <reward-component :reward-type="6" @select-reward="selectReward"></reward-component>
  341. </el-drawer>
  342. <!-- 选择公域疗法券优惠券 -->
  343. <el-drawer :append-to-body="true" :with-header="false" size="75%" :visible.sync="couponDrawerOpen">
  344. <coupon-component :coupon-type="7" @select-coupon="selectCoupon"></coupon-component>
  345. </el-drawer>
  346. <!-- 选择门店核销券 -->
  347. <el-drawer :append-to-body="true" :with-header="false" size="75%" :visible.sync="verifyCouponDrawerOpen">
  348. <coupon-component :coupon-type="8" @select-coupon="selectVerifyCoupon"></coupon-component>
  349. </el-drawer>
  350. </div>
  351. </template>
  352. <script>
  353. import { getCompanyList } from "@/api/company/company";
  354. import { listByIds, listReward } from '@/api/course/reward'
  355. import { listIntegralGoods } from "@/api/his/integralGoods";
  356. import {
  357. listCheckinActivity,
  358. getCheckinActivity,
  359. addCheckinActivity,
  360. updateCheckinActivity,
  361. delCheckinActivity,
  362. copyCheckinActivity,
  363. getPrizeRecord
  364. } from "@/api/his/checkinActivity";
  365. import CouponComponent from '@/views/components/his/couponComponent.vue'
  366. import RewardComponent from '@/views/components/course/rewardComponent.vue'
  367. import { getByIds } from '@/api/his/coupon'
  368. export default {
  369. name: "CourseCheckIn",
  370. components: { CouponComponent, RewardComponent },
  371. data() {
  372. return {
  373. loading: true,
  374. showSearch: true,
  375. total: 0,
  376. list: [],
  377. companys: [],
  378. projects: [],
  379. integralGoodsList: [],
  380. grandGiftList: [],
  381. open: false,
  382. title: "",
  383. queryParams: {
  384. pageNum: 1,
  385. pageSize: 10,
  386. activityName: null,
  387. status: null,
  388. prizeType: null
  389. },
  390. form: {
  391. activityId: null,
  392. activityName: null,
  393. timeRange: [],
  394. startTime: null,
  395. endTime: null,
  396. companyIds: [],
  397. projectIds: [],
  398. notifyTemplate: null,
  399. status: 0,
  400. prizeType: 1,
  401. redpacketAmount: null,
  402. prizeGoodsId: null,
  403. prizeGoodsName: null,
  404. prizeList: [],
  405. remark: null,
  406. checkinDays: null,
  407. grandGiftId: null,
  408. freeCouponId: null,
  409. },
  410. rules: {
  411. activityName: [
  412. { required: true, message: "活动名称不能为空", trigger: "blur" }
  413. ],
  414. timeRange: [
  415. { required: true, message: "活动时间不能为空", trigger: "change" }
  416. ],
  417. checkinDays: [
  418. { required: true, message: "打卡天数不能为空", trigger: "blur" },
  419. { type: "number", min: 1, message: "打卡天数必须大于0", trigger: "blur" },
  420. { validator: this.validateCheckinDays, trigger: "blur" }
  421. ],
  422. companyIds: [
  423. { required: true, message: "参与公司不能为空", trigger: "change" }
  424. ],
  425. projectIds: [
  426. { required: true, message: "参与项目不能为空", trigger: "change" }
  427. ],
  428. },
  429. copyOpen: false,
  430. copyForm: {
  431. activityId: null,
  432. timeRange: []
  433. },
  434. copyRules: {
  435. timeRange: [
  436. { required: true, message: "新活动时间不能为空", trigger: "change" }
  437. ]
  438. },
  439. // 奖品领取记录
  440. prizeRecordOpen: false,
  441. prizeRecordTitle: "",
  442. prizeRecordType: null,
  443. prizeRecordLoading: false,
  444. prizeRecordList: [],
  445. prizeRecordTotal: 0,
  446. prizeRecordQuery: {
  447. pageNum: 1,
  448. pageSize: 10,
  449. activityId: null,
  450. prizeType: 1
  451. },
  452. couponDrawerOpen: false,
  453. couponList: [],
  454. verifyCouponDrawerOpen: false,
  455. verifyCouponList: [],
  456. rewardDrawerOpen: false,
  457. rewardList: [],
  458. };
  459. },
  460. created() {
  461. this.getCompanyList();
  462. this.getProjectList();
  463. this.getIntegralGoodsList();
  464. this.getList();
  465. this.initGiftList()
  466. },
  467. methods: {
  468. getList() {
  469. this.loading = true;
  470. listCheckinActivity(this.queryParams).then(response => {
  471. this.list = response.rows || [];
  472. this.total = response.total || 0;
  473. this.loading = false;
  474. }).catch(() => {
  475. this.loading = false;
  476. });
  477. },
  478. getCompanyList() {
  479. getCompanyList().then(response => {
  480. this.companys = response.data || [];
  481. });
  482. },
  483. getProjectList() {
  484. this.getDicts("sys_course_project").then(response => {
  485. this.projects = response.data || [];
  486. });
  487. },
  488. getIntegralGoodsList() {
  489. listIntegralGoods({ pageNum: 1, pageSize: 1000 }).then(response => {
  490. this.integralGoodsList = response.rows || [];
  491. });
  492. },
  493. initGiftList() {
  494. listReward({"rewardType": 6}).then(response => {
  495. const {rows} = response
  496. this.grandGiftList = rows
  497. })
  498. },
  499. handleQuery() {
  500. this.queryParams.pageNum = 1;
  501. this.getList();
  502. },
  503. resetQuery() {
  504. this.resetForm("queryForm");
  505. this.queryParams = {
  506. pageNum: 1,
  507. pageSize: 10,
  508. activityName: null,
  509. status: null,
  510. prizeType: null
  511. };
  512. this.handleQuery();
  513. },
  514. reset() {
  515. this.form = {
  516. activityId: null,
  517. activityName: null,
  518. timeRange: [],
  519. startTime: null,
  520. endTime: null,
  521. companyIds: [],
  522. projectIds: [],
  523. notifyTemplate: null,
  524. status: 0,
  525. prizeType: 1,
  526. redpacketAmount: null,
  527. prizeGoodsId: null,
  528. prizeGoodsName: null,
  529. prizeList: [],
  530. remark: null,
  531. checkinDays: null,
  532. grandGiftId: null,
  533. freeCouponId: null,
  534. };
  535. },
  536. // 校验打卡天数不能超过活动时长
  537. validateCheckinDays(rule, value, callback) {
  538. if (!this.form.timeRange || this.form.timeRange.length < 2) {
  539. callback(new Error('请先选择活动时间'));
  540. return;
  541. }
  542. const startDate = new Date(this.form.timeRange[0]);
  543. const endDate = new Date(this.form.timeRange[1]);
  544. const diffTime = Math.abs(endDate - startDate);
  545. const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)) + 1; // 包含首尾天数
  546. if (value > diffDays) {
  547. callback(new Error('打卡天数不能超过活动时长(' + diffDays + '天)'));
  548. } else {
  549. callback();
  550. }
  551. },
  552. handlePrizeGoodsChange(goodsId) {
  553. if (goodsId) {
  554. const goods = this.integralGoodsList.find(item => item.goodsId === goodsId);
  555. this.form.prizeGoodsName = goods ? goods.goodsName : null;
  556. } else {
  557. this.form.prizeGoodsName = null;
  558. }
  559. },
  560. handleAdd() {
  561. this.reset();
  562. this.open = true;
  563. this.title = "添加打卡活动";
  564. // 等待对话框打开后再重置表单验证
  565. this.$nextTick(() => {
  566. this.resetForm("form");
  567. });
  568. },
  569. handleUpdate(row) {
  570. const activityId = row.activityId;
  571. getCheckinActivity(activityId).then(response => {
  572. // 先重置表单
  573. this.reset();
  574. // 使用 Object.assign 合并数据,保持响应式
  575. Object.assign(this.form, response.data);
  576. this.$set(this.form, 'timeRange', [this.form.startTime, this.form.endTime]);
  577. // 将逗号分隔的字符串转为数组
  578. if (this.form.companyIds) {
  579. this.$set(this.form, 'companyIds', this.form.companyIds.split(',').map(id => parseInt(id)));
  580. } else {
  581. this.$set(this.form, 'companyIds', []);
  582. }
  583. if (this.form.projectIds) {
  584. this.$set(this.form, 'projectIds', this.form.projectIds.split(','));
  585. } else {
  586. this.$set(this.form, 'projectIds', []);
  587. }
  588. // 处理奖品数据 - 从prizeList解析单个奖品
  589. if (this.form.prizeList && this.form.prizeList.length > 0) {
  590. const prize = this.form.prizeList[0];
  591. this.$set(this.form, 'prizeType', Number(prize.prizeType));
  592. if (this.form.prizeType === 1) {
  593. this.$set(this.form, 'redpacketAmount', prize.redpacketAmount);
  594. } else if (this.form.prizeType === 2) {
  595. this.$set(this.form, 'freeCouponId', prize.freeCouponId)
  596. this.initCouponList(prize.freeCouponId)
  597. } else if (this.form.prizeType === 3) {
  598. this.$set(this.form, 'grandGiftId', prize.grandGiftId);
  599. console.log(prize.grandGiftId);
  600. this.initRewardList(prize.grandGiftId)
  601. } else if (this.form.prizeType === 4) {
  602. this.$set(this.form, 'freeCouponId', prize.freeCouponId)
  603. this.initVerifyCouponList(prize.freeCouponId)
  604. }
  605. }
  606. this.open = true;
  607. this.title = "修改打卡活动";
  608. // 等待对话框打开后再清除验证状态
  609. this.$nextTick(() => {
  610. if (this.$refs.form) {
  611. this.$refs.form.clearValidate();
  612. }
  613. });
  614. });
  615. },
  616. initRewardList(id) {
  617. if (!id) {
  618. return;
  619. }
  620. listByIds(id).then(response => {
  621. const {data} = response
  622. data.forEach(d => {
  623. if (!this.rewardList.some(item => item.id === d.id)) {
  624. this.rewardList.push({"id": d.id, "name": d.name})
  625. }
  626. })
  627. })
  628. },
  629. initCouponList(ids) {
  630. if (!ids) {
  631. return
  632. }
  633. getByIds({ids}).then(response => {
  634. const {data} = response
  635. data.forEach(d => {
  636. if (!this.couponList.some(item => item.id === d.couponId)) {
  637. this.couponList.push({"id": d.couponId, "name": d.title})
  638. }
  639. })
  640. })
  641. },
  642. handleDelete(row) {
  643. const activityIds = row.activityId;
  644. this.$confirm('是否确认删除该打卡活动?', "警告", {
  645. confirmButtonText: "确定",
  646. cancelButtonText: "取消",
  647. type: "warning"
  648. }).then(() => {
  649. return delCheckinActivity(activityIds);
  650. }).then(() => {
  651. this.getList();
  652. this.msgSuccess("删除成功");
  653. }).catch(() => {});
  654. },
  655. handleCopy(row) {
  656. this.copyForm.activityId = row.activityId;
  657. this.copyForm.timeRange = [];
  658. this.copyOpen = true;
  659. this.$nextTick(() => {
  660. if (this.$refs.copyForm) {
  661. this.$refs.copyForm.clearValidate();
  662. }
  663. });
  664. },
  665. submitCopy() {
  666. this.$refs.copyForm.validate(valid => {
  667. if (valid) {
  668. const params = {
  669. activityId: this.copyForm.activityId,
  670. startTime: this.copyForm.timeRange[0],
  671. endTime: this.copyForm.timeRange[1]
  672. };
  673. copyCheckinActivity(params).then(() => {
  674. this.msgSuccess("复制成功");
  675. this.copyOpen = false;
  676. this.getList();
  677. });
  678. }
  679. });
  680. },
  681. handlePrizeRecord(row) {
  682. this.prizeRecordTitle = row.activityName;
  683. this.prizeRecordQuery.activityId = row.activityId;
  684. this.prizeRecordQuery.pageNum = 1;
  685. this.prizeRecordQuery.prizeType = row.prizeType;
  686. this.prizeRecordType = row.prizeType.toString()
  687. this.prizeRecordOpen = true;
  688. this.getPrizeRecordList();
  689. },
  690. getPrizeRecordList() {
  691. this.prizeRecordLoading = true;
  692. getPrizeRecord(this.prizeRecordQuery).then(response => {
  693. this.prizeRecordList = response.rows || [];
  694. this.prizeRecordTotal = response.total || 0;
  695. this.prizeRecordLoading = false;
  696. }).catch(() => {
  697. this.prizeRecordLoading = false;
  698. });
  699. },
  700. cancel() {
  701. this.open = false;
  702. this.reset();
  703. },
  704. submitForm() {
  705. this.$refs["form"].validate(valid => {
  706. if (valid) {
  707. const prizeList = [];
  708. if (this.form.prizeType === 1) {
  709. prizeList.push({
  710. prizeType: 1,
  711. redpacketAmount: this.form.redpacketAmount
  712. });
  713. } else if (this.form.prizeType === 2) {
  714. prizeList.push({
  715. prizeType: 2,
  716. freeCouponId: this.form.freeCouponId
  717. })
  718. } else if (this.form.prizeType === 3) {
  719. prizeList.push({
  720. prizeType: 3,
  721. grandGiftId: this.form.grandGiftId
  722. })
  723. } else if (this.form.prizeType === 4) {
  724. prizeList.push({
  725. prizeType: 4,
  726. freeCouponId: this.form.freeCouponId
  727. })
  728. }
  729. const submitData = {
  730. activityId: this.form.activityId,
  731. activityName: this.form.activityName,
  732. startTime: this.form.timeRange[0],
  733. endTime: this.form.timeRange[1],
  734. checkinDays: this.form.checkinDays,
  735. companyIds: this.form.companyIds.join(','),
  736. projectIds: this.form.projectIds.join(','),
  737. notifyTemplate: this.form.notifyTemplate,
  738. status: this.form.status,
  739. prizeList: prizeList,
  740. remark: this.form.remark,
  741. prizeType: this.form.prizeType
  742. };
  743. if (this.form.activityId != null) {
  744. updateCheckinActivity(submitData).then(() => {
  745. this.msgSuccess("修改成功");
  746. this.open = false;
  747. this.getList();
  748. });
  749. } else {
  750. addCheckinActivity(submitData).then(() => {
  751. this.msgSuccess("新增成功");
  752. this.open = false;
  753. this.getList();
  754. });
  755. }
  756. }
  757. });
  758. },
  759. openCouponDrawer() {
  760. this.$nextTick(() => {
  761. this.$refs.customSelectCoupon?.blur?.()
  762. });
  763. this.couponDrawerOpen = true
  764. },
  765. selectCoupon(coupon) {
  766. this.form.freeCouponId = coupon.id
  767. if (!this.couponList.some(item => item.id === coupon.id)) {
  768. this.couponList.push(coupon)
  769. }
  770. this.couponDrawerOpen = false
  771. },
  772. openRewardDrawer() {
  773. this.$nextTick(() => {
  774. this.$refs.customSelectReward?.blur?.()
  775. });
  776. this.rewardDrawerOpen = true
  777. },
  778. selectReward(reward) {
  779. this.form.grandGiftId = reward.id
  780. if (!this.rewardList.some(item => item.id === reward.id)) {
  781. this.rewardList.push(reward)
  782. }
  783. this.rewardDrawerOpen = false
  784. },
  785. openVerifyCouponDrawer() {
  786. this.$nextTick(() => {
  787. this.$refs.customSelectVerifyCoupon?.blur?.()
  788. });
  789. this.verifyCouponDrawerOpen = true
  790. },
  791. selectVerifyCoupon(coupon) {
  792. this.form.freeCouponId = coupon.id
  793. if (!this.verifyCouponList.some(item => item.id === coupon.id)) {
  794. this.verifyCouponList.push(coupon)
  795. }
  796. this.verifyCouponDrawerOpen = false
  797. },
  798. initVerifyCouponList(ids) {
  799. if (!ids) return
  800. getByIds({ids}).then(response => {
  801. const {data} = response
  802. data.forEach(d => {
  803. if (!this.verifyCouponList.some(item => item.id === d.couponId)) {
  804. this.verifyCouponList.push({"id": d.couponId, "name": d.title})
  805. }
  806. })
  807. })
  808. },
  809. }
  810. };
  811. </script>
  812. <style scoped>
  813. .prize-item {
  814. margin-bottom: 10px;
  815. }
  816. .clearfix:before,
  817. .clearfix:after {
  818. display: table;
  819. content: "";
  820. }
  821. .clearfix:after {
  822. clear: both;
  823. }
  824. </style>