From bd57e65508781d967dedff5bb535dfefdb56e9e2 Mon Sep 17 00:00:00 2001 From: zxl <763096477@qq.com> Date: 星期四, 21 八月 2025 14:39:30 +0800 Subject: [PATCH] 抽奖活动,奖品 --- manager/src/views/activity-prize/prize.vue | 923 ++++++++++++++++++++++++++++++++ manager/src/api/prize.js | 42 + manager/src/api/activity-prize.js | 19 manager/src/views/activity-prize/index.vue | 661 ++++++++++++++++++++--- 4 files changed, 1,552 insertions(+), 93 deletions(-) diff --git a/manager/src/api/activity-prize.js b/manager/src/api/activity-prize.js index e0bfcab..f33bfa4 100644 --- a/manager/src/api/activity-prize.js +++ b/manager/src/api/activity-prize.js @@ -33,3 +33,22 @@ method: "DELETE", }) } +export const addActivityRefPrizeList = (id,params) =>{ + return service({ + url:"/lmk/activity-prize/addActivityRefPrizeList/" +id, + method: "POST", + data:params + }) +} +export const getActivityRefPrizeByActivityId = (params) =>{ + return service({ + url:"/lmk/activity-prize/getActivityRefPrizeByActivityId/"+params, + method: "GET", + }) +} +export const publishPrizeActivity =(params)=> { + return service({ + url:"/lmk/activity-prize/publishPrizeActivity/" +params, + method:"PUT" + }) +} diff --git a/manager/src/api/prize.js b/manager/src/api/prize.js new file mode 100644 index 0000000..d011201 --- /dev/null +++ b/manager/src/api/prize.js @@ -0,0 +1,42 @@ +import service from "../libs/axios"; + +export const getPage = (params) =>{ + return service({ + url: "/lmk/prizeDraw", + method: "GET", + params: params + }) +} +export const detail = (params) =>{ + return service({ + url: "/lmk/prizeDraw/" +params, + method: "GET", + }) +} +export const edit = (params) =>{ + return service({ + url: "/lmk/prizeDraw", + method: "PUT", + data: params + }) +} +export const add = (params) =>{ + return service({ + url: "/lmk/prizeDraw", + method: "POST", + data: params + }) +} +export const del = (params) =>{ + return service({ + url: "/lmk/prizeDraw/" +params, + method: "DELETE", + }) +} + +export const canUpDatePrizeDraw = (params) =>{ + return service({ + url: "/lmk/prizeDraw/canUpDatePrizeDraw/" +params, + method: "GET", + }) +} diff --git a/manager/src/views/activity-prize/index.vue b/manager/src/views/activity-prize/index.vue index d29b7aa..dc68f1e 100644 --- a/manager/src/views/activity-prize/index.vue +++ b/manager/src/views/activity-prize/index.vue @@ -75,7 +75,7 @@ <Button type="primary" size="small" - @click="changeStatus(row, row.enableStatus === 'on' ? '鍏抽棴' : '寮�鍚�')" + @click="publishPrizeActivity(row)" :loading="row.statusLoading" > {{row.enableStatus === 'on' ? '鍏抽棴' : '寮�鍚�'}} @@ -188,6 +188,7 @@ <Col span="24"> <FormItem label="娲诲姩鍥剧墖锛�" prop="activityImg"> <Upload + v-if="!imgTempUrl" :before-upload="(file) => handleBeforeUpload(file, 'content')" :format="['jpg','jpeg','png','gif']" :max-size="20480" @@ -195,11 +196,9 @@ accept="image/*" > <Button icon="ios-cloud-upload-outline">涓婁紶灏侀潰鍥剧墖</Button> - <div class="upload-tip">鏀寔鍥剧墖锛屾渶澶�20MB</div> </Upload> - <div v-if="activityImg" class="upload-file-info"> - <p>宸查�夋枃浠�: {{ activityImg.name }}</p> - <img :src="activityImg.activityImgUrl" alt="娲诲姩鍥剧墖" style="max-width: 100%; max-height: 200px;"> + <div v-else class="upload-file-info"> + <img :src="imgTempUrl" alt="娲诲姩鍥剧墖" class="preview-image-limit"> <Button type="text" @click="handleRemove('content')">鍒犻櫎</Button> </div> @@ -209,6 +208,7 @@ <Col span="24"> <FormItem label="娲诲姩灏侀潰锛�" prop="activityCover"> <Upload + v-if="!coverTempUrl" :before-upload="(file) => handleBeforeUpload(file, 'cover')" :format="['jpg','jpeg','png','gif']" :max-size="20480" @@ -216,11 +216,9 @@ accept="image/*" > <Button icon="ios-cloud-upload-outline">涓婁紶灏侀潰鍥剧墖</Button> - <div class="upload-tip">鏀寔鍥剧墖锛屾渶澶�20MB</div> </Upload> - <div v-if="activityCover" class="upload-file-info"> - <p>宸查�夋枃浠�: {{ activityCover.name }}</p> - <img :src="activityCover.activityCoverUrl" alt="娲诲姩鍥剧墖" style="max-width: 100%; max-height: 200px;"> + <div v-else class="upload-file-info"> + <img :src="coverTempUrl" alt="娲诲姩鍥剧墖" class="preview-image-limit"> <Button type="text" @click="handleRemove('cover')">鍒犻櫎</Button> </div> @@ -292,8 +290,8 @@ <Col span="24"> <div class="detail-item"> <label>娲诲姩鍥剧墖锛�</label> - <div v-if="detailData.activityImg" class="detail-image"> - <img :src="detailData.activityImg" alt="娲诲姩鍥剧墖" style="max-width: 100%; max-height: 200px;"> + <div v-if="detailData.activityImgUrl" class="detail-image"> + <img :src="detailData.activityImgUrl" alt="娲诲姩鍥剧墖" class="preview-image-limit"> </div> <span v-else>-</span> </div> @@ -301,10 +299,10 @@ <Col span="24"> <div class="detail-item"> <label>娲诲姩灏侀潰锛�</label> - <div v-if="detailData.activityCover" class="detail-image"> + <div v-if="detailData.activityCoverUrl" class="detail-image"> <img - :src="detailData.activityCover" alt="娲诲姩灏侀潰" - style="max-width: 100%; max-height: 200px;" + :src="detailData.activityCoverUrl" alt="娲诲姩灏侀潰" + class="preview-image-limit" > </div> <span v-else>-</span> @@ -313,23 +311,185 @@ <Col span="24"> <div class="detail-item"> <label>濂栧搧锛�</label> + <div style="width: 100%; overflow-y: auto; padding-bottom: 8px; box-sizing: border-box;height: 150px"> + <div v-if="detailData.prizes && detailData.prizes.length > 0" class="prize-list"> + <div v-for="(prize, index) in detailData.prizes" :key="index" class="prize-item"> + <div class="prize-header"> + <span class="prize-name">{{ prize.prizeName }}</span> + <Tag v-if="prize.prizeType"> + {{ replaceText(prize.prizeType) }} + </Tag> + </div> + <div class="prize-content"> + <p v-if="prize.prizeContent">{{ prize.prizeContent }}</p> + <Row :gutter="16" class="prize-info"> + <Col span="12"> + <span>鎬绘暟: {{ prize.prizeNum}}</span> + </Col> + <Col span="12"> + <span>鍓╀綑: + <span> + {{ prize.remainNum }} + </span> + </span> + </Col> + <Col span="12"> + <span>姒傜巼: {{ prize.probability}}%</span> + </Col> + </Row> + </div> + </div> + </div> + <div v-else class="no-prize"> + <span>鏆傛棤濂栧搧淇℃伅</span> + </div> + </div> + + </div> </Col> </Row> </div> </Modal> + + <Modal + v-model="prizeSettingShow" + title="濂栧搧璁剧疆" + @on-cancel="prizeSettingModelClose" + width="1200" + :mask-closable="false"> + <!-- 濂栧搧閮ㄥ垎 --> + + + <Form ref="activityPrizeForm" :label-width="100" > + <Col span="24"> + <FormItem label="濂栧搧鍒楄〃:"> + <Table + :loading="prizeLoading" + border + :columns="prizeColumns" + :data="prizeList" + ref="table" + class="prize-table" + > + <template slot-scope="{ row }" slot="prizeCoverUrl"> + <img + :src="row.prizeCoverUrl" + alt="濂栧搧灏侀潰" + class="thumbnail" + > + </template> + <template slot-scope="{ row }" slot="action"> + <Button + @click="choicePrize(row)" + :disabled="isPrizeChosen(row.id)" + type="primary" + icon="md-add" + > + {{ isPrizeChosen(row.id) ? '宸叉坊鍔�' : '娣诲姞' }} + </Button> + </template> + </Table> + <Row type="flex" justify="end" class="page-footer"> + <Page + :current="prizeSearchForm.pageNumber" + :total="prizeTotal" + :page-size="prizeSearchForm.pageSize" + @on-change="prizeChangePage" + @on-page-size-change="prizeChangePageSize" + :page-size-opts="[10, 20, 50]" + size="small" + show-total + show-elevator + show-sizer + ></Page> + </Row> + </FormItem> + </Col> + <Col span="24"> + <FormItem label="宸查�夊鍝�:"> + <!-- 閬嶅巻宸查�夊鍝侊紝骞跺彲浠ヨ缃暟閲忕瓑灞炴�� --> + <Table + :data="choiceData" + :columns="choiceColumns" + border + style="margin-top: 10px;" + :loading="choiceLoading" + > + <!-- 濂栧搧鍥剧墖 slot --> + <template slot-scope="{ row }" slot="prizeCoverUrl"> + <img :src="row.prizeCoverUrl" alt="濂栧搧灏侀潰" style="width: 50px; height: 50px; object-fit: cover;"> + </template> + <!-- 鏁伴噺 slot --> + <template slot-scope="{ row, index }" slot="maxPreDay"> + <InputNumber + v-model="row.maxPreDay" + :min="1" + :max="999999" + placeholder="璇疯緭鍏ユ瘡鏃ユ渶澶т腑濂栨暟" + style="width: 100%" + @on-change="(val) => handleMaxPreDayChange(val, index)" + ></InputNumber> + </template> + <template slot-scope="{ row, index }" slot="prizeNum"> + <InputNumber + v-model="row.prizeNum" + :min="1" + :max="999999" + placeholder="璇疯緭鍏ユ瘡鏃ユ渶澶т腑濂栨暟" + style="width: 100%" + @on-change="(val) => handlePrizeNumChange(val, index)" + ></InputNumber> + </template> + + <!-- 姒傜巼 slot --> + <template slot-scope="{ row, index }" slot="prizeProbability"> + <Input + v-model="row.prizeProbability" + placeholder="0.01" + style="width: 100%" + @on-blur="(e) => handleProbabilityInput(e, index)" + @on-enter="(e) => handleProbabilityInput(e, index)" + ></Input> + </template> + + <!-- 鎿嶄綔 slot --> + <template slot-scope="{ row, index }" slot="action"> + <Button type="error" size="small" icon="md-close" @click="removePrize(index)">绉婚櫎</Button> + </template> + </Table> + <!-- 濡傛灉娌℃湁閫夋嫨浠讳綍濂栧搧鏃剁殑鎻愮ず --> + <div v-if="choiceData.length === 0" style="text-align: center; color: #999; padding: 20px;"> + 灏氭湭閫夋嫨浠讳綍濂栧搧 + </div> + + </FormItem> + </Col> + </Form> + <div slot="footer"> + <Button @click="prizeSettingModelClose">鍙栨秷</Button> + <Button type="primary" :loading="choiceSubmitLoading" @click="choiceSubmit">鎻愪氦</Button> + </div> + </Modal> + </Card> </div> </template> <script> import { + getPage as getPrizePage +} from '@/api/prize.js' +import { getPage, detail, edit, add, - del + del, + addActivityRefPrizeList, + getActivityRefPrizeByActivityId, + publishPrizeActivity } from '@/api/activity-prize.js' import {delByKey, uploadFileByLmk} from "../../api/common"; @@ -338,6 +498,112 @@ data() { return { + //濂栧搧璁剧疆寮圭獥 + choiceLoading:false, + choiceSubmitLoading:false, + prizeTotal:0, + choiceData:[], + choiceColumns:[ + { + title: '濂栧搧鍥剧墖', + slot: 'prizeCoverUrl', + width: 80, + align: 'center' + }, + { + title: '濂栧搧鍚嶇О', + key: 'prizeName', + minWidth: 120 + }, + { + title: '濂栧搧绫诲瀷', + slot: 'prizeType', + width: 100, + render: (h, params) => { + if (params.row.prizeType === "coupon") { + return h("Tag", {props: {color: "red"}}, "浼樻儬鍒�"); + } else { + return h("Tag", {props: {color: "purple"}}, "鏈煡"); + } + } + }, + { + title: '姣忔棩鏈�澶т腑濂栨暟', + slot: 'maxPreDay', + width: 120 + }, + { + title: '鏁伴噺', + slot: 'prizeNum', + width: 120 + }, + { + title: '涓皢姒傜巼涓嶈兘涓虹┖', + slot: 'prizeProbability', + width: 120 + }, + { + title: '鎿嶄綔', + slot: 'action', + width: 80, + align: 'center' + } + ], + + prizeLoading:false, + prizeList:[], + prizeSettingShow:false, + prizeColumns:[ + { + title: '濂栧搧灏侀潰', + key: 'prizeCoverUrl', + slot:'prizeCoverUrl', + align: 'center', + minWidth: 100, + }, + { + title: '濂栧搧鍚嶇О', + key: 'prizeName', + minWidth: 100, + }, + { + title: '濂栧搧绫诲瀷', + key: 'prizeType', + minWidth: 100, + render: (h, params) => { + if (params.row.prizeType === "coupon") { + return h("Tag", {props: {color: "red"}}, "浼樻儬鍒�"); + } else { + return h("Tag", {props: {color: "purple"}}, "鏈煡"); + } + } + }, + { + title: '濂栧搧鍐呭', + key: 'prizeContent', + minWidth: 100, + }, + { + title: '濂栧搧鎻忚堪', + key: 'prizeDes', + minWidth: 100, + }, + { + title:'鎿嶄綔', + slot: 'action', + width: 200, + align:'center', + fixed:'right' + } + ], + activityPrizeId:null, + prizeSearchForm:{ + prizeName:'', + prizeType:'', + pageSize:10, + pageNumber:1, + }, + infoModalShow:false, detailData: {}, modelShow:false, @@ -462,11 +728,14 @@ activityName:'', endTime:'', beginTime:'', - }, submitLoading:false, activityCover:null, activityImg:null, + + coverTempUrl:null, + imgTempUrl:null, + } }, // 鍦ㄧ粍浠跺垱寤哄墠娉ㄥ唽 @@ -477,6 +746,125 @@ this.init(); }, methods: { + handleProbabilityInput(event, index) { + const inputValue = event.target.value; + let numericValue = parseFloat(inputValue); + + if (isNaN(numericValue)) { + this.choiceData[index].prizeProbabilityDisplay = '0.01'; + this.choiceData[index].prizeProbability = 0.01; + this.$Message.warning('璇疯緭鍏ユ湁鏁堢殑鏁板瓧'); + return; + } + + // 闄愬埗鑼冨洿 + if (numericValue < 0.01) { + numericValue = 0.01; + this.$Message.warning('涓姒傜巼涓嶈兘灏忎簬0.01'); + } else if (numericValue > 100) { + numericValue = 100; + this.$Message.warning('涓姒傜巼涓嶈兘澶т簬100'); + } + + // 淇濇寔2浣嶅皬鏁� + const fixedValue = parseFloat(numericValue.toFixed(2)); + this.choiceData[index].prizeProbabilityDisplay = fixedValue.toString(); + this.choiceData[index].prizeProbability = fixedValue; + + // 鏇存柊鍚庣瀛楁 + this.choiceData[index].probability = (fixedValue / 100).toFixed(4); + }, + choiceSubmit(){ + addActivityRefPrizeList(this.activityPrizeId,this.choiceData).then(res =>{ + if (res.code === 200){ + this.$Message.success(res.msg) + this.prizeSettingModelClose() + }else{ + this.$Message.error(res.msg) + } + }) + }, + + // 鏍煎紡鍖栧鍝佺被鍨� + replaceText(type) { + console.log(type) + if (type === "coupon") { + return "浼樻儬鍒�"; + } + return type; // 濡傛灉涓嶆槸鐩爣璇嶏紝杩斿洖鍘熸枃鏈� + }, + + // 鏁伴噺鍙樺寲澶勭悊 + handlePrizeNumChange(value, index) { + if (value === null || value < 1) { + this.choiceData[index].prizeNum = 1; + this.$Message.warning('鏁伴噺涓嶈兘灏忎簬1'); + } else { + this.choiceData[index].prizeNum = value; + } + }, + // 鏁伴噺鍙樺寲澶勭悊 + handleMaxPreDayChange(value, index) { + if (value === null || value < 1) { + this.choiceData[index].maxPreDay = 1; + this.$Message.warning('鏁伴噺涓嶈兘灏忎簬1'); + } else { + this.choiceData[index].maxPreDay = value; + } + }, + + // 绉婚櫎宸查�夊鍝� + removePrize(index) { + this.choiceData.splice(index, 1); + this.$Message.info('宸茬Щ闄ゅ鍝�'); + }, + // 妫�鏌ュ鍝佹槸鍚﹀凡琚�夋嫨 + isPrizeChosen(prizeId) { + return this.choiceData.some(item => item.id === prizeId); + }, + choicePrize(row){ + //鍒ゆ柇鏁扮粍闀垮害 + if(this.choiceData.length >= 5){ + this.$Message.warning("鏈�澶氭坊鍔�5涓鍝�") + return; + } + if (this.isPrizeChosen(row.id)){ + this.$Message.warning("宸叉坊鍔�") + return; + } + this.choiceLoading = true; + + const prizeToAdd = { + prizeCoverUrl:row.prizeCoverUrl, + prizeType: row.prizeType, + prizeName: row.prizeName, + prizeNum: 1, // 榛樿鏁伴噺涓�1 + maxPreDay:1, + prizeProbability:0.01, + prizeId:row.id, + prizeContent:row.prizeContent + // 鍙互娣诲姞鍏朵粬鎵╁睍灞炴�э紝濡傦細 + // sort: this.choiceData.length + 1 // 鎺掑簭 + }; + this.choiceData.push(prizeToAdd); + this.choiceLoading = false; + this.$Message.success('娣诲姞鎴愬姛锛�'); + + }, + getPrizeList(){ + this.prizeLoading = true; + getPrizePage(this.prizeSearchForm).then(res =>{ + this.prizeLoading = false; + if (res.code === 200){ + this.prizeList = res.data; + this.prizeTotal = res.total + }else { + this.$Message.error(res.msg) + } + }) + }, + + //瑙勫垯 validateBeginTime(rule, value, callback) { console.log("瑙﹀彂楠岃瘉") // 鏍¢獙蹇呭~ @@ -503,9 +891,35 @@ } callback(); // 楠岃瘉閫氳繃 }, + + //濂栧搧璁剧疆 setPrize(row){ + //鍒ゆ柇鏄惁鍚姩锛岃嫢鍚姩鍒欙紝鏃犳硶缂栬緫 + if("on" === row.enableStatus){ + this.$Message.error("鎶藉宸插紑鍚紝涓嶈兘缂栬緫!") + return + } + + this.activityPrizeId = row.id; + this.getPrizeList(); + this.prizeSettingShow = true; + + this.choiceLoading = true; + getActivityRefPrizeByActivityId(row.id).then(res =>{ + this.choiceLoading = false; + if (res.code === 200){ + this.choiceData = res.data + } + + }) }, + prizeSettingModelClose(){ + this.activityPrizeId = null; + this.prizeSettingShow = false; + this.choiceData = []; + }, + //鏂囨湰杞崲 formatDate(date, format = 'YYYY-MM-DD HH:mm:ss') { if (!date) return ''; @@ -534,87 +948,70 @@ this.getPage() }, handleBeforeUpload(file,type){ - if ("content" === type){ - this.activityImg = file + if("content" === type){ + this.activityImg = file; + this.imgTempUrl = URL.createObjectURL(file); + return false; + }else if ("cover" === type){ + this.activityCover = file; + this.coverTempUrl = URL.createObjectURL(file); + return false; + } + }, + // 鍒犻櫎鏂囦欢 + handleRemove(type) { + if ('content' === type){ + this.activityImg = null; + this.imgTempUrl = null; + + }else if ('cover' === type){ + this.activityCover = null; + this.coverTempUrl = null; + } + }, + + async uploadFileByLmk(){ + if (this.activityImg){ this.submitLoading = true const formData = new FormData() formData.append('file', this.activityImg) - - uploadFileByLmk(formData).then(res => { + await uploadFileByLmk(formData).then(res => { this.submitLoading = false if (res.code === 200) { this.activityFrom.activityImg = res.data.fileKey; - this.activityImg.activityImgUrl = res.data.url; - this.$Message.success('涓婁紶鎴愬姛') + // this.$Message.success('涓婁紶鎴愬姛') }else{ - this.$Message.error(res.msg) + // this.$Message.error(res.msg) } }).catch(() => { this.submitLoading = false }) - }else if ("cover" === type){ - this.activityCover = file + } + if (this.activityCover){ this.submitLoading = true const formData = new FormData() formData.append('file', this.activityCover) - uploadFileByLmk(formData).then(res => { + await uploadFileByLmk(formData).then(res => { this.submitLoading = false if (res.code === 200) { this.activityFrom.activityCover = res.data.fileKey - this.activityCover.activityCoverUrl = res.data.url; - this.$Message.success('涓婁紶鎴愬姛') + // this.$Message.success('涓婁紶鎴愬姛') }else{ - this.$Message.error(res.msg) + // this.$Message.error(res.msg) } }).catch(() => { this.submitLoading = false }) } - - }, - // 鍒犻櫎鏂囦欢 - handleRemove(type) { - if ("content" === type){ - //鐐瑰嚮鍏抽棴绐楀彛鏃剁‘淇濇枃浠跺凡琚竻闄� - if (this.activityImg === null) { - return; - } - if (!this.activityFrom.activityImg) { - this.activityImg = null - return - } - delByKey(this.activityFrom.activityImg).then(res => { - if (res.code === 200) { - this.activityImg = null - this.activityFrom.activityImg = '' - }else{ - this.$Message.error(res.msg) - } - }) - }else if ("cover" === type){ - if (this.activityCover === null) { - return; - } - if (!this.activityFrom.activityCover) { - this.activityCover = null - return - } - delByKey(this.activityFrom.activityCover).then(res => { - if (res.code === 200) { - this.activityCover = null - this.activityFrom.activityCover = '' - }else{ - this.$Message.error(res.msg) - } - }) + async saveOrUpdate(){ + if (this.activityFrom.maxPrize < this.activityFrom.prizeNum){ + this.$Message.error("鍒濆鍖栨鏁板洜灏忎簬鎴栫瓑浜庢渶澶ф娊濂栨鏁�") + return } + await this.uploadFileByLmk(); - - - }, - saveOrUpdate(){ const submitData = { ...this.activityFrom, beginTime: this.formatDate(this.activityFrom.beginTime, 'YYYY-MM-DD HH:mm:ss'), @@ -629,7 +1026,7 @@ this.submitLoading = false if (res.code === 200) { this.$Message.success(res.msg) - this.modelClose() + this.modelShow = false; this.getPage() }else{ this.$Message.error(res.msg) @@ -646,8 +1043,6 @@ modelClose(){ this.modelShow = false this.submitLoading = false - this.handleRemove("content"); - this.handleRemove("cover"); this.$refs.form.resetFields() }, getPage(){ @@ -656,6 +1051,7 @@ this.loading = false; if (res.code === 200){ this.activityList = res.data; + this.total = res.total; }else { this.$Message.error(res.msg) } @@ -664,6 +1060,13 @@ detail(row){ this.infoModalShow = true; this.detailData = {...row}; + getActivityRefPrizeByActivityId(row.id).then(res=>{ + if (res.code ===200){ + this.$set(this.detailData,'prizes', res.data); + } + }) + console.log(this.detailData) + }, openEdit(row){ this.modelShow = true; @@ -680,6 +1083,9 @@ activityCover:row.activityCover, enableStatus:row.enableStatus, } + this.coverTempUrl = row.activityCoverUrl; + this.imgTempUrl = row.activityImgUrl; + }, handleSearch(type,value){ @@ -691,8 +1097,13 @@ this.getPage() }, openAdd(){ + this.$refs.form.resetFields() this.modelShow = true; this.modelTitle = "鏂板娲诲姩"; + this.coverTempUrl = null; + this.prizeCover=null; + this.prizeImg = null; + this.imgTempUrl = null; }, delById(row){ del(row.id).then(res=>{ @@ -718,8 +1129,24 @@ this.searchForm.pageNumber = page this.getPage() }, - changeStatus(){ - + prizeChangePage(){ + this.prizeSearchForm.pageNumber = 1 + this.prizeSearchForm.pageSize = pageSize + this.getPrizeList() + }, + prizeChangePageSize(){ + this.prizeSearchForm.pageNumber = page + this.getPrizeList() + }, + publishPrizeActivity(row){ + publishPrizeActivity(row.id).then(res =>{ + if (res.code === 200){ + this.$Message.success(res.msg) + }else{ + this.$Message.error(res.msg) + } + }) + this.getPage() }, }, @@ -780,12 +1207,6 @@ } } .activity-table { - .media-container { - display: flex; - justify-content: center; - align-items: center; - height: 100px; - .thumbnail { max-width: 100%; max-height: 100%; @@ -798,21 +1219,32 @@ box-shadow: 0 0 8px rgba(0, 0, 0, 0.2); } } + .action-btns { + display: flex; + flex-wrap: wrap; + justify-content: center; - .video-player { - max-width: 100%; - max-height: 100px; - background: #000; - } - - .text-cover { - padding: 8px; - background: #f8f8f9; - border-radius: 4px; - max-width: 100%; - word-break: break-all; + .ivu-btn { + margin: 4px; + font-size: 12px; + padding: 2px 6px; + min-width: 60px; } } +} +.prize-table { + .thumbnail { + max-width: 100px; + max-height: 100px; + object-fit: contain; + cursor: pointer; + transition: all 0.3s; + + &:hover { + transform: scale(1.05); + box-shadow: 0 0 8px rgba(0, 0, 0, 0.2); + } + } .action-btns { display: flex; @@ -827,4 +1259,47 @@ } } } +.preview-image-limit{ + max-width: 100%; + max-height: 200px; + object-fit: contain; + border-radius: 4px; + box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); + display: block; +} +//璇︽儏鍟嗗搧鏍峰紡 +.prize-list { + margin-top: 10px; + max-height: 300px; + overflow-y: auto; +} + +.prize-item { + padding: 12px; + border: 1px solid #e8eaec; + border-radius: 4px; + margin-bottom: 10px; + background: #f8f9fa; +} +.prize-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 8px; +} + +.prize-name { + font-weight: bold; + color: #17233d; +} + +.prize-content { + font-size: 13px; +} + +.prize-info { + margin-top: 8px; + color: #808695; +} + </style> diff --git a/manager/src/views/activity-prize/prize.vue b/manager/src/views/activity-prize/prize.vue new file mode 100644 index 0000000..a2050a3 --- /dev/null +++ b/manager/src/views/activity-prize/prize.vue @@ -0,0 +1,923 @@ +<template> + <div> + <Card> + <!-- 鎼滅储琛ㄥ崟 --> + <Form + ref="searchForm" + @keydown.enter.native="handleSearch" + :model="searchForm" + inline + :label-width="80" + class="search-form" + > + <FormItem label="濂栧搧鍚�" prop="prizeName"> + <Input + type="text" + v-model="searchForm.prizeName" + placeholder="璇疯緭鍏ュ鍝佸悕" + clearable + @on-clear="handleSearch" + @on-change="handleSearch" + style="width: 180px" + /> + </FormItem> + <FormItem label="濂栧搧绫诲瀷" prop="prizeType"> + <Select + v-model="searchForm.prizeType" + placeholder="璇烽�夋嫨濂栧搧绫诲瀷" + style="width: 180px" + clearable + @on-clear="handleSearch" + @on-change="handleSearch" + > + <Option + v-for="item in typeSelect" + :value="item.value" + :key="item.id" + > + {{ item.label }} + </Option> + </Select> + </FormItem> + + <Button + @click="handleSearch" + type="primary" + icon="ios-search" + class="search-btn" + >鎼滅储</Button> + <Button + @click="resetSearch" + icon="md-refresh" + style="margin-left: 8px" + >閲嶇疆</Button> + </Form> + + <!-- 鎿嶄綔鎸夐挳 --> + <Row class="operation"> + <Button @click="openAdd" type="primary" icon="md-add">鏂板濂栧搧</Button> + </Row> + + <!-- 濂栧搧琛ㄦ牸 --> + <Table + :loading="loading" + border + :columns="columns" + :data="prizeList" + ref="table" + class="prize-table" + > + <template slot-scope="{ row }" slot="prizeCoverUrl"> + <img + :src="row.prizeCoverUrl" + alt="濂栧搧灏侀潰" + class="thumbnail" + @click="previewImage(row.prizeCoverUrl)" + > + </template> + <!-- 鎿嶄綔鎸夐挳鎻掓Ы --> + <template slot-scope="{ row }" slot="action"> + <div class="action-btns"> + <Button + type="info" + size="small" + @click="detail(row)" + >璇︽儏</Button> + <Button + type="info" + size="small" + @click="openEdit(row)" + >缂栬緫</Button> + <Button + type="error" + size="small" + @click="delById(row)" + >鍒犻櫎</Button> + + </div> + </template> + </Table> + + <!-- 鍒嗛〉 --> + <Row type="flex" justify="end" class="page-footer"> + <Page + :current="searchForm.pageNumber" + :total="total" + :page-size="searchForm.pageSize" + @on-change="changePage" + @on-page-size-change="changePageSize" + :page-size-opts="[10, 20, 50]" + size="small" + show-total + show-elevator + show-sizer + ></Page> + </Row> + + <!-- 濂栧搧缂栬緫/鏂板妯℃�佹 --> + <Modal + v-model="modelShow" + :title="modelTitle" + @on-cancel="modelClose" + width="1200" + :mask-closable="false" + > + <Form ref="form" :model="prizeFrom" :label-width="100" :rules="rules"> + <Row :gutter="16"> + <Col span ="12"> + <FormItem label="濂栧搧绫诲瀷" prop="prizeType"> + <Select + v-model="prizeFrom.prizeType" + placeholder="璇烽�夋嫨濂栧搧绫诲瀷" + style="width: 180px" + clearable + > + <Option + v-for="item in typeSelect" + :value="item.value" + :key="item.id" + > + {{ item.label }} + </Option> + </Select> + </FormItem> + </Col> + <Col span ="24"> +<!-- <div >--> + <FormItem label="宸查�変紭鎯犲姷" prop="couponId" v-if="prizeFrom.prizeType === 'coupon'" style="margin-bottom: 20px"> + <Input :disabled="true" style="width: 30%;margin-bottom: 20px" v-model="showCoupon" placeholder="璇风偣鍑婚�夋嫨琛ㄦ牸鍐呬紭鎯犲姷"></Input> + <Table + :loading="couponLoading" + border + :columns="couponColumns" + :data="couponData" + ref="table" + @on-current-change="handleRowClick" + highlight-row + ></Table> + <Row type="flex" justify="center" class="mt_10"> + <Page + :current="couponSearchForm.pageNumber" + :total="couponTotal" + :page-size="couponSearchForm.pageSize" + @on-change="couponChangePage" + @on-page-size-change="couponChangePageSize" + :page-size-opts="[10, 20, 50]" + size="small" + show-total + show-elevator + show-sizer + ></Page> + </Row> + </FormItem> +<!-- </div>--> + </Col> + <Col span="24"> + <FormItem label="濂栧搧鍚嶇О" prop="prizeName"> + <Input + v-model="prizeFrom.prizeName" + placeholder="璇疯緭鍏ュ鍝佸悕绉�" + clearable + style="width: 180px" + /> + </FormItem> + </Col> + <Col span="12"> + <FormItem label="濂栧搧鍐呭" prop="prizeContent" :label-width="100"> + <Input v-model="prizeFrom.prizeContent" + style="width: 300px" type="textarea" :autosize="{minRows: 2,maxRows: 5}" placeholder="璇疯緭鍏�"></Input> + </FormItem> + </Col> + <Col span="12"> + <FormItem label="濂栧搧鎻忚堪" prop="prizeDes" :label-width="100"> + <Input v-model="prizeFrom.prizeDes" + style="width: 300px" type="textarea" :autosize="{minRows: 2,maxRows: 5}" placeholder="璇疯緭鍏�"></Input> + </FormItem> + </Col> + <Col span="24"> + <FormItem label="濂栧搧灏侀潰锛�" prop="prizeCover"> + <Upload + v-if="!coverTempUrl" + :before-upload="(file) => handleBeforeUpload(file, 'cover')" + :format="['jpg','jpeg','png','gif']" + :max-size="20480" + action="" + accept="image/*" + > + <Button icon="ios-cloud-upload-outline" >涓婁紶灏侀潰鏂囦欢</Button> + </Upload> + <div v-else class="upload-file-info"> + <img :src="coverTempUrl" alt="濂栧搧灏侀潰" class="preview-image-limit"> + <Button type="text" @click="handleRemove('cover')">鍒犻櫎</Button> + </div> + + </FormItem> + </Col> + <Col span="24"> + <FormItem label="濂栧搧鍥剧墖锛�" prop="prizeImg"> + + <Upload + v-if="!imgTempUrl" + :before-upload="(file) => handleBeforeUpload(file, 'content')" + :format="['jpg','jpeg','png','gif']" + :max-size="20480" + action="" + accept="image/*" + > + <Button icon="ios-cloud-upload-outline" >涓婁紶鍥剧墖</Button> + </Upload> + <div v-if="imgTempUrl" class="upload-file-info"> + <img :src="imgTempUrl" alt="濂栧搧鍥剧墖" class="preview-image-limit"> + <Button type="text" @click="handleRemove('content')">鍒犻櫎</Button> + </div> + + <!-- 鍩轰簬elementUi鐨勪笂浼犵粍浠� el-upload end--> + </FormItem> + </Col> + + + + </Row> + </Form> + + <div slot="footer"> + <Button @click="modelClose">鍙栨秷</Button> + <Button type="primary" :loading="submitLoading" @click="saveOrUpdate">鎻愪氦</Button> + </div> + </Modal> + <!-- 鍥剧墖棰勮妯℃�佹 --> + <Modal v-model="previewVisible" title="鍥剧墖棰勮" footer-hide> + <img :src="previewImageUrl" class="preview-image"> + </Modal> + + <!-- 璇︽儏--> + <Modal + v-model="infoModalShow" + title="濂栧搧璇︽儏" + @on-cancel="infoModelClose" + width="800" + :mask-closable="false" + > + <div class="detail-container"> + <Row :gutter="16"> + <Col span="12"> + <div class="detail-item"> + <label>濂栧搧鍚嶇О锛�</label> + <span>{{ detailData.prizeName }}</span> + </div> + </Col> + <Col span="12"> + <div class="detail-item"> + <label>濂栧搧绫诲瀷锛�</label> + <span> + {{replaceText(detailData.prizeType)}}</span> + </div> + </Col> + <Col span="12"> + <div class="detail-item"> + <label>濂栧搧鍐呭锛�</label> + <span>{{ detailData.prizeContent}}</span> + </div> + </Col> + <Col span="12"> + <div class="detail-item"> + <label>濂栧搧鎻忚堪锛�</label> + <span>{{ detailData.prizeDes}}</span> + </div> + </Col> + + <Col span="24"> + <div class="detail-item"> + <label>濂栧搧灏侀潰锛�</label> + <div v-if="detailData.prizeCoverUrl" class="detail-image"> + <img + :src="detailData.prizeCoverUrl" alt="濂栧搧灏侀潰" + class="preview-image-limit" + > + </div> + <span v-else>-</span> + </div> + </Col> + <Col span="24"> + <div class="detail-item"> + <label>濂栧搧鍥剧墖锛�</label> + <div v-if="detailData.prizeImgUrl" class="detail-image"> + <img :src="detailData.prizeImgUrl" alt="濂栧搧鍥剧墖" class="preview-image-limit"> + </div> + <span v-else>-</span> + </div> + </Col> + + </Row> + </div> + + </Modal> + + + </Card> + </div> +</template> + +<script> +import { + getPage, + detail, + edit, + add, + del, + canUpDatePrizeDraw +} from '@/api/prize.js' +import {delByKey, uploadFileByLmk} from "../../api/common"; +import {promotionsScopeTypeRender, promotionsStatusRender} from "../../utils/promotions"; +import {getPlatformCouponList} from "../../api/promotion"; + +export default { + name: "prize", + watch: { + 'prizeFrom.prizeType'(newVal) { + if (newVal === 'coupon') { + this.getCouponDataList(); // 鍔犺浇浼樻儬鍒稿垪琛� + } else { + this.prizeFrom.couponId = ''; // 娓呯┖宸查�夌殑浼樻儬鍒� + } + } + }, + data() { + return { + infoModalShow:false, + detailData: {}, + showCoupon:'', + coverTempUrl:null, + imgTempUrl:null, + // 鍥剧墖棰勮 + previewVisible: false, + previewImageUrl: '', + + //浼樻儬鍔� + selectedRowId:'', + couponTotal:0, + couponData:[], + couponLoading:false, + couponColumns: [ + // 琛ㄥご + { + title: "浼樻儬鍒稿悕绉�", + key: "couponName", + width: 180, + tooltip: true, + }, + { + title: "闈㈤/鎶樻墸", + key: "price", + width: 150, + render: (h, params) => { + if (params.row.price) { + return h("priceColorScheme", {props:{value:params.row.price,color:this.$mainColor}} ); + + } else { + return h("div", params.row.couponDiscount + "鎶�"); + } + }, + }, + + { + title: "鑾峰彇鏂瑰紡", + width: 120, + key: "getType", + render: (h, params) => { + if (params.row.getType === "FREE") { + return h("Tag", { props: { color: "red" } }, "鍏嶈垂鑾峰彇"); + } else if (params.row.getType === "ACTIVITY") { + return h("Tag", { props: { color: "volcano" } }, "娲诲姩鑾峰彇"); + } else if (params.row.getType === "INSIDE") { + return h("Tag", { props: { color: "lime" } }, "鍐呰喘"); + } else if (params.row.getType === "IGAME") { + return h("Tag", { props: { color: "lime" } }, "娓告垙浜虹敓"); + } else { + return h("Tag", { props: { color: "purple" } }, "鏈煡"); + } + }, + }, + { + title: "浼樻儬鍒哥被鍨�", + key: "couponType", + width: 150, + render: (h, params) => { + let text = ""; + if (params.row.couponType === "DISCOUNT") { + return h("Tag", { props: { color: "blue" } }, "鎵撴姌"); + } else if (params.row.couponType === "PRICE") { + return h("Tag", { props: { color: "geekblue" } }, "鍑忓厤鐜伴噾"); + } else { + return h("Tag", { props: { color: "purple" } }, "鏈煡"); + } + }, + }, + { + title: "鍝佺被鎻忚堪", + key: "scopeType", + width: 120, + render: (h, params) => { + return promotionsScopeTypeRender(h, params); + }, + }, + { + title: "娲诲姩鏃堕棿", + render: (h, params) => { + if ( + params?.row?.getType === "ACTIVITY" && + params?.row?.rangeDayType === "DYNAMICTIME" + ) { + return h("div", "闀挎湡鏈夋晥"); + } else if (params?.row?.startTime && params?.row?.endTime) { + return h("div", { + domProps: { + innerHTML: + params.row.startTime + "<br/>" + params.row.endTime, + }, + }); + } + }, + }, + { + title: "鐘舵��", + width: 100, + key: "promotionStatus", + align: "center", + fixed: "right", + render: (h, params) => { + return promotionsStatusRender(h, params); + }, + }, + ], + + typeSelect:[ + { + id:1, + value:'coupon', + label:'浼樻儬鍔�' + } + ], + modelShow:false, + modelTitle:'', + rules: { + couponId:[{ + required: true, + }], + prizeName:[ + { required: true, message: '璇疯緭鍏ュ鍝佸悕绉�', trigger: 'blur' }, + { max: 50, message: '闀垮害涓嶈兘瓒呰繃50涓瓧绗�', trigger: 'blur' } + ], + prizeType: [ + { required: true, message: '璇烽�夋嫨濂栧搧绫诲瀷', trigger: 'change' }, + ], + prizeContent: [ + { required: true, message: '璇疯緭鍏ュ鍝佸唴瀹�', trigger: 'blur' }, + { max: 100, message: '闀垮害涓嶈兘瓒呰繃100涓瓧绗�', trigger: 'blur' } + ], + prizeDes: [ + { required: true, message: '璇疯緭鍏ュ鍝佹弿杩�', trigger: 'blur' }, + { max: 100, message: '闀垮害涓嶈兘瓒呰繃100涓瓧绗�', trigger: 'blur' } + ], + prizeCover: [ + {required: true, message: '璇烽�夋嫨濂栧搧灏侀潰', trigger: 'blur'} + ], + prizeImg: [ + {required: true, message: '璇烽�夋嫨濂栧搧鍥剧墖', trigger: 'blur'} + ], + }, + + prizeFrom:{ + id:'', + prizeName:'', + prizeType:'', + couponId:'', + prizeContent:'', + prizeCover:'', + prizeDes:'', + prizeImg:'', + }, + loading:false, + + columns:[ + { + title: '濂栧搧灏侀潰', + key: 'prizeCoverUrl', + slot:'prizeCoverUrl', + align: 'center', + minWidth: 100, + }, + { + title: '濂栧搧鍚嶇О', + key: 'prizeName', + minWidth: 100, + }, + { + title: '濂栧搧绫诲瀷', + key: 'prizeType', + minWidth: 100, + render: (h, params) => { + if (params.row.prizeType === "coupon") { + return h("Tag", {props: {color: "red"}}, "浼樻儬鍒�"); + } else { + return h("Tag", {props: {color: "purple"}}, "鏈煡"); + } + } + }, + { + title: '濂栧搧鍐呭', + key: 'prizeContent', + minWidth: 100, + }, + { + title: '濂栧搧鎻忚堪', + key: 'prizeDes', + minWidth: 100, + }, + { + title:'鎿嶄綔', + slot: 'action', + width: 200, + align:'center', + fixed:'right' + } + ], + prizeList:[], + total:0, + searchForm:{ + prizeName:'', + prizeType:'', + pageSize:10, + pageNumber:1, + }, + couponSearchForm: { + // 鎼滅储妗嗗垵濮嬪寲瀵硅薄 + pageNumber: 1, // 褰撳墠椤垫暟 + pageSize: 10, // 椤甸潰澶у皬 + sort: "create_time", // 榛樿鎺掑簭瀛楁 + order: "desc", // 榛樿鎺掑簭鏂瑰紡 + getType: "", // 榛樿鎺掑簭鏂瑰紡 + promotionStatus:"START", + }, + + submitLoading:false, + prizeCover:null, + prizeImg:null, + } + }, + // 鍦ㄧ粍浠跺垱寤哄墠娉ㄥ唽 + beforeCreate() { + + }, + mounted() { + this.init(); + }, + methods: { + replaceText(text) { + if (text === "coupon") { + return "浼樻儬鍒�"; + } + return text; // 濡傛灉涓嶆槸鐩爣璇嶏紝杩斿洖鍘熸枃鏈� + }, + // 棰勮鍥剧墖 + previewImage(url) { + this.previewImageUrl = url + this.previewVisible = true + }, + // 澶勭悊琛岀偣鍑讳簨浠� + handleRowClick(currentRow ,oldCurrentRow){ + this.prizeFrom.couponId = currentRow.id; + this.showCoupon = currentRow.couponName; + }, + getCouponDataList() { + // 鑾峰彇鏁版嵁 + this.couponLoading = true; + getPlatformCouponList(this.couponSearchForm).then((res) => { + this.couponLoading = false; + if (res.success) { + console.log(res); + this.couponData = res.result.records; + this.couponTotal = res.result.total; + } + }); + this.couponTotal = this.couponData.length; + this.couponLoading = false; + }, + + resetSearch(){ + this.$refs.searchForm.resetFields() + this.searchForm.pageNumber = 1 + this.getPage() + }, + handleBeforeUpload(file,type) { + if("content" === type){ + this.prizeImg = file; + this.imgTempUrl = URL.createObjectURL(file); + return false; + }else if ("cover" === type){ + this.prizeCover = file; + this.coverTempUrl = URL.createObjectURL(file); + return false; + } + + }, + + async uploadFileByLmk(){ + if (this.prizeImg){ + this.submitLoading = true + const formData = new FormData() + formData.append('file', this.prizeImg) + await uploadFileByLmk(formData).then(res => { + this.submitLoading = false + if (res.code === 200) { + this.prizeFrom.prizeImg = res.data.fileKey; + // this.$Message.success('涓婁紶鎴愬姛') + }else{ + // this.$Message.error(res.msg) + } + }).catch(() => { + this.submitLoading = false + }) + } + if (this.prizeCover){ + this.submitLoading = true + const formData = new FormData() + formData.append('file', this.prizeCover) + + await uploadFileByLmk(formData).then(res => { + this.submitLoading = false + if (res.code === 200) { + this.prizeFrom.prizeCover = res.data.fileKey + // this.$Message.success('涓婁紶鎴愬姛') + }else{ + // this.$Message.error(res.msg) + } + }).catch(() => { + this.submitLoading = false + }) + } + }, + + // 鍒犻櫎鏂囦欢 + handleRemove(type) { + if ('content' === type){ + this.prizeImg = null; + this.imgTempUrl = null; + + }else if ('cover' === type){ + this.prizeCover = null; + this.coverTempUrl = null; + } + }, + + async saveOrUpdate(){ + await this.uploadFileByLmk(); + if (this.prizeFrom.prizeType === 'coupon') { + if (this.prizeFrom.couponId === null || this.prizeFrom.couponId === ''){ + this.$Message.error("璇烽�夋嫨琛ㄦ牸涓紭鎯犲嵎") + return; + } + } + this.$refs.form.validate(valid => { + if (valid) { + this.submitLoading = true + const api = this.prizeFrom.id ? edit : add + api(this.prizeFrom).then(res => { + this.submitLoading = false + if (res.code === 200) { + this.$Message.success(res.msg) + this.modelShow = false; + this.getPage() + }else{ + this.$Message.error(res.msg) + } + }).catch(() => { + this.submitLoading = false + }) + } + }) + }, + modelClose(){ + this.modelShow = false + this.submitLoading = false + this.showCoupon = ''; + this.$refs.form.resetFields() + }, + getPage(){ + this.loading = true; + getPage(this.searchForm).then(res =>{ + this.loading = false; + if (res.code === 200){ + this.prizeList = res.data; + this.total = res.total + }else { + this.$Message.error(res.msg) + } + }) + }, + detail(row){ + this.infoModalShow = true; + this.detailData = {...row}; + }, + infoModelClose(){ + this.infoModalShow = false; + }, + openEdit(row){ + //闇�瑕佸垽鏂槸鍚﹀彲浠ョ紪杈� + canUpDatePrizeDraw(row.id).then(res =>{ + if (res.code === 200){ + if (res.state){ + this.modelShow = true; + this.modelTitle = "缂栬緫濂栧搧"; + this.prizeFrom ={ + id:row.id, + prizeName: row.prizeName, + prizeType: row.prizeType, + couponId: row.couponId, + prizeContent: row.prizeContent, + prizeCover: row.prizeCover, + prizeDes: row.prizeDes, + prizeImg: row.prizeImg, + } + this.coverTempUrl = row.prizeCoverUrl; + this.imgTempUrl = row.prizeImgUrl; + this.showCoupon = res.data.couponName; + + }else { + this.$Message.error("璇ュ鍝佸湪鎶藉娲诲姩涓棤娉曠紪杈�!") + } + + } + }) + + + }, + + handleSearch(){ + this.getPage() + }, + openAdd(){ + this.$refs.form.resetFields() + this.modelShow = true; + this.modelTitle = "鏂板濂栧搧"; + //娓呴櫎琛ㄥ崟鐘舵��. + this.coverTempUrl = null; + this.prizeCover=null; + this.prizeImg = null; + this.imgTempUrl = null; + this.showCoupon = null; + }, + delById(row){ + del(row.id).then(res=>{ + if (res.code === 200){ + this.$Message.success(res.msg) + }else { + this.$Message.error(res.msg) + } + this.getPage() + }) + }, + // 鑾峰彇瀵屾枃鏈紪杈戝櫒鐨勫唴瀹� + // 鍒濆鍖栨暟鎹� + init() { + this.getPage() + }, + changePage(){ + this.searchForm.pageNumber = 1 + this.searchForm.pageSize = pageSize + this.getPage() + }, + changePageSize(){ + this.searchForm.pageNumber = page + this.getPage() + }, + couponChangePage(v) { + // 鏀瑰彉椤电爜 + this.couponSearchForm.pageNumber = v; + this.getCouponDataList(); + }, + couponChangePageSize(v) { + // 鏀瑰彉椤垫暟 + this.couponSearchForm.pageNumber = 1; + this.couponSearchForm.pageSize = v; + this.getCouponDataList(); + }, + }, +} +</script> + +<style lang="scss" scoped> +.detail-container { + padding: 16px; +} + +.detail-item { + margin-bottom: 16px; + line-height: 1.5; +} + +.detail-item label { + display: inline-block; + width: 120px; + font-weight: bold; + color: #515a6e; + vertical-align: top; +} + +.detail-item span { + display: inline-block; + max-width: calc(100% - 120px); +} + +.detail-image { + display: inline-block; + margin-top: 8px; + border: 1px dashed #dcdee2; + padding: 4px; + border-radius: 4px; + background: #f8f8f9; +} +.search-form { + padding: 16px; + background: #f8f8f9; + border-radius: 4px; + margin-bottom: 16px; + + .ivu-form-item { + margin-bottom: 16px; + margin-right: 16px; + } + + .search-btn { + margin-left: 8px; + } +} +.operation { + margin-bottom: 16px; + + .ivu-btn { + margin-right: 8px; + } +} +/* 閫変腑琛屾牱寮� */ +.selected-row { + background-color: #e6f7ff; /* 娴呰摑鑹茶儗鏅� */ + border-left: 3px solid #1890ff; /* 宸︿晶钃濊壊杈规 */ +} + +/* 閫変腑琛宧over鏍峰紡锛堝彲閫夛級 */ +.selected-row:hover { + background-color: #d1eaff !important; +} + + +.preview-image{ + width: 200px; + height: auto; + object-fit: contain +} +.preview-image { + max-width: 100%; + max-height: 70vh; + object-fit: contain; + border-radius: 4px; + box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); + display: block; + margin: 0 auto; +} +.preview-image-limit{ + max-width: 100%; + max-height: 200px; + object-fit: contain; + border-radius: 4px; + box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); + display: block; +} +.prize-table { + .thumbnail { + max-width: 100%; + max-height: 100px; + object-fit: contain; + cursor: pointer; + transition: all 0.3s; + + &:hover { + transform: scale(1.05); + box-shadow: 0 0 8px rgba(0, 0, 0, 0.2); + } + } + + .action-btns { + display: flex; + flex-wrap: wrap; + justify-content: center; + + .ivu-btn { + margin: 4px; + font-size: 12px; + padding: 2px 6px; + min-width: 60px; + } + } +} +</style> -- Gitblit v1.8.0