giftList.vue 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. <template>
  2. <div class="app-container calendar-list-container">
  3. <!-- 查询和其他操作 -->
  4. <div class="filter-container">
  5. <el-input clearable class="filter-item" style="width: 200px;" placeholder="礼品名称"
  6. v-model="listQuery.name"></el-input>
  7. <el-input clearable class="filter-item" style="width: 200px;" placeholder="礼品编号"
  8. v-model="listQuery.seq"></el-input>
  9. <!-- <el-date-picker class="filter-item" v-model="listQuery.shelfTime" type="datetime" placeholder="礼品上架时间">
  10. </el-date-picker> -->
  11. <el-select v-model="listQuery.status" clearable placeholder="状态" style="top: -4px;width: 200px;">
  12. <el-option :key="item.type" v-for="item in goodsStatusList" :label="item.name" :value="item.type">
  13. </el-option>
  14. </el-select>
  15. <el-button class="filter-item" type="primary" v-waves icon="el-icon-search" @click="handleFilter">查找</el-button>
  16. <el-button class="filter-item" type="primary" @click="handleCreate" icon="el-icon-edit">添加</el-button>
  17. </div>
  18. <!-- 查询结果 -->
  19. <el-table size="small" :data="list" v-loading="listLoading" element-loading-text="正在查询中。。。" border fit
  20. highlight-current-row>
  21. <el-table-column type="index" label="序号" header-align="center" align="center">
  22. </el-table-column>
  23. <el-table-column align="center" min-width="100px" label="礼品名称" prop="name">
  24. </el-table-column>
  25. <el-table-column align="center" min-width="120px" label="礼品编号" prop="seq">
  26. </el-table-column>
  27. <el-table-column align="center" min-width="80px" label="礼品属性">
  28. <template slot-scope="props">
  29. <span v-if="props.row.productAttribute == 1">实物</span>
  30. <span v-if="props.row.productAttribute == 0">虚拟</span>
  31. </template>
  32. </el-table-column>
  33. <!-- <el-table-column align="center" min-width="80px" label="积分" prop="integral">
  34. </el-table-column> -->
  35. <el-table-column align="center" min-width="100px" label="库存量" prop="actualStock">
  36. </el-table-column>
  37. <el-table-column align="center" min-width="100px" label="可兑换库存量" prop="stock">
  38. </el-table-column>
  39. <el-table-column align="center" min-width="80px" label="兑换方式">
  40. <template slot-scope="props">
  41. <span v-if="props.row.deliveryType == 1">快递</span>
  42. <span v-if="props.row.deliveryType == 0">无需快递</span>
  43. </template>
  44. </el-table-column>
  45. <el-table-column align="center" min-width="100px" label="礼品所在地" prop="location">
  46. </el-table-column>
  47. <!-- <el-table-column align="center" min-width="150px" label="上架时间" prop="shelfTime">
  48. </el-table-column> -->
  49. <el-table-column align="center" min-width="80px" label="礼品状态">
  50. <template slot-scope="props">
  51. <span v-if="props.row.status == 1">上架</span>
  52. <span v-if="props.row.status == 0">下架</span>
  53. </template>
  54. </el-table-column>
  55. <el-table-column align="center" min-width="80px" label="兑换记录">
  56. <template slot-scope="props">
  57. <span @click="handleView(props.row)" style="color:green;cursor: pointer;">查看</span>
  58. </template>
  59. </el-table-column>
  60. <el-table-column align="center" min-width="80px" label="福利名称" prop="title">
  61. </el-table-column>
  62. <el-table-column align="center" label="操作" width="350px" class-name="small-padding fixed-width">
  63. <template slot-scope="scope">
  64. <el-button type="primary" size="small" @click="handleUpdate(scope.row)">编辑</el-button>
  65. <el-button v-if="scope.row.status == 0" type="success" size="small"
  66. @click="changeGoodsState(scope.row.skuId, 1)">上架</el-button>
  67. <el-button v-if="scope.row.status == 1" type="warning" size="small"
  68. @click="changeGoodsState(scope.row.skuId, 0)">下架</el-button>
  69. <el-button type="primary" size="small" @click="handleRelated(scope.row)">关联福利</el-button>
  70. <el-button type="danger" size="mini" @click="handleDelete(scope.row.skuId, -1)">删除</el-button>
  71. </template>
  72. </el-table-column>
  73. </el-table>
  74. <!-- 分页 -->
  75. <div class="pagination-container">
  76. <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange"
  77. :current-page="listQuery.page" :page-sizes="[10, 20, 30, 50]" :page-size="listQuery.limit"
  78. layout="total, sizes, prev, pager, next, jumper" :total="total">
  79. </el-pagination>
  80. </div>
  81. <!-- 员工积分记录列表 -->
  82. <el-dialog title="兑换记录" :visible.sync="dialogListVisible" width="70%">
  83. <div class="filter-container">
  84. <el-select filterable v-model="itemListQuery.deptId" clearable placeholder="部门" style="top: -4px;width: 200px;">
  85. <el-option :key="item.deptId" v-for="item in depTypeList" :label="item.deptName" :value="item.deptId">
  86. </el-option>
  87. </el-select>
  88. <el-input clearable class="filter-item" style="width: 200px;" placeholder="员工名称"
  89. v-model="itemListQuery.purchaserName"></el-input>
  90. <el-button class="filter-item" type="primary" v-waves icon="el-icon-search"
  91. @click="itemHandleFilter">查找</el-button>
  92. <el-button class="filter-item" type="primary" v-waves icon="el-icon-download">导出</el-button>
  93. </div>
  94. <!-- 查询结果 -->
  95. <el-table size="small" :data="itemList" v-loading="listLoading" element-loading-text="正在查询中。。。" border fit
  96. highlight-current-row>
  97. <el-table-column type="index" label="序号" header-align="center" align="center">
  98. </el-table-column>
  99. <el-table-column align="center" width="200px" label="部门" prop="deptName">
  100. </el-table-column>
  101. <el-table-column align="center" label="员工姓名" prop="purchaser">
  102. </el-table-column>
  103. <el-table-column align="center" label="兑换方式" prop="deliveryTypeName">
  104. </el-table-column>
  105. <el-table-column align="center" label="联系人" prop="contact">
  106. </el-table-column>
  107. <el-table-column align="center" width="120px" label="联系方式" prop="contactPhone">
  108. </el-table-column>
  109. <el-table-column align="center" width="200px" label="地址" prop="contactAddr">
  110. </el-table-column>
  111. <el-table-column align="center" width="200px" label="邮箱" prop="contactEmail">
  112. </el-table-column>
  113. <el-table-column align="center" width="150px" label="兑换时间" prop="createTime">
  114. </el-table-column>
  115. </el-table>
  116. <!-- 分页 -->
  117. <div class="pagination-container">
  118. <el-pagination background @size-change="itemHandleSizeChange" @current-change="itemHandleCurrentChange"
  119. :current-page="itemListQuery.page" :page-sizes="[10, 20, 30, 50]" :page-size="itemListQuery.limit"
  120. layout="total, sizes, prev, pager, next, jumper" :total="itemTotal">
  121. </el-pagination>
  122. </div>
  123. </el-dialog>
  124. <!-- 添加或修改对话框 -->
  125. <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible" width="70%">
  126. <el-form :rules="rules" ref="dataForm" :model="dataForm" status-icon label-position="left" label-width="100px" style='width:700px;margin-left:50px;'>
  127. <el-form-item label="礼品编号" prop="seq">
  128. <el-input disabled placeholder="添加成功后自动生成" readonly v-model="dataForm.seq"></el-input>
  129. </el-form-item>
  130. <el-form-item label="礼品名称" prop="name">
  131. <el-input v-model="dataForm.name"></el-input>
  132. </el-form-item>
  133. <el-form-item label="礼品属性" prop="productAttribute">
  134. <el-select v-model="dataForm.productAttribute" filterable placeholder="请选择" style="width: 350px"
  135. value-key="value" @change="changeProductAttribute">
  136. <el-option :key="item.dictValue" v-for="item in productAttributeList" :label="item.dictLabel"
  137. :value="item.dictValue">
  138. </el-option>
  139. </el-select>
  140. </el-form-item>
  141. <el-form-item label="兑换方式" prop="deliveryType">
  142. <el-select v-model="dataForm.deliveryType" filterable placeholder="请选择" style="width: 350px">
  143. <el-option :key="item.type" v-for="item in deliveryTypeList" :label="item.name" :value="item.type">
  144. </el-option>
  145. </el-select>
  146. </el-form-item>
  147. <el-form-item v-if="dataForm.productAttribute==1" label="礼品所在地" prop="location">
  148. <el-select v-model="dataForm.location" filterable placeholder="请选择" style="width: 350px">
  149. <el-option :key="item.dictLabel" v-for="item in locationList" :label="item.dictLabel" :value="item.dictLabel">
  150. </el-option>
  151. </el-select>
  152. </el-form-item>
  153. <el-form-item style="width: 800px" label="礼品图片" prop="imgUrl">
  154. <el-upload :action="fileImgUrl" list-type="picture-card" :file-list="dataForm.images"
  155. :on-success="handleGallerySucess" :on-exceed="handleExceed" :before-upload="uploadBannerImg"
  156. :on-remove="handleRemove">
  157. <i class="el-icon-plus"></i>
  158. </el-upload>
  159. </el-form-item>
  160. <el-form-item label="库存量" prop="actualStock">
  161. <el-input-number :precision="0" :step="1" v-model="dataForm.actualStock"></el-input-number>
  162. </el-form-item>
  163. <el-form-item
  164. style="width: 800px"
  165. label="礼品说明"
  166. prop="comment"
  167. >
  168. <tinymce v-model="dataForm.comment" ref="tinymce"></tinymce>
  169. </el-form-item>
  170. </el-form>
  171. <div slot="footer" class="dialog-footer">
  172. <el-button @click="dialogFormVisible = false">取消</el-button>
  173. <el-button v-if="dialogStatus == 'create'" type="primary" @click="createData">确定</el-button>
  174. <el-button v-else type="primary" @click="updateData">确定</el-button>
  175. </div>
  176. </el-dialog>
  177. <!-- 关联福利操作 -->
  178. <el-dialog title="关联福利" :visible.sync="dialogRelatedVisible" width="40%">
  179. <div class="filter-container">
  180. <el-select clearable v-model="welfareId" style="width: 100%;" placeholder="请选择">
  181. <el-option v-for="item in options" :key="item.id" :label="item.title" :value="item.id">
  182. </el-option>
  183. </el-select>
  184. </div>
  185. <div slot="footer" class="dialog-footer">
  186. <el-button @click="dialogRelatedVisible = false">取消</el-button>
  187. <el-button type="primary" @click="handleRelatedWelfare">确定</el-button>
  188. </div>
  189. </el-dialog>
  190. </div>
  191. </template>
  192. <style>
  193. .demo-table-expand {
  194. font-size: 0;
  195. }
  196. .demo-table-expand label {
  197. width: 200px;
  198. color: #99a9bf;
  199. }
  200. .demo-table-expand .el-form-item {
  201. margin-right: 0;
  202. margin-bottom: 0;
  203. }
  204. </style>
  205. <script>
  206. import { createItem, updateItem, giftList, giftState, exchangeHistory, relatedWelfare, welfareList } from "@/api/giftManage";
  207. import { depTypeList,dataTypeList } from "@/api/public";
  208. import waves from "@/directive/waves"; // 水波纹指令
  209. import Tinymce from '@/components/Tinymce'
  210. export default {
  211. name: 'giftList',
  212. components: { Tinymce },
  213. directives: { waves },
  214. data() {
  215. return {
  216. welfareId:'',
  217. skuId:'',
  218. options: [],
  219. locationList:[],
  220. productAttributeList: [
  221. {
  222. type: 1,
  223. name: '实物'
  224. },
  225. {
  226. type: 0,
  227. name: '虚拟'
  228. },
  229. ],
  230. deliveryTypeList: [
  231. {
  232. type: 1,
  233. name: '快递'
  234. },
  235. {
  236. type: 0,
  237. name: '无需快递'
  238. },
  239. ],
  240. goodsStatusList: [
  241. {
  242. type: 1,
  243. name: '上架'
  244. },
  245. {
  246. type: 0,
  247. name: '下架'
  248. },
  249. ],
  250. depTypeList: [
  251. ],
  252. list: [
  253. ],
  254. itemList: [
  255. ],
  256. total: 0,
  257. itemTotal: 0,
  258. listLoading: false,
  259. downloadLoading: false,
  260. listQuery: {
  261. page: 1,
  262. limit: 10,
  263. name: '',
  264. seq: '',
  265. shelfTime: '',
  266. status: '',
  267. },
  268. itemListQuery: {
  269. page: 1,
  270. limit: 10,
  271. deptId: '',
  272. purchaserName: '',
  273. },
  274. dataForm: {
  275. comment: undefined,
  276. name: undefined,
  277. seq: undefined,
  278. productAttribute: undefined,
  279. imgUrl: undefined,
  280. integral: undefined,
  281. actualStock: undefined,
  282. deliveryType: undefined,
  283. location: undefined,
  284. images: [],
  285. },
  286. dialogFormVisible: false,
  287. dialogStatus: '',
  288. textMap: {
  289. update: "编辑",
  290. create: "创建",
  291. },
  292. rules: {
  293. name: [{ required: true, message: "请填写礼品名称", trigger: "blur" }],
  294. imgUrl: [{ required: true, message: "请上传礼品图片", trigger: "blur" }],
  295. productAttribute: [{ required: true, message: "请选择礼品属性", trigger: "blur" }],
  296. integral: [{ required: true, message: "请填写礼品积分", trigger: "blur" }],
  297. actualStock: [{ required: true, message: "请设置库存量", trigger: "blur" }],
  298. deliveryType: [{ required: true, message: "请选择兑换方式", trigger: "blur" }],
  299. location: [{ required: true, message: "请选择礼品所在地", trigger: "blur" }],
  300. comment: [{ required: true, message: "说明不能为空", trigger: "blur" }],
  301. },
  302. dialogListVisible: false,
  303. dialogRelatedVisible:false,
  304. fileImgUrl: this.upLoadUrl,
  305. }
  306. },
  307. created() {
  308. // this.getCompanyTypeList();
  309. this.getProductAttributeList();
  310. this.getDataTypeList();
  311. this.getDepTypeList();
  312. this.getList();
  313. },
  314. methods: {
  315. getDataTypeList() {
  316. dataTypeList({dictType:'mall_sku_location'}).then(response => {
  317. this.locationList = response.data.data;
  318. }).catch(() => {});
  319. },
  320. getProductAttributeList(){
  321. dataTypeList({dictType:'mall_sku_attribute'}).then(response => {
  322. this.productAttributeList = response.data.data;
  323. }).catch(() => {});
  324. },
  325. getWelfareList(){
  326. welfareList({status:1}).then(response => {
  327. this.options = response.data.data;
  328. }).catch(() => {});
  329. },
  330. changeProductAttribute(val) {
  331. this.dataForm.deliveryType = '';
  332. this.dataForm.location = '';
  333. if (val == 1) {
  334. this.deliveryTypeList = [
  335. {
  336. type: 1,
  337. name: '快递'
  338. },
  339. {
  340. type: 0,
  341. name: '无需快递'
  342. },
  343. ]
  344. } else {
  345. this.deliveryTypeList = [
  346. {
  347. type: 0,
  348. name: '无需快递'
  349. },
  350. ]
  351. }
  352. },
  353. handleRemove(file, fileList) {
  354. console.log(file, fileList);
  355. let images = [];
  356. for (let i in fileList) {
  357. let response = fileList[i].response;
  358. let url = response.data.url;
  359. images.push(url);
  360. this.dataForm.imgUrl = images.join(",");
  361. }
  362. },
  363. uploadBannerImg(file) {
  364. const isJPGs = file.type === "image/jpeg";
  365. console.log(isJPGs);
  366. },
  367. handleExceed(files, fileList) {
  368. this.$message.warning(
  369. `当前限制选择 5 个文件,本次选择了 ${files.length} 个文件!,共选择了 ${files.length + fileList.length
  370. } 个文件`
  371. );
  372. },
  373. handleGallerySucess(res, file, fileList) {
  374. this.dataForm.imgUrl = ""; // 清空画廊图片数组
  375. let images = [];
  376. for (let i in fileList) {
  377. let response = fileList[i].response;
  378. if (response.errno && response.errno != "0") {
  379. this.$message.error("该图片上传失败,已被移除,请重新上传!");
  380. // 上传失败移除该 file 对象
  381. fileList.splice(i, 1);
  382. } else {
  383. let url = response.data.url;
  384. images.push(url);
  385. }
  386. }
  387. this.dataForm.imgUrl = images.join(",");
  388. },
  389. resetForm() {
  390. this.dataForm = {
  391. comment: undefined,
  392. name: undefined,
  393. seq: undefined,
  394. productAttribute: undefined,
  395. imgUrl: undefined,
  396. integral: undefined,
  397. actualStock: undefined,
  398. deliveryType: undefined,
  399. location: undefined,
  400. images: [],
  401. };
  402. },
  403. handleCreate() {
  404. this.resetForm();
  405. this.dialogFormVisible = true;
  406. this.dialogStatus = "create";
  407. this.$nextTick(() => {
  408. this.$refs.tinymce.setContent("");
  409. this.$refs["dataForm"].clearValidate();
  410. });
  411. },
  412. createData() {
  413. this.$refs["dataForm"].validate((valid) => {
  414. if (valid) {
  415. createItem(this.dataForm)
  416. .then((response) => {
  417. this.getList();
  418. this.dialogFormVisible = false;
  419. this.$notify({
  420. title: "成功",
  421. message: "创建成功",
  422. type: "success",
  423. duration: 2000,
  424. });
  425. this.reload();
  426. })
  427. .catch(() => { });
  428. }
  429. });
  430. },
  431. handleUpdate(row) {
  432. this.dataForm = Object.assign({}, row);
  433. this.dataForm.productAttribute = row.productAttribute.toString();
  434. let comment = this.dataForm.comment;
  435. if (row.productAttribute == 1) {
  436. this.deliveryTypeList = [
  437. {
  438. type: 1,
  439. name: '快递'
  440. },
  441. {
  442. type: 0,
  443. name: '无需快递'
  444. },
  445. ]
  446. } else {
  447. this.deliveryTypeList = [
  448. {
  449. type: 0,
  450. name: '无需快递'
  451. },
  452. ]
  453. }
  454. if (this.dataForm.imgUrl) {
  455. let images = this.dataForm.imgUrl.split(",");
  456. this.dataForm.images = [];
  457. for (let i in images) {
  458. let url = images[i];
  459. let name = "image_" + i;
  460. this.dataForm.images.push({
  461. name: name,
  462. url: url,
  463. response: { error: "0", data: { url: url } },
  464. });
  465. }
  466. }
  467. this.dialogStatus = 'update'
  468. this.dialogFormVisible = true
  469. this.$nextTick(() => {
  470. this.$refs.tinymce.setContent(comment);
  471. this.$refs['dataForm'].clearValidate()
  472. })
  473. },
  474. updateData() {
  475. this.$refs['dataForm'].validate((valid) => {
  476. if (valid) {
  477. updateItem(this.dataForm).then(() => {
  478. this.dialogFormVisible = false
  479. this.$notify({
  480. title: '成功',
  481. message: '更新成功',
  482. type: 'success',
  483. duration: 2000
  484. })
  485. this.getList()
  486. })
  487. }
  488. })
  489. },
  490. handleRelated(row) {
  491. this.welfareId = row.welfareId;
  492. this.skuId = row.skuId;
  493. this.getWelfareList();
  494. this.dialogRelatedVisible = true
  495. },
  496. handleRelatedWelfare(){
  497. relatedWelfare({ skuId: this.skuId, welfareId: this.welfareId }).then(response => {
  498. this.dialogRelatedVisible = false;
  499. this.$notify({
  500. title: '成功',
  501. message: '福利关联成功',
  502. type: 'success',
  503. duration: 2000
  504. })
  505. this.getList()
  506. })
  507. },
  508. changeGoodsState(id, index) {
  509. giftState({ skuId: id, status: index }).then(response => {
  510. this.$notify({
  511. title: '成功',
  512. message: '礼品状态修改成功',
  513. type: 'success',
  514. duration: 2000
  515. })
  516. this.getList()
  517. })
  518. },
  519. handleDelete(id, index) {
  520. this.$confirm('确认删除吗?', '提示', {
  521. confirmButtonText: '确定',
  522. cancelButtonText: '取消',
  523. type: 'warning'
  524. }).then(() => {
  525. giftState({ skuId: id, status: index }).then(response => {
  526. this.$notify({
  527. title: '成功',
  528. message: '删除成功',
  529. type: 'success',
  530. duration: 2000
  531. })
  532. this.getList();
  533. })
  534. }).catch(() => {})
  535. },
  536. getDepTypeList() {
  537. depTypeList().then(response => {
  538. this.depTypeList = response.data.data;
  539. }).catch(() => {});
  540. },
  541. getList() {
  542. this.listLoading = true
  543. giftList(this.listQuery).then(response => {
  544. this.list = response.data.data.items
  545. this.total = response.data.data.total
  546. this.listLoading = false
  547. }).catch(() => {})
  548. },
  549. getItemList() {
  550. this.listLoading = true
  551. exchangeHistory(this.itemListQuery).then(response => {
  552. this.itemList = response.data.data.items
  553. this.itemLotal = response.data.data.total
  554. this.listLoading = false
  555. }).catch(() => {})
  556. },
  557. handleFilter() {
  558. this.listQuery.page = 1
  559. this.getList()
  560. },
  561. handleSizeChange(val) {
  562. this.listQuery.limit = val
  563. this.getList()
  564. },
  565. handleCurrentChange(val) {
  566. this.listQuery.page = val
  567. this.getList()
  568. },
  569. itemHandleFilter() {
  570. this.itemListQuery.page = 1
  571. this.getItemList()
  572. },
  573. itemHandleSizeChange(val) {
  574. this.itemListQuery.limit = val
  575. this.getItemList()
  576. },
  577. itemHandleCurrentChange(val) {
  578. this.itemListQuery.page = val
  579. this.getItemList()
  580. },
  581. handleView(row) {
  582. this.itemListQuery.id = row.id;
  583. this.getItemList()
  584. this.dialogListVisible = true
  585. },
  586. }
  587. }
  588. </script>
  589. <style>
  590. .ad-avatar-uploader .el-upload {
  591. border: 1px dashed #d9d9d9;
  592. border-radius: 6px;
  593. cursor: pointer;
  594. position: relative;
  595. overflow: hidden;
  596. }
  597. .ad-avatar-uploader .el-upload:hover {
  598. border-color: #409EFF;
  599. }
  600. .ad-avatar-uploader-icon {
  601. font-size: 28px;
  602. color: #8c939d;
  603. width: 178px;
  604. height: 178px;
  605. line-height: 178px;
  606. text-align: center;
  607. }
  608. .ad-avatar {
  609. display: block;
  610. }
  611. </style>