From f6c05b70e6f74b413d8bce3d63f844c6cdb194f2 Mon Sep 17 00:00:00 2001 From: xiangpei <xiangpei@timesnew.cn> Date: 星期三, 25 六月 2025 21:20:48 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/dev' into dev --- manager/src/api/customer.js | 6 manager/src/views/goods/goods-info/goodsApply.vue | 6 manager/src/views/tag/tag/index.vue | 403 ++++++++ seller/src/views/goods/goods-seller/goodsOperationFirst.vue | 48 seller/src/views/goods/goods-seller/goods.vue | 3 manager/src/views/customer/index.vue | 173 +++ seller/src/views/goods/goods-seller/goodsOperationSec.vue | 633 ++++++++++--- manager/src/views/activity/index.vue | 139 +++ manager/src/api/order.js | 4 manager/src/api/tag.js | 47 + seller/src/views/goods/goods-seller/goodsOperation.vue | 6 manager/src/views/goods/goods-info/goods.vue | 18 manager/src/views/goods/goods-info/goodsDetail.vue | 21 manager/src/views/kitchen/kitchenVideo.vue | 5 seller/src/api/file.js | 31 seller/src/views/lili-components/editor/index.vue | 5 seller/src/libs/axios.js | 3 manager/src/api/tag-type.js | 48 + manager/src/views/news/index.vue | 543 +++++++++++ manager/src/api/news.js | 39 seller/src/utils/file.js | 40 manager/src/views/tag/tag-type/index.vue | 311 ++++++ seller/package.json | 1 manager/src/views/health/HealthVideoList.vue | 5 manager/src/views/order/order/orderDetail.vue | 175 +++ 25 files changed, 2,513 insertions(+), 200 deletions(-) diff --git a/manager/src/api/customer.js b/manager/src/api/customer.js index 9128455..9972185 100644 --- a/manager/src/api/customer.js +++ b/manager/src/api/customer.js @@ -78,3 +78,9 @@ }) } +export const getCustomerInfo= (params) =>{ + return service({ + url: '/customerManager/'+ params, + method: 'GET' + }) +} diff --git a/manager/src/api/news.js b/manager/src/api/news.js new file mode 100644 index 0000000..19aca4e --- /dev/null +++ b/manager/src/api/news.js @@ -0,0 +1,39 @@ +import service from "../libs/axios"; + +export const getNews = (params) =>{ + return service({ + url: "/news/page", + method: "GET", + params: params + }) +} + +export const addNews = (params) =>{ + return service({ + url: "/news", + method: "POST", + data: params + }) +} + +export const editNews = (params) =>{ + return service({ + url: "/news", + method: "PUT", + data: params + }) +} + +export const publish = (param) =>{ + return service({ + url: "/news/publish/"+ param, + method: "PUT", + }) +} + +export const delById = (param) =>{ + return service({ + url: "/news/"+ param, + method: "DELETE", + }) +} diff --git a/manager/src/api/order.js b/manager/src/api/order.js index 4981a96..b46c866 100644 --- a/manager/src/api/order.js +++ b/manager/src/api/order.js @@ -130,6 +130,10 @@ export const getLogisticsChecked = () => { return getRequest(`/other/logistics/getChecked`) } +//鏌ヨ鍖呰9鍒楄〃 +export const getPackage = (orderSn) => { + return getRequest(`/order/order/getPackage/${orderSn}`); +} //鏌ヨ鐗╂祦 export const getTraces = (sn, params) => { diff --git a/manager/src/api/tag-type.js b/manager/src/api/tag-type.js new file mode 100644 index 0000000..7776630 --- /dev/null +++ b/manager/src/api/tag-type.js @@ -0,0 +1,48 @@ +import service from "@/libs/axios"; + +// 鑾峰彇鏍囩鍒嗙被鍒楄〃 +export const getTagTypeList = (params) => { + return service({ + url: "/lmk/tag-type/list", + method: "GET", + params: params + }) +} + +export const getTagKeyTypeList = () => { + return service({ + url: "/lmk/tag-type/key/list", + method: "GET" + }) +} + + + +// 閫氳繃id鍒犻櫎鏍囩鍒嗙被 +export const deleteTagTypeById = (params) => { + return service({ + url: "/lmk/tag-type/" + params, + method: "DELETE" + }) +} + + +// 淇敼鏍囩鍒嗙被 +export const updateTagType = (params) => { + return service({ + url: "/lmk/tag-type/", + method: "PUT", + data: params + }) +} + +// 娣诲姞鏍囩鍒嗙被 +export const saveTagType = (params) => { + return service({ + url: "/lmk/tag-type/", + method: "POST", + data: params + }) +} + + diff --git a/manager/src/api/tag.js b/manager/src/api/tag.js new file mode 100644 index 0000000..a97d17a --- /dev/null +++ b/manager/src/api/tag.js @@ -0,0 +1,47 @@ +import service from "@/libs/axios"; + +// 鑾峰彇鏍囩鍒嗛〉 +export const getTags = (data) => { + return service({ + url: "/lmk/tag/page", + method: "GET", + params: data + }) +} + +// 鑾峰彇鏍囩鍒楄〃 +export const getTagList = () => { + return service({ + url: "/lmk/tag/list", + method: "GET" + }) +} + + +// 閫氳繃id鍒犻櫎鏍囩 +export const deleteTagById = (params) => { + return service({ + url: "/lmk/tag/" + params, + method: "DELETE" + }) +} + + +// 淇敼鏍囩 +export const editTag = (params) => { + return service({ + url: "/lmk/tag/", + method: "PUT", + data: params + }) +} + +// 娣诲姞鏍囩 +export const addTag = (params) => { + return service({ + url: "/lmk/tag/", + method: "POST", + data: params + }) +} + diff --git a/manager/src/views/activity/index.vue b/manager/src/views/activity/index.vue index b1f49f2..26a2c42 100644 --- a/manager/src/views/activity/index.vue +++ b/manager/src/views/activity/index.vue @@ -136,6 +136,11 @@ <Button type="info" size="small" + @click="detail(row)" + >璇︽儏</Button> + <Button + type="info" + size="small" @click="openEdit(row)" >缂栬緫</Button> <Button @@ -336,6 +341,82 @@ </Row> </Modal> + <Modal + v-model="infoModelShow" + :title="modelTitle" + @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>{{ activityInfo.activityName || '-' }}</span> + </div> + </Col> + <Col span="12"> + <div class="detail-item"> + <label>娲诲姩绫诲瀷锛�</label> + <span>{{activityInfo.activityType === 'online' ? '绾夸笂':'绾夸笅'}}</span> + </div> + </Col> + <Col span="12"> + <div class="detail-item"> + <label>鎶ュ悕鏃堕棿娈碉細</label> + <span>{{ activityInfo.reportStartTime }} - {{ activityInfo.reportEndTime }}</span> + </div> + </Col> + <Col span="12"> + <div class="detail-item"> + <label>娲诲姩鏃堕棿娈碉細</label> + <span>{{ activityInfo.startTime }} - {{ activityInfo.endTime }}</span> + </div> + </Col> + + <Col span="24" v-if="coverType === '杈撳叆鏂囧瓧灏侀潰'"> + <div class="detail-item"> + <label>灏侀潰鏂囧瓧锛�</label> + <span>{{ activityInfo.cover || '-' }}</span> + </div> + </Col> + <Col span="24" v-if="coverType === '閫夋嫨鏂囦欢灏侀潰'"> + <div class="detail-item"> + <label>涓婁紶灏侀潰锛�</label> + <span>{{ activityInfo.cover }}</span> + </div> + </Col> + <Col span="12"> + <div class="detail-item"> + <label>浜烘暟闄愬埗锛�</label> + <span>{{ activityInfo.limitUserNum || '鏃犻檺鍒�' }}</span> + </div> + </Col> + <Col span="12"> + <div class="detail-item"> + <label>娲诲姩鍦扮偣锛�</label> + <span>{{ activityInfo.activityLocation || '-' }}</span> + </div> + </Col> + <Col span="24"> + <div class="detail-item"> + <label>娲诲姩鍐呭锛�</label> + <div + class="activity-content" + v-html="activityInfo.activityContent || '鏃犲唴瀹�'" + ></div> + </div> + </Col> + </Row> + </div> + + <div slot="footer"> + <Button @click="infoModelClose">鍏抽棴</Button> + </div> + </Modal> + + <!-- 鍥剧墖棰勮妯℃�佹 --> <Modal v-model="previewVisible" title="鍥剧墖棰勮" footer-hide> <img :src="previewImageUrl" style="width: 100%"> @@ -361,6 +442,8 @@ components: {Editor}, data() { return { + infoModelShow:false, + loading: false, membersLoading: false, submitLoading: false, @@ -397,6 +480,24 @@ // 娲诲姩琛ㄥ崟 activityFrom: { + id: '', + activityName: '', + activityType: '', + reportTime: [], + time: [], + activityContent: '', + cover: '', + coverType: '', + status: '', + reportStartTime: '', + reportEndTime: '', + startTime: '', + endTime: '', + recommend: false, + limitUserNum: 0, + activityLocation: '', + }, + activityInfo: { id: '', activityName: '', activityType: '', @@ -645,6 +746,11 @@ this.init() }, methods: { + detail(row){ + this.modelTitle = '娲诲姩璇︽儏' + this.infoModelShow = true + this.activityInfo = row + }, // 鑾峰彇瀵屾枃鏈紪杈戝櫒鐨勫唴瀹� getReason(content) { this.activityFrom.activityContent = content @@ -757,7 +863,9 @@ this.coverType = row.coverType === 'text' ? '杈撳叆鏂囧瓧灏侀潰' : '閫夋嫨鏂囦欢灏侀潰' }) }, - + infoModelClose(){ + this.infoModelShow = false + }, // 鍏抽棴妯℃�佹 modelClose() { this.modelShow = false @@ -1183,4 +1291,33 @@ margin-top: 4px; } } +.detail-container { + padding: 16px; +} + +.detail-item { + margin-bottom: 18px; + line-height: 1.5; + + label { + display: inline-block; + width: 100px; + color: #666; + font-weight: bold; + vertical-align: top; + } + + span { + display: inline-block; + width: calc(100% - 110px); + } +} + +.activity-content { + border: 1px solid #dcdee2; + border-radius: 4px; + padding: 12px; + min-height: 100px; + margin-top: 8px; +} </style> diff --git a/manager/src/views/customer/index.vue b/manager/src/views/customer/index.vue index 40112e7..6208375 100644 --- a/manager/src/views/customer/index.vue +++ b/manager/src/views/customer/index.vue @@ -68,6 +68,7 @@ @on-selection-change="showSelect" > <template slot-scope="{ row, index }" slot="action"> + <Button type="info" size="small" style="margin-right: 5px" @click="openInfo(row)">鏌ョ湅璇︽儏</Button> <Button type="info" size="small" style="margin-right: 5px" @click="openEdit(row)">缂栬緫鏍囩</Button> <Button type="error" size="small" style="margin-right: 5px" @click="joinBlack(row)">鍔犲叆榛戝悕鍗�</Button> </template> @@ -87,6 +88,82 @@ ></Page> </Row> + <Modal + v-model="showCustomerInfo" + :title="modelTitle" + width="700" + :mask-closable="false" + > + <div class="customer-detail"> + <div class="avatar-section"> + <Avatar :src="customerInfo.face" size="large" /> + <div class="basic-info"> + <h3>{{ customerInfo.nickName || '寰俊鐢ㄦ埛' }}</h3> + <p>ID: {{ customerInfo.id }}</p> + <p>鐢ㄦ埛鍚�: {{ customerInfo.username }}</p> + </div> + </div> + + <Divider /> + + <div class="detail-grid"> + <div class="detail-row"> + <span class="detail-label">鎬у埆锛�</span> + <span class="detail-value">{{ customerInfo.sex === 0 ? "濂�" : "鐢�"}}</span> + </div> + <div class="detail-row"> + <span class="detail-label">鍦板尯锛�</span> + <span class="detail-value">{{ customerInfo.region || '鏈缃�' }}</span> + </div> + <div class="detail-row"> + <span class="detail-label">鎵嬫満鍙凤細</span> + <span class="detail-value">{{ customerInfo.mobile || '鏈粦瀹�' }}</span> + </div> + <div class="detail-row"> + <span class="detail-label">褰撳墠绉垎锛�</span> + <span class="detail-value">{{ customerInfo.point }}</span> + </div> + <div class="detail-row"> + <span class="detail-label">鎬荤Н鍒嗭細</span> + <span class="detail-value">{{ customerInfo.totalPoint }}</span> + </div> + <div class="detail-row"> + <span class="detail-label">璐﹀彿鐘舵�侊細</span> + <span class="detail-value"> + <Tag :color="customerInfo.disabled ? 'error' : 'success'"> + {{ customerInfo.disabled ? '宸茬鐢�' : '姝e父' }} + </Tag> + </span> + </div> + <div class="detail-row"> + <span class="detail-label">鏄惁鍏宠仈搴楅摵锛�</span> + <span class="detail-value">{{ customerInfo.haveStore ? '鏄�' : '鍚�' }}</span> + </div> + <div class="detail-row"> + <span class="detail-label">娉ㄥ唽鏃堕棿锛�</span> + <span class="detail-value">{{ customerInfo.createTime }}</span> + </div> + <div class="detail-row"> + <span class="detail-label">鏈�鍚庣櫥褰曟椂闂达細</span> + <span class="detail-value">{{ customerInfo.lastLoginDate }}</span> + </div> + </div> + + <div v-if="customerInfo.customerTagList && customerInfo.customerTagList.length > 0" class="tags-section"> + <h4>鐢ㄦ埛鏍囩</h4> + <div> + <Tag v-for="tag in customerInfo.customerTagList" :key="tag" color="default" style="margin-right: 8px;"> + {{ tag }} + </Tag> + </div> + </div> + </div> + + <div slot="footer"> + <Button type="primary" @click="showCustomerInfo = false">鍏抽棴</Button> + </div> + </Modal> +<!-- 鏍囩寮圭獥--> <Modal v-model="showCustomerTag" :title="modelTitle" @@ -125,7 +202,7 @@ <script> import JsonExcel from "vue-json-excel"; -import {getCustomerList,addCustomerTag,saveCustomerTagById,getTagList,getStoreSelectOptions} from "@/api/customer"; +import {getCustomerList,addCustomerTag,saveCustomerTagById,getTagList,getStoreSelectOptions,getCustomerInfo} from "@/api/customer"; import {addCustomerBlackByPC} from "@/api/customer-black.js" export default { @@ -135,6 +212,30 @@ }, data(){ return{ + customerInfo: { + birthday: null, + blackId: null, + clientEnum: null, + createTime: "", + customerTagList: [], + disabled: true, + experience: null, + face: "", + gradeId: null, + haveStore: false, + id: "", + lastLoginDate: "", + mobile: null, + nickName: "", + openId: null, + point: 10, + region: "", + regionId: "", + sex: 0, + storeId: null, + totalPoint: 0, + username: "" + }, loading: false, // 琛ㄥ崟鍔犺浇鐘舵�� //鏌ヨ瀹㈡埛鍒楄〃璇锋眰鍙傛暟 searchForm:{ @@ -225,8 +326,9 @@ selectCount: 0, // 宸查�夋暟閲� selectList: [], // 宸查�夋暟鎹垪琛� + //瀹㈡埛璇︽儏瀵硅瘽妗�--- + showCustomerInfo:false, //瀹㈡埛鏍囩瀵硅瘽妗�--- - showCustomerTag:false, submitLoading:false, selectLoading:false, @@ -301,6 +403,39 @@ this.selectList = e.map(d => d.id); this.selectCount = e.length; }, + //鏌ョ湅璇︽儏 + openInfo(row){ + this.showCustomerInfo = true; + this.modelTitle = "鐢ㄦ埛璇︽儏" + getCustomerInfo(row.id).then(res =>{ + if(res.code === 200){ + this.customerInfo = { + birthday: res.data.birthday || null, + blackId: res.data.blackId || null, + clientEnum: res.data.clientEnum || null, + createTime: res.data.createTime || '', + customerTagList: res.data.customerTagList || [], + disabled: res.data.disabled || false, + experience: res.data.experience || null, + face: res.data.face || '榛樿澶村儚URL', + gradeId: res.data.gradeId || null, + haveStore: res.data.haveStore || false, + id: res.data.id || '', + lastLoginDate: res.data.lastLoginDate || '', + mobile: res.data.mobile || null, + nickName: res.data.nickName || '寰俊鐢ㄦ埛', + openId: res.data.openId || null, + point: res.data.point || 0, + region: res.data.region || '', + regionId: res.data.regionId || '', + sex: res.data.sex || 0, + storeId: res.data.storeId || null, + totalPoint: res.data.totalPoint || 0, + username: res.data.username || '' + }; + } + }) + }, // 缂栬緫鏍囩 openEdit(row){ this.showCustomerTag = true @@ -360,6 +495,40 @@ </script> <style lang="scss" scoped> +.customer-detail { + padding: 16px; +} + +.avatar-section { + display: flex; + align-items: center; + margin-bottom: 16px; +} + +.basic-info { + margin-left: 16px; +} + +.basic-info h3 { + margin: 0 0 8px 0; + font-size: 18px; +} + +.basic-info p { + margin: 6px 0; + color: #808695; + font-size: 14px; +} + +.tags-section { + margin-top: 16px; + padding-top: 16px; +} + +.tags-section h4 { + margin-bottom: 12px; + color: #17233d; +} .export { margin: 10px 20px 10px 0; } diff --git a/manager/src/views/goods/goods-info/goods.vue b/manager/src/views/goods/goods-info/goods.vue index 7a5f7d3..7d1d4e4 100644 --- a/manager/src/views/goods/goods-info/goods.vue +++ b/manager/src/views/goods/goods-info/goods.vue @@ -89,9 +89,12 @@ <template slot="goodsSlot" slot-scope="{ row }"> <div style="margin: 5px 0px; height: 80px; display: flex"> <div style=""> - <img + <img v-if="row.original" :src="row.original" style="height: 60px; margin-top: 1px; width: 60px" + /> + <video v-else + :src="row.goodsVideo" style="height: 60px; margin-top: 1px; width: 60px" /> </div> @@ -159,6 +162,7 @@ <script> import { getGoodsListData, upGoods, lowGoods } from "@/api/goods"; +import {getSts} from '@/api/file' import vueQr from "vue-qr"; export default { components: { @@ -376,6 +380,18 @@ this.loading = false; if (res.success) { this.data = res.result.records; + getSts().then(res => { + const endpoint = res.data.endpoint + this.data.forEach(item => { + if (item.goodsVideo != null && item.goodsVideo.indexOf('http')===-1) { + item.goodsVideo = endpoint + '/' + item.goodsVideo; + } + if (item.original !=null && item.original.indexOf('http') ===-1) { + item.original = endpoint + '/' + item.original; + } + }) + }) + this.total = res.result.total; } }); diff --git a/manager/src/views/goods/goods-info/goodsApply.vue b/manager/src/views/goods/goods-info/goodsApply.vue index 30deb6a..8b8aa08 100644 --- a/manager/src/views/goods/goods-info/goodsApply.vue +++ b/manager/src/views/goods/goods-info/goodsApply.vue @@ -42,11 +42,13 @@ <!-- 鍟嗗搧鏍忕洰鏍煎紡鍖� --> <template slot="goodsSlot" slot-scope="scope"> <div style="margin-top: 5px; height: 80px; display: flex"> - <div style=""> - <img + <div style="" > + <img v-if="scope.row.original" :src="scope.row.original" style="height: 60px; margin-top: 3px; width: 60px" /> + <video v-else :src="scope.row.goodsVideo" style="height: 60px; margin-top: 3px; width: 60px" + /> </div> <div style="margin-left: 13px"> diff --git a/manager/src/views/goods/goods-info/goodsDetail.vue b/manager/src/views/goods/goods-info/goodsDetail.vue index 60d4c41..af66491 100644 --- a/manager/src/views/goods/goods-info/goodsDetail.vue +++ b/manager/src/views/goods/goods-info/goodsDetail.vue @@ -143,6 +143,7 @@ </template> <script> import { getGoodsDetail } from "@/api/goods"; +import {getSts} from '@/api/file' export default { name: "goodsDetail", data() { @@ -193,6 +194,26 @@ initGoods(id) { getGoodsDetail(id).then((res) => { this.goods = res.result; + if (this.goods.goodsVideo != null && this.goods.goodsVideo !== '') { + getSts().then(res => { + console.log('--------------->',this.goods.goodsVideo.indexOf('http')!== -1) + if (this.goods.goodsVideo !== null && this.goods.goodsVideo.indexOf('http')=== -1) { + this.goods.goodsVideo = res.data.endpoint+'/'+this.goods.goodsVideo; + } + }) + } + if (this.goods.goodsGalleryList != null && this.goods.goodsGalleryList.length > 0) { + getSts().then(res => { + this.goods.goodsGalleryList = this.goods.goodsGalleryList.map((item) => { + if (item !== null&&item.indexOf('http')===-1) { + return res.data.endpoint+'/'+item; + }else { + return item; + } + }) + }) + } + let that = this; res.result.skuList.forEach(function (sku, index, array) { that.skuData.push({ diff --git a/manager/src/views/health/HealthVideoList.vue b/manager/src/views/health/HealthVideoList.vue index 9c87653..43ef70c 100644 --- a/manager/src/views/health/HealthVideoList.vue +++ b/manager/src/views/health/HealthVideoList.vue @@ -112,6 +112,7 @@ <FormItem label="瑙嗛"> <video style="width: 150px;height: 150px" controls + @loadedmetadata="getVideoDuration" :poster="uploadVideoForm.showCoverUrl" :autoplay="false" id="remoteVideo" :src="uploadVideoForm.showVideoUrl" @@ -671,6 +672,10 @@ this.auditingLoading = false }) }, + getVideoDuration(e){ + const duration = this.$refs.healthVideoInfo.duration; + this.uploadVideoForm.videoDuration = Math.floor(duration); + }, // 鎵撳紑缂栬緫寮圭獥 deleteHealthVideo(row) { console.log('鍒犻櫎娴嬭瘯', row) diff --git a/manager/src/views/kitchen/kitchenVideo.vue b/manager/src/views/kitchen/kitchenVideo.vue index d3e945a..40e7079 100644 --- a/manager/src/views/kitchen/kitchenVideo.vue +++ b/manager/src/views/kitchen/kitchenVideo.vue @@ -112,6 +112,7 @@ <FormItem label="瑙嗛"> <video style="width: 150px;height: 150px" controls + @loadedmetadata="getVideoDuration" :poster="uploadVideoForm.showCoverUrl" :autoplay="false" id="remoteVideo" :src="uploadVideoForm.showVideoUrl" @@ -588,6 +589,10 @@ this.$set(this.uploadVideoForm, 'temp', new Date().getTime()); console.log(this.uploadVideoForm) }, + getVideoDuration(e){ + const duration = this.$refs.healthVideoInfo.duration; + this.uploadVideoForm.videoDuration = Math.floor(duration); + }, // 瑙嗛涓婃灦 videoUp(row) { this.$Modal.confirm({ diff --git a/manager/src/views/news/index.vue b/manager/src/views/news/index.vue new file mode 100644 index 0000000..e9d2d95 --- /dev/null +++ b/manager/src/views/news/index.vue @@ -0,0 +1,543 @@ +<template> + <div class="news-management"> + <Card> + <!-- 鎼滅储琛ㄥ崟 --> + <Form + ref="searchForm" + @keydown.enter.native="handleSearch" + :model="searchForm" + inline + :label-width="80" + class="search-form" + > + <FormItem label="鏍囬" prop="title"> + <Input + type="text" + v-model="searchForm.title" + placeholder="璇疯緭鍏ユ爣棰樺悕绉�" + clearable + @on-clear="handleSearch" + style="width: 180px" + /> + </FormItem> + <FormItem label="鏄惁鍙戝竷" prop="publish"> + <Select + v-model="searchForm.publish" + 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> + <Button @click="delBatch" type="error" icon="md-trash" :disabled="selectCount === 0">鎵归噺鍒犻櫎</Button> + </Row> + + <!-- 娲诲姩琛ㄦ牸 --> + <Table + :loading="loading" + border + :columns="columns" + :data="newsList" + ref="table" + @on-selection-change="showSelect" + class="news-table" + > + <!-- 灏侀潰灞曠ず鎻掓Ы --> + <!-- 鎿嶄綔鎸夐挳鎻掓Ы --> + <template slot-scope="{ row }" slot="action"> + <div class="action-btns"> + <Button + type="primary" + size="small" + @click="changeStatus(row, row.publish ? '涓嬫灦' : '鍙戝竷')" + :loading="row.statusLoading" + > + {{ row.publish ? '涓嬫灦' : '鍙戝竷' }} + </Button> + <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="800" + :mask-closable="false" + > + <Form ref="form" :model="newsForm" :label-width="100" :rules="rules"> + <Row :gutter="16"> + <Col span="12"> + <FormItem label="鏍囬" prop="title"> + <Input + v-model="newsForm.title" + placeholder="璇疯緭鍏ユ爣棰樺悕绉�" + clearable + /> + </FormItem> + </Col> + <Col span="24"> + <FormItem label="鏂伴椈鍐呭锛�" prop="content"> + <editor ref="editor" @input="getReason" /> + </FormItem> + </Col> + </Row> + </Form> + + <div slot="footer"> + <Button @click="modelClose">鍙栨秷</Button> + <Button type="primary" :loading="submitLoading" @click="saveOrUpdate">鎻愪氦</Button> + </div> + </Modal> + + + <Modal + v-model="infoModelShow" + :title="modelTitle" + @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>{{ newsInfo.title || '-' }}</span> + </div> + </Col> + <Col span="12"> + <div class="detail-item"> + <label>鏄惁鍙戝竷锛�</label> + <span>{{newsInfo.publish ? '宸插彂甯�':'鏈彂甯�'}}</span> + </div> + </Col> + + <Col span="12"> + <div class="detail-item" v-if="newsInfo.publish"> + <label>鍙戝竷鏃堕棿锛�</label> + <span>{{ newsInfo.publishDate}}</span> + </div> + </Col> + <Col span="24"> + <div class="detail-item"> + <label>鏂伴椈鍐呭锛�</label> + <div + class="news-content" + v-html="newsInfo.content || '鏃犲唴瀹�'" + ></div> + </div> + </Col> + </Row> + </div> + + <div slot="footer"> + <Button @click="infoModelClose">鍏抽棴</Button> + </div> + </Modal> + + + <!-- 鍥剧墖棰勮妯℃�佹 --> + <Modal v-model="previewVisible" title="鍥剧墖棰勮" footer-hide> + <img :src="previewImageUrl" style="width: 100%"> + </Modal> + </Card> + </div> +</template> +<script> +import Editor from '@/components/editor/index.vue' +import { getNews,editNews,addNews,publish,delById } from '@/api/news.js' +export default { + name: "newsManagement", + components: {Editor}, + data(){ + return{ + // 鍥剧墖棰勮 + previewVisible: false, + previewImageUrl: '', + + modelShow:false, + modelTitle:'', + submitLoading:false, + infoModelShow:false, + //琛ㄥご + columns: [ + { + type: 'selection', + width: 60, + align: 'center' + }, + { + title: '鏍囬', + key: 'title', + minWidth: 120, + tooltip: true + }, + { + title: '鍙戝竷', + key: 'publish', + width: 100, + align: 'center', + render: (h, params) => { + return h('Tag', { + props: { + color: params.row.publish ? 'green' : 'default' + } + }, params.row.publish ? '宸插彂甯�' : '鏈彂甯�') + } + }, + { + title: '鍙戝竷鏃堕棿', + key: 'publishDate', + width: 300, + align: 'center', + render: (h, { row }) => { + // 濡傛灉 publishDate 涓� null 鎴� undefined锛屾樉绀� "鏈彂甯�" + if (row.publishDate == null) { + return h('span', { style: { color: '#999' } }, '鏆傛棤'); + } + // 鍚﹀垯姝e父鏄剧ず鏃ユ湡 + return h('span', row.publishDate); + }, + }, + { + title: '鎿嶄綔', + slot: 'action', + width: 280, + align: 'center', + fixed: 'right' + } + ], + + newsList:[], + total:0, + newsForm:{ + id:'', + title:'', + content:'', + publish:0, + }, + newsInfo:{ + title:'', + publish:false, + publishDate:'', + content:'' + }, + rules: { + title: [ + { required: true, message: '璇疯緭鍏ユ爣棰�', trigger: 'blur' }, + { max: 50, message: '闀垮害涓嶈兘瓒呰繃50涓瓧绗�', trigger: 'blur' } + ], + publish: [ + { required: true, message: '璇烽�夋嫨鏄惁鍙戝竷', trigger: 'blur' }, + ], + content: [ + { required: true, message: '璇疯緭鍏ユ柊闂诲唴瀹�', trigger: 'blur' } + ] + }, + + selectList:[], + selectCount:0, + + loading:false, + + searchForm: { + title: '', + publish: 0, + pageNumber: 1, + pageSize: 10 + }, + typeSelect:[ + { + id:1, + label:'鏈彂甯�', + value:0 + }, + { + id:2, + label:'宸插彂甯�', + value:1 + } + + ] + } + }, + mounted() { + this.getNewsList(); + }, + methods:{ + getNewsList(){ + this.loading = true + getNews(this.searchForm).then(res =>{ + this.loading = false + if (res.code === 200) { + // 涓烘瘡涓�琛屾坊鍔爈oading鐘舵�� + this.newsList = res.data.map(item => ({ + ...item, + })) + this.total = res.total + } + }).catch(() => { + this.loading = false + }) + }, + getReason(content) { + this.newsForm.content = content + }, + saveOrUpdate(){ + this.$refs.form.validate(valid => { + if (valid) { + this.submitLoading = true + const submitData = { + ...this.newsForm, + publish: this.newsForm.publish !== 0, // true 鈫� 1, false 鈫� 0 + }; + if (this.newsForm.id){ + editNews(submitData).then(res => { + this.submitLoading = false + if (res.code === 200) { + this.$Message.success(res.msg) + this.modelClose() + this.getNewsList() + } + }).catch(() => { + this.submitLoading = false + }) + }else { + addNews(submitData).then(res => { + this.submitLoading = false + if (res.code === 200) { + this.$Message.success(res.msg) + this.modelClose() + this.getNewsList() + } + }).catch(() => { + this.submitLoading = false + }) + } + + } + }) + }, + infoModelClose(){ + this.infoModelShow = false; + }, + modelClose(){ + this.modelShow = false; + }, + changePage(page) { + this.searchForm.pageNumber = page + this.getNewsList() + }, + // 鏀瑰彉姣忛〉鏉℃暟 + changePageSize(pageSize) { + this.searchForm.pageNumber = 1 + this.searchForm.pageSize = pageSize + this.getNewsList() + }, + + delById(row){ + delById(row.id).then(res =>{ + if (res.code === 200){ + this.$Message.success(res.msg); + this.getNewsList(); + } + + }) + }, + openEdit(row){ + this.modelTitle = '淇敼鏂伴椈'; + this.modelShow = true; + this.$refs.form.resetFields(); + this.newsForm.title = row.title; + this.newsForm.content = row.content; + this.newsForm.id = row.id; + this.$refs.editor.setContent(this.newsForm.content) + }, + openAdd(){ + this.modelTitle = '鏂板鏂伴椈'; + this.modelShow = true; + this.$refs.form.resetFields() + this.newsForm.id = ''; + + }, + detail(row){ + this.modelTitle = '娲诲姩璇︽儏' + this.infoModelShow = true + this.newsInfo = row + }, + changeStatus(row,action){ + row.statusLoading = true; + + publish(row.id).then(res =>{ + row.statusLoading = false + if (res.code === 200){ + this.$Message.success(res.msg); + this.getNewsList(); + } + }).catch(() => { + row.statusLoading = false + }) + }, + // 琛ㄦ牸閫夋嫨鍙樺寲 + showSelect(selection) { + this.selectList = selection.map(item => item.id) + this.selectCount = selection.length + }, + + delBatch(){ + + }, + handleSearch(type, value){ + this.searchForm.pageNumber = 1 + this.getNewsList() + }, + resetSearch(){ + this.$refs.searchForm.resetFields() + this.searchForm.pageNumber = 1 + this.getNewsList() + }, + + } +} +</script> + +<style scoped lang="scss"> +.activity-management { + .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; + } + } +} +.detail-container { + padding: 16px; +} + +.detail-item { + margin-bottom: 18px; + line-height: 1.5; + + label { + display: inline-block; + width: 100px; + color: #666; + font-weight: bold; + vertical-align: top; + } + + span { + display: inline-block; + width: calc(100% - 110px); + } +} + +.news-content { + border: 1px solid #dcdee2; + border-radius: 4px; + padding: 12px; + min-height: 100px; + margin-top: 8px; +} +.news-table { + .media-container { + display: flex; + justify-content: center; + align-items: center; + height: 100px; + + .thumbnail { + max-width: 100%; + max-height: 100%; + 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> diff --git a/manager/src/views/order/order/orderDetail.vue b/manager/src/views/order/order/orderDetail.vue index dbf46b1..0007005 100644 --- a/manager/src/views/order/order/orderDetail.vue +++ b/manager/src/views/order/order/orderDetail.vue @@ -7,6 +7,7 @@ <Button v-if="allowOperation.editConsignee" @click="editAddress" type="primary" ghost>淇敼鏀惰揣鍦板潃</Button> <Button v-if="allowOperation.cancel" @click="orderCancel" type="warning" ghost>璁㈠崟鍙栨秷</Button> <Button v-if="orderInfo.order.orderStatus === 'UNPAID'" @click="confirmPrice" type="primary">鏀舵</Button> + <Button v-if="allowOperation.showLogistics || orderPackage.length > 0" @click="checkLogistics" type="primary">鏌ョ湅鐗╂祦</Button> <Button @click="orderLog" type="info" ghost>璁㈠崟鏃ュ織</Button> <Button @click="printOrder" type="primary" ghost style="float:right;" v-if="$route.query.orderType != 'VIRTUAL'">鎵撳嵃鍙戣揣鍗�</Button> @@ -310,6 +311,74 @@ <Button type="primary" @click="modifyPriceSubmit">璋冩暣</Button> </div> </Modal> + <!-- 鏌ヨ鐗╂祦 --> + <Modal v-model="logisticsModal" width="40"> + <p slot="header"> + <span>鏌ヨ鐗╂祦</span> + </p> + <div class="layui-layer-wrap"> + <dl> + <dt>璁㈠崟鍙凤細</dt> + <dd> + <div class="text-box">{{ sn }}</div> + </dd> + </dl> + </div> + <div v-if="packageTraceList.length > 0" v-for="(packageItem, packageIndex) in packageTraceList" :key="packageIndex"> + <div class="layui-layer-wrap"> + <dl> + <dt>鐗╂祦鍏徃锛�</dt> + <dd><div class="text-box">{{ packageItem.logisticsName }}</div></dd> + </dl> + <dl> + <dt>蹇�掑崟鍙凤細</dt> + <dd><div nctype="ordersSn" class="text-box">{{ packageItem.logisticsNo }}</div></dd> + </dl> + <div class="div-express-log"> + <ul class="express-log express-log-name"> + <li v-for="(item, index) in packageItem.orderPackageItemList" :key="index"> + <span class="time" style="width: 50%;"><span>鍟嗗搧鍚嶇О锛�</span><span>{{ item.goodsName }}</span></span> + <span class="time" style="width: 30%;"><span>鍙戣揣鏃堕棿锛�</span><span>{{ item.logisticsTime }}</span></span> + <span class="time" style="width: 20%;"><span>鍙戣揣鏁伴噺锛�</span><span>{{ item.deliverNumber }}</span></span> + </li> + </ul> + </div> + <div class="div-express-log"> + <ul class="express-log" v-if="packageItem.traces && packageItem.traces.traces"> + <li v-for="(item, index) in packageItem.traces.traces" :key="index"> + <span class="time">{{ item.AcceptTime || item.acceptTime }}</span> + <span class="detail">{{ item.AcceptStation || item.remark }}</span> + </li> + </ul> + <ul class="express-log" v-else><li>鏆傛棤鐗╂祦淇℃伅</li></ul> + </div> + </div> + </div> + <div v-if = "packageTraceList.length == 0 && logisticsInfo"> + <div class="layui-layer-wrap"> + <dl> + <dt>鐗╂祦鍏徃锛�</dt> + <dd><div class="text-box">{{ logisticsInfo.shipper }}</div></dd> + </dl> + <dl> + <dt>蹇�掑崟鍙凤細</dt> + <dd><div nctype="ordersSn" class="text-box">{{ logisticsInfo.logisticCode }}</div></dd> + </dl> + <div class="div-express-log"> + <ul class="express-log" v-if="logisticsInfo && logisticsInfo.traces"> + <li v-for="(item, index) in logisticsInfo.traces" :key="index"> + <span class="time">{{ item.AcceptTime }}</span> + <span class="detail">{{ item.AcceptStation }}</span> + </li> + </ul> + <ul class="express-log" v-else><li>鏆傛棤鐗╂祦淇℃伅</li></ul> + </div> + </div> + </div> + <div slot="footer" style="text-align: right"> + <Button @click="logisticsModal = false">鍙栨秷</Button> + </div> + </Modal> <!-- 璁㈠崟鍙栨秷妯℃�佹 --> <Modal v-model="orderCancelModal" width="530"> <p slot="header"> @@ -468,6 +537,12 @@ orderLogModal: false, //寮瑰嚭璋冩暣浠锋牸妗� checkedLogistics: [], //閫変腑鐨勭墿娴佸叕鍙搁泦鍚� allowOperation: {}, //璁㈠崟鍙墠鍋氶�夐」 + logisticsModal: false, //寮瑰嚭鏌ヨ鐗╂祦妗� + packageTraceList: [], + orderPackage: [], + logisticsInfo: { + shipper: "", + }, //鐗╂祦淇℃伅 sn: "", //璁㈠崟缂栧彿 orderInfo: { order: { @@ -645,7 +720,39 @@ gotoHomes () { return false }, - + getOrderPackage() { + API_Order.getPackage(this.sn).then(res => { + if (res.success) { + this.orderPackage = res.result; + console.log('this.orderPackage',this.orderPackage); + } + }) + }, + //鏌ヨ鐗╂祦 + checkLogistics () { + this.logisticsModal = true; + if (this.orderPackage.length > 0) { + this.logisticsList(); + } else { + this.logistics(); + } + }, + logisticsList () { + this.logisticsModal = true; + API_Order.getPackage(this.sn).then((res) => { + if (res.success && res.result != null) { + this.packageTraceList = res.result; + } + }); + }, + logistics () { + this.logisticsModal = true; + API_Order.getTraces(this.sn).then((res) => { + if (res.success && res.result != null) { + this.logisticsInfo = res.result; + } + }); + }, //纭鏀舵 confirmPrice () { this.$Modal.confirm({ @@ -805,6 +912,7 @@ mounted () { this.sn = this.$route.query.sn; this.getDataList(); + this.getOrderPackage(); }, }; </script> @@ -910,7 +1018,72 @@ } } } +.div-express-log { + max-height: 300px; + border: solid 1px #e7e7e7; + background: #fafafa; + overflow-y: auto; + overflow-x: auto; +} +.layui-layer-wrap { + dl { + border-top: solid 1px #f5f5f5; + margin-top: -1px; + overflow: hidden; + dt { + font-size: 14px; + line-height: 28px; + display: inline-block; + padding: 8px 1% 8px 0; + color: #999; + } + + dd { + font-size: 14px; + line-height: 28px; + display: inline-block; + padding: 8px 0 8px 8px; + border-left: solid 1px #f5f5f5; + + .text-box { + line-height: 40px; + color: #333; + word-break: break-all; + } + } + } +} +.express-log { + /*margin: 5px -10px 5px 5px;*/ + padding: 10px; + list-style-type: none; + + .time { + width: 30%; + display: inline-block; + float: left; + } + + .detail { + width: 60%; + margin-left: 30px; + display: inline-block; + } + + li { + line-height: 30px; + } +} + +.express-log-name { + li { + display: flex; + span { + display: flex; + } + } +} .f14 { font-size: 14px; color: #333; diff --git a/manager/src/views/tag/tag-type/index.vue b/manager/src/views/tag/tag-type/index.vue new file mode 100644 index 0000000..a97eba3 --- /dev/null +++ b/manager/src/views/tag/tag-type/index.vue @@ -0,0 +1,311 @@ +<template> + <div> + <Card> + <div class="operation mb_10"> + <Button @click="addParent" type="primary" icon="md-add">娣诲姞涓�绾у垎绫�</Button> + </div> + <tree-table ref="treeTable" size="default" :loading="loading" :data="tableData" :columns="columns" + :border="true" :show-index="false" :is-fold="true" :expand-type="false" primary-key="id"> + <template slot="action" slot-scope="scope"> + <Button type="info" @click="edit(scope.row)" size="small" style="margin-right: 5px">缂栬緫 + </Button> + + <Button type="error" @click="remove(scope.row)" size="small" style="margin-right: 5px">鍒犻櫎 + </Button> + <Button v-show="scope.row.level != 1" type="success" @click="addChildren(scope.row)" size="small" + style="margin-right: 5px">娣诲姞瀛愬垎绫� + </Button> + </template> + </tree-table> + </Card> + <Modal :title="modalTitle" v-model="modalVisible" :mask-closable="false" :width="500"> + <Form ref="formAdd" :model="formAdd" :label-width="100" :rules="formValidate"> + <div v-if="showParent"> + <FormItem label="涓婄骇鍒嗙被" prop="parentId"> + {{ parentTitle }} + <Input v-model="formAdd.parentId" clearable style="width: 100%; display: none" /> + </FormItem> + </div> + <FormItem label="鍒嗙被鍚嶇О" prop="tagTypeName"> + <Input v-model="formAdd.tagTypeName" clearable style="width: 100%" /> + </FormItem> + <FormItem label="鍒嗙被鏍囪瘑" prop="typeKey"> + + <Select v-model="formAdd.typeKey" :disabled="formAdd.parentId!==0" placeholder="璇烽�夋嫨鍒嗙被鏍囪瘑" filterable :popper-append-to-body="false" + popper-class="spec-values-popper" style="width: 100%; text-align: left; margin-right: 10px"> + <Option v-for="item in typeKeyList" :value="item.value" :label="item.value" :key="item.value"> + </Option> + </Select> + </FormItem> + <FormItem label="鎺掑簭鍊�" prop="sortNum"> + <InputNumber v-model="formAdd.sortNum"></InputNumber> + </FormItem> + </Form> + <div slot="footer"> + <Button type="text" @click="modalVisible = false">鍙栨秷</Button> + <Button type="primary" :loading="submitLoading" @click="Submit">鎻愪氦</Button> + </div> + </Modal> + </div> +</template> +<script> +import { + saveTagType, + getTagTypeList , + deleteTagTypeById, + updateTagType,getTagKeyTypeList +} from "@/api/tag-type"; +import TreeTable from "@/components/tree-table/Table/Table"; +import uploadPicInput from "@/components/lili/upload-pic-input"; +import { regular } from "@/utils"; +export default { + name: "lili-components", + components: { + TreeTable, + uploadPicInput, + }, + data() { + return { + submitLoading: false, + loading: false, // 鍔犺浇鐘舵�� + expandLevel: 1, // 灞曞紑鐨勫眰绾� + modalType: 0, // 娣诲姞鎴栫紪杈戞爣璇� + modalVisible: false, // 娣诲姞鎴栫紪杈戞樉绀� + modalTitle: "", // 娣诲姞鎴栫紪杈戞爣棰� + showParent: false, // 鏄惁灞曠ず涓婄骇鑿滃崟 + parentTitle: "", // 鐖剁骇鑿滃崟鍚嶇О + formAdd: { + // 娣诲姞鎴栫紪杈戣〃鍗曞璞″垵濮嬪寲鏁版嵁 + parentId: "", + sortNum: 1, + level: 0, + tagTypeName: "", + typeKey:'' + }, + // 琛ㄥ崟楠岃瘉瑙勫垯 + formValidate: { + tagTypeName: [regular.REQUIRED], + typeKey: [regular.REQUIRED], + sortNum: [regular.REQUIRED, regular.INTEGER], + }, + columns: [ + { + title: "鍒嗙被鍚嶇О", + key: "tagTypeName", + witt: "100px", + }, + { + title: "鍒嗙被鏍囪瘑", + key: "typeKey", + witt: "100px", + }, + { + title: "鎺掑簭", + key: "sortNum", + width: "100px", + }, + { + title: "鎿嶄綔", + key: "action", + align: "center", + headerAlign: "center", + width: "400px", + type: "template", + template: "action", + }, + ], + typeKeyList: [], + tableData: [], // 琛ㄦ牸鏁版嵁 + }; + }, + methods: { + // 鍒濆鍖栨暟鎹� + init() { + this.getAllList(); + this.getKeyTypeList(); + }, + getKeyTypeList() { + getTagKeyTypeList().then((res) => { + this.typeKeyList = res.data + }) + }, + // 娣诲姞瀛愬垎绫� + addChildren(v) { + this.modalType = 0; + this.modalTitle = "娣诲姞瀛愬垎绫�"; + this.formAdd.tagTypeName = ""; + this.parentTitle = v.tagTypeName; + this.formAdd.typeKey = v.typeKey; + this.typeKeyEdit = false + this.formAdd.level = eval(v.level + "+1"); + this.showParent = true; + delete this.formAdd.id; + this.formAdd.parentId = v.id; + this.modalVisible = true; + }, + // 缂栬緫鍒嗙被 + edit(v) { + this.modalType = 1; + this.modalTitle = "缂栬緫"; + this.formAdd.id = v.id; + this.formAdd.tagTypeName = v.tagTypeName; + this.formAdd.level = v.level; + this.formAdd.parentId = v.parentId; + this.formAdd.sortNum = v.sortNum; + this.showParent = false; + this.modalVisible = true; + }, + // 娣诲姞涓�绾у垎绫� + addParent() { + this.modalType = 0; + this.modalTitle = "娣诲姞涓�绾у垎绫�"; + this.parentTitle = "椤剁骇鍒嗙被"; + this.showParent = true; + this.$refs.formAdd.resetFields(); + delete this.formAdd.id; + this.formAdd.parentId = 0; + this.modalVisible = true; + }, + // 鎻愪氦 + Submit() { + this.$refs.formAdd.validate((valid) => { + if (valid) { + this.submitLoading = true; + if (this.modalType === 0) { + // 娣诲姞 閬垮厤缂栬緫鍚庝紶鍏d绛夋暟鎹� 璁板緱鍒犻櫎 + delete this.formAdd.id; + saveTagType(this.formAdd).then((res) => { + this.submitLoading = false; + if (res.success) { + this.$Message.success("娣诲姞鎴愬姛"); + + this.formAdd = { + // 娣诲姞鎴栫紪杈戣〃鍗曞璞″垵濮嬪寲鏁版嵁 + parentId: "", + sortNum: 1, + level: 0, + tagTypeName: "", + }; + } else { + // this.$Message.error(res.message); + } + this.getAllList(); + this.modalVisible = false; + }); + } else { + // 缂栬緫 + updateTagType(this.formAdd, this.formAdd.id).then((res) => { + this.submitLoading = false; + if (res.success) { + this.$Message.success("淇敼鎴愬姛"); + } else { + // this.$Message.error(res.message); + } + this.getAllList(); + this.modalVisible = false; + this.$refs.formAdd.resetFields(); + }); + } + } + }); + }, + // 鍒犻櫎鍒嗙被 + remove(v) { + this.$Modal.confirm({ + title: "纭鍒犻櫎", + content: "鎮ㄧ‘璁よ鍒犻櫎 " + v.tagTypeName + " ?", + loading: true, + onOk: () => { + // 鍒犻櫎 + deleteTagTypeById(v.id).then((res) => { + this.$Modal.remove(); + if (res.code===200) { + this.$Message.success("鎿嶄綔鎴愬姛"); + this.getAllList(); + } + }); + }, + }); + }, + // 鑾峰彇鍒嗙被鏁版嵁 + getAllList(newval) { + this.loading = true; + getTagTypeList().then((res) => { + this.loading = false; + if (res.code===200) { + // 浠呭睍寮�鎸囧畾绾ф暟 榛樿鍚庡彴宸插睍寮�鎵�鏈� + let expandLevel = this.expandLevel; + res.data.forEach(function (e) { + if (expandLevel == 1) { + if (e.level == 0) { + e.expand = false; + } + if (e.children && e.children.length > 0) { + e.children.forEach(function (c) { + if (c.level == 1) { + c.expand = false; + } + if (c.children && c.children.length > 0) { + c.children.forEach(function (b) { + if (b.level == 2) { + b.expand = false; + } + }); + } + }); + } + } else if (expandLevel == 2) { + if (e.level == 0) { + e.expand = true; + } + if (e.children && e.children.length > 0) { + e.children.forEach(function (c) { + if (c.level == 1) { + c.expand = false; + } + if (c.children && c.children.length > 0) { + c.children.forEach(function (b) { + if (b.level == 2) { + b.expand = false; + } + }); + } + }); + } + } else if (expandLevel == 3) { + if (e.level == 0) { + e.expand = true; + } + if (e.children && e.children.length > 0) { + e.children.forEach(function (c) { + if (c.level == 1) { + c.expand = true; + } + if (c.children && c.children.length > 0) { + c.children.forEach(function (b) { + if (b.level == 2) { + b.expand = false; + } + }); + } + }); + } + } + }); + this.tableData = res.data; + } + }); + }, + }, + mounted() { + this.init(); + }, +}; +</script> +<style lang="scss" scoped> +.article { + font-size: 16px; + font-weight: 400; + margin: 12px 0; +} +</style> diff --git a/manager/src/views/tag/tag/index.vue b/manager/src/views/tag/tag/index.vue new file mode 100644 index 0000000..51c9c9d --- /dev/null +++ b/manager/src/views/tag/tag/index.vue @@ -0,0 +1,403 @@ +<template> + <div class="wrapper"> + <Row> + <Col span="4"> + <Card style="height: 100%;" class="article-category mr_10"> + <Tree :data="treeData" @on-select-change="handleCateChange"></Tree> + </Card> + </Col> + <Col span="20"> + <Card class="article-detail"> + <Row @keydown.enter.native="handleSearch"> + <Form ref="searchForm" :model="searchForm" inline :label-width="70" style="width: 100%" class="search-form"> + <Form-item label="鏍囩鍚嶇О" prop="tagName"> + <Input type="text" v-model="searchForm.tagName" placeholder="璇疯緭鍏ユ爣绛惧悕绉�" clearable style="width: 200px" /> + </Form-item> + <Button @click="handleSearch" type="primary" icon="ios-search" class="search-btn">鎼滅储</Button> + </Form> + </Row> + <Row class="operation padding-row"> + <Button @click="add" v-if="!selected" type="primary">娣诲姞</Button> + </Row> + <Table :loading="loading" border :columns="columns" :data="data" style="height: calc(100vh - 328px);" + ref="table"> + <!-- 椤甸潰灞曠ず --> + <template slot="openStatusSlot" slot-scope="scope"> + <div></div> + <i-switch size="large" v-model="scope.row.openStatus" @on-change="changeSwitch(scope.row)"> + <span slot="open">灞曠ず</span> + <span slot="close">闅愯棌</span> + </i-switch> + </template> + </Table> + <Row type="flex" justify="end" class="mt_10"> + <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> + </Page> + </Row> + </Card> + </Col> + </Row> + <template v-if="!selected"> + <Modal :tagName="modalTitle" v-model="modalVisible" :mask-closable="false" :width="1100"> + <Form ref="form" :model="form" :label-width="100"> + <FormItem label="鏍囩鍚嶇О" prop="tagName"> + <Input v-model="form.tagName" clearable style="width: 40%" /> + </FormItem> + <FormItem label="鏍囩鍒嗙被" prop="tagTypeId"> + <Select v-model="treeValue" placeholder="璇烽�夋嫨" clearable style="width: 180px"> + <Option v-if="treeValue" :value="treeValue" style="display: none">{{ treeValue }} + </Option> + <Tree :data="treeDataDefault" @on-select-change="handleCheckChange"></Tree> + </Select> + </FormItem> + <FormItem label="鎺掑簭" prop="sortNum"> + <Input type="number" v-model="form.sortNum" clearable style="width: 10%" /> + </FormItem> + </Form> + <div slot="footer"> + <Button type="text" @click="modalVisible = false">鍙栨秷</Button> + <Button type="primary" :loading="submitLoading" @click="handleSubmit">鎻愪氦</Button> + </div> + </Modal> + </template> + </div> +</template> + +<script> +import { getTagTypeList } from "@/api/tag-type"; +import { getTags, deleteTagById, editTag, addTag } from "@/api/tag"; +import tinymec from "@/components/editor/index.vue"; +export default { + components: { + tinymec: tinymec, + }, + props: { + selected: { + type: Boolean, + default: false, + }, + }, + data() { + return { + selectedIndex: 99999, // 宸查�変笅鏍� + loading: true, // 琛ㄥ崟鍔犺浇鐘舵�� + modalType: 0, // 娣诲姞鎴栫紪杈戞爣璇� + modalVisible: false, // 娣诲姞鎴栫紪杈戞樉绀� + modalTitle: "", // 娣诲姞鎴栫紪杈戞爣棰� + treeDataDefault: [], + searchForm: { + // 鎼滅储妗嗗垵濮嬪寲瀵硅薄 + pageNumber: 1, // 褰撳墠椤垫暟 + pageSize: 10, // 椤甸潰澶у皬 + sortNum: "createTime", // 榛樿鎺掑簭瀛楁 + order: "desc", // 榛樿鎺掑簭鏂瑰紡 + tagTypeId: "", + }, + searchTreeValue: "", // 鍒囨崲 + form: { + // 娣诲姞鎴栫紪杈戣〃鍗曞璞″垵濮嬪寲鏁版嵁 + tagName: "", + tagTypeId: "", + sortNum: 1, + id: "", + }, + list: [], // 鍒楄〃 + treeValue: "", // 閫夋嫨鐨勫垎绫� + //鏍戠粨鏋� + treeData: [], + submitLoading: false, // 娣诲姞鎴栫紪杈戞彁浜ょ姸鎬� + columns: [ + // 琛ㄥご + { + title: "鍒嗙被鍚嶇О", + key: "tagTypeName", + width: 150, + }, + { + title: "鏍囩鍚嶇О", + key: "tagName", + minWidth: 200, + tooltip: true, + }, + { + title: "鎺掑簭", + key: "sortNum", + width: 100, + }, + { + title: "鎿嶄綔", + key: "action", + align: "center", + + width: 230, + render: (h, params) => { + return h("div", [ + h( + "Button", + { + props: { + size: "small", + type: + this.selectedIndex == params.index + ? "primary" + : "default", + }, + style: { + marginRight: "5px", + display: this.selected ? "" : "none", + }, + on: { + click: () => { + this.selectedIndex = params.index; + this.$emit("callbacked", params.row); + }, + }, + }, + this.selectedIndex == params.index ? "宸查��" : "閫夋嫨" + ), + h( + "Button", + { + props: { + size: "small", + type: "info", + }, + style: { + marginRight: "5px", + }, + on: { + click: () => { + this.edit(params.row); + }, + }, + }, + "缂栬緫" + ), + h( + "Button", + { + props: { + type: "error", + size: "small", + }, + on: { + click: () => { + this.remove(params.row); + }, + }, + }, + "鍒犻櫎" + ), + ]); + }, + }, + ], + data: [], // 琛ㄥ崟鏁版嵁 + total: 0, // 琛ㄥ崟鏁版嵁鎬绘暟 + }; + }, + watch: { + "searchForm.tagTypeId": { + handler() { + this.handleSearch(); + }, + deep: true, + }, + "searchForm.tagName": { + handler() { + this.handleSearch(); + }, + deep: true, + }, + }, + methods: { + // 鍒濆鍖栨暟鎹� + init() { + this.getDataList(); + this.getAllList(0); + }, + // 閫夋嫨鍒嗙被鍥炶皟 + handleCateChange(data) { + let { value, title } = data[0]; + this.list.push({ + value, + title, + }); + this.searchForm.tagTypeId = value; + this.searchTreeValue = title; + this.getDataList() + }, + // 鏍囩鍒嗙被鐨勯�夋嫨浜嬩欢 + handleCheckChange(data) { + let value = ""; + let title = ""; + this.list = []; + data.forEach((item, index) => { + value += `${item.value},`; + title += `${item.title},`; + }); + value = value.substring(0, value.length - 1); + title = title.substring(0, title.length - 1); + this.list.push({ + value, + title, + }); + this.form.tagTypeId = value; + this.treeValue = title; + }, + // 鏀瑰彉椤垫暟 + changePage(v) { + this.searchForm.pageNumber = v; + this.getDataList(); + }, + // 鏀瑰彉椤电爜 + changePageSize(v) { + this.selected.pageNumber = 1; + this.searchForm.pageSize = v; + this.getDataList(); + }, + // 鎼滅储鍒楄〃 + handleSearch() { + this.searchForm.pageNumber = 1; + this.searchForm.pageSize = 10; + this.getDataList(); + }, + // 鑾峰彇鍏ㄩ儴鏍囩鍒嗙被 + getAllList(parent_id) { + this.loading = true; + getTagTypeList(parent_id).then((res) => { + this.loading = false; + if (res.code == 200) { + this.treeData = this.getTree(res.data); + this.treeDataDefault = this.getTree(res.data); + this.treeData.unshift({ + title: "鍏ㄩ儴", + level: 0, + children: [], + id: "0", + tagTypeId: 0, + }); + } + }); + }, + // 鏍囩鍒嗙被鏍煎紡鍖栨柟娉� + getTree(tree = []) { + let arr = []; + if (!!tree && tree.length !== 0) { + tree.forEach((item) => { + let obj = {}; + obj.title = item.tagTypeName; + obj.value = item.id; + obj.attr = item.tagTypeName; // 鍏朵粬浣犳兂瑕佹坊鍔犵殑灞炴�� + obj.expand = false; + obj.selected = false; + obj.children = this.getTree(item.children); // 閫掑綊璋冪敤 + arr.push(obj); + }); + } + return arr; + }, + // 鑾峰彇鏍囩鍒楄〃 + getDataList(val) { + if (val) this.form = {}; + this.loading = true; + getTags(this.searchForm).then((res) => { + this.loading = false; + if (res.code === 200) { + this.total = res.total; + //涓轰簡鍦ㄦ槸鍚﹀睍绀轰竴鍒楀睍绀哄紑鍏� 闇�瑕佹敼涓�涓嬫暟鎹被鍨嬶紝鏈�缁堟彁浜ゅ啀娆℃洿鏀� + this.data = []; + if (res.data.length > 0) { + this.data = res.data; + } + } + }); + this.total = this.data?.length; + this.loading = false; + }, + // 娣诲姞鏍囩 + handleSubmit() { + this.$refs.form.validate((valid) => { + if (valid) { + this.submitLoading = true; + if (this.modalType === 0) { + // 娣诲姞 閬垮厤缂栬緫鍚庝紶鍏d绛夋暟鎹� 璁板緱鍒犻櫎 + delete this.form.id; + addTag(this.form).then((res) => { + this.submitLoading = false; + if (res.code === 200) { + this.$Message.success("鎿嶄綔鎴愬姛"); + this.getDataList(); + this.modalVisible = false; + } + }); + } else { + // 缂栬緫 + editTag(this.form).then((res) => { + this.submitLoading = false; + if (res.code === 200) { + this.$Message.success("鎿嶄綔鎴愬姛"); + this.getDataList(); + this.modalVisible = false; + } + }); + } + } + }); + }, + // 娣诲姞鏍囩modal + add() { + this.modalType = 0; + this.modalTitle = "娣诲姞鏍囩"; + this.treeValue = ""; + + this.form = { + sortNum: 1, + tagName: "", + }; + this.$refs.form.resetFields(); + delete this.form.id; + this.modalVisible = true; + }, + // 缂栬緫鏍囩modal + edit(data) { + this.modalType = 1; + this.modalTitle = "缂栬緫鏍囩"; + this.treeValue = ""; + this.form = { + tagName: "", + }; + this.$refs.form.resetFields(); + + this.modalVisible = true; + this.form.tagTypeId = data.tagTypeId; + this.treeValue = data.tagTypeName; + this.form.id = data.id; + this.form.tagName = data.tagName; + this.form.sortNum = data.sortNum; + }, + // 鍒犻櫎鏍囩 + remove(v) { + this.$Modal.confirm({ + tagName: "纭鍒犻櫎", + content: "鎮ㄧ‘璁よ鍒犻櫎涔�?", + loading: true, + onOk: () => { + // 鍒犻櫎 + deleteTagById(v.id).then((res) => { + this.$Modal.remove(); + if (res.code === 200) { + this.$Message.success("鎿嶄綔鎴愬姛"); + this.getDataList(); + } + }); + }, + }); + }, + }, + mounted() { + this.init(); + }, +}; +</script> diff --git a/seller/package.json b/seller/package.json index 23f4baf..fe2ac56 100644 --- a/seller/package.json +++ b/seller/package.json @@ -13,6 +13,7 @@ "@amap/amap-jsapi-loader": "0.0.7", "@antv/g2": "^4.1.14", "axios": "^0.21.1", + "cos-js-sdk-v5": "^1.10.1", "dplayer": "^1.27.1", "js-cookie": "^2.2.1", "node-sass": "^4.14.1", diff --git a/seller/src/api/file.js b/seller/src/api/file.js new file mode 100644 index 0000000..8c1bee0 --- /dev/null +++ b/seller/src/api/file.js @@ -0,0 +1,31 @@ +import service, { + getRequest, + postRequest, + putRequest, + deleteRequest, + importRequest, + getRequestWithNoToken, + commonUrl, + postRequestWithNoForm +} from "@/libs/axios"; + + +// 鑾峰彇鏂囦欢涓存椂璁块棶url +export const getFilePreview = (fileKey) => { + return service({ + baseURL: commonUrl, + url: "/common/lmk/file/preview", + method: "POST", + data: {"fileKey": fileKey} + }) +} + +// 鑾峰彇STS璁块棶浠ょ墝 +export const getSts = () => { + return service({ + baseURL: commonUrl, + url: "/common/lmk/file/sts", + method: "GET" + }) +} + diff --git a/seller/src/libs/axios.js b/seller/src/libs/axios.js index a61bcf6..768708e 100644 --- a/seller/src/libs/axios.js +++ b/seller/src/libs/axios.js @@ -353,7 +353,8 @@ } }); }; - +// 鍘熷鐨刟xios鏆撮湶鍑哄幓鐢ㄥ嵆鍙� +export default service export const uploadFileRequest = (url, params) => { let accessToken = getStore("accessToken"); return service({ diff --git a/seller/src/utils/file.js b/seller/src/utils/file.js new file mode 100644 index 0000000..74cfa34 --- /dev/null +++ b/seller/src/utils/file.js @@ -0,0 +1,40 @@ + +/** + * 鐢熸垚fileKey + * + * @param fileName 鏂囦欢鍚� + * @returns {*} + */ +export function getFileKey (fileName) { + const extension = fileName.split('.').pop().toLowerCase(); + + const fileTypes = { + image: { name: '鍥剧墖', exts: ["jpg", "png", "jpeg", "gif", "bmp", "webp", "tiff", "svg", "ico", "psd", "raw"] }, + video: { name: '瑙嗛', exts: ["mp4", "avi", "rmvb", "mov", "wmv", "flv", "mkv", "mpeg", "mpg", "m4v", "3gp", "webm", "vob", "swf"] }, + radio: { name: '闊抽', exts: ["mp3", "wma", "wav", "mpeg-4", "cd", "m4a", "aac", "flac", "ogg", "aiff", "ape", "midi", "amr", "ra"] }, + text: { name: '鏂囨湰', exts: ["txt", "xls", "xlsx", "doc", "docx", "pdf", "ppt", "pptx", "csv", "rtf", "odt", "ods", "odp", "epub", "mobi", "pages", "numbers", "key"] }, + zip: { name: '鍘嬬缉鏂囦欢', exts: ["zip", "rar", "7z", "tar", "gz", "bz2", "xz", "iso", "dmg", "pkg", "cab", "z", "lz", "lzma", "lzo"] } + }; + + // 鑾峰彇褰撳墠鏃堕棿骞舵牸寮忓寲涓� yyyyMMddHHmmss + const now = new Date(); + const yyyyMMddHHmmss = [ + now.getFullYear(), + String(now.getMonth() + 1).padStart(2, '0'), + String(now.getDate()).padStart(2, '0'), + String(now.getHours()).padStart(2, '0'), + String(now.getMinutes()).padStart(2, '0'), + String(now.getSeconds()).padStart(2, '0') + ].join(''); + + // 鐢熸垚5浣嶉殢鏈烘暟瀛� + const random5Digits = Math.floor(10000 + Math.random() * 90000); + + // 鏌ユ壘鍖归厤鐨勬枃浠剁被鍨� + for (const [type, data] of Object.entries(fileTypes)) { + if (data.exts.includes(extension)) { + return `${type}/${yyyyMMddHHmmss}${random5Digits}` + '.' + extension; + } + } + return ''; +} diff --git a/seller/src/views/goods/goods-seller/goods.vue b/seller/src/views/goods/goods-seller/goods.vue index ed68fda..e4efb96 100644 --- a/seller/src/views/goods/goods-seller/goods.vue +++ b/seller/src/views/goods/goods-seller/goods.vue @@ -95,10 +95,11 @@ <template slot="goodsSlot" slot-scope="{ row }"> <div style="margin-top: 5px; height: 90px; display: flex"> <div style=""> - <img + <img v-if="row.original" :src="row.original" style="height: 80px; margin-top: 3px; width: 70px" /> + <video :src="row.goodsVideo" v-else style="height: 80px; margin-top: 3px; width: 70px"></video> </div> <div style="margin-left: 13px"> diff --git a/seller/src/views/goods/goods-seller/goodsOperation.vue b/seller/src/views/goods/goods-seller/goodsOperation.vue index 77c41ec..d689a13 100644 --- a/seller/src/views/goods/goods-seller/goodsOperation.vue +++ b/seller/src/views/goods/goods-seller/goodsOperation.vue @@ -13,8 +13,8 @@ <second-step ref='second' :firstData="firstData" v-if="activestep === 1"></second-step> <!-- 绗笁姝� 鍙戝竷瀹屾垚 --> <third-step ref='third' v-if="activestep === 2"></third-step> - - + + </div> </template> <script> @@ -51,7 +51,7 @@ this.activestep = 0 this.$refs.first.selectGoodsType = true; } - + } }; </script> diff --git a/seller/src/views/goods/goods-seller/goodsOperationFirst.vue b/seller/src/views/goods/goods-seller/goodsOperationFirst.vue index 47af408..db69887 100644 --- a/seller/src/views/goods/goods-seller/goodsOperationFirst.vue +++ b/seller/src/views/goods/goods-seller/goodsOperationFirst.vue @@ -109,19 +109,19 @@ type: "PHYSICAL_GOODS", check: false, }, - { - title: "铏氭嫙鍟嗗搧", - img: require("@/assets/goodsType2.png"), - desc: "铏氭嫙鏍搁獙锛屾棤闇�鐗╂祦", - type: "VIRTUAL_GOODS", - check: false, - }, - { - title: "鍟嗗搧妯℃澘瀵煎叆", - img: require("@/assets/goodsTypeTpl.png"), - desc: "鍟嗗搧妯℃澘锛屼竴閿鍏�", - check: false, - }, + // { + // title: "铏氭嫙鍟嗗搧", + // img: require("@/assets/goodsType2.png"), + // desc: "铏氭嫙鏍搁獙锛屾棤闇�鐗╂祦", + // type: "VIRTUAL_GOODS", + // check: false, + // }, + // { + // title: "鍟嗗搧妯℃澘瀵煎叆", + // img: require("@/assets/goodsTypeTpl.png"), + // desc: "鍟嗗搧妯℃澘锛屼竴閿鍏�", + // check: false, + // }, ], // 鍟嗗搧鍒嗙被閫夋嫨鏁扮粍 category: [ @@ -130,7 +130,8 @@ { name: "", id: "" }, ], // 鍟嗗搧绫诲瀷 - goodsType: "", + // goodsType: "", + goodsType: "PHYSICAL_GOODS", /** 1绾у垎绫诲垪琛�*/ categoryListLevel1: [], /** 2绾у垎绫诲垪琛�*/ @@ -230,10 +231,13 @@ if (!this.category[0].name) { this.$Message.error("璇烽�夋嫨鍟嗗搧鍒嗙被"); return; - } else if (!this.category[2].name) { - this.$Message.error("蹇呴』閫夋嫨鍒颁笁绾у垎绫�"); - return; - } else if (this.category[2].name) { + } + //鍏抽棴蹇呴』閫夋嫨3涓祦绋嬬殑閫夐」 + // else if (!this.category[2].name) { + // this.$Message.error("蹇呴』閫夋嫨鍒颁笁绾у垎绫�"); + // return; + // } + else if (this.category[2].name) { let params = { category: this.category, goodsType: this.goodsType, @@ -245,6 +249,14 @@ this.$emit("change", params); } } + //娴佺▼璋冩暣 + else { + let params = { + category: this.category, + goodsType: this.goodsType, + }; + this.$emit("change", params); + } }, }, mounted() { diff --git a/seller/src/views/goods/goods-seller/goodsOperationSec.vue b/seller/src/views/goods/goods-seller/goodsOperationSec.vue index 0965954..dbbdb51 100644 --- a/seller/src/views/goods/goods-seller/goodsOperationSec.vue +++ b/seller/src/views/goods/goods-seller/goodsOperationSec.vue @@ -26,13 +26,13 @@ <FormItem label="鍟嗗搧鍗栫偣" prop="sellingPoint"> <Input v-model="baseInfoForm.sellingPoint" :rows="4" style="width: 260px" type="textarea"/> </FormItem> - <FormItem label="鍟嗗搧鍝佺墝" prop="brandId"> - <Select v-model="baseInfoForm.brandId" filterable style="width: 200px"> - <Option v-for="item in brandList" :key="item.id" :label="item.name" :value="item.id"></Option> - </Select> - <Button class="refresh-icon" icon="md-refresh" shape="circle" type="text" - @click="refresh('brand')"></Button> - </FormItem> +<!-- <FormItem label="鍟嗗搧鍝佺墝" prop="brandId">--> +<!-- <Select v-model="baseInfoForm.brandId" filterable style="width: 200px">--> +<!-- <Option v-for="item in brandList" :key="item.id" :label="item.name" :value="item.id"></Option>--> +<!-- </Select>--> +<!-- <Button class="refresh-icon" icon="md-refresh" shape="circle" type="text"--> +<!-- @click="refresh('brand')"></Button>--> +<!-- </FormItem>--> </div> <h4>鍟嗗搧浜ゆ槗淇℃伅</h4> <div class="form-item-view"> @@ -101,10 +101,10 @@ </div> <h4>鍟嗗搧瑙勬牸鍙婂浘鐗�</h4> <div class="form-item-view"> - <FormItem class="form-item-view-el required" label="涓诲浘" prop="goodsGalleryFiles"> + <FormItem class="form-item-view-el required" label="涓诲浘" prop="goodsGalleryFiles" > <div style="display: flex; flex-wrap: wrap;"> - <vuedraggable :animation="200" :list="baseInfoForm.goodsGalleryFiles"> - <div v-for="(item, __index) in baseInfoForm.goodsGalleryFiles" :key="__index" + <vuedraggable :animation="200" :list="showListImages"> + <div v-for="(item, __index) in showListImages" :key="__index" class="demo-upload-list"> <template> <img :src="item"/> @@ -118,17 +118,17 @@ </div> </vuedraggable> <!--<Upload ref="upload"--> - <!--:action="uploadFileUrl" :before-upload="handleBeforeUploadGoodsPicture"--> - <!--:format="['jpg', 'jpeg', 'png', 'webp']"--> - <!--:headers="{ ...accessToken }"--> - <!--:max-size="2048" :on-error="() => { $Spin.hide(); }" :on-exceeded-size="handleMaxSize"--> - <!--:on-format-error="handleFormatError" :on-progress="() => { $Spin.show(); }"--> - <!--:on-success="handleSuccessGoodsPicture" :show-upload-list="false" multiple--> - <!--style="margin-left: 10px"--> - <!--type="drag">--> - <!--<div style="width: 148px; height: 148px; line-height: 148px">--> - <!--<Icon size="20" type="md-add"></Icon>--> - <!--</div>--> + <!--:action="uploadFileUrl" :before-upload="handleBeforeUploadGoodsPicture"--> + <!--:format="['jpg', 'jpeg', 'png', 'webp']"--> + <!--:headers="{ ...accessToken }"--> + <!--:max-size="2048" :on-error="() => { $Spin.hide(); }" :on-exceeded-size="handleMaxSize"--> + <!--:on-format-error="handleFormatError" :on-progress="() => { $Spin.show(); }"--> + <!--:on-success="handleSuccessGoodsPicture" :show-upload-list="false" multiple--> + <!--style="margin-left: 10px"--> + <!--type="drag">--> + <!--<div style="width: 148px; height: 148px; line-height: 148px">--> + <!--<Icon size="20" type="md-add"></Icon>--> + <!--</div>--> <!--</Upload>--> </div> <div style="width: 100%;display: flex;justify-content: start;margin-top: 10px;"> @@ -139,22 +139,33 @@ </Modal> </FormItem> <FormItem> - <div style="color: grey">涓诲浘浠呮敮鎸乸ng锛宩pg锛宩peg鏍煎紡锛屽楂樿嚦灏�600*600px锛屽ぇ灏�2M鍐咃紝鍙嫋鎷借皟鏁翠富鍥鹃『搴�</div> + +<!-- <div class="demo-upload-list" v-for="(item,index) in showListImages">--> +<!-- <template style="display: flex">--> +<!-- <img :src="item">--> +<!-- <div class="demo-upload-list-cover">--> +<!-- <Icon type="ios-eye-outline" @click.native="handleView(item)"></Icon>--> +<!-- <Icon type="ios-trash-outline" @click.native="handleRemove(index)"></Icon>--> +<!-- </div>--> +<!-- </template>--> +<!-- </div>--> + <div style="color: grey" v-if="!baseInfoForm.goodsVideo">涓诲浘浠呮敮鎸乸ng锛宩pg锛宩peg鏍煎紡锛屽楂樿嚦灏�600*600px锛屽ぇ灏�2M鍐�</div> </FormItem> - <FormItem class="form-item-view-el" label="涓诲浘瑙嗛" prop="goodsVideo"> + <FormItem class="form-item-view-el" label="瑙嗛" prop="goodsVideo" > <div class="goods-video"> <div v-if="baseInfoForm.goodsVideo"> <div> - <video :src="baseInfoForm.goodsVideo" class="video" controls style="max-width: 300px;"/> + <video :src="baseInfoForm.showGoodsVideo" class="video" controls style="max-width: 300px;"/> </div> </div> - <Upload ref="upload" :action="uploadFileUrl" :format="['avi', 'wmv', 'mpeg', 'mp4', 'mov']" + <Upload ref="upload" action="-" :format="['avi', 'wmv', 'mpeg', 'mp4', 'mov']" :headers="{ ...accessToken }" :max-size="10240" :on-error="() => { loadingVideo = false }" :on-exceeded-size="handleVideoMaxSize" :on-format-error="handleFormatError" :on-progress="() => { loadingVideo = true }" :on-success="handleSuccessGoodsVideo" :show-upload-list="false" - multiple + :before-upload="upLoadVideo" + accept="video/*" style="margin-left: 10px" type="drag"> <Button :loading="loadingVideo" icon="ios-cloud-upload-outline" type="text"> <span v-if="!loadingVideo"> @@ -165,6 +176,9 @@ </span> </Button> </Upload> + <Button :loading="loadingVideo" v-if="baseInfoForm.goodsVideo" icon="delete" @click="removeVideo" type="text"> + <span>鍒犻櫎瑙嗛</span> + </Button> </div> </FormItem> <div class="layout" style="width: 100%"> @@ -176,7 +190,7 @@ <div v-for="(item, $index) in skuInfo" :key="$index" class="sku-item-content"> <Card :bordered="true" class="ivu-card-body"> <a slot="extra" style="margin-left: 6px"> - <Icon size="20" type="md-trash" @click="handleCloseSkuItem($index, item)"></Icon> + <Icon size="20" type="md-trash" @click="handleCloseSkuItem($index, item)"></Icon> </a> <div> <div style="display: flex;margin-bottom: 10px;font-weight: bold">瑙勬牸椤�</div> @@ -185,10 +199,13 @@ <div> <AutoComplete v-model="item.name" :filter-method="filterMethod" :maxlength="30" placeholder="璇疯緭鍏ヨ鏍奸」鍚嶇О" style="width: 150px" - @on-focus="changeSkuItem(item.name)" @on-change="editSkuItem(item.name, $index, item)"> + @on-focus="changeSkuItem(item.name)" + @on-change="editSkuItem(item.name, $index, item)"> </AutoComplete> - <iSwitch v-if="$index === 0" style="margin-left: 10px" size="small" @on-change="changeSkuOpenImage" v-model="openImage" /><span v-if="$index === 0" style="margin-left: 5px">娣诲姞瑙勬牸鍥剧墖</span> +<!-- <iSwitch v-if="$index === 0" style="margin-left: 10px" size="small"--> +<!-- @on-change="changeSkuOpenImage" v-model="openImage"/>--> +<!-- <span v-if="$index === 0" style="margin-left: 5px">娣诲姞瑙勬牸鍥剧墖</span>--> </div> </FormItem> @@ -210,7 +227,8 @@ @on-change="skuValueChange(val, index, item)"> </AutoComplete> <a style="margin-left: 6px" v-if="val.value && val.value !== ''"> - <Icon size="15" type="md-trash" @click="handleCloseSkuValue(val, index, item)"></Icon> + <Icon size="15" type="md-trash" + @click="handleCloseSkuValue(val, index, item)"></Icon> </a> </div> <div v-if="$index === 0 && openImage" style="margin-top: 10px"> @@ -225,19 +243,20 @@ style="width: 180px;height: 140px" /> <div class="sku-upload-list-cover"> - <div style="margin-top: 50px" > + <div style="margin-top: 50px"> <Icon size="25" type="md-search" @click="handleView(img)"></Icon> - <Icon size="25" type="md-trash" @click="handleRemove(val.images, __index)"></Icon> + <Icon size="25" type="md-trash" + @click="handleRemove(val.images, __index)"></Icon> </div> </div> </template> </div> </vuedraggable> - <Upload ref="uploadSku" :action="uploadFileUrl" +<!-- todo 3--> + <Upload ref="uploadSku" action="-" v-if="val.images < 1" :before-upload="handleBeforeUpload" :format="['jpg', 'jpeg', 'png', 'webp']" - :headers="{ ...accessToken }" :max-size="2048" :on-error="() => { $Spin.hide(); }" :on-exceeded-size="handleMaxSize" @@ -255,7 +274,9 @@ </div> </FormItem> - <FormItem v-if="item.spec_values.length < 10 && item.spec_values.length >= 1 && item.spec_values[0].value !== ''" class="sku-item-content-val flex" label="" style="line-height: 32px;"> + <FormItem + v-if="item.spec_values.length < 10 && item.spec_values.length >= 1 && item.spec_values[0].value !== ''" + class="sku-item-content-val flex" label="" style="line-height: 32px;"> <AutoComplete ref="input" v-model="newSkuValues[$index]" :filter-method="filterMethod" :maxlength="30" placeholder="鑷畾涔夎鏍煎��" style="width: 180px" @@ -362,6 +383,7 @@ </div> <FormItem class="form-item-view-el" label="PC鍟嗗搧鎻忚堪" prop="intro" style="width: 100%"> <editor + :show-upload="false" ref="editor" v-model="baseInfoForm.intro" height="800px" @@ -375,6 +397,7 @@ <FormItem class="form-item-view-el" label="绉诲姩绔弿杩�" prop="skuList" style="width: 100%"> <editor + :show-upload="false" ref="introEditor" v-model="baseInfoForm.mobileIntro" height="800px" @@ -473,8 +496,32 @@ <!--<Modal width="1200px" v-model="picModelFlag">--> <!--<ossManage @callback="callbackSelected" ref="ossManage" />--> <!--</Modal>--> - <Modal v-model="picModelFlag" width="1200px" @on-ok="confirmUrls"> - <ossManage ref="ossManage" :isComponent="true" :initialize="picModelFlag" @callback="callbackSelected" @selected="(list)=>{ selectedImage = list}"/> + <!-- todo web--> + <Modal v-model="picModelFlag" width="1200px"> + <!-- <ossManage ref="ossManRage" :isComponent="true" :initialize="picModelFlag" @callback="callbackSelected" @selected="(list)=>{ selectedImage = list}"/>--> + <div class="demo-upload-list" v-for="(item,index) in showListImages"> + <template> + <img :src="item"> + <div class="demo-upload-list-cover"> + <Icon type="ios-eye-outline" @click.native="handleView(item)"></Icon> + <Icon type="ios-trash-outline" @click.native="handleRemove(null,index)"></Icon> + </div> + </template> + </div> + <div class="demo-upload-list"> + <Upload + :before-upload="upLoadImg" + accept="image/*" + action="-" + type="drag" + style=" display: inline-block;width: 58px" + > + <div style="width: 58px;height:58px;line-height: 58px;"> + <Icon type="ios-camera" size="20"></Icon> + </div> + </Upload> + </div> + </Modal> </div> @@ -491,6 +538,9 @@ import DPlayer from 'dplayer'; // import ossManage from "@/views/sys/oss-manage/ossManage"; import ossManage from "@/views/shop/ossManages"; +import COS from 'cos-js-sdk-v5'; +import {getFileKey} from "@/utils/file.js"; +import {getFilePreview, getSts} from "@/api/file"; export default { @@ -523,6 +573,7 @@ }, 1000); }; return { + showListImages: [], regular, openImage: false, needToloadSku: false, @@ -625,6 +676,7 @@ /** 鍟嗗搧鍒嗙被涓枃鍚� */ categoryName: [], goodsVideo: "", + showGoodsVideo: "", }, /** 琛ㄦ牸澶� */ skuTableColumn: [], @@ -698,12 +750,19 @@ if (val) { this.initVideo(); } + }, + showListImages(newValue){ + this.baseInfoForm.goodsGalleryFiles = newValue.map(item => { + return item.split('/').slice(-2).join('/') + }) } }, methods: { // 閫夋嫨鍥剧墖modal handleCLickImg(val, index) { - this.$refs.ossManage.selectImage = true; + console.log('娴嬭瘯杈撳叆鐨勫��----------------銆�', val) + // 搴熷純鍘熸湁鐨勫浘鐗囦笂浼� + // this.$refs.ossManage.selectImage = true; this.picModelFlag = true; this.selectedFormBtnName = val; // this.picIndex = index; @@ -724,10 +783,10 @@ }, // ship澶у皬涓嶆纭� handleVideoMaxSize(file) { - this.$Notice.warning({ - title: "瓒呰繃鏂囦欢澶у皬闄愬埗", - desc: "瑙嗛澶у皬涓嶈兘瓒呰繃10MB", - }); + // this.$Notice.warning({ + // title: "瓒呰繃鏂囦欢澶у皬闄愬埗", + // desc: "瑙嗛澶у皬涓嶈兘瓒呰繃10MB", + // }); }, onAddSku(index) { if (!this.newSkuValues[index]) { @@ -865,7 +924,15 @@ }, // 绉婚櫎宸查�夊浘鐗� handleRemove(item, index) { - item.splice(index, 1) + if (!item) { + this.listImages.splice(index, 1); + this.showListImages.splice(index, 1); + this.baseInfoForm.goodsGalleryFiles.splice(index, 1); + this.baseInfoForm.goodsGalleryList.splice(index, 1); + } else { + console.log('绉婚櫎娴嬭瘯',item, index); + item.splice(index, 1) + } this.previewPicture = ""; }, // 鏌ョ湅鍟嗗搧澶у浘 @@ -999,14 +1066,57 @@ } }, // sku鍥剧墖涓婁紶鍓嶉挬瀛� - handleBeforeUpload(file) { + async handleBeforeUpload(file) { const check = this.selectedSku.images !== undefined && this.selectedSku.images.length > 5; if (check) { this.$Notice.warning({title: "鍥剧墖鏁伴噺涓嶈兘澶т簬浜斿紶"}); - return false; } + try { + // this.upLoadVideoLoading = true; + // 鑾峰彇鏂囦欢涓婁紶涓存椂瀵嗛挜 + const sts = await getSts(); + const cos = new COS({ + getAuthorization: async function (options, callback) { + callback({ + TmpSecretId: sts.data.tmpSecretId, + TmpSecretKey: sts.data.tmpSecretKey, + SecurityToken: sts.data.sessionToken, + // 寤鸿杩斿洖鏈嶅姟鍣ㄦ椂闂翠綔涓虹鍚嶇殑寮�濮嬫椂闂达紝閬垮厤瀹㈡埛绔湰鍦版椂闂村亸宸繃澶у鑷寸鍚嶉敊璇� + StartTime: sts.data.stsStartTime, // 鏃堕棿鎴筹紝鍗曚綅绉掞紝濡傦細1580000000 + ExpiredTime: sts.data.stsEndTime,// 鏃堕棿鎴筹紝鍗曚綅绉掞紝濡傦細1580000000 + ScopeLimit: true, // 缁嗙矑搴︽帶鍒舵潈闄愰渶瑕佽涓� true锛屼細闄愬埗瀵嗛挜鍙湪鐩稿悓璇锋眰鏃堕噸澶嶄娇鐢� + }); + } + }) + const fileKey = getFileKey(file.name) + const upData = await cos.uploadFile({ + Bucket: sts.data.bucket, + Region: sts.data.region, + Key: fileKey, + Body: file, // 瑕佷笂浼犵殑鏂囦欢瀵硅薄銆� + SliceSize: 1024 * 1024 * 5, + onProgress: function (progressData) { + console.log('涓婁紶杩涘害锛�', progressData); + }, + }); + console.log("涓婁紶鎴愬姛", upData) + this.$nextTick(() => { + this.listImages.push(fileKey); + this.showListImages.push(sts.data.endpoint + "/" + fileKey); + this.baseInfoForm.goodsGalleryFiles.push(fileKey); + }) + + } catch (e) { + console.log("涓婁紶澶辫触", upData) + return false; + } finally { + // this.upLoadVideoLoading = false; + + } + return false; + }, /** 鏌ヨ鍟嗗搧鍝佺墝鍒楄〃 */ @@ -1086,8 +1196,34 @@ this.baseInfoForm.goodsGalleryFiles = response.result.goodsGalleryList.map((i) => { return i; - }); + }) + try { + const stsInfo = await getSts(); + const endpoint = stsInfo.data.endpoint; + this.showListImages = response.result.goodsGalleryList.map((i) => { + if (i!=null&&i.indexOf('http')===-1) + return endpoint+'/'+i; + else return i; + }) + if (response.result.goodsVideo){ + + } + } catch (e) { + console.log('缁勮璺緞鍑洪棶棰�',e); + } + } + if (response.result.goodsVideo){ + try { + const stsInfo = await getSts(); + const endpoint = stsInfo.data.endpoint; + this.baseInfoForm.goodsVideo = response.result.goodsVideo; + this.baseInfoForm.showGoodsVideo = endpoint + '/' + response.result.goodsVideo; + console.log('鏄剧ず鍟嗗搧瑙嗛------------------->', this.baseInfoForm.showGoodsVideo); + } catch (e) { + console.log('缁勮瑙嗛鍦板潃鍑洪敊浜�') + } + } if ( response.result.wholesaleList && @@ -1105,7 +1241,8 @@ this.renderGoodsDetailSku(response.result.skuList); /** 鏌ヨ鍝佺墝鍒楄〃 */ - this.getGoodsBrandList(); + //todo 绉婚櫎鍝佺墝姒傚康 + // this.getGoodsBrandList(); /** 鏌ヨ搴楅摵鍟嗗搧鍒嗙被 */ this.GET_ShopGoodsLabel(); @@ -1125,7 +1262,7 @@ this.firstData.goodsType && (this.baseInfoForm.goodsType = this.firstData.goodsType); /** 鏌ヨ鍟嗗搧鍙傛暟 */ - this.GET_GoodsParams(); + // this.GET_GoodsParams(); }, // 娓叉煋sku鏁版嵁 renderGoodsDetailSku(skuList) { @@ -1780,124 +1917,134 @@ }, /** 娣诲姞鍟嗗搧 **/ save() { - this.submitLoading = true; - this.$refs["baseInfoForm"].validate((valid) => { - if (valid) { - if (this.baseInfoForm.salesModel === "WHOLESALE") { - for (let i = 0; i < this.wholesaleData.length; i++) { - this.checkWholesaleNum(i); - this.checkWholesalePrice(i); - this.wholesaleData[i].goodsId = this.goodsId; - } - this.baseInfoForm.wholesaleList = this.wholesaleData; - } - this.baseInfoForm.goodsId = this.goodsId; - let submit = JSON.parse(JSON.stringify(this.baseInfoForm)); - if ( - submit.goodsGalleryFiles && - submit.goodsGalleryFiles.length <= 0 - ) { - this.submitLoading = false; - this.$Message.error("璇蜂笂浼犲晢鍝佸浘鐗�"); - return; - } - if (submit.templateId === "") submit.templateId = 0; - let flag = false; - let paramValue = ""; - - if (flag) { - this.$Message.error(paramValue + " 鍙傛暟鍊间笉鑳戒负绌�"); - this.submitLoading = false; - return; - } - - if (this.goodsUnitList && !this.goodsUnitList.find(i => i === this.baseInfoForm.goodsUnit)) { - submit.goodsUnit = "" - this.$Message.error("鍟嗗搧鍗曚綅涓嶅瓨鍦�"); - this.submitLoading = false; - return; - } - let skuInfoNames = this.skuInfo.map((n) => n.name); - submit.skuList = []; - let containEmptyImage = false; - this.skuTableData.map((sku) => { - let skuCopy = { - cost: 1, - price: sku.price, - quantity: sku.quantity, - // alertQuantity: sku.alertQuantity, - sn: sku.sn, - images: [], - }; - if (this.openImage) { - this.skuInfo[0].spec_values.forEach(item => { - if (!item.images || item.images.length === 0) { - containEmptyImage = true; - return; - } - if (item.value === sku[this.skuInfo[0].name]) { - skuCopy.images = item.images - } - }) - - } - if (sku.weight) { - skuCopy.weight = sku.weight; - } - if (this.baseInfoForm.weight) { - skuCopy.weight = this.baseInfoForm.weight; - } - if (sku.id) { - skuCopy.id = sku.id; - } - for (let skuInfoName of skuInfoNames) { - skuCopy[skuInfoName] = sku[skuInfoName]; - } - submit.skuList.push(skuCopy); - }); - if (containEmptyImage) { - this.$Message.error("寮�鍚鏍煎浘鐗囷紝鎵�鏈夎鏍煎浘鐗囦笉鑳戒负绌猴紒"); - this.submitLoading = false; - return; - } - if (submit.goodsGalleryFiles.length > 0) { - submit.goodsGalleryList = submit.goodsGalleryFiles.map( - (i) => i - ); - } - /** 鍙傛暟鏍¢獙 **/ - /* Object.keys(submit.goodsParamsList).forEach((item) => { - });*/ - submit.release ? (submit.release = true) : (submit.release = false); - submit.recommend - ? (submit.recommend = true) - : (submit.recommend = false); - if (this.goodsId) { - API_GOODS.editGoods(this.goodsId, submit).then((res) => { - if (res.success) { - this.submitLoading = false; - this.$router.go(-1); - } else { - this.submitLoading = false; + try { + this.submitLoading = true; + this.$refs["baseInfoForm"].validate((valid) => { + if (valid) { + if (this.baseInfoForm.salesModel === "WHOLESALE") { + for (let i = 0; i < this.wholesaleData.length; i++) { + this.checkWholesaleNum(i); + this.checkWholesalePrice(i); + this.wholesaleData[i].goodsId = this.goodsId; } + this.baseInfoForm.wholesaleList = this.wholesaleData; + } + this.baseInfoForm.goodsId = this.goodsId; + let submit = JSON.parse(JSON.stringify(this.baseInfoForm)); + console.log('----------------->鎻愪氦',submit); + if ( + submit.goodsGalleryFiles && + submit.goodsGalleryFiles.length <= 0 + ) { + this.submitLoading = false; + this.$Message.error("璇蜂笂浼犲晢鍝佸浘鐗�"); + return; + } + if (!submit.goodsVideo){ + this.submitLoading = false; + this.$Message.error("璇蜂笂浼犲晢鍝佽棰�"); + return; + } + if (submit.templateId === "") submit.templateId = 0; + let flag = false; + let paramValue = ""; + + if (flag) { + this.$Message.error(paramValue + " 鍙傛暟鍊间笉鑳戒负绌�"); + this.submitLoading = false; + return; + } + + if (this.goodsUnitList && !this.goodsUnitList.find(i => i === this.baseInfoForm.goodsUnit)) { + submit.goodsUnit = "" + this.$Message.error("鍟嗗搧鍗曚綅涓嶅瓨鍦�"); + this.submitLoading = false; + return; + } + let skuInfoNames = this.skuInfo.map((n) => n.name); + submit.skuList = []; + let containEmptyImage = false; + this.skuTableData.map((sku) => { + let skuCopy = { + cost: 1, + price: sku.price, + quantity: sku.quantity, + // alertQuantity: sku.alertQuantity, + sn: sku.sn, + images: [], + }; + if (this.openImage) { + this.skuInfo[0].spec_values.forEach(item => { + if (!item.images || item.images.length === 0) { + containEmptyImage = true; + return; + } + if (item.value === sku[this.skuInfo[0].name]) { + skuCopy.images = item.images + } + }) + + } + if (sku.weight) { + skuCopy.weight = sku.weight; + } + if (this.baseInfoForm.weight) { + skuCopy.weight = this.baseInfoForm.weight; + } + if (sku.id) { + skuCopy.id = sku.id; + } + for (let skuInfoName of skuInfoNames) { + skuCopy[skuInfoName] = sku[skuInfoName]; + } + submit.skuList.push(skuCopy); }); + if (containEmptyImage) { + this.$Message.error("寮�鍚鏍煎浘鐗囷紝鎵�鏈夎鏍煎浘鐗囦笉鑳戒负绌猴紒"); + this.submitLoading = false; + return; + } + if (submit.goodsGalleryFiles.length > 0) { + submit.goodsGalleryList = submit.goodsGalleryFiles.map( + (i) => i + ); + } + /** 鍙傛暟鏍¢獙 **/ + /* Object.keys(submit.goodsParamsList).forEach((item) => { + });*/ + submit.release ? (submit.release = true) : (submit.release = false); + submit.recommend + ? (submit.recommend = true) + : (submit.recommend = false); + if (this.goodsId) { + API_GOODS.editGoods(this.goodsId, submit).then((res) => { + if (res.success) { + this.submitLoading = false; + this.$router.go(-1); + } else { + this.submitLoading = false; + } + }); + } else { + API_GOODS.createGoods(submit).then((res) => { + if (res.success) { + this.submitLoading = false; + this.$parent.activestep = 2; + window.scrollTo(0, 0); + } else { + this.submitLoading = false; + } + }); + } } else { - API_GOODS.createGoods(submit).then((res) => { - if (res.success) { - this.submitLoading = false; - this.$parent.activestep = 2; - window.scrollTo(0, 0); - } else { - this.submitLoading = false; - } - }); - } - } else { - this.submitLoading = false; + this.submitLoading = false; - this.$Message.error("杩樻湁蹇呭~椤规湭鍋氬鐞嗭紝璇锋鏌ヨ〃鍗�"); - } - }); + this.$Message.error("杩樻湁蹇呭~椤规湭鍋氬鐞嗭紝璇锋鏌ヨ〃鍗�"); + } + }); + } finally { + this.submitLoading = false; + } }, /** 淇濆瓨涓烘ā鏉� */ saveToDraft() { @@ -1961,8 +2108,110 @@ } else if (type === 'localRefresh') { this.$Message.error("鍒锋柊澶辫触锛岃閲嶈瘯"); } + }).catch(reason => { + console.log("鑾峰彇妯℃澘澶辫触",reason) }); - } + }, + removeVideo(){ + this.baseInfoForm.showGoodsVideo = null; + this.baseInfoForm.goodsVideo = null; + }, + // todo 鏂囦欢涓婁紶 + async upLoadImg(file) { + console.log(file,this.count++); + if (this.listImages.length >= 5) { + this.$Message.error("鍥剧墖涓婁紶涓嶈兘瓒呰繃5涓�"); + return; + } + try { + // this.upLoadVideoLoading = true; + // 鑾峰彇鏂囦欢涓婁紶涓存椂瀵嗛挜 + const sts = await getSts(); + const cos = new COS({ + getAuthorization: async function (options, callback) { + callback({ + TmpSecretId: sts.data.tmpSecretId, + TmpSecretKey: sts.data.tmpSecretKey, + SecurityToken: sts.data.sessionToken, + // 寤鸿杩斿洖鏈嶅姟鍣ㄦ椂闂翠綔涓虹鍚嶇殑寮�濮嬫椂闂达紝閬垮厤瀹㈡埛绔湰鍦版椂闂村亸宸繃澶у鑷寸鍚嶉敊璇� + StartTime: sts.data.stsStartTime, // 鏃堕棿鎴筹紝鍗曚綅绉掞紝濡傦細1580000000 + ExpiredTime: sts.data.stsEndTime,// 鏃堕棿鎴筹紝鍗曚綅绉掞紝濡傦細1580000000 + ScopeLimit: true, // 缁嗙矑搴︽帶鍒舵潈闄愰渶瑕佽涓� true锛屼細闄愬埗瀵嗛挜鍙湪鐩稿悓璇锋眰鏃堕噸澶嶄娇鐢� + }); + } + }) + const fileKey = getFileKey(file.name) + const upData = await cos.uploadFile({ + Bucket: sts.data.bucket, + Region: sts.data.region, + Key: fileKey, + Body: file, // 瑕佷笂浼犵殑鏂囦欢瀵硅薄銆� + SliceSize: 1024 * 1024 * 5, + onProgress: function (progressData) { + console.log('涓婁紶杩涘害锛�', progressData); + }, + }); + console.log("涓婁紶鎴愬姛", upData) + this.$nextTick(() => { + this.listImages.push(fileKey); + this.showListImages.push(sts.data.endpoint + "/" + fileKey); + this.baseInfoForm.goodsGalleryFiles.push(fileKey); + }) + + } catch (e) { + console.log("涓婁紶澶辫触", upData) + return false; + } finally { + // this.upLoadVideoLoading = false; + + } + return false; + }, + async upLoadVideo(file) { + try { + // this.upLoadVideoLoading = true; + // 鑾峰彇鏂囦欢涓婁紶涓存椂瀵嗛挜 + const sts = await getSts(); + const cos = new COS({ + getAuthorization: async function (options, callback) { + callback({ + TmpSecretId: sts.data.tmpSecretId, + TmpSecretKey: sts.data.tmpSecretKey, + SecurityToken: sts.data.sessionToken, + // 寤鸿杩斿洖鏈嶅姟鍣ㄦ椂闂翠綔涓虹鍚嶇殑寮�濮嬫椂闂达紝閬垮厤瀹㈡埛绔湰鍦版椂闂村亸宸繃澶у鑷寸鍚嶉敊璇� + StartTime: sts.data.stsStartTime, // 鏃堕棿鎴筹紝鍗曚綅绉掞紝濡傦細1580000000 + ExpiredTime: sts.data.stsEndTime,// 鏃堕棿鎴筹紝鍗曚綅绉掞紝濡傦細1580000000 + ScopeLimit: true, // 缁嗙矑搴︽帶鍒舵潈闄愰渶瑕佽涓� true锛屼細闄愬埗瀵嗛挜鍙湪鐩稿悓璇锋眰鏃堕噸澶嶄娇鐢� + }); + } + }) + const fileKey = getFileKey(file.name) + const upData = await cos.uploadFile({ + Bucket: sts.data.bucket, + Region: sts.data.region, + Key: fileKey, + Body: file, // 瑕佷笂浼犵殑鏂囦欢瀵硅薄銆� + SliceSize: 1024 * 1024 * 5, + onProgress: function (progressData) { + console.log('涓婁紶杩涘害锛�', progressData); + }, + }); + console.log("涓婁紶鎴愬姛", upData) + this.$nextTick(() => { + this.baseInfoForm.goodsVideo = fileKey; + this.baseInfoForm.showGoodsVideo = sts.data.endpoint + "/" + fileKey; + this.baseInfoForm.goodsVideo = fileKey; + }) + + } catch (e) { + console.log("涓婁紶澶辫触", upData) + return false; + } finally { + // this.upLoadVideoLoading = false; + + } + return false; + }, }, mounted() { this.accessToken = { @@ -1988,12 +2237,17 @@ this.baseInfoForm.goodsType = this.firstData.goodsType; - /** 鑾峰彇璇ュ晢鍩庡垎绫讳笅 鍟嗗搧鍙傛暟淇℃伅 */ - this.GET_GoodsParams(); - /** 鏌ヨ鍝佺墝鍒楄〃 */ - this.getGoodsBrandList(); - /** 鏌ヨ鍒嗙被缁戝畾鐨勮鏍间俊鎭� */ - this.Get_SkuInfoByCategory(this.categoryId); + + + if (this.categoryId!=null && this.categoryId!=='') { + /** 鑾峰彇璇ュ晢鍩庡垎绫讳笅 鍟嗗搧鍙傛暟淇℃伅 */ + this.GET_GoodsParams(); + console.log('鍒嗙被id------------------>',this.categoryId); + /** 鏌ヨ鍒嗙被缁戝畾鐨勮鏍间俊鎭� */ + this.Get_SkuInfoByCategory(this.categoryId); + /** 鏌ヨ鍝佺墝鍒楄〃 */ + this.getGoodsBrandList(); + } // 鑾峰彇鍟嗗搧鍗曚綅 this.GET_GoodsUnit(); // 鑾峰彇褰撳墠搴楅摵鍒嗙被 @@ -2044,4 +2298,45 @@ .refresh-icon { margin-left: 10px; } + +.demo-upload-list { + display: inline-block; + width: 60px; + height: 60px; + text-align: center; + line-height: 60px; + border: 1px solid transparent; + border-radius: 4px; + overflow: hidden; + background: #fff; + position: relative; + box-shadow: 0 1px 1px rgba(0, 0, 0, .2); + margin-right: 4px; +} + +.demo-upload-list img { + width: 100%; + height: 100%; +} + +.demo-upload-list-cover { + display: none; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + background: rgba(0, 0, 0, .6); +} + +.demo-upload-list:hover .demo-upload-list-cover { + display: block; +} + +.demo-upload-list-cover i { + color: #fff; + font-size: 20px; + cursor: pointer; + margin: 0 2px; +} </style> diff --git a/seller/src/views/lili-components/editor/index.vue b/seller/src/views/lili-components/editor/index.vue index a28d64e..5bd05ee 100644 --- a/seller/src/views/lili-components/editor/index.vue +++ b/seller/src/views/lili-components/editor/index.vue @@ -3,7 +3,7 @@ <!-- 浣跨敤 fullscreen 绫绘潵鎺у埗鏄惁鍏ㄥ睆鏄剧ず --> <div :class="{ fullscreen: fullscreen }" class="tinymce-container"> <!-- 浣跨敤 tinymce-textarea 绫讳綔涓虹紪杈戝櫒鐨勬枃鏈尯鍩� --> - <uploadImage @callback="insertImage" /> + <uploadImage @callback="insertImage" v-if="showUpload"/> <textarea :id="tinymceId" class="tinymce-textarea" /> </div> </div> @@ -23,6 +23,9 @@ height:{ type:String, default:'500px' + },showUpload:{ + type:Boolean, + default:true } }, data() { -- Gitblit v1.8.0