dev2 #1
62
JenkinsfileBuild
Normal file
62
JenkinsfileBuild
Normal file
@ -0,0 +1,62 @@
|
||||
pipeline {
|
||||
agent any
|
||||
|
||||
tools {
|
||||
nodejs 'NodeJS16'
|
||||
}
|
||||
|
||||
environment {
|
||||
// 抽取部署目标路径为公共变量
|
||||
DEPLOY_DIR = '/data/nginx/www/fafamall/admin'
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('拉取代码') {
|
||||
steps {
|
||||
checkout scm
|
||||
}
|
||||
}
|
||||
|
||||
stage('安装依赖') {
|
||||
steps {
|
||||
sh '''
|
||||
echo "清理旧依赖..."
|
||||
rm -rf node_modules package-lock.json
|
||||
npm cache clean --force
|
||||
|
||||
echo "设置国内腾讯云镜像源加速..."
|
||||
npm config set registry https://mirrors.cloud.tencent.com/npm/
|
||||
|
||||
# 安装其他依赖
|
||||
npm install
|
||||
'''
|
||||
}
|
||||
}
|
||||
|
||||
stage('构建项目') {
|
||||
steps {
|
||||
sh 'npm run build'
|
||||
}
|
||||
}
|
||||
|
||||
stage('部署项目') {
|
||||
steps {
|
||||
sh '''
|
||||
# 公共部署逻辑(创建目录、清理、复制)
|
||||
mkdir -p ${DEPLOY_DIR}
|
||||
rm -rf ${DEPLOY_DIR}/*
|
||||
cp -r admin/* ${DEPLOY_DIR}/
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
success {
|
||||
echo '项目部署成功.'
|
||||
}
|
||||
failure {
|
||||
echo '项目部署失败.'
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Jenkinsfile
vendored
Normal file
36
Jenkinsfile
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
pipeline {
|
||||
agent any
|
||||
|
||||
environment {
|
||||
DEPLOY_DIR = '/data/nginx/www/fafamall/admin'
|
||||
DIST_PATH = 'admin'
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('拉取代码并验证') {
|
||||
steps {
|
||||
checkout scm
|
||||
sh """
|
||||
[ -d "${DIST_PATH}" ] || { echo "错误:未找到 ${DIST_PATH} 文件夹"; exit 1; }
|
||||
echo "${DIST_PATH} 验证通过"
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
stage('部署') {
|
||||
steps {
|
||||
sh """
|
||||
mkdir -p ${DEPLOY_DIR}
|
||||
rm -rf ${DEPLOY_DIR}/*
|
||||
cp -r ${DIST_PATH}/* ${DEPLOY_DIR}/
|
||||
echo "部署完成:${DIST_PATH} → ${DEPLOY_DIR}"
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
success { echo "✅ 部署成功" }
|
||||
failure { echo "❌ 部署失败" }
|
||||
}
|
||||
}
|
||||
@ -5,5 +5,5 @@
|
||||
window.ver = "2.0.278";
|
||||
window.SYS = {CONFIG:{}, URL:{}};</script><script>window._AMapSecurityConfig = {
|
||||
securityJsCode:"07788e7ebd7e913985722bfc5986999f"
|
||||
}</script><script src="https://mall.gpxscs.cn/admin/config.js?v=2.0.278"></script><script src="https://mall.gpxscs.cn/admin/im/libs3.6.0.min.js?v=2.0.278"></script><script src="https://mall.gpxscs.cn/admin/im/im.js?v=2.0.278"></script><link href="static/css/chunk-19648027.83a11e8c.css" rel="prefetch"><link href="static/css/chunk-250d32fa.ad6e6718.css" rel="prefetch"><link href="static/css/vab-extra.f3d407d7.css" rel="prefetch"><link href="static/js/chunk-19648027.6233a553.js" rel="prefetch"><link href="static/js/chunk-250d32fa.ee34e965.js" rel="prefetch"><link href="static/js/vab-extra.29abc81b.js" rel="prefetch"><link href="static/css/app.1f390f7c.css" rel="preload" as="style"><link href="static/css/element-ui.0e3a750b.css" rel="preload" as="style"><link href="static/js/app.7b6be8c5.js" rel="preload" as="script"><link href="static/js/element-ui.4e8e0db4.js" rel="preload" as="script"><link href="static/js/vue.11eaebc3.js" rel="preload" as="script"><link href="static/css/element-ui.0e3a750b.css" rel="stylesheet"><link href="static/css/app.1f390f7c.css" rel="stylesheet"><link rel="icon" type="image/png" sizes="32x32" href="img/icons/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="img/icons/favicon-16x16.png"><link rel="manifest" href="manifest.json"><meta name="theme-color" content="#ffffff"><meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="black"><meta name="apple-mobile-web-app-title" content="xiaofa-admin"><link rel="apple-touch-icon" href="img/icons/apple-touch-icon-152x152.png"><link rel="mask-icon" href="img/icons/safari-pinned-tab.svg" color="#ffffff"><meta name="msapplication-TileImage" content="img/icons/msapplication-icon-144x144.png"><meta name="msapplication-TileColor" content="#ffffff"></head><body><noscript></noscript><div id="app"><div class="first-loading-wrp"><div class="loading-wrp"><span class="dot dot-spin"><i></i> <i></i> <i></i> <i></i></span></div><h1>小发同城</h1></div></div><script>if (window.location.hostname !== 'localhost') {
|
||||
}</script><script src="static/js/element-ui.4e8e0db4.js"></script><script src="static/js/vue.11eaebc3.js"></script><script src="static/js/app.7b6be8c5.js"></script></body></html>
|
||||
}</script><script src="https://mall.gpxscs.cn/admin/config.js?v=2.0.278"></script><script src="https://mall.gpxscs.cn/admin/im/libs3.6.0.min.js?v=2.0.278"></script><script src="https://mall.gpxscs.cn/admin/im/im.js?v=2.0.278"></script><link href="static/css/chunk-19648027.83a11e8c.css" rel="prefetch"><link href="static/css/chunk-982af3b2.2e626fb8.css" rel="prefetch"><link href="static/css/vab-extra.9da8d2d7.css" rel="prefetch"><link href="static/js/chunk-19648027.6233a553.js" rel="prefetch"><link href="static/js/chunk-982af3b2.f27b9204.js" rel="prefetch"><link href="static/js/vab-extra.29abc81b.js" rel="prefetch"><link href="static/css/app.d3766ec2.css" rel="preload" as="style"><link href="static/css/element-ui.0e3a750b.css" rel="preload" as="style"><link href="static/js/app.22ca6c1e.js" rel="preload" as="script"><link href="static/js/element-ui.4e8e0db4.js" rel="preload" as="script"><link href="static/js/vue.11eaebc3.js" rel="preload" as="script"><link href="static/css/element-ui.0e3a750b.css" rel="stylesheet"><link href="static/css/app.d3766ec2.css" rel="stylesheet"><link rel="icon" type="image/png" sizes="32x32" href="img/icons/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="img/icons/favicon-16x16.png"><link rel="manifest" href="manifest.json"><meta name="theme-color" content="#ffffff"><meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="black"><meta name="apple-mobile-web-app-title" content="xiaofa-admin"><link rel="apple-touch-icon" href="img/icons/apple-touch-icon-152x152.png"><link rel="mask-icon" href="img/icons/safari-pinned-tab.svg" color="#ffffff"><meta name="msapplication-TileImage" content="img/icons/msapplication-icon-144x144.png"><meta name="msapplication-TileColor" content="#ffffff"></head><body><noscript></noscript><div id="app"><div class="first-loading-wrp"><div class="loading-wrp"><span class="dot dot-spin"><i></i> <i></i> <i></i> <i></i></span></div><h1>小发同城</h1></div></div><script>if (window.location.hostname !== 'localhost') {
|
||||
}</script><script src="static/js/element-ui.4e8e0db4.js"></script><script src="static/js/vue.11eaebc3.js"></script><script src="static/js/app.22ca6c1e.js"></script></body></html>
|
||||
@ -2376,7 +2376,7 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([
|
||||
"url": "im/libs3.6.0.min.js"
|
||||
},
|
||||
{
|
||||
"revision": "cf9154a132f8f4fd10d64989353a912e",
|
||||
"revision": "7ebe59974ea1890f83750ee0d5c03c81",
|
||||
"url": "index.html"
|
||||
},
|
||||
{
|
||||
@ -2392,16 +2392,16 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([
|
||||
"url": "robots.txt"
|
||||
},
|
||||
{
|
||||
"revision": "9093e5e0114d448ce863",
|
||||
"url": "static/css/app.1f390f7c.css"
|
||||
"revision": "056b89c76cfe8cf92d74",
|
||||
"url": "static/css/app.d3766ec2.css"
|
||||
},
|
||||
{
|
||||
"revision": "f5dd29b853f67685e75d",
|
||||
"url": "static/css/chunk-19648027.83a11e8c.css"
|
||||
},
|
||||
{
|
||||
"revision": "c620221a39684b688176",
|
||||
"url": "static/css/chunk-250d32fa.ad6e6718.css"
|
||||
"revision": "6984a81f0f371ff13778",
|
||||
"url": "static/css/chunk-982af3b2.2e626fb8.css"
|
||||
},
|
||||
{
|
||||
"revision": "7b9212a0410ce12f6058",
|
||||
@ -2488,8 +2488,8 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([
|
||||
"url": "static/css/loading.css"
|
||||
},
|
||||
{
|
||||
"revision": "12a2a22f0838cb088347",
|
||||
"url": "static/css/vab-extra.f3d407d7.css"
|
||||
"revision": "7d112341fd53f7fa582e",
|
||||
"url": "static/css/vab-extra.9da8d2d7.css"
|
||||
},
|
||||
{
|
||||
"revision": "1e254113bacc83eb432837057e7dfeb1",
|
||||
@ -2636,23 +2636,23 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([
|
||||
"url": "static/img/xiaofa-logo.20439423.png"
|
||||
},
|
||||
{
|
||||
"revision": "9093e5e0114d448ce863",
|
||||
"url": "static/js/app.7b6be8c5.js"
|
||||
"revision": "056b89c76cfe8cf92d74",
|
||||
"url": "static/js/app.22ca6c1e.js"
|
||||
},
|
||||
{
|
||||
"revision": "f5dd29b853f67685e75d",
|
||||
"url": "static/js/chunk-19648027.6233a553.js"
|
||||
},
|
||||
{
|
||||
"revision": "c620221a39684b688176",
|
||||
"url": "static/js/chunk-250d32fa.ee34e965.js"
|
||||
"revision": "6984a81f0f371ff13778",
|
||||
"url": "static/js/chunk-982af3b2.f27b9204.js"
|
||||
},
|
||||
{
|
||||
"revision": "7b9212a0410ce12f6058",
|
||||
"url": "static/js/element-ui.4e8e0db4.js"
|
||||
},
|
||||
{
|
||||
"revision": "12a2a22f0838cb088347",
|
||||
"revision": "7d112341fd53f7fa582e",
|
||||
"url": "static/js/vab-extra.29abc81b.js"
|
||||
},
|
||||
{
|
||||
@ -14,7 +14,7 @@
|
||||
importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js");
|
||||
|
||||
importScripts(
|
||||
"precache-manifest.5a6aa66371ba042aaeb4213a18385bd8.js"
|
||||
"precache-manifest.9096de45da1fb13ceb1af813c8893e26.js"
|
||||
);
|
||||
|
||||
workbox.core.setCacheNameDetails({prefix: "xiaofa-admin"});
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -1,7 +1,7 @@
|
||||
/*!
|
||||
* build: xiaofa-admin
|
||||
* copyright: https://www.lancerdt.com
|
||||
* time: 2025-8-2 15:53:06
|
||||
* time: 2025-9-27 18:25:36
|
||||
*/
|
||||
/*!
|
||||
* Quill Editor v1.3.7
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* build: xiaofa-admin
|
||||
* copyright: https://www.lancerdt.com
|
||||
* time: 2025-8-2 15:53:06
|
||||
* time: 2025-9-27 18:25:36
|
||||
*/@media only screen and (max-width:767px){.hidden-xs-only{display:none!important}}@media only screen and (min-width:768px){.hidden-sm-and-up{display:none!important}}@media only screen and (min-width:768px) and (max-width:991px){.hidden-sm-only{display:none!important}}@media only screen and (max-width:991px){.hidden-sm-and-down{display:none!important}}@media only screen and (min-width:992px){.hidden-md-and-up{display:none!important}}@media only screen and (min-width:992px) and (max-width:1199px){.hidden-md-only{display:none!important}}@media only screen and (max-width:1199px){.hidden-md-and-down{display:none!important}}@media only screen and (min-width:1200px){.hidden-lg-and-up{display:none!important}}@media only screen and (min-width:1200px) and (max-width:1919px){.hidden-lg-only{display:none!important}}@media only screen and (max-width:1919px){.hidden-lg-and-down{display:none!important}}@media only screen and (min-width:1920px){.hidden-xl-only{display:none!important}}
|
||||
@ -1,5 +1,5 @@
|
||||
/*!
|
||||
* build: xiaofa-admin
|
||||
* copyright: https://www.lancerdt.com
|
||||
* time: 2025-8-2 15:53:06
|
||||
* time: 2025-9-27 18:25:36
|
||||
*/[data-v-28093814]:export{menu-color:#fff;menu-color-active:#fff;menu-background:#282c34;column-second-menu-background:#fff}.vab-avatar-list[data-v-28093814] .el-avatar{display:inline-block;margin-left:-15px;cursor:pointer;border:3px solid #fff}.echarts{width:600px;height:400px}[data-v-7f7baab5]:export{menu-color:#fff;menu-color-active:#fff;menu-background:#282c34;column-second-menu-background:#fff}@media only screen and (max-width:767px){[data-v-7f7baab5] .vab-cropper-canvas{display:block;float:none;margin:0 auto}[data-v-7f7baab5] .vab-cropper-preview{display:none}}[data-v-7f7baab5] .el-textarea{margin-top:20px}[data-v-7f7baab5] .el-dialog__footer{height:72px}[data-v-7f7baab5] .el-dialog__footer:before{display:block;clear:both;content:""}[data-v-7f7baab5] .el-dialog__footer>div>div{display:inline}[data-v-7f7baab5] .el-dialog__footer>div>div .el-upload-list{display:none}[data-v-7f7baab5] .el-dialog__footer>div>div .el-upload--picture-card{float:right;width:auto;height:32px;line-height:32px;vertical-align:middle;background-color:transparent;border:0;border-radius:0}[data-v-7f7baab5] .el-dialog__footer>div .el-button{float:right;margin-left:10px}.icon-selector-popper .el-card__body{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;height:20px;cursor:pointer}.icon-selector-popper .el-card__body i{font-size:28px;color:rgba(0,0,0,.65);text-align:center;vertical-align:middle;pointer-events:none;cursor:pointer}.icon-selector-popper .el-pagination{margin:0}[data-v-3aef4cea]:export{menu-color:#fff;menu-color-active:#fff;menu-background:#282c34;column-second-menu-background:#fff}.upload[data-v-3aef4cea]{height:500px}.upload .upload-content .el-upload__tip[data-v-3aef4cea]{display:block;height:30px;line-height:30px}.upload .upload-content[data-v-3aef4cea] .el-upload--picture-card{width:128px;height:128px;margin:3px 8px 8px 8px;border:2px dashed #c0ccda}.upload .upload-content[data-v-3aef4cea] .el-upload-list--picture{margin-bottom:20px}.upload .upload-content[data-v-3aef4cea] .el-upload-list--picture-card .el-upload-list__item{width:128px;height:128px;margin:3px 8px 8px 8px}
|
||||
55
admin/static/js/app.22ca6c1e.js
Normal file
55
admin/static/js/app.22ca6c1e.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
6
admin/static/js/chunk-982af3b2.f27b9204.js
Normal file
6
admin/static/js/chunk-982af3b2.f27b9204.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
24
src/api/baidu/baidu.js
Normal file
24
src/api/baidu/baidu.js
Normal file
@ -0,0 +1,24 @@
|
||||
import request from '@/utils/request'
|
||||
import { URL } from '@/config'
|
||||
|
||||
/**
|
||||
* 获取百度地图输入点提示词
|
||||
* @author Seven
|
||||
* @data 2025-3-5
|
||||
* @param {
|
||||
* query: value, //关键词
|
||||
* region: this.citys[0], //城市名
|
||||
* city_limit: true, //指定的区域的返回结果
|
||||
* ret_coordtype: "gcj02ll", //坐标类型 1(WGS84ll即GPS经纬度)2(GCJ02ll即国测局经纬度坐标) 3(BD09ll即百度经纬度坐标) 4(BD09mc即百度米制坐标)
|
||||
*}
|
||||
* @returns { query,region }
|
||||
* @see https://mall.gpxscs.cn/mobile/shop/merch/baidu/place/v2/suggestion
|
||||
*/
|
||||
|
||||
export function getBaiduSuggestion(params) {
|
||||
return request({
|
||||
url: URL.baidu.getBaiduSuggestion,
|
||||
method: 'get',
|
||||
params,
|
||||
})
|
||||
}
|
||||
@ -64,3 +64,20 @@ export function getSmsRecord(params) {
|
||||
params,
|
||||
})
|
||||
}
|
||||
export function getReportList(params){
|
||||
return request({
|
||||
url:URL.account.base.config.report_list,
|
||||
method:'get',
|
||||
params:params
|
||||
})
|
||||
}
|
||||
export function dealReport(data){
|
||||
return request({
|
||||
url:URL.account.base.config.deal_report,
|
||||
method:'post',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
data: JSON.stringify(data)
|
||||
})
|
||||
}
|
||||
@ -126,7 +126,23 @@ export async function syncShopImages(data) {
|
||||
method: 'post',
|
||||
})
|
||||
}
|
||||
|
||||
export async function getImgList(data) {
|
||||
data = stringify(data)
|
||||
return request({
|
||||
url: `/admin/shop/libraryProduct/list?${data}`,
|
||||
method:'get',
|
||||
})
|
||||
}
|
||||
export async function saveBatchBarcode(data) {
|
||||
return request({
|
||||
url:'/admin/shop/libraryProduct/saveBatch',
|
||||
method:'put',
|
||||
data,
|
||||
headers: {
|
||||
'Content-Type': 'application/json;charset=UTF-8'
|
||||
}
|
||||
})
|
||||
}
|
||||
export default {
|
||||
getProductMapperList,
|
||||
getShopList,
|
||||
@ -141,4 +157,6 @@ export default {
|
||||
syncProductMaping,
|
||||
importGoodsData,
|
||||
syncShopImages,
|
||||
getImgList,
|
||||
saveBatchBarcode
|
||||
}
|
||||
|
||||
@ -1,23 +1,22 @@
|
||||
import request from '@/utils/request'
|
||||
import { URL } from '@/config'
|
||||
|
||||
|
||||
/**
|
||||
* @name 获取商品分类列表(下拉框)
|
||||
* @api
|
||||
* @api
|
||||
* @returns {
|
||||
* "id": 256, 1级分类ID
|
||||
* "label": "安防监控", 分类名称
|
||||
* "children": [ 二级分类数组
|
||||
* {
|
||||
* "id": 257, 二级分类ID
|
||||
* "label": "室内摄像机", 分类名称
|
||||
* "children": [], 三级分类数组
|
||||
* "pid": null
|
||||
* },
|
||||
* ],
|
||||
* "pid": null
|
||||
*}
|
||||
* "id": 256, 1级分类ID
|
||||
* "label": "安防监控", 分类名称
|
||||
* "children": [ 二级分类数组
|
||||
* {
|
||||
* "id": 257, 二级分类ID
|
||||
* "label": "室内摄像机", 分类名称
|
||||
* "children": [], 三级分类数组
|
||||
* "pid": null
|
||||
* },
|
||||
* ],
|
||||
* "pid": null
|
||||
*}
|
||||
*/
|
||||
|
||||
export function getList(params) {
|
||||
@ -28,8 +27,6 @@ export function getList(params) {
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
export function doEdit(data) {
|
||||
return request({
|
||||
url: URL.shop.product.base.doEdit,
|
||||
|
||||
@ -126,3 +126,32 @@ export function createSubAccount(params) {
|
||||
data: params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @name 检查店铺名字
|
||||
* @api api_url + '/admin/shop/esign/signed/contract/file'
|
||||
* @param { mchMobile }
|
||||
* @returns
|
||||
*/
|
||||
|
||||
export function checkShopName(params) {
|
||||
return request({
|
||||
url: URL.shop.merch.checkShopName,
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: params,
|
||||
})
|
||||
}
|
||||
//编辑用户信息
|
||||
export function updateUserInfo(data){
|
||||
return request({
|
||||
url: URL.shop.merch.update,
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: data,
|
||||
})
|
||||
}
|
||||
33
src/api/upload.js
Normal file
33
src/api/upload.js
Normal file
@ -0,0 +1,33 @@
|
||||
import request from '@/utils/request'
|
||||
import { URL } from '@/config'
|
||||
|
||||
export function batchNoApi(file, type) {
|
||||
const formData = new FormData()
|
||||
formData.append('upfile', file)
|
||||
formData.append('imgType', type)
|
||||
return new Promise((resolve, reject) => {
|
||||
request({
|
||||
url: URL.ocr.batchNoApi,
|
||||
method: 'post',
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
})
|
||||
.then((res) => {
|
||||
resolve(res)
|
||||
})
|
||||
.catch((e) => reject(console.warn(e)))
|
||||
})
|
||||
}
|
||||
|
||||
export function imgOcrResultApi(data) {
|
||||
return request({
|
||||
url: URL.ocr.imgOcrResultApi,
|
||||
method: 'POST',
|
||||
data,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
})
|
||||
}
|
||||
@ -29,6 +29,14 @@ let url = {
|
||||
disableUpdateShopApp:
|
||||
api_url + '/admin/admin/app-market-update/enable-or-disable',
|
||||
},
|
||||
baidu: {
|
||||
getBaiduSuggestion:
|
||||
api_url + '/mobile/shop/merch/baidu/place/v2/suggestion',
|
||||
},
|
||||
ocr: {
|
||||
batchNoApi: api_url + '/mobile/shop/lakala/tk/uploadOcrImg',
|
||||
imgOcrResultApi: api_url + '/mobile/shop/lakala/tk/imgOcrResult',
|
||||
},
|
||||
orderPush: {
|
||||
orderPushTest: api_url + '/mobile/account/login/push/testcase',
|
||||
},
|
||||
@ -255,6 +263,8 @@ let url = {
|
||||
editLanguage:
|
||||
api_url + '/admin/account/account-base-config/editLanguage',
|
||||
cleanCache: api_url + '/admin/account/account-base-config/cleanCache',
|
||||
report_list: api_url + '/admin/sns/snsUserReport/list',
|
||||
deal_report: '/admin/sns/snsUserReport/dealReport',
|
||||
},
|
||||
|
||||
user: {
|
||||
@ -437,6 +447,8 @@ let url = {
|
||||
merchDetail: api_url + '/admin/shop/merch/detail',
|
||||
// 审批商家申请入驻
|
||||
merchApproval: api_url + '/admin/shop/merch/approval',
|
||||
//更新商家信息
|
||||
update:api_url + '/admin/shop/merch/update',
|
||||
// 发起合同签署
|
||||
createByFile: api_url + '/admin/shop/esign/sign-flow/create-by-file',
|
||||
//查看商家签署合同
|
||||
@ -445,6 +457,8 @@ let url = {
|
||||
createShop: api_url + '/admin/shop/shop-store-base/mchinfo/to/storeinfo',
|
||||
//创建分账(补偿机制)
|
||||
createSubAccount: api_url + '/mobile/pay/lakala/ledger/applyLedgerMer',
|
||||
//检查店铺名字可用不
|
||||
checkShopName: api_url + '/mobile/shop/store/check-store-name-exists',
|
||||
},
|
||||
activity: {
|
||||
lottery: {
|
||||
|
||||
87
src/utils/file.js
Normal file
87
src/utils/file.js
Normal file
@ -0,0 +1,87 @@
|
||||
export async function compressImage(file, options = {}) {
|
||||
// 提取选项参数,设置默认值
|
||||
const {
|
||||
quality = 0.75,
|
||||
maxWidth = 800,
|
||||
maxHeight = 600
|
||||
} = options;
|
||||
|
||||
// 验证输入是否为有效的File对象
|
||||
if (!(file instanceof File)) {
|
||||
throw new Error('输入参数必须是一个File对象');
|
||||
}
|
||||
|
||||
// 检查文件类型是否为图片
|
||||
if (!file.type.startsWith('image/')) {
|
||||
throw new Error('输入文件必须是图片类型');
|
||||
}
|
||||
|
||||
// 创建一个Promise来处理异步操作
|
||||
return new Promise((resolve, reject) => {
|
||||
// 创建Image对象用于加载图片
|
||||
const img = new Image();
|
||||
|
||||
// 监听图片加载完成事件
|
||||
img.onload = () => {
|
||||
// 创建Canvas元素
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
// 获取原始图片尺寸
|
||||
let width = img.width;
|
||||
let height = img.height;
|
||||
|
||||
// 计算调整后的尺寸(保持原始比例)
|
||||
if (width > maxWidth) {
|
||||
height = height * (maxWidth / width);
|
||||
width = maxWidth;
|
||||
}
|
||||
|
||||
if (height > maxHeight) {
|
||||
width = width * (maxHeight / height);
|
||||
height = maxHeight;
|
||||
}
|
||||
|
||||
// 设置Canvas尺寸
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
|
||||
// 在Canvas上绘制图片
|
||||
ctx.drawImage(img, 0, 0, width, height);
|
||||
|
||||
// 将Canvas内容转换为Blob对象
|
||||
canvas.toBlob(
|
||||
(blob) => {
|
||||
if (!blob) {
|
||||
reject(new Error('图片转换失败'));
|
||||
return;
|
||||
}
|
||||
|
||||
// 创建新的File对象
|
||||
const compressedFile = new File(
|
||||
[blob],
|
||||
file.name,
|
||||
{ type: blob.type, lastModified: Date.now() }
|
||||
);
|
||||
|
||||
resolve(compressedFile);
|
||||
},
|
||||
file.type, // 使用原始图片类型
|
||||
quality // 压缩质量
|
||||
);
|
||||
};
|
||||
|
||||
// 监听图片加载错误事件
|
||||
img.onerror = () => reject(new Error('图片加载失败'));
|
||||
|
||||
// 读取图片数据
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => {
|
||||
img.src = reader.result;
|
||||
};
|
||||
reader.onerror = () => reject(new Error('文件读取失败'));
|
||||
|
||||
// 开始读取文件
|
||||
reader.readAsDataURL(file);
|
||||
});
|
||||
}
|
||||
@ -59,7 +59,6 @@ const requestConf = (config) => {
|
||||
let source_lang_json = JSON.parse(value)
|
||||
source_lang = source_lang_json.language
|
||||
}
|
||||
|
||||
config.params['source_lang'] = source_lang
|
||||
|
||||
const token = store.getters['user/token']
|
||||
|
||||
@ -30,7 +30,22 @@ export function convertRouter(asyncRoutes) {
|
||||
|
||||
route.children.push(obj)
|
||||
}
|
||||
|
||||
if (route.meta.title == '商品' && route.name == 'Vab320') {
|
||||
const obj = {
|
||||
path: '/goodsImgs',
|
||||
component: '@/views/product/goodsImg/goodsImgs',
|
||||
name: 'Vab88000',
|
||||
redirect: null,
|
||||
meta: {
|
||||
title: '商品图库管理',
|
||||
icon: '',
|
||||
noClosable: 0,
|
||||
hidden: null,
|
||||
},
|
||||
menuHidden: false,
|
||||
}
|
||||
route.children.push(obj)
|
||||
}
|
||||
if (route.meta.title == '店铺' && route.name == 'Vab330') {
|
||||
const obj = {
|
||||
path: '/storeConf',
|
||||
@ -84,7 +99,23 @@ export function convertRouter(asyncRoutes) {
|
||||
|
||||
route.children.push(obj)
|
||||
}
|
||||
if (route.meta.title == '设置') {
|
||||
const obj = {
|
||||
path: '/report',
|
||||
component: '@/views/settings/config/report.vue',
|
||||
name: 'Vab86001',
|
||||
redirect: null,
|
||||
meta: {
|
||||
title: '举报中心',
|
||||
icon: '',
|
||||
noClosable: 0,
|
||||
hidden: null,
|
||||
},
|
||||
menuHidden: false,
|
||||
}
|
||||
|
||||
route.children.push(obj)
|
||||
}
|
||||
if (route.meta.title == '基础') {
|
||||
const cloudPrintRoute = {
|
||||
path: '/cloudPrint',
|
||||
|
||||
@ -44,6 +44,11 @@
|
||||
v-model="form.crontab_minute"
|
||||
:placeholder="__('每分')"
|
||||
:style="{ width: '100%' }"
|
||||
filterable
|
||||
allow-create
|
||||
@blur="handleSelectBlur('crontab_minute')"
|
||||
@input="handleSelectInput($event, 'crontab_minute')"
|
||||
ref="minuteSelect"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in crontab_minute_opt"
|
||||
@ -60,6 +65,11 @@
|
||||
v-model="form.crontab_hour"
|
||||
:placeholder="__('小时')"
|
||||
:style="{ width: '100%' }"
|
||||
filterable
|
||||
allow-create
|
||||
@blur="handleSelectBlur('crontab_hour')"
|
||||
@input="handleSelectInput($event, 'crontab_hour')"
|
||||
ref="hourSelect"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in crontab_hour_opt"
|
||||
@ -78,6 +88,11 @@
|
||||
v-model="form.crontab_day"
|
||||
:placeholder="__('每天')"
|
||||
:style="{ width: '100%' }"
|
||||
filterable
|
||||
allow-create
|
||||
@blur="handleSelectBlur('crontab_day')"
|
||||
@input="handleSelectInput($event, 'crontab_day')"
|
||||
ref="daySelect"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in crontab_day_opt"
|
||||
@ -94,13 +109,18 @@
|
||||
v-model="form.crontab_month"
|
||||
:placeholder="__('每月')"
|
||||
:style="{ width: '100%' }"
|
||||
filterable
|
||||
allow-create
|
||||
@blur="handleSelectBlur('crontab_month')"
|
||||
@input="handleSelectInput($event, 'crontab_month')"
|
||||
ref="monthSelect"
|
||||
>
|
||||
<el-option
|
||||
<el-option
|
||||
v-for="item in crontab_month_opt"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@ -112,6 +132,11 @@
|
||||
v-model="form.crontab_week"
|
||||
:placeholder="__('每周')"
|
||||
:style="{ width: '100%' }"
|
||||
filterable
|
||||
allow-create
|
||||
@input="handleSelectInput($event, 'crontab_week')"
|
||||
@blur="handleSelectBlur('crontab_week')"
|
||||
ref="weekSelect"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in crontab_week_opt"
|
||||
@ -239,6 +264,37 @@
|
||||
}
|
||||
this.crontab_month_opt = crontab_month_opt
|
||||
},
|
||||
handleSelectInput(value, field) {
|
||||
// 对于自定义输入,value 可能为 null,需要特殊处理
|
||||
if (value === null) {
|
||||
// 直接获取输入框的值
|
||||
const inputValue = this.$refs[`${field}Select`].$refs.input.value;
|
||||
if (inputValue) {
|
||||
this.$set(this.form, field, inputValue.trim());
|
||||
}
|
||||
} else {
|
||||
this.$set(this.form, field, value);
|
||||
}
|
||||
},
|
||||
|
||||
// 处理失去焦点事件 - 确保值被正确保留
|
||||
handleSelectBlur(field) {
|
||||
const selectComp = this.$refs[`${field}Select`];
|
||||
if (selectComp) {
|
||||
const inputValue = selectComp.$refs.input.value.trim();
|
||||
const currentValue = this.form[field];
|
||||
|
||||
// 如果输入框有值但未被正确绑定,则强制绑定
|
||||
if (inputValue && inputValue !== currentValue) {
|
||||
this.$set(this.form, field, inputValue);
|
||||
|
||||
// 手动更新组件内部状态,防止显示异常
|
||||
selectComp.currentValue = inputValue;
|
||||
selectComp.selectedLabel = inputValue;
|
||||
selectComp.$forceUpdate();
|
||||
}
|
||||
}
|
||||
},
|
||||
initHour() {
|
||||
let crontab_hour_opt = []
|
||||
crontab_hour_opt.push({
|
||||
|
||||
@ -675,6 +675,7 @@
|
||||
return item.spec_id
|
||||
})
|
||||
.join(',')
|
||||
|
||||
},
|
||||
// 品牌默认选中
|
||||
brandDefaultSelected(brandIds) {
|
||||
|
||||
@ -361,6 +361,7 @@ export default {
|
||||
// 统计申请总额
|
||||
getSummaries(param) {
|
||||
const { columns, data } = param
|
||||
|
||||
const sums = []
|
||||
sums[0] = '申请总额'
|
||||
columns.forEach((column, index) => {
|
||||
|
||||
@ -1295,7 +1295,6 @@
|
||||
}
|
||||
|
||||
const unitIndex = this.virtualHead.findIndex(item => item.property === 'item_unit_price');
|
||||
|
||||
if (unitIndex !== -1) {
|
||||
this.virtualHead[unitIndex].label = this.__('成本价');
|
||||
|
||||
@ -1766,6 +1765,7 @@
|
||||
this.row = Object.assign({}, row)
|
||||
|
||||
if (row != null) {
|
||||
|
||||
this.categoryId = row.category_id
|
||||
this.productForm.category_id = row.category_id
|
||||
this.productForm.text_category_id = row.category_name
|
||||
@ -1888,6 +1888,7 @@
|
||||
productSpec: this.getProductSpec(),
|
||||
valid: validForm ? validForm : '',
|
||||
}
|
||||
|
||||
const specData = this.specData
|
||||
for (let i = 0; i < specData.length; i++) {
|
||||
if (specData[i].item_unit_price <= 0 && specData[i].item_unit_points <= 0) {
|
||||
@ -1967,15 +1968,18 @@
|
||||
},
|
||||
async getType(type_id) {
|
||||
const { data } = await get({ type_id: type_id })
|
||||
this.brands = data.brands
|
||||
this.assists = data.assists
|
||||
this.specs = data.specs
|
||||
if(data){
|
||||
this.brands = data.brands
|
||||
this.assists = data.assists
|
||||
this.specs = data.specs
|
||||
|
||||
// 维护image类型的spec
|
||||
// this.initSpecImageList()
|
||||
// 动态添加vue 属性
|
||||
this.initAssistArr(this.assists)
|
||||
this.initCheckSpecArr(this.specs)
|
||||
// 维护image类型的spec
|
||||
// this.initSpecImageList()
|
||||
// 动态添加vue 属性
|
||||
this.initAssistArr(this.assists)
|
||||
this.initCheckSpecArr(this.specs)
|
||||
}
|
||||
|
||||
},
|
||||
// 初始化vue属性 assistArr
|
||||
initAssistArr(assists) {
|
||||
|
||||
@ -55,7 +55,7 @@
|
||||
<el-input
|
||||
v-model.trim="queryForm.product_id"
|
||||
clearable
|
||||
:placeholder="__('产品编号')"
|
||||
:placeholder="__('商品编号')"
|
||||
style="width: 100px"
|
||||
/>
|
||||
</el-form-item>
|
||||
@ -68,12 +68,19 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item prop="store_name">
|
||||
<el-input
|
||||
v-model.trim="queryForm.store_name"
|
||||
<el-select
|
||||
v-model="queryForm.store_id"
|
||||
clearable
|
||||
:placeholder="__('所属店铺')"
|
||||
style="width: 100px"
|
||||
/>
|
||||
filterable
|
||||
placeholder="选择店铺"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in shopList"
|
||||
:key="item.store_id"
|
||||
:label="item.store_name"
|
||||
:value="item.store_id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item prop="brand_id">
|
||||
<el-select
|
||||
@ -98,7 +105,7 @@
|
||||
<el-select
|
||||
v-model.trim="queryForm.product_state_id"
|
||||
clearable
|
||||
:placeholder="__('产品状态')"
|
||||
:placeholder="__('商品状态')"
|
||||
style="width: 100px"
|
||||
>
|
||||
<el-option
|
||||
@ -230,7 +237,7 @@
|
||||
<el-table-column
|
||||
align="center"
|
||||
fixed="left"
|
||||
:label="__('产品编号')"
|
||||
:label="__('商品编号')"
|
||||
prop="product_id"
|
||||
/>
|
||||
<el-table-column
|
||||
@ -255,7 +262,7 @@
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
:label="__('产品名称')"
|
||||
:label="__('商品名称')"
|
||||
prop="product_name"
|
||||
show-overflow-tooltip
|
||||
width="200"
|
||||
@ -467,7 +474,7 @@ import {
|
||||
import Table from './components/ProductItemTable'
|
||||
import StockTable from './components/OutOfStockTable'
|
||||
import ReviewEdit from './components/ReviewEdit'
|
||||
|
||||
import GoodsToolApi from '@/api/goodsTool'
|
||||
export default {
|
||||
name: 'ProductManagement',
|
||||
components: { TreeSelect, Table, StockTable, ReviewEdit },
|
||||
@ -526,7 +533,7 @@ import {
|
||||
label:"是"
|
||||
}
|
||||
],
|
||||
data: [], // 产品规格数据
|
||||
data: [], // 商品规格数据
|
||||
defaultProps: {
|
||||
children: 'children',
|
||||
label: 'label',
|
||||
@ -554,6 +561,7 @@ import {
|
||||
}
|
||||
this.queryData()
|
||||
this.getTree()
|
||||
this.getShopList()
|
||||
},
|
||||
methods: {
|
||||
__,
|
||||
@ -563,6 +571,10 @@ import {
|
||||
outOfStock(row) {
|
||||
this.$refs['StockTable'].showTable(row)
|
||||
},
|
||||
async getShopList() {
|
||||
let res = await GoodsToolApi.getShopList()
|
||||
this.shopList = res.data.items
|
||||
},
|
||||
reviewEdit(row) {
|
||||
this.$refs['ReviewEdit'].showTable(row)
|
||||
},
|
||||
@ -642,22 +654,30 @@ import {
|
||||
|
||||
async review(product_state_id) {
|
||||
if (this.selectRows.length > 0) {
|
||||
let product_id = this.selectRows.map((item) => item.product_id)
|
||||
let product_id = this.selectRows.map((item) => item.product_id);
|
||||
|
||||
// 步骤1:显示加载状态(可选,增强用户感知)
|
||||
this.listLoading = true; // 复用表格的加载状态,让用户看到“正在处理”
|
||||
|
||||
// 步骤2:添加延迟(核心,控制等待时长)
|
||||
await new Promise(resolve => setTimeout(resolve, 11000));
|
||||
|
||||
// 步骤3:调用下架接口(原逻辑不变)
|
||||
const { msg, status } = await editState({
|
||||
product_state_id: product_state_id,
|
||||
product_id: product_id.toString(),
|
||||
})
|
||||
});
|
||||
|
||||
if (200 == status) {
|
||||
this.$baseMessage(msg, 'success')
|
||||
this.$baseMessage(msg, 'success');
|
||||
} else {
|
||||
this.$baseMessage(msg, 'error')
|
||||
this.$baseMessage(msg, 'error');
|
||||
}
|
||||
|
||||
await this.fetchData()
|
||||
await this.fetchData();
|
||||
this.listLoading = false; // 关闭加载状态
|
||||
} else {
|
||||
this.$baseMessage(this.__('未选中任何行'), 'error')
|
||||
return false
|
||||
this.$baseMessage(this.__('未选中任何行'), 'error');
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
177
src/views/product/goodsImg/batchEditBarcode.vue
Normal file
177
src/views/product/goodsImg/batchEditBarcode.vue
Normal file
@ -0,0 +1,177 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
title="批量编辑商品编码"
|
||||
:visible.sync="visible"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
:max-height="600"
|
||||
@close="handleClose"
|
||||
>
|
||||
<div class="batch-tip">
|
||||
共选中
|
||||
{{ selectedData.length }} 个商品,请为每个商品设置编码(仅填写需要修改的)
|
||||
</div>
|
||||
|
||||
<!-- 批量编辑列表 -->
|
||||
<div
|
||||
class="edit-list"
|
||||
style="max-height: 400px; overflow-y: auto; padding-right: 10px"
|
||||
>
|
||||
<el-form ref="batchForm" :model="formData" label-width="100px">
|
||||
<!-- 循环渲染每个选中的商品 -->
|
||||
<div
|
||||
v-for="(item, index) in formData.items"
|
||||
:key="item.id"
|
||||
class="edit-item"
|
||||
>
|
||||
<el-form-item label="商品ID" :label-width="100">
|
||||
<div class="product-id">{{ item.id }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品名称" :label-width="100">
|
||||
<div class="product-name">{{ item.name }}</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item
|
||||
label="商品编码"
|
||||
:prop="`items[${index}].barcode`"
|
||||
:rules="[
|
||||
{ required: false, message: '请输入商品编码', trigger: 'blur' },
|
||||
]"
|
||||
:label-width="100"
|
||||
>
|
||||
<el-input
|
||||
v-model="item.barcode"
|
||||
placeholder="请输入商品编码"
|
||||
clearable
|
||||
maxlength="50"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-divider v-if="index !== formData.items.length - 1" />
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit">提交修改</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GoodsToolApi from '@/api/goodsTool'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
selectedData: [], // 选中的商品数据
|
||||
formData: {
|
||||
items: [], // 用于编辑的商品列表
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 打开弹窗并初始化数据
|
||||
open(selection) {
|
||||
this.visible = true
|
||||
this.selectedData = [...selection]
|
||||
|
||||
// 初始化表单数据
|
||||
this.formData.items = this.selectedData.map((item) => ({
|
||||
id: item.id,
|
||||
name: item.name || '未知名称',
|
||||
barcode: item.barcode || '', // 保留原有编码
|
||||
}))
|
||||
|
||||
// 重置表单验证
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.batchForm) {
|
||||
this.$refs.batchForm.clearValidate()
|
||||
}
|
||||
})
|
||||
},
|
||||
handleClose() {
|
||||
this.visible = false
|
||||
this.selectedData = []
|
||||
this.formData.items = []
|
||||
if (this.$refs.batchForm) {
|
||||
this.$refs.batchForm.clearValidate()
|
||||
}
|
||||
},
|
||||
|
||||
// 提交批量修改
|
||||
async handleSubmit() {
|
||||
// 表单验证
|
||||
try {
|
||||
await this.$refs.batchForm.validate()
|
||||
} catch (error) {
|
||||
return false
|
||||
}
|
||||
|
||||
// 构建提交数据 - 只包含有填写编码的商品
|
||||
const submitData = this.formData.items
|
||||
.filter((item) => item.barcode.trim() !== '') // 过滤掉未填写编码的
|
||||
.map((item) => ({
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
barcode: item.barcode.trim(),
|
||||
}))
|
||||
|
||||
if (submitData.length === 0) {
|
||||
this.$message.warning('请至少填写一个商品编码')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
// 调用接口提交数据
|
||||
const res = await GoodsToolApi.saveBatchBarcode(submitData)
|
||||
console.log('批量修改结果:', res)
|
||||
|
||||
this.$message.success(`成功修改 ${submitData.length} 个商品编码`)
|
||||
this.handleClose()
|
||||
this.$emit('success') // 通知父组件刷新列表
|
||||
} catch (error) {
|
||||
console.error('批量修改失败:', error)
|
||||
this.$message.error('修改失败,请重试')
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.batch-tip {
|
||||
color: #666;
|
||||
padding: 8px 12px;
|
||||
background-color: #f5f7fa;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 16px;
|
||||
font-size: 13px;
|
||||
border-left: 3px solid #409eff;
|
||||
}
|
||||
|
||||
.edit-item {
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.product-name {
|
||||
line-height: 32px;
|
||||
color: #333;
|
||||
max-width: 400px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.product-id {
|
||||
line-height: 32px;
|
||||
color: #666;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
::v-deep .el-form-item {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
158
src/views/product/goodsImg/editGoodsImgs.vue
Normal file
158
src/views/product/goodsImg/editGoodsImgs.vue
Normal file
@ -0,0 +1,158 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="dialogTitle"
|
||||
:visible.sync="visible"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-form
|
||||
ref="editForm"
|
||||
:model="formData"
|
||||
:rules="formRules"
|
||||
label-width="120px"
|
||||
class="edit-form"
|
||||
>
|
||||
<el-form-item label="商品id" prop="id">
|
||||
<el-input
|
||||
v-model="formData.id"
|
||||
placeholder="请输入商品id"
|
||||
disabled
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品名称" prop="name">
|
||||
<el-input
|
||||
v-model="formData.name"
|
||||
placeholder="请输入商品名称"
|
||||
disabled
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="商品编码" prop="barcode">
|
||||
<el-input
|
||||
v-model="formData.barcode"
|
||||
placeholder="请输入商品编码"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit">提交</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GoodsToolApi from '@/api/goodsTool'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
isBatch: false, // 是否批量编辑
|
||||
selectedData: [], // 选中的数据
|
||||
formData: {
|
||||
id: '',
|
||||
barcode: '',
|
||||
name: ''
|
||||
},
|
||||
formRules: {
|
||||
barcode: [
|
||||
{ required: false, message: '请输入商品编码', trigger: 'blur' }
|
||||
],
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 弹窗标题
|
||||
dialogTitle() {
|
||||
return this.isBatch ? '批量编辑商品' : '编辑商品'
|
||||
},
|
||||
// 选中数量
|
||||
selectedCount() {
|
||||
return this.selectedData.length
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 打开弹窗
|
||||
open(options) {
|
||||
this.isBatch = options.isBatch
|
||||
this.selectedData = options.data instanceof Array ? options.data : [options.data]
|
||||
this.visible = true
|
||||
|
||||
// 单条编辑时填充当前数据
|
||||
if (!this.isBatch && this.selectedData.length > 0) {
|
||||
const item = this.selectedData[0]
|
||||
this.formData = {
|
||||
name: item.name || '',
|
||||
barcode: item.barcode || '',
|
||||
id: item.id || ''
|
||||
}
|
||||
} else {
|
||||
// 批量编辑清空表单
|
||||
this.formData = {
|
||||
name: '',
|
||||
barcode: '',
|
||||
id: ''
|
||||
}
|
||||
}
|
||||
|
||||
// 重置表单验证
|
||||
this.$nextTick(() => {
|
||||
this.$refs.editForm.clearValidate()
|
||||
})
|
||||
},
|
||||
|
||||
// 关闭弹窗
|
||||
handleClose() {
|
||||
this.visible = false
|
||||
this.$refs.editForm.clearValidate()
|
||||
},
|
||||
|
||||
// 提交编辑
|
||||
async handleSubmit() {
|
||||
// 表单验证
|
||||
try {
|
||||
await this.$refs.editForm.validate()
|
||||
} catch (error) {
|
||||
return false
|
||||
}
|
||||
|
||||
// 构建提交数据 - 只包含有修改的字段
|
||||
const updateData = this.selectedData.map(item => {
|
||||
const data = { id: item.id }
|
||||
if (this.formData.barcode !== '') data.barcode = this.formData.barcode
|
||||
return data
|
||||
})
|
||||
|
||||
try {
|
||||
let res=await GoodsToolApi.saveBatchBarcode(updateData)
|
||||
this.$message.success(this.isBatch ? '批量编辑成功' : '编辑成功')
|
||||
this.visible = false
|
||||
// 通知父组件刷新列表
|
||||
this.$emit('success')
|
||||
} catch (error) {
|
||||
console.error('编辑商品失败:', error)
|
||||
this.$message.error('编辑失败,请重试')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.edit-form {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.batch-tip {
|
||||
color: #666;
|
||||
padding: 8px 12px;
|
||||
background-color: #f5f7fa;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 20px;
|
||||
font-size: 13px;
|
||||
border-left: 3px solid #409eff;
|
||||
}
|
||||
</style>
|
||||
351
src/views/product/goodsImg/goodsImgs.vue
Normal file
351
src/views/product/goodsImg/goodsImgs.vue
Normal file
@ -0,0 +1,351 @@
|
||||
<template>
|
||||
<div class="imgs-container">
|
||||
<div class="filter">
|
||||
<el-input
|
||||
v-model="filter.name"
|
||||
class="input_item"
|
||||
clearable
|
||||
placeholder="请输入商品名字"
|
||||
prefix-icon="el-icon-search"
|
||||
/>
|
||||
<el-input
|
||||
v-model="filter.barcode"
|
||||
class="input_item"
|
||||
clearable
|
||||
placeholder="请输入商品条码"
|
||||
prefix-icon="el-icon-barcode"
|
||||
/>
|
||||
<el-select
|
||||
v-model="filter.barcodeEmty"
|
||||
clearable
|
||||
placeholder="条码是否为空"
|
||||
class="input_item"
|
||||
>
|
||||
<el-option label="无条码" value="yes" />
|
||||
<el-option label="有条码" value="no" />
|
||||
</el-select>
|
||||
<el-button size="medium" type="primary" @click="handleSearch">
|
||||
查询
|
||||
</el-button>
|
||||
<el-button size="medium" @click="handleReset">重置</el-button>
|
||||
<el-button size="medium" type="warning" @click="handleBatchEdit">
|
||||
批量编辑
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="list">
|
||||
<el-table
|
||||
ref="imgTable"
|
||||
:data="tableData"
|
||||
style="width: 100%"
|
||||
border
|
||||
stripe
|
||||
:empty-text="tableData.length === 0 ? '暂无商品数据' : '加载中...'"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="55" />
|
||||
<!-- 操作列:编辑 + 新增保存按钮 -->
|
||||
<el-table-column label="操作" width="100">
|
||||
<template #default="scope">
|
||||
<!-- 保存按钮:点击提交当前行条码修改 -->
|
||||
<el-button
|
||||
plain
|
||||
size="mini"
|
||||
type="success"
|
||||
@click="handleSaveSingle(scope.row)"
|
||||
:loading="scope.row.saveLoading"
|
||||
>
|
||||
保存
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品条码" width="180">
|
||||
<template #default="scope">
|
||||
<el-input
|
||||
v-model="scope.row.barcode"
|
||||
placeholder="请输入商品条码"
|
||||
clearable
|
||||
size="small"
|
||||
class="barcode-input"
|
||||
:disabled="scope.row.saveLoading"
|
||||
@change="handleBarcodeChange(scope.row)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品主图" width="180px">
|
||||
<template #default="scope">
|
||||
<div v-if="scope.row.thumb" class="img-group">
|
||||
<el-image
|
||||
:src="scope.row.thumb"
|
||||
:preview-src-list="[scope.row.thumb]"
|
||||
class="img-thumb"
|
||||
fit="cover"
|
||||
:title="scope.row.name || '商品主图'"
|
||||
/>
|
||||
</div>
|
||||
<span v-else class="no-data">无主图</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品名称" prop="name" width="300">
|
||||
<template #default="scope">
|
||||
<div class="text-ellipsis" :title="scope.row.name">
|
||||
{{ scope.row.name }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品id" prop="id" width="120px" />
|
||||
<el-table-column label="分类" prop="category" width="120" />
|
||||
<el-table-column label="价格" width="120">
|
||||
<template #default="scope">
|
||||
{{ Number(scope.row.price).toFixed(2) }} 元
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" prop="createdAt" width="180" />
|
||||
<el-table-column label="更新时间" prop="updatedAt" width="180" />
|
||||
</el-table>
|
||||
|
||||
<el-pagination
|
||||
background
|
||||
:current-page="pagination.pageNum"
|
||||
:page-size="pagination.pageSize"
|
||||
:total="pagination.total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
:disabled="pagination.total === 0"
|
||||
/>
|
||||
</div>
|
||||
<batchEditBarcode ref="batchEditBarcode" @success="handleEditSuccess" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GoodsToolApi from '@/api/goodsTool'
|
||||
import batchEditBarcode from './batchEditBarcode.vue'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
tableData: [],
|
||||
pagination: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
pages: 0,
|
||||
},
|
||||
filter: {
|
||||
name: '',
|
||||
barcode: '',
|
||||
barcodeEmty: '', // 条码是否为空: 'yes'无条码, 'no'有条码
|
||||
},
|
||||
multipleSelection: [],
|
||||
}
|
||||
},
|
||||
components: {
|
||||
batchEditBarcode,
|
||||
},
|
||||
mounted() {
|
||||
this.handleImgList()
|
||||
},
|
||||
methods: {
|
||||
// 表格数据获取
|
||||
async handleImgList() {
|
||||
try {
|
||||
const params = {
|
||||
pageNum: this.pagination.pageNum,
|
||||
pageSize: this.pagination.pageSize,
|
||||
...(this.filter.name && { name: this.filter.name }),
|
||||
...(this.filter.barcode && { barcode: this.filter.barcode }),
|
||||
...(this.filter.barcodeEmty && {
|
||||
barcodeEmty: this.filter.barcodeEmty,
|
||||
}),
|
||||
}
|
||||
|
||||
const res = await GoodsToolApi.getImgList(params)
|
||||
|
||||
// 给每一行添加“保存加载状态”字段,避免重复提交
|
||||
this.tableData = (res.records || []).map(item => ({
|
||||
...item,
|
||||
saveLoading: false, // 保存按钮加载状态
|
||||
originalBarcode: item.barcode, // 存储原始条码,用于对比是否修改
|
||||
}))
|
||||
this.pagination.total = res.total || 0
|
||||
this.pagination.pages = res.pages || 0
|
||||
this.pagination.current = res.current || 1
|
||||
|
||||
console.log('商品列表数据获取成功', {
|
||||
tableData: this.tableData,
|
||||
pagination: this.pagination,
|
||||
params: params,
|
||||
})
|
||||
} catch (error) {
|
||||
this.$message.error('获取数据失败,请重试')
|
||||
this.tableData = []
|
||||
}
|
||||
},
|
||||
|
||||
// 查询
|
||||
handleSearch() {
|
||||
this.pagination.pageNum = 1
|
||||
this.handleImgList()
|
||||
},
|
||||
|
||||
// 重置查询条件
|
||||
handleReset() {
|
||||
this.filter = {
|
||||
name: '',
|
||||
barcode: '',
|
||||
barcodeEmty: '',
|
||||
}
|
||||
this.pagination.pageNum = 1
|
||||
this.handleImgList()
|
||||
},
|
||||
|
||||
// 分页切换
|
||||
handleCurrentChange(pageNum) {
|
||||
this.pagination.pageNum = pageNum
|
||||
this.handleImgList()
|
||||
},
|
||||
|
||||
handleSizeChange(pageSize) {
|
||||
this.pagination.pageSize = pageSize
|
||||
this.pagination.pageNum = 1
|
||||
this.handleImgList()
|
||||
},
|
||||
|
||||
// 表格选中
|
||||
handleSelectionChange(val) {
|
||||
this.multipleSelection = val
|
||||
},
|
||||
|
||||
// 批量编辑
|
||||
handleBatchEdit() {
|
||||
if (this.multipleSelection.length === 0) {
|
||||
this.$message.warning('请先选中需要编辑的商品');
|
||||
return;
|
||||
}
|
||||
this.$refs.batchEditBarcode.open(this.multipleSelection);
|
||||
},
|
||||
|
||||
// 单条保存(提交当前行条码修改)
|
||||
async handleSaveSingle(row) {
|
||||
// 条码未修改则不提交
|
||||
if (row.barcode === row.originalBarcode) {
|
||||
this.$message.info('商品条码未修改,无需保存');
|
||||
return;
|
||||
}
|
||||
|
||||
// 校验:条码格式
|
||||
if (row.barcode && row.barcode.length > 50) {
|
||||
this.$message.warning('商品条码长度不能超过50个字符');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 显示加载状态,禁用输入和按钮
|
||||
row.saveLoading = true;
|
||||
|
||||
// 调用接口提交(复用批量编辑接口,单条也按数组格式传参)
|
||||
const updateData = [{
|
||||
id: row.id,
|
||||
barcode: row.barcode || '', // 空值也提交(清除条码)
|
||||
}];
|
||||
let res=await GoodsToolApi.saveBatchBarcode(updateData);
|
||||
if(res.status==200){
|
||||
// 保存成功:更新原始条码,提示用户
|
||||
row.originalBarcode = row.barcode;
|
||||
this.$message.success('商品条码保存成功');
|
||||
}else{
|
||||
this.$message.error('操作异常');
|
||||
}
|
||||
} catch (error) {
|
||||
// 保存失败:回滚条码,提示错误
|
||||
row.barcode = row.originalBarcode;
|
||||
this.$message.error('保存失败,请重试');
|
||||
console.error('单条保存条码失败:', error);
|
||||
} finally {
|
||||
// 无论成功失败,关闭加载状态
|
||||
row.saveLoading = false;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
handleBarcodeChange(row) {
|
||||
if (row.barcode && row.barcode.length > 50) {
|
||||
this.$message.warning('商品条码长度不能超过50个字符');
|
||||
}
|
||||
},
|
||||
|
||||
// 编辑成功后刷新列表(批量编辑成功后调用)
|
||||
handleEditSuccess() {
|
||||
this.handleImgList();
|
||||
this.$refs.imgTable.clearSelection();
|
||||
this.multipleSelection = [];
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.filter {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 15px 20px;
|
||||
margin-bottom: 15px;
|
||||
gap: 10px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 1px 1px 6px rgba(0, 0, 0, 0.1);
|
||||
background: #fff;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.input_item {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.list {
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 1px 1px 6px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.img-group {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.img-thumb {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
cursor: pointer;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.text-ellipsis {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.no-data {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
// 调整条码输入框样式,使其更贴合表格
|
||||
.barcode-input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::v-deep .el-table__cell {
|
||||
vertical-align: middle !important;
|
||||
}
|
||||
|
||||
::v-deep .el-pagination {
|
||||
margin-top: 10px;
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
@ -137,12 +137,7 @@
|
||||
<el-checkbox
|
||||
v-for="item in spec.specItems"
|
||||
:key="item.spec_item_id"
|
||||
:disabled="
|
||||
!configs.config.product_spec_edit &&
|
||||
((newSpecItemIdRow.indexOf(item.spec_item_id) > -1 &&
|
||||
checkSpec[spec.spec_id].indexOf(item) > -1) ||
|
||||
!(allowCheckSpecRow.indexOf(spec.spec_id) > -1))
|
||||
"
|
||||
|
||||
:label="item"
|
||||
>
|
||||
{{ item.spec_item_name }}
|
||||
@ -607,7 +602,7 @@
|
||||
:model="productForm"
|
||||
size="medium"
|
||||
>
|
||||
<el-col :span="12">
|
||||
<!-- <el-col :span="12">
|
||||
<el-form-item :label="__('运费设置')" prop="transport_type_id">
|
||||
<el-select
|
||||
v-model="productForm.transport_type_id"
|
||||
@ -623,7 +618,7 @@
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-col> -->
|
||||
<el-col :span="12">
|
||||
<el-form-item :label="__('购买上限')" prop="product_buy_limit">
|
||||
<el-input
|
||||
@ -1387,6 +1382,7 @@ export default {
|
||||
let checkSpecElement = checkSpec[spec_id]
|
||||
return checkSpecElement.length > 0 && spec.spec_format === 'image'
|
||||
})
|
||||
|
||||
return sp ? sp.spec_id : null
|
||||
},
|
||||
// 四舍五入返回四位有效数字
|
||||
@ -1953,6 +1949,7 @@ export default {
|
||||
const strSpecs = this.shop_product_info
|
||||
? this.shop_product_info.product_spec
|
||||
: '{}'
|
||||
|
||||
const specs = JSON.parse(strSpecs)
|
||||
console.info('+++++++++++++++++')
|
||||
console.info(specs)
|
||||
@ -1966,11 +1963,13 @@ export default {
|
||||
const items = this.getSpecItemByIds(spec_id, idsArr)
|
||||
// 设置spec 勾选数据
|
||||
this.$set(this.checkSpec, spec_id, items)
|
||||
|
||||
console.info(items)
|
||||
items.forEach((item, index) => {
|
||||
that.newSpecItemIdRow.push(item.spec_item_id)
|
||||
})
|
||||
})
|
||||
|
||||
},
|
||||
initTableHead() {
|
||||
const checkSpec = this.checkSpec
|
||||
@ -2318,14 +2317,17 @@ export default {
|
||||
},
|
||||
async getType(type_id, productId) {
|
||||
const { data } = await get({ type_id: type_id, product_id: productId })
|
||||
this.brands = data.brands
|
||||
this.assists = data.assists
|
||||
this.specs = data.specs
|
||||
// 维护image类型的spec
|
||||
// this.initSpecImageList()
|
||||
// // 动态添加vue 属性
|
||||
this.initAssistArr(this.assists)
|
||||
this.initCheckSpecArr(this.specs)
|
||||
if(data){
|
||||
this.brands = data.brands
|
||||
this.assists = data.assists
|
||||
this.specs = data.specs
|
||||
// 维护image类型的spec
|
||||
// this.initSpecImageList()
|
||||
// // 动态添加vue 属性
|
||||
this.initAssistArr(this.assists)
|
||||
this.initCheckSpecArr(this.specs)
|
||||
}
|
||||
|
||||
},
|
||||
// 初始化vue属性 assistArr
|
||||
initAssistArr(assists) {
|
||||
|
||||
363
src/views/settings/config/report.vue
Normal file
363
src/views/settings/config/report.vue
Normal file
@ -0,0 +1,363 @@
|
||||
<template>
|
||||
<div class="report_container">
|
||||
<div class="filter">
|
||||
<el-input
|
||||
v-model="filter.reporterNickname"
|
||||
class="input_item"
|
||||
clearable
|
||||
placeholder="请输入举报人昵称"
|
||||
prefix-icon="el-icon-search"
|
||||
/>
|
||||
<el-select
|
||||
v-model="filter.processingStatus"
|
||||
clearable
|
||||
filterable
|
||||
placeholder="选择处理状态"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in reportList"
|
||||
:key="item.report_id"
|
||||
:label="item.report_name"
|
||||
:value="item.report_id"
|
||||
/>
|
||||
</el-select>
|
||||
|
||||
<el-button size="medium" type="primary" @click="handleSearch">
|
||||
查询
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="list">
|
||||
<el-table
|
||||
ref="reportTable"
|
||||
:data="tableData"
|
||||
style="width: 100%"
|
||||
border
|
||||
stripe
|
||||
>
|
||||
|
||||
<el-table-column label="举报正文" prop="reportContent" width="180px">
|
||||
<template #default="scope">
|
||||
<div class="text-ellipsis" :title="scope.row.reportContent">
|
||||
{{ scope.row.reportContent }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
|
||||
<el-table-column label="举报凭证" prop="reportVerify" width="180px">
|
||||
<template #default="scope">
|
||||
<div
|
||||
v-if="scope.row.reportVerify && scope.row.reportVerify.length"
|
||||
class="img-group"
|
||||
>
|
||||
<el-image
|
||||
v-for="(img, index) in scope.row.reportVerify"
|
||||
:key="index"
|
||||
:src="img.url"
|
||||
:preview-src-list="scope.row.reportVerify.map((item) => item.url)"
|
||||
class="img-thumb"
|
||||
fit="cover"
|
||||
:title="img.description || `举报凭证${index + 1}`"
|
||||
v-if="index < 3"
|
||||
/>
|
||||
<span v-if="scope.row.reportVerify.length > 3" class="img-count">
|
||||
+{{ scope.row.reportVerify.length - 3 }}
|
||||
</span>
|
||||
</div>
|
||||
<span v-else class="no-data">无凭证</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="举报人昵称" prop="reporterNickname" width="120" />
|
||||
<el-table-column
|
||||
label="举报人手机号"
|
||||
prop="reporterPhone"
|
||||
width="130"
|
||||
/>
|
||||
<el-table-column label="被举报人昵称" prop="reportedNickname" width="120" />
|
||||
<el-table-column label="被举报人用户ID" prop="reportedUserId" width="140" />
|
||||
<el-table-column label="举报时间" prop="reporterTime" width="180" />
|
||||
<el-table-column label="状态" prop="processingStatus" width="110">
|
||||
<template #default="scope">
|
||||
<el-tag :type="getStatusTagType(scope.row.processingStatus)">
|
||||
{{ getStatusText(scope.row.processingStatus) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- 处理凭证(后台上传) -->
|
||||
<el-table-column label="处理凭证" prop="processingVerify" width="180px">
|
||||
<template #default="scope">
|
||||
<div
|
||||
v-if="scope.row.processingVerify && scope.row.processingVerify.length"
|
||||
class="img-group"
|
||||
>
|
||||
<el-image
|
||||
v-for="(img, index) in scope.row.processingVerify"
|
||||
:key="index"
|
||||
:src="img.url"
|
||||
:preview-src-list="scope.row.processingVerify.map((item) => item.url)"
|
||||
class="img-thumb"
|
||||
fit="cover"
|
||||
:title="img.description || `处理凭证${index + 1}`"
|
||||
v-if="index < 3"
|
||||
/>
|
||||
<span v-if="scope.row.processingVerify.length > 3" class="img-count">
|
||||
+{{ scope.row.processingVerify.length - 3 }}
|
||||
</span>
|
||||
</div>
|
||||
<span v-else class="no-data">无处理凭证</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- 处理结果 -->
|
||||
<el-table-column label="处理结果" prop="processingResult" width="180px">
|
||||
<template #default="scope">
|
||||
<div class="text-ellipsis" :title="scope.row.processingResult">
|
||||
{{ scope.row.processingResult || '未处理' }}
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
plain
|
||||
size="mini"
|
||||
type="primary"
|
||||
@click="handleReport(scope.row)"
|
||||
:disabled="scope.row.processingStatus === '处理完成'"
|
||||
>
|
||||
处理举报
|
||||
</el-button>
|
||||
<el-button
|
||||
plain
|
||||
size="mini"
|
||||
type="primary"
|
||||
@click="handleDetail(scope.row)"
|
||||
>
|
||||
详情
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-pagination
|
||||
background
|
||||
:current-page="pagination.pageNum"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:page-size="pagination.pageSize"
|
||||
:total="pagination.total"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
/>
|
||||
<ReportDeal ref="handleReport" @success="handleSuccess" />
|
||||
<ReportDetail ref="handleDetail" @success="handleSuccess" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ReportDeal from './reportDeal.vue'
|
||||
import ReportDetail from './reportDetail.vue'
|
||||
import { getReportList } from '@/api/base/config'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ReportDeal,
|
||||
ReportDetail,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
filter: {
|
||||
reporterNickname: '',
|
||||
processingStatus: '',
|
||||
},
|
||||
reportList: [
|
||||
{ report_id: 0, report_name: '未处理' },
|
||||
{ report_id: 1, report_name: '已受理' },
|
||||
{ report_id: 2, report_name: '已驳回' },
|
||||
{ report_id: 3, report_name: '处理完成' },
|
||||
],
|
||||
tableData: [],
|
||||
pagination: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
pages: 0,
|
||||
},
|
||||
multipleSelection: [],
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.handleReportList()
|
||||
},
|
||||
methods: {
|
||||
handleReport(row) {
|
||||
this.$refs.handleReport.open(row)
|
||||
},
|
||||
handleDetail(row) {
|
||||
this.$refs.handleDetail.open(row)
|
||||
},
|
||||
handleSuccess() {
|
||||
this.handleReportList()
|
||||
},
|
||||
handleSelectionChange(val) {
|
||||
this.multipleSelection = val
|
||||
},
|
||||
async handleReportList() {
|
||||
try {
|
||||
const params = {
|
||||
pageNum: this.pagination.pageNum,
|
||||
pageSize: this.pagination.pageSize,
|
||||
reporterNickname: this.filter.reporterNickname,
|
||||
processingStatus: this.filter.processingStatus,
|
||||
}
|
||||
|
||||
const res = await getReportList(params)
|
||||
console.log('ssssss', params)
|
||||
this.tableData = (res.records || []).map((item) => ({
|
||||
id: item.id,
|
||||
reportContent: item.reportContent,
|
||||
// 解析用户举报凭证
|
||||
reportVerify: item.evidenceImages
|
||||
? JSON.parse(item.evidenceImages)
|
||||
: [],
|
||||
// 解析后台处理凭证
|
||||
processingVerify: item.processingEvidenceImages
|
||||
? JSON.parse(item.processingEvidenceImages)
|
||||
: [],
|
||||
// 处理结果
|
||||
processingResult: item.processingResult || '',
|
||||
reporterNickname: item.reporterNickname,
|
||||
reporterPhone: item.reporterPhone || '无',
|
||||
reporterTime: item.createdAt,
|
||||
processingStatus: this.getStatusText(item.processingStatus),
|
||||
reportedNickname: item.reportedNickname,
|
||||
reportedUserId: item.reportedUserId || '无',
|
||||
// 保留原始数据供弹窗使用
|
||||
rawData: item,
|
||||
}))
|
||||
|
||||
this.pagination = {
|
||||
...this.pagination,
|
||||
total: res.total || 0,
|
||||
pageNum: res.current || 1,
|
||||
pageSize: res.size || 10,
|
||||
pages: res.pages || 0,
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取举报列表失败:', error)
|
||||
this.$message.error('获取数据失败,请重试')
|
||||
}
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.pagination.pageNum = val
|
||||
this.handleReportList()
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.pagination.pageSize = val
|
||||
this.pagination.pageNum = 1
|
||||
this.handleReportList()
|
||||
},
|
||||
handleSearch() {
|
||||
this.pagination.pageNum = 1
|
||||
this.handleReportList()
|
||||
},
|
||||
getStatusText(status) {
|
||||
switch (status) {
|
||||
case 0:
|
||||
return '未处理'
|
||||
case 1:
|
||||
return '已受理'
|
||||
case 2:
|
||||
return '已驳回'
|
||||
case 3:
|
||||
return '处理完成'
|
||||
default:
|
||||
return '未知状态'
|
||||
}
|
||||
},
|
||||
getStatusTagType(state) {
|
||||
switch (state) {
|
||||
case '未处理':
|
||||
return 'warning'
|
||||
case '已受理':
|
||||
return 'info'
|
||||
case '已驳回':
|
||||
return 'danger'
|
||||
case '处理完成':
|
||||
return 'success'
|
||||
default:
|
||||
return 'default'
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.filter {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
margin-bottom: 15px;
|
||||
gap: 10px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 1px 1px 6px rgba(0, 0, 0, 0.1);
|
||||
background: #fff;
|
||||
|
||||
.input_item {
|
||||
width: 250px;
|
||||
}
|
||||
}
|
||||
.list {
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 1px 1px 6px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
// 图片样式
|
||||
.img-group {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
gap: 5px;
|
||||
}
|
||||
.img-thumb {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
cursor: pointer;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.img-count {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
// 文本省略样式
|
||||
.text-ellipsis {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
// 无数据样式
|
||||
.no-data {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
// 表格单元格垂直居中
|
||||
::v-deep .el-table__cell {
|
||||
vertical-align: middle !important;
|
||||
}
|
||||
</style>
|
||||
263
src/views/settings/config/reportDeal.vue
Normal file
263
src/views/settings/config/reportDeal.vue
Normal file
@ -0,0 +1,263 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
append-to-body
|
||||
title="处理举报"
|
||||
:visible.sync="visible"
|
||||
width="600px"
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
|
||||
<!-- 处理状态选择 -->
|
||||
<el-form-item label="处理状态" prop="processingStatus">
|
||||
<el-select
|
||||
v-model="form.processingStatus"
|
||||
placeholder="请选择处理状态"
|
||||
@change="handleStatusChange"
|
||||
clearable
|
||||
>
|
||||
<el-option label="受理中" value="1" />
|
||||
<el-option label="证据不足(已驳回)" value="2" />
|
||||
<el-option label="已处理" value="3" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 处理结果(状态2/3显示) -->
|
||||
<el-form-item
|
||||
label="处理结果"
|
||||
prop="processingResult"
|
||||
v-if="['2', '3'].includes(form.processingStatus)"
|
||||
>
|
||||
<el-input
|
||||
v-model="form.processingResult"
|
||||
type="textarea"
|
||||
rows="3"
|
||||
placeholder="请输入处理结果(如:已核实违规,封禁账号7天)"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 核心:上传区域(仅状态3显示,适配项目路由的OSS上传接口) -->
|
||||
<el-form-item
|
||||
label="佐证材料"
|
||||
v-if="form.processingStatus === '3'"
|
||||
prop="processingEvidenceImages"
|
||||
>
|
||||
<el-upload
|
||||
ref="evidenceUpload"
|
||||
:action="uploadUrl"
|
||||
:auto-upload="true"
|
||||
:data="uploadParams"
|
||||
:file-list="uploadFileList"
|
||||
:multiple="true"
|
||||
:on-success="handleUploadSuccess"
|
||||
:on-error="handleUploadError"
|
||||
:on-remove="handleFileRemove"
|
||||
list-type="picture-card"
|
||||
accept=".png,.jpg,.jpeg,.mp4,.avi"
|
||||
>
|
||||
<i class="el-icon-plus"></i>
|
||||
<div slot="tip" class="el-upload__tip">
|
||||
支持上传 PNG/JPG/MP4/AVI 格式,单个文件不超过50MB
|
||||
</div>
|
||||
</el-upload>
|
||||
|
||||
<!-- 已上传文件预览 -->
|
||||
<div v-if="uploadFileList.length > 0" style="margin-top: 15px;">
|
||||
<span class="el-text--primary">已上传文件:</span>
|
||||
<div style="display: flex; gap: 10px; margin-top: 8px; flex-wrap: wrap;">
|
||||
<!-- 图片预览 -->
|
||||
<div
|
||||
v-for="(file, index) in uploadFileList.filter(f => f.raw?.type.startsWith('image/'))"
|
||||
:key="index"
|
||||
style="position: relative; width: 80px; height: 80px;"
|
||||
>
|
||||
<el-image
|
||||
:src="file.url"
|
||||
style="width: 100%; height: 100%; object-fit: cover;"
|
||||
:preview-src-list="[file.url]"
|
||||
/>
|
||||
<el-button
|
||||
type="text"
|
||||
size="mini"
|
||||
style="position: absolute; top: -5px; right: -5px; color: #f56c6c;"
|
||||
@click.stop="handleFileRemove(file, index)"
|
||||
>
|
||||
<i class="el-icon-close"></i>
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 视频预览 -->
|
||||
<div
|
||||
v-for="(file, index) in uploadFileList.filter(f => f.raw?.type.startsWith('video/'))"
|
||||
:key="index"
|
||||
style="position: relative; width: 80px; height: 80px; background: #f5f7fa; display: flex; flex-direction: column; align-items: center; justify-content: center;"
|
||||
>
|
||||
<i class="el-icon-video-play" style="font-size: 24px; color: #409eff;"></i>
|
||||
<span style="font-size: 12px; margin-top: 5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; width: 70px;">
|
||||
{{ file.name }}
|
||||
</span>
|
||||
<el-button
|
||||
type="text"
|
||||
size="mini"
|
||||
style="position: absolute; top: -5px; right: -5px; color: #f56c6c;"
|
||||
@click.stop="handleFileRemove(file, index)"
|
||||
>
|
||||
<i class="el-icon-close"></i>
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div slot="footer">
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit">提交处理</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { URL } from '@/config';
|
||||
import { dealReport } from '@/api/base/config';
|
||||
import { getToken } from '@/utils/token';
|
||||
|
||||
export default {
|
||||
name: 'ReportDeal',
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
form: {
|
||||
id: null,
|
||||
processingStatus: '',
|
||||
processingResult: '',
|
||||
processingEvidenceImages: [] // 佐证材料(传给后端的格式)
|
||||
},
|
||||
// 表单验证规则
|
||||
rules: {
|
||||
processingStatus: [
|
||||
{ required: true, message: '请选择处理状态', trigger: 'change' }
|
||||
],
|
||||
processingResult: [
|
||||
{ required: true, message: '请输入处理结果', trigger: 'blur' },
|
||||
{ min: 10, message: '处理结果至少10个字符', trigger: 'blur' }
|
||||
],
|
||||
processingEvidenceImages: [
|
||||
{ required: true, message: '请上传佐证材料', trigger: 'change' }
|
||||
]
|
||||
},
|
||||
// 上传配置(完全适配项目路由)
|
||||
uploadUrl: URL.upload, // 从路由取OSS上传地址:api_url + '/admin/oss/upload'
|
||||
uploadParams: {
|
||||
authorization: getToken(),
|
||||
gallery_type: 'image' //
|
||||
},
|
||||
uploadFileList: [] // 上传文件列表
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 父组件调用:打开处理弹窗,传入举报记录
|
||||
open(row) {
|
||||
this.form = {
|
||||
...this.form,
|
||||
id: row.id, // 绑定举报ID
|
||||
processingStatus: '',
|
||||
processingResult: '',
|
||||
processingEvidenceImages: []
|
||||
};
|
||||
this.uploadFileList = []; // 清空历史上传
|
||||
this.visible = true;
|
||||
},
|
||||
|
||||
// 处理状态变化:非"已处理"时清空上传文件
|
||||
handleStatusChange(val) {
|
||||
if (val !== '3') {
|
||||
this.uploadFileList = [];
|
||||
this.form.processingEvidenceImages = [];
|
||||
} else {
|
||||
// 切换到"已处理"时,动态调整上传参数(如视频上传需改gallery_type)
|
||||
this.uploadParams.gallery_type = 'image';
|
||||
}
|
||||
},
|
||||
|
||||
// 上传成功回调
|
||||
handleUploadSuccess(response, file, fileList) {
|
||||
if (response.code == 0) {
|
||||
file.url = response.data.media_url; // 绑定后端返回的文件URL
|
||||
this.form.processingEvidenceImages = fileList.map(item => ({
|
||||
url: item.url,
|
||||
description: `佐证材料_${item.name}`
|
||||
}));
|
||||
this.$message.success(`文件 ${file.name} 上传成功`);
|
||||
} else {
|
||||
this.$message.error(`文件 ${file.name} 上传失败:${response.msg || '未知错误'}`);
|
||||
// 上传失败移除无效文件
|
||||
this.uploadFileList = this.uploadFileList.filter(item => item.uid !== file.uid);
|
||||
}
|
||||
},
|
||||
|
||||
// 上传失败回调
|
||||
handleUploadError(error, file) {
|
||||
this.$message.error(`文件 ${file.name} 上传失败:网络错误或接口异常`);
|
||||
this.uploadFileList = this.uploadFileList.filter(item => item.uid !== file.uid);
|
||||
},
|
||||
|
||||
// 移除文件回调
|
||||
handleFileRemove(file, index) {
|
||||
this.uploadFileList.splice(index, 1);
|
||||
// 同步更新佐证材料
|
||||
this.form.processingEvidenceImages = this.uploadFileList.map(item => ({
|
||||
url: item.url,
|
||||
description: `佐证材料_${item.name}`
|
||||
}));
|
||||
},
|
||||
|
||||
// 提交处理结果
|
||||
async handleSubmit() {
|
||||
this.$refs.form.validate(async (valid) => {
|
||||
if (!valid) return;
|
||||
|
||||
// 整理提交参数
|
||||
const submitData = {
|
||||
id: this.form.id,
|
||||
processingStatus: this.form.processingStatus,
|
||||
processingResult: this.form.processingResult
|
||||
};
|
||||
|
||||
// 状态3时添加佐证材料(转JSON字符串)
|
||||
if (this.form.processingStatus === '3') {
|
||||
submitData.processingEvidenceImages = JSON.stringify(this.form.processingEvidenceImages);
|
||||
}
|
||||
|
||||
try {
|
||||
await dealReport(submitData);
|
||||
this.$message.success('处理成功!');
|
||||
this.visible = false;
|
||||
this.$emit('success'); // 通知父组件刷新举报列表
|
||||
} catch (err) {
|
||||
this.$message.error(`处理失败:${err.message || '未知错误'}`);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
handleClose() {
|
||||
this.visible = false;
|
||||
this.$refs.form?.resetFields();
|
||||
this.uploadFileList = [];
|
||||
this.form.processingEvidenceImages = [];
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
::v-deep .el-upload {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
::v-deep .el-image-viewer__mask {
|
||||
background: rgba(0, 0, 0, 0.7) !important;
|
||||
}
|
||||
.el-upload__tip {
|
||||
color: #666 !important;
|
||||
font-size: 12px !important;
|
||||
}
|
||||
</style>
|
||||
75
src/views/settings/config/reportDetail.vue
Normal file
75
src/views/settings/config/reportDetail.vue
Normal file
@ -0,0 +1,75 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:visible.sync="visible"
|
||||
title="举报详情"
|
||||
width="600px"
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<div>
|
||||
<p>
|
||||
<strong>举报正文:</strong>
|
||||
{{ detailData.reportContent }}
|
||||
</p>
|
||||
<div>
|
||||
<p><strong>举报凭证:</strong></p>
|
||||
<div class="verify_container">
|
||||
<div v-for="verify_item in detailData.reportVerify">
|
||||
<img :src="verify_item.url" class="verify_img" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
<strong>举报人:</strong>
|
||||
{{ detailData.reporterName }}
|
||||
</p>
|
||||
<p>
|
||||
<strong>举报时间:</strong>
|
||||
{{ detailData.reporterTime }}
|
||||
</p>
|
||||
<p>
|
||||
<strong>状态:</strong>
|
||||
<el-tag :type="detailData.state === '未处理' ? 'warning' : 'success'">
|
||||
{{ detailData.state }}
|
||||
</el-tag>
|
||||
</p>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ReportDetail',
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
detailData: {},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 打开对话框并接收数据
|
||||
open(row) {
|
||||
this.detailData = row
|
||||
this.visible = true // 显示对话框
|
||||
},
|
||||
// 关闭对话框
|
||||
handleClose() {
|
||||
this.visible = false
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.verify_container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.verify_img {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
@ -61,6 +61,9 @@
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="__('分账比例')" prop="split_ratio">
|
||||
<el-input v-model.trim="form.split_ratio" :placeholder="__('比例在70%-99%之间')" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item :label="__('所属分站')" prop="subsite_id">
|
||||
<el-select
|
||||
v-model.trim="form.subsite_id"
|
||||
@ -155,6 +158,7 @@ export default {
|
||||
store_type: 1,
|
||||
store_o2o_flag: 0,
|
||||
subsite_id: 0,
|
||||
split_ratio:0,
|
||||
},
|
||||
rules: {
|
||||
user_password: [
|
||||
|
||||
@ -92,7 +92,7 @@
|
||||
<el-form-item
|
||||
label="营业状态"
|
||||
label-width="150px"
|
||||
prop="store_district_id"
|
||||
prop="store_biz_state"
|
||||
>
|
||||
<el-switch
|
||||
v-model="storeForm.store_biz_state"
|
||||
@ -102,8 +102,47 @@
|
||||
inactive-color="#ff4949"
|
||||
active-text="营业中"
|
||||
@change="handleStoreStatus"
|
||||
inactive-text="已打烊">
|
||||
</el-switch>
|
||||
inactive-text="已打烊"
|
||||
></el-switch>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<div class="grid-content bg-purple">
|
||||
<el-form-item
|
||||
label="语音播报"
|
||||
label-width="150px"
|
||||
prop="ringtone_is_enable"
|
||||
>
|
||||
<el-switch
|
||||
v-model="storeForm.ringtone_is_enable"
|
||||
:active-value="1"
|
||||
:inactive-value="2"
|
||||
@change="handleRingStatus"
|
||||
active-text="开启"
|
||||
inactive-text="关闭"
|
||||
></el-switch>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<div class="grid-content bg-purple">
|
||||
<el-form-item
|
||||
label="打包费"
|
||||
label-width="150px"
|
||||
prop="store_longitude"
|
||||
:style="{ width: '100%' }"
|
||||
>
|
||||
<el-input
|
||||
v-model="storeForm.packing_fee"
|
||||
clearable
|
||||
placeholder="请输入打包费"
|
||||
:style="{ width: '80%' }"
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-col>
|
||||
@ -444,268 +483,76 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { translateTitle as __ } from '@/utils/i18n'
|
||||
import VabQuill from '@/extra/VabQuill'
|
||||
import Area from '@/components/VabArea/area'
|
||||
import upload from '@/components/upload'
|
||||
import tree from '@/components/universalTreeSelect.vue'
|
||||
import keyword from '@/components/baiduMap/keyword'
|
||||
import { get, storeSetUp } from '@/api/store/base'
|
||||
import { getTree } from '@/api/base/market/category'
|
||||
import { handleMatched } from '@/utils/routes'
|
||||
import { translateTitle as __ } from '@/utils/i18n'
|
||||
import VabQuill from '@/extra/VabQuill'
|
||||
import Area from '@/components/VabArea/area'
|
||||
import upload from '@/components/upload'
|
||||
import tree from '@/components/universalTreeSelect.vue'
|
||||
import keyword from '@/components/baiduMap/keyword'
|
||||
import { get, storeSetUp } from '@/api/store/base'
|
||||
import { getTree } from '@/api/base/market/category'
|
||||
import { handleMatched } from '@/utils/routes'
|
||||
|
||||
export default {
|
||||
name: 'SetUpShop',
|
||||
components: { VabQuill, Area, upload, keyword, tree },
|
||||
data() {
|
||||
return {
|
||||
tableConfig: {
|
||||
height: window.innerHeight - 220 - 90,
|
||||
},
|
||||
test: 666,
|
||||
treeData: [],
|
||||
activeName: 'first',
|
||||
optionslist: [
|
||||
{
|
||||
value: '1001',
|
||||
label: this.__('免费停车'),
|
||||
export default {
|
||||
name: 'SetUpShop',
|
||||
components: { VabQuill, Area, upload, keyword, tree },
|
||||
data() {
|
||||
return {
|
||||
tableConfig: {
|
||||
height: window.innerHeight - 220 - 90,
|
||||
},
|
||||
{
|
||||
value: '1002',
|
||||
label: this.__('免费WiFi'),
|
||||
},
|
||||
{
|
||||
value: '1003',
|
||||
label: this.__('免费送货'),
|
||||
},
|
||||
],
|
||||
value: '',
|
||||
options: {
|
||||
theme: 'snow',
|
||||
bounds: document.body,
|
||||
debug: 'warn',
|
||||
modules: {
|
||||
toolbar: {
|
||||
container: [
|
||||
['bold', 'italic', 'underline', 'strike'],
|
||||
[{ header: [1, 2, 3, 4, 5, 6, false] }],
|
||||
[{ size: ['small', false, 'large', 'huge'] }],
|
||||
[{ color: [] }, { background: [] }],
|
||||
['blockquote', 'code-block'],
|
||||
[{ list: 'ordered' }, { list: 'bullet' }],
|
||||
[{ script: 'sub' }, { script: 'super' }],
|
||||
[{ indent: '-1' }, { indent: '+1' }],
|
||||
[{ align: [] }],
|
||||
[{ direction: 'rtl' }],
|
||||
[{ font: [] }],
|
||||
['clean'],
|
||||
['link', 'image', 'vab-upload-image'],
|
||||
],
|
||||
test: 666,
|
||||
treeData: [],
|
||||
activeName: 'first',
|
||||
optionslist: [
|
||||
{
|
||||
value: '1001',
|
||||
label: this.__('免费停车'),
|
||||
},
|
||||
{
|
||||
value: '1002',
|
||||
label: this.__('免费WiFi'),
|
||||
},
|
||||
{
|
||||
value: '1003',
|
||||
label: this.__('免费送货'),
|
||||
},
|
||||
},
|
||||
placeholder: '',
|
||||
readOnly: false,
|
||||
isRest:false
|
||||
},
|
||||
defaultProps: {
|
||||
label: 'category_name',
|
||||
children: 'children',
|
||||
disabled: 'disabled',
|
||||
},
|
||||
storeForm: {},
|
||||
slideShowForm: {
|
||||
store_slide: [
|
||||
{ img: '', check: true, name: '' },
|
||||
{ img: '', check: true, name: '' },
|
||||
{ img: '', check: true, name: '' },
|
||||
{ img: '', check: true, name: '' },
|
||||
{ img: '', check: true, name: '' },
|
||||
],
|
||||
},
|
||||
physicalStoreForm: {
|
||||
store_notice: undefined,
|
||||
store_o2o_tags: [],
|
||||
store_opening_hours: undefined,
|
||||
store_close_hours: undefined,
|
||||
store_discount: undefined,
|
||||
store_circle: undefined,
|
||||
},
|
||||
storeConfigForm: {
|
||||
sc_is_enabled_invoice: undefined,
|
||||
},
|
||||
form: {
|
||||
store_name: undefined,
|
||||
store_logo: undefined,
|
||||
store_slogan: undefined,
|
||||
store_address: undefined,
|
||||
store_longitude: '',
|
||||
store_latitude: '',
|
||||
str_store_area: undefined,
|
||||
store_tel: undefined,
|
||||
store_opening_hours: undefined,
|
||||
store_circle: undefined,
|
||||
store_discount: undefined,
|
||||
store_close_hours: undefined,
|
||||
store_qq: undefined,
|
||||
company_description: undefined,
|
||||
store_banner: undefined,
|
||||
store_ww: undefined,
|
||||
store_notice: undefined,
|
||||
store_o2o_tags: [],
|
||||
store_district_id: '',
|
||||
},
|
||||
queryArea: {
|
||||
province: { code: '', name: '' },
|
||||
city: { code: '', name: '' },
|
||||
district: { code: '', name: '' },
|
||||
},
|
||||
srcList: [],
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchData()
|
||||
this.getTree()
|
||||
},
|
||||
methods: {
|
||||
getPhysicalStoreParams() {
|
||||
const form = this.physicalStoreForm
|
||||
let params = {
|
||||
store_notice: form.store_notice,
|
||||
// store_o2o_tags: form.store_o2o_tags.toString(),
|
||||
store_opening_hours: form.store_opening_hours,
|
||||
store_close_hours: form.store_close_hours,
|
||||
store_discount: form.store_discount,
|
||||
store_circle: form.store_circle,
|
||||
}
|
||||
return params
|
||||
},
|
||||
getStoreParams() {
|
||||
const form = this.storeForm
|
||||
let params = {
|
||||
store_name: form.store_name,
|
||||
store_slogan: form.store_slogan,
|
||||
store_logo: form.store_logo,
|
||||
store_banner: form.store_banner,
|
||||
store_address: form.store_address,
|
||||
store_longitude: form.store_longitude,
|
||||
store_latitude: form.store_latitude,
|
||||
store_tel: form.store_tel,
|
||||
store_qq: form.store_qq,
|
||||
store_ww: form.store_ww,
|
||||
company_description: form.company_description,
|
||||
store_biz_state:form.store_biz_state
|
||||
}
|
||||
|
||||
if (this.queryArea.province.name) {
|
||||
params.store_area = this.queryArea.province.name
|
||||
}
|
||||
if (this.queryArea.city.name) {
|
||||
params.store_area += '/' + this.queryArea.city.name
|
||||
}
|
||||
if (this.queryArea.district.name) {
|
||||
params.store_area += '/' + this.queryArea.district.name
|
||||
}
|
||||
|
||||
if (this.queryArea.province.code) {
|
||||
params.store_district_id = this.queryArea.province.code
|
||||
}
|
||||
if (this.queryArea.city.code) {
|
||||
params.store_district_id += '/' + this.queryArea.city.code
|
||||
}
|
||||
if (this.queryArea.district.code) {
|
||||
params.store_district_id += '/' + this.queryArea.district.code
|
||||
}
|
||||
|
||||
return params
|
||||
},
|
||||
handleStoreStatus(e){
|
||||
this.storeForm.store_biz_state = e;
|
||||
},
|
||||
getSlideShowForm() {
|
||||
const form = this.slideShowForm
|
||||
let params = {
|
||||
store_slide: JSON.stringify(form.store_slide),
|
||||
}
|
||||
return params
|
||||
},
|
||||
getStoreConfigForm() {
|
||||
const form = this.storeConfigForm
|
||||
let params = {
|
||||
sc_is_enabled_invoice: JSON.stringify(form.sc_is_enabled_invoice),
|
||||
}
|
||||
return params
|
||||
},
|
||||
__,
|
||||
upImage(image, index) {
|
||||
this.form.store_slide[index].img = image
|
||||
},
|
||||
|
||||
async handleEdit(params) {
|
||||
this.$baseConfirm(this.__('修改立马生效,是否继续?'), null, async () => {
|
||||
const { msg, status } = await storeSetUp(params)
|
||||
if (200 == status) {
|
||||
this.$baseMessage(msg, 'success')
|
||||
} else {
|
||||
this.$baseMessage(msg, 'error')
|
||||
}
|
||||
await this.fetchData()
|
||||
})
|
||||
},
|
||||
handleParams() {
|
||||
let params = Object.assign({}, this.form)
|
||||
params.store_o2o_tags = this.form.store_o2o_tags.toString()
|
||||
params.store_slide = JSON.stringify(params.store_slide)
|
||||
return params
|
||||
},
|
||||
async fetchData(params) {
|
||||
const { data } = await get({ params })
|
||||
this.initData(data)
|
||||
},
|
||||
async getTree() {
|
||||
const { data } = await getTree()
|
||||
console.log(data)
|
||||
if (data) {
|
||||
this.treeData = data
|
||||
} else {
|
||||
this.treeData = []
|
||||
}
|
||||
},
|
||||
initData(data) {
|
||||
this.physicalStoreForm = {
|
||||
store_notice: data.info.store_notice,
|
||||
store_opening_hours: data.info.store_opening_hours,
|
||||
store_close_hours: data.info.store_close_hours,
|
||||
store_discount: data.info.store_discount,
|
||||
store_circle: Number(data.store_circle),
|
||||
}
|
||||
this.storeConfigForm = {
|
||||
sc_is_enabled_invoice: data.sc_is_enabled_invoice,
|
||||
}
|
||||
if (data.store_o2o_tags) {
|
||||
this.physicalStoreForm.store_o2o_tags = data.store_o2o_tags.split(',')
|
||||
}
|
||||
|
||||
this.storeForm = {
|
||||
store_name: data.store_name,
|
||||
store_slogan: data.store_slogan,
|
||||
store_logo: data.store_logo,
|
||||
store_banner: data.info.store_banner,
|
||||
store_address: data.store_address,
|
||||
store_longitude: data.store_longitude,
|
||||
store_latitude: data.store_latitude,
|
||||
store_tel: data.info.store_tel,
|
||||
store_qq: data.info.store_qq,
|
||||
store_ww: data.info.store_ww,
|
||||
company_description: data.company.company_description,
|
||||
wx_qrcode: data.wx_qrcode,
|
||||
store_biz_state:data.store_biz_state
|
||||
}
|
||||
|
||||
this.srcList.push(data.wx_qrcode)
|
||||
if (data.info.store_slide && data.info.store_slide.length > 0) {
|
||||
this.slideShowForm.store_slide = data.info.store_slide
|
||||
} else {
|
||||
this.slideShowForm = {
|
||||
value: '',
|
||||
options: {
|
||||
theme: 'snow',
|
||||
bounds: document.body,
|
||||
debug: 'warn',
|
||||
modules: {
|
||||
toolbar: {
|
||||
container: [
|
||||
['bold', 'italic', 'underline', 'strike'],
|
||||
[{ header: [1, 2, 3, 4, 5, 6, false] }],
|
||||
[{ size: ['small', false, 'large', 'huge'] }],
|
||||
[{ color: [] }, { background: [] }],
|
||||
['blockquote', 'code-block'],
|
||||
[{ list: 'ordered' }, { list: 'bullet' }],
|
||||
[{ script: 'sub' }, { script: 'super' }],
|
||||
[{ indent: '-1' }, { indent: '+1' }],
|
||||
[{ align: [] }],
|
||||
[{ direction: 'rtl' }],
|
||||
[{ font: [] }],
|
||||
['clean'],
|
||||
['link', 'image', 'vab-upload-image'],
|
||||
],
|
||||
},
|
||||
},
|
||||
placeholder: '',
|
||||
readOnly: false,
|
||||
isRest: false,
|
||||
},
|
||||
defaultProps: {
|
||||
label: 'category_name',
|
||||
children: 'children',
|
||||
disabled: 'disabled',
|
||||
},
|
||||
storeForm: {},
|
||||
slideShowForm: {
|
||||
store_slide: [
|
||||
{ img: '', check: true, name: '' },
|
||||
{ img: '', check: true, name: '' },
|
||||
@ -713,70 +560,275 @@ export default {
|
||||
{ img: '', check: true, name: '' },
|
||||
{ img: '', check: true, name: '' },
|
||||
],
|
||||
},
|
||||
physicalStoreForm: {
|
||||
store_notice: undefined,
|
||||
store_o2o_tags: [],
|
||||
store_opening_hours: undefined,
|
||||
store_close_hours: undefined,
|
||||
store_discount: undefined,
|
||||
store_circle: undefined,
|
||||
},
|
||||
storeConfigForm: {
|
||||
sc_is_enabled_invoice: undefined,
|
||||
},
|
||||
form: {
|
||||
store_name: undefined,
|
||||
store_logo: undefined,
|
||||
store_slogan: undefined,
|
||||
store_address: undefined,
|
||||
store_longitude: '',
|
||||
store_latitude: '',
|
||||
str_store_area: undefined,
|
||||
store_tel: undefined,
|
||||
store_opening_hours: undefined,
|
||||
store_circle: undefined,
|
||||
store_discount: undefined,
|
||||
store_close_hours: undefined,
|
||||
store_qq: undefined,
|
||||
company_description: undefined,
|
||||
store_banner: undefined,
|
||||
store_ww: undefined,
|
||||
store_notice: undefined,
|
||||
store_o2o_tags: [],
|
||||
store_district_id: '',
|
||||
packing_fee: 0,
|
||||
},
|
||||
queryArea: {
|
||||
province: { code: '', name: '' },
|
||||
city: { code: '', name: '' },
|
||||
district: { code: '', name: '' },
|
||||
},
|
||||
srcList: [],
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchData()
|
||||
this.getTree()
|
||||
},
|
||||
methods: {
|
||||
getPhysicalStoreParams() {
|
||||
const form = this.physicalStoreForm
|
||||
let params = {
|
||||
store_notice: form.store_notice,
|
||||
// store_o2o_tags: form.store_o2o_tags.toString(),
|
||||
store_opening_hours: form.store_opening_hours,
|
||||
store_close_hours: form.store_close_hours,
|
||||
store_discount: form.store_discount,
|
||||
store_circle: form.store_circle,
|
||||
}
|
||||
return params
|
||||
},
|
||||
getStoreParams() {
|
||||
const form = this.storeForm
|
||||
let params = {
|
||||
store_name: form.store_name,
|
||||
store_slogan: form.store_slogan,
|
||||
store_logo: form.store_logo,
|
||||
store_banner: form.store_banner,
|
||||
store_address: form.store_address,
|
||||
store_longitude: form.store_longitude,
|
||||
store_latitude: form.store_latitude,
|
||||
store_tel: form.store_tel,
|
||||
ringtone_is_enable:form.ringtone_is_enable,
|
||||
store_qq: form.store_qq,
|
||||
store_ww: form.store_ww,
|
||||
company_description: form.company_description,
|
||||
store_biz_state: form.store_biz_state,
|
||||
packing_fee: form.packing_fee,
|
||||
}
|
||||
}
|
||||
|
||||
const store_area = data.store_area.split('/')
|
||||
const store_district_id = data.store_district_id.split(',')
|
||||
if (this.queryArea.province.name) {
|
||||
params.store_area = this.queryArea.province.name
|
||||
}
|
||||
if (this.queryArea.city.name) {
|
||||
params.store_area += '/' + this.queryArea.city.name
|
||||
}
|
||||
if (this.queryArea.district.name) {
|
||||
params.store_area += '/' + this.queryArea.district.name
|
||||
}
|
||||
|
||||
this.initQueryArea(store_district_id, store_area)
|
||||
this.form.store_o2o_flag = data.store_o2o_flag
|
||||
if (this.queryArea.province.code) {
|
||||
params.store_district_id = this.queryArea.province.code
|
||||
}
|
||||
if (this.queryArea.city.code) {
|
||||
params.store_district_id += '/' + this.queryArea.city.code
|
||||
}
|
||||
if (this.queryArea.district.code) {
|
||||
params.store_district_id += '/' + this.queryArea.district.code
|
||||
}
|
||||
|
||||
return params
|
||||
},
|
||||
handleStoreStatus(e) {
|
||||
this.storeForm.store_biz_state = e
|
||||
},
|
||||
handleRingStatus(e) {
|
||||
this.storeForm.ringtone_is_enable = e
|
||||
console.log('ringtone_is_enable:', this.storeForm.ringtone_is_enable)
|
||||
},
|
||||
getSlideShowForm() {
|
||||
const form = this.slideShowForm
|
||||
let params = {
|
||||
store_slide: JSON.stringify(form.store_slide),
|
||||
}
|
||||
return params
|
||||
},
|
||||
getStoreConfigForm() {
|
||||
const form = this.storeConfigForm
|
||||
let params = {
|
||||
sc_is_enabled_invoice: JSON.stringify(form.sc_is_enabled_invoice),
|
||||
}
|
||||
return params
|
||||
},
|
||||
__,
|
||||
upImage(image, index) {
|
||||
this.form.store_slide[index].img = image
|
||||
},
|
||||
|
||||
async handleEdit(params) {
|
||||
console.log('handleEdit params:', params)
|
||||
this.$baseConfirm(
|
||||
this.__('修改立马生效,是否继续?'),
|
||||
null,
|
||||
async () => {
|
||||
const { msg, status } = await storeSetUp(params)
|
||||
if (200 == status) {
|
||||
this.$baseMessage(msg, 'success')
|
||||
} else {
|
||||
this.$baseMessage(msg, 'error')
|
||||
}
|
||||
await this.fetchData()
|
||||
}
|
||||
)
|
||||
},
|
||||
handleParams() {
|
||||
let params = Object.assign({}, this.form)
|
||||
params.store_o2o_tags = this.form.store_o2o_tags.toString()
|
||||
params.store_slide = JSON.stringify(params.store_slide)
|
||||
return params
|
||||
},
|
||||
async fetchData(params) {
|
||||
const { data } = await get({ params })
|
||||
this.initData(data)
|
||||
},
|
||||
async getTree() {
|
||||
const { data } = await getTree()
|
||||
if (data) {
|
||||
this.treeData = data
|
||||
} else {
|
||||
this.treeData = []
|
||||
}
|
||||
},
|
||||
initData(data) {
|
||||
this.physicalStoreForm = {
|
||||
store_notice: data.info.store_notice,
|
||||
store_opening_hours: data.info.store_opening_hours,
|
||||
store_close_hours: data.info.store_close_hours,
|
||||
store_discount: data.info.store_discount,
|
||||
store_circle: Number(data.store_circle),
|
||||
}
|
||||
this.storeConfigForm = {
|
||||
sc_is_enabled_invoice: data.sc_is_enabled_invoice,
|
||||
}
|
||||
if (data.store_o2o_tags) {
|
||||
this.physicalStoreForm.store_o2o_tags = data.store_o2o_tags.split(',')
|
||||
}
|
||||
|
||||
this.storeForm = {
|
||||
store_name: data.store_name,
|
||||
store_slogan: data.store_slogan,
|
||||
store_logo: data.store_logo,
|
||||
store_banner: data.info.store_banner,
|
||||
store_address: data.store_address,
|
||||
store_longitude: data.store_longitude,
|
||||
store_latitude: data.store_latitude,
|
||||
store_tel: data.info.store_tel,
|
||||
store_qq: data.info.store_qq,
|
||||
store_ww: data.info.store_ww,
|
||||
company_description: data.company.company_description,
|
||||
wx_qrcode: data.wx_qrcode,
|
||||
store_biz_state: data.store_biz_state,
|
||||
packing_fee: data.packing_fee,
|
||||
ringtone_is_enable: data.ringtone_is_enable,
|
||||
}
|
||||
|
||||
this.srcList.push(data.wx_qrcode)
|
||||
if (data.info.store_slide && data.info.store_slide.length > 0) {
|
||||
this.slideShowForm.store_slide = data.info.store_slide
|
||||
} else {
|
||||
this.slideShowForm = {
|
||||
store_slide: [
|
||||
{ img: '', check: true, name: '' },
|
||||
{ img: '', check: true, name: '' },
|
||||
{ img: '', check: true, name: '' },
|
||||
{ img: '', check: true, name: '' },
|
||||
{ img: '', check: true, name: '' },
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
const store_area = data.store_area.split('/')
|
||||
const store_district_id = data.store_district_id.split(',')
|
||||
|
||||
this.initQueryArea(store_district_id, store_area)
|
||||
this.form.store_o2o_flag = data.store_o2o_flag
|
||||
},
|
||||
initQueryArea(store_district_id, store_area) {
|
||||
if (!store_district_id && store_area) return
|
||||
if (store_district_id[0]) {
|
||||
this.queryArea.province.code = store_district_id[0]
|
||||
}
|
||||
if (store_district_id[1]) {
|
||||
this.queryArea.city.code = store_district_id[1]
|
||||
}
|
||||
if (store_district_id[2]) {
|
||||
this.queryArea.district.code = store_district_id[2]
|
||||
}
|
||||
if (store_area[0]) {
|
||||
this.queryArea.province.name = store_area[0]
|
||||
}
|
||||
if (store_area[1]) {
|
||||
this.queryArea.city.name = store_area[1]
|
||||
}
|
||||
if (store_area[2]) {
|
||||
this.queryArea.district.name = store_area[2]
|
||||
}
|
||||
},
|
||||
getAddress(address) {
|
||||
this.storeForm.store_address = address.value
|
||||
this.storeForm.store_longitude = address.lng
|
||||
this.storeForm.store_latitude = address.lat
|
||||
},
|
||||
},
|
||||
initQueryArea(store_district_id, store_area) {
|
||||
if (!store_district_id && store_area) return
|
||||
if (store_district_id[0]) {
|
||||
this.queryArea.province.code = store_district_id[0]
|
||||
}
|
||||
if (store_district_id[1]) {
|
||||
this.queryArea.city.code = store_district_id[1]
|
||||
}
|
||||
if (store_district_id[2]) {
|
||||
this.queryArea.district.code = store_district_id[2]
|
||||
}
|
||||
if (store_area[0]) {
|
||||
this.queryArea.province.name = store_area[0]
|
||||
}
|
||||
if (store_area[1]) {
|
||||
this.queryArea.city.name = store_area[1]
|
||||
}
|
||||
if (store_area[2]) {
|
||||
this.queryArea.district.name = store_area[2]
|
||||
}
|
||||
},
|
||||
getAddress(address) {
|
||||
this.storeForm.store_address = address.value
|
||||
this.storeForm.store_longitude = address.lng
|
||||
this.storeForm.store_latitude = address.lat
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.config-save {
|
||||
color: white;
|
||||
text-align: center;
|
||||
background-color: #2c2e30;
|
||||
padding: 12px;
|
||||
}
|
||||
.config-save {
|
||||
color: white;
|
||||
text-align: center;
|
||||
background-color: #2c2e30;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.config-save:hover {
|
||||
background-color: #3d3d3d;
|
||||
}
|
||||
.config-save:hover {
|
||||
background-color: #3d3d3d;
|
||||
}
|
||||
|
||||
.form-item-img-list {
|
||||
.el-form-item__content {
|
||||
.form-item-img-list {
|
||||
.el-form-item__content {
|
||||
display: flex;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.QRcode {
|
||||
display: flex;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
margin-left: 40px;
|
||||
|
||||
.QRcode {
|
||||
display: flex;
|
||||
margin-left: 40px;
|
||||
|
||||
.QRcode-img {
|
||||
border: 1px solid #cccccc;
|
||||
border-radius: 6px;
|
||||
.QRcode-img {
|
||||
border: 1px solid #cccccc;
|
||||
border-radius: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -189,10 +189,6 @@ export default {
|
||||
prop: 'has_apply_mer',
|
||||
label: '商家进件状态',
|
||||
},
|
||||
{
|
||||
prop: 'store_status',
|
||||
label: '店铺创建状态',
|
||||
},
|
||||
{
|
||||
prop: 'has_apply_split',
|
||||
label: '申请分账业务状态',
|
||||
@ -205,6 +201,10 @@ export default {
|
||||
prop: 'has_bind_receiver',
|
||||
label: '绑定分账接收方',
|
||||
},
|
||||
{
|
||||
prop: 'store_status',
|
||||
label: '店铺创建状态',
|
||||
},
|
||||
],
|
||||
tableData: [
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -9,6 +9,22 @@
|
||||
<el-form-item :label="__('模版编号')" prop="tplmsg_tpl_id">
|
||||
<el-input v-model="form.tplmsg_tpl_id" :placeholder="__('模版编号')" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="__('店铺')" prop="store_id">
|
||||
<el-select
|
||||
v-model="form.store_id"
|
||||
clearable
|
||||
filterable
|
||||
placeholder="选择店铺">
|
||||
<el-option
|
||||
v-for="item in shopList"
|
||||
:key="item.store_id"
|
||||
:label="item.store_name"
|
||||
:value="item.store_id"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="__('跳转路径')" prop="link_url">
|
||||
<el-input v-model="form.link_url" :placeholder="__('微信公众号或者小程序跳转路径')" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="close">{{ __('取消') }}</el-button>
|
||||
@ -21,7 +37,7 @@
|
||||
import { translateTitle as __ } from '@/utils/i18n'
|
||||
|
||||
import { doEdit } from '@/api/wechat/tplmsg'
|
||||
|
||||
import GoodsToolApi from '@/api/goodsTool'
|
||||
export default {
|
||||
name: 'WechatTplmsgEdit',
|
||||
data() {
|
||||
@ -30,11 +46,13 @@
|
||||
rules: {},
|
||||
title: '',
|
||||
dialogFormVisible: false,
|
||||
shopList:[],
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
mounted() {
|
||||
this.$forceUpdate()
|
||||
this.getShopList()
|
||||
},
|
||||
methods: {
|
||||
__,
|
||||
@ -65,6 +83,10 @@
|
||||
}
|
||||
})
|
||||
},
|
||||
async getShopList() {
|
||||
let res = await GoodsToolApi.getShopList()
|
||||
this.shopList = res.data.items
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -34,7 +34,7 @@
|
||||
/>
|
||||
<el-table-column
|
||||
align="center"
|
||||
:label="__('模版编号')"
|
||||
:label="__('微信模版编号')"
|
||||
prop="tplmsg_tpl_id"
|
||||
show-overflow-tooltip
|
||||
width="150"
|
||||
@ -76,6 +76,12 @@
|
||||
prop="tplmsg_is_buildin"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column
|
||||
align="center"
|
||||
:label="__('跳转路径')"
|
||||
prop="link_url"
|
||||
show-overflow-tooltip
|
||||
/>
|
||||
<el-table-column
|
||||
align="center"
|
||||
:label="__('备注')"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user